mirror of
https://github.com/gedoor/legado.git
synced 2024-07-06 23:47:49 +08:00
优化
This commit is contained in:
parent
0fe3cff114
commit
497a1c9960
@ -16,7 +16,6 @@ import me.ag2s.epublib.domain.EpubBook
|
|||||||
import me.ag2s.epublib.domain.Resource
|
import me.ag2s.epublib.domain.Resource
|
||||||
import me.ag2s.epublib.domain.TOCReference
|
import me.ag2s.epublib.domain.TOCReference
|
||||||
import me.ag2s.epublib.epub.EpubReader
|
import me.ag2s.epublib.epub.EpubReader
|
||||||
import me.ag2s.epublib.util.StringUtil
|
|
||||||
import me.ag2s.epublib.util.zip.AndroidZipFile
|
import me.ag2s.epublib.util.zip.AndroidZipFile
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
@ -25,6 +24,7 @@ import java.io.File
|
|||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import java.net.URI
|
||||||
import java.net.URLDecoder
|
import java.net.URLDecoder
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
@ -245,11 +245,7 @@ class EpubFile(var book: Book) {
|
|||||||
}
|
}
|
||||||
bodyElement.select("img").forEach {
|
bodyElement.select("img").forEach {
|
||||||
val src = it.attr("src")
|
val src = it.attr("src")
|
||||||
val path = res.href.substringBeforeLast("/", "")
|
it.attr("src", URI(res.href).resolve(src).toString())
|
||||||
if (path.isNotEmpty()) {
|
|
||||||
val absSrc = StringUtil.collapsePathDots("$path/$src")
|
|
||||||
it.attr("src", absSrc)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return bodyElement
|
return bodyElement
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import io.legado.app.ui.book.read.page.entities.TextPage
|
|||||||
import io.legado.app.ui.book.read.page.entities.column.ImageColumn
|
import io.legado.app.ui.book.read.page.entities.column.ImageColumn
|
||||||
import io.legado.app.ui.book.read.page.entities.column.ReviewColumn
|
import io.legado.app.ui.book.read.page.entities.column.ReviewColumn
|
||||||
import io.legado.app.ui.book.read.page.entities.column.TextColumn
|
import io.legado.app.ui.book.read.page.entities.column.TextColumn
|
||||||
|
import io.legado.app.utils.LogUtils
|
||||||
import io.legado.app.utils.RealPathUtil
|
import io.legado.app.utils.RealPathUtil
|
||||||
import io.legado.app.utils.dpToPx
|
import io.legado.app.utils.dpToPx
|
||||||
import io.legado.app.utils.fastSum
|
import io.legado.app.utils.fastSum
|
||||||
@ -816,6 +817,9 @@ object ChapterProvider {
|
|||||||
titleBottomSpacing = ReadBookConfig.titleBottomSpacing.dpToPx()
|
titleBottomSpacing = ReadBookConfig.titleBottomSpacing.dpToPx()
|
||||||
val bodyIndent = ReadBookConfig.paragraphIndent
|
val bodyIndent = ReadBookConfig.paragraphIndent
|
||||||
indentCharWidth = StaticLayout.getDesiredWidth(bodyIndent, contentPaint) / bodyIndent.length
|
indentCharWidth = StaticLayout.getDesiredWidth(bodyIndent, contentPaint) / bodyIndent.length
|
||||||
|
LogUtils.d("ChapterProvider") {
|
||||||
|
"bodyIndentLength:${bodyIndent.length} indentCharWidth:$indentCharWidth"
|
||||||
|
}
|
||||||
titlePaintTextHeight = titlePaint.textHeight
|
titlePaintTextHeight = titlePaint.textHeight
|
||||||
contentPaintTextHeight = contentPaint.textHeight
|
contentPaintTextHeight = contentPaint.textHeight
|
||||||
titlePaintFontMetrics = titlePaint.fontMetrics
|
titlePaintFontMetrics = titlePaint.fontMetrics
|
||||||
@ -885,9 +889,17 @@ object ChapterProvider {
|
|||||||
//正文
|
//正文
|
||||||
val cPaint = TextPaint()
|
val cPaint = TextPaint()
|
||||||
cPaint.color = ReadBookConfig.textColor
|
cPaint.color = ReadBookConfig.textColor
|
||||||
cPaint.letterSpacing = ReadBookConfig.letterSpacing
|
cPaint.letterSpacing = ReadBookConfig.letterSpacing.also {
|
||||||
|
LogUtils.d("ChapterProvider") {
|
||||||
|
"ReadBookConfig.letterSpacing:$it"
|
||||||
|
}
|
||||||
|
}
|
||||||
cPaint.typeface = textFont
|
cPaint.typeface = textFont
|
||||||
cPaint.textSize = ReadBookConfig.textSize.toFloat().spToPx()
|
cPaint.textSize = ReadBookConfig.textSize.toFloat().spToPx().also {
|
||||||
|
LogUtils.d("ChapterProvider") {
|
||||||
|
"ReadBookConfig.textSize:$it"
|
||||||
|
}
|
||||||
|
}
|
||||||
cPaint.isAntiAlias = true
|
cPaint.isAntiAlias = true
|
||||||
cPaint.isLinearText = true
|
cPaint.isLinearText = true
|
||||||
return Pair(tPaint, cPaint)
|
return Pair(tPaint, cPaint)
|
||||||
|
@ -21,6 +21,7 @@ import io.legado.app.ui.book.read.page.entities.TextPage
|
|||||||
import io.legado.app.ui.book.read.page.entities.column.ImageColumn
|
import io.legado.app.ui.book.read.page.entities.column.ImageColumn
|
||||||
import io.legado.app.ui.book.read.page.entities.column.ReviewColumn
|
import io.legado.app.ui.book.read.page.entities.column.ReviewColumn
|
||||||
import io.legado.app.ui.book.read.page.entities.column.TextColumn
|
import io.legado.app.ui.book.read.page.entities.column.TextColumn
|
||||||
|
import io.legado.app.utils.LogUtils
|
||||||
import io.legado.app.utils.dpToPx
|
import io.legado.app.utils.dpToPx
|
||||||
import io.legado.app.utils.fastSum
|
import io.legado.app.utils.fastSum
|
||||||
import io.legado.app.utils.splitNotBlank
|
import io.legado.app.utils.splitNotBlank
|
||||||
@ -29,6 +30,8 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
import java.util.LinkedList
|
import java.util.LinkedList
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import kotlin.coroutines.coroutineContext
|
import kotlin.coroutines.coroutineContext
|
||||||
@ -81,13 +84,19 @@ class TextChapterLayout(
|
|||||||
|
|
||||||
var channel = Channel<TextPage>(Int.MAX_VALUE)
|
var channel = Channel<TextPage>(Int.MAX_VALUE)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val lock = Mutex()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
job = Coroutine.async(scope) {
|
job = Coroutine.async(scope) {
|
||||||
launch {
|
launch {
|
||||||
val bookSource = book.getBookSource() ?: return@launch
|
val bookSource = book.getBookSource() ?: return@launch
|
||||||
BookHelp.saveImages(bookSource, book, bookChapter, bookContent.toString())
|
BookHelp.saveImages(bookSource, book, bookChapter, bookContent.toString())
|
||||||
}
|
}
|
||||||
getTextChapter(book, bookChapter, displayTitle, bookContent)
|
lock.withLock {
|
||||||
|
getTextChapter(book, bookChapter, displayTitle, bookContent)
|
||||||
|
}
|
||||||
}.onError {
|
}.onError {
|
||||||
exception = it
|
exception = it
|
||||||
onException(it)
|
onException(it)
|
||||||
@ -650,7 +659,20 @@ class TextChapterLayout(
|
|||||||
val gapCount: Int = words.lastIndex
|
val gapCount: Int = words.lastIndex
|
||||||
val d = residualWidth / gapCount
|
val d = residualWidth / gapCount
|
||||||
textLine.extraLetterSpacingOffsetX = -d / 2
|
textLine.extraLetterSpacingOffsetX = -d / 2
|
||||||
textLine.extraLetterSpacing = d / textPaint.textSize
|
val textSize = textPaint.textSize
|
||||||
|
textLine.extraLetterSpacing = d / textSize
|
||||||
|
LogUtils.d("TextChapterLayout") {
|
||||||
|
"words:$words"
|
||||||
|
}
|
||||||
|
LogUtils.d("TextChapterLayout") {
|
||||||
|
"textWidths:$textWidths"
|
||||||
|
}
|
||||||
|
LogUtils.d("TextChapterLayout") {
|
||||||
|
"textSize:$textSize desiredWidth:$desiredWidth residualWidth:$residualWidth " +
|
||||||
|
"gapCount:$gapCount d:$d " +
|
||||||
|
"extraLetterSpacingOffsetX:${textLine.extraLetterSpacingOffsetX} " +
|
||||||
|
"extraLetterSpacing:${textLine.extraLetterSpacing}"
|
||||||
|
}
|
||||||
var x = startX
|
var x = startX
|
||||||
for (index in words.indices) {
|
for (index in words.indices) {
|
||||||
val char = words[index]
|
val char = words[index]
|
||||||
|
@ -9,6 +9,8 @@ import org.xml.sax.SAXException;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -57,18 +59,26 @@ public class PackageDocumentReader extends PackageDocumentBase {
|
|||||||
|
|
||||||
Document packageDocument = ResourceUtil.getAsDocument(packageResource);
|
Document packageDocument = ResourceUtil.getAsDocument(packageResource);
|
||||||
String packageHref = packageResource.getHref();
|
String packageHref = packageResource.getHref();
|
||||||
resources = fixHrefs(packageHref, resources);
|
|
||||||
|
URI packagePath;
|
||||||
|
try {
|
||||||
|
packagePath = new URI(packageHref);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//resources = fixHrefs(packageHref, resources);
|
||||||
readGuide(packageDocument, epubReader, book, resources);
|
readGuide(packageDocument, epubReader, book, resources);
|
||||||
|
|
||||||
// Books sometimes use non-identifier ids. We map these here to legal ones
|
// Books sometimes use non-identifier ids. We map these here to legal ones
|
||||||
Map<String, String> idMapping = new HashMap<>();
|
Map<String, String> idMapping = new HashMap<>();
|
||||||
String version = DOMUtil.getAttribute(packageDocument.getDocumentElement(), PREFIX_OPF, PackageDocumentBase.version);
|
String version = DOMUtil.getAttribute(packageDocument.getDocumentElement(), PREFIX_OPF, PackageDocumentBase.version);
|
||||||
|
|
||||||
resources = readManifest(packageDocument, packageHref, epubReader,
|
resources = readManifest(packageDocument, packageHref, packagePath, epubReader,
|
||||||
resources, idMapping);
|
resources, idMapping);
|
||||||
book.setResources(resources);
|
book.setResources(resources);
|
||||||
book.setVersion(version);
|
book.setVersion(version);
|
||||||
readCover(packageDocument, book);
|
readCover(packageDocument, packagePath, book);
|
||||||
book.setMetadata(
|
book.setMetadata(
|
||||||
PackageDocumentMetadataReader.readMetadata(packageDocument));
|
PackageDocumentMetadataReader.readMetadata(packageDocument));
|
||||||
book.setSpine(readSpine(packageDocument, book.getResources(), idMapping));
|
book.setSpine(readSpine(packageDocument, book.getResources(), idMapping));
|
||||||
@ -136,6 +146,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
|
|||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static Resources readManifest(Document packageDocument,
|
private static Resources readManifest(Document packageDocument,
|
||||||
String packageHref,
|
String packageHref,
|
||||||
|
URI packagePath,
|
||||||
EpubReader epubReader, Resources resources,
|
EpubReader epubReader, Resources resources,
|
||||||
Map<String, String> idMapping) {
|
Map<String, String> idMapping) {
|
||||||
Element manifestElement = DOMUtil
|
Element manifestElement = DOMUtil
|
||||||
@ -156,7 +167,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
|
|||||||
.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.href);
|
.getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.href);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
href = URLDecoder.decode(href, Constants.CHARACTER_ENCODING);
|
href = URLDecoder.decode(packagePath.resolve(href).toString(), Constants.CHARACTER_ENCODING);
|
||||||
} catch (UnsupportedEncodingException e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
Log.e(TAG, e.getMessage());
|
Log.e(TAG, e.getMessage());
|
||||||
}
|
}
|
||||||
@ -412,7 +423,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
|
|||||||
* @return all resources that have something to do with the coverpage and the cover image.
|
* @return all resources that have something to do with the coverpage and the cover image.
|
||||||
*/
|
*/
|
||||||
// package
|
// package
|
||||||
static Set<String> findCoverHrefs(Document packageDocument) {
|
static Set<String> findCoverHrefs(Document packageDocument, URI packagePath) {
|
||||||
|
|
||||||
Set<String> result = new HashSet<>();
|
Set<String> result = new HashSet<>();
|
||||||
|
|
||||||
@ -428,10 +439,11 @@ public class PackageDocumentReader extends PackageDocumentBase {
|
|||||||
OPFTags.item, OPFAttributes.id, coverResourceId,
|
OPFTags.item, OPFAttributes.id, coverResourceId,
|
||||||
OPFAttributes.href);
|
OPFAttributes.href);
|
||||||
if (StringUtil.isNotBlank(coverHref)) {
|
if (StringUtil.isNotBlank(coverHref)) {
|
||||||
result.add(coverHref);
|
result.add(packagePath.resolve(coverHref).toString());
|
||||||
} else {
|
} else {
|
||||||
|
String resolved = packagePath.resolve(coverResourceId).toString();
|
||||||
result.add(
|
result.add(
|
||||||
coverResourceId); // maybe there was a cover href put in the cover id attribute
|
resolved); // maybe there was a cover href put in the cover id attribute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try and find a reference tag with type is 'cover' and reference is not blank
|
// try and find a reference tag with type is 'cover' and reference is not blank
|
||||||
@ -440,7 +452,7 @@ public class PackageDocumentReader extends PackageDocumentBase {
|
|||||||
OPFTags.reference, OPFAttributes.type, OPFValues.reference_cover,
|
OPFTags.reference, OPFAttributes.type, OPFValues.reference_cover,
|
||||||
OPFAttributes.href);
|
OPFAttributes.href);
|
||||||
if (StringUtil.isNotBlank(coverHref)) {
|
if (StringUtil.isNotBlank(coverHref)) {
|
||||||
result.add(coverHref);
|
result.add(packagePath.resolve(coverHref).toString());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -452,9 +464,9 @@ public class PackageDocumentReader extends PackageDocumentBase {
|
|||||||
* @param packageDocument s
|
* @param packageDocument s
|
||||||
* @param book x
|
* @param book x
|
||||||
*/
|
*/
|
||||||
private static void readCover(Document packageDocument, EpubBook book) {
|
private static void readCover(Document packageDocument, URI packagePath, EpubBook book) {
|
||||||
|
|
||||||
Collection<String> coverHrefs = findCoverHrefs(packageDocument);
|
Collection<String> coverHrefs = findCoverHrefs(packageDocument, packagePath);
|
||||||
for (String coverHref : coverHrefs) {
|
for (String coverHref : coverHrefs) {
|
||||||
Resource resource = book.getResources().getByHref(coverHref);
|
Resource resource = book.getResources().getByHref(coverHref);
|
||||||
if (resource == null) {
|
if (resource == null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user