Repository navigation
Conversation
|
Hi @ybelakov! 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! |
A node's rounded width and height are the difference of its two rounded absolute edges. roundValueToPixelGrid returns float, so that difference was taken in float; far from the origin a float has fewer bits than a pixel, and when the two edges fall on either side of a power of two they are quantized differently. A measured text node spanning y = 2048 on a 3x screen came out 43.9998779 tall instead of 44, one float step short of the two lines it was measured at, and the text renderer then dropped the last line. Round in double and subtract before narrowing to float. The public roundValueToPixelGrid keeps its signature.
9631935 to
b7b0540
Compare
|
React Native issue with a reproducer and screenshots: react/react-native#58970 |
…nding test On the previous rounding each of these came out off by a float step (44.00006, 43.99994, 43.99988, 43.99988 and 43.99976); all are exactly 44 now.
9d8ce79 to
471a201
Compare
Summary
roundLayoutResultsToPixelGridcomputes a node's rounded width and height as the difference of its two rounded absolute edges.roundValueToPixelGridreturnsfloat, so the subtraction happened in float. Far from the origin a float has fewer bits than a pixel (at y ≈ 2000 the step is 2⁻¹³ ≈ 0.00012pt; a 3x pixel is 0.333pt), and when the two edges fall on either side of a power of two they are quantized with different steps. The difference can then come out a float step short of the true size.Concrete case (React Native 0.86, iOS, 3x screen): a measured text node with top at 2004⅓ and height 44 (two lines of
lineHeight: 22) gotheight = 43.9998779296875. React Native hands that box to TextKit as the container, TextKit decides the second line doesn't fit, and the text is drawn as one unwrapped line clipped at the edge. User-facing report with a reproducer: react/react-native#58970.This change rounds in double and subtracts before narrowing to float.
roundValueToPixelGridkeeps its public signature and now wraps the double version.Test plan
New test
rounding_measured_height_is_exact_across_float_steps: a 3x config, a spacer, then a measured node returning 292×44, for spacers on both sides of 1024, 2048 and 4096. Heights on the previous code vs. this change (verified by compiling the Yoga sources with the test scenario directly; no CMake on this machine):Formatted by hand in the repo's style;
clang-formatwasn't available locally.