|
|
@@ -2,6 +2,7 @@ package io.legado.app.feature.reader.core.layout
|
|
|
|
|
|
import org.junit.Assert.assertArrayEquals
|
|
|
import org.junit.Assert.assertEquals
|
|
|
+import org.junit.Assert.assertFalse
|
|
|
import org.junit.Test
|
|
|
|
|
|
class ChineseLineBreakerTest {
|
|
|
@@ -135,4 +136,60 @@ class ChineseLineBreakerTest {
|
|
|
assertArrayEquals(intArrayOf(0, 2, 4, 5, 7), result.lineStarts)
|
|
|
assertArrayEquals(floatArrayOf(20f, 20f, 10f, 20f), result.lineWidthsPx, 0f)
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 超长 Latin 单词前有正文时:先整体移到下一行,再在下一行按字符回退。上一行因此变短,
|
|
|
+ * 这是浏览器 `overflow-wrap: break-word` 的同类行为,锁住以免被当成回退。
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ fun overlongLatinWordAfterTextMovesDownThenBreaksByCharacter() {
|
|
|
+ val result = breakText("aa supercalifragilistic".map(Char::toString), 80)
|
|
|
+
|
|
|
+ assertArrayEquals(intArrayOf(0, 3, 11, 19, 23), result.lineStarts)
|
|
|
+ assertArrayEquals(floatArrayOf(30f, 80f, 80f, 40f), result.lineWidthsPx, 0f)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Latin 词边界回退不得制造避头尾违规:词首前是开引号/开括号时(`isForbiddenBreak` 判定
|
|
|
+ * 非法),必须退回原有断点,否则开标点会落到行尾。
|
|
|
+ */
|
|
|
+ @Test
|
|
|
+ fun latinRewindNeverProducesForbiddenBreak() {
|
|
|
+ val texts = listOf(
|
|
|
+ "aa “word”",
|
|
|
+ "中文“English”中文",
|
|
|
+ "中文(English)中文",
|
|
|
+ "中文「English」中文",
|
|
|
+ "aa (word) bb",
|
|
|
+ "aa 中文“word”",
|
|
|
+ "请阅读“README.md”文件中的说明。",
|
|
|
+ "他打开“Settings”面板,然后点击“About”。",
|
|
|
+ "这本书引用了《The Great Gatsby》里的一句话。",
|
|
|
+ )
|
|
|
+ texts.forEach { text ->
|
|
|
+ val clusters = text.map(Char::toString)
|
|
|
+ listOf(40, 60, 80, 100).forEach { limit ->
|
|
|
+ val starts = breakText(clusters, limit).lineStarts
|
|
|
+ for (index in 1 until starts.size - 1) {
|
|
|
+ assertFalse(
|
|
|
+ "「$text」limit=$limit 断点非法:" +
|
|
|
+ "行尾「${clusters[starts[index] - 1]}」/ 行首「${clusters[starts[index]]}」",
|
|
|
+ ChineseLineBreaker.isForbiddenBreak(
|
|
|
+ clusters[starts[index] - 1],
|
|
|
+ clusters[starts[index]],
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 安全回退生效时,原有的 Latin 整词换行收益必须保留。 */
|
|
|
+ @Test
|
|
|
+ fun latinWordBoundaryStillKeepsWordsIntactWithoutOpeningMark() {
|
|
|
+ val result = breakText("中文English中文".map(Char::toString), 80)
|
|
|
+
|
|
|
+ assertArrayEquals(intArrayOf(0, 2, 10, 11), result.lineStarts)
|
|
|
+ assertArrayEquals(floatArrayOf(20f, 80f, 10f), result.lineWidthsPx, 0f)
|
|
|
+ }
|
|
|
}
|