feat: 优化代码

pull/120/head
kunfei 5 years ago
parent 20486e7852
commit 6cc2e8b140
  1. 172
      app/src/main/java/io/legado/app/ui/book/read/page/ChapterProvider.kt
  2. 4
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt
  3. 8
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt
  4. 12
      app/src/main/java/io/legado/app/utils/StringExtensions.kt

@ -12,7 +12,6 @@ import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.ui.book.read.page.entities.TextChapter
import io.legado.app.ui.book.read.page.entities.TextChar
import io.legado.app.ui.book.read.page.entities.TextLine 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.TextPage
import io.legado.app.utils.dp import io.legado.app.utils.dp
@ -148,40 +147,13 @@ object ChapterProvider {
textLine.text = words textLine.text = words
val desiredWidth = layout.getLineWidth(lineIndex) val desiredWidth = layout.getLineWidth(lineIndex)
if (lineIndex != layout.lineCount - 1) { if (lineIndex != layout.lineCount - 1) {
val gapCount: Int = words.length - 1 addCharsToLineMiddle(textLine, words, titlePaint, desiredWidth, 0f)
val d = (visibleWidth - desiredWidth) / gapCount
var x = 0f
for (i in words.indices) {
val char = words[i].toString()
val cw = StaticLayout.getDesiredWidth(char, titlePaint)
val x1 = if (i != words.lastIndex) (x + cw + d) else (x + cw)
val textChar = TextChar(
charData = char,
start = paddingLeft + x,
end = paddingLeft + x1
)
textLine.textChars.add(textChar)
x = x1
}
} else { } else {
//最后一行 //最后一行
textLine.text = "$words\n" val x = if (ReadBookConfig.titleCenter)
stringBuilder.append("\n")
var x = if (ReadBookConfig.titleCenter)
(visibleWidth - layout.getLineWidth(lineIndex)) / 2 (visibleWidth - layout.getLineWidth(lineIndex)) / 2
else 0f else 0f
for (i in words.indices) { addCharsToLineLast(textLine, words, stringBuilder, titlePaint, x)
val char = words[i].toString()
val cw = StaticLayout.getDesiredWidth(char, titlePaint)
val x1 = x + cw
val textChar = TextChar(
charData = char,
start = paddingLeft + x,
end = paddingLeft + x1
)
textLine.textChars.add(textChar)
x = x1
}
} }
} }
durY += paragraphSpacing durY += paragraphSpacing
@ -225,80 +197,102 @@ object ChapterProvider {
textLine.lineBase = (paddingTop + durY - textLine.lineBase = (paddingTop + durY -
(layout.getLineBottom(lineIndex) - layout.getLineBaseline(lineIndex))).toFloat() (layout.getLineBottom(lineIndex) - layout.getLineBaseline(lineIndex))).toFloat()
textLine.lineBottom = textLine.lineBase + contentPaint.fontMetrics.descent textLine.lineBottom = textLine.lineBase + contentPaint.fontMetrics.descent
var words = val words =
text.substring(layout.getLineStart(lineIndex), layout.getLineEnd(lineIndex)) text.substring(layout.getLineStart(lineIndex), layout.getLineEnd(lineIndex))
stringBuilder.append(words) stringBuilder.append(words)
textLine.text = words textLine.text = words
val desiredWidth = layout.getLineWidth(lineIndex) val desiredWidth = layout.getLineWidth(lineIndex)
if (lineIndex == 0 && layout.lineCount > 1) { if (lineIndex == 0 && layout.lineCount > 1) {
//第一行 //第一行
var x = 0f addCharsToLineFirst(textLine, words, contentPaint, desiredWidth)
val icw = StaticLayout.getDesiredWidth(bodyIndent, contentPaint) / bodyIndent.length
for (i in 0..bodyIndent.lastIndex) {
val x1 = x + icw
val textChar = TextChar(
charData = bodyIndent[i].toString(),
start = paddingLeft + x,
end = paddingLeft + x1
)
textLine.textChars.add(textChar)
x = x1
}
words = words.replaceFirst(bodyIndent, "")
val gapCount: Int = words.length - 1
val d = (visibleWidth - desiredWidth) / gapCount
for (i in words.indices) {
val char = words[i].toString()
val cw = StaticLayout.getDesiredWidth(char, contentPaint)
val x1 = if (i != words.lastIndex) x + cw + d else x + cw
val textChar1 = TextChar(
charData = char,
start = paddingLeft + x,
end = paddingLeft + x1
)
textLine.textChars.add(textChar1)
x = x1
}
} else if (lineIndex == layout.lineCount - 1) { } else if (lineIndex == layout.lineCount - 1) {
//最后一行 //最后一行
stringBuilder.append("\n") addCharsToLineLast(textLine, words, stringBuilder, contentPaint, 0f)
textLine.text = "$words\n"
var x = 0f
for (i in words.indices) {
val char = words[i].toString()
val cw = StaticLayout.getDesiredWidth(char, contentPaint)
val x1 = x + cw
val textChar = TextChar(
charData = char,
start = paddingLeft + x,
end = paddingLeft + x1
)
textLine.textChars.add(textChar)
x = x1
}
} else { } else {
//中间行 //中间行
val gapCount: Int = words.length - 1 addCharsToLineMiddle(textLine, words, contentPaint, desiredWidth, 0f)
val d = (visibleWidth - desiredWidth) / gapCount
var x = 0f
for (i in words.indices) {
val char = words[i].toString()
val cw = StaticLayout.getDesiredWidth(char, contentPaint)
val x1 = if (i != words.lastIndex) x + cw + d else x + cw
val textChar = TextChar(
charData = char,
start = paddingLeft + x,
end = paddingLeft + x1
)
textLine.textChars.add(textChar)
x = x1
}
} }
} }
durY += paragraphSpacing durY += paragraphSpacing
return durY return durY
} }
/**
* 有缩进,两端对齐
*/
private fun addCharsToLineFirst(
textLine: TextLine,
words: String,
textPaint: TextPaint,
desiredWidth: Float
) {
var x = 0f
val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length
for (i in 0..bodyIndent.lastIndex) {
val x1 = x + icw
textLine.addTextChar(
charData = bodyIndent[i].toString(),
start = paddingLeft + x,
end = paddingLeft + x1
)
x = x1
}
val words1 = words.replaceFirst(bodyIndent, "")
addCharsToLineMiddle(textLine, words1, textPaint, desiredWidth, x)
}
/**
* 无缩进,两端对齐
*/
private fun addCharsToLineMiddle(
textLine: TextLine,
words: String,
textPaint: TextPaint,
desiredWidth: Float,
startX: Float
) {
val gapCount: Int = words.length - 1
val d = (visibleWidth - desiredWidth) / gapCount
var x = startX
for (i in words.indices) {
val char = words[i]
val cw = StaticLayout.getDesiredWidth(char.toString(), textPaint)
val x1 = if (i != words.lastIndex) (x + cw + d) else (x + cw)
textLine.addTextChar(
charData = char.toString(),
start = paddingLeft + x,
end = paddingLeft + x1
)
x = x1
}
}
/**
* 最后一行,自然排列
*/
private fun addCharsToLineLast(
textLine: TextLine,
words: String,
stringBuilder: StringBuilder,
textPaint: TextPaint,
startX: Float
) {
stringBuilder.append("\n")
textLine.text = "$words\n"
var x = startX
for (i in words.indices) {
val char = words[i].toString()
val cw = StaticLayout.getDesiredWidth(char, textPaint)
val x1 = x + cw
textLine.addTextChar(
charData = char,
start = paddingLeft + x,
end = paddingLeft + x1
)
x = x1
}
}
/** /**
* 更新样式 * 更新样式

@ -2,7 +2,7 @@ package io.legado.app.ui.book.read.page.entities
data class TextChar( data class TextChar(
val charData: String, val charData: String,
var selected: Boolean = false,
val start: Float, val start: Float,
val end: Float val end: Float,
var selected: Boolean = false
) )

@ -8,4 +8,10 @@ data class TextLine(
var lineBottom: Float = 0f, var lineBottom: Float = 0f,
val isTitle: Boolean = false, val isTitle: Boolean = false,
var isReadAloud: Boolean = false var isReadAloud: Boolean = false
) ) {
fun addTextChar(charData: String, start: Float, end: Float) {
textChars.add(TextChar(charData, start = start, end = end))
}
}

@ -48,4 +48,14 @@ fun String.splitNotBlank(regex: Regex, limit: Int = 0): Array<String> = run {
this.split(regex, limit).map { it.trim() }.filterNot { it.isBlank() }.toTypedArray() this.split(regex, limit).map { it.trim() }.filterNot { it.isBlank() }.toTypedArray()
} }
fun Char?.isHAN(): Boolean {
this ?: return false
val ub: Character.UnicodeBlock = Character.UnicodeBlock.of(this) ?: return false
return ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
|| ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C
|| ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D
|| ub === Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub === Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT
}

Loading…
Cancel
Save