Fix percentage calculation when parent size is undefined
Summary: If parent size was undefined and node specified percentage size it would pass does an exact measure mode with an undefined value which broke an assertion. Reviewed By: gkassabli Differential Revision: D4494265 fbshipit-source-id: 9efef9e39a1b66af2d0f144575a96c919d60dbf7
This commit is contained in:
committed by
Facebook Github Bot
parent
4227e36ca5
commit
cfeac79130
@@ -955,5 +955,41 @@ namespace Facebook.Yoga
|
|||||||
YogaNode.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, false);
|
YogaNode.SetExperimentalFeatureEnabled(YogaExperimentalFeature.Rounding, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Test_percentage_width_height_undefined_parent_size()
|
||||||
|
{
|
||||||
|
YogaNode root = new YogaNode();
|
||||||
|
|
||||||
|
YogaNode root_child0 = new YogaNode();
|
||||||
|
root_child0.Width = 50.Percent();
|
||||||
|
root_child0.Height = 50.Percent();
|
||||||
|
root.Insert(0, root_child0);
|
||||||
|
root.StyleDirection = YogaDirection.LTR;
|
||||||
|
root.CalculateLayout();
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, root.LayoutX);
|
||||||
|
Assert.AreEqual(0f, root.LayoutY);
|
||||||
|
Assert.AreEqual(0f, root.LayoutWidth);
|
||||||
|
Assert.AreEqual(0f, root.LayoutHeight);
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutX);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutY);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutWidth);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutHeight);
|
||||||
|
|
||||||
|
root.StyleDirection = YogaDirection.RTL;
|
||||||
|
root.CalculateLayout();
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, root.LayoutX);
|
||||||
|
Assert.AreEqual(0f, root.LayoutY);
|
||||||
|
Assert.AreEqual(0f, root.LayoutWidth);
|
||||||
|
Assert.AreEqual(0f, root.LayoutHeight);
|
||||||
|
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutX);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutY);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutWidth);
|
||||||
|
Assert.AreEqual(0f, root_child0.LayoutHeight);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -79,3 +79,7 @@
|
|||||||
<div id="percentage_absolute_position" experiments="Rounding" style="width: 200px; height: 100px;">
|
<div id="percentage_absolute_position" experiments="Rounding" style="width: 200px; height: 100px;">
|
||||||
<div style="position: absolute; top: 10%; left: 30%; width: 10px; height: 10px;"></div>
|
<div style="position: absolute; top: 10%; left: 30%; width: 10px; height: 10px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="percentage_width_height_undefined_parent_size">
|
||||||
|
<div style="width: 50%; height: 50%;"></div>
|
||||||
|
</div>
|
||||||
|
@@ -938,4 +938,39 @@ public class YGPercentageTest {
|
|||||||
YogaNode.setExperimentalFeatureEnabled(YogaExperimentalFeature.ROUNDING, false);
|
YogaNode.setExperimentalFeatureEnabled(YogaExperimentalFeature.ROUNDING, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test_percentage_width_height_undefined_parent_size() {
|
||||||
|
final YogaNode root = new YogaNode();
|
||||||
|
|
||||||
|
final YogaNode root_child0 = new YogaNode();
|
||||||
|
root_child0.setWidthPercent(50f);
|
||||||
|
root_child0.setHeightPercent(50f);
|
||||||
|
root.addChildAt(root_child0, 0);
|
||||||
|
root.setDirection(YogaDirection.LTR);
|
||||||
|
root.calculateLayout();
|
||||||
|
|
||||||
|
assertEquals(0f, root.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, root.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(0f, root.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(0f, root.getLayoutHeight(), 0.0f);
|
||||||
|
|
||||||
|
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
|
||||||
|
|
||||||
|
root.setDirection(YogaDirection.RTL);
|
||||||
|
root.calculateLayout();
|
||||||
|
|
||||||
|
assertEquals(0f, root.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, root.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(0f, root.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(0f, root.getLayoutHeight(), 0.0f);
|
||||||
|
|
||||||
|
assertEquals(0f, root_child0.getLayoutX(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutY(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
|
||||||
|
assertEquals(0f, root_child0.getLayoutHeight(), 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -965,3 +965,40 @@ it("percentage_absolute_position", function () {
|
|||||||
|
|
||||||
Yoga.setExperimentalFeatureEnabled(Yoga.FEATURE_ROUNDING, false);
|
Yoga.setExperimentalFeatureEnabled(Yoga.FEATURE_ROUNDING, false);
|
||||||
});
|
});
|
||||||
|
it("percentage_width_height_undefined_parent_size", function () {
|
||||||
|
var root = Yoga.Node.create();
|
||||||
|
|
||||||
|
var root_child0 = Yoga.Node.create();
|
||||||
|
root_child0.setWidth("50%");
|
||||||
|
root_child0.setHeight("50%");
|
||||||
|
root.insertChild(root_child0, 0);
|
||||||
|
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR);
|
||||||
|
|
||||||
|
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
|
||||||
|
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
|
||||||
|
console.assert(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
|
||||||
|
console.assert(0 === root.getComputedHeight(), "0 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
|
||||||
|
|
||||||
|
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
|
||||||
|
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
|
||||||
|
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
|
||||||
|
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
|
||||||
|
|
||||||
|
root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL);
|
||||||
|
|
||||||
|
console.assert(0 === root.getComputedLeft(), "0 === root.getComputedLeft() (" + root.getComputedLeft() + ")");
|
||||||
|
console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")");
|
||||||
|
console.assert(0 === root.getComputedWidth(), "0 === root.getComputedWidth() (" + root.getComputedWidth() + ")");
|
||||||
|
console.assert(0 === root.getComputedHeight(), "0 === root.getComputedHeight() (" + root.getComputedHeight() + ")");
|
||||||
|
|
||||||
|
console.assert(0 === root_child0.getComputedLeft(), "0 === root_child0.getComputedLeft() (" + root_child0.getComputedLeft() + ")");
|
||||||
|
console.assert(0 === root_child0.getComputedTop(), "0 === root_child0.getComputedTop() (" + root_child0.getComputedTop() + ")");
|
||||||
|
console.assert(0 === root_child0.getComputedWidth(), "0 === root_child0.getComputedWidth() (" + root_child0.getComputedWidth() + ")");
|
||||||
|
console.assert(0 === root_child0.getComputedHeight(), "0 === root_child0.getComputedHeight() (" + root_child0.getComputedHeight() + ")");
|
||||||
|
|
||||||
|
if (typeof root !== "undefined")
|
||||||
|
root.freeRecursive();
|
||||||
|
|
||||||
|
(typeof gc !== "undefined") && gc();
|
||||||
|
console.assert(0 === Yoga.getInstanceCount(), "0 === Yoga.getInstanceCount() (" + Yoga.getInstanceCount() + ")");
|
||||||
|
});
|
||||||
|
@@ -917,3 +917,37 @@ TEST(YogaTest, percentage_absolute_position) {
|
|||||||
|
|
||||||
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureRounding, false);
|
YGSetExperimentalFeatureEnabled(YGExperimentalFeatureRounding, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(YogaTest, percentage_width_height_undefined_parent_size) {
|
||||||
|
const YGNodeRef root = YGNodeNew();
|
||||||
|
|
||||||
|
const YGNodeRef root_child0 = YGNodeNew();
|
||||||
|
YGNodeStyleSetWidthPercent(root_child0, 50);
|
||||||
|
YGNodeStyleSetHeightPercent(root_child0, 50);
|
||||||
|
YGNodeInsertChild(root, root_child0, 0);
|
||||||
|
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
|
||||||
|
|
||||||
|
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root));
|
||||||
|
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
|
||||||
|
ASSERT_FLOAT_EQ(0, YGNodeLayoutGetHeight(root_child0));
|
||||||
|
|
||||||
|
YGNodeFreeRecursive(root);
|
||||||
|
}
|
||||||
|
20
yoga/Yoga.c
20
yoga/Yoga.c
@@ -256,12 +256,16 @@ static inline const YGValue *YGComputedEdgeValue(const YGValue edges[YGEdgeCount
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float YGValueResolve(const YGValue *const unit, const float parentSize) {
|
static inline float YGValueResolve(const YGValue *const value, const float parentSize) {
|
||||||
if (unit->unit == YGUnitPixel) {
|
switch (value->unit) {
|
||||||
return unit->value;
|
case YGUnitUndefined:
|
||||||
} else {
|
return YGUndefined;
|
||||||
return unit->value * parentSize / 100.0f;
|
case YGUnitPixel:
|
||||||
|
return value->value;
|
||||||
|
case YGUnitPercent:
|
||||||
|
return value->value * parentSize / 100.0f;
|
||||||
}
|
}
|
||||||
|
return YGUndefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t gNodeInstanceCount = 0;
|
int32_t gNodeInstanceCount = 0;
|
||||||
@@ -2253,7 +2257,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
childHeight = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionHeight],
|
childHeight = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionHeight],
|
||||||
availableInnerHeight) +
|
availableInnerHeight) +
|
||||||
marginColumn;
|
marginColumn;
|
||||||
childHeightMeasureMode = YGMeasureModeExactly;
|
childHeightMeasureMode =
|
||||||
|
YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeExactly;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
childHeight = updatedMainSize + marginColumn;
|
childHeight = updatedMainSize + marginColumn;
|
||||||
@@ -2277,7 +2282,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
childWidth = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionWidth],
|
childWidth = YGValueResolve(¤tRelativeChild->style.dimensions[YGDimensionWidth],
|
||||||
availableInnerWidth) +
|
availableInnerWidth) +
|
||||||
marginRow;
|
marginRow;
|
||||||
childWidthMeasureMode = YGMeasureModeExactly;
|
childWidthMeasureMode =
|
||||||
|
YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeExactly;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user