From 4f32cf0566597fd064282bf817e7f6a4af78a8bb Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 10 Sep 2022 21:54:15 +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 --- .../app/ui/book/read/page/ContentTextView.kt | 161 ++++++------------ .../ui/book/read/page/entities/BaseColumn.kt | 14 ++ .../ui/book/read/page/entities/ImageColumn.kt | 8 + .../book/read/page/entities/ReviewColumn.kt | 83 +++++++++ .../ui/book/read/page/entities/TextColumn.kt | 11 +- .../ui/book/read/page/entities/TextLine.kt | 11 +- .../ui/book/read/page/entities/TextPage.kt | 6 +- .../read/page/provider/ChapterProvider.kt | 24 +-- 8 files changed, 176 insertions(+), 142 deletions(-) create mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/entities/BaseColumn.kt create mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/entities/ImageColumn.kt create mode 100644 app/src/main/java/io/legado/app/ui/book/read/page/entities/ReviewColumn.kt diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index ea9c097c1..ffa6cff25 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -4,7 +4,6 @@ import android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.graphics.RectF -import android.text.StaticLayout import android.text.TextPaint import android.util.AttributeSet import android.view.View @@ -16,10 +15,7 @@ import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.lib.theme.accentColor import io.legado.app.model.ReadBook -import io.legado.app.ui.book.read.page.entities.TextColumn -import io.legado.app.ui.book.read.page.entities.TextLine -import io.legado.app.ui.book.read.page.entities.TextPage -import io.legado.app.ui.book.read.page.entities.TextPos +import io.legado.app.ui.book.read.page.entities.* import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ImageProvider import io.legado.app.ui.book.read.page.provider.TextPageFactory @@ -168,86 +164,19 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at reviewCountPaint.textSize = textPaint.textSize * 0.6F reviewCountPaint.color = textColor textLine.columns.forEach { - when (it.style) { - 0 -> { + when (it) { + is TextColumn -> { textPaint.color = textColor if (it.isSearchResult) { textPaint.color = context.accentColor } canvas.drawText(it.charData, it.start, lineBase, textPaint) + if (it.selected) { + canvas.drawRect(it.start, lineTop, it.end, lineBottom, selectedPaint) + } } - 1 -> drawImage(canvas, textPage, textLine, it, lineTop, lineBottom) - 2 -> { - if (textLine.reviewCount <= 0) return@forEach - canvas.drawLine( - it.start, - lineBase - textPaint.textSize * 2 / 5, - it.start + textPaint.textSize / 6, - lineBase - textPaint.textSize / 4, - linePaint - ) - canvas.drawLine( - it.start, - lineBase - textPaint.textSize * 0.38F, - it.start + textPaint.textSize / 6, - lineBase - textPaint.textSize * 0.55F, - linePaint - ) - canvas.drawLine( - it.start + textPaint.textSize / 6, - lineBase - textPaint.textSize / 4, - it.start + textPaint.textSize / 6, - lineBase, - linePaint - ) - canvas.drawLine( - it.start + textPaint.textSize / 6, - lineBase - textPaint.textSize * 0.55F, - it.start + textPaint.textSize / 6, - lineBase - textPaint.textSize * 0.8F, - linePaint - ) - canvas.drawLine( - it.start + textPaint.textSize / 6, - lineBase, - it.start + textPaint.textSize * 1.6F, - lineBase, - linePaint - ) - canvas.drawLine( - it.start + textPaint.textSize / 6, - lineBase - textPaint.textSize * 0.8F, - it.start + textPaint.textSize * 1.6F, - lineBase - textPaint.textSize * 0.8F, - linePaint - ) - canvas.drawLine( - it.start + textPaint.textSize * 1.6F, - lineBase - textPaint.textSize * 0.8F, - it.start + textPaint.textSize * 1.6F, - lineBase, - linePaint - ) - if (textLine.reviewCount < 100) canvas.drawText( - textLine.reviewCount.toString(), - it.start + textPaint.textSize * 0.87F - - StaticLayout.getDesiredWidth( - textLine.reviewCount.toString(), - reviewCountPaint - ) / 2, - lineBase - textPaint.textSize / 6, - reviewCountPaint - ) - else canvas.drawText( - "99+", - it.start + textPaint.textSize * 0.35F, - lineBase - textPaint.textSize / 6, - reviewCountPaint - ) - } - } - if (it.selected) { - canvas.drawRect(it.start, lineTop, it.end, lineBottom, selectedPaint) + is ImageColumn -> drawImage(canvas, textPage, textLine, it, lineTop, lineBottom) + is ReviewColumn -> it.drawToCanvas(canvas, linePaint, reviewCountPaint, lineBase) } } } @@ -260,7 +189,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at canvas: Canvas, textPage: TextPage, textLine: TextLine, - textColumn: TextColumn, + column: ImageColumn, lineTop: Float, lineBottom: Float ) { @@ -278,7 +207,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at isVisible && !cacheIncreased && ImageProvider.isTriggerRecycled() && - !ImageProvider.isImageAlive(book, textColumn.charData) + !ImageProvider.isImageAlive(book, column.src) ) { val newSize = ImageProvider.bitmapLruCache.maxSize() + increaseSize if (newSize < maxCacheSize) { @@ -290,8 +219,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } val bitmap = ImageProvider.getImage( book, - textColumn.charData, - (textColumn.end - textColumn.start).toInt(), + column.src, + (column.end - column.start).toInt(), (lineBottom - lineTop).toInt() ) { if (!drawVisibleImageOnly && isVisible) { @@ -301,12 +230,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } ?: return val rectF = if (textLine.isImage) { - RectF(textColumn.start, lineTop, textColumn.end, lineBottom) + RectF(column.start, lineTop, column.end, lineBottom) } else { /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/ - val h = (textColumn.end - textColumn.start) / bitmap.width * bitmap.height + val h = (column.end - column.start) / bitmap.width * bitmap.height val div = (lineBottom - lineTop - h) / 2 - RectF(textColumn.start, lineTop + div, textColumn.end, lineBottom - div) + RectF(column.start, lineTop + div, column.end, lineBottom - div) } kotlin.runCatching { canvas.drawBitmap(bitmap, null, rectF, imagePaint) @@ -360,15 +289,15 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at y: Float, select: (textPos: TextPos) -> Unit, ) { - touch(x, y) { _, textPos, _, _, textColumn -> - if (textColumn.style == 2) return@touch - if (textColumn.style == 1) { - callBack.onImageLongPress(x, y, textColumn.charData) - } else { - if (!selectAble) return@touch - textColumn.selected = true - invalidate() - select(textPos) + touch(x, y) { _, textPos, _, _, column -> + when (column) { + is ImageColumn -> callBack.onImageLongPress(x, y, column.src) + is TextColumn -> { + if (!selectAble) return@touch + column.selected = true + invalidate() + select(textPos) + } } } } @@ -379,8 +308,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at */ fun click(x: Float, y: Float): Boolean { var handled = false - touch(x, y) { _, textPos, textPage, textLine, textColumn -> - if (textColumn.style == 2) { + touch(x, y) { _, textPos, textPage, textLine, column -> + if (column is ReviewColumn) { context.toastOnUi("Button Pressed!") handled = true } @@ -396,11 +325,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at y: Float, select: (textPos: TextPos) -> Unit, ) { - touch(x, y) { _, textPos, _, _, textColumn -> - if (textColumn.style == 2) return@touch - textColumn.selected = true - invalidate() - select(textPos) + touch(x, y) { _, textPos, _, _, column -> + if (column is TextColumn) { + column.selected = true + invalidate() + select(textPos) + } } } @@ -450,7 +380,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at textPos: TextPos, textPage: TextPage, textLine: TextLine, - textColumn: TextColumn + column: BaseColumn ) -> Unit ) { if (!visibleRect.contains(x, y)) return @@ -518,13 +448,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at textPos.relativePagePos = relativePos for ((lineIndex, textLine) in relativePage(relativePos).lines.withIndex()) { textPos.lineIndex = lineIndex - for ((charIndex, textColumn) in textLine.columns.withIndex()) { + for ((charIndex, column) in textLine.columns.withIndex()) { textPos.charIndex = charIndex - if (textColumn.style == 2) continue - textColumn.selected = - textPos.compare(selectStart) >= 0 && textPos.compare(selectEnd) <= 0 - textColumn.isSearchResult = - textColumn.selected && callBack.isSelectingSearchResult + if (column is TextColumn) { + column.selected = + textPos.compare(selectStart) >= 0 && textPos.compare(selectEnd) <= 0 + column.isSearchResult = + column.selected && callBack.isSelectingSearchResult + } } } } @@ -544,8 +475,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at for (relativePos in 0..last) { relativePage(relativePos).lines.forEach { textLine -> textLine.columns.forEach { - it.selected = false - if (fromSearchExit) it.isSearchResult = false + if (it is TextColumn) { + it.selected = false + if (fromSearchExit) it.isSearchResult = false + } } } } @@ -561,12 +494,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at textPos.relativePagePos = relativePos textPage.lines.forEachIndexed { lineIndex, textLine -> textPos.lineIndex = lineIndex - textLine.columns.forEachIndexed { charIndex, textColumn -> + textLine.columns.forEachIndexed { charIndex, column -> textPos.charIndex = charIndex val compareStart = textPos.compare(selectStart) val compareEnd = textPos.compare(selectEnd) if (compareStart >= 0 && compareEnd <= 0) { - builder.append(textColumn.charData) + if (column is TextColumn) { + builder.append(column.charData) + } if ( textLine.isParagraphEnd && charIndex == textLine.charSize - 1 diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/BaseColumn.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/BaseColumn.kt new file mode 100644 index 000000000..f67340272 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/BaseColumn.kt @@ -0,0 +1,14 @@ +package io.legado.app.ui.book.read.page.entities + +/** + * 列基类 + */ +interface BaseColumn { + var start: Float + var end: Float + + fun isTouch(x: Float): Boolean { + return x > start && x < end + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/ImageColumn.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/ImageColumn.kt new file mode 100644 index 000000000..19ff8d3e1 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/ImageColumn.kt @@ -0,0 +1,8 @@ +package io.legado.app.ui.book.read.page.entities + +data class ImageColumn( + override var start: Float, + override var end: Float, + var src: String +) : BaseColumn { +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/ReviewColumn.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/ReviewColumn.kt new file mode 100644 index 000000000..a50bf7693 --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/ReviewColumn.kt @@ -0,0 +1,83 @@ +package io.legado.app.ui.book.read.page.entities + +import android.graphics.Canvas +import android.graphics.Paint +import android.text.StaticLayout +import android.text.TextPaint + +data class ReviewColumn( + override var start: Float, + override var end: Float, + var count: Int = 0 +) : BaseColumn { + + fun getCountText(): String { + if (count > 99) { + return "99+" + } + return count.toString() + } + + fun drawToCanvas(canvas: Canvas, paint: Paint, countPaint: TextPaint, y: Float) { + if (count == 0) return + canvas.drawLine( + start, + y - paint.textSize * 2 / 5, + start + paint.textSize / 6, + y - paint.textSize / 4, + paint + ) + canvas.drawLine( + start, + y - paint.textSize * 0.38F, + start + paint.textSize / 6, + y - paint.textSize * 0.55F, + paint + ) + canvas.drawLine( + start + paint.textSize / 6, + y - paint.textSize / 4, + start + paint.textSize / 6, + y, + paint + ) + canvas.drawLine( + start + paint.textSize / 6, + y - paint.textSize * 0.55F, + start + paint.textSize / 6, + y - paint.textSize * 0.8F, + paint + ) + canvas.drawLine( + start + paint.textSize / 6, + y, + start + paint.textSize * 1.6F, + y, + paint + ) + canvas.drawLine( + start + paint.textSize / 6, + y - paint.textSize * 0.8F, + start + paint.textSize * 1.6F, + y - paint.textSize * 0.8F, + paint + ) + canvas.drawLine( + start + paint.textSize * 1.6F, + y - paint.textSize * 0.8F, + start + paint.textSize * 1.6F, + y, + paint + ) + val text = getCountText() + val textWidth = StaticLayout.getDesiredWidth(getCountText(), countPaint) + canvas.drawText( + text, + start + paint.textSize * 0.87F - textWidth / 2, + y - paint.textSize / 6, + countPaint + ) + } + + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextColumn.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextColumn.kt index 82badb33f..45fabe569 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextColumn.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextColumn.kt @@ -4,16 +4,11 @@ package io.legado.app.ui.book.read.page.entities * 字符信息 */ data class TextColumn( + override var start: Float, + override var end: Float, val charData: String, - var start: Float, - var end: Float, - val style: Int = 0, //0:文字,1:图片,2:按钮 var selected: Boolean = false, var isSearchResult: Boolean = false -) { - - fun isTouch(x: Float): Boolean { - return x > start && x < end - } +) : BaseColumn { } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt index f9040423f..c5a1f17f0 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt @@ -10,8 +10,7 @@ import io.legado.app.utils.textHeight @Suppress("unused", "MemberVisibilityCanBePrivate") data class TextLine( var text: String = "", - private val textColumns: ArrayList = arrayListOf(), - val reviewCount: Int = 0, + private val textColumns: ArrayList = arrayListOf(), var lineTop: Float = 0f, var lineBase: Float = 0f, var lineBottom: Float = 0f, @@ -21,22 +20,22 @@ data class TextLine( var isImage: Boolean = false ) { - val columns: List get() = textColumns + val columns: List get() = textColumns val charSize: Int get() = textColumns.size val lineStart: Float get() = textColumns.firstOrNull()?.start ?: 0f val lineEnd: Float get() = textColumns.lastOrNull()?.end ?: 0f - fun addColumn(column: TextColumn) { + fun addColumn(column: BaseColumn) { textColumns.add(column) } - fun getColumn(index: Int): TextColumn { + fun getColumn(index: Int): BaseColumn { return textColumns.getOrElse(index) { textColumns.last() } } - fun getColumnReverseAt(index: Int): TextColumn { + fun getColumnReverseAt(index: Int): BaseColumn { return textColumns[textColumns.lastIndex - index] } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt index b5ee422ca..934021bd4 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt @@ -119,11 +119,7 @@ data class TextPage( val cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint) val x1 = x + cw textLine.addColumn( - TextColumn( - char, - start = x, - end = x1 - ) + TextColumn(start = x, end = x1, char) ) x = x1 } 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 8c518ea44..267cf24a2 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 @@ -13,10 +13,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.model.ReadBook -import io.legado.app.ui.book.read.page.entities.TextChapter -import io.legado.app.ui.book.read.page.entities.TextColumn -import io.legado.app.ui.book.read.page.entities.TextLine -import io.legado.app.ui.book.read.page.entities.TextPage +import io.legado.app.ui.book.read.page.entities.* import io.legado.app.utils.* import splitties.init.appCtx import java.util.* @@ -268,7 +265,7 @@ object ChapterProvider { Pair(0f, width.toFloat()) } textLine.addColumn( - TextColumn(charData = src, start = x + start, end = x + end, style = 1) + ImageColumn(start = x + start, end = x + end, src = src) ) textPages.last().addLine(textLine) } @@ -501,20 +498,27 @@ object ChapterProvider { ImageProvider.cacheImage(book, src, ReadBook.bookSource) textLine.addColumn( TextColumn( - charData = src, start = absStartX + xStart, end = absStartX + xEnd, - style = 1 + charData = src ) ) } else { - textLine.addColumn( + val column = if (isLineEnd && char == reviewChar) { + ReviewColumn( + start = absStartX + xStart, + end = absStartX + xEnd, + count = 1 + ) + } else { TextColumn( - charData = char, start = absStartX + xStart, end = absStartX + xEnd, - style = if (isLineEnd && char == reviewChar) 2 else 0 + charData = char ) + } + textLine.addColumn( + column ) } }