diff --git a/gentest/fixtures/YGJustifyContentTest.html b/gentest/fixtures/YGJustifyContentTest.html index 0dee8c3a..2f832df7 100644 --- a/gentest/fixtures/YGJustifyContentTest.html +++ b/gentest/fixtures/YGJustifyContentTest.html @@ -86,3 +86,18 @@
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
diff --git a/tests/YGJustifyContentTest.cpp b/tests/YGJustifyContentTest.cpp index e5d42168..9a022889 100644 --- a/tests/YGJustifyContentTest.cpp +++ b/tests/YGJustifyContentTest.cpp @@ -1,11 +1,12 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - -// @Generated by gentest/gentest.rb from gentest/fixtures/YGJustifyContentTest.html +// @Generated by gentest/gentest.rb from +// gentest/fixtures/YGJustifyContentTest.html #include #include @@ -735,6 +736,164 @@ TEST(YogaTest, justify_content_row_min_width_and_margin) { YGConfigFree(config); } +TEST( + YogaTest, + justify_content_min_width_with_padding_child_width_greater_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetWidth(root, 1000); + YGNodeStyleSetHeight(root, 1584); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child0, YGAlignStretch); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0_child0, YGAlignStretch); + YGNodeStyleSetMinWidth(root_child0_child0, 400); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeHorizontal, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child0_child0_child0, YGAlignStretch); + YGNodeStyleSetWidth(root_child0_child0_child0, 300); + YGNodeStyleSetHeight(root_child0_child0_child0, 100); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(1000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(1584, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1000, 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(500, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(1000, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(1584, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1000, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(500, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(300, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + +TEST( + YogaTest, + justify_content_min_width_with_padding_child_width_lower_than_parent) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetAlignContent(root, YGAlignStretch); + YGNodeStyleSetWidth(root, 1080); + YGNodeStyleSetHeight(root, 1584); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child0, YGAlignStretch); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetJustifyContent(root_child0_child0, YGJustifyCenter); + YGNodeStyleSetAlignContent(root_child0_child0, YGAlignStretch); + YGNodeStyleSetMinWidth(root_child0_child0, 400); + YGNodeStyleSetPadding(root_child0_child0, YGEdgeHorizontal, 100); + YGNodeInsertChild(root_child0, root_child0_child0, 0); + + const YGNodeRef root_child0_child0_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root_child0_child0_child0, YGFlexDirectionRow); + YGNodeStyleSetAlignContent(root_child0_child0_child0, YGAlignStretch); + YGNodeStyleSetWidth(root_child0_child0_child0, 199); + YGNodeStyleSetHeight(root_child0_child0_child0, 100); + YGNodeInsertChild(root_child0_child0, root_child0_child0_child0, 0); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(1584, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1080, 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(400, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(101, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(199, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(1584, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(1080, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(680, YGNodeLayoutGetLeft(root_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0)); + ASSERT_FLOAT_EQ(400, YGNodeLayoutGetWidth(root_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0)); + + ASSERT_FLOAT_EQ(101, YGNodeLayoutGetLeft(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(199, YGNodeLayoutGetWidth(root_child0_child0_child0)); + ASSERT_FLOAT_EQ(100, YGNodeLayoutGetHeight(root_child0_child0_child0)); + // + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} + TEST(YogaTest, justify_content_row_max_width_and_margin) { const YGConfigRef config = YGConfigNew(); diff --git a/tests/YGPaddingTest.cpp b/tests/YGPaddingTest.cpp index f0d37527..1873151c 100644 --- a/tests/YGPaddingTest.cpp +++ b/tests/YGPaddingTest.cpp @@ -1,10 +1,10 @@ -/** - * Copyright (c) 2014-present, Facebook, Inc. +/* + * Copyright (c) 2014-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the LICENSE + * file in the root directory of this source tree. * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. */ - // @Generated by gentest/gentest.rb from gentest/fixtures/YGPaddingTest.html #include diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index f35b70b5..621564f4 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -2420,20 +2420,32 @@ static void YGJustifyMainAxis( const float& availableInnerWidth, const bool& performLayout) { const YGStyle& style = node->getStyle(); - - // If we are using "at most" rules in the main axis. Calculate the remaining - // space when constraint by the min size defined for the main axis. + const float leadingPaddingAndBorderMain = YGUnwrapFloatOptional( + node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)); + const float trailingPaddingAndBorderMain = YGUnwrapFloatOptional( + node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)); + // If we are using "at most" rules in the main axis, make sure that + // remainingFreeSpace is 0 when min main dimension is not given if (measureModeMainDim == YGMeasureModeAtMost && collectedFlexItemsValues.remainingFreeSpace > 0) { if (style.minDimensions[dim[mainAxis]].unit != YGUnitUndefined && !YGResolveValue(style.minDimensions[dim[mainAxis]], mainAxisownerSize) .isUndefined()) { - collectedFlexItemsValues.remainingFreeSpace = YGFloatMax( - 0, + // This condition makes sure that if the size of main dimension(after + // considering child nodes main dim, leading and trailing padding etc) + // falls below min dimension, then the remainingFreeSpace is reassigned + // considering the min dimension + + // `minAvailableMainDim` denotes minimum available space in which child + // can be laid out, it will exclude space consumed by padding and border. + const float minAvailableMainDim = YGUnwrapFloatOptional(YGResolveValue( style.minDimensions[dim[mainAxis]], mainAxisownerSize)) - - (availableInnerMainDim - - collectedFlexItemsValues.remainingFreeSpace)); + leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; + const float occupiedSpaceByChildNodes = + availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace; + collectedFlexItemsValues.remainingFreeSpace = + YGFloatMax(0, minAvailableMainDim - occupiedSpaceByChildNodes); } else { collectedFlexItemsValues.remainingFreeSpace = 0; } @@ -2495,8 +2507,6 @@ static void YGJustifyMainAxis( } } - const float leadingPaddingAndBorderMain = YGUnwrapFloatOptional( - node->getLeadingPaddingAndBorder(mainAxis, ownerWidth)); collectedFlexItemsValues.mainDim = leadingPaddingAndBorderMain + leadingMainDim; collectedFlexItemsValues.crossDim = 0; @@ -2579,8 +2589,7 @@ static void YGJustifyMainAxis( } } } - collectedFlexItemsValues.mainDim += YGUnwrapFloatOptional( - node->getTrailingPaddingAndBorder(mainAxis, ownerWidth)); + collectedFlexItemsValues.mainDim += trailingPaddingAndBorderMain; } //