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
This commit is contained in:
Lukas Wöhrl
2017-02-11 08:32:51 -08:00
committed by Facebook Github Bot
parent adf8691093
commit 063f65d065
6 changed files with 5043 additions and 232 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -6,15 +6,23 @@
<div style="width: 50px; height: 10px;"></div>
</div>
<div id="align_content_flex_end" style="width: 130px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: flex-end;">
<div style="width: 50px; height: 10px;"></div>
<div style="width: 50px; height: 10px;"></div>
<div style="width: 50px; height: 10px;"></div>
<div id="align_content_flex_start_without_height_on_children" style="width: 100px; height: 100px; flex-wrap: wrap; flex-direction: column; align-content: flex-start;">
<div style="width: 50px;"></div>
<div style="width: 50px; height: 10px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px; height: 10px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_center" style="width: 130px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: center;">
<div id="align_content_flex_start_with_flex" style="width: 100px; height: 120px; flex-wrap: wrap; flex-direction: column; align-content: flex-start;">
<div style="width: 50px; flex: 1; flex-shrink: 0;"></div>
<div style="width: 50px; flex: 1; height: 10px; flex-shrink: 0;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px; flex: 1;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_flex_end" style="width: 100px; height: 100px; flex-wrap: wrap; flex-direction: column; align-content: flex-end;">
<div style="width: 50px; height: 10px;"></div>
<div style="width: 50px; height: 10px;"></div>
<div style="width: 50px; height: 10px;"></div>
@@ -45,3 +53,92 @@
<div style="width: 50px; height: 10px;"></div>
<div style="width: 50px; height: 10px;"></div>
</div>
<div id="align_content_stretch_row" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_children" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;">
<div style="flex: 1;"></div>
</div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_flex" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px; flex: 1;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px; flex: 1;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_flex_no_shrink" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px; flex: 1;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px; flex: 1; flex-shrink: 0;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_margin" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px; margin: 10px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px; margin: 10px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_padding" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px; padding: 10px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px; padding: 10px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_single_row" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_fixed_height" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px; height: 60px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_max_height" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px; max-height: 20px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_row_with_min_height" style="width: 150px; height: 100px; flex-wrap: wrap; flex-direction: row; align-content: stretch;">
<div style="width: 50px;"></div>
<div style="width: 50px; min-height: 80px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
<div style="width: 50px;"></div>
</div>
<div id="align_content_stretch_column" style="width: 100px; height: 150px; flex-wrap: wrap; flex-direction: column; align-content: stretch;">
<div style="height: 50px;">
<div style="flex: 1;"></div>
</div>
<div style="height: 50px; flex: 1;"></div>
<div style="height: 50px;"></div>
<div style="height: 50px;"></div>
<div style="height: 50px;"></div>
</div>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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: {