From 3d840e533bdcbfe1166c69e7698176f40c6d0869 Mon Sep 17 00:00:00 2001 From: Lukas Woehrl Date: Wed, 4 Jan 2017 22:21:29 +0100 Subject: [PATCH] added baseline support --- csharp/tests/Facebook.Yoga/YGAlignBaseline.cs | 285 ++++++++++++++++++ enums.py | 1 + gentest/fixtures/YGAlignBaseline.html | 26 ++ gentest/gentest-cpp.js | 2 + gentest/gentest-cs.js | 1 + gentest/gentest-java.js | 1 + gentest/gentest-javascript.js | 1 + gentest/gentest.js | 1 + .../com/facebook/yoga/YGAlignBaseline.java | 279 +++++++++++++++++ tests/YGAlignBaseline.cpp | 269 +++++++++++++++++ tests/YGAlignBaselineCustomTest.cpp | 63 ++++ yoga/YGEnums.h | 3 +- yoga/Yoga.c | 88 +++++- yoga/Yoga.h | 4 + 14 files changed, 1021 insertions(+), 3 deletions(-) create mode 100644 csharp/tests/Facebook.Yoga/YGAlignBaseline.cs create mode 100644 gentest/fixtures/YGAlignBaseline.html create mode 100644 java/tests/com/facebook/yoga/YGAlignBaseline.java create mode 100644 tests/YGAlignBaseline.cpp create mode 100644 tests/YGAlignBaselineCustomTest.cpp diff --git a/csharp/tests/Facebook.Yoga/YGAlignBaseline.cs b/csharp/tests/Facebook.Yoga/YGAlignBaseline.cs new file mode 100644 index 00000000..7494a0bb --- /dev/null +++ b/csharp/tests/Facebook.Yoga/YGAlignBaseline.cs @@ -0,0 +1,285 @@ +/** + * 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. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignBaseline.html + +using System; +using NUnit.Framework; + +namespace Facebook.Yoga +{ + [TestFixture] + public class YGAlignBaseline + { + [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_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); + } + + } +} diff --git a/enums.py b/enums.py index f23fa164..819dd7d7 100644 --- a/enums.py +++ b/enums.py @@ -46,6 +46,7 @@ ENUMS = { 'Center', 'FlexEnd', 'Stretch', + 'Baseline', ], 'PositionType': [ 'Relative', diff --git a/gentest/fixtures/YGAlignBaseline.html b/gentest/fixtures/YGAlignBaseline.html new file mode 100644 index 00000000..f8910b95 --- /dev/null +++ b/gentest/fixtures/YGAlignBaseline.html @@ -0,0 +1,26 @@ +
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ + +
+
+
+
diff --git a/gentest/gentest-cpp.js b/gentest/gentest-cpp.js index f8ecf8be..6b3180c0 100644 --- a/gentest/gentest-cpp.js +++ b/gentest/gentest-cpp.js @@ -82,6 +82,8 @@ CPPEmitter.prototype = Object.create(Emitter.prototype, { YGAlignFlexEnd:{value:'YGAlignFlexEnd'}, YGAlignFlexStart:{value:'YGAlignFlexStart'}, YGAlignStretch:{value:'YGAlignStretch'}, + + YGAlignBaseline:{value:'YGAlignBaseline'}, YGDirectionInherit:{value:'YGDirectionInherit'}, YGDirectionLTR:{value:'YGDirectionLTR'}, 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..6d8afd0c 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 8c65867c..0db3888e 100644 --- a/gentest/gentest-javascript.js +++ b/gentest/gentest-javascript.js @@ -84,6 +84,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/tests/com/facebook/yoga/YGAlignBaseline.java b/java/tests/com/facebook/yoga/YGAlignBaseline.java new file mode 100644 index 00000000..c7969020 --- /dev/null +++ b/java/tests/com/facebook/yoga/YGAlignBaseline.java @@ -0,0 +1,279 @@ +/** + * 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. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignBaseline.html + +package com.facebook.yoga; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class YGAlignBaseline { + @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_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); + } + +} diff --git a/tests/YGAlignBaseline.cpp b/tests/YGAlignBaseline.cpp new file mode 100644 index 00000000..d283b63c --- /dev/null +++ b/tests/YGAlignBaseline.cpp @@ -0,0 +1,269 @@ +/** + * 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. + */ + + // @Generated by gentest/gentest.rb from gentest/fixtures/YGAlignBaseline.html + +#include +#include + +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_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); +} diff --git a/tests/YGAlignBaselineCustomTest.cpp b/tests/YGAlignBaselineCustomTest.cpp new file mode 100644 index 00000000..dccaa32a --- /dev/null +++ b/tests/YGAlignBaselineCustomTest.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) { + 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 d4285444..ac2d3308 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; } YGNode; @@ -334,6 +335,20 @@ YGMeasureFunc YGNodeGetMeasureFunc(const YGNodeRef node) { return node->measure; } + +void YGNodeSetBaselineFunc(const YGNodeRef node, YGBaselineFunc baselineFunc) { + if (baselineFunc == NULL) { + node->baseline = NULL; + } + else { + 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, @@ -941,6 +956,61 @@ static inline YGDirection YGNodeResolveDirection(const YGNodeRef node, } } + +static float YGBaselineOfFirstLine(const YGNodeRef node, const YGFlexDirection mainAxis, const float parentWidth) +{ + if(node->baseline != NULL) + { + return node->baseline(node); + } + + YGNodeRef baselineChild = NULL; + for(unsigned int i = 0; i < YGNodeGetChildCount(node); ++i) + { + const YGNodeRef child = YGNodeGetChild(node, i); + if(child->style.positionType == YGPositionTypeAbsolute || child->lineIndex > 0) + { + continue; + } + + if(YGNodeAlignItem(node, child) == YGAlignBaseline) + { + baselineChild = child; + break; + } + + if(baselineChild == NULL) + { + baselineChild = child; + } + } + + if(baselineChild == NULL) + { + return YGUndefined; + } + + float baseline = YGBaselineOfFirstLine(baselineChild, node->style.direction, node->layout.measuredDimensions[YGDimensionWidth]); + if(YGFloatIsUndefined(baseline)) + { + baseline = YGNodeLeadingPaddingAndBorder(baselineChild, mainAxis, parentWidth) + + baselineChild->layout.measuredDimensions[dim[mainAxis]]; + } + + return baseline + baselineChild->layout.position[YGEdgeTop]; +} + +static float YGBaselineWithMargin(const YGNodeRef node, const YGFlexDirection mainAxis, const float parentWidth) +{ + float baseline = YGBaselineOfFirstLine(node, mainAxis, parentWidth); + if(YGFloatIsUndefined(baseline)) + { + baseline = node->layout.measuredDimensions[dim[mainAxis]]; + } + return baseline + YGNodeLeadingMargin(node, mainAxis, parentWidth); +} + + static inline YGFlexDirection YGFlexDirectionResolve(const YGFlexDirection flexDirection, const YGDirection direction) { if (direction == YGDirectionRTL) { @@ -2422,7 +2492,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, } // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (lineCount > 1 && performLayout && !YGFloatIsUndefined(availableInnerCrossDim)) { + if ((node->style.alignItems == YGAlignBaseline || lineCount > 1) && performLayout && !YGFloatIsUndefined(availableInnerCrossDim)) { const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; float crossDimLead = 0; @@ -2442,6 +2512,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, break; case YGAlignAuto: case YGAlignFlexStart: + case YGAlignBaseline: break; } @@ -2452,6 +2523,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, // compute the line's height and find the endIndex float lineHeight = 0; + float maxAscentForCurrentLine = 0; for (ii = startIndex; ii < childCount; ii++) { const YGNodeRef child = YGNodeListGet(node->children, ii); @@ -2460,6 +2532,12 @@ static void YGNodelayoutImpl(const YGNodeRef node, break; } + if (performLayout && YGNodeAlignItem(node, child) == YGAlignBaseline) + { + maxAscentForCurrentLine = fmaxf(maxAscentForCurrentLine, + YGBaselineWithMargin(child, crossAxis, availableInnerWidth)); + } + if (YGNodeIsLayoutDimDefined(child, crossAxis)) { lineHeight = fmaxf(lineHeight, child->layout.measuredDimensions[dim[crossAxis]] + @@ -2476,7 +2554,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, if (child->style.positionType == YGPositionTypeRelative) { switch (YGNodeAlignItem(node, child)) { - case YGAlignFlexStart: { + case YGAlignFlexStart: { child->layout.position[pos[crossAxis]] = currentLead + YGNodeLeadingMargin(child, crossAxis, availableInnerWidth); break; @@ -2501,6 +2579,12 @@ static void YGNodelayoutImpl(const YGNodeRef node, // (auto) crossAxis dimension. break; } + case YGAlignBaseline: { + child->layout.position[pos[crossAxis]] = currentLead + + maxAscentForCurrentLine - + YGBaselineWithMargin(child, crossAxis, availableInnerWidth);; + break; + } case YGAlignAuto: break; } diff --git a/yoga/Yoga.h b/yoga/Yoga.h index 083d3073..6b84d0e6 100644 --- a/yoga/Yoga.h +++ b/yoga/Yoga.h @@ -49,6 +49,9 @@ typedef YGSize (*YGMeasureFunc)(YGNodeRef node, YGMeasureMode widthMode, float height, YGMeasureMode heightMode); + +typedef float(*YGBaselineFunc)(YGNodeRef node); + typedef void (*YGPrintFunc)(YGNodeRef node); typedef int (*YGLogger)(YGLogLevel level, const char *format, va_list args); @@ -138,6 +141,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);