kunfei 4 лет назад
Родитель
Сommit
d2b0aa56e8

+ 48 - 113
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.Canvas
 import android.graphics.Paint
 import android.graphics.Paint
 import android.graphics.RectF
 import android.graphics.RectF
-import android.text.StaticLayout
 import android.text.TextPaint
 import android.text.TextPaint
 import android.util.AttributeSet
 import android.util.AttributeSet
 import android.view.View
 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.help.config.ReadBookConfig
 import io.legado.app.lib.theme.accentColor
 import io.legado.app.lib.theme.accentColor
 import io.legado.app.model.ReadBook
 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.ChapterProvider
 import io.legado.app.ui.book.read.page.provider.ImageProvider
 import io.legado.app.ui.book.read.page.provider.ImageProvider
 import io.legado.app.ui.book.read.page.provider.TextPageFactory
 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.textSize = textPaint.textSize * 0.6F
         reviewCountPaint.color = textColor
         reviewCountPaint.color = textColor
         textLine.columns.forEach {
         textLine.columns.forEach {
-            when (it.style) {
-                0 -> {
+            when (it) {
+                is TextColumn -> {
                     textPaint.color = textColor
                     textPaint.color = textColor
                     if (it.isSearchResult) {
                     if (it.isSearchResult) {
                         textPaint.color = context.accentColor
                         textPaint.color = context.accentColor
                     }
                     }
                     canvas.drawText(it.charData, it.start, lineBase, textPaint)
                     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,
         canvas: Canvas,
         textPage: TextPage,
         textPage: TextPage,
         textLine: TextLine,
         textLine: TextLine,
-        textColumn: TextColumn,
+        column: ImageColumn,
         lineTop: Float,
         lineTop: Float,
         lineBottom: Float
         lineBottom: Float
     ) {
     ) {
@@ -278,7 +207,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
             isVisible &&
             isVisible &&
             !cacheIncreased &&
             !cacheIncreased &&
             ImageProvider.isTriggerRecycled() &&
             ImageProvider.isTriggerRecycled() &&
-            !ImageProvider.isImageAlive(book, textColumn.charData)
+            !ImageProvider.isImageAlive(book, column.src)
         ) {
         ) {
             val newSize = ImageProvider.bitmapLruCache.maxSize() + increaseSize
             val newSize = ImageProvider.bitmapLruCache.maxSize() + increaseSize
             if (newSize < maxCacheSize) {
             if (newSize < maxCacheSize) {
@@ -290,8 +219,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         }
         }
         val bitmap = ImageProvider.getImage(
         val bitmap = ImageProvider.getImage(
             book,
             book,
-            textColumn.charData,
-            (textColumn.end - textColumn.start).toInt(),
+            column.src,
+            (column.end - column.start).toInt(),
             (lineBottom - lineTop).toInt()
             (lineBottom - lineTop).toInt()
         ) {
         ) {
             if (!drawVisibleImageOnly && isVisible) {
             if (!drawVisibleImageOnly && isVisible) {
@@ -301,12 +230,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         } ?: return
         } ?: return
 
 
         val rectF = if (textLine.isImage) {
         val rectF = if (textLine.isImage) {
-            RectF(textColumn.start, lineTop, textColumn.end, lineBottom)
+            RectF(column.start, lineTop, column.end, lineBottom)
         } else {
         } else {
             /*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/
             /*以宽度为基准保持图片的原始比例叠加,当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
             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 {
         kotlin.runCatching {
             canvas.drawBitmap(bitmap, null, rectF, imagePaint)
             canvas.drawBitmap(bitmap, null, rectF, imagePaint)
@@ -360,15 +289,15 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         y: Float,
         y: Float,
         select: (textPos: TextPos) -> Unit,
         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 {
     fun click(x: Float, y: Float): Boolean {
         var handled = false
         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!")
                 context.toastOnUi("Button Pressed!")
                 handled = true
                 handled = true
             }
             }
@@ -396,11 +325,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
         y: Float,
         y: Float,
         select: (textPos: TextPos) -> Unit,
         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,
             textPos: TextPos,
             textPage: TextPage,
             textPage: TextPage,
             textLine: TextLine,
             textLine: TextLine,
-            textColumn: TextColumn
+            column: BaseColumn
         ) -> Unit
         ) -> Unit
     ) {
     ) {
         if (!visibleRect.contains(x, y)) return
         if (!visibleRect.contains(x, y)) return
@@ -518,13 +448,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
             textPos.relativePagePos = relativePos
             textPos.relativePagePos = relativePos
             for ((lineIndex, textLine) in relativePage(relativePos).lines.withIndex()) {
             for ((lineIndex, textLine) in relativePage(relativePos).lines.withIndex()) {
                 textPos.lineIndex = lineIndex
                 textPos.lineIndex = lineIndex
-                for ((charIndex, textColumn) in textLine.columns.withIndex()) {
+                for ((charIndex, column) in textLine.columns.withIndex()) {
                     textPos.charIndex = charIndex
                     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) {
         for (relativePos in 0..last) {
             relativePage(relativePos).lines.forEach { textLine ->
             relativePage(relativePos).lines.forEach { textLine ->
                 textLine.columns.forEach {
                 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
             textPos.relativePagePos = relativePos
             textPage.lines.forEachIndexed { lineIndex, textLine ->
             textPage.lines.forEachIndexed { lineIndex, textLine ->
                 textPos.lineIndex = lineIndex
                 textPos.lineIndex = lineIndex
-                textLine.columns.forEachIndexed { charIndex, textColumn ->
+                textLine.columns.forEachIndexed { charIndex, column ->
                     textPos.charIndex = charIndex
                     textPos.charIndex = charIndex
                     val compareStart = textPos.compare(selectStart)
                     val compareStart = textPos.compare(selectStart)
                     val compareEnd = textPos.compare(selectEnd)
                     val compareEnd = textPos.compare(selectEnd)
                     if (compareStart >= 0 && compareEnd <= 0) {
                     if (compareStart >= 0 && compareEnd <= 0) {
-                        builder.append(textColumn.charData)
+                        if (column is TextColumn) {
+                            builder.append(column.charData)
+                        }
                         if (
                         if (
                             textLine.isParagraphEnd
                             textLine.isParagraphEnd
                             && charIndex == textLine.charSize - 1
                             && charIndex == textLine.charSize - 1

+ 14 - 0
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
+    }
+
+}

+ 8 - 0
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 {
+}

+ 83 - 0
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
+        )
+    }
+
+
+}

+ 3 - 8
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(
 data class TextColumn(
+    override var start: Float,
+    override var end: Float,
     val charData: String,
     val charData: String,
-    var start: Float,
-    var end: Float,
-    val style: Int = 0, //0:文字,1:图片,2:按钮
     var selected: Boolean = false,
     var selected: Boolean = false,
     var isSearchResult: Boolean = false
     var isSearchResult: Boolean = false
-) {
-
-    fun isTouch(x: Float): Boolean {
-        return x > start && x < end
-    }
+) : BaseColumn {
 
 
 }
 }

+ 5 - 6
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")
 @Suppress("unused", "MemberVisibilityCanBePrivate")
 data class TextLine(
 data class TextLine(
     var text: String = "",
     var text: String = "",
-    private val textColumns: ArrayList<TextColumn> = arrayListOf(),
-    val reviewCount: Int = 0,
+    private val textColumns: ArrayList<BaseColumn> = arrayListOf(),
     var lineTop: Float = 0f,
     var lineTop: Float = 0f,
     var lineBase: Float = 0f,
     var lineBase: Float = 0f,
     var lineBottom: Float = 0f,
     var lineBottom: Float = 0f,
@@ -21,22 +20,22 @@ data class TextLine(
     var isImage: Boolean = false
     var isImage: Boolean = false
 ) {
 ) {
 
 
-    val columns: List<TextColumn> get() = textColumns
+    val columns: List<BaseColumn> get() = textColumns
     val charSize: Int get() = textColumns.size
     val charSize: Int get() = textColumns.size
     val lineStart: Float get() = textColumns.firstOrNull()?.start ?: 0f
     val lineStart: Float get() = textColumns.firstOrNull()?.start ?: 0f
     val lineEnd: Float get() = textColumns.lastOrNull()?.end ?: 0f
     val lineEnd: Float get() = textColumns.lastOrNull()?.end ?: 0f
 
 
-    fun addColumn(column: TextColumn) {
+    fun addColumn(column: BaseColumn) {
         textColumns.add(column)
         textColumns.add(column)
     }
     }
 
 
-    fun getColumn(index: Int): TextColumn {
+    fun getColumn(index: Int): BaseColumn {
         return textColumns.getOrElse(index) {
         return textColumns.getOrElse(index) {
             textColumns.last()
             textColumns.last()
         }
         }
     }
     }
 
 
-    fun getColumnReverseAt(index: Int): TextColumn {
+    fun getColumnReverseAt(index: Int): BaseColumn {
         return textColumns[textColumns.lastIndex - index]
         return textColumns[textColumns.lastIndex - index]
     }
     }
 
 

+ 1 - 5
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 cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint)
                     val x1 = x + cw
                     val x1 = x + cw
                     textLine.addColumn(
                     textLine.addColumn(
-                        TextColumn(
-                            char,
-                            start = x,
-                            end = x1
-                        )
+                        TextColumn(start = x, end = x1, char)
                     )
                     )
                     x = x1
                     x = x1
                 }
                 }

+ 14 - 10
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.AppConfig
 import io.legado.app.help.config.ReadBookConfig
 import io.legado.app.help.config.ReadBookConfig
 import io.legado.app.model.ReadBook
 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 io.legado.app.utils.*
 import splitties.init.appCtx
 import splitties.init.appCtx
 import java.util.*
 import java.util.*
@@ -268,7 +265,7 @@ object ChapterProvider {
                 Pair(0f, width.toFloat())
                 Pair(0f, width.toFloat())
             }
             }
             textLine.addColumn(
             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)
             textPages.last().addLine(textLine)
         }
         }
@@ -501,20 +498,27 @@ object ChapterProvider {
             ImageProvider.cacheImage(book, src, ReadBook.bookSource)
             ImageProvider.cacheImage(book, src, ReadBook.bookSource)
             textLine.addColumn(
             textLine.addColumn(
                 TextColumn(
                 TextColumn(
-                    charData = src,
                     start = absStartX + xStart,
                     start = absStartX + xStart,
                     end = absStartX + xEnd,
                     end = absStartX + xEnd,
-                    style = 1
+                    charData = src
                 )
                 )
             )
             )
         } else {
         } else {
-            textLine.addColumn(
+            val column = if (isLineEnd && char == reviewChar) {
+                ReviewColumn(
+                    start = absStartX + xStart,
+                    end = absStartX + xEnd,
+                    count = 1
+                )
+            } else {
                 TextColumn(
                 TextColumn(
-                    charData = char,
                     start = absStartX + xStart,
                     start = absStartX + xStart,
                     end = absStartX + xEnd,
                     end = absStartX + xEnd,
-                    style = if (isLineEnd && char == reviewChar) 2 else 0
+                    charData = char
                 )
                 )
+            }
+            textLine.addColumn(
+                column
             )
             )
         }
         }
     }
     }