mirror of
https://github.com/gedoor/legado.git
synced 2025-08-10 00:52:30 +00:00
@@ -164,7 +164,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
val reviewCountPaint = TextPaint()
|
||||
reviewCountPaint.textSize = textPaint.textSize * 0.6F
|
||||
reviewCountPaint.color = textColor
|
||||
textLine.textChars.forEach {
|
||||
textLine.textColumns.forEach {
|
||||
when (it.style) {
|
||||
0 -> {
|
||||
textPaint.color = textColor
|
||||
@@ -257,7 +257,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
canvas: Canvas,
|
||||
textPage: TextPage,
|
||||
textLine: TextLine,
|
||||
textChar: TextColumn,
|
||||
textColumn: TextColumn,
|
||||
lineTop: Float,
|
||||
lineBottom: Float
|
||||
) {
|
||||
@@ -275,7 +275,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
isVisible &&
|
||||
!cacheIncreased &&
|
||||
ImageProvider.isTriggerRecycled() &&
|
||||
!ImageProvider.isImageAlive(book, textChar.charData)
|
||||
!ImageProvider.isImageAlive(book, textColumn.charData)
|
||||
) {
|
||||
val newSize = ImageProvider.bitmapLruCache.maxSize() + increaseSize
|
||||
if (newSize < maxCacheSize) {
|
||||
@@ -287,8 +287,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
}
|
||||
val bitmap = ImageProvider.getImage(
|
||||
book,
|
||||
textChar.charData,
|
||||
(textChar.end - textChar.start).toInt(),
|
||||
textColumn.charData,
|
||||
(textColumn.end - textColumn.start).toInt(),
|
||||
(lineBottom - lineTop).toInt()
|
||||
) {
|
||||
if (!drawVisibleImageOnly && isVisible) {
|
||||
@@ -298,12 +298,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
} ?: return
|
||||
|
||||
val rectF = if (textLine.isImage) {
|
||||
RectF(textChar.start, lineTop, textChar.end, lineBottom)
|
||||
RectF(textColumn.start, lineTop, textColumn.end, lineBottom)
|
||||
} else {
|
||||
/*以宽度为基准保持图片的原始比例叠加,当div为负数时,允许高度比字符更高*/
|
||||
val h = (textChar.end - textChar.start) / bitmap.width * bitmap.height
|
||||
val h = (textColumn.end - textColumn.start) / bitmap.width * bitmap.height
|
||||
val div = (lineBottom - lineTop - h) / 2
|
||||
RectF(textChar.start, lineTop + div, textChar.end, lineBottom - div)
|
||||
RectF(textColumn.start, lineTop + div, textColumn.end, lineBottom - div)
|
||||
}
|
||||
kotlin.runCatching {
|
||||
canvas.drawBitmap(bitmap, null, rectF, imagePaint)
|
||||
@@ -405,12 +405,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
* 开始选择符移动
|
||||
*/
|
||||
fun selectStartMove(x: Float, y: Float) {
|
||||
touch(x, y) { relativeOffset, textPos, _, textLine, textChar ->
|
||||
touch(x, y) { relativeOffset, textPos, _, textLine, textColumn ->
|
||||
if (selectStart.compare(textPos) != 0) {
|
||||
if (textPos.compare(selectEnd) <= 0) {
|
||||
selectStart.upData(pos = textPos)
|
||||
upSelectedStart(
|
||||
textChar.start,
|
||||
textColumn.start,
|
||||
textLine.lineBottom + relativeOffset,
|
||||
textLine.lineTop + relativeOffset
|
||||
)
|
||||
@@ -424,11 +424,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
* 结束选择符移动
|
||||
*/
|
||||
fun selectEndMove(x: Float, y: Float) {
|
||||
touch(x, y) { relativeOffset, textPos, _, textLine, textChar ->
|
||||
touch(x, y) { relativeOffset, textPos, _, textLine, textColumn ->
|
||||
if (textPos.compare(selectEnd) != 0) {
|
||||
if (textPos.compare(selectStart) >= 0) {
|
||||
selectEnd.upData(textPos)
|
||||
upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset)
|
||||
upSelectedEnd(textColumn.end, textLine.lineBottom + relativeOffset)
|
||||
upSelectChars()
|
||||
}
|
||||
}
|
||||
@@ -462,12 +462,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
val textPage = relativePage(relativePos)
|
||||
for ((lineIndex, textLine) in textPage.textLines.withIndex()) {
|
||||
if (textLine.isTouch(x, y, relativeOffset)) {
|
||||
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
|
||||
if (textChar.isTouch(x)) {
|
||||
for ((charIndex, textColumn) in textLine.textColumns.withIndex()) {
|
||||
if (textColumn.isTouch(x)) {
|
||||
touched.invoke(
|
||||
relativeOffset,
|
||||
TextPos(relativePos, lineIndex, charIndex),
|
||||
textPage, textLine, textChar
|
||||
textPage, textLine, textColumn
|
||||
)
|
||||
return
|
||||
}
|
||||
@@ -486,9 +486,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
selectStart.lineIndex = lineIndex
|
||||
selectStart.charIndex = charIndex
|
||||
val textLine = relativePage(relativePagePos).getLine(lineIndex)
|
||||
val textChar = textLine.getTextChar(charIndex)
|
||||
val textColumn = textLine.getTextColumn(charIndex)
|
||||
upSelectedStart(
|
||||
textChar.start,
|
||||
textColumn.start,
|
||||
textLine.lineBottom + relativeOffset(relativePagePos),
|
||||
textLine.lineTop + relativeOffset(relativePagePos)
|
||||
)
|
||||
@@ -503,8 +503,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
selectEnd.lineIndex = lineIndex
|
||||
selectEnd.charIndex = charIndex
|
||||
val textLine = relativePage(relativePage).getLine(lineIndex)
|
||||
val textChar = textLine.getTextChar(charIndex)
|
||||
upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset(relativePage))
|
||||
val textColumn = textLine.getTextColumn(charIndex)
|
||||
upSelectedEnd(textColumn.end, textLine.lineBottom + relativeOffset(relativePage))
|
||||
upSelectChars()
|
||||
}
|
||||
|
||||
@@ -515,12 +515,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
textPos.relativePagePos = relativePos
|
||||
for ((lineIndex, textLine) in relativePage(relativePos).textLines.withIndex()) {
|
||||
textPos.lineIndex = lineIndex
|
||||
for ((charIndex, textChar) in textLine.textChars.withIndex()) {
|
||||
for ((charIndex, textColumn) in textLine.textColumns.withIndex()) {
|
||||
textPos.charIndex = charIndex
|
||||
if (textChar.style == 2) continue
|
||||
textChar.selected =
|
||||
if (textColumn.style == 2) continue
|
||||
textColumn.selected =
|
||||
textPos.compare(selectStart) >= 0 && textPos.compare(selectEnd) <= 0
|
||||
textChar.isSearchResult = textChar.selected && callBack.isSelectingSearchResult
|
||||
textColumn.isSearchResult = textColumn.selected && callBack.isSelectingSearchResult
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -539,7 +539,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
val last = if (callBack.isScroll) 2 else 0
|
||||
for (relativePos in 0..last) {
|
||||
relativePage(relativePos).textLines.forEach { textLine ->
|
||||
textLine.textChars.forEach {
|
||||
textLine.textColumns.forEach {
|
||||
it.selected = false
|
||||
if (fromSearchExit) it.isSearchResult = false
|
||||
}
|
||||
@@ -557,12 +557,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
|
||||
textPos.relativePagePos = relativePos
|
||||
textPage.textLines.forEachIndexed { lineIndex, textLine ->
|
||||
textPos.lineIndex = lineIndex
|
||||
textLine.textChars.forEachIndexed { charIndex, textChar ->
|
||||
textLine.textColumns.forEachIndexed { charIndex, textColumn ->
|
||||
textPos.charIndex = charIndex
|
||||
val compareStart = textPos.compare(selectStart)
|
||||
val compareEnd = textPos.compare(selectEnd)
|
||||
if (compareStart >= 0 && compareEnd <= 0) {
|
||||
builder.append(textChar.charData)
|
||||
builder.append(textColumn.charData)
|
||||
if (
|
||||
textLine.isParagraphEnd
|
||||
&& charIndex == textLine.charSize - 1
|
||||
|
||||
@@ -10,7 +10,7 @@ import io.legado.app.utils.textHeight
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
data class TextLine(
|
||||
var text: String = "",
|
||||
val textChars: ArrayList<TextColumn> = arrayListOf(),
|
||||
val textColumns: ArrayList<TextColumn> = arrayListOf(),
|
||||
val reviewCount: Int = 0,
|
||||
var lineTop: Float = 0f,
|
||||
var lineBase: Float = 0f,
|
||||
@@ -21,9 +21,9 @@ data class TextLine(
|
||||
var isImage: Boolean = false
|
||||
) {
|
||||
|
||||
val charSize: Int get() = textChars.size
|
||||
val lineStart: Float get() = textChars.firstOrNull()?.start ?: 0f
|
||||
val lineEnd: Float get() = textChars.lastOrNull()?.end ?: 0f
|
||||
val charSize: Int get() = textColumns.size
|
||||
val lineStart: Float get() = textColumns.firstOrNull()?.start ?: 0f
|
||||
val lineEnd: Float get() = textColumns.lastOrNull()?.end ?: 0f
|
||||
|
||||
fun upTopBottom(durY: Float, textPaint: TextPaint) {
|
||||
lineTop = ChapterProvider.paddingTop + durY
|
||||
@@ -31,18 +31,18 @@ data class TextLine(
|
||||
lineBase = lineBottom - textPaint.fontMetrics.descent
|
||||
}
|
||||
|
||||
fun getTextChar(index: Int): TextColumn {
|
||||
return textChars.getOrElse(index) {
|
||||
textChars.last()
|
||||
fun getTextColumn(index: Int): TextColumn {
|
||||
return textColumns.getOrElse(index) {
|
||||
textColumns.last()
|
||||
}
|
||||
}
|
||||
|
||||
fun getTextCharReverseAt(index: Int): TextColumn {
|
||||
return textChars[textChars.lastIndex - index]
|
||||
fun getTextColumnReverseAt(index: Int): TextColumn {
|
||||
return textColumns[textColumns.lastIndex - index]
|
||||
}
|
||||
|
||||
fun getTextCharsCount(): Int {
|
||||
return textChars.size
|
||||
fun getTextColumnsCount(): Int {
|
||||
return textColumns.size
|
||||
}
|
||||
|
||||
fun isTouch(x: Float, y: Float, relativeOffset: Float): Boolean {
|
||||
|
||||
@@ -113,7 +113,7 @@ data class TextPage(
|
||||
val char = textLine.text[i].toString()
|
||||
val cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint)
|
||||
val x1 = x + cw
|
||||
textLine.textChars.add(
|
||||
textLine.textColumns.add(
|
||||
TextColumn(
|
||||
char,
|
||||
start = x,
|
||||
|
||||
@@ -263,7 +263,7 @@ object ChapterProvider {
|
||||
} else {
|
||||
Pair(0f, width.toFloat())
|
||||
}
|
||||
textLine.textChars.add(
|
||||
textLine.textColumns.add(
|
||||
TextColumn(charData = src, start = x + start, end = x + end, style = 1)
|
||||
)
|
||||
textPages.last().textLines.add(textLine)
|
||||
@@ -411,7 +411,7 @@ object ChapterProvider {
|
||||
val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length
|
||||
for (char in bodyIndent.toStringArray()) {
|
||||
val x1 = x + icw
|
||||
textLine.textChars.add(
|
||||
textLine.textColumns.add(
|
||||
TextColumn(
|
||||
charData = char,
|
||||
start = absStartX + x,
|
||||
@@ -495,7 +495,7 @@ object ChapterProvider {
|
||||
if (srcList != null && char == srcReplaceChar) {
|
||||
val src = srcList.removeFirst()
|
||||
ImageProvider.cacheImage(book, src, ReadBook.bookSource)
|
||||
textLine.textChars.add(
|
||||
textLine.textColumns.add(
|
||||
TextColumn(
|
||||
charData = src,
|
||||
start = absStartX + xStart,
|
||||
@@ -504,7 +504,7 @@ object ChapterProvider {
|
||||
)
|
||||
)
|
||||
} else {
|
||||
textLine.textChars.add(
|
||||
textLine.textColumns.add(
|
||||
TextColumn(
|
||||
charData = char,
|
||||
start = absStartX + xStart,
|
||||
@@ -520,11 +520,11 @@ object ChapterProvider {
|
||||
*/
|
||||
private fun exceed(absStartX: Int, textLine: TextLine, words: Array<String>) {
|
||||
val visibleEnd = absStartX + visibleWidth
|
||||
val endX = textLine.textChars.lastOrNull()?.end ?: return
|
||||
val endX = textLine.textColumns.lastOrNull()?.end ?: return
|
||||
if (endX > visibleEnd) {
|
||||
val cc = (endX - visibleEnd) / words.size
|
||||
for (i in 0..words.lastIndex) {
|
||||
textLine.getTextCharReverseAt(i).let {
|
||||
textLine.getTextColumnReverseAt(i).let {
|
||||
val py = cc * (words.size - i)
|
||||
it.start = it.start - py
|
||||
it.end = it.end - py
|
||||
|
||||
Reference in New Issue
Block a user