Skip to content

Conversation

@MatkovIvan
Copy link
Member

@MatkovIvan MatkovIvan commented Dec 8, 2025

Fixes CMP-8028 Text color is sometimes randomly black on iOS when using Compose Multiplatform (BasicText)

It's a minimal, simplified version of #2629

Testing

  • Existing tests on CI
  • Reproducer from CMP-8028
val textMeasurer = rememberTextMeasurer(cacheSize = 100)
Canvas(Modifier.background(Color.DarkGray)) {
    for (i in 0 until 100) {
        drawText(
            textLayoutResult = textMeasurer.measure(text = "$i"),
            color = Color.White,
            topLeft = Offset(x = i % 10 * 50f, y = i / 10 * 50f)
        )
    }
}

Release Notes

Fixes - iOS

  • Fix possible text styles cache corruption (text color is sometimes randomly black)

MatkovIvan added a commit that referenced this pull request Dec 9, 2025
Fixes [CMP-8028](https://youtrack.jetbrains.com/issue/CMP-8028) Text
color is sometimes randomly black on iOS when using Compose
Multiplatform (BasicText)

The main change here is to make sure that keys in `skTextStylesCache`
are immutable.
However, during the paragraph building, we need this class to be mutable
to avoid unnecessary allocations. While it's possible to fix the issue
with just a few lines (#2630), it seems really dangerous long term, so
this PR replaces `ComputedStyle` to `sealed intefrace` with both
variants to ensure immutability at compile time instead.

In addition to that, it contains a small cleanup of code around:
- Add `@InternalTextApi` to functions with `TODO: Remove from public`,
so we can actually remove them later
- Optimize cleaning up styles cache: remove in-place during iteration to
avoid allocation of extra list and additional look-ups

## Testing
- Existing tests on CI
- Reproducer from
[CMP-8028](https://youtrack.jetbrains.com/issue/CMP-8028)
```kt
val textMeasurer = rememberTextMeasurer(cacheSize = 100)
Canvas(Modifier.background(Color.DarkGray)) {
    for (i in 0 until 100) {
        drawText(
            textLayoutResult = textMeasurer.measure(text = "$i"),
            color = Color.White,
            topLeft = Offset(x = i % 10 * 50f, y = i / 10 * 50f)
        )
    }
}
```

Additional auto tests are problematic because the issue reproduces only
on K/N (both macOS and iOS) where we didn't have infrastructure for
fonts-related testing yet.

## Release Notes
### Fixes - iOS
- Fix possible text styles cache corruption (text color is sometimes
randomly black)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants