diff --git a/CSSLayout/CSSLayout.c b/CSSLayout/CSSLayout.c
index 470c048c..f2d884b7 100644
--- a/CSSLayout/CSSLayout.c
+++ b/CSSLayout/CSSLayout.c
@@ -107,7 +107,7 @@ static void _CSSNodeMarkDirty(const CSSNodeRef node);
static int _csslayoutAndroidLog(CSSLogLevel level, const char *format, va_list args) {
int androidLevel = CSSLogLevelDebug;
switch (level) {
- case CSSLogLevelError:
+ case CSSLogLevelError:
androidLevel = ANDROID_LOG_ERROR;
break;
case CSSLogLevelWarn:
@@ -116,7 +116,7 @@ static int _csslayoutAndroidLog(CSSLogLevel level, const char *format, va_list a
case CSSLogLevelInfo:
androidLevel = ANDROID_LOG_INFO;
break;
- case CSSLogLevelDebug:
+ case CSSLogLevelDebug:
androidLevel = ANDROID_LOG_DEBUG;
break;
case CSSLogLevelVerbose:
@@ -130,11 +130,11 @@ static CSSLogger gLogger = &_csslayoutAndroidLog;
#else
static int _csslayoutDefaultLog(CSSLogLevel level, const char *format, va_list args) {
switch (level) {
- case CSSLogLevelError:
+ case CSSLogLevelError:
return vfprintf(stderr, format, args);
case CSSLogLevelWarn:
case CSSLogLevelInfo:
- case CSSLogLevelDebug:
+ case CSSLogLevelDebug:
case CSSLogLevelVerbose:
default:
return vprintf(format, args);
@@ -289,7 +289,8 @@ void CSSNodeSetMeasureFunc(const CSSNodeRef node, CSSMeasureFunc measureFunc) {
if (measureFunc == NULL) {
node->measure = NULL;
} else {
- CSS_ASSERT(CSSNodeChildCount(node) == 0, "Cannot set measure function: Nodes with measure functions cannot have children.");
+ CSS_ASSERT(CSSNodeChildCount(node) == 0,
+ "Cannot set measure function: Nodes with measure functions cannot have children.");
node->measure = measureFunc;
}
}
@@ -897,6 +898,23 @@ static float getRelativePosition(const CSSNodeRef node, const CSSFlexDirection a
: -getTrailingPosition(node, axis);
}
+static void constrainMaxSizeForMode(const float maxSize, CSSMeasureMode *mode, float *size) {
+ switch (*mode) {
+ case CSSMeasureModeExactly:
+ case CSSMeasureModeAtMost:
+ *size = (CSSValueIsUndefined(maxSize) || *size < maxSize) ? *size : maxSize;
+ break;
+ case CSSMeasureModeUndefined:
+ if (!CSSValueIsUndefined(maxSize)) {
+ *mode = CSSMeasureModeAtMost;
+ *size = maxSize;
+ }
+ break;
+ case CSSMeasureModeCount:
+ break;
+ }
+}
+
static void setPosition(const CSSNodeRef node, const CSSDirection direction) {
const CSSFlexDirection mainAxis = resolveAxis(node->style.flexDirection, direction);
const CSSFlexDirection crossAxis = getCrossFlexDirection(mainAxis, direction);
@@ -996,15 +1014,12 @@ static void computeChildFlexBasis(const CSSNodeRef node,
childHeightMeasureMode = CSSMeasureModeExactly;
}
- if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionWidth])) {
- childWidth = child->style.maxDimensions[CSSDimensionWidth];
- childWidthMeasureMode = CSSMeasureModeAtMost;
- }
-
- if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionHeight])) {
- childHeight = child->style.maxDimensions[CSSDimensionHeight];
- childHeightMeasureMode = CSSMeasureModeAtMost;
- }
+ constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionWidth],
+ &childWidthMeasureMode,
+ &childWidth);
+ constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionHeight],
+ &childHeightMeasureMode,
+ &childHeight);
// Measure the child
layoutNodeInternal(child,
@@ -1122,7 +1137,7 @@ static void absoluteLayoutChild(const CSSNodeRef node,
if (isTrailingPosDefined(child, crossAxis) && !isLeadingPosDefined(child, crossAxis)) {
child->layout.position[leading[crossAxis]] = node->layout.measuredDimensions[dim[crossAxis]] -
child->layout.measuredDimensions[dim[crossAxis]] -
- getTrailingBorder(node, crossAxis) -
+ getTrailingBorder(node, crossAxis) -
getTrailingPosition(child, crossAxis);
}
}
@@ -1738,15 +1753,12 @@ static void layoutNodeImpl(const CSSNodeRef node,
}
}
- if (!CSSValueIsUndefined(currentRelativeChild->style.maxDimensions[CSSDimensionWidth])) {
- childWidth = currentRelativeChild->style.maxDimensions[CSSDimensionWidth];
- childWidthMeasureMode = CSSMeasureModeAtMost;
- }
-
- if (!CSSValueIsUndefined(currentRelativeChild->style.maxDimensions[CSSDimensionHeight])) {
- childHeight = currentRelativeChild->style.maxDimensions[CSSDimensionHeight];
- childHeightMeasureMode = CSSMeasureModeAtMost;
- }
+ constrainMaxSizeForMode(currentRelativeChild->style.maxDimensions[CSSDimensionWidth],
+ &childWidthMeasureMode,
+ &childWidth);
+ constrainMaxSizeForMode(currentRelativeChild->style.maxDimensions[CSSDimensionHeight],
+ &childHeightMeasureMode,
+ &childHeight);
const bool requiresStretchLayout =
!isStyleDimDefined(currentRelativeChild, crossAxis) &&
@@ -1858,7 +1870,8 @@ static void layoutNodeImpl(const CSSNodeRef node,
crossDim = fmaxf(crossDim, getDimWithMargin(child, crossAxis));
}
} else if (performLayout) {
- child->layout.position[pos[mainAxis]] += getLeadingBorder(node, mainAxis) + leadingMainDim;
+ child->layout.position[pos[mainAxis]] +=
+ getLeadingBorder(node, mainAxis) + leadingMainDim;
}
}
}
@@ -1924,8 +1937,8 @@ static void layoutNodeImpl(const CSSNodeRef node,
float childWidth;
float childHeight;
- CSSMeasureMode childWidthMeasureMode;
- CSSMeasureMode childHeightMeasureMode;
+ CSSMeasureMode childWidthMeasureMode = CSSMeasureModeExactly;
+ CSSMeasureMode childHeightMeasureMode = CSSMeasureModeExactly;
if (isMainAxisRow) {
childHeight = crossDim;
@@ -1937,13 +1950,12 @@ static void layoutNodeImpl(const CSSNodeRef node,
getMarginAxis(child, CSSFlexDirectionColumn);
}
- if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionWidth])) {
- childWidth = child->style.maxDimensions[CSSDimensionWidth];
- }
-
- if (!CSSValueIsUndefined(child->style.maxDimensions[CSSDimensionHeight])) {
- childHeight = child->style.maxDimensions[CSSDimensionHeight];
- }
+ constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionWidth],
+ &childWidthMeasureMode,
+ &childWidth);
+ constrainMaxSizeForMode(child->style.maxDimensions[CSSDimensionHeight],
+ &childHeightMeasureMode,
+ &childHeight);
// If the child defines a definite size for its cross axis, there's
// no need to stretch.
@@ -1952,6 +1964,7 @@ static void layoutNodeImpl(const CSSNodeRef node,
CSSValueIsUndefined(childWidth) ? CSSMeasureModeUndefined : CSSMeasureModeExactly;
childHeightMeasureMode = CSSValueIsUndefined(childHeight) ? CSSMeasureModeUndefined
: CSSMeasureModeExactly;
+
layoutNodeInternal(child,
childWidth,
childHeight,
diff --git a/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs b/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs
index f09deb1f..8365a082 100644
--- a/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs
+++ b/csharp/tests/Facebook.CSSLayout/CSSLayoutMinMaxDimensionTest.cs
@@ -47,6 +47,12 @@
+
+
*
*/
@@ -442,5 +448,58 @@ namespace Facebook.CSSLayout
Assert.AreEqual(20, root_child0_child0.LayoutHeight);
}
+ [Test]
+ public void Test_flex_grow_within_constrained_max_width()
+ {
+ CSSNode root = new CSSNode();
+ root.StyleWidth = 200;
+ root.StyleHeight = 100;
+
+ CSSNode root_child0 = new CSSNode();
+ root_child0.FlexDirection = CSSFlexDirection.Row;
+ root_child0.StyleMaxWidth = 300;
+ root.Insert(0, root_child0);
+
+ CSSNode root_child0_child0 = new CSSNode();
+ root_child0_child0.FlexGrow = 1;
+ root_child0_child0.StyleHeight = 20;
+ root_child0.Insert(0, root_child0_child0);
+ root.StyleDirection = CSSDirection.LeftToRight;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0, root.LayoutX);
+ Assert.AreEqual(0, root.LayoutY);
+ Assert.AreEqual(200, root.LayoutWidth);
+ Assert.AreEqual(100, root.LayoutHeight);
+
+ Assert.AreEqual(0, root_child0.LayoutX);
+ Assert.AreEqual(0, root_child0.LayoutY);
+ Assert.AreEqual(200, root_child0.LayoutWidth);
+ Assert.AreEqual(20, root_child0.LayoutHeight);
+
+ Assert.AreEqual(0, root_child0_child0.LayoutX);
+ Assert.AreEqual(0, root_child0_child0.LayoutY);
+ Assert.AreEqual(200, root_child0_child0.LayoutWidth);
+ Assert.AreEqual(20, root_child0_child0.LayoutHeight);
+
+ root.StyleDirection = CSSDirection.RightToLeft;
+ root.CalculateLayout();
+
+ Assert.AreEqual(0, root.LayoutX);
+ Assert.AreEqual(0, root.LayoutY);
+ Assert.AreEqual(200, root.LayoutWidth);
+ Assert.AreEqual(100, root.LayoutHeight);
+
+ Assert.AreEqual(0, root_child0.LayoutX);
+ Assert.AreEqual(0, root_child0.LayoutY);
+ Assert.AreEqual(200, root_child0.LayoutWidth);
+ Assert.AreEqual(20, root_child0.LayoutHeight);
+
+ Assert.AreEqual(0, root_child0_child0.LayoutX);
+ Assert.AreEqual(0, root_child0_child0.LayoutY);
+ Assert.AreEqual(200, root_child0_child0.LayoutWidth);
+ Assert.AreEqual(20, root_child0_child0.LayoutHeight);
+ }
+
}
}
diff --git a/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html b/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html
index 599f3fe6..6e469707 100644
--- a/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html
+++ b/gentest/fixtures/CSSLayoutMinMaxDimensionTest.html
@@ -35,3 +35,9 @@
+
+
diff --git a/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java b/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java
index 271f3a9f..d513f5e4 100644
--- a/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java
+++ b/java/tests/com/facebook/csslayout/CSSLayoutMinMaxDimensionTest.java
@@ -47,6 +47,12 @@
+
+
*
*/
@@ -433,4 +439,56 @@ public class CSSLayoutMinMaxDimensionTest {
assertEquals(20, root_child0_child0.getLayoutHeight(), 0.0f);
}
+ @Test
+ public void test_flex_grow_within_constrained_max_width() {
+ final CSSNode root = new CSSNode();
+ root.setStyleWidth(200);
+ root.setStyleHeight(100);
+
+ final CSSNode root_child0 = new CSSNode();
+ root_child0.setFlexDirection(CSSFlexDirection.ROW);
+ root_child0.setStyleMaxWidth(300);
+ root.addChildAt(root_child0, 0);
+
+ final CSSNode root_child0_child0 = new CSSNode();
+ root_child0_child0.setFlexGrow(1);
+ root_child0_child0.setStyleHeight(20);
+ root_child0.addChildAt(root_child0_child0, 0);
+ root.setDirection(CSSDirection.LTR);
+ root.calculateLayout(null);
+
+ assertEquals(0, root.getLayoutX(), 0.0f);
+ assertEquals(0, root.getLayoutY(), 0.0f);
+ assertEquals(200, root.getLayoutWidth(), 0.0f);
+ assertEquals(100, root.getLayoutHeight(), 0.0f);
+
+ assertEquals(0, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0, root_child0.getLayoutY(), 0.0f);
+ assertEquals(200, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(20, root_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(0, root_child0_child0.getLayoutX(), 0.0f);
+ assertEquals(0, root_child0_child0.getLayoutY(), 0.0f);
+ assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f);
+ assertEquals(20, root_child0_child0.getLayoutHeight(), 0.0f);
+
+ root.setDirection(CSSDirection.RTL);
+ root.calculateLayout(null);
+
+ assertEquals(0, root.getLayoutX(), 0.0f);
+ assertEquals(0, root.getLayoutY(), 0.0f);
+ assertEquals(200, root.getLayoutWidth(), 0.0f);
+ assertEquals(100, root.getLayoutHeight(), 0.0f);
+
+ assertEquals(0, root_child0.getLayoutX(), 0.0f);
+ assertEquals(0, root_child0.getLayoutY(), 0.0f);
+ assertEquals(200, root_child0.getLayoutWidth(), 0.0f);
+ assertEquals(20, root_child0.getLayoutHeight(), 0.0f);
+
+ assertEquals(0, root_child0_child0.getLayoutX(), 0.0f);
+ assertEquals(0, root_child0_child0.getLayoutY(), 0.0f);
+ assertEquals(200, root_child0_child0.getLayoutWidth(), 0.0f);
+ assertEquals(20, root_child0_child0.getLayoutHeight(), 0.0f);
+ }
+
}
diff --git a/tests/CSSLayoutMinMaxDimensionTest.cpp b/tests/CSSLayoutMinMaxDimensionTest.cpp
index 38358a36..b9bec882 100644
--- a/tests/CSSLayoutMinMaxDimensionTest.cpp
+++ b/tests/CSSLayoutMinMaxDimensionTest.cpp
@@ -47,6 +47,12 @@
+
+
*
*/
@@ -420,3 +426,54 @@ TEST(CSSLayoutTest, flex_grow_within_max_width) {
CSSNodeFreeRecursive(root);
}
+
+TEST(CSSLayoutTest, flex_grow_within_constrained_max_width) {
+ const CSSNodeRef root = CSSNodeNew();
+ CSSNodeStyleSetWidth(root, 200);
+ CSSNodeStyleSetHeight(root, 100);
+
+ const CSSNodeRef root_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexDirection(root_child0, CSSFlexDirectionRow);
+ CSSNodeStyleSetMaxWidth(root_child0, 300);
+ CSSNodeInsertChild(root, root_child0, 0);
+
+ const CSSNodeRef root_child0_child0 = CSSNodeNew();
+ CSSNodeStyleSetFlexGrow(root_child0_child0, 1);
+ CSSNodeStyleSetHeight(root_child0_child0, 20);
+ CSSNodeInsertChild(root_child0, root_child0_child0, 0);
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionLTR);
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_EQ(200, CSSNodeLayoutGetWidth(root));
+ ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0));
+ ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0));
+ ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0_child0));
+
+ CSSNodeCalculateLayout(root, CSSUndefined, CSSUndefined, CSSDirectionRTL);
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root));
+ ASSERT_EQ(200, CSSNodeLayoutGetWidth(root));
+ ASSERT_EQ(100, CSSNodeLayoutGetHeight(root));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0));
+ ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0));
+ ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0));
+
+ ASSERT_EQ(0, CSSNodeLayoutGetLeft(root_child0_child0));
+ ASSERT_EQ(0, CSSNodeLayoutGetTop(root_child0_child0));
+ ASSERT_EQ(200, CSSNodeLayoutGetWidth(root_child0_child0));
+ ASSERT_EQ(20, CSSNodeLayoutGetHeight(root_child0_child0));
+
+ CSSNodeFreeRecursive(root);
+}