Fix RTL start overhang clipping on Android 15+ - #58072
Conversation
|
Hi @ngocdevv! 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! |
Summary:
Fixes #58064.
Android 15 added glyph-bounds APIs for
StaticLayout, butLayout.draw()only shifts drawing when ink extends past the left edge. In an exactly constrained RTL paragraph, leading ink extends past the right edge instead, so fonts such as Amiri still clip their first glyph at a wrapped line start.This change:
setUseBoundsForWidthandsetShiftDrawingOffsetForStartOverhangfor exactly constrainedStaticLayouts on API 35+ using the existing reflection approach;AT_MOSTand unconstrained text on the existing advance-based measurement path.On the issue reproducer, the first layout was 1280 px wide while its glyph bounds extended to x=1287.07. Reserving 8 px in the text layout keeps the complete alif-madda ink inside the unchanged 1280 px React Native view.
Changelog:
[ANDROID] [FIXED] - Prevent RTL line-start glyph ink from clipping on Android 15 and later
Test Plan:
JAVA_HOME=$(/usr/libexec/java_home -v 17) ./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests com.facebook.react.views.text.TextLayoutManagerStartOverhangTest -Preact.internal.useHermesStable=true --no-daemon— BUILD SUCCESSFULJAVA_HOME=$(/usr/libexec/java_home -v 17) ./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest --tests 'com.facebook.react.views.text.*' -Preact.internal.useHermesStable=true --no-daemon— BUILD SUCCESSFULJAVA_HOME=$(/usr/libexec/java_home -v 17) ./gradlew :packages:react-native:ReactAndroid:ktfmtCheck -Preact.internal.useHermesStable=true --no-daemon --rerun-tasks— BUILD SUCCESSFULenablePreparedTextLayoutenabled and the Amiri font from the mandatory reproducer. Before the fix, ink reached and was cut at the final pixel column; after the fix, the complete stroke renders inside the tinted Text bounds.