compose-multiplatform icon indicating copy to clipboard operation
compose-multiplatform copied to clipboard

Text composable on web doesn't render text with emoji strings properly

Open ghost opened this issue 1 year ago • 4 comments

Describe the bug The Text composable doesn't render text with emoji strings properly

Affected platforms Select one of the platforms below:

  • Web (K/JS) - Canvas based API

Versions

  • Kotlin version*: 1.8.20
  • Compose Multiplatform version*: 1.4.0
  • OS version(s)*: macOS 13.3
  • Browser version: Chrome 112.0.5615.49 and Firefox 112.0 (64-bit)

To Reproduce Run this Composable as a Compose canvas app:

@Composable
fun EmojiTextTester() {
    Text(
        text = "Grinning Face emoji \uD83D\uDE00",
        fontFamily = FontFamily.Default, // or Monospace, Cursive, Serif, SansSerif
    )
}

Note that the displayed text reads: "Grinning Face emoji" but ends with a square box. Tested on up-to-date versions of Chrome and Firefox, versions listed above.

Similar code running on Android and Desktop via Compose Multiplatform renders as expected.

Expected behavior The text should read: "Grinning Face emoji 😀"

Screenshots Result with FontFamily.Serif Emoji rendering with FontFamily Serif

Result with FontFamily.Default Emoji rendering with FontFamily Default

The choice of fontFamily = FontFamily.Cursive, Serif, etc doesn't impact the displayed typeface. Perhaps there's a related typeface bug here?

Additional context

I've also attempted to use the Google Noto Color Emoji font (happy to provide code if useful). When it's presented as the first Font in a FontFamily the emojis render but regular type does not. When it's the second or later in a FontFamily, emojis render as boxes like the attached screenshot.

ghost avatar Apr 13 '23 19:04 ghost

Related discussion on the Slack: https://kotlinlang.slack.com/archives/C01F2HV7868/p1681146359217349

dima-avdeev-jb avatar Apr 14 '23 07:04 dima-avdeev-jb

Idem on my side. I tested by importing font from js resources like that:

  • id("org.jetbrains.compose") version "1.5.0-dev1049"
  • Kotlin 1.8.20
  • skiko
val fontFamilyState: MutableState<FontFamily?> = remember { mutableStateOf(null) }
rememberCoroutineScope().launch {
    fontFamilyState.value = FontFamily(
        Font("joypixels-android.ttf", resource("joypixels-android.ttf").readBytes())
    )
}

Emoji renders with this font but impossible to have emoji working with default fonts.

PS: No issue on Android because emoji seems based on the Android API version and no issue on desktop (jvm). No idea how to intercept the text rendered. Maybe merge ttf could be an alternative.

Thank you so much for this great library 🙏

Mercandj avatar May 31 '23 19:05 Mercandj

i tried with japanese words and alphabet . they are also apears as boxes . if i add the same text in index.html it works . only happened in comosable from js app .

kotlin:1.9.0 jb-compose:1.4.3

naser09 avatar Aug 02 '23 19:08 naser09

not only emoji don't render. also lot of rare unicode symbols are just abset and render as rectangles. the desktop build works fine though

mykola-dev avatar Apr 24 '24 16:04 mykola-dev

Compose Multiplatform 1.7.0-dev1721 is out and it contains the Fonts fallback provider change: https://github.com/JetBrains/compose-multiplatform-core/pull/1400 (please take a look to see a usage example).

That version of Compose for Web can be used either with kotlin 1.9.24 or with 2.0.10-RC-515 (it won't work with kotlin 2.0).

eymar avatar Jul 10 '24 13:07 eymar

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

okushnikov avatar Jul 14 '24 14:07 okushnikov