Skip to content

Commit 40e1bf6

Browse files
Emil Sjolanderfacebook-github-bot
authored andcommitted
Treat measured nodes size as a minimun contraint when rounding
Summary: We need to treat measurements from nodes with measure functions as minimum values as to not truncate text. Reviewed By: shergin Differential Revision: D4972290 fbshipit-source-id: 0a7bcc7f47b3e5acb8745da5286abcb9c4e44a38
1 parent 7b89a1d commit 40e1bf6

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

tests/YGRoundingMeasureFuncTest.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,29 @@ TEST(YogaTest, rounding_feature_with_custom_measure_func_floor) {
4949

5050
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
5151

52-
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
53-
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
52+
ASSERT_FLOAT_EQ(11, YGNodeLayoutGetWidth(root_child0));
53+
ASSERT_FLOAT_EQ(11, YGNodeLayoutGetHeight(root_child0));
5454

5555
YGConfigSetPointScaleFactor(config, 2.0f);
5656

5757
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
5858

59-
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child0));
60-
ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child0));
59+
ASSERT_FLOAT_EQ(10.5, YGNodeLayoutGetWidth(root_child0));
60+
ASSERT_FLOAT_EQ(10.5, YGNodeLayoutGetHeight(root_child0));
6161

6262
YGConfigSetPointScaleFactor(config, 4.0f);
6363

6464
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
6565

66-
ASSERT_FLOAT_EQ(10.25f, YGNodeLayoutGetWidth(root_child0));
66+
ASSERT_FLOAT_EQ(10.25, YGNodeLayoutGetWidth(root_child0));
6767
ASSERT_FLOAT_EQ(10.25, YGNodeLayoutGetHeight(root_child0));
6868

6969
YGConfigSetPointScaleFactor(config, 1.0f / 3.0f);
7070

7171
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
7272

73-
ASSERT_FLOAT_EQ(9.0, YGNodeLayoutGetWidth(root_child0));
74-
ASSERT_FLOAT_EQ(9.0, YGNodeLayoutGetHeight(root_child0));
73+
ASSERT_FLOAT_EQ(12.0, YGNodeLayoutGetWidth(root_child0));
74+
ASSERT_FLOAT_EQ(12.0, YGNodeLayoutGetHeight(root_child0));
7575

7676
YGNodeFreeRecursive(root);
7777

yoga/Yoga.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3297,9 +3297,20 @@ void YGConfigSetPointScaleFactor(const YGConfigRef config, const float pixelsInP
32973297
}
32983298
}
32993299

3300-
static float YGRoundValueToPixelGrid(const float value, const float pointScaleFactor) {
3300+
static float YGRoundValueToPixelGrid(const float value, const float pointScaleFactor, const bool forceCeil, const bool forceFloor) {
33013301
float fractial = fmodf(value, pointScaleFactor);
3302-
return value - fractial + (fractial >= pointScaleFactor / 2.0f ? pointScaleFactor : 0);
3302+
if (YGFloatsEqual(fractial, 0)) {
3303+
// Still remove fractial as fractial could be extremely small.
3304+
return value - fractial;
3305+
}
3306+
3307+
if (forceCeil) {
3308+
return value - fractial + pointScaleFactor;
3309+
} else if (forceFloor) {
3310+
return value - fractial;
3311+
} else {
3312+
return value - fractial + (fractial >= pointScaleFactor / 2.0f ? pointScaleFactor : 0);
3313+
}
33033314
}
33043315

33053316
static void YGRoundToPixelGrid(const YGNodeRef node, const float pointScaleFactor, const float absoluteLeft, const float absoluteTop) {
@@ -3319,13 +3330,17 @@ static void YGRoundToPixelGrid(const YGNodeRef node, const float pointScaleFacto
33193330
const float absoluteNodeRight = absoluteNodeLeft + nodeWidth;
33203331
const float absoluteNodeBottom = absoluteNodeTop + nodeHeight;
33213332

3322-
node->layout.position[YGEdgeLeft] = YGRoundValueToPixelGrid(nodeLeft, pointScaleFactor);
3323-
node->layout.position[YGEdgeTop] = YGRoundValueToPixelGrid(nodeTop, pointScaleFactor);
3333+
// If a node has a custom measure function we never want to round down its size as this could
3334+
// lead to unwanted text truncation.
3335+
const bool hasMeasure = node->measure != NULL;
3336+
3337+
node->layout.position[YGEdgeLeft] = YGRoundValueToPixelGrid(nodeLeft, pointScaleFactor, false, hasMeasure);
3338+
node->layout.position[YGEdgeTop] = YGRoundValueToPixelGrid(nodeTop, pointScaleFactor, false, hasMeasure);
33243339

33253340
node->layout.dimensions[YGDimensionWidth] =
3326-
YGRoundValueToPixelGrid(absoluteNodeRight, pointScaleFactor) - YGRoundValueToPixelGrid(absoluteNodeLeft, pointScaleFactor);
3341+
YGRoundValueToPixelGrid(absoluteNodeRight, pointScaleFactor, hasMeasure, false) - YGRoundValueToPixelGrid(absoluteNodeLeft, pointScaleFactor, false, hasMeasure);
33273342
node->layout.dimensions[YGDimensionHeight] =
3328-
YGRoundValueToPixelGrid(absoluteNodeBottom, pointScaleFactor) - YGRoundValueToPixelGrid(absoluteNodeTop, pointScaleFactor);
3343+
YGRoundValueToPixelGrid(absoluteNodeBottom, pointScaleFactor, hasMeasure, false) - YGRoundValueToPixelGrid(absoluteNodeTop, pointScaleFactor, false, hasMeasure);
33293344

33303345
const uint32_t childCount = YGNodeListCount(node->children);
33313346
for (uint32_t i = 0; i < childCount; i++) {

0 commit comments

Comments
 (0)