Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextLayoutResult#getLineForOffset is too slow #4021

Closed
sunny-chung opened this issue Dec 9, 2023 · 2 comments · Fixed by JetBrains/compose-multiplatform-core#934
Closed
Assignees

Comments

@sunny-chung
Copy link

sunny-chung commented Dec 9, 2023

Describe the problem
TextLayoutResult#getLineForOffset is too slow. I looked at source code, linear search is performed in the class SkiaParagraph. It can be optimized by using binary search.

Affected platforms

  • Desktop
    I only tried on Desktop.

If the problem is Android-only, report it in the Jetpack Compose tracker

Versions

  • Kotlin version: 1.8.0
  • Compose Multiplatform version: 1.5.11
  • OS version(s) (required for Desktop and iOS issues): macOS 14.0 Beta
  • OS architecture (x86 or arm64): arm64
  • JDK (for desktop issues): 17

Sample code

@Composable
fun App() {
    val text = remember { "Super long text\n".repeat(10000) }
    val scrollState = rememberScrollState()

    Box {
        BasicTextField(
            value = text,
            onValueChange = {},
            onTextLayout = { textLayoutResult ->
                val lineOffsets = listOf(0) + "\n".toRegex().findAll(text).map { it.range.endInclusive + 1 }
                val lineTops = lineOffsets.map { textLayoutResult.getLineTop(textLayoutResult.getLineForOffset(it)) }
                println("Done. ${lineTops.size}")
            },
            modifier = Modifier.fillMaxSize().verticalScroll(scrollState),
        )
        VerticalScrollbar(
            modifier = Modifier.align(Alignment.CenterEnd),
            adapter = rememberScrollbarAdapter(scrollState),
        )
    }
}

Reproduction steps

  1. Run the app
  2. Hangs until some minutes later

Video
N/A

Profiling data
N/A

Additional information
I was implementing line number display and text folding for a TextField. As #3866 is not available yet, I try an alternative using TextLayoutResult#getLineForOffset. Unfortunately, it only works for small number of lines. I wonder if there is a feasible workaround at this moment.

@m-sasha
Copy link
Member

m-sasha commented Dec 11, 2023

Thanks, I'll fix it.

@okushnikov
Copy link
Collaborator

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants