From e9927377b58a2bcac3615d79062ad6d81854bcdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20W=C3=B6hrl?= Date: Tue, 11 Apr 2017 13:00:02 -0700 Subject: [PATCH] Fix position on root node with RTL direction Summary: If the root node has a position and we have a RTL layout, that position must be like LTR direction. See #477. Closes https://github.com/facebook/yoga/pull/502 Differential Revision: D4867144 Pulled By: emilsjolander fbshipit-source-id: b5ad3d87e7054090da12d7665a3d1abe8496a548 --- .../Facebook.Yoga/YGAbsolutePositionTest.cs | 26 +++++++++++++++++ gentest/fixtures/YGAbsolutePositionTest.html | 23 ++++++++------- .../facebook/yoga/YGAbsolutePositionTest.java | 25 ++++++++++++++++ .../Facebook.Yoga/YGAbsolutePositionTest.js | 29 +++++++++++++++++++ tests/YGAbsolutePositionTest.cpp | 26 +++++++++++++++++ yoga/Yoga.c | 8 +++-- 6 files changed, 125 insertions(+), 12 deletions(-) diff --git a/csharp/tests/Facebook.Yoga/YGAbsolutePositionTest.cs b/csharp/tests/Facebook.Yoga/YGAbsolutePositionTest.cs index b2277bfb..274123db 100644 --- a/csharp/tests/Facebook.Yoga/YGAbsolutePositionTest.cs +++ b/csharp/tests/Facebook.Yoga/YGAbsolutePositionTest.cs @@ -719,5 +719,31 @@ namespace Facebook.Yoga Assert.AreEqual(40f, root_child0.LayoutHeight); } + [Test] + public void Test_position_root_with_rtl_should_position_withoutdirection() + { + YogaConfig config = new YogaConfig(); + + YogaNode root = new YogaNode(config); + root.Left = 72; + root.Width = 52; + root.Height = 52; + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(72f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(52f, root.LayoutWidth); + Assert.AreEqual(52f, root.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(72f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(52f, root.LayoutWidth); + Assert.AreEqual(52f, root.LayoutHeight); + } + } } diff --git a/gentest/fixtures/YGAbsolutePositionTest.html b/gentest/fixtures/YGAbsolutePositionTest.html index 4a1a1127..31864672 100644 --- a/gentest/fixtures/YGAbsolutePositionTest.html +++ b/gentest/fixtures/YGAbsolutePositionTest.html @@ -26,37 +26,40 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
\ No newline at end of file +
+ + +
+
diff --git a/java/tests/com/facebook/yoga/YGAbsolutePositionTest.java b/java/tests/com/facebook/yoga/YGAbsolutePositionTest.java index ca9978e3..42413fc7 100644 --- a/java/tests/com/facebook/yoga/YGAbsolutePositionTest.java +++ b/java/tests/com/facebook/yoga/YGAbsolutePositionTest.java @@ -703,4 +703,29 @@ public class YGAbsolutePositionTest { assertEquals(40f, root_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_position_root_with_rtl_should_position_withoutdirection() { + YogaConfig config = new YogaConfig(); + + final YogaNode root = new YogaNode(config); + root.setPosition(YogaEdge.LEFT, 72f); + root.setWidth(52f); + root.setHeight(52f); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(72f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(52f, root.getLayoutWidth(), 0.0f); + assertEquals(52f, root.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(YogaConstants.UNDEFINED, YogaConstants.UNDEFINED); + + assertEquals(72f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(52f, root.getLayoutWidth(), 0.0f); + assertEquals(52f, root.getLayoutHeight(), 0.0f); + } + } diff --git a/javascript/tests/Facebook.Yoga/YGAbsolutePositionTest.js b/javascript/tests/Facebook.Yoga/YGAbsolutePositionTest.js index fa7f48a0..d6049fa0 100644 --- a/javascript/tests/Facebook.Yoga/YGAbsolutePositionTest.js +++ b/javascript/tests/Facebook.Yoga/YGAbsolutePositionTest.js @@ -758,3 +758,32 @@ it("absolute_layout_align_items_and_justify_content_center_and_right_position", config.free(); } }); +it("position_root_with_rtl_should_position_withoutdirection", function () { + var config = Yoga.Config.create(); + + try { + var root = Yoga.Node.create(config); + root.setPosition(Yoga.EDGE_LEFT, 72); + root.setWidth(52); + root.setHeight(52); + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_LTR); + + console.assert(72 === root.getComputedLeft(), "72 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(52 === root.getComputedWidth(), "52 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(52 === root.getComputedHeight(), "52 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + + root.calculateLayout(Yoga.UNDEFINED, Yoga.UNDEFINED, Yoga.DIRECTION_RTL); + + console.assert(72 === root.getComputedLeft(), "72 === root.getComputedLeft() (" + root.getComputedLeft() + ")"); + console.assert(0 === root.getComputedTop(), "0 === root.getComputedTop() (" + root.getComputedTop() + ")"); + console.assert(52 === root.getComputedWidth(), "52 === root.getComputedWidth() (" + root.getComputedWidth() + ")"); + console.assert(52 === root.getComputedHeight(), "52 === root.getComputedHeight() (" + root.getComputedHeight() + ")"); + } finally { + if (typeof root !== "undefined") { + root.freeRecursive(); + } + + config.free(); + } +}); diff --git a/tests/YGAbsolutePositionTest.cpp b/tests/YGAbsolutePositionTest.cpp index d012dd02..dd52824f 100644 --- a/tests/YGAbsolutePositionTest.cpp +++ b/tests/YGAbsolutePositionTest.cpp @@ -713,3 +713,29 @@ TEST(YogaTest, absolute_layout_align_items_and_justify_content_center_and_right_ YGConfigFree(config); } + +TEST(YogaTest, position_root_with_rtl_should_position_withoutdirection) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetPosition(root, YGEdgeLeft, 72); + YGNodeStyleSetWidth(root, 52); + YGNodeStyleSetHeight(root, 52); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(72, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(52, YGNodeLayoutGetHeight(root)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/yoga/Yoga.c b/yoga/Yoga.c index 6a550206..10bd80e4 100644 --- a/yoga/Yoga.c +++ b/yoga/Yoga.c @@ -1324,8 +1324,12 @@ static void YGNodeSetPosition(const YGNodeRef node, const float mainSize, const float crossSize, const float parentWidth) { - const YGFlexDirection mainAxis = YGResolveFlexDirection(node->style.flexDirection, direction); - const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); + /* Root nodes should be always layouted as LTR, so we don't return negative values. */ + const YGDirection directionRespectingRoot = node->parent != NULL ? direction : YGDirectionLTR; + const YGFlexDirection mainAxis = + YGResolveFlexDirection(node->style.flexDirection, directionRespectingRoot); + const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, directionRespectingRoot); + const float relativePositionMain = YGNodeRelativePosition(node, mainAxis, mainSize); const float relativePositionCross = YGNodeRelativePosition(node, crossAxis, crossSize);