From f288368cef80fd7eac25d1ced33515262f77a98b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20W=C3=B6hrl?= Date: Sat, 11 Feb 2017 08:32:51 -0800 Subject: [PATCH] Fix align-content strech with multiple lines Summary: Fixes ```align-content:strech``` on nodes without specified cross dimension, if there are multiple lines. Currently it uses the full height of the parent, but it has to use the line height. As we don't know the number of lines until here, we need to realign the relevant children. Closes https://github.com/facebook/yoga/pull/368 Reviewed By: gkassabli Differential Revision: D4528559 Pulled By: emilsjolander fbshipit-source-id: 019e6f85fa452d0c3412f711e3886f0c4452da47 --- ReactCommon/yoga/yoga/Yoga.c | 56 +++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/ReactCommon/yoga/yoga/Yoga.c b/ReactCommon/yoga/yoga/Yoga.c index e8d5c31ec..771a8a175 100644 --- a/ReactCommon/yoga/yoga/Yoga.c +++ b/ReactCommon/yoga/yoga/Yoga.c @@ -2485,10 +2485,23 @@ static void YGNodelayoutImpl(const YGNodeRef node, // the spacing. mainDim += betweenMainDim + YGNodeDimWithMargin(child, mainAxis, availableInnerWidth); - // The cross dimension is the max of the elements dimension since - // there - // can only be one element in that cross dimension. - crossDim = fmaxf(crossDim, YGNodeDimWithMargin(child, crossAxis, availableInnerWidth)); + if (YGNodeIsStyleDimDefined(child, crossAxis, availableInnerCrossDim) || + child->measure != NULL || + !isNodeFlexWrap) { + // The cross dimension is the max of the elements dimension since + // there + // can only be one element in that cross dimension. + crossDim = + fmaxf(crossDim, YGNodeDimWithMargin(child, crossAxis, availableInnerWidth)); + } else { + // If we wrap the lines we only take the space we need at least. + crossDim = fmaxf( + crossDim, + YGNodeMarginForAxis(child, crossAxis, availableInnerWidth) + + fmaxf(YGValueResolve(&child->style.minDimensions[dim[crossAxis]], + availableInnerWidth), + YGNodePaddingAndBorderForAxis(child, crossAxis, availableInnerWidth))); + } } } else if (performLayout) { child->layout.position[pos[mainAxis]] += @@ -2652,7 +2665,8 @@ static void YGNodelayoutImpl(const YGNodeRef node, } // STEP 8: MULTI-LINE CONTENT ALIGNMENT - if (performLayout && (lineCount > 1 || YGIsBaselineLayout(node)) && + if (performLayout && + (lineCount > 1 || node->style.alignContent == YGAlignStretch || YGIsBaselineLayout(node)) && !YGFloatIsUndefined(availableInnerCrossDim)) { const float remainingAlignContentDim = availableInnerCrossDim - totalLineCrossDim; @@ -2760,8 +2774,36 @@ static void YGNodelayoutImpl(const YGNodeRef node, case YGAlignStretch: { child->layout.position[pos[crossAxis]] = currentLead + YGNodeLeadingMargin(child, crossAxis, availableInnerWidth); - // TODO(prenaux): Correctly set the height of items with indefinite - // (auto) crossAxis dimension. + + // Remeasure child with the line height as it as been only measured with the + // parents height yet. + if (!YGNodeIsStyleDimDefined(child, crossAxis, availableInnerCrossDim)) { + const float childWidth = + isMainAxisRow ? (child->layout.measuredDimensions[YGDimensionWidth] + + YGNodeMarginForAxis(child, crossAxis, availableInnerWidth)) + : lineHeight; + + const float childHeight = + !isMainAxisRow ? (child->layout.measuredDimensions[YGDimensionHeight] + + YGNodeMarginForAxis(child, crossAxis, availableInnerWidth)) + : lineHeight; + + if (!(YGFloatsEqual(childWidth, + child->layout.measuredDimensions[YGDimensionWidth]) && + YGFloatsEqual(childHeight, + child->layout.measuredDimensions[YGDimensionHeight]))) { + YGLayoutNodeInternal(child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + availableInnerWidth, + availableInnerHeight, + true, + "stretch"); + } + } break; } case YGAlignBaseline: {