Repository navigation
Conversation
|
Hi @nowex35! 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! |
9075389 to
b3f81db
Compare
Yoga snaps each edge of a node to the pixel grid independently and derives the height from their difference. On screens whose scale is not a power of two, a node far enough down the screen can get a frame one float ULP short of its `lineHeight` (19.999992 for 20, react/yoga#2011). `compareToSize:` had no tolerance on the height, and the line height does not change when the font is scaled, so such a row never fit and was scaled down to `minimumFontSize` even though the text fit (react#52642). Treat a height shortfall smaller than one physical pixel as fitting. Width keeps its existing check. Adds an RNTester example that reproduces the condition on a 3x device.
b3f81db to
2b08f9a
Compare
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
Summary:
<Text adjustsFontSizeToFit numberOfLines={1} style={{lineHeight: N}}>sometimes collapses to the minimum font size on iOS even though the text fits, and which row it happens to depends on the row's position on screen (#52642).Two things combine:
pointScaleFactorand narrowed tofloat, so on a 3x screen a node far enough down the screen can get a height one float ULP short of itslineHeight(19.99999237060547forlineHeight: 20;10.999969482421875for11on a production screen). Subtract rounded edges in pixel space when rounding layout results yoga#2011 addresses that side.compareToSize:inNSTextStorage+FontScaling.mrequiressize.height >= measuredSize.heightwith no tolerance. The text is laid out at the fixed line height at every font ratio, so such a frame never fits,lastRatioWhichFitskeeps its initial value and the text ends atminimumFontSize(4pt before FixminimumFontScalewithadjustsFontSizeToFitin the New Architecture #58492).This PR treats a height shortfall smaller than one physical pixel as fitting. A sub-pixel difference cannot change what is drawn, and one physical pixel is the granularity the Fabric measure path already snaps to (
RCTTextLayoutManagermeasureAttributedString:ceils topointScaleFactor).compareToSize:has no layout context in scope, so the scale comes fromRCTScreenScale(), the same helperRCTCeilPixelValue()inRCTUtilsuses. The width check is unchanged. The file is shared by Paper and Fabric, so both renderers get the same behavior.It also adds an RNTester example (
Font Size Adjustment with lineHeight) that reproduces the condition: tenlineHeight: 20rows after a 0.5pt separator. On a 3x device one of the rows (which one depends on the device) gets a frame of19.99999237060547and collapsed before this change.Fixes #52642
Changelog:
[IOS] [FIXED] - Fix
adjustsFontSizeToFittext collapsing to the minimum size when Yoga's pixel-grid rounding leaves the frame a sub-pixel short oflineHeightTest Plan:
Verified by applying the
NSTextStorage+FontScaling.mchange to React Native 0.86.2 (Expo SDK 57, New Architecture) and rebuilding the app, with the same ten-row layout as the RNTester example, on an iPhone 13 simulator (3x, iOS 26.5). The number next to each row is theonLayoutheight.Before (row 3 has a frame of
19.99999237060547and collapses):After (same layout, same frame heights, no row collapses):
Regression check in the same build: a row whose text is genuinely too wide for 200pt still shrinks to fit, and a row with
lineHeight: 10, fontSize: 15is still left unscaled (both unchanged from before, since the width check is untouched and that frame equals the line height):