Repository navigation
Conversation
…es an emoji ReactTextView and ReactEditText extend AppCompat views, and AppCompat runs their text through EmojiCompat. When the system font has no glyph for an emoji (U+1FAE9 on Android 15, for example), EmojiCompat swaps it for a span drawn from the downloadable emoji font. TextLayoutManager measured the same text with the system font, so the drawn text came out wider than its box and ran into whatever was laid out after it. On the phone I tested, each U+1FAE9 was measured at about 8.7dp and drawn at about 24.7dp. Run EmojiCompat on every Spannable TextLayoutManager builds, once EmojiCompat has loaded, so measurement sees the same spans the view draws. emoji2 is already on the runtime classpath through appcompat 1.7.0; this adds it as a direct dependency at the same version (1.3.0) so ReactAndroid can compile against it.
|
Hi @KAMRONBEK! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
Summary:
Fixes #59850
On Android, text with an emoji the system font lacks ( U+1FAE9 on Android 15, for example) is measured narrower than it's drawn, so the next view overlaps it.
ReactTextViewandReactEditTextare AppCompat views, and AppCompat runs their text throughEmojiCompat, which replaces that emoji with anEmojiSpanfrom the downloadable font.TextLayoutManagermeasured the string without that span.This runs
EmojiCompat.process()on the Spannable increateSpannableFromAttributedString, right afteronPostProcessSpannable, so measurement sees the same spans the view draws. It only does anything when EmojiCompat is configured and has finished loading, and with the default config it only adds spans for emoji the system font can't draw.emoji2 1.3.0 is already on the runtime classpath through appcompat 1.7.0, but not on ReactAndroid's compile classpath. I added it as a direct dependency at that same version so the resolved version doesn't change. Internal builds will probably need the same dependency.
Known limits:
Changelog:
[ANDROID] [FIXED] - Fix text being measured narrower than drawn when EmojiCompat replaces an emoji the system font lacks
Test Plan:
Applied the same change to 0.88.1, built React Native from source in a fresh release app, and ran it on an ASUS Zenfone 10 (Android 15, Google Play services). Widths in dp, rows mounted 3 s after launch:
inline endinline🫨 endinline endwwww 😠abWith main's two text flags forced on in that app, selectable
select endwent from 99.64 (wrapped, clipped) to 115.64.Repro app: https://github.com/KAMRONBEK/rn-emojicompat-repro
145 tests, 0 failures. ktfmt 0.59.0 with the
format-kotlinflags passes on both changed Kotlin files.Not run: the full test suite,
yarn lint, RNTester, an app built from main, other devices.