bugfix: fix indent issues.

This commit is contained in:
cgspine
2022-03-01 16:10:02 +08:00
parent 978b184d61
commit 273495295b
3 changed files with 49 additions and 43 deletions
@@ -212,7 +212,7 @@ class QDQQFaceUsageFragment : BaseFragment() {
mLineType2!!.text = content2
val pairs = arrayListOf<Pair<Int, Int>>()
val pattern = Pattern.compile("([a-z]\\.)")
val pattern = Pattern.compile("([a-z]+\\.)")
val matcher = pattern.matcher(content2)
while (matcher.find()){
pairs.add(matcher.start() to matcher.end() - 1)
@@ -3,53 +3,55 @@ package com.qmuiteam.qmui.type
import com.qmuiteam.qmui.type.element.Element
interface LineIndentHandler {
fun getIndent(typeModel: TypeModel, firstElement: Element): Int
fun reset()
fun processIndent(typeModel: TypeModel, firstElement: Element, newParagraph: Boolean): Int
}
class SerialLineIndentHandler(serials: List<Pair<Int, Int>>): LineIndentHandler {
class SerialLineIndentHandler(
serials: List<Pair<Int, Int>>,
private val followIndentForNewParagraphIfNeeded: Boolean = false): LineIndentHandler {
private val sorted = serials.sortedBy {
it.first
}
var prevIndexCache = -1
var currentIntend = 0
private var pendingCalculatePair: Pair<Int, Int>? = null
var nextIndex = 0
override fun getIndent(typeModel: TypeModel, firstElement: Element): Int {
if(sorted.isEmpty()){
return 0
}
if(prevIndexCache >= 0 && firstElement.index > prevIndexCache){
// check fast path
if(prevIndexCache == sorted.size - 1 || sorted[prevIndexCache + 1].first > firstElement.index){
return calculateIndent(typeModel, firstElement, prevIndexCache)
} else if(prevIndexCache + 1 == sorted.size - 1 || sorted[prevIndexCache + 2].first > firstElement.index) {
prevIndexCache += 1
return calculateIndent(typeModel, firstElement, prevIndexCache)
}else{
prevIndexCache = -1
}
}
val nextIndex = sorted.indexOfFirst { it.first > firstElement.index }
if(nextIndex == 0){
return 0
}
val prevIndex = if(nextIndex < 0) sorted.size - 1 else nextIndex - 1
prevIndexCache = prevIndex
return calculateIndent(typeModel, firstElement, prevIndex)
override fun reset() {
currentIntend = 0
nextIndex = 0
}
private fun calculateIndent(typeModel: TypeModel, firstElement: Element, index: Int): Int{
val cur = sorted[index]
if(firstElement.index <= cur.second){
return 0
override fun processIndent(typeModel: TypeModel, firstElement: Element, newParagraph: Boolean): Int {
if(newParagraph){
val pair = sorted.find { it.first == firstElement.index }
if(pair != null){
currentIntend = 0
}else if(!followIndentForNewParagraphIfNeeded){
currentIntend = 0
} else {
// make sure it's calculated.
pendingCalculatePair?.let {
var indent = 0
for(i in it.first until it.second + 1){
indent += typeModel[i]?.measureWidth ?: 0
}
currentIntend = indent
}
}
pendingCalculatePair = pair
}else{
pendingCalculatePair?.let {
var indent = 0
for(i in it.first until it.second + 1){
indent += typeModel[i]?.measureWidth ?: 0
}
currentIntend = indent
}
pendingCalculatePair = null
}
var indent = 0
for(i in cur.first until cur.second + 1){
indent += typeModel[i]?.measureWidth ?: 0
}
return indent
return currentIntend
}
}
@@ -58,13 +58,14 @@ class LineLayout {
exactlyHeightMaxLine = Int.MAX_VALUE
env.clear()
release()
lineIndentHandler?.reset()
if (typeModel == null) {
return
}
var element: Element? = typeModel!!.firstElement()
var line = Line.acquire()
var y = 0
val indent = element?.let { lineIndentHandler?.getIndent(typeModel!!, it) } ?: 0
val indent = element?.let { lineIndentHandler?.processIndent(typeModel!!, it, true) } ?: 0
line.init(indent, y, env.widthLimit - indent)
fun addLineAndHandleMaxLineAndNextY(line: Line, isParagraphEndLine: Boolean){
@@ -94,13 +95,15 @@ class LineLayout {
addLineAndHandleMaxLineAndNextY(line, true)
if (canInterrupt()) {
handleEllipse(env,true)
totalLineCount = mLines.size
return
}
line = createNewLine(env, element.next, y)
line = createNewLine(env, element.next, y, true)
} else if (line.contentWidth + element.measureWidth >= line.widthLimit) {
if (mLines.size == 0 && line.size == 0) {
// the width is too small.
line.release()
totalLineCount = mLines.size
return
}
val back = line.handleWordBreak(env, shouldHandleWordBreak)
@@ -108,11 +111,12 @@ class LineLayout {
addLineAndHandleMaxLineAndNextY(line, false)
if (canInterrupt()) {
totalLineCount = mLines.size
handleEllipse(env,true)
return
}
line = createNewLine(env, back?.firstOrNull() ?: element, y)
line = createNewLine(env, back?.firstOrNull() ?: element, y, false)
if (back != null && back.isNotEmpty()) {
for (el in back) {
line.add(el)
@@ -144,9 +148,9 @@ class LineLayout {
}
}
private fun createNewLine(env: TypeEnvironment, firstElement: Element?, y: Int): Line {
private fun createNewLine(env: TypeEnvironment, firstElement: Element?, y: Int, newParagraph: Boolean): Line {
val line = Line.acquire()
val indent = firstElement?.let { lineIndentHandler?.getIndent(typeModel!!, it) } ?: 0
val indent = firstElement?.let { lineIndentHandler?.processIndent(typeModel!!, it, newParagraph) } ?: 0
line.init(indent, y, env.widthLimit - indent)
return line
}