fix(ios): Fix rounding error occurring randomly in iOS text line height calculation - #54260
fix(ios): Fix rounding error occurring randomly in iOS text line height calculation#54260soutua wants to merge 2 commits into
Conversation
|
Hi @soutua! 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! |
cipolleschi
left a comment
There was a problem hiding this comment.
@soutua thanks for the fix!
|
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this in D85438723. |
|
Hey guys! Thank you so much for the fix 🚀 is there any timeline to get this released? I think that a lot of apps are having this trouble. Thanks! |
|
Hey @soutua
@emaestre the steps are:
|
cab8bb5 to
7a885cb
Compare
I've now rebased and added a new text layout example screen in the RNTester app, I've also updated the test plan in the issue description to showcase the before/after difference. |
|
Thank you so much @cipolleschi! I created a Cherry Pick request here: reactwg/react-native-releases#1161 (comment) Appreciate the information and the help. |
7a885cb to
eb6650b
Compare
|
Noticed that the flow type check failed in the CI, I pushed new changes and it passes at least locally for me now, there was no types used in the test screen before this. |
|
@cipolleschi Is it still possible to get this into the 0.83? I think you might have tried importing this last week but it failed in CI type checks, which I then fixed (I believe) after I got the notification. I'm just thinking that if this doesn't make it to the 0.83, and considering e.g. Expo doesn't seem to support the even numbered React Native releases, then it might in practice be version 0.85 / Expo 56 that would have the fix for most people, which might be next fall or something 😅 |
|
sure, we will need a cherry pick request, but this is a fix, so that's fine. |
|
@cipolleschi merged this pull request in 581d643. |
|
This pull request was successfully merged by @soutua in 581d643 When will my fix make it into a release? | How to file a pick request? |
… line height calculation" (#54510) Summary: Pull Request resolved: #54510 Original commit changeset: f1b2890ce534 Original Phabricator Diff: D85438723 Original PR: #54260 The original fix broke some internal tests. ## Changelog: [iOS][Changed] - Revert Fix rounding error occurring randomly in iOS text line height calculation Reviewed By: javache Differential Revision: D86791267 fbshipit-source-id: e3466b44cdbb0cbae0d87a7c20fd33658e803b26
|
This pull request has been reverted by 6355501. |
|
This PR is now reverted? So the fix is not going to land in the next release? |
…ht calculation (#54260) Summary: Fixes issue react/react-native#53450 There are some discussion and explanation about the issue here: react/react-native#53450 (comment) In short, there seems to be a rounding error occurring with the new architecture's implementation when the text paragraph line heights are calculated on iOS, that happens randomly and depends on what text content the view has, and on the device screen. The fix is basically the same that had been implemented in the React Native's [old architecture 8 years ago](react/react-native@a534672), but hasn't been brought into the new architecture implementation. The fix adds a fraction to the text line dimensions to mitigate the rounding error. ## Changelog: [IOS] [FIXED] - Fix rounding error occurring randomly in iOS text line height calculation Pull Request resolved: react/react-native#54260 Test Plan: Note that the reproduction of the issue is also dependant on the used device/simulator, this was tested using the iPhone 17 simulator. - Go to Text Layout Example in the RNTester app - Scroll down the text until you see this text paragraph: Without the fix: <img width="400" alt="without-the-fix" src="https://github.com/user-attachments/assets/9a1fe071-be39-4f99-a7e6-25c2fb431fa4" /> With the fix: <img width="400" alt="with-the-fix" src="https://github.com/user-attachments/assets/eb798afc-1d39-4464-a21a-07d95db8ce62" /> Reviewed By: javache Differential Revision: D85438723 Pulled By: cipolleschi fbshipit-source-id: f1b2890ce5341fda790f5689ab1291b69cf7595b
… line height calculation" (#54510) Summary: Pull Request resolved: react/react-native#54510 Original commit changeset: f1b2890ce534 Original Phabricator Diff: D85438723 Original PR: react/react-native#54260 The original fix broke some internal tests. ## Changelog: [iOS][Changed] - Revert Fix rounding error occurring randomly in iOS text line height calculation Reviewed By: javache Differential Revision: D86791267 fbshipit-source-id: e3466b44cdbb0cbae0d87a7c20fd33658e803b26
|
Hey guys! @cipolleschi @soutua @douglowder Hope everyone is doing well. Any update on this? We're still experiencing the issue, and we would like to know what we can do, at least a workaround, while this is fixed. |
You can use this to create a patchfile Here is ours: diff --git a/node_modules/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm b/node_modules/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm
index 216bb23..b19b566 100644
--- a/node_modules/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm
+++ b/node_modules/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm
@@ -386,9 +386,9 @@ - (TextMeasurement)_measureTextStorage:(NSTextStorage *)textStorage
size.height = enumeratedLinesHeight;
}
- size = (CGSize){
- ceil(size.width * layoutContext.pointScaleFactor) / layoutContext.pointScaleFactor,
- ceil(size.height * layoutContext.pointScaleFactor) / layoutContext.pointScaleFactor};
+ CGFloat epsilon = 0.001;
+ size = (CGSize){ceil((size.width + epsilon) * layoutContext.pointScaleFactor) / layoutContext.pointScaleFactor,
+ ceil((size.height + epsilon) * layoutContext.pointScaleFactor) / layoutContext.pointScaleFactor};
__block auto attachments = TextMeasurement::Attachments{};
|
|
Yep, you can patch it locally in your project. I don't know why the change was reverted from the main branch, probably something didn't work because of it, or alternatively it was reverted by mistake. Don't know if it's coming back or not. |
|
So is this going to be released or not? |
|
I cant get why this is so hardcore ignored. This is a major bug within a most basic component. |
|
Agreed, especially as the fix provided by @soutua matches the fix that was in the old architecture. Details on what it broke would be good, so we could address them and get the fix merged. |
|
The original issue does seem like a pretty bad bug. The revert happened in #54510 because this change broke internal tests. @cipolleschi it would be great to understand what tests broke -- maybe there are certain values of size and pointScaleFactor where the result is off by one. I'll take a look to see if I (or maybe Claude 😄 ) can write some detailed unit tests for many different combinations of inputs. |
|
FYI folks, we are trying to land the fix again in #57698. |
Summary: Pull Request resolved: #57698 Re-lands the iOS text measurement rounding fix from PR #54260 / D85438723, which was reverted by D86791267. This version adds unit test coverage and moves the rounding into a helper that can be tested. On iOS, text measurement is rounded up to the device pixel grid. Converting the measured size from double to float and then rounding it to the pixel grid in Yoga can lose precision for a value that sits on a pixel boundary. That value can round down instead of up and clip the final line (height) or the trailing glyph (width). Fixes #53450. The fix adds a small epsilon before ceil on both width and height. This matches the approach the legacy architecture has used since D7074168 (a534672). The rounding now lives in a helper, internal_roundTextMeasurementToPixelGrid, so it can be covered by unit tests. The helper keeps the internal_ prefix so it stays out of the public C++ API snapshot. On the earlier revert: D85438723 was backed out after wildeMarketplaceScreenshot-e2e.js failed. Running that test on an OnDemand shows what actually happens. It passes on trunk. With this change the ad renders one physical pixel taller (height 44px to 45px, width unchanged). The top 44 rows are byte-for-byte identical to the baseline and the extra row is blank, so the content renders correctly and the failure is only the pixel-exact size check rejecting a 1px-different image. This is expected for the epsilon and is resolved by re-capturing the baseline, which is what D7074168 did in its own commit. The test is also independently flaky (test infra has flagged it, and it renders autoplaying video and carousels), which is a separate reason its earlier auto-rebaseline looked wrong. Rendering verification (wildeMarketplaceScreenshot, config browse_dynamic_image_layer_frame_overlay_high_res_sr_video), captured on an OnDemand. This is the element-scoped capture the test compares (the mp_feed_ad_item ad cell), not a full screen. The two are identical except for one blank pixel row at the bottom. | Before (trunk, 274x44) | After (this change, 274x45) | | --- | --- | | {F1993025868} | {F1993025869} | Changelog: [iOS] [Fixed] - Prevent the final line or trailing glyph of text from being clipped due to pixel-grid rounding precision loss (#53450) Reviewed By: cipolleschi Differential Revision: D113691958 fbshipit-source-id: 5824ac5efa6c01d630aaaa16cbb9181061e841a1
Summary:
Fixes issue #53450
There are some discussion and explanation about the issue here: #53450 (comment)
In short, there seems to be a rounding error occurring with the new architecture's implementation when the text paragraph line heights are calculated on iOS, that happens randomly and depends on what text content the view has, and on the device screen.
The fix is basically the same that had been implemented in the React Native's old architecture 8 years ago, but hasn't been brought into the new architecture implementation. The fix adds a fraction to the text line dimensions to mitigate the rounding error.
Changelog:
[IOS] [FIXED] - Fix rounding error occurring randomly in iOS text line height calculation
Test Plan:
Note that the reproduction of the issue is also dependant on the used device/simulator, this was tested using the iPhone 17 simulator.
Without the fix:

With the fix: