Skip to content

[Android] Text measured narrower than drawn when EmojiCompat replaces an emoji the system font lacks (🫩 on Android 15) #59850

Open

Description

@KAMRONBEK

Description

On Android, a <Text> or <TextInput> with an emoji the system font doesn't have gets measured narrower than it's drawn, so whatever comes after it ends up on top of the text. I hit this in a chat app: the timestamp next to a message covered the end of any message with 🫩 (U+1FAE9, Emoji 16) on an Android 15 phone.

As far as I can tell, ReactTextView and ReactEditText extend AppCompat views, and AppCompat runs their text through androidx.emoji2 EmojiCompat. When the system font has no glyph, EmojiCompat swaps the emoji for an EmojiSpan drawn from the downloadable emoji font. TextLayoutManager measures the same string with a plain StaticLayout/BoringLayout in the system font and never sees that span, so the measured width and the drawn width differ.

I think this is the same bug as #57995 / #57994, which were closed without a fix. sbaiahmed1's comment in #57995 narrowing it down to a glyph missing from the system font is what pointed me here.

I also forced main's text flags (enablePreparedTextLayout and enableAndroidTextMeasurementOptimizations) on in the same 0.88.1 app. I didn't build main itself. Plain Text then stops overlapping but draws 🫩 as tofu. Selectable Text and TextInput still overlap.

Steps to reproduce

  1. New 0.88.1 app, release build, on an Android 15 phone with Google Play services (EmojiCompat needs its font provider).
  2. Render a row: <Text style={{backgroundColor: 'yellow'}}>inline🫩 end</Text> followed by <Text>12:34</Text>.
  3. Mount it after EmojiCompat has loaded (I used a 3 s timeout).
  4. " end" is hidden under "12:34", and onTextLayout reports a narrower line than the same string with 🫨.

React Native Version

0.88.1

Affected Platforms

Runtime - Android

Output of npx @react-native-community/cli info

Didn't save the full output, the relevant bits:

react-native 0.88.1, react 19.3.0, New Architecture, Hermes, release build
Device: ASUS Zenfone 10 (AI2302), Android 15, Google Play services

Stacktrace or Logs

No crash. Line widths from onTextLayout (TextInput: box width), in dp:
inline end       84.36   (no emoji)
inline🫨 end     109.09  (system font has the glyph)
inline🫩 end     93.09   " end" hidden under the label
wwww 🫩 😠       103.27  😠 not visible
🫩🫩🫩            26.18   one emoji visible
TextInput "a🫩b"  30.91   🫩 drawn as tofu (TextInput "ab" is 22.18)

MANDATORY Reproducer

https://github.com/KAMRONBEK/rn-emojicompat-repro

Screenshots and Videos

Zenfone 10, Android 15, 0.88.1 defaults. The rows under "Mounted 3 s later" are the ones above:

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions