mirror of
https://github.com/status-im/react-native.git
synced 2025-02-05 14:13:26 +00:00
Round ShadowNode layout coordinates to a pixel boundary
Summary: When layout happens, left/top/right/bottom coordinates (and thus clip-*, too) are sometimes not at a pixel boundary for 2 reasons: a) width/height in Flexbox are floats, and can contain any value, not just a whole pixel. E.g. style={{width: 3.1415926}} is perfectly valid b) floating point arithmetics sometimes leads to values barely outside of pixel boundaries (width 18.0f can become 18.000001f when a sibling/child size changes). a) is \"breaking\" screenshot tests, which slightly but differ from reference implementation b) causes extra View updates/redraws for no reason This patch is rounding DrawCommand bounds to a whole pixel to avoid these 2 issues. Reviewed By: ahmedre Differential Revision: D2934401
This commit is contained in:
parent
addd233d31
commit
44b6200392
@ -359,15 +359,20 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
node.markLayoutSeen();
|
||||
}
|
||||
|
||||
float roundedLeft = roundToPixel(left);
|
||||
float roundedTop = roundToPixel(top);
|
||||
float roundedRight = roundToPixel(right);
|
||||
float roundedBottom = roundToPixel(bottom);
|
||||
|
||||
// notify JS about layout event if requested
|
||||
if (node.shouldNotifyOnLayout()) {
|
||||
mOnLayoutEvents.add(
|
||||
OnLayoutEvent.obtain(
|
||||
node.getReactTag(),
|
||||
Math.round(left),
|
||||
Math.round(top),
|
||||
Math.round(right - left),
|
||||
Math.round(bottom - top)));
|
||||
(int) roundedLeft,
|
||||
(int) roundedTop,
|
||||
(int) (roundedRight - roundedLeft),
|
||||
(int) (roundedBottom - roundedTop)));
|
||||
}
|
||||
|
||||
if (node.clipToBounds()) {
|
||||
@ -377,7 +382,16 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
clipBottom = Math.min(bottom, clipBottom);
|
||||
}
|
||||
|
||||
node.collectState(this, left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom);
|
||||
node.collectState(
|
||||
this,
|
||||
roundedLeft,
|
||||
roundedTop,
|
||||
roundedRight,
|
||||
roundedBottom,
|
||||
roundToPixel(clipLeft),
|
||||
roundToPixel(clipTop),
|
||||
roundToPixel(clipRight),
|
||||
clipBottom);
|
||||
|
||||
for (int i = 0, childCount = node.getChildCount(); i != childCount; ++i) {
|
||||
ReactShadowNode child = node.getChildAt(i);
|
||||
@ -499,4 +513,11 @@ import com.facebook.react.uimanager.events.EventDispatcher;
|
||||
|
||||
return viewTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is what Math.round() does, except it returns float.
|
||||
*/
|
||||
private static float roundToPixel(float pos) {
|
||||
return (float) Math.floor(pos + 0.5f);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user