From 497a1c99607daea8da8f84ca277e9dd762164a14 Mon Sep 17 00:00:00 2001 From: Horis <821938089@qq.com> Date: Wed, 6 Mar 2024 20:13:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/model/localBook/EpubFile.kt | 8 ++--- .../read/page/provider/ChapterProvider.kt | 16 ++++++++-- .../read/page/provider/TextChapterLayout.kt | 26 +++++++++++++-- .../epublib/epub/PackageDocumentReader.java | 32 +++++++++++++------ 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt index bb3f47ba4..768f29237 100644 --- a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt @@ -16,7 +16,6 @@ import me.ag2s.epublib.domain.EpubBook import me.ag2s.epublib.domain.Resource import me.ag2s.epublib.domain.TOCReference import me.ag2s.epublib.epub.EpubReader -import me.ag2s.epublib.util.StringUtil import me.ag2s.epublib.util.zip.AndroidZipFile import org.jsoup.Jsoup import org.jsoup.nodes.Element @@ -25,6 +24,7 @@ import java.io.File import java.io.FileOutputStream import java.io.IOException import java.io.InputStream +import java.net.URI import java.net.URLDecoder import java.nio.charset.Charset @@ -245,11 +245,7 @@ class EpubFile(var book: Book) { } bodyElement.select("img").forEach { val src = it.attr("src") - val path = res.href.substringBeforeLast("/", "") - if (path.isNotEmpty()) { - val absSrc = StringUtil.collapsePathDots("$path/$src") - it.attr("src", absSrc) - } + it.attr("src", URI(res.href).resolve(src).toString()) } return bodyElement } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index a498de9be..9509fdfac 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -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.ReviewColumn 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.dpToPx import io.legado.app.utils.fastSum @@ -816,6 +817,9 @@ object ChapterProvider { titleBottomSpacing = ReadBookConfig.titleBottomSpacing.dpToPx() val bodyIndent = ReadBookConfig.paragraphIndent indentCharWidth = StaticLayout.getDesiredWidth(bodyIndent, contentPaint) / bodyIndent.length + LogUtils.d("ChapterProvider") { + "bodyIndentLength:${bodyIndent.length} indentCharWidth:$indentCharWidth" + } titlePaintTextHeight = titlePaint.textHeight contentPaintTextHeight = contentPaint.textHeight titlePaintFontMetrics = titlePaint.fontMetrics @@ -885,9 +889,17 @@ object ChapterProvider { //正文 val cPaint = TextPaint() cPaint.color = ReadBookConfig.textColor - cPaint.letterSpacing = ReadBookConfig.letterSpacing + cPaint.letterSpacing = ReadBookConfig.letterSpacing.also { + LogUtils.d("ChapterProvider") { + "ReadBookConfig.letterSpacing:$it" + } + } 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.isLinearText = true return Pair(tPaint, cPaint) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt index daab964f4..20a7cc2bf 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/TextChapterLayout.kt @@ -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.ReviewColumn 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.fastSum import io.legado.app.utils.splitNotBlank @@ -29,6 +30,8 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.ensureActive import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import java.util.LinkedList import java.util.Locale import kotlin.coroutines.coroutineContext @@ -81,13 +84,19 @@ class TextChapterLayout( var channel = Channel(Int.MAX_VALUE) + companion object { + val lock = Mutex() + } + init { job = Coroutine.async(scope) { launch { val bookSource = book.getBookSource() ?: return@launch BookHelp.saveImages(bookSource, book, bookChapter, bookContent.toString()) } - getTextChapter(book, bookChapter, displayTitle, bookContent) + lock.withLock { + getTextChapter(book, bookChapter, displayTitle, bookContent) + } }.onError { exception = it onException(it) @@ -650,7 +659,20 @@ class TextChapterLayout( val gapCount: Int = words.lastIndex val d = residualWidth / gapCount 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 for (index in words.indices) { val char = words[index] diff --git a/modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java b/modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java index bdf9a9637..41611dec7 100644 --- a/modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java +++ b/modules/book/src/main/java/me/ag2s/epublib/epub/PackageDocumentReader.java @@ -9,6 +9,8 @@ import org.xml.sax.SAXException; import java.io.IOException; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collection; @@ -57,18 +59,26 @@ public class PackageDocumentReader extends PackageDocumentBase { Document packageDocument = ResourceUtil.getAsDocument(packageResource); 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); // Books sometimes use non-identifier ids. We map these here to legal ones Map idMapping = new HashMap<>(); String version = DOMUtil.getAttribute(packageDocument.getDocumentElement(), PREFIX_OPF, PackageDocumentBase.version); - resources = readManifest(packageDocument, packageHref, epubReader, + resources = readManifest(packageDocument, packageHref, packagePath, epubReader, resources, idMapping); book.setResources(resources); book.setVersion(version); - readCover(packageDocument, book); + readCover(packageDocument, packagePath, book); book.setMetadata( PackageDocumentMetadataReader.readMetadata(packageDocument)); book.setSpine(readSpine(packageDocument, book.getResources(), idMapping)); @@ -136,6 +146,7 @@ public class PackageDocumentReader extends PackageDocumentBase { @SuppressWarnings("unused") private static Resources readManifest(Document packageDocument, String packageHref, + URI packagePath, EpubReader epubReader, Resources resources, Map idMapping) { Element manifestElement = DOMUtil @@ -156,7 +167,7 @@ public class PackageDocumentReader extends PackageDocumentBase { .getAttribute(itemElement, NAMESPACE_OPF, OPFAttributes.href); try { - href = URLDecoder.decode(href, Constants.CHARACTER_ENCODING); + href = URLDecoder.decode(packagePath.resolve(href).toString(), Constants.CHARACTER_ENCODING); } catch (UnsupportedEncodingException e) { 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. */ // package - static Set findCoverHrefs(Document packageDocument) { + static Set findCoverHrefs(Document packageDocument, URI packagePath) { Set result = new HashSet<>(); @@ -428,10 +439,11 @@ public class PackageDocumentReader extends PackageDocumentBase { OPFTags.item, OPFAttributes.id, coverResourceId, OPFAttributes.href); if (StringUtil.isNotBlank(coverHref)) { - result.add(coverHref); + result.add(packagePath.resolve(coverHref).toString()); } else { + String resolved = packagePath.resolve(coverResourceId).toString(); 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 @@ -440,7 +452,7 @@ public class PackageDocumentReader extends PackageDocumentBase { OPFTags.reference, OPFAttributes.type, OPFValues.reference_cover, OPFAttributes.href); if (StringUtil.isNotBlank(coverHref)) { - result.add(coverHref); + result.add(packagePath.resolve(coverHref).toString()); } return result; } @@ -452,9 +464,9 @@ public class PackageDocumentReader extends PackageDocumentBase { * @param packageDocument s * @param book x */ - private static void readCover(Document packageDocument, EpubBook book) { + private static void readCover(Document packageDocument, URI packagePath, EpubBook book) { - Collection coverHrefs = findCoverHrefs(packageDocument); + Collection coverHrefs = findCoverHrefs(packageDocument, packagePath); for (String coverHref : coverHrefs) { Resource resource = book.getResources().getByHref(coverHref); if (resource == null) {