From c169a98be6410df5b5297e7ea87ec2638ec8c6a3 Mon Sep 17 00:00:00 2001 From: Lukas Woehrl Date: Fri, 6 Jan 2017 06:51:56 -0800 Subject: [PATCH] Baseline support Summary: Added baseline support (see #132) You have the ability for a custom baseline function (```float(*YGBaselineFunc)(YGNodeRef node);```) to return whatever baseline you want. Closes https://github.com/facebook/yoga/pull/317 Reviewed By: splhack Differential Revision: D4385061 Pulled By: emilsjolander fbshipit-source-id: cb8a59a09237c840fa3e21753ab68239997dab0c --- csharp/Facebook.Yoga/YogaAlign.cs | 1 + .../tests/Facebook.Yoga/YGAlignItemsTest.cs | 1378 +++++++++++++++++ csharp/tests/Facebook.Yoga/YGAlignSelfTest.cs | 71 + enums.py | 1 + gentest/fixtures/YGAlignItemsTest.html | 132 ++ gentest/fixtures/YGAlignSelfTest.html | 8 + gentest/gentest-cpp.js | 2 + gentest/gentest-cs.js | 1 + gentest/gentest-java.js | 1 + gentest/gentest-javascript.js | 1 + gentest/gentest.js | 1 + java/com/facebook/yoga/YogaAlign.java | 4 +- .../com/facebook/yoga/YGAlignItemsTest.java | 1363 ++++++++++++++++ .../com/facebook/yoga/YGAlignSelfTest.java | 70 + javascript/sources/YGEnums.js | 3 +- tests/YGAlignItemsTest.cpp | 1348 ++++++++++++++++ tests/YGAlignSelfTest.cpp | 69 + tests/YGBaselineFuncTest.cpp | 63 + yoga/YGEnums.h | 3 +- yoga/Yoga.c | 122 +- yoga/Yoga.h | 2 + 21 files changed, 4628 insertions(+), 16 deletions(-) create mode 100644 tests/YGBaselineFuncTest.cpp diff --git a/csharp/Facebook.Yoga/YogaAlign.cs b/csharp/Facebook.Yoga/YogaAlign.cs index 80835d73..71b8b33b 100644 --- a/csharp/Facebook.Yoga/YogaAlign.cs +++ b/csharp/Facebook.Yoga/YogaAlign.cs @@ -16,5 +16,6 @@ namespace Facebook.Yoga Center, FlexEnd, Stretch, + Baseline, } } diff --git a/csharp/tests/Facebook.Yoga/YGAlignItemsTest.cs b/csharp/tests/Facebook.Yoga/YGAlignItemsTest.cs index bcafe460..1ef9047d 100644 --- a/csharp/tests/Facebook.Yoga/YGAlignItemsTest.cs +++ b/csharp/tests/Facebook.Yoga/YGAlignItemsTest.cs @@ -171,5 +171,1383 @@ namespace Facebook.Yoga Assert.AreEqual(10f, root_child0.LayoutHeight); } + [Test] + public void Test_align_baseline() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(30f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(30f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child_multiline() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 60; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexDirection = YogaFlexDirection.Row; + root_child1.Wrap = YogaWrap.Wrap; + root_child1.Width = 50; + root_child1.Height = 25; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 25; + root_child1_child0.Height = 20; + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child1_child1 = new YogaNode(); + root_child1_child1.Width = 25; + root_child1_child1.Height = 10; + root_child1.Insert(1, root_child1_child1); + + YogaNode root_child1_child2 = new YogaNode(); + root_child1_child2.Width = 25; + root_child1_child2.Height = 20; + root_child1.Insert(2, root_child1_child2); + + YogaNode root_child1_child3 = new YogaNode(); + root_child1_child3.Width = 25; + root_child1_child3.Height = 10; + root_child1.Insert(3, root_child1_child3); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(60f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(25f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(25f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child1.LayoutX); + Assert.AreEqual(0f, root_child1_child1.LayoutY); + Assert.AreEqual(25f, root_child1_child1.LayoutWidth); + Assert.AreEqual(10f, root_child1_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child2.LayoutX); + Assert.AreEqual(20f, root_child1_child2.LayoutY); + Assert.AreEqual(25f, root_child1_child2.LayoutWidth); + Assert.AreEqual(20f, root_child1_child2.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child3.LayoutX); + Assert.AreEqual(20f, root_child1_child3.LayoutY); + Assert.AreEqual(25f, root_child1_child3.LayoutWidth); + Assert.AreEqual(10f, root_child1_child3.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(60f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(25f, root_child1.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(25f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child1.LayoutX); + Assert.AreEqual(0f, root_child1_child1.LayoutY); + Assert.AreEqual(25f, root_child1_child1.LayoutWidth); + Assert.AreEqual(10f, root_child1_child1.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child2.LayoutX); + Assert.AreEqual(20f, root_child1_child2.LayoutY); + Assert.AreEqual(25f, root_child1_child2.LayoutWidth); + Assert.AreEqual(20f, root_child1_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child3.LayoutX); + Assert.AreEqual(20f, root_child1_child3.LayoutY); + Assert.AreEqual(25f, root_child1_child3.LayoutWidth); + Assert.AreEqual(10f, root_child1_child3.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child_multiline_override() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 60; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexDirection = YogaFlexDirection.Row; + root_child1.Wrap = YogaWrap.Wrap; + root_child1.Width = 50; + root_child1.Height = 25; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 25; + root_child1_child0.Height = 20; + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child1_child1 = new YogaNode(); + root_child1_child1.AlignSelf = YogaAlign.Baseline; + root_child1_child1.Width = 25; + root_child1_child1.Height = 10; + root_child1.Insert(1, root_child1_child1); + + YogaNode root_child1_child2 = new YogaNode(); + root_child1_child2.Width = 25; + root_child1_child2.Height = 20; + root_child1.Insert(2, root_child1_child2); + + YogaNode root_child1_child3 = new YogaNode(); + root_child1_child3.AlignSelf = YogaAlign.Baseline; + root_child1_child3.Width = 25; + root_child1_child3.Height = 10; + root_child1.Insert(3, root_child1_child3); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(60f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(25f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(25f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child1.LayoutX); + Assert.AreEqual(0f, root_child1_child1.LayoutY); + Assert.AreEqual(25f, root_child1_child1.LayoutWidth); + Assert.AreEqual(10f, root_child1_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child2.LayoutX); + Assert.AreEqual(20f, root_child1_child2.LayoutY); + Assert.AreEqual(25f, root_child1_child2.LayoutWidth); + Assert.AreEqual(20f, root_child1_child2.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child3.LayoutX); + Assert.AreEqual(20f, root_child1_child3.LayoutY); + Assert.AreEqual(25f, root_child1_child3.LayoutWidth); + Assert.AreEqual(10f, root_child1_child3.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(60f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(25f, root_child1.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(25f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child1.LayoutX); + Assert.AreEqual(0f, root_child1_child1.LayoutY); + Assert.AreEqual(25f, root_child1_child1.LayoutWidth); + Assert.AreEqual(10f, root_child1_child1.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child2.LayoutX); + Assert.AreEqual(20f, root_child1_child2.LayoutY); + Assert.AreEqual(25f, root_child1_child2.LayoutWidth); + Assert.AreEqual(20f, root_child1_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child3.LayoutX); + Assert.AreEqual(20f, root_child1_child3.LayoutY); + Assert.AreEqual(25f, root_child1_child3.LayoutWidth); + Assert.AreEqual(10f, root_child1_child3.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child_multiline_no_override_on_secondline() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 60; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.FlexDirection = YogaFlexDirection.Row; + root_child1.Wrap = YogaWrap.Wrap; + root_child1.Width = 50; + root_child1.Height = 25; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 25; + root_child1_child0.Height = 20; + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child1_child1 = new YogaNode(); + root_child1_child1.Width = 25; + root_child1_child1.Height = 10; + root_child1.Insert(1, root_child1_child1); + + YogaNode root_child1_child2 = new YogaNode(); + root_child1_child2.Width = 25; + root_child1_child2.Height = 20; + root_child1.Insert(2, root_child1_child2); + + YogaNode root_child1_child3 = new YogaNode(); + root_child1_child3.AlignSelf = YogaAlign.Baseline; + root_child1_child3.Width = 25; + root_child1_child3.Height = 10; + root_child1.Insert(3, root_child1_child3); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(60f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(25f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(25f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child1.LayoutX); + Assert.AreEqual(0f, root_child1_child1.LayoutY); + Assert.AreEqual(25f, root_child1_child1.LayoutWidth); + Assert.AreEqual(10f, root_child1_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child2.LayoutX); + Assert.AreEqual(20f, root_child1_child2.LayoutY); + Assert.AreEqual(25f, root_child1_child2.LayoutWidth); + Assert.AreEqual(20f, root_child1_child2.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child3.LayoutX); + Assert.AreEqual(20f, root_child1_child3.LayoutY); + Assert.AreEqual(25f, root_child1_child3.LayoutWidth); + Assert.AreEqual(10f, root_child1_child3.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(60f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(25f, root_child1.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(25f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child1.LayoutX); + Assert.AreEqual(0f, root_child1_child1.LayoutY); + Assert.AreEqual(25f, root_child1_child1.LayoutWidth); + Assert.AreEqual(10f, root_child1_child1.LayoutHeight); + + Assert.AreEqual(25f, root_child1_child2.LayoutX); + Assert.AreEqual(20f, root_child1_child2.LayoutY); + Assert.AreEqual(25f, root_child1_child2.LayoutWidth); + Assert.AreEqual(20f, root_child1_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child3.LayoutX); + Assert.AreEqual(20f, root_child1_child3.LayoutY); + Assert.AreEqual(25f, root_child1_child3.LayoutWidth); + Assert.AreEqual(10f, root_child1_child3.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child_top() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.SetPosition(YogaEdge.Top, 10); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(10f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(10f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child_top2() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.SetPosition(YogaEdge.Top, 5); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(45f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(45f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + } + + [Test] + public void Test_align_baseline_double_nested_child() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.Width = 50; + root_child0_child0.Height = 20; + root_child0.Insert(0, root_child0_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 15; + root_child1.Insert(0, root_child1_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(50f, root_child0_child0.LayoutWidth); + Assert.AreEqual(20f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(5f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(15f, root_child1_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child0_child0.LayoutX); + Assert.AreEqual(0f, root_child0_child0.LayoutY); + Assert.AreEqual(50f, root_child0_child0.LayoutWidth); + Assert.AreEqual(20f, root_child0_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(5f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(15f, root_child1_child0.LayoutHeight); + } + + [Test] + public void Test_align_baseline_column() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child_margin() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.SetMargin(YogaEdge.Left, 5); + root_child0.SetMargin(YogaEdge.Top, 5); + root_child0.SetMargin(YogaEdge.Right, 5); + root_child0.SetMargin(YogaEdge.Bottom, 5); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.SetMargin(YogaEdge.Left, 1); + root_child1_child0.SetMargin(YogaEdge.Top, 1); + root_child1_child0.SetMargin(YogaEdge.Right, 1); + root_child1_child0.SetMargin(YogaEdge.Bottom, 1); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(5f, root_child0.LayoutX); + Assert.AreEqual(5f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(60f, root_child1.LayoutX); + Assert.AreEqual(44f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(1f, root_child1_child0.LayoutX); + Assert.AreEqual(1f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(45f, root_child0.LayoutX); + Assert.AreEqual(5f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(-10f, root_child1.LayoutX); + Assert.AreEqual(44f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(-1f, root_child1_child0.LayoutX); + Assert.AreEqual(1f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + } + + [Test] + public void Test_align_baseline_child_padding() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.SetPadding(YogaEdge.Left, 5); + root.SetPadding(YogaEdge.Top, 5); + root.SetPadding(YogaEdge.Right, 5); + root.SetPadding(YogaEdge.Bottom, 5); + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.SetPadding(YogaEdge.Left, 5); + root_child1.SetPadding(YogaEdge.Top, 5); + root_child1.SetPadding(YogaEdge.Right, 5); + root_child1.SetPadding(YogaEdge.Bottom, 5); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(5f, root_child0.LayoutX); + Assert.AreEqual(5f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(55f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(5f, root_child1_child0.LayoutX); + Assert.AreEqual(5f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(45f, root_child0.LayoutX); + Assert.AreEqual(5f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(-5f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(-5f, root_child1_child0.LayoutX); + Assert.AreEqual(5f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + } + + [Test] + public void Test_align_baseline_multiline() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Wrap = YogaWrap.Wrap; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root_child2.Height = 20; + root.Insert(2, root_child2); + + YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.Width = 50; + root_child2_child0.Height = 10; + root_child2.Insert(0, root_child2_child0); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root_child3.Height = 50; + root.Insert(3, root_child3); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(100f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(20f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(50f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(60f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(100f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(20f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(50f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(60f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(50f, root_child3.LayoutHeight); + } + + [Test] + public void Test_align_baseline_multiline_column() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Baseline; + root.Wrap = YogaWrap.Wrap; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 30; + root_child1.Height = 50; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 20; + root_child1_child0.Height = 20; + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 40; + root_child2.Height = 70; + root.Insert(2, root_child2); + + YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.Width = 10; + root_child2_child0.Height = 10; + root_child2.Insert(0, root_child2_child0); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root_child3.Height = 20; + root.Insert(3, root_child3); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(30f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(20f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(40f, root_child2.LayoutWidth); + Assert.AreEqual(70f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(10f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(70f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(70f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(30f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(10f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(20f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(10f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(40f, root_child2.LayoutWidth); + Assert.AreEqual(70f, root_child2.LayoutHeight); + + Assert.AreEqual(30f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(10f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(70f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + } + + [Test] + public void Test_align_baseline_multiline_column2() + { + YogaNode root = new YogaNode(); + root.AlignItems = YogaAlign.Baseline; + root.Wrap = YogaWrap.Wrap; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 30; + root_child1.Height = 50; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 20; + root_child1_child0.Height = 20; + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 40; + root_child2.Height = 70; + root.Insert(2, root_child2); + + YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.Width = 10; + root_child2_child0.Height = 10; + root_child2.Insert(0, root_child2_child0); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root_child3.Height = 20; + root.Insert(3, root_child3); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(30f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(20f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(40f, root_child2.LayoutWidth); + Assert.AreEqual(70f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(10f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(70f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(70f, root_child1.LayoutX); + Assert.AreEqual(50f, root_child1.LayoutY); + Assert.AreEqual(30f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(10f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(20f, root_child1_child0.LayoutWidth); + Assert.AreEqual(20f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(10f, root_child2.LayoutX); + Assert.AreEqual(0f, root_child2.LayoutY); + Assert.AreEqual(40f, root_child2.LayoutWidth); + Assert.AreEqual(70f, root_child2.LayoutHeight); + + Assert.AreEqual(30f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(10f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(70f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + } + + [Test] + public void Test_align_baseline_multiline_row_and_column() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.AlignItems = YogaAlign.Baseline; + root.Wrap = YogaWrap.Wrap; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.Width = 50; + root_child1.Height = 50; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + + YogaNode root_child2 = new YogaNode(); + root_child2.Width = 50; + root_child2.Height = 20; + root.Insert(2, root_child2); + + YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.Width = 50; + root_child2_child0.Height = 10; + root_child2.Insert(0, root_child2_child0); + + YogaNode root_child3 = new YogaNode(); + root_child3.Width = 50; + root_child3.Height = 20; + root.Insert(3, root_child3); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child2.LayoutX); + Assert.AreEqual(100f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(20f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(50f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child3.LayoutX); + Assert.AreEqual(90f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(50f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child2.LayoutX); + Assert.AreEqual(100f, root_child2.LayoutY); + Assert.AreEqual(50f, root_child2.LayoutWidth); + Assert.AreEqual(20f, root_child2.LayoutHeight); + + Assert.AreEqual(0f, root_child2_child0.LayoutX); + Assert.AreEqual(0f, root_child2_child0.LayoutY); + Assert.AreEqual(50f, root_child2_child0.LayoutWidth); + Assert.AreEqual(10f, root_child2_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child3.LayoutX); + Assert.AreEqual(90f, root_child3.LayoutY); + Assert.AreEqual(50f, root_child3.LayoutWidth); + Assert.AreEqual(20f, root_child3.LayoutHeight); + } + } } diff --git a/csharp/tests/Facebook.Yoga/YGAlignSelfTest.cs b/csharp/tests/Facebook.Yoga/YGAlignSelfTest.cs index b4ca0e13..520d5e8c 100644 --- a/csharp/tests/Facebook.Yoga/YGAlignSelfTest.cs +++ b/csharp/tests/Facebook.Yoga/YGAlignSelfTest.cs @@ -174,5 +174,76 @@ namespace Facebook.Yoga Assert.AreEqual(10f, root_child0.LayoutHeight); } + [Test] + public void Test_align_self_baseline() + { + YogaNode root = new YogaNode(); + root.FlexDirection = YogaFlexDirection.Row; + root.Width = 100; + root.Height = 100; + + YogaNode root_child0 = new YogaNode(); + root_child0.AlignSelf = YogaAlign.Baseline; + root_child0.Width = 50; + root_child0.Height = 50; + root.Insert(0, root_child0); + + YogaNode root_child1 = new YogaNode(); + root_child1.AlignSelf = YogaAlign.Baseline; + root_child1.Width = 50; + root_child1.Height = 20; + root.Insert(1, root_child1); + + YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.Width = 50; + root_child1_child0.Height = 10; + root_child1.Insert(0, root_child1_child0); + root.StyleDirection = YogaDirection.LTR; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(0f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(50f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + + root.StyleDirection = YogaDirection.RTL; + root.CalculateLayout(); + + Assert.AreEqual(0f, root.LayoutX); + Assert.AreEqual(0f, root.LayoutY); + Assert.AreEqual(100f, root.LayoutWidth); + Assert.AreEqual(100f, root.LayoutHeight); + + Assert.AreEqual(50f, root_child0.LayoutX); + Assert.AreEqual(0f, root_child0.LayoutY); + Assert.AreEqual(50f, root_child0.LayoutWidth); + Assert.AreEqual(50f, root_child0.LayoutHeight); + + Assert.AreEqual(0f, root_child1.LayoutX); + Assert.AreEqual(40f, root_child1.LayoutY); + Assert.AreEqual(50f, root_child1.LayoutWidth); + Assert.AreEqual(20f, root_child1.LayoutHeight); + + Assert.AreEqual(0f, root_child1_child0.LayoutX); + Assert.AreEqual(0f, root_child1_child0.LayoutY); + Assert.AreEqual(50f, root_child1_child0.LayoutWidth); + Assert.AreEqual(10f, root_child1_child0.LayoutHeight); + } + } } diff --git a/enums.py b/enums.py index 3b433a72..53b2ab53 100644 --- a/enums.py +++ b/enums.py @@ -46,6 +46,7 @@ ENUMS = { 'Center', 'FlexEnd', 'Stretch', + 'Baseline', ], 'PositionType': [ 'Relative', diff --git a/gentest/fixtures/YGAlignItemsTest.html b/gentest/fixtures/YGAlignItemsTest.html index e040b9ed..49aaa9aa 100644 --- a/gentest/fixtures/YGAlignItemsTest.html +++ b/gentest/fixtures/YGAlignItemsTest.html @@ -13,3 +13,135 @@
+ +
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+ + +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ + +
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
\ No newline at end of file diff --git a/gentest/fixtures/YGAlignSelfTest.html b/gentest/fixtures/YGAlignSelfTest.html index 047de30c..c2f656ed 100644 --- a/gentest/fixtures/YGAlignSelfTest.html +++ b/gentest/fixtures/YGAlignSelfTest.html @@ -13,3 +13,11 @@
+ + +
+
+
+
+
+
diff --git a/gentest/gentest-cpp.js b/gentest/gentest-cpp.js index f8ecf8be..4834b45a 100644 --- a/gentest/gentest-cpp.js +++ b/gentest/gentest-cpp.js @@ -83,6 +83,8 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, { YGAlignFlexStart:{value:'YGAlignFlexStart'}, YGAlignStretch:{value:'YGAlignStretch'}, + YGAlignBaseline:{value:'YGAlignBaseline'}, + YGDirectionInherit:{value:'YGDirectionInherit'}, YGDirectionLTR:{value:'YGDirectionLTR'}, YGDirectionRTL:{value:'YGDirectionRTL'}, diff --git a/gentest/gentest-cs.js b/gentest/gentest-cs.js index 3c78198d..22ffa846 100644 --- a/gentest/gentest-cs.js +++ b/gentest/gentest-cs.js @@ -96,6 +96,7 @@ CSEmitter.prototype = Object.create(Emitter.prototype, { YGAlignFlexEnd:{value:'YogaAlign.FlexEnd'}, YGAlignFlexStart:{value:'YogaAlign.FlexStart'}, YGAlignStretch:{value:'YogaAlign.Stretch'}, + YGAlignBaseline:{value:'YogaAlign.Baseline'}, YGDirectionInherit:{value:'YogaDirection.Inherit'}, YGDirectionLTR:{value:'YogaDirection.LTR'}, diff --git a/gentest/gentest-java.js b/gentest/gentest-java.js index 36fd578a..1c510c48 100644 --- a/gentest/gentest-java.js +++ b/gentest/gentest-java.js @@ -100,6 +100,7 @@ JavaEmitter.prototype = Object.create(Emitter.prototype, { YGAlignFlexEnd:{value:'YogaAlign.FLEX_END'}, YGAlignFlexStart:{value:'YogaAlign.FLEX_START'}, YGAlignStretch:{value:'YogaAlign.STRETCH'}, + YGAlignBaseline:{value:'YogaAlign.BASELINE'}, YGDirectionInherit:{value:'YogaDirection.INHERIT'}, YGDirectionLTR:{value:'YogaDirection.LTR'}, diff --git a/gentest/gentest-javascript.js b/gentest/gentest-javascript.js index 9a081592..8f56477e 100644 --- a/gentest/gentest-javascript.js +++ b/gentest/gentest-javascript.js @@ -90,6 +90,7 @@ JavascriptEmitter.prototype = Object.create(Emitter.prototype, { YGAlignFlexEnd:{value:'Yoga.ALIGN_FLEX_END'}, YGAlignFlexStart:{value:'Yoga.ALIGN_FLEX_START'}, YGAlignStretch:{value:'Yoga.ALIGN_STRETCH'}, + YGAlignBaseline:{value:'Yoga.ALIGN_BASELINE'}, YGDirectionInherit:{value:'Yoga.DIRECTION_INHERIT'}, YGDirectionLTR:{value:'Yoga.DIRECTION_LTR'}, diff --git a/gentest/gentest.js b/gentest/gentest.js index 59341c88..2c63d9ae 100755 --- a/gentest/gentest.js +++ b/gentest/gentest.js @@ -377,6 +377,7 @@ function alignValue(e, value) { case 'stretch': return e.YGAlignStretch; case 'flex-start': return e.YGAlignFlexStart; case 'flex-end': return e.YGAlignFlexEnd; + case 'baseline': return e.YGAlignBaseline; } } diff --git a/java/com/facebook/yoga/YogaAlign.java b/java/com/facebook/yoga/YogaAlign.java index 74bcde73..7466dcda 100644 --- a/java/com/facebook/yoga/YogaAlign.java +++ b/java/com/facebook/yoga/YogaAlign.java @@ -17,7 +17,8 @@ public enum YogaAlign { FLEX_START(1), CENTER(2), FLEX_END(3), - STRETCH(4); + STRETCH(4), + BASELINE(5); private int mIntValue; @@ -36,6 +37,7 @@ public enum YogaAlign { case 2: return CENTER; case 3: return FLEX_END; case 4: return STRETCH; + case 5: return BASELINE; default: throw new IllegalArgumentException("Unkown enum value: " + value); } } diff --git a/java/tests/com/facebook/yoga/YGAlignItemsTest.java b/java/tests/com/facebook/yoga/YGAlignItemsTest.java index c7fd7a2a..b4585437 100644 --- a/java/tests/com/facebook/yoga/YGAlignItemsTest.java +++ b/java/tests/com/facebook/yoga/YGAlignItemsTest.java @@ -166,4 +166,1367 @@ public class YGAlignItemsTest { assertEquals(10f, root_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_align_baseline() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(30f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(30f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child_multiline() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(60f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexDirection(YogaFlexDirection.ROW); + root_child1.setWrap(YogaWrap.WRAP); + root_child1.setWidth(50f); + root_child1.setHeight(25f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(25f); + root_child1_child0.setHeight(20f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child1_child1 = new YogaNode(); + root_child1_child1.setWidth(25f); + root_child1_child1.setHeight(10f); + root_child1.addChildAt(root_child1_child1, 1); + + final YogaNode root_child1_child2 = new YogaNode(); + root_child1_child2.setWidth(25f); + root_child1_child2.setHeight(20f); + root_child1.addChildAt(root_child1_child2, 2); + + final YogaNode root_child1_child3 = new YogaNode(); + root_child1_child3.setWidth(25f); + root_child1_child3.setHeight(10f); + root_child1.addChildAt(root_child1_child3, 3); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(25f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child2.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child3.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child3.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child3.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(25f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child1.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child2.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child3.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child3.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child3.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child_multiline_override() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(60f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexDirection(YogaFlexDirection.ROW); + root_child1.setWrap(YogaWrap.WRAP); + root_child1.setWidth(50f); + root_child1.setHeight(25f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(25f); + root_child1_child0.setHeight(20f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child1_child1 = new YogaNode(); + root_child1_child1.setAlignSelf(YogaAlign.BASELINE); + root_child1_child1.setWidth(25f); + root_child1_child1.setHeight(10f); + root_child1.addChildAt(root_child1_child1, 1); + + final YogaNode root_child1_child2 = new YogaNode(); + root_child1_child2.setWidth(25f); + root_child1_child2.setHeight(20f); + root_child1.addChildAt(root_child1_child2, 2); + + final YogaNode root_child1_child3 = new YogaNode(); + root_child1_child3.setAlignSelf(YogaAlign.BASELINE); + root_child1_child3.setWidth(25f); + root_child1_child3.setHeight(10f); + root_child1.addChildAt(root_child1_child3, 3); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(25f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child2.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child3.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child3.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child3.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(25f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child1.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child2.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child3.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child3.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child3.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child_multiline_no_override_on_secondline() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(60f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setFlexDirection(YogaFlexDirection.ROW); + root_child1.setWrap(YogaWrap.WRAP); + root_child1.setWidth(50f); + root_child1.setHeight(25f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(25f); + root_child1_child0.setHeight(20f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child1_child1 = new YogaNode(); + root_child1_child1.setWidth(25f); + root_child1_child1.setHeight(10f); + root_child1.addChildAt(root_child1_child1, 1); + + final YogaNode root_child1_child2 = new YogaNode(); + root_child1_child2.setWidth(25f); + root_child1_child2.setHeight(20f); + root_child1.addChildAt(root_child1_child2, 2); + + final YogaNode root_child1_child3 = new YogaNode(); + root_child1_child3.setAlignSelf(YogaAlign.BASELINE); + root_child1_child3.setWidth(25f); + root_child1_child3.setHeight(10f); + root_child1.addChildAt(root_child1_child3, 3); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(25f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child2.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child3.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child3.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child3.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(60f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(25f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child1.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child1.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child1.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child1.getLayoutHeight(), 0.0f); + + assertEquals(25f, root_child1_child2.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child3.getLayoutX(), 0.0f); + assertEquals(20f, root_child1_child3.getLayoutY(), 0.0f); + assertEquals(25f, root_child1_child3.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child3.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child_top() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setPosition(YogaEdge.TOP, 10f); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(10f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(10f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child_top2() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setPosition(YogaEdge.TOP, 5f); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(45f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(45f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_double_nested_child() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child0_child0 = new YogaNode(); + root_child0_child0.setWidth(50f); + root_child0_child0.setHeight(20f); + root_child0.addChildAt(root_child0_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(15f); + root_child1.addChildAt(root_child1_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(5f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(15f, root_child1_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child0_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(5f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(15f, root_child1_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_column() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child_margin() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setMargin(YogaEdge.LEFT, 5f); + root_child0.setMargin(YogaEdge.TOP, 5f); + root_child0.setMargin(YogaEdge.RIGHT, 5f); + root_child0.setMargin(YogaEdge.BOTTOM, 5f); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setMargin(YogaEdge.LEFT, 1f); + root_child1_child0.setMargin(YogaEdge.TOP, 1f); + root_child1_child0.setMargin(YogaEdge.RIGHT, 1f); + root_child1_child0.setMargin(YogaEdge.BOTTOM, 1f); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(5f, root_child0.getLayoutX(), 0.0f); + assertEquals(5f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(60f, root_child1.getLayoutX(), 0.0f); + assertEquals(44f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(1f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(1f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(45f, root_child0.getLayoutX(), 0.0f); + assertEquals(5f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(-10f, root_child1.getLayoutX(), 0.0f); + assertEquals(44f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-1f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(1f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_child_padding() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setPadding(YogaEdge.LEFT, 5); + root.setPadding(YogaEdge.TOP, 5); + root.setPadding(YogaEdge.RIGHT, 5); + root.setPadding(YogaEdge.BOTTOM, 5); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setPadding(YogaEdge.LEFT, 5); + root_child1.setPadding(YogaEdge.TOP, 5); + root_child1.setPadding(YogaEdge.RIGHT, 5); + root_child1.setPadding(YogaEdge.BOTTOM, 5); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(5f, root_child0.getLayoutX(), 0.0f); + assertEquals(5f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(55f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(5f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(5f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(45f, root_child0.getLayoutX(), 0.0f); + assertEquals(5f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(-5f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(-5f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(5f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_multiline() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root_child2.setHeight(20f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.setWidth(50f); + root_child2_child0.setHeight(10f); + root_child2.addChildAt(root_child2_child0, 0); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root_child3.setHeight(50f); + root.addChildAt(root_child3, 3); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(100f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(60f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(100f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(60f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child3.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_multiline_column() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.BASELINE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(30f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(20f); + root_child1_child0.setHeight(20f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(40f); + root_child2.setHeight(70f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.setWidth(10f); + root_child2_child0.setHeight(10f); + root_child2.addChildAt(root_child2_child0, 0); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root_child3.setHeight(20f); + root.addChildAt(root_child3, 3); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(30f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(70f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(70f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(70f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(30f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(10f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(10f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(70f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(30f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(70f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_multiline_column2() { + final YogaNode root = new YogaNode(); + root.setAlignItems(YogaAlign.BASELINE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(30f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(20f); + root_child1_child0.setHeight(20f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(40f); + root_child2.setHeight(70f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.setWidth(10f); + root_child2_child0.setHeight(10f); + root_child2.addChildAt(root_child2_child0, 0); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root_child3.setHeight(20f); + root.addChildAt(root_child3, 3); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(30f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(70f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(70f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(70f, root_child1.getLayoutX(), 0.0f); + assertEquals(50f, root_child1.getLayoutY(), 0.0f); + assertEquals(30f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(10f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(10f, root_child2.getLayoutX(), 0.0f); + assertEquals(0f, root_child2.getLayoutY(), 0.0f); + assertEquals(40f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(70f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(30f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(70f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + } + + @Test + public void test_align_baseline_multiline_row_and_column() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setAlignItems(YogaAlign.BASELINE); + root.setWrap(YogaWrap.WRAP); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setWidth(50f); + root_child1.setHeight(50f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + + final YogaNode root_child2 = new YogaNode(); + root_child2.setWidth(50f); + root_child2.setHeight(20f); + root.addChildAt(root_child2, 2); + + final YogaNode root_child2_child0 = new YogaNode(); + root_child2_child0.setWidth(50f); + root_child2_child0.setHeight(10f); + root_child2.addChildAt(root_child2_child0, 0); + + final YogaNode root_child3 = new YogaNode(); + root_child3.setWidth(50f); + root_child3.setHeight(20f); + root.addChildAt(root_child3, 3); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2.getLayoutX(), 0.0f); + assertEquals(100f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child3.getLayoutX(), 0.0f); + assertEquals(90f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child2.getLayoutX(), 0.0f); + assertEquals(100f, root_child2.getLayoutY(), 0.0f); + assertEquals(50f, root_child2.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child2.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child2_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child2_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child2_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child2_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child3.getLayoutX(), 0.0f); + assertEquals(90f, root_child3.getLayoutY(), 0.0f); + assertEquals(50f, root_child3.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child3.getLayoutHeight(), 0.0f); + } + } diff --git a/java/tests/com/facebook/yoga/YGAlignSelfTest.java b/java/tests/com/facebook/yoga/YGAlignSelfTest.java index f8dc750b..006ae1f7 100644 --- a/java/tests/com/facebook/yoga/YGAlignSelfTest.java +++ b/java/tests/com/facebook/yoga/YGAlignSelfTest.java @@ -169,4 +169,74 @@ public class YGAlignSelfTest { assertEquals(10f, root_child0.getLayoutHeight(), 0.0f); } + @Test + public void test_align_self_baseline() { + final YogaNode root = new YogaNode(); + root.setFlexDirection(YogaFlexDirection.ROW); + root.setWidth(100f); + root.setHeight(100f); + + final YogaNode root_child0 = new YogaNode(); + root_child0.setAlignSelf(YogaAlign.BASELINE); + root_child0.setWidth(50f); + root_child0.setHeight(50f); + root.addChildAt(root_child0, 0); + + final YogaNode root_child1 = new YogaNode(); + root_child1.setAlignSelf(YogaAlign.BASELINE); + root_child1.setWidth(50f); + root_child1.setHeight(20f); + root.addChildAt(root_child1, 1); + + final YogaNode root_child1_child0 = new YogaNode(); + root_child1_child0.setWidth(50f); + root_child1_child0.setHeight(10f); + root_child1.addChildAt(root_child1_child0, 0); + root.setDirection(YogaDirection.LTR); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + + root.setDirection(YogaDirection.RTL); + root.calculateLayout(); + + assertEquals(0f, root.getLayoutX(), 0.0f); + assertEquals(0f, root.getLayoutY(), 0.0f); + assertEquals(100f, root.getLayoutWidth(), 0.0f); + assertEquals(100f, root.getLayoutHeight(), 0.0f); + + assertEquals(50f, root_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child0.getLayoutWidth(), 0.0f); + assertEquals(50f, root_child0.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1.getLayoutX(), 0.0f); + assertEquals(40f, root_child1.getLayoutY(), 0.0f); + assertEquals(50f, root_child1.getLayoutWidth(), 0.0f); + assertEquals(20f, root_child1.getLayoutHeight(), 0.0f); + + assertEquals(0f, root_child1_child0.getLayoutX(), 0.0f); + assertEquals(0f, root_child1_child0.getLayoutY(), 0.0f); + assertEquals(50f, root_child1_child0.getLayoutWidth(), 0.0f); + assertEquals(10f, root_child1_child0.getLayoutHeight(), 0.0f); + } + } diff --git a/javascript/sources/YGEnums.js b/javascript/sources/YGEnums.js index 0d6bfa8b..400f27f1 100644 --- a/javascript/sources/YGEnums.js +++ b/javascript/sources/YGEnums.js @@ -76,12 +76,13 @@ module.exports = { EXPERIMENTAL_FEATURE_ROUNDING: 0, EXPERIMENTAL_FEATURE_WEB_FLEX_BASIS: 1, - ALIGN_COUNT: 5, + ALIGN_COUNT: 6, ALIGN_AUTO: 0, ALIGN_FLEX_START: 1, ALIGN_CENTER: 2, ALIGN_FLEX_END: 3, ALIGN_STRETCH: 4, + ALIGN_BASELINE: 5, UNIT_COUNT: 3, UNIT_UNDEFINED: 0, diff --git a/tests/YGAlignItemsTest.cpp b/tests/YGAlignItemsTest.cpp index e80ae1d4..dbbd1e9b 100644 --- a/tests/YGAlignItemsTest.cpp +++ b/tests/YGAlignItemsTest.cpp @@ -157,3 +157,1351 @@ TEST(YogaTest, align_items_flex_end) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, align_baseline) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child_multiline) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 25); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child1_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child1, 25); + YGNodeStyleSetHeight(root_child1_child1, 10); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + const YGNodeRef root_child1_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child2, 25); + YGNodeStyleSetHeight(root_child1_child2, 20); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + const YGNodeRef root_child1_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child3, 25); + YGNodeStyleSetHeight(root_child1_child3, 10); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child_multiline_override) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 25); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child1_child1 = YGNodeNew(); + YGNodeStyleSetAlignSelf(root_child1_child1, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1_child1, 25); + YGNodeStyleSetHeight(root_child1_child1, 10); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + const YGNodeRef root_child1_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child2, 25); + YGNodeStyleSetHeight(root_child1_child2, 20); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + const YGNodeRef root_child1_child3 = YGNodeNew(); + YGNodeStyleSetAlignSelf(root_child1_child3, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1_child3, 25); + YGNodeStyleSetHeight(root_child1_child3, 10); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child_multiline_no_override_on_secondline) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 60); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetFlexDirection(root_child1, YGFlexDirectionRow); + YGNodeStyleSetFlexWrap(root_child1, YGWrapWrap); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 25); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 25); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child1_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child1, 25); + YGNodeStyleSetHeight(root_child1_child1, 10); + YGNodeInsertChild(root_child1, root_child1_child1, 1); + + const YGNodeRef root_child1_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child2, 25); + YGNodeStyleSetHeight(root_child1_child2, 20); + YGNodeInsertChild(root_child1, root_child1_child2, 2); + + const YGNodeRef root_child1_child3 = YGNodeNew(); + YGNodeStyleSetAlignSelf(root_child1_child3, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1_child3, 25); + YGNodeStyleSetHeight(root_child1_child3, 10); + YGNodeInsertChild(root_child1, root_child1_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child1)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child1)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child1)); + + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetLeft(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child2)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetTop(root_child1_child3)); + ASSERT_FLOAT_EQ(25, YGNodeLayoutGetWidth(root_child1_child3)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child3)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child_top) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child_top2) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetPosition(root_child1, YGEdgeTop, 5); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_double_nested_child) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0_child0, 50); + YGNodeStyleSetHeight(root_child0_child0, 20); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 15); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(15, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child_margin) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetMargin(root_child0, YGEdgeLeft, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeTop, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeRight, 5); + YGNodeStyleSetMargin(root_child0, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeLeft, 1); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeTop, 1); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeRight, 1); + YGNodeStyleSetMargin(root_child1_child0, YGEdgeBottom, 1); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(44, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(-10, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(44, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-1, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(1, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_child_padding) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetPadding(root, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root, YGEdgeTop, 5); + YGNodeStyleSetPadding(root, YGEdgeRight, 5); + YGNodeStyleSetPadding(root, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetPadding(root_child1, YGEdgeLeft, 5); + YGNodeStyleSetPadding(root_child1, YGEdgeTop, 5); + YGNodeStyleSetPadding(root_child1, YGEdgeRight, 5); + YGNodeStyleSetPadding(root_child1, YGEdgeBottom, 5); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(55, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(45, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(-5, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(5, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_multiline) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2_child0, 50); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 50); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_multiline_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 20); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 40); + YGNodeStyleSetHeight(root_child2, 70); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2_child0, 10); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_multiline_column2) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 30); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 20); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 40); + YGNodeStyleSetHeight(root_child2, 70); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2_child0, 10); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(30, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(70, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); +} + +TEST(YogaTest, align_baseline_multiline_row_and_column) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetFlexWrap(root, YGWrapWrap); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 50); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + + const YGNodeRef root_child2 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2, 50); + YGNodeStyleSetHeight(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child2_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child2_child0, 50); + YGNodeStyleSetHeight(root_child2_child0, 10); + YGNodeInsertChild(root_child2, root_child2_child0, 0); + + const YGNodeRef root_child3 = YGNodeNew(); + YGNodeStyleSetWidth(root_child3, 50); + YGNodeStyleSetHeight(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child2_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child2_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child2_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(90, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); +} diff --git a/tests/YGAlignSelfTest.cpp b/tests/YGAlignSelfTest.cpp index 436d78b4..79e3f89b 100644 --- a/tests/YGAlignSelfTest.cpp +++ b/tests/YGAlignSelfTest.cpp @@ -160,3 +160,72 @@ TEST(YogaTest, align_self_flex_end_override_flex_start) { YGNodeFreeRecursive(root); } + +TEST(YogaTest, align_self_baseline) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetAlignSelf(root_child0, YGAlignBaseline); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetAlignSelf(root_child1, YGAlignBaseline); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeStyleSetHeight(root_child1_child0, 10); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(root_child1_child0)); + + YGNodeFreeRecursive(root); +} diff --git a/tests/YGBaselineFuncTest.cpp b/tests/YGBaselineFuncTest.cpp new file mode 100644 index 00000000..f48dc6ec --- /dev/null +++ b/tests/YGBaselineFuncTest.cpp @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include +#include + +static float _baseline(YGNodeRef node, const float width, const float height) { + float *baseline = (float *) YGNodeGetContext(node); + return *baseline; +} + +TEST(YogaTest, align_baseline_customer_func) { + const YGNodeRef root = YGNodeNew(); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignBaseline); + YGNodeStyleSetWidth(root, 100); + YGNodeStyleSetHeight(root, 100); + + const YGNodeRef root_child0 = YGNodeNew(); + YGNodeStyleSetWidth(root_child0, 50); + YGNodeStyleSetHeight(root_child0, 50); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNew(); + YGNodeStyleSetWidth(root_child1, 50); + YGNodeStyleSetHeight(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + float baselineValue = 10; + const YGNodeRef root_child1_child0 = YGNodeNew(); + YGNodeSetContext(root_child1_child0, &baselineValue); + YGNodeStyleSetWidth(root_child1_child0, 50); + YGNodeSetBaselineFunc(root_child1_child0, _baseline); + YGNodeStyleSetHeight(root_child1_child0, 20); + YGNodeInsertChild(root_child1, root_child1_child0, 0); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1_child0)); + ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetHeight(root_child1_child0)); +} diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h index be60e02c..24606bcd 100644 --- a/yoga/YGEnums.h +++ b/yoga/YGEnums.h @@ -104,13 +104,14 @@ typedef enum YGExperimentalFeature { YGExperimentalFeatureWebFlexBasis, } YGExperimentalFeature; -#define YGAlignCount 5 +#define YGAlignCount 6 typedef enum YGAlign { YGAlignAuto, YGAlignFlexStart, YGAlignCenter, YGAlignFlexEnd, YGAlignStretch, + YGAlignBaseline, } YGAlign; #define YGUnitCount 3 diff --git a/yoga/Yoga.c b/yoga/Yoga.c index bc73ecbc..d5e4917b 100644 --- a/yoga/Yoga.c +++ b/yoga/Yoga.c @@ -102,6 +102,7 @@ typedef struct YGNode { struct YGNode *nextChild; YGMeasureFunc measure; + YGBaselineFunc baseline; YGPrintFunc print; void *context; @@ -337,6 +338,14 @@ YGMeasureFunc YGNodeGetMeasureFunc(const YGNodeRef node) { return node->measure; } +void YGNodeSetBaselineFunc(const YGNodeRef node, YGBaselineFunc baselineFunc) { + node->baseline = baselineFunc; +} + +YGBaselineFunc YGNodeGetBaselineFunc(const YGNodeRef node) { + return node->baseline; +} + void YGNodeInsertChild(const YGNodeRef node, const YGNodeRef child, const uint32_t index) { YG_ASSERT(child->parent == NULL, "Child already has a parent, it must be removed first."); YG_ASSERT(node->measure == NULL, @@ -893,8 +902,8 @@ static float YGNodeLeadingPadding(const YGNodeRef node, } return fmaxf(YGValueResolve(YGComputedEdgeValue(node->style.padding, leading[axis], &YGValueZero), - widthSize), - 0.0f); + widthSize), + 0.0f); } static float YGNodeTrailingPadding(const YGNodeRef node, @@ -906,8 +915,8 @@ static float YGNodeTrailingPadding(const YGNodeRef node, } return fmaxf(YGValueResolve(YGComputedEdgeValue(node->style.padding, trailing[axis], &YGValueZero), - widthSize), - 0.0f); + widthSize), + 0.0f); } static float YGNodeLeadingBorder(const YGNodeRef node, const YGFlexDirection axis) { @@ -954,7 +963,12 @@ static inline float YGNodePaddingAndBorderForAxis(const YGNodeRef node, } static inline YGAlign YGNodeAlignItem(const YGNodeRef node, const YGNodeRef child) { - return child->style.alignSelf == YGAlignAuto ? node->style.alignItems : child->style.alignSelf; + const YGAlign align = + child->style.alignSelf == YGAlignAuto ? node->style.alignItems : child->style.alignSelf; + if (align == YGAlignBaseline && YGFlexDirectionIsColumn(node->style.flexDirection)) { + return YGAlignFlexStart; + } + return align; } static inline YGDirection YGNodeResolveDirection(const YGNodeRef node, @@ -966,6 +980,40 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node, } } +static float YGBaseline(const YGNodeRef node) { + if (node->baseline != NULL) { + const float baseline = node->baseline(node, node->layout.measuredDimensions[YGDimensionWidth], node->layout.measuredDimensions[YGDimensionHeight]); + YG_ASSERT(!YGFloatIsUndefined(baseline), "Expect custom baseline function to not return NaN") + return baseline; + } + + YGNodeRef baselineChild = NULL; + for (uint32_t i = 0; i < YGNodeGetChildCount(node); i++) { + const YGNodeRef child = YGNodeGetChild(node, i); + if (child->lineIndex > 0) { + break; + } + if (child->style.positionType == YGPositionTypeAbsolute) { + continue; + } + if (YGNodeAlignItem(node, child) == YGAlignBaseline) { + baselineChild = child; + break; + } + + if (baselineChild == NULL) { + baselineChild = child; + } + } + + if (baselineChild == NULL) { + return node->layout.measuredDimensions[YGDimensionHeight]; + } + + const float baseline = YGBaseline(baselineChild); + return baseline + baselineChild->layout.position[YGEdgeTop]; +} + static inline YGFlexDirection YGFlexDirectionResolve(const YGFlexDirection flexDirection, const YGDirection direction) { if (direction == YGDirectionRTL) { @@ -991,6 +1039,24 @@ static inline bool YGNodeIsFlex(const YGNodeRef node) { (YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0)); } +static bool YGIsBaselineLayout(const YGNodeRef node) { + if (YGFlexDirectionIsColumn(node->style.flexDirection)) { + return false; + } + if (node->style.alignItems == YGAlignBaseline) { + return true; + } + for (uint32_t i = 0; i < YGNodeGetChildCount(node); i++) { + const YGNodeRef child = YGNodeGetChild(node, i); + if (child->style.positionType == YGPositionTypeRelative && + child->style.alignSelf == YGAlignBaseline) { + return true; + } + } + + return false; +} + static inline float YGNodeDimWithMargin(const YGNodeRef node, const YGFlexDirection axis, const float widthSize) { @@ -1583,8 +1649,6 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(const YGNodeRef node, // * Margins cannot be specified as 'auto'. They must be specified in terms of // pixel // values, and the default value is 0. -// * The 'baseline' value is not supported for alignItems and alignSelf -// properties. // * Values of width, maxWidth, minWidth, height, maxHeight and minHeight must // be // specified as pixel values, not as percentages. @@ -1680,10 +1744,22 @@ static void YGNodelayoutImpl(const YGNodeRef node, const YGDirection direction = YGNodeResolveDirection(node, parentDirection); node->layout.direction = direction; - node->layout.padding[YGEdgeStart] = YGNodeLeadingPadding(node, YGFlexDirectionResolve(YGFlexDirectionRow, direction), parentWidth); - node->layout.padding[YGEdgeEnd] = YGNodeTrailingPadding(node, YGFlexDirectionResolve(YGFlexDirectionRow, direction), parentWidth); - node->layout.padding[YGEdgeTop] = YGNodeLeadingPadding(node, YGFlexDirectionResolve(YGFlexDirectionColumn, direction), parentWidth); - node->layout.padding[YGEdgeBottom] = YGNodeTrailingPadding(node, YGFlexDirectionResolve(YGFlexDirectionColumn, direction), parentWidth); + node->layout.padding[YGEdgeStart] = + YGNodeLeadingPadding(node, + YGFlexDirectionResolve(YGFlexDirectionRow, direction), + parentWidth); + node->layout.padding[YGEdgeEnd] = + YGNodeTrailingPadding(node, + YGFlexDirectionResolve(YGFlexDirectionRow, direction), + parentWidth); + node->layout.padding[YGEdgeTop] = + YGNodeLeadingPadding(node, + YGFlexDirectionResolve(YGFlexDirectionColumn, direction), + parentWidth); + node->layout.padding[YGEdgeBottom] = + YGNodeTrailingPadding(node, + YGFlexDirectionResolve(YGFlexDirectionColumn, direction), + parentWidth); if (node->measure) { YGNodeWithMeasureFuncSetMeasuredDimensions( @@ -2452,7 +2528,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, } // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (lineCount > 1 && performLayout && !YGFloatIsUndefined(availableInnerCrossDim)) { + if (performLayout && (lineCount > 1 || YGIsBaselineLayout(node)) && + !YGFloatIsUndefined(availableInnerCrossDim)) { const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; float crossDimLead = 0; @@ -2472,6 +2549,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, break; case YGAlignAuto: case YGAlignFlexStart: + case YGAlignBaseline: break; } @@ -2482,6 +2560,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, // compute the line's height and find the endIndex float lineHeight = 0; + float maxAscentForCurrentLine = 0; + float maxDescentForCurrentLine = 0; for (ii = startIndex; ii < childCount; ii++) { const YGNodeRef child = YGNodeListGet(node->children, ii); @@ -2489,12 +2569,22 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (child->lineIndex != i) { break; } - if (YGNodeIsLayoutDimDefined(child, crossAxis)) { lineHeight = fmaxf(lineHeight, child->layout.measuredDimensions[dim[crossAxis]] + YGNodeMarginForAxis(child, crossAxis, availableInnerWidth)); } + if (YGNodeAlignItem(node, child) == YGAlignBaseline) { + const float ascent = + YGBaseline(child) + + YGNodeLeadingMargin(child, YGFlexDirectionColumn, availableInnerWidth); + const float descent = + child->layout.measuredDimensions[YGDimensionHeight] + + YGNodeMarginForAxis(child, YGFlexDirectionColumn, availableInnerWidth) - ascent; + maxAscentForCurrentLine = fmaxf(maxAscentForCurrentLine, ascent); + maxDescentForCurrentLine = fmaxf(maxDescentForCurrentLine, descent); + lineHeight = fmaxf(lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine); + } } } endIndex = ii; @@ -2531,6 +2621,12 @@ static void YGNodelayoutImpl(const YGNodeRef node, // (auto) crossAxis dimension. break; } + case YGAlignBaseline: { + child->layout.position[YGEdgeTop] = + currentLead + maxAscentForCurrentLine - YGBaseline(child) + + YGNodeLeadingPosition(child, YGFlexDirectionColumn, availableInnerCrossDim); + break; + } case YGAlignAuto: break; } diff --git a/yoga/Yoga.h b/yoga/Yoga.h index ba96b9cf..34a90f57 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -49,6 +49,7 @@ typedef YGSize (*YGMeasureFunc)(YGNodeRef node, YGMeasureMode widthMode, float height, YGMeasureMode heightMode); +typedef float (*YGBaselineFunc)(YGNodeRef node, const float width, const float height); typedef void (*YGPrintFunc)(YGNodeRef node); typedef int (*YGLogger)(YGLogLevel level, const char *format, va_list args); @@ -138,6 +139,7 @@ WIN_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode YG_NODE_PROPERTY(void *, Context, context); YG_NODE_PROPERTY(YGMeasureFunc, MeasureFunc, measureFunc); +YG_NODE_PROPERTY(YGBaselineFunc, BaselineFunc, baselineFunc) YG_NODE_PROPERTY(YGPrintFunc, PrintFunc, printFunc); YG_NODE_PROPERTY(bool, HasNewLayout, hasNewLayout);