Horis 2 سال پیش
والد
کامیت
6e16560b3a

+ 2 - 6
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
     }

+ 14 - 2
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)

+ 24 - 2
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<TextPage>(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]

+ 22 - 10
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<String, String> 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<String, String> 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<String> findCoverHrefs(Document packageDocument) {
+    static Set<String> findCoverHrefs(Document packageDocument, URI packagePath) {
 
         Set<String> 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<String> coverHrefs = findCoverHrefs(packageDocument);
+        Collection<String> coverHrefs = findCoverHrefs(packageDocument, packagePath);
         for (String coverHref : coverHrefs) {
             Resource resource = book.getResources().getByHref(coverHref);
             if (resource == null) {