diff --git a/ReactCommon/yoga/yoga/Yoga.c b/ReactCommon/yoga/yoga/Yoga.c index 792464b64..1163e870a 100644 --- a/ReactCommon/yoga/yoga/Yoga.c +++ b/ReactCommon/yoga/yoga/Yoga.c @@ -1071,9 +1071,14 @@ static inline float YGNodeDimWithMargin(const YGNodeRef node, YGNodeTrailingMargin(node, axis, widthSize); } -static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, const YGFlexDirection axis) { - return node->style.dimensions[dim[axis]].unit != YGUnitUndefined && - node->style.dimensions[dim[axis]].value >= 0.0f; +static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, + const YGFlexDirection axis, + const float parentSize) { + return !( + node->style.dimensions[dim[axis]].unit == YGUnitUndefined || + (node->style.dimensions[dim[axis]].unit == YGUnitPixel && + node->style.dimensions[dim[axis]].value < 0.0f) || + (node->style.dimensions[dim[axis]].unit == YGUnitPercent && YGFloatIsUndefined(parentSize))); } static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, const YGFlexDirection axis) { @@ -1244,17 +1249,18 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node, YGMeasureMode childWidthMeasureMode; YGMeasureMode childHeightMeasureMode; - const bool isRowStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionRow); - const bool isColumnStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn); + const float resolvedFlexBasis = + YGValueResolve(YGNodeStyleGetFlexBasisPtr(child), mainAxisParentSize); + const bool isRowStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, parentWidth); + const bool isColumnStyleDimDefined = + YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, parentHeight); - if (YGNodeStyleGetFlexBasisPtr(child)->unit != YGUnitUndefined && - !YGFloatIsUndefined(mainAxisSize)) { + if (!YGFloatIsUndefined(resolvedFlexBasis) && !YGFloatIsUndefined(mainAxisSize)) { if (YGFloatIsUndefined(child->layout.computedFlexBasis) || (YGIsExperimentalFeatureEnabled(YGExperimentalFeatureWebFlexBasis) && child->layout.computedFlexBasisGeneration != gCurrentGenerationCount)) { child->layout.computedFlexBasis = - fmaxf(YGValueResolve(YGNodeStyleGetFlexBasisPtr(child), mainAxisParentSize), - YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)); + fmaxf(resolvedFlexBasis, YGNodePaddingAndBorderForAxis(child, mainAxis, parentWidth)); } } else if (isMainAxisRow && isRowStyleDimDefined) { // The width is definite, so use that as the flex basis. @@ -1382,7 +1388,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, const float marginRow = YGNodeMarginForAxis(child, YGFlexDirectionRow, width); const float marginColumn = YGNodeMarginForAxis(child, YGFlexDirectionColumn, width); - if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow)) { + if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { childWidth = YGValueResolve(&child->style.dimensions[YGDimensionWidth], width) + marginRow; } else { // If the child doesn't have a specified width, compute the width based @@ -1399,7 +1405,7 @@ static void YGNodeAbsoluteLayoutChild(const YGNodeRef node, } } - if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn)) { + if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { childHeight = YGValueResolve(&child->style.dimensions[YGDimensionHeight], height) + marginColumn; } else { @@ -2230,12 +2236,16 @@ static void YGNodelayoutImpl(const YGNodeRef node, childWidthMeasureMode = YGMeasureModeExactly; if (!YGFloatIsUndefined(availableInnerCrossDim) && - !YGNodeIsStyleDimDefined(currentRelativeChild, YGFlexDirectionColumn) && + !YGNodeIsStyleDimDefined(currentRelativeChild, + YGFlexDirectionColumn, + availableInnerHeight) && heightMeasureMode == YGMeasureModeExactly && YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch) { childHeight = availableInnerCrossDim; childHeightMeasureMode = YGMeasureModeExactly; - } else if (!YGNodeIsStyleDimDefined(currentRelativeChild, YGFlexDirectionColumn)) { + } else if (!YGNodeIsStyleDimDefined(currentRelativeChild, + YGFlexDirectionColumn, + availableInnerHeight)) { childHeight = availableInnerCrossDim; childHeightMeasureMode = YGFloatIsUndefined(childHeight) ? YGMeasureModeUndefined : YGMeasureModeAtMost; @@ -2250,12 +2260,16 @@ static void YGNodelayoutImpl(const YGNodeRef node, childHeightMeasureMode = YGMeasureModeExactly; if (!YGFloatIsUndefined(availableInnerCrossDim) && - !YGNodeIsStyleDimDefined(currentRelativeChild, YGFlexDirectionRow) && + !YGNodeIsStyleDimDefined(currentRelativeChild, + YGFlexDirectionRow, + availableInnerWidth) && widthMeasureMode == YGMeasureModeExactly && YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch) { childWidth = availableInnerCrossDim; childWidthMeasureMode = YGMeasureModeExactly; - } else if (!YGNodeIsStyleDimDefined(currentRelativeChild, YGFlexDirectionRow)) { + } else if (!YGNodeIsStyleDimDefined(currentRelativeChild, + YGFlexDirectionRow, + availableInnerWidth)) { childWidth = availableInnerCrossDim; childWidthMeasureMode = YGFloatIsUndefined(childWidth) ? YGMeasureModeUndefined : YGMeasureModeAtMost; @@ -2312,7 +2326,7 @@ static void YGNodelayoutImpl(const YGNodeRef node, &childHeight); const bool requiresStretchLayout = - !YGNodeIsStyleDimDefined(currentRelativeChild, crossAxis) && + !YGNodeIsStyleDimDefined(currentRelativeChild, crossAxis, availableInnerCrossDim) && YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch; // Recursively call the layout algorithm for this child with the updated @@ -2497,8 +2511,10 @@ static void YGNodelayoutImpl(const YGNodeRef node, // current line. if (alignItem == YGAlignStretch) { const bool isCrossSizeDefinite = - (isMainAxisRow && YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn)) || - (!isMainAxisRow && YGNodeIsStyleDimDefined(child, YGFlexDirectionRow)); + (isMainAxisRow && + YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, availableInnerHeight)) || + (!isMainAxisRow && + YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, availableInnerWidth)); float childWidth; float childHeight; @@ -3106,7 +3122,7 @@ void YGNodeCalculateLayout(const YGNodeRef node, if (!YGFloatIsUndefined(width)) { widthMeasureMode = YGMeasureModeExactly; - } else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow)) { + } else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, availableWidth)) { width = YGValueResolve(&node->style.dimensions[dim[YGFlexDirectionRow]], availableWidth) + YGNodeMarginForAxis(node, YGFlexDirectionRow, availableWidth); widthMeasureMode = YGMeasureModeExactly; @@ -3117,7 +3133,7 @@ void YGNodeCalculateLayout(const YGNodeRef node, if (!YGFloatIsUndefined(height)) { heightMeasureMode = YGMeasureModeExactly; - } else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn)) { + } else if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, availableHeight)) { height = YGValueResolve(&node->style.dimensions[dim[YGFlexDirectionColumn]], availableHeight) + YGNodeMarginForAxis(node, YGFlexDirectionColumn, availableWidth); heightMeasureMode = YGMeasureModeExactly;