diff --git a/YogaKit/Tests/YogaKitTests.m b/YogaKit/Tests/YogaKitTests.m
index 99927ade..68d97dd5 100644
--- a/YogaKit/Tests/YogaKitTests.m
+++ b/YogaKit/Tests/YogaKitTests.m
@@ -268,4 +268,79 @@
}
}
+- (void)testyg_isLeafFlag
+{
+ UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
+ XCTAssertTrue(view.yg_isLeaf);
+
+ for (int i=0; i<10; i++) {
+ UIView *subview = [[UIView alloc] initWithFrame:CGRectZero];
+ [view addSubview:subview];
+ }
+ XCTAssertTrue(view.yg_isLeaf);
+
+ [view yg_setUsesYoga:YES];
+ [view yg_setWidth:50.0];
+ XCTAssertTrue(view.yg_isLeaf);
+
+ UIView *const subview = view.subviews[0];
+ [subview yg_setUsesYoga:YES];
+ [subview yg_setWidth:50.0];
+ XCTAssertFalse(view.yg_isLeaf);
+}
+
+- (void)testThatWeCorrectlyAttachNestedViews
+{
+ UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 50)];
+ [container yg_setUsesYoga:YES];
+ [container yg_setFlexDirection:YGFlexDirectionColumn];
+
+ UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
+ [subview1 yg_setUsesYoga:YES];
+ [subview1 yg_setWidth:100];
+ [subview1 yg_setFlexGrow:1];
+ [subview1 yg_setFlexDirection:YGFlexDirectionColumn];
+ [container addSubview:subview1];
+
+ UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
+ [subview2 yg_setUsesYoga:YES];
+ [subview2 yg_setWidth:150];
+ [subview2 yg_setFlexGrow:1];
+ [subview2 yg_setFlexDirection:YGFlexDirectionColumn];
+ [container addSubview:subview2];
+
+ for (UIView *view in @[subview1, subview2]) {
+ UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
+ [someView yg_setUsesYoga:YES];
+ [someView yg_setFlexGrow:1];
+ [view addSubview:someView];
+ }
+ [container yg_applyLayout];
+
+ // Add the same amount of new views, reapply layout.
+ for (UIView *view in @[subview1, subview2]) {
+ UIView *someView = [[UIView alloc] initWithFrame:CGRectZero];
+ [someView yg_setUsesYoga:YES];
+ [someView yg_setFlexGrow:1];
+ [view addSubview:someView];
+ }
+ [container yg_applyLayout];
+
+ XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(100, 25), subview1.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview1.bounds.size));
+ for (UIView *subview in subview1.subviews) {
+ const CGSize subviewSize = subview.bounds.size;
+ XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subviewSize));
+ XCTAssertFalse(isnan(subviewSize.height));
+ XCTAssertFalse(isnan(subviewSize.width));
+ }
+
+ XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(150, 25), subview2.bounds.size), @"Actual size is %@", NSStringFromCGSize(subview2.bounds.size));
+ for (UIView *subview in subview2.subviews) {
+ const CGSize subviewSize = subview.bounds.size;
+ XCTAssertFalse(CGSizeEqualToSize(CGSizeZero, subview.bounds.size));
+ XCTAssertFalse(isnan(subviewSize.height));
+ XCTAssertFalse(isnan(subviewSize.width));
+ }
+}
+
@end
diff --git a/csharp/Unity/.gitignore b/csharp/Unity/.gitignore
new file mode 100644
index 00000000..a26b100a
--- /dev/null
+++ b/csharp/Unity/.gitignore
@@ -0,0 +1,3 @@
+Yoga
+yoga.dll
+yoga.unitypackage
diff --git a/csharp/Unity/pack.sh b/csharp/Unity/pack.sh
new file mode 100755
index 00000000..402a9632
--- /dev/null
+++ b/csharp/Unity/pack.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+# 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.
+
+cd "$( dirname "$0" )"
+
+if [ \! -f yoga.dll ]; then
+ echo "Launch win.bat on Windows and copy yoga.dll to here"
+ exit 1
+fi
+
+function build {
+ buck build $1
+ echo "$root/`buck targets --show-output $1|tail -1|awk '{print $2}'`"
+}
+
+function copy {
+ mkdir -p $3
+ cp $1 $3/$2
+}
+
+rm -rf Yoga yoga.unitypackage
+
+root=`buck root|tail -f`
+mac=$(build '//csharp:yoganet#default,shared')
+armv7=$(build '//csharp:yoganet#android-armv7,shared')
+ios=$(build '//csharp:yoganet-ios')
+win=yoga.dll
+
+Unity -quit -batchMode -createProject Yoga
+
+copy $win ${win##*/} Yoga/Assets/Facebook.Yoga/Plugins/x86_64
+copy $mac yoga Yoga/Assets/Facebook.Yoga/Plugins/x86_64/yoga.bundle/Contents/MacOS
+armv7path=Assets/Plugins/Android/libs/armeabi-v7a
+copy $armv7 ${armv7##*/} Yoga/$armv7path
+iospath=Assets/Plugins/iOS
+copy $ios ${ios##*/} Yoga/$iospath
+libs="$armv7path/${armv7##*/} $iospath/${ios##*/}"
+
+scripts=Yoga/Assets/Facebook.Yoga/Scripts/Facebook.Yoga
+mkdir -p $scripts
+(cd ../Facebook.Yoga; tar cf - *.cs)|tar -C $scripts -xf -
+
+tests=Yoga/Assets/Facebook.Yoga/Editor/Facebook.Yoga.Tests
+mkdir -p $tests
+(cd ../tests/Facebook.Yoga; tar cf - *.cs)|tar -C $tests -xf -
+
+Unity -quit -batchMode -projectPath `pwd`/Yoga -exportPackage Assets/Facebook.Yoga $libs `pwd`/yoga.unitypackage
+
diff --git a/csharp/Unity/win.bat b/csharp/Unity/win.bat
new file mode 100755
index 00000000..3f838cd4
--- /dev/null
+++ b/csharp/Unity/win.bat
@@ -0,0 +1,2 @@
+"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" ..\Yoga\Yoga.vcxproj /p:configuration=Release /property:Platform=x64
+xcopy "..\Yoga\x64\Release\yoga.dll" %~dp0 /s /d /y
diff --git a/csharp/tests/Facebook.Yoga/YGMinMaxDimensionTest.cs b/csharp/tests/Facebook.Yoga/YGMinMaxDimensionTest.cs
index 04413d41..39eca9ca 100644
--- a/csharp/tests/Facebook.Yoga/YGMinMaxDimensionTest.cs
+++ b/csharp/tests/Facebook.Yoga/YGMinMaxDimensionTest.cs
@@ -454,5 +454,226 @@ namespace Facebook.Yoga
Assert.AreEqual(20f, root_child0_child0.LayoutHeight);
}
+ [Test]
+ public void Test_flex_grow_within_constrained_min_row()
+ {
+ YogaNode root = new YogaNode();
+ root.FlexDirection = YogaFlexDirection.Row;
+ root.MinWidth = 100f;
+ root.Height = 100f;
+
+ YogaNode root_child0 = new YogaNode();
+ root_child0.FlexGrow = 1f;
+ root.Insert(0, root_child0);
+
+ YogaNode root_child1 = new YogaNode();
+ root_child1.Width = 50f;
+ 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(100f, root_child0.LayoutHeight);
+
+ Assert.AreEqual(50f, root_child1.LayoutX);
+ Assert.AreEqual(0f, root_child1.LayoutY);
+ Assert.AreEqual(50f, root_child1.LayoutWidth);
+ Assert.AreEqual(100f, 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(100f, root_child0.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child1.LayoutX);
+ Assert.AreEqual(0f, root_child1.LayoutY);
+ Assert.AreEqual(50f, root_child1.LayoutWidth);
+ Assert.AreEqual(100f, root_child1.LayoutHeight);
+ }
+
+ [Test]
+ public void Test_flex_grow_within_constrained_min_column()
+ {
+ YogaNode root = new YogaNode();
+ root.MinHeight = 100f;
+
+ YogaNode root_child0 = new YogaNode();
+ root_child0.FlexGrow = 1f;
+ root.Insert(0, root_child0);
+
+ YogaNode root_child1 = new YogaNode();
+ root_child1.Height = 50f;
+ root.Insert(1, root_child1);
+ root.StyleDirection = YogaDirection.LTR;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0f, root.LayoutX);
+ Assert.AreEqual(0f, root.LayoutY);
+ Assert.AreEqual(0f, root.LayoutWidth);
+ Assert.AreEqual(100f, root.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0.LayoutY);
+ Assert.AreEqual(0f, root_child0.LayoutWidth);
+ Assert.AreEqual(50f, root_child0.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child1.LayoutX);
+ Assert.AreEqual(50f, root_child1.LayoutY);
+ Assert.AreEqual(0f, root_child1.LayoutWidth);
+ Assert.AreEqual(50f, root_child1.LayoutHeight);
+
+ root.StyleDirection = YogaDirection.RTL;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0f, root.LayoutX);
+ Assert.AreEqual(0f, root.LayoutY);
+ Assert.AreEqual(0f, root.LayoutWidth);
+ Assert.AreEqual(100f, root.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0.LayoutY);
+ Assert.AreEqual(0f, root_child0.LayoutWidth);
+ Assert.AreEqual(50f, root_child0.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child1.LayoutX);
+ Assert.AreEqual(50f, root_child1.LayoutY);
+ Assert.AreEqual(0f, root_child1.LayoutWidth);
+ Assert.AreEqual(50f, root_child1.LayoutHeight);
+ }
+
+ [Test]
+ public void Test_flex_grow_within_constrained_max_row()
+ {
+ YogaNode root = new YogaNode();
+ root.Width = 200f;
+
+ YogaNode root_child0 = new YogaNode();
+ root_child0.FlexDirection = YogaFlexDirection.Row;
+ root_child0.MaxWidth = 100f;
+ root_child0.Height = 100f;
+ root.Insert(0, root_child0);
+
+ YogaNode root_child0_child0 = new YogaNode();
+ root_child0_child0.FlexShrink = 1f;
+ root_child0_child0.FlexBasis = 100f;
+ root_child0.Insert(0, root_child0_child0);
+
+ YogaNode root_child0_child1 = new YogaNode();
+ root_child0_child1.Width = 50f;
+ root_child0.Insert(1, root_child0_child1);
+ root.StyleDirection = YogaDirection.LTR;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0f, root.LayoutX);
+ Assert.AreEqual(0f, root.LayoutY);
+ Assert.AreEqual(200f, root.LayoutWidth);
+ Assert.AreEqual(100f, root.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0.LayoutY);
+ Assert.AreEqual(100f, root_child0.LayoutWidth);
+ Assert.AreEqual(100f, 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(100f, root_child0_child0.LayoutHeight);
+
+ Assert.AreEqual(50f, root_child0_child1.LayoutX);
+ Assert.AreEqual(0f, root_child0_child1.LayoutY);
+ Assert.AreEqual(50f, root_child0_child1.LayoutWidth);
+ Assert.AreEqual(100f, root_child0_child1.LayoutHeight);
+
+ root.StyleDirection = YogaDirection.RTL;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0f, root.LayoutX);
+ Assert.AreEqual(0f, root.LayoutY);
+ Assert.AreEqual(200f, root.LayoutWidth);
+ Assert.AreEqual(100f, root.LayoutHeight);
+
+ Assert.AreEqual(100f, root_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0.LayoutY);
+ Assert.AreEqual(100f, root_child0.LayoutWidth);
+ Assert.AreEqual(100f, root_child0.LayoutHeight);
+
+ Assert.AreEqual(50f, root_child0_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0_child0.LayoutY);
+ Assert.AreEqual(50f, root_child0_child0.LayoutWidth);
+ Assert.AreEqual(100f, root_child0_child0.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child0_child1.LayoutX);
+ Assert.AreEqual(0f, root_child0_child1.LayoutY);
+ Assert.AreEqual(50f, root_child0_child1.LayoutWidth);
+ Assert.AreEqual(100f, root_child0_child1.LayoutHeight);
+ }
+
+ [Test]
+ public void Test_flex_grow_within_constrained_max_column()
+ {
+ YogaNode root = new YogaNode();
+ root.Width = 100f;
+ root.MaxHeight = 100f;
+
+ YogaNode root_child0 = new YogaNode();
+ root_child0.FlexShrink = 1f;
+ root_child0.FlexBasis = 100f;
+ root.Insert(0, root_child0);
+
+ YogaNode root_child1 = new YogaNode();
+ root_child1.Height = 50f;
+ 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(100f, root_child0.LayoutWidth);
+ Assert.AreEqual(50f, root_child0.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child1.LayoutX);
+ Assert.AreEqual(50f, root_child1.LayoutY);
+ Assert.AreEqual(100f, root_child1.LayoutWidth);
+ Assert.AreEqual(50f, 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(0f, root_child0.LayoutX);
+ Assert.AreEqual(0f, root_child0.LayoutY);
+ Assert.AreEqual(100f, root_child0.LayoutWidth);
+ Assert.AreEqual(50f, root_child0.LayoutHeight);
+
+ Assert.AreEqual(0f, root_child1.LayoutX);
+ Assert.AreEqual(50f, root_child1.LayoutY);
+ Assert.AreEqual(100f, root_child1.LayoutWidth);
+ Assert.AreEqual(50f, root_child1.LayoutHeight);
+ }
+
}
}
diff --git a/enums.py b/enums.py
index 8584f81c..2ae25f2a 100644
--- a/enums.py
+++ b/enums.py
@@ -128,20 +128,20 @@ def to_java_upper(symbol):
root = os.path.dirname(os.path.abspath(__file__))
-# write out C header
+# write out C headers
with open(root + '/yoga/YGEnums.h', 'w') as f:
f.write(LICENSE)
f.write('#pragma once\n\n')
f.write('#include "YGMacros.h"\n\n')
f.write('YG_EXTERN_C_BEGIN\n\n')
for name, values in ENUMS.items():
+ f.write('#define YG%sCount %s\n' % (name, len(values)))
f.write('typedef enum YG%s {\n' % name)
for value in values:
if isinstance(value, tuple):
f.write(' YG%s%s = %d,\n' % (name, value[0], value[1]))
else:
f.write(' YG%s%s,\n' % (name, value))
- f.write(' YG%sCount,\n' % name)
f.write('} YG%s;\n' % name)
f.write('\n')
f.write('YG_EXTERN_C_END\n')
diff --git a/gentest/fixtures/YGMinMaxDimensionTest.html b/gentest/fixtures/YGMinMaxDimensionTest.html
index 6e469707..6adf67e5 100644
--- a/gentest/fixtures/YGMinMaxDimensionTest.html
+++ b/gentest/fixtures/YGMinMaxDimensionTest.html
@@ -41,3 +41,25 @@
+
+
+
+
+
+
+
+
diff --git a/java/tests/com/facebook/yoga/YGMinMaxDimensionTest.java b/java/tests/com/facebook/yoga/YGMinMaxDimensionTest.java
index f37a5c54..f5f96357 100644
--- a/java/tests/com/facebook/yoga/YGMinMaxDimensionTest.java
+++ b/java/tests/com/facebook/yoga/YGMinMaxDimensionTest.java
@@ -444,4 +444,221 @@ public class YGMinMaxDimensionTest {
assertEquals(20f, root_child0_child0.getLayoutHeight(), 0.0f);
}
+ @Test
+ public void test_flex_grow_within_constrained_min_row() {
+ final YogaNode root = new YogaNode();
+ root.setFlexDirection(YogaFlexDirection.ROW);
+ root.setMinWidth(100f);
+ root.setHeight(100f);
+
+ final YogaNode root_child0 = new YogaNode();
+ root_child0.setFlexGrow(1f);
+ root.addChildAt(root_child0, 0);
+
+ final YogaNode root_child1 = new YogaNode();
+ root_child1.setWidth(50f);
+ 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(100f, root_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(50f, root_child1.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child1.getLayoutY(), 0.0f);
+ assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
+ assertEquals(100f, 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(100f, root_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child1.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child1.getLayoutY(), 0.0f);
+ assertEquals(50f, root_child1.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root_child1.getLayoutHeight(), 0.0f);
+ }
+
+ @Test
+ public void test_flex_grow_within_constrained_min_column() {
+ final YogaNode root = new YogaNode();
+ root.setMinHeight(100f);
+
+ final YogaNode root_child0 = new YogaNode();
+ root_child0.setFlexGrow(1f);
+ root.addChildAt(root_child0, 0);
+
+ final YogaNode root_child1 = new YogaNode();
+ root_child1.setHeight(50f);
+ root.addChildAt(root_child1, 1);
+ root.setDirection(YogaDirection.LTR);
+ root.calculateLayout();
+
+ assertEquals(0f, root.getLayoutX(), 0.0f);
+ assertEquals(0f, root.getLayoutY(), 0.0f);
+ assertEquals(0f, root.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutY(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child1.getLayoutX(), 0.0f);
+ assertEquals(50f, root_child1.getLayoutY(), 0.0f);
+ assertEquals(0f, root_child1.getLayoutWidth(), 0.0f);
+ assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
+
+ root.setDirection(YogaDirection.RTL);
+ root.calculateLayout();
+
+ assertEquals(0f, root.getLayoutX(), 0.0f);
+ assertEquals(0f, root.getLayoutY(), 0.0f);
+ assertEquals(0f, root.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutY(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(50f, root_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child1.getLayoutX(), 0.0f);
+ assertEquals(50f, root_child1.getLayoutY(), 0.0f);
+ assertEquals(0f, root_child1.getLayoutWidth(), 0.0f);
+ assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
+ }
+
+ @Test
+ public void test_flex_grow_within_constrained_max_row() {
+ final YogaNode root = new YogaNode();
+ root.setWidth(200f);
+
+ final YogaNode root_child0 = new YogaNode();
+ root_child0.setFlexDirection(YogaFlexDirection.ROW);
+ root_child0.setMaxWidth(100f);
+ root_child0.setHeight(100f);
+ root.addChildAt(root_child0, 0);
+
+ final YogaNode root_child0_child0 = new YogaNode();
+ root_child0_child0.setFlexShrink(1f);
+ root_child0_child0.setFlexBasis(100f);
+ root_child0.addChildAt(root_child0_child0, 0);
+
+ final YogaNode root_child0_child1 = new YogaNode();
+ root_child0_child1.setWidth(50f);
+ root_child0.addChildAt(root_child0_child1, 1);
+ root.setDirection(YogaDirection.LTR);
+ root.calculateLayout();
+
+ assertEquals(0f, root.getLayoutX(), 0.0f);
+ assertEquals(0f, root.getLayoutY(), 0.0f);
+ assertEquals(200f, 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(100f, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(100f, 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(100f, root_child0_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(50f, root_child0_child1.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
+ assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root_child0_child1.getLayoutHeight(), 0.0f);
+
+ root.setDirection(YogaDirection.RTL);
+ root.calculateLayout();
+
+ assertEquals(0f, root.getLayoutX(), 0.0f);
+ assertEquals(0f, root.getLayoutY(), 0.0f);
+ assertEquals(200f, root.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root.getLayoutHeight(), 0.0f);
+
+ assertEquals(100f, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutY(), 0.0f);
+ assertEquals(100f, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(50f, root_child0_child0.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0_child0.getLayoutY(), 0.0f);
+ assertEquals(50f, root_child0_child0.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root_child0_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(0f, root_child0_child1.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0_child1.getLayoutY(), 0.0f);
+ assertEquals(50f, root_child0_child1.getLayoutWidth(), 0.0f);
+ assertEquals(100f, root_child0_child1.getLayoutHeight(), 0.0f);
+ }
+
+ @Test
+ public void test_flex_grow_within_constrained_max_column() {
+ final YogaNode root = new YogaNode();
+ root.setWidth(100f);
+ root.setMaxHeight(100f);
+
+ final YogaNode root_child0 = new YogaNode();
+ root_child0.setFlexShrink(1f);
+ root_child0.setFlexBasis(100f);
+ root.addChildAt(root_child0, 0);
+
+ final YogaNode root_child1 = new YogaNode();
+ root_child1.setHeight(50f);
+ 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(100f, 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(100f, root_child1.getLayoutWidth(), 0.0f);
+ assertEquals(50f, 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(0f, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0f, root_child0.getLayoutY(), 0.0f);
+ assertEquals(100f, 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(100f, root_child1.getLayoutWidth(), 0.0f);
+ assertEquals(50f, root_child1.getLayoutHeight(), 0.0f);
+ }
+
}
diff --git a/tests/YGAspectRatioTest.cpp b/tests/YGAspectRatioTest.cpp
index 22846c9b..b6e32de2 100644
--- a/tests/YGAspectRatioTest.cpp
+++ b/tests/YGAspectRatioTest.cpp
@@ -63,12 +63,15 @@ TEST(YogaTest, aspect_ratio_main_defined) {
YGNodeFreeRecursive(root);
}
-TEST(YogaTest, aspect_ratio_both_dimensions_defined) {
+TEST(YogaTest, aspect_ratio_both_dimensions_defined_row) {
const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 100);
const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0, 100);
YGNodeStyleSetHeight(root_child0, 50);
YGNodeStyleSetAspectRatio(root_child0, 1);
YGNodeInsertChild(root, root_child0, 0);
@@ -78,6 +81,28 @@ TEST(YogaTest, aspect_ratio_both_dimensions_defined) {
ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_both_dimensions_defined_column) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0, 100);
+ YGNodeStyleSetHeight(root_child0, 50);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
@@ -351,7 +376,7 @@ TEST(YogaTest, aspect_ratio_double_main) {
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 50);
- YGNodeStyleSetAspectRatio(root_child0, 2);
+ YGNodeStyleSetAspectRatio(root_child0, 0.5);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
@@ -372,7 +397,7 @@ TEST(YogaTest, aspect_ratio_half_main) {
const YGNodeRef root_child0 = YGNodeNew();
YGNodeStyleSetWidth(root_child0, 100);
- YGNodeStyleSetAspectRatio(root_child0, 0.5);
+ YGNodeStyleSetAspectRatio(root_child0, 2);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
@@ -405,3 +430,249 @@ TEST(YogaTest, aspect_ratio_with_measure_func) {
YGNodeFreeRecursive(root);
}
+
+TEST(YogaTest, aspect_ratio_width_height_flex_grow_row) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 200);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0, 50);
+ YGNodeStyleSetHeight(root_child0, 50);
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_width_height_flex_grow_column) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
+ YGNodeStyleSetWidth(root, 200);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0, 50);
+ YGNodeStyleSetHeight(root_child0, 50);
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_height_as_flex_basis) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetWidth(root, 200);
+ YGNodeStyleSetHeight(root, 200);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetHeight(root_child0, 50);
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ const YGNodeRef root_child1 = YGNodeNew();
+ YGNodeStyleSetHeight(root_child1, 100);
+ YGNodeStyleSetFlexGrow(root_child1, 1);
+ YGNodeStyleSetAspectRatio(root_child1, 1);
+ YGNodeInsertChild(root, root_child1, 1);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(75, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(75, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_EQ(75, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child1));
+ ASSERT_EQ(125, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_EQ(125, YGNodeLayoutGetHeight(root_child1));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_width_as_flex_basis) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
+ YGNodeStyleSetWidth(root, 200);
+ YGNodeStyleSetHeight(root, 200);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0, 50);
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ const YGNodeRef root_child1 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child1, 100);
+ YGNodeStyleSetFlexGrow(root_child1, 1);
+ YGNodeStyleSetAspectRatio(root_child1, 1);
+ YGNodeInsertChild(root, root_child1, 1);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(75, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(75, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_EQ(75, YGNodeLayoutGetTop(root_child1));
+ ASSERT_EQ(125, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_EQ(125, YGNodeLayoutGetHeight(root_child1));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_overrides_flex_grow_row) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0, 50);
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeStyleSetAspectRatio(root_child0, 0.5);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_overrides_flex_grow_column) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetAlignItems(root, YGAlignFlexStart);
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetHeight(root_child0, 50);
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeStyleSetAspectRatio(root_child0, 2);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_left_right_absolute) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute);
+ YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10);
+ YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10);
+ YGNodeStyleSetPosition(root_child0, YGEdgeRight, 10);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(10, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(10, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(80, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(80, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_top_bottom_absolute) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetPositionType(root_child0, YGPositionTypeAbsolute);
+ YGNodeStyleSetPosition(root_child0, YGEdgeLeft, 10);
+ YGNodeStyleSetPosition(root_child0, YGEdgeTop, 10);
+ YGNodeStyleSetPosition(root_child0, YGEdgeBottom, 10);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(10, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(10, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(80, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(80, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_width_overrides_align_stretch_row) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0, 50);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, aspect_ratio_height_overrides_align_stretch_column) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetHeight(root_child0, 50);
+ YGNodeStyleSetAspectRatio(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(50, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(50, YGNodeLayoutGetHeight(root_child0));
+
+ YGNodeFreeRecursive(root);
+}
diff --git a/tests/YGMemoryFuncTest.cpp b/tests/YGMemoryFuncTest.cpp
index bef2985c..b6481373 100644
--- a/tests/YGMemoryFuncTest.cpp
+++ b/tests/YGMemoryFuncTest.cpp
@@ -56,7 +56,7 @@ TEST(YogaTest, memory_func_test_funcs) {
}
YGNodeFreeRecursive(root);
ASSERT_NE(testMallocCount, 0);
- ASSERT_NE(testCallocCount, 0);
+ ASSERT_EQ(testCallocCount, 0);
ASSERT_NE(testReallocCount, 0);
ASSERT_NE(testFreeCount, 0);
YGSetMemoryFuncs(NULL, NULL, NULL, NULL);
diff --git a/tests/YGMinMaxDimensionTest.cpp b/tests/YGMinMaxDimensionTest.cpp
index 2c6d3120..b1463e52 100644
--- a/tests/YGMinMaxDimensionTest.cpp
+++ b/tests/YGMinMaxDimensionTest.cpp
@@ -430,3 +430,216 @@ TEST(YogaTest, flex_grow_within_constrained_max_width) {
YGNodeFreeRecursive(root);
}
+
+TEST(YogaTest, flex_grow_within_constrained_min_row) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow);
+ YGNodeStyleSetMinWidth(root, 100);
+ YGNodeStyleSetHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ const YGNodeRef root_child1 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child1, 50);
+ 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(100, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, 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(100, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child1));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, flex_grow_within_constrained_min_column) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetMinHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetFlexGrow(root_child0, 1);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ const YGNodeRef root_child1 = YGNodeNew();
+ YGNodeStyleSetHeight(root_child1, 50);
+ 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(0, 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(0, 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(0, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetTop(root_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, flex_grow_within_constrained_max_row) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetWidth(root, 200);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow);
+ YGNodeStyleSetMaxWidth(root_child0, 100);
+ YGNodeStyleSetHeight(root_child0, 100);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ const YGNodeRef root_child0_child0 = YGNodeNew();
+ YGNodeStyleSetFlexShrink(root_child0_child0, 1);
+ YGNodeStyleSetFlexBasis(root_child0_child0, 100);
+ YGNodeInsertChild(root_child0, root_child0_child0, 0);
+
+ const YGNodeRef root_child0_child1 = YGNodeNew();
+ YGNodeStyleSetWidth(root_child0_child1, 50);
+ YGNodeInsertChild(root_child0, root_child0_child1, 1);
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(200, 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(100, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, 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(100, YGNodeLayoutGetHeight(root_child0_child0));
+
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1));
+
+ YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL);
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root));
+ ASSERT_FLOAT_EQ(200, YGNodeLayoutGetWidth(root));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root));
+
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetWidth(root_child0));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0));
+
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetLeft(root_child0_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child0));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0));
+
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0_child1));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetWidth(root_child0_child1));
+ ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child1));
+
+ YGNodeFreeRecursive(root);
+}
+
+TEST(YogaTest, flex_grow_within_constrained_max_column) {
+ const YGNodeRef root = YGNodeNew();
+ YGNodeStyleSetWidth(root, 100);
+ YGNodeStyleSetMaxHeight(root, 100);
+
+ const YGNodeRef root_child0 = YGNodeNew();
+ YGNodeStyleSetFlexShrink(root_child0, 1);
+ YGNodeStyleSetFlexBasis(root_child0, 100);
+ YGNodeInsertChild(root, root_child0, 0);
+
+ const YGNodeRef root_child1 = YGNodeNew();
+ YGNodeStyleSetHeight(root_child1, 50);
+ 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(100, 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(100, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(50, 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(0, YGNodeLayoutGetLeft(root_child0));
+ ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0));
+ ASSERT_FLOAT_EQ(100, 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(100, YGNodeLayoutGetWidth(root_child1));
+ ASSERT_FLOAT_EQ(50, YGNodeLayoutGetHeight(root_child1));
+
+ YGNodeFreeRecursive(root);
+}
diff --git a/yoga/YGEnums.h b/yoga/YGEnums.h
index 85d9d2f9..a64c1673 100644
--- a/yoga/YGEnums.h
+++ b/yoga/YGEnums.h
@@ -13,28 +13,29 @@
YG_EXTERN_C_BEGIN
+#define YGFlexDirectionCount 4
typedef enum YGFlexDirection {
YGFlexDirectionColumn,
YGFlexDirectionColumnReverse,
YGFlexDirectionRow,
YGFlexDirectionRowReverse,
- YGFlexDirectionCount,
} YGFlexDirection;
+#define YGMeasureModeCount 3
typedef enum YGMeasureMode {
YGMeasureModeUndefined,
YGMeasureModeExactly,
YGMeasureModeAtMost,
- YGMeasureModeCount,
} YGMeasureMode;
+#define YGPrintOptionsCount 3
typedef enum YGPrintOptions {
YGPrintOptionsLayout = 1,
YGPrintOptionsStyle = 2,
YGPrintOptionsChildren = 4,
- YGPrintOptionsCount,
} YGPrintOptions;
+#define YGEdgeCount 9
typedef enum YGEdge {
YGEdgeLeft,
YGEdgeTop,
@@ -45,72 +46,71 @@ typedef enum YGEdge {
YGEdgeHorizontal,
YGEdgeVertical,
YGEdgeAll,
- YGEdgeCount,
} YGEdge;
+#define YGPositionTypeCount 2
typedef enum YGPositionType {
YGPositionTypeRelative,
YGPositionTypeAbsolute,
- YGPositionTypeCount,
} YGPositionType;
+#define YGDimensionCount 2
typedef enum YGDimension {
YGDimensionWidth,
YGDimensionHeight,
- YGDimensionCount,
} YGDimension;
+#define YGJustifyCount 5
typedef enum YGJustify {
YGJustifyFlexStart,
YGJustifyCenter,
YGJustifyFlexEnd,
YGJustifySpaceBetween,
YGJustifySpaceAround,
- YGJustifyCount,
} YGJustify;
+#define YGDirectionCount 3
typedef enum YGDirection {
YGDirectionInherit,
YGDirectionLTR,
YGDirectionRTL,
- YGDirectionCount,
} YGDirection;
+#define YGLogLevelCount 5
typedef enum YGLogLevel {
YGLogLevelError,
YGLogLevelWarn,
YGLogLevelInfo,
YGLogLevelDebug,
YGLogLevelVerbose,
- YGLogLevelCount,
} YGLogLevel;
+#define YGWrapCount 2
typedef enum YGWrap {
YGWrapNoWrap,
YGWrapWrap,
- YGWrapCount,
} YGWrap;
+#define YGOverflowCount 3
typedef enum YGOverflow {
YGOverflowVisible,
YGOverflowHidden,
YGOverflowScroll,
- YGOverflowCount,
} YGOverflow;
+#define YGExperimentalFeatureCount 2
typedef enum YGExperimentalFeature {
YGExperimentalFeatureRounding,
YGExperimentalFeatureWebFlexBasis,
- YGExperimentalFeatureCount,
} YGExperimentalFeature;
+#define YGAlignCount 5
typedef enum YGAlign {
YGAlignAuto,
YGAlignFlexStart,
YGAlignCenter,
YGAlignFlexEnd,
YGAlignStretch,
- YGAlignCount,
} YGAlign;
YG_EXTERN_C_END
diff --git a/yoga/Yoga.c b/yoga/Yoga.c
index dad81116..9723d894 100644
--- a/yoga/Yoga.c
+++ b/yoga/Yoga.c
@@ -42,7 +42,7 @@ typedef struct YGCachedMeasurement {
// This value was chosen based on empiracle data. Even the most complicated
// layouts should not require more than 16 entries to fit within the cache.
-enum { YG_MAX_CACHED_RESULT_COUNT = 16 };
+#define YG_MAX_CACHED_RESULT_COUNT 16
typedef struct YGLayout {
float position[4];
@@ -106,6 +106,66 @@ typedef struct YGNode {
void *context;
} YGNode;
+#define YG_DEFAULT_EDGE_VALUES { \
+ [YGEdgeLeft] = YGUndefined, \
+ [YGEdgeTop] = YGUndefined, \
+ [YGEdgeRight] = YGUndefined, \
+ [YGEdgeBottom] = YGUndefined, \
+ [YGEdgeStart] = YGUndefined, \
+ [YGEdgeEnd] = YGUndefined, \
+ [YGEdgeHorizontal] = YGUndefined, \
+ [YGEdgeVertical] = YGUndefined, \
+ [YGEdgeAll] = YGUndefined, \
+}
+
+#define YG_DEFAULT_DIMENSION_VALUES { \
+ [YGDimensionWidth] = YGUndefined, \
+ [YGDimensionHeight] = YGUndefined, \
+}
+
+YGNode gYGNodeDefaults = {
+ .parent = NULL,
+ .children = NULL,
+ .hasNewLayout = true,
+ .isDirty = false,
+
+ .style = {
+ .flex = YGUndefined,
+ .flexGrow = YGUndefined,
+ .flexShrink = YGUndefined,
+ .flexBasis = YGUndefined,
+ .justifyContent = YGJustifyFlexStart,
+ .alignItems = YGAlignStretch,
+ .alignContent = YGAlignFlexStart,
+ .direction = YGDirectionInherit,
+ .flexDirection = YGFlexDirectionColumn,
+ .overflow = YGOverflowVisible,
+ .dimensions = YG_DEFAULT_DIMENSION_VALUES,
+ .minDimensions = YG_DEFAULT_DIMENSION_VALUES,
+ .maxDimensions = YG_DEFAULT_DIMENSION_VALUES,
+ .position = YG_DEFAULT_EDGE_VALUES,
+ .margin = YG_DEFAULT_EDGE_VALUES,
+ .padding = YG_DEFAULT_EDGE_VALUES,
+ .border = YG_DEFAULT_EDGE_VALUES,
+ .aspectRatio = YGUndefined,
+ },
+
+ .layout = {
+ .dimensions = YG_DEFAULT_DIMENSION_VALUES,
+ .lastParentDirection = (YGDirection) -1,
+ .nextCachedMeasurementsIndex = 0,
+ .computedFlexBasis = YGUndefined,
+ .measuredDimensions = YG_DEFAULT_DIMENSION_VALUES,
+
+ .cachedLayout = {
+ .widthMeasureMode = (YGMeasureMode) -1,
+ .heightMeasureMode = (YGMeasureMode) -1,
+ .computedWidth = -1,
+ .computedHeight = -1,
+ },
+ },
+};
+
static void YGNodeMarkDirtyInternal(const YGNodeRef node);
YGMalloc gYGMalloc = &malloc;
@@ -133,8 +193,6 @@ static int YGAndroidLog(YGLogLevel level, const char *format, va_list args) {
case YGLogLevelVerbose:
androidLevel = ANDROID_LOG_VERBOSE;
break;
- case YGLogLevelCount:
- break;
}
const int result = __android_log_vprint(androidLevel, "YG-layout", format, args);
return result;
@@ -185,68 +243,14 @@ static inline float YGComputedEdgeValue(const float edges[YGEdgeCount],
return defaultValue;
}
-static void YGNodeInit(const YGNodeRef node) {
- node->parent = NULL;
- node->children = NULL;
- node->hasNewLayout = true;
- node->isDirty = false;
-
- node->style.flex = YGUndefined;
- node->style.flexGrow = YGUndefined;
- node->style.flexShrink = YGUndefined;
- node->style.flexBasis = YGUndefined;
-
- node->style.alignItems = YGAlignStretch;
- node->style.alignContent = YGAlignFlexStart;
-
- node->style.direction = YGDirectionInherit;
- node->style.flexDirection = YGFlexDirectionColumn;
-
- node->style.overflow = YGOverflowVisible;
-
- // Some of the fields default to undefined and not 0
- node->style.dimensions[YGDimensionWidth] = YGUndefined;
- node->style.dimensions[YGDimensionHeight] = YGUndefined;
-
- node->style.minDimensions[YGDimensionWidth] = YGUndefined;
- node->style.minDimensions[YGDimensionHeight] = YGUndefined;
-
- node->style.maxDimensions[YGDimensionWidth] = YGUndefined;
- node->style.maxDimensions[YGDimensionHeight] = YGUndefined;
-
- for (YGEdge edge = YGEdgeLeft; edge < YGEdgeCount; edge++) {
- node->style.position[edge] = YGUndefined;
- node->style.margin[edge] = YGUndefined;
- node->style.padding[edge] = YGUndefined;
- node->style.border[edge] = YGUndefined;
- }
-
- node->style.aspectRatio = YGUndefined;
-
- node->layout.dimensions[YGDimensionWidth] = YGUndefined;
- node->layout.dimensions[YGDimensionHeight] = YGUndefined;
-
- // Such that the comparison is always going to be false
- node->layout.lastParentDirection = (YGDirection) -1;
- node->layout.nextCachedMeasurementsIndex = 0;
- node->layout.computedFlexBasis = YGUndefined;
-
- node->layout.measuredDimensions[YGDimensionWidth] = YGUndefined;
- node->layout.measuredDimensions[YGDimensionHeight] = YGUndefined;
- node->layout.cachedLayout.widthMeasureMode = (YGMeasureMode) -1;
- node->layout.cachedLayout.heightMeasureMode = (YGMeasureMode) -1;
- node->layout.cachedLayout.computedWidth = -1;
- node->layout.cachedLayout.computedHeight = -1;
-}
-
int32_t gNodeInstanceCount = 0;
YGNodeRef YGNodeNew(void) {
- const YGNodeRef node = gYGCalloc(1, sizeof(YGNode));
+ const YGNodeRef node = gYGMalloc(sizeof(YGNode));
YG_ASSERT(node, "Could not allocate memory for node");
gNodeInstanceCount++;
- YGNodeInit(node);
+ memcpy(node, &gYGNodeDefaults, sizeof(YGNode));
return node;
}
@@ -281,8 +285,7 @@ void YGNodeReset(const YGNodeRef node) {
YG_ASSERT(node->parent == NULL, "Cannot reset a node still attached to a parent");
YGNodeListFree(node->children);
- memset(node, 0, sizeof(YGNode));
- YGNodeInit(node);
+ memcpy(node, &gYGNodeDefaults, sizeof(YGNode));
}
int32_t YGNodeGetInstanceCount(void) {
@@ -824,7 +827,7 @@ static YGFlexDirection YGFlexDirectionCross(const YGFlexDirection flexDirection,
static inline bool YGNodeIsFlex(const YGNodeRef node) {
return (node->style.positionType == YGPositionTypeRelative &&
- (node->style.flexGrow != 0 || node->style.flexShrink != 0 || node->style.flex != 0));
+ (YGNodeStyleGetFlexGrow(node) != 0 || YGNodeStyleGetFlexShrink(node) != 0));
}
static inline float YGNodeDimWithMargin(const YGNodeRef node, const YGFlexDirection axis) {
@@ -950,8 +953,6 @@ static void YGConstrainMaxSizeForMode(const float maxSize, YGMeasureMode *mode,
*size = maxSize;
}
break;
- case YGMeasureModeCount:
- break;
}
}
@@ -1061,7 +1062,7 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
if (!YGValueIsUndefined(child->style.aspectRatio)) {
if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) {
child->layout.computedFlexBasis =
- fmaxf(childWidth * child->style.aspectRatio,
+ fmaxf(childWidth / child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn));
return;
} else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) {
@@ -1156,7 +1157,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node,
childWidth = fmaxf(childHeight * child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn));
} else if (YGValueIsUndefined(childHeight)) {
- childHeight = fmaxf(childWidth * child->style.aspectRatio,
+ childHeight = fmaxf(childWidth / child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow));
}
}
@@ -1506,10 +1507,25 @@ static void YGNodelayoutImpl(const YGNodeRef node,
const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn);
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
- const float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
- const float availableInnerHeight =
+ float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
+ const float minInnerWidth = node->style.minDimensions[YGDimensionWidth] - marginAxisRow - paddingAndBorderAxisRow;
+ const float maxInnerWidth = node->style.maxDimensions[YGDimensionWidth] - marginAxisRow - paddingAndBorderAxisRow;
+ float availableInnerHeight =
availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
- const float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;
+ const float minInnerHeight = node->style.minDimensions[YGDimensionHeight] - marginAxisColumn - paddingAndBorderAxisColumn;
+ const float maxInnerHeight = node->style.maxDimensions[YGDimensionHeight] - marginAxisColumn - paddingAndBorderAxisColumn;
+ const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight;
+ const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight;
+
+ // Max dimension overrides predefined dimension value; Min dimension in turn overrides both of the above
+ if (!YGValueIsUndefined(availableInnerWidth)) {
+ availableInnerWidth = fmaxf(fminf(availableInnerWidth, maxInnerWidth), minInnerWidth);
+ }
+ if (!YGValueIsUndefined(availableInnerHeight)) {
+ availableInnerHeight = fmaxf(fminf(availableInnerHeight, maxInnerHeight), minInnerHeight);
+ }
+
+ float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;
const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;
// If there is only one child with flexGrow + flexShrink it means we can set the
@@ -1663,6 +1679,18 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Calculate the remaining available space that needs to be allocated.
// If the main dimension size isn't known, it is computed based on
// the line length, so there's no more space left to distribute.
+
+ // We resolve main dimension to fit minimum and maximum values
+ if (YGValueIsUndefined(availableInnerMainDim)) {
+ if (!YGValueIsUndefined(minInnerMainDim) &&
+ sizeConsumedOnCurrentLine < minInnerMainDim) {
+ availableInnerMainDim = minInnerMainDim;
+ } else if (!YGValueIsUndefined(maxInnerMainDim) &&
+ sizeConsumedOnCurrentLine > maxInnerMainDim) {
+ availableInnerMainDim = maxInnerMainDim;
+ }
+ }
+
float remainingFreeSpace = 0;
if (!YGValueIsUndefined(availableInnerMainDim)) {
remainingFreeSpace = availableInnerMainDim - sizeConsumedOnCurrentLine;
@@ -1850,16 +1878,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
}
if (!YGValueIsUndefined(currentRelativeChild->style.aspectRatio)) {
- if (isMainAxisRow && childHeightMeasureMode != YGMeasureModeExactly) {
+ if (isMainAxisRow) {
childHeight =
- fmaxf(childWidth * currentRelativeChild->style.aspectRatio,
+ fmaxf(childWidth / currentRelativeChild->style.aspectRatio,
YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionColumn));
childHeightMeasureMode = YGMeasureModeExactly;
- } else if (!isMainAxisRow && childWidthMeasureMode != YGMeasureModeExactly) {
+
+ childHeight = fminf(childHeight, availableInnerHeight);
+ childWidth = childHeight * currentRelativeChild->style.aspectRatio;
+ } else {
childWidth =
fmaxf(childHeight * currentRelativeChild->style.aspectRatio,
YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionRow));
childWidthMeasureMode = YGMeasureModeExactly;
+
+ childWidth = fminf(childWidth, availableInnerWidth);
+ childHeight = childWidth / currentRelativeChild->style.aspectRatio;
}
}
@@ -1934,7 +1968,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
leadingMainDim = betweenMainDim / 2;
break;
case YGJustifyFlexStart:
- case YGJustifyCount:
break;
}
@@ -2052,13 +2085,23 @@ static void YGNodelayoutImpl(const YGNodeRef node,
YGMeasureMode childHeightMeasureMode = YGMeasureModeExactly;
if (isMainAxisRow) {
- childHeight = crossDim;
childWidth = child->layout.measuredDimensions[YGDimensionWidth] +
YGNodeMarginForAxis(child, YGFlexDirectionRow);
+
+ if (!YGValueIsUndefined(child->style.aspectRatio)) {
+ childHeight = childWidth / child->style.aspectRatio;
+ } else {
+ childHeight = crossDim;
+ }
} else {
- childWidth = crossDim;
childHeight = child->layout.measuredDimensions[YGDimensionHeight] +
YGNodeMarginForAxis(child, YGFlexDirectionColumn);
+
+ if (!YGValueIsUndefined(child->style.aspectRatio)) {
+ childWidth = childHeight * child->style.aspectRatio;
+ } else {
+ childWidth = crossDim;
+ }
}
YGConstrainMaxSizeForMode(child->style.maxDimensions[YGDimensionWidth],
@@ -2127,7 +2170,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
break;
case YGAlignAuto:
case YGAlignFlexStart:
- case YGAlignCount:
break;
}
@@ -2187,7 +2229,6 @@ static void YGNodelayoutImpl(const YGNodeRef node,
break;
}
case YGAlignAuto:
- case YGAlignCount:
break;
}
}
diff --git a/yoga/Yoga.h b/yoga/Yoga.h
index 3bb96727..5e10b503 100644
--- a/yoga/Yoga.h
+++ b/yoga/Yoga.h
@@ -151,6 +151,9 @@ YG_NODE_STYLE_PROPERTY(float, MaxHeight, maxHeight);
// Yoga specific properties, not compatible with flexbox specification
// Aspect ratio control the size of the undefined dimension of a node.
+// Aspect ratio is encoded as a floating point value width/height. e.g. A value of 2 leads to a node
+// with a width twice the size of its height while a value of 0.5 gives the opposite effect.
+//
// - On a node with a set width/height aspect ratio control the size of the unset dimension
// - On a node with a set flex basis aspect ratio controls the size of the node in the cross axis if
// unset