|
|
@@ -22,6 +22,7 @@ import io.legado.app.ui.book.read.page.api.DataSource
|
|
|
import io.legado.app.ui.book.read.page.delegate.*
|
|
|
import io.legado.app.ui.book.read.page.entities.PageDirection
|
|
|
import io.legado.app.ui.book.read.page.entities.TextChapter
|
|
|
+import io.legado.app.ui.book.read.page.entities.TextPos
|
|
|
import io.legado.app.ui.book.read.page.provider.ChapterProvider
|
|
|
import io.legado.app.ui.book.read.page.provider.TextPageFactory
|
|
|
import io.legado.app.utils.activity
|
|
|
@@ -76,9 +77,7 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
|
|
}
|
|
|
var isTextSelected = false
|
|
|
private var pressOnTextSelected = false
|
|
|
- private var firstRelativePage = 0
|
|
|
- private var firstLineIndex: Int = 0
|
|
|
- private var firstCharIndex: Int = 0
|
|
|
+ private val initialTextPos = TextPos(0, 0, 0)
|
|
|
|
|
|
val slopSquare by lazy { ViewConfiguration.get(context).scaledTouchSlop }
|
|
|
private val tlRect = RectF()
|
|
|
@@ -275,106 +274,73 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
|
|
*/
|
|
|
private fun onLongPress() {
|
|
|
kotlin.runCatching {
|
|
|
- curPage.selectText(startX, startY) { relativePage, lineIndex, charIndex ->
|
|
|
+ curPage.selectText(startX, startY) { relativePos, lineIndex, charIndex ->
|
|
|
isTextSelected = true
|
|
|
- firstRelativePage = relativePage
|
|
|
- firstLineIndex = lineIndex
|
|
|
- firstCharIndex = charIndex
|
|
|
- val page = curPage.relativePage(relativePage)
|
|
|
- with(page) {
|
|
|
- var lineStart = lineIndex
|
|
|
- var lineEnd = lineIndex
|
|
|
- var start: Int
|
|
|
- var end: Int
|
|
|
- if (lineIndex - 1 > 0 && lineIndex + 1 < lineSize) {
|
|
|
- // 中间行
|
|
|
- val lineText = with(textLines) {
|
|
|
- get(lineIndex - 1).text + get(lineIndex).text + get(lineIndex + 1).text
|
|
|
- }
|
|
|
- boundary.setText(lineText)
|
|
|
- start = boundary.first()
|
|
|
- end = boundary.next()
|
|
|
- val cIndex = textLines[lineIndex - 1].text.length + charIndex
|
|
|
- while (end != BreakIterator.DONE) {
|
|
|
- if (cIndex in start until end) {
|
|
|
- break
|
|
|
- }
|
|
|
- start = end
|
|
|
- end = boundary.next()
|
|
|
- }
|
|
|
- if (start < textLines[lineIndex - 1].text.length) {
|
|
|
- lineStart = lineIndex - 1
|
|
|
- } else {
|
|
|
- start -= textLines[lineIndex - 1].text.length
|
|
|
- }
|
|
|
- if (end > textLines[lineIndex - 1].text.length + textLines[lineIndex].text.length) {
|
|
|
- lineEnd = lineIndex + 1
|
|
|
- end = (end - textLines[lineIndex - 1].text.length
|
|
|
- - textLines[lineIndex].text.length)
|
|
|
- } else {
|
|
|
- end = end - textLines[lineIndex - 1].text.length - 1
|
|
|
- }
|
|
|
- } else if (lineIndex - 1 > 0) {
|
|
|
- // 尾行
|
|
|
- val lineText = with(textLines) {
|
|
|
- get(lineIndex - 1).text + get(lineIndex).text
|
|
|
- }
|
|
|
- boundary.setText(lineText)
|
|
|
- start = boundary.first()
|
|
|
- end = boundary.next()
|
|
|
- val cIndex = textLines[lineIndex - 1].text.length + charIndex
|
|
|
- while (end != BreakIterator.DONE) {
|
|
|
- if (cIndex in start until end) {
|
|
|
- break
|
|
|
- }
|
|
|
- start = end
|
|
|
- end = boundary.next()
|
|
|
- }
|
|
|
- if (start < textLines[lineIndex - 1].text.length) {
|
|
|
- lineStart = lineIndex - 1
|
|
|
- } else {
|
|
|
- start -= textLines[lineIndex - 1].text.length
|
|
|
- }
|
|
|
- end = end - textLines[lineIndex - 1].text.length - 1
|
|
|
- } else if (lineIndex + 1 < lineSize) {
|
|
|
- // 首行
|
|
|
- val lineText = with(textLines) {
|
|
|
- get(lineIndex).text + get(lineIndex + 1).text
|
|
|
- }
|
|
|
- boundary.setText(lineText)
|
|
|
- start = boundary.first()
|
|
|
- end = boundary.next()
|
|
|
- while (end != BreakIterator.DONE) {
|
|
|
- if (charIndex in start until end) {
|
|
|
- break
|
|
|
- }
|
|
|
- start = end
|
|
|
- end = boundary.next()
|
|
|
- }
|
|
|
- if (end > textLines[lineIndex].text.length) {
|
|
|
- lineEnd = lineIndex + 1
|
|
|
- end -= textLines[lineIndex].text.length
|
|
|
- } else {
|
|
|
- end -= 1
|
|
|
- }
|
|
|
+ initialTextPos.upData(relativePos, lineIndex, charIndex)
|
|
|
+ val startPos = TextPos(relativePos, lineIndex, charIndex)
|
|
|
+ val endPos = TextPos(relativePos, lineIndex, charIndex)
|
|
|
+ val page = curPage.relativePage(relativePos)
|
|
|
+ val stringBuilder = StringBuilder()
|
|
|
+ var cIndex = charIndex
|
|
|
+ var lineStart = lineIndex
|
|
|
+ var lineEnd = lineIndex
|
|
|
+ for (index in lineIndex - 1 downTo 0) {
|
|
|
+ val textLine = page.getLine(index)
|
|
|
+ if (textLine.isLastLine) {
|
|
|
+ break
|
|
|
} else {
|
|
|
- // 单行
|
|
|
- val lineText = textLines[lineIndex].text
|
|
|
- boundary.setText(lineText)
|
|
|
- start = boundary.first()
|
|
|
- end = boundary.next()
|
|
|
- while (end != BreakIterator.DONE) {
|
|
|
- if (charIndex in start until end) {
|
|
|
- break
|
|
|
+ stringBuilder.insert(0, textLine.text)
|
|
|
+ lineStart -= 1
|
|
|
+ cIndex += textLine.charSize
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (index in lineIndex until page.lineSize) {
|
|
|
+ val textLine = page.getLine(index)
|
|
|
+ stringBuilder.append(textLine.text)
|
|
|
+ lineEnd += 1
|
|
|
+ if (textLine.isLastLine) {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var start: Int
|
|
|
+ var end: Int
|
|
|
+ boundary.setText(stringBuilder.toString())
|
|
|
+ start = boundary.first()
|
|
|
+ end = boundary.next()
|
|
|
+ while (end != BreakIterator.DONE) {
|
|
|
+ if (cIndex in start until end) {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ start = end
|
|
|
+ end = boundary.next()
|
|
|
+ }
|
|
|
+ kotlin.run {
|
|
|
+ var ci = 0
|
|
|
+ for (index in lineStart..lineEnd) {
|
|
|
+ val textLine = page.getLine(index)
|
|
|
+ for (j in 0 until textLine.charSize) {
|
|
|
+ if (ci == start) {
|
|
|
+ startPos.lineIndex = index
|
|
|
+ startPos.charIndex = j
|
|
|
+ } else if (ci == end) {
|
|
|
+ endPos.lineIndex = index
|
|
|
+ endPos.charIndex = j - 1
|
|
|
+ return@run
|
|
|
}
|
|
|
- start = end
|
|
|
- end = boundary.next()
|
|
|
+ ci++
|
|
|
}
|
|
|
- end -= 1
|
|
|
}
|
|
|
- curPage.selectStartMoveIndex(firstRelativePage, lineStart, start)
|
|
|
- curPage.selectEndMoveIndex(firstRelativePage, lineEnd, end)
|
|
|
}
|
|
|
+ curPage.selectStartMoveIndex(
|
|
|
+ startPos.relativePagePos,
|
|
|
+ startPos.lineIndex,
|
|
|
+ startPos.charIndex
|
|
|
+ )
|
|
|
+ curPage.selectEndMoveIndex(
|
|
|
+ endPos.relativePagePos,
|
|
|
+ endPos.lineIndex,
|
|
|
+ endPos.charIndex
|
|
|
+ )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -431,31 +397,24 @@ class ReadView(context: Context, attrs: AttributeSet) :
|
|
|
* 选择文本
|
|
|
*/
|
|
|
private fun selectText(x: Float, y: Float) {
|
|
|
- curPage.selectText(x, y) { relativePage, lineIndex, charIndex ->
|
|
|
+ curPage.selectText(x, y) { relativePagePos, lineIndex, charIndex ->
|
|
|
+ val compare = initialTextPos.compare(relativePagePos, lineIndex, charIndex)
|
|
|
when {
|
|
|
- relativePage > firstRelativePage -> {
|
|
|
- curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
|
- curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
|
|
|
- }
|
|
|
- relativePage < firstRelativePage -> {
|
|
|
- curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
|
- curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
|
|
|
- }
|
|
|
- lineIndex > firstLineIndex -> {
|
|
|
- curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
|
- curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
|
|
|
- }
|
|
|
- lineIndex < firstLineIndex -> {
|
|
|
- curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
|
- curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
|
|
|
- }
|
|
|
- charIndex > firstCharIndex -> {
|
|
|
- curPage.selectStartMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
|
- curPage.selectEndMoveIndex(relativePage, lineIndex, charIndex)
|
|
|
+ compare >= 0 -> {
|
|
|
+ curPage.selectStartMoveIndex(relativePagePos, lineIndex, charIndex)
|
|
|
+ curPage.selectEndMoveIndex(
|
|
|
+ initialTextPos.relativePagePos,
|
|
|
+ initialTextPos.lineIndex,
|
|
|
+ initialTextPos.charIndex
|
|
|
+ )
|
|
|
}
|
|
|
else -> {
|
|
|
- curPage.selectEndMoveIndex(firstRelativePage, firstLineIndex, firstCharIndex)
|
|
|
- curPage.selectStartMoveIndex(relativePage, lineIndex, charIndex)
|
|
|
+ curPage.selectStartMoveIndex(
|
|
|
+ initialTextPos.relativePagePos,
|
|
|
+ initialTextPos.lineIndex,
|
|
|
+ initialTextPos.charIndex
|
|
|
+ )
|
|
|
+ curPage.selectEndMoveIndex(relativePagePos, lineIndex, charIndex)
|
|
|
}
|
|
|
}
|
|
|
}
|