Skip to content

Keep the measured pixel size of text nodes when rounding to the pixel grid - #2040

Merged
cortinico merged 1 commit into
react:mainfrom
intergalacticspacehighway:fix-pixel-grid-tolerance
Oct 15, 2026
Merged

cortinico merged 1 commit into
react:mainfrom
intergalacticspacehighway:fix-pixel-grid-tolerance

Conversation

@intergalacticspacehighway

@intergalacticspacehighway intergalacticspacehighway commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #1975
Fixes #749

Thanks @stleamist for the analysis and the reproduction in #1975.

Issue

The issue happens when a text node's rounded layout size is smaller than its measured size.

Example:
absoluteNodeLeft = 490.999923px
nodeWidth = 163.999968px
absoluteNodeRight = 490.999923px + 163.999968px = 654.999891px

The layout dimension width is set with the code below:

// Here hasFractionalWidth is false because nodeWidth (163.999968) is within the 0.0001 threshold of 164.
roundValueToPixelGridDouble(absoluteNodeRight, pointScaleFactor, (textRounding && hasFractionalWidth), (textRounding && !hasFractionalWidth)) -
roundValueToPixelGridDouble(absoluteNodeLeft, pointScaleFactor, false, textRounding)))

absoluteNodeRight (654.999891) is outside the 0.0001 threshold of 655, so it gets floored to 654.
absoluteNodeLeft (490.999923) is within the 0.0001 threshold of 491, so it gets rounded to 491.
The size becomes 654 - 491 = 163. The measured size was 164, so the text gets truncated.

Solution

When a text node's size is a whole number of pixels, set the layout dimension to round(scaledNodeWidth) / pointScaleFactor (in points).

Fix tested in the original repro #1975 (comment)

Unrelated

Fixed the scaledNodeWith variable name typo.

… grid

When a text node's scaled size is a whole number of pixels, use that pixel count as its rounded size instead of the difference of its two rounded edges. The 0.0001 snap tolerance could snap one edge to a pixel and floor the other, which made the node one pixel smaller than its measured size and truncated its text.
@meta-cla meta-cla Bot added the CLA Signed label Oct 15, 2026
@intergalacticspacehighway
intergalacticspacehighway marked this pull request as ready for review October 15, 2026 05:48
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 15, 2026

@cortinico cortinico left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 thanks for adding the regression tests

@cortinico
cortinico merged commit 6ac92f4 into react:main Oct 15, 2026
33 checks passed
stleamist added a commit to stleamist/FlexLayout that referenced this pull request Oct 19, 2026
Pin Swift Package Manager to Yoga main commit 52f6d0bd3824296b8e852cb4fcdf3b9821ab2aa5, which includes react/yoga#2040.

Support both float and YGValue gap getters while retaining CocoaPods compatibility with Yoga 3.2.1. Mark the version-specific overloads maybe_unused for warning-as-error builds and cover point gap getters and layout with tests.

Select a simulator available with CI's Xcode 16.4 via an overridable device name.
stleamist added a commit to stleamist/FlexLayout that referenced this pull request Oct 19, 2026
Pin Swift Package Manager to Yoga main commit 52f6d0bd3824296b8e852cb4fcdf3b9821ab2aa5, which includes react/yoga#2040.

Support both float and YGValue gap getters while retaining CocoaPods compatibility with Yoga 3.2.1. Mark the version-specific overloads maybe_unused for warning-as-error builds and cover point gap getters and layout with tests.

Select a simulator available with CI's Xcode 16.4 via an overridable device name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Layout bug caused by floating point rounding error

2 participants