From 0596ddafa8c1e37796c0843a19cb7eb433d3f920 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 7 Mar 2021 22:42:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9B=BE=E7=89=87=E6=A0=B7?= =?UTF-8?q?=E5=BC=8FTEXT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../read/page/provider/ChapterProvider.kt | 130 +++++++++++++++--- .../io/legado/app/utils/StringExtensions.kt | 2 - 2 files changed, 109 insertions(+), 23 deletions(-) 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 e2e963431..730f79a34 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 @@ -69,6 +69,8 @@ object ChapterProvider { @JvmStatic lateinit var contentPaint: TextPaint + private const val srcReplaceChar = "🖼" + init { upStyle() } @@ -86,23 +88,68 @@ object ChapterProvider { val stringBuilder = StringBuilder() var durY = 0f textPages.add(TextPage()) - contents.forEachIndexed { index, text -> - val matcher = AppPattern.imgPattern.matcher(text) - if (matcher.find()) { - matcher.group(1)?.let { - if (!book.isEpub()) { - val src = NetworkUtils.getAbsoluteURL(bookChapter.url, it) - durY = setTypeImage( - book, bookChapter, src, durY, textPages, book.getImageStyle() - ) + contents.forEachIndexed { index, content -> + if (book.getImageStyle() == Book.imgStyleText) { + var text = content.replace(srcReplaceChar, "画") + val srcList = LinkedList() + val sb = StringBuffer() + val matcher = AppPattern.imgPattern.matcher(text) + while (matcher.find()) { + matcher.group(1)?.let { + srcList.add(it) + matcher.appendReplacement(sb, srcReplaceChar) } } - } else { + matcher.appendTail(sb) + text = sb.toString() val isTitle = index == 0 val textPaint = if (isTitle) titlePaint else contentPaint if (!(isTitle && ReadBookConfig.titleMode == 2)) { - durY = setTypeText(text, durY, textPages, stringBuilder, isTitle, textPaint) + durY = setTypeText( + text, + durY, + textPages, + stringBuilder, + isTitle, + textPaint, + srcList + ) } + } else if (book.getImageStyle() != Book.imgStyleText) { + content.replace(AppPattern.imgPattern.toRegex(), "\n\$0\n") + .split("\n").forEach { text -> + if (text.isNotBlank()) { + val matcher = AppPattern.imgPattern.matcher(text) + if (matcher.find()) { + matcher.group(1)?.let { mt -> + if (!book.isEpub()) { + val src = NetworkUtils.getAbsoluteURL(bookChapter.url, mt) + durY = setTypeImage( + book, + bookChapter, + src, + durY, + textPages, + book.getImageStyle() + ) + } + } + } else { + val isTitle = index == 0 + val textPaint = if (isTitle) titlePaint else contentPaint + if (!(isTitle && ReadBookConfig.titleMode == 2)) { + durY = setTypeText( + text, + durY, + textPages, + stringBuilder, + isTitle, + textPaint + ) + } + } + } + } } } textPages.last().height = durY + 20.dp @@ -199,7 +246,8 @@ object ChapterProvider { textPages: ArrayList, stringBuilder: StringBuilder, isTitle: Boolean, - textPaint: TextPaint + textPaint: TextPaint, + srcList: LinkedList? = null ): Float { var durY = if (isTitle) y + titleTopSpacing else y val layout = if (ReadBookConfig.useZhLayout) { @@ -216,7 +264,13 @@ object ChapterProvider { if (lineIndex == 0 && layout.lineCount > 1 && !isTitle) { //第一行 textLine.text = words - addCharsToLineFirst(textLine, words.toStringArray(), textPaint, desiredWidth) + addCharsToLineFirst( + textLine, + words.toStringArray(), + textPaint, + desiredWidth, + srcList + ) } else if (lineIndex == layout.lineCount - 1) { //最后一行 textLine.text = "$words\n" @@ -224,11 +278,18 @@ object ChapterProvider { val x = if (isTitle && ReadBookConfig.titleMode == 1) (visibleWidth - layout.getLineWidth(lineIndex)) / 2 else 0f - addCharsToLineLast(textLine, words.toStringArray(), textPaint, x) + addCharsToLineLast(textLine, words.toStringArray(), textPaint, x, srcList) } else { //中间行 textLine.text = words - addCharsToLineMiddle(textLine, words.toStringArray(), textPaint, desiredWidth, 0f) + addCharsToLineMiddle( + textLine, + words.toStringArray(), + textPaint, + desiredWidth, + 0f, + srcList + ) } if (durY + textPaint.textHeight > visibleHeight) { //当前页面结束,设置各种值 @@ -259,21 +320,30 @@ object ChapterProvider { words: Array, textPaint: TextPaint, desiredWidth: Float, + srcList: LinkedList? ) { var x = 0f if (!ReadBookConfig.textFullJustify) { - addCharsToLineLast(textLine, words, textPaint, x) + addCharsToLineLast(textLine, words, textPaint, x, srcList) return } val bodyIndent = ReadBookConfig.paragraphIndent val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length bodyIndent.toStringArray().forEach { val x1 = x + icw - textLine.addTextChar(charData = it, start = paddingLeft + x, end = paddingLeft + x1) + if (srcList != null && it == srcReplaceChar) { + textLine.addTextChar( + srcList.removeFirst(), + start = paddingLeft + x, + end = paddingLeft + x1 + ) + } else { + textLine.addTextChar(it, start = paddingLeft + x, end = paddingLeft + x1) + } x = x1 } val words1 = words.copyOfRange(bodyIndent.length, words.size) - addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x) + addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x, srcList) } /** @@ -285,9 +355,10 @@ object ChapterProvider { textPaint: TextPaint, desiredWidth: Float, startX: Float, + srcList: LinkedList? ) { if (!ReadBookConfig.textFullJustify) { - addCharsToLineLast(textLine, words, textPaint, startX) + addCharsToLineLast(textLine, words, textPaint, startX, srcList) return } val gapCount: Int = words.lastIndex @@ -296,7 +367,15 @@ object ChapterProvider { words.forEachIndexed { index, s -> val cw = StaticLayout.getDesiredWidth(s, textPaint) val x1 = if (index != words.lastIndex) (x + cw + d) else (x + cw) - textLine.addTextChar(charData = s, start = paddingLeft + x, end = paddingLeft + x1) + if (srcList != null && s == srcReplaceChar) { + textLine.addTextChar( + srcList.removeFirst(), + start = paddingLeft + x, + end = paddingLeft + x1 + ) + } else { + textLine.addTextChar(charData = s, start = paddingLeft + x, end = paddingLeft + x1) + } x = x1 } exceed(textLine, words) @@ -310,12 +389,21 @@ object ChapterProvider { words: Array, textPaint: TextPaint, startX: Float, + srcList: LinkedList? ) { var x = startX words.forEach { val cw = StaticLayout.getDesiredWidth(it, textPaint) val x1 = x + cw - textLine.addTextChar(charData = it, start = paddingLeft + x, end = paddingLeft + x1) + if (srcList != null && it == srcReplaceChar) { + textLine.addTextChar( + srcList.removeFirst(), + start = paddingLeft + x, + end = paddingLeft + x1 + ) + } else { + textLine.addTextChar(charData = it, start = paddingLeft + x, end = paddingLeft + x1) + } x = x1 } exceed(textLine, words) diff --git a/app/src/main/java/io/legado/app/utils/StringExtensions.kt b/app/src/main/java/io/legado/app/utils/StringExtensions.kt index b6a6d23e2..0ca1950d9 100644 --- a/app/src/main/java/io/legado/app/utils/StringExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/StringExtensions.kt @@ -9,7 +9,6 @@ import java.io.File import java.util.* val removeHtmlRegex = "]*>".toRegex() -val imgRegex = "]*>".toRegex() val notImgHtmlRegex = "])[^<>]*>".toRegex() fun String?.safeTrim() = if (this.isNullOrBlank()) null else this.trim() @@ -54,7 +53,6 @@ fun String?.isJsonArray(): Boolean = fun String?.htmlFormat(): String { this ?: return "" return this - .replace(imgRegex, "\n$0\n") .replace(removeHtmlRegex, "\n") .replace(notImgHtmlRegex, "") .replace("\\s*\\n+\\s*".toRegex(), "\n  ")