MohamedRejeb / compose-rich-editor

A Rich text editor library for both Jetpack Compose and Compose Multiplatform, fully customizable, supports HTML and Markdown.
https://mohamedrejeb.github.io/compose-rich-editor/
Apache License 2.0
1.17k stars 76 forks source link

TextMeasurer return wrong lineCount for RichTextState.setHtml('<p>ABC</p><br>') #387

Open XJianfei opened 1 month ago

XJianfei commented 1 month ago

After fixed #355 , the lineCount still wrong. The code like this:

    val state = rememberRichTextState()
    val tm = rememberTextMeasurer()
    LaunchedEffect(Unit) {
        state.setHtml("<p>ABC</p>")
        println("state: ${state.toHtml()}")
        var annotatedString = state.annotatedString
        var textContentLayout = tm.measure(
            text = annotatedString,
            style = cardTextStyle,
            constraints = Constraints(0, 1000, 0, Constraints.Infinity),
            overflow = TextOverflow.Clip,
        )
        println("A lineCount=${textContentLayout?.lineCount}")  // lineCount=1

        state.setHtml("<p>ABC</p><br>")
        println("state: ${state.toHtml()}")
        annotatedString = state.annotatedString
        textContentLayout = tm.measure(
            text = annotatedString,
            style = cardTextStyle,
            constraints = Constraints(0, 1000, 0, Constraints.Infinity),
            overflow = TextOverflow.Clip,
        )
        println("B lineCount=${textContentLayout?.lineCount}")       // lineCount=3
    }

The output is

state: <p>ABC</p>
A lineCount=1
state: <p>ABC</p><br>
B lineCount=3
MohamedRejeb commented 1 month ago

I think if you try adding some text, it will be more clear.

state: <p>ABC</p>Test A lineCount=2 state: <p>ABC</p>Test1<br>Test2 B lineCount=3

Also, if you set this HTML to add a RichTextState <p>ABC</p><br> and then try to change the RichTextState back to HTML you will get the exact same HTML data <p>ABC</p><br>.

MohamedRejeb commented 1 month ago

The second line is coming from the closing of the p tag, and the third line is coming from the br tag. That's the exact result that you will get if you try that HTML in the browser.

XJianfei commented 1 month ago

I try the code as below, and after type 'ABC',
It show 'state lineCount=2', but 'state2 lineCount=3',

state2 is setHtml from state.toHtml

val state = rememberRichTextState()
        val textMeasurer = rememberTextMeasurer()
        BasicRichTextEditor(
            state = state,
            onTextLayout = { layout ->
                println("html: ${state.toHtml()}")

                var annotatedString = state.annotatedString
                val textStyle = TextStyle()
                var textLayout = textMeasurer.measure(
                    text = annotatedString,
                    style = textStyle,
                    constraints = Constraints(0, 1000, 0, Constraints.Infinity),
                    overflow = TextOverflow.Clip,
                )
                println("state lineCount=${textLayout.lineCount}, ${layout.lineCount}")

                val state2 = RichTextState()
                state2.setHtml(state.toHtml())
                annotatedString = state2.annotatedString
                textLayout = textMeasurer.measure(
                    text = annotatedString,
                    style = textStyle,
                    constraints = Constraints(0, 1000, 0, Constraints.Infinity),
                    overflow = TextOverflow.Clip,
                )
                println("state2 lineCount=${textLayout.lineCount}")
            },
        )
XJianfei commented 1 month ago

And after type 'AB' the BasicRichTextEditor in Screen, only show 2 line.

image