use correct parent sizes for percentage calculation

This commit is contained in:
Lukas Woehrl
2016-12-15 15:33:55 +01:00
parent 687cbb8632
commit a84d55e3c5

View File

@@ -194,11 +194,13 @@ static inline YGValue YGComputedEdgeValue(const YGValue edges[YGEdgeCount],
} }
static inline float YGValueToFloat(const YGValue unit, const float parentSize) { static inline float YGValueToFloat(const YGValue unit, const float parentSize) {
float result;
if (unit.unit == YGUnitPixel){ if (unit.unit == YGUnitPixel){
return unit.value; result = unit.value;
} else { } else {
return unit.value * parentSize / 100.0f; result = unit.value * parentSize / 100.0f;
} }
return result;
} }
static void YGNodeInit(const YGNodeRef node) { static void YGNodeInit(const YGNodeRef node) {
@@ -1102,11 +1104,14 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
const float width, const float width,
const YGMeasureMode widthMode, const YGMeasureMode widthMode,
const float height, const float height,
const float parentWidth,
const float parentHeight,
const YGMeasureMode heightMode, const YGMeasureMode heightMode,
const YGDirection direction) { const YGDirection direction) {
const YGFlexDirection mainAxis = YGFlexDirectionResolve(node->style.flexDirection, direction); const YGFlexDirection mainAxis = YGFlexDirectionResolve(node->style.flexDirection, direction);
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
float mainAxisSize = isMainAxisRow ? width : height; const float mainAxisSize = isMainAxisRow ? width : height;
const float mainAxisParentSize = isMainAxisRow ? parentWidth : parentHeight;
float childWidth; float childWidth;
float childHeight; float childHeight;
@@ -1122,18 +1127,18 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
(YGIsExperimentalFeatureEnabled(YGExperimentalFeatureWebFlexBasis) && (YGIsExperimentalFeatureEnabled(YGExperimentalFeatureWebFlexBasis) &&
child->layout.computedFlexBasisGeneration != gCurrentGenerationCount)) { child->layout.computedFlexBasisGeneration != gCurrentGenerationCount)) {
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(YGValueToFloat(YGNodeStyleGetFlexBasisWithUnit(child), mainAxisSize), YGNodePaddingAndBorderForAxis(child, mainAxis, mainAxisSize)); fmaxf(YGValueToFloat(YGNodeStyleGetFlexBasisWithUnit(child), mainAxisParentSize), YGNodePaddingAndBorderForAxis(child, mainAxis, mainAxisParentSize));
} }
} else if (isMainAxisRow && isRowStyleDimDefined) { } else if (isMainAxisRow && isRowStyleDimDefined) {
// The width is definite, so use that as the flex basis. // The width is definite, so use that as the flex basis.
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(YGValueToFloat(child->style.dimensions[YGDimensionWidth], width), fmaxf(YGValueToFloat(child->style.dimensions[YGDimensionWidth], parentWidth),
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, width)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentWidth));
} else if (!isMainAxisRow && isColumnStyleDimDefined) { } else if (!isMainAxisRow && isColumnStyleDimDefined) {
// The height is definite, so use that as the flex basis. // The height is definite, so use that as the flex basis.
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(YGValueToFloat(child->style.dimensions[YGDimensionHeight], height), fmaxf(YGValueToFloat(child->style.dimensions[YGDimensionHeight], parentHeight),
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, height)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, parentHeight));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped // Compute the flex basis and hypothetical main size (i.e. the clamped
// flex basis). // flex basis).
@@ -1143,13 +1148,13 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
childHeightMeasureMode = YGMeasureModeUndefined; childHeightMeasureMode = YGMeasureModeUndefined;
if (isRowStyleDimDefined) { if (isRowStyleDimDefined) {
childWidth = YGValueToFloat(child->style.dimensions[YGDimensionWidth], width) + childWidth = YGValueToFloat(child->style.dimensions[YGDimensionWidth], parentWidth) +
YGNodeMarginForAxis(child, YGFlexDirectionRow, width); YGNodeMarginForAxis(child, YGFlexDirectionRow, parentWidth);
childWidthMeasureMode = YGMeasureModeExactly; childWidthMeasureMode = YGMeasureModeExactly;
} }
if (isColumnStyleDimDefined) { if (isColumnStyleDimDefined) {
childHeight = YGValueToFloat(child->style.dimensions[YGDimensionHeight], height) + childHeight = YGValueToFloat(child->style.dimensions[YGDimensionHeight], parentHeight) +
YGNodeMarginForAxis(child, YGFlexDirectionColumn, height); YGNodeMarginForAxis(child, YGFlexDirectionColumn, parentHeight);
childHeightMeasureMode = YGMeasureModeExactly; childHeightMeasureMode = YGMeasureModeExactly;
} }
@@ -1189,20 +1194,20 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) {
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(childWidth * child->style.aspectRatio, fmaxf(childWidth * child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, width)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionColumn, parentWidth));
return; return;
} else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { } else if (isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) {
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(childHeight * child->style.aspectRatio, fmaxf(childHeight * child->style.aspectRatio,
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, height)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, parentHeight));
return; return;
} }
} }
YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionWidth], width), YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionWidth], parentWidth),
&childWidthMeasureMode, &childWidthMeasureMode,
&childWidth); &childWidth);
YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionHeight], height), YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionHeight], parentHeight),
&childHeightMeasureMode, &childHeightMeasureMode,
&childHeight); &childHeight);
@@ -1213,15 +1218,15 @@ static void YGNodeComputeFlexBasisForChild(const YGNodeRef node,
direction, direction,
childWidthMeasureMode, childWidthMeasureMode,
childHeightMeasureMode, childHeightMeasureMode,
width, parentWidth,
height, parentHeight,
false, false,
"measure"); "measure");
child->layout.computedFlexBasis = child->layout.computedFlexBasis =
fmaxf(isMainAxisRow ? child->layout.measuredDimensions[YGDimensionWidth] fmaxf(isMainAxisRow ? child->layout.measuredDimensions[YGDimensionWidth]
: child->layout.measuredDimensions[YGDimensionHeight], : child->layout.measuredDimensions[YGDimensionHeight],
YGNodePaddingAndBorderForAxis(child, mainAxis, mainAxisSize)); YGNodePaddingAndBorderForAxis(child, mainAxis, mainAxisParentSize));
} }
child->layout.computedFlexBasisGeneration = gCurrentGenerationCount; child->layout.computedFlexBasisGeneration = gCurrentGenerationCount;
@@ -1628,31 +1633,38 @@ static void YGNodelayoutImpl(const YGNodeRef node,
const YGJustify justifyContent = node->style.justifyContent; const YGJustify justifyContent = node->style.justifyContent;
const bool isNodeFlexWrap = node->style.flexWrap == YGWrapWrap; const bool isNodeFlexWrap = node->style.flexWrap == YGWrapWrap;
const float mainAxisSize = isMainAxisRow ? availableWidth : availableHeight; const float mainAxisParentSize = isMainAxisRow ? parentWidth : parentHeight;
const float crossAxisSize = isMainAxisRow ? availableHeight : availableWidth; const float crossAxisParentSize = isMainAxisRow ? parentHeight : parentWidth;
//const float mainAxisSize = isMainAxisRow ? availableWidth : availableHeight;
//const float crossAxisSize = isMainAxisRow ? availableHeight : availableWidth;
YGNodeRef firstAbsoluteChild = NULL; YGNodeRef firstAbsoluteChild = NULL;
YGNodeRef currentAbsoluteChild = NULL; YGNodeRef currentAbsoluteChild = NULL;
const float leadingPaddingAndBorderMain = YGNodeLeadingPaddingAndBorder(node, mainAxis, mainAxisSize); const float leadingPaddingAndBorderMain = YGNodeLeadingPaddingAndBorder(node, mainAxis, mainAxisParentSize);
const float trailingPaddingAndBorderMain = YGNodeTrailingPaddingAndBorder(node, mainAxis, mainAxisSize); const float trailingPaddingAndBorderMain = YGNodeTrailingPaddingAndBorder(node, mainAxis, mainAxisParentSize);
const float leadingPaddingAndBorderCross = YGNodeLeadingPaddingAndBorder(node, crossAxis, crossAxisSize); const float leadingPaddingAndBorderCross = YGNodeLeadingPaddingAndBorder(node, crossAxis, crossAxisParentSize);
const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, mainAxisSize); const float paddingAndBorderAxisMain = YGNodePaddingAndBorderForAxis(node, mainAxis, mainAxisParentSize);
const float paddingAndBorderAxisCross = YGNodePaddingAndBorderForAxis(node, crossAxis, crossAxisSize); const float paddingAndBorderAxisCross = YGNodePaddingAndBorderForAxis(node, crossAxis, crossAxisParentSize);
const YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode; const YGMeasureMode measureModeMainDim = isMainAxisRow ? widthMeasureMode : heightMeasureMode;
const YGMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode; const YGMeasureMode measureModeCrossDim = isMainAxisRow ? heightMeasureMode : widthMeasureMode;
const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, parentHeight);
const float paddingAndBorderAxisColumn = const float paddingAndBorderAxisColumn =
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, availableHeight); YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, parentHeight);
const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, availableWidth); const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, parentHeight);
const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, availableHeight); const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, parentHeight);
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
const float possibleNodeWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
const float possibleNodeHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
const float possibleNodeMainDim = isMainAxisRow ? possibleNodeWidth : possibleNodeHeight;
const float possibleNodeCrossDim = isMainAxisRow ? possibleNodeHeight : possibleNodeWidth;
const float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow; const float availableInnerWidth = availableWidth - marginAxisRow - paddingAndBorderAxisRow;
const float availableInnerHeight = const float availableInnerHeight = availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
availableHeight - marginAxisColumn - paddingAndBorderAxisColumn;
const float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; const float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight;
const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth; const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth;
@@ -1683,7 +1695,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (performLayout) { if (performLayout) {
// Set the initial position (relative to the parent). // Set the initial position (relative to the parent).
const YGDirection childDirection = YGNodeResolveDirection(child, direction); const YGDirection childDirection = YGNodeResolveDirection(child, direction);
YGNodeSetPosition(child, childDirection, mainAxisSize, crossAxisSize); YGNodeSetPosition(child, childDirection, crossAxisParentSize, mainAxisParentSize);
} }
// Absolute-positioned children don't participate in flex layout. Add them // Absolute-positioned children don't participate in flex layout. Add them
@@ -1709,6 +1721,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerWidth, availableInnerWidth,
widthMeasureMode, widthMeasureMode,
availableInnerHeight, availableInnerHeight,
possibleNodeWidth,
possibleNodeHeight,
heightMeasureMode, heightMeasureMode,
direction); direction);
} }
@@ -1757,7 +1771,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (child->style.positionType != YGPositionTypeAbsolute) { if (child->style.positionType != YGPositionTypeAbsolute) {
const float outerFlexBasis = const float outerFlexBasis =
child->layout.computedFlexBasis + YGNodeMarginForAxis(child, mainAxis, mainAxisSize); child->layout.computedFlexBasis + YGNodeMarginForAxis(child, mainAxis, possibleNodeMainDim);
// If this is a multi-line flow and this item pushes us over the // If this is a multi-line flow and this item pushes us over the
// available size, we've // available size, we've
@@ -1868,7 +1882,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
baseMainSize = baseMainSize =
childFlexBasis + childFlexBasis +
remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor; remainingFreeSpace / totalFlexShrinkScaledFactors * flexShrinkScaledFactor;
boundMainSize = YGNodeBoundAxis(currentRelativeChild, mainAxis, baseMainSize, mainAxisSize); boundMainSize = YGNodeBoundAxis(currentRelativeChild, mainAxis, baseMainSize, possibleNodeMainDim);
if (baseMainSize != boundMainSize) { if (baseMainSize != boundMainSize) {
// By excluding this item's size and flex factor from remaining, // By excluding this item's size and flex factor from remaining,
// this item's // this item's
@@ -1887,7 +1901,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (flexGrowFactor != 0) { if (flexGrowFactor != 0) {
baseMainSize = baseMainSize =
childFlexBasis + remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor; childFlexBasis + remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor;
boundMainSize = YGNodeBoundAxis(currentRelativeChild, mainAxis, baseMainSize, mainAxisSize); boundMainSize = YGNodeBoundAxis(currentRelativeChild, mainAxis, baseMainSize, possibleNodeMainDim);
if (baseMainSize != boundMainSize) { if (baseMainSize != boundMainSize) {
// By excluding this item's size and flex factor from remaining, // By excluding this item's size and flex factor from remaining,
// this item's // this item's
@@ -1929,7 +1943,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
(remainingFreeSpace / totalFlexShrinkScaledFactors) * flexShrinkScaledFactor; (remainingFreeSpace / totalFlexShrinkScaledFactors) * flexShrinkScaledFactor;
} }
updatedMainSize = YGNodeBoundAxis(currentRelativeChild, mainAxis, childSize, mainAxisSize); updatedMainSize = YGNodeBoundAxis(currentRelativeChild, mainAxis, childSize, possibleNodeMainDim);
} }
} else if (remainingFreeSpace > 0) { } else if (remainingFreeSpace > 0) {
flexGrowFactor = YGNodeStyleGetFlexGrow(currentRelativeChild); flexGrowFactor = YGNodeStyleGetFlexGrow(currentRelativeChild);
@@ -1940,7 +1954,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
YGNodeBoundAxis(currentRelativeChild, YGNodeBoundAxis(currentRelativeChild,
mainAxis, mainAxis,
childFlexBasis + childFlexBasis +
remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor, mainAxisSize); remainingFreeSpace / totalFlexGrowFactors * flexGrowFactor, possibleNodeMainDim);
} }
} }
@@ -1953,7 +1967,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (isMainAxisRow) { if (isMainAxisRow) {
childWidth = childWidth =
updatedMainSize + YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionRow, availableWidth); updatedMainSize + YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionRow, possibleNodeWidth);
childWidthMeasureMode = YGMeasureModeExactly; childWidthMeasureMode = YGMeasureModeExactly;
if (!YGValueIsUndefinedf(availableInnerCrossDim) && if (!YGValueIsUndefinedf(availableInnerCrossDim) &&
@@ -1967,13 +1981,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
childHeightMeasureMode = childHeightMeasureMode =
YGValueIsUndefinedf(childHeight) ? YGMeasureModeUndefined : YGMeasureModeAtMost; YGValueIsUndefinedf(childHeight) ? YGMeasureModeUndefined : YGMeasureModeAtMost;
} else { } else {
childHeight = YGValueToFloat(currentRelativeChild->style.dimensions[YGDimensionHeight], availableHeight) + childHeight = YGValueToFloat(currentRelativeChild->style.dimensions[YGDimensionHeight], possibleNodeHeight) +
YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionColumn, availableHeight); YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionColumn, possibleNodeHeight);
childHeightMeasureMode = YGMeasureModeExactly; childHeightMeasureMode = YGMeasureModeExactly;
} }
} else { } else {
childHeight = childHeight =
updatedMainSize + YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionColumn, availableHeight); updatedMainSize + YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionColumn, possibleNodeHeight);
childHeightMeasureMode = YGMeasureModeExactly; childHeightMeasureMode = YGMeasureModeExactly;
if (!YGValueIsUndefinedf(availableInnerCrossDim) && if (!YGValueIsUndefinedf(availableInnerCrossDim) &&
@@ -1987,8 +2001,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
childWidthMeasureMode = childWidthMeasureMode =
YGValueIsUndefinedf(childWidth) ? YGMeasureModeUndefined : YGMeasureModeAtMost; YGValueIsUndefinedf(childWidth) ? YGMeasureModeUndefined : YGMeasureModeAtMost;
} else { } else {
childWidth = YGValueToFloat(currentRelativeChild->style.dimensions[YGDimensionWidth], availableWidth) + childWidth = YGValueToFloat(currentRelativeChild->style.dimensions[YGDimensionWidth], possibleNodeWidth) +
YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionRow, availableWidth); YGNodeMarginForAxis(currentRelativeChild, YGFlexDirectionRow, possibleNodeWidth);
childWidthMeasureMode = YGMeasureModeExactly; childWidthMeasureMode = YGMeasureModeExactly;
} }
} }
@@ -1997,20 +2011,20 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (isMainAxisRow && childHeightMeasureMode != YGMeasureModeExactly) { if (isMainAxisRow && childHeightMeasureMode != YGMeasureModeExactly) {
childHeight = childHeight =
fmaxf(childWidth * currentRelativeChild->style.aspectRatio, fmaxf(childWidth * currentRelativeChild->style.aspectRatio,
YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionColumn, availableHeight)); YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionColumn, possibleNodeHeight));
childHeightMeasureMode = YGMeasureModeExactly; childHeightMeasureMode = YGMeasureModeExactly;
} else if (!isMainAxisRow && childWidthMeasureMode != YGMeasureModeExactly) { } else if (!isMainAxisRow && childWidthMeasureMode != YGMeasureModeExactly) {
childWidth = childWidth =
fmaxf(childHeight * currentRelativeChild->style.aspectRatio, fmaxf(childHeight * currentRelativeChild->style.aspectRatio,
YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionRow, availableWidth)); YGNodePaddingAndBorderForAxis(currentRelativeChild, YGFlexDirectionRow, possibleNodeWidth));
childWidthMeasureMode = YGMeasureModeExactly; childWidthMeasureMode = YGMeasureModeExactly;
} }
} }
YGConstrainMaxSizeForMode(YGValueToFloat(currentRelativeChild->style.maxDimensions[YGDimensionWidth], availableWidth), YGConstrainMaxSizeForMode(YGValueToFloat(currentRelativeChild->style.maxDimensions[YGDimensionWidth], possibleNodeWidth),
&childWidthMeasureMode, &childWidthMeasureMode,
&childWidth); &childWidth);
YGConstrainMaxSizeForMode(YGValueToFloat(currentRelativeChild->style.maxDimensions[YGDimensionHeight], availableHeight), YGConstrainMaxSizeForMode(YGValueToFloat(currentRelativeChild->style.maxDimensions[YGDimensionHeight], possibleNodeHeight),
&childHeightMeasureMode, &childHeightMeasureMode,
&childHeight); &childHeight);
@@ -2026,8 +2040,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
direction, direction,
childWidthMeasureMode, childWidthMeasureMode,
childHeightMeasureMode, childHeightMeasureMode,
parentWidth, possibleNodeWidth,
parentHeight, possibleNodeHeight,
performLayout && !requiresStretchLayout, performLayout && !requiresStretchLayout,
"flex"); "flex");
@@ -2051,9 +2065,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (measureModeMainDim == YGMeasureModeAtMost && remainingFreeSpace > 0) { if (measureModeMainDim == YGMeasureModeAtMost && remainingFreeSpace > 0) {
if (!YGValueIsUndefined(node->style.minDimensions[dim[mainAxis]]) && if (!YGValueIsUndefined(node->style.minDimensions[dim[mainAxis]]) &&
YGValueToFloat(node->style.minDimensions[dim[mainAxis]], mainAxisSize) >= 0) { YGValueToFloat(node->style.minDimensions[dim[mainAxis]], mainAxisParentSize) >= 0) {
remainingFreeSpace = fmaxf(0, remainingFreeSpace = fmaxf(0,
YGValueToFloat(node->style.minDimensions[dim[mainAxis]], mainAxisSize) - YGValueToFloat(node->style.minDimensions[dim[mainAxis]], mainAxisParentSize) -
(availableInnerMainDim - remainingFreeSpace)); (availableInnerMainDim - remainingFreeSpace));
} else { } else {
remainingFreeSpace = 0; remainingFreeSpace = 0;
@@ -2096,9 +2110,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// In case the child is position absolute and has left/top being // In case the child is position absolute and has left/top being
// defined, we override the position to whatever the user said // defined, we override the position to whatever the user said
// (and margin/border). // (and margin/border).
child->layout.position[pos[mainAxis]] = YGNodeLeadingPosition(child, mainAxis, mainAxisSize) + child->layout.position[pos[mainAxis]] = YGNodeLeadingPosition(child, mainAxis, possibleNodeMainDim) +
YGNodeLeadingBorder(node, mainAxis, mainAxisSize) + YGNodeLeadingBorder(node, mainAxis, mainAxisParentSize) +
YGNodeLeadingMargin(child, mainAxis, mainAxisSize); YGNodeLeadingMargin(child, mainAxis, possibleNodeMainDim);
} }
} else { } else {
// Now that we placed the element, we need to update the variables. // Now that we placed the element, we need to update the variables.
@@ -2113,22 +2127,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// If we skipped the flex step, then we can't rely on the // If we skipped the flex step, then we can't rely on the
// measuredDims because // measuredDims because
// they weren't computed. This means we can't call YGNodeDimWithMargin. // they weren't computed. This means we can't call YGNodeDimWithMargin.
mainDim += betweenMainDim + YGNodeMarginForAxis(child, mainAxis, mainAxisSize) + mainDim += betweenMainDim + YGNodeMarginForAxis(child, mainAxis, possibleNodeMainDim) +
child->layout.computedFlexBasis; child->layout.computedFlexBasis;
crossDim = availableInnerCrossDim; crossDim = availableInnerCrossDim;
} else { } else {
// The main dimension is the sum of all the elements dimension plus // The main dimension is the sum of all the elements dimension plus
// the spacing. // the spacing.
mainDim += betweenMainDim + YGNodeDimWithMargin(child, mainAxis, mainAxisSize); mainDim += betweenMainDim + YGNodeDimWithMargin(child, mainAxis, possibleNodeMainDim);
// The cross dimension is the max of the elements dimension since // The cross dimension is the max of the elements dimension since
// there // there
// can only be one element in that cross dimension. // can only be one element in that cross dimension.
crossDim = fmaxf(crossDim, YGNodeDimWithMargin(child, crossAxis, crossAxisSize)); crossDim = fmaxf(crossDim, YGNodeDimWithMargin(child, crossAxis, possibleNodeCrossDim));
} }
} else if (performLayout) { } else if (performLayout) {
child->layout.position[pos[mainAxis]] += child->layout.position[pos[mainAxis]] +=
YGNodeLeadingBorder(node, mainAxis, mainAxisSize) + leadingMainDim; YGNodeLeadingBorder(node, mainAxis, mainAxisParentSize) + leadingMainDim;
} }
} }
} }
@@ -2139,7 +2153,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (measureModeCrossDim == YGMeasureModeUndefined || if (measureModeCrossDim == YGMeasureModeUndefined ||
measureModeCrossDim == YGMeasureModeAtMost) { measureModeCrossDim == YGMeasureModeAtMost) {
// Compute the cross axis from the max cross dimension of the children. // Compute the cross axis from the max cross dimension of the children.
containerCrossAxis = YGNodeBoundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross, crossAxisSize) - containerCrossAxis = YGNodeBoundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross, crossAxisParentSize) -
paddingAndBorderAxisCross; paddingAndBorderAxisCross;
if (measureModeCrossDim == YGMeasureModeAtMost) { if (measureModeCrossDim == YGMeasureModeAtMost) {
@@ -2153,7 +2167,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
} }
// Clamp to the min/max size specified on the container. // Clamp to the min/max size specified on the container.
crossDim = YGNodeBoundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross, crossAxisSize) - crossDim = YGNodeBoundAxis(node, crossAxis, crossDim + paddingAndBorderAxisCross, crossAxisParentSize) -
paddingAndBorderAxisCross; paddingAndBorderAxisCross;
// STEP 7: CROSS-AXIS ALIGNMENT // STEP 7: CROSS-AXIS ALIGNMENT
@@ -2168,12 +2182,12 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// set, override all the previously computed positions to set it // set, override all the previously computed positions to set it
// correctly. // correctly.
if (YGNodeIsLeadingPosDefined(child, crossAxis)) { if (YGNodeIsLeadingPosDefined(child, crossAxis)) {
child->layout.position[pos[crossAxis]] = YGNodeLeadingPosition(child, crossAxis, crossAxisSize) + child->layout.position[pos[crossAxis]] = YGNodeLeadingPosition(child, crossAxis, possibleNodeCrossDim) +
YGNodeLeadingBorder(node, crossAxis, crossAxisSize) + YGNodeLeadingBorder(node, crossAxis, crossAxisParentSize) +
YGNodeLeadingMargin(child, crossAxis, crossAxisSize); YGNodeLeadingMargin(child, crossAxis, possibleNodeCrossDim);
} else { } else {
child->layout.position[pos[crossAxis]] = child->layout.position[pos[crossAxis]] =
YGNodeLeadingBorder(node, crossAxis, crossAxisSize) + YGNodeLeadingMargin(child, crossAxis, crossAxisSize); YGNodeLeadingBorder(node, crossAxis, crossAxisParentSize) + YGNodeLeadingMargin(child, crossAxis, possibleNodeCrossDim);
} }
} else { } else {
float leadingCrossDim = leadingPaddingAndBorderCross; float leadingCrossDim = leadingPaddingAndBorderCross;
@@ -2200,17 +2214,17 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (isMainAxisRow) { if (isMainAxisRow) {
childHeight = crossDim; childHeight = crossDim;
childWidth = child->layout.measuredDimensions[YGDimensionWidth] + childWidth = child->layout.measuredDimensions[YGDimensionWidth] +
YGNodeMarginForAxis(child, YGFlexDirectionRow, availableWidth); YGNodeMarginForAxis(child, YGFlexDirectionRow, possibleNodeWidth);
} else { } else {
childWidth = crossDim; childWidth = crossDim;
childHeight = child->layout.measuredDimensions[YGDimensionHeight] + childHeight = child->layout.measuredDimensions[YGDimensionHeight] +
YGNodeMarginForAxis(child, YGFlexDirectionColumn, availableHeight); YGNodeMarginForAxis(child, YGFlexDirectionColumn, possibleNodeHeight);
} }
YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionWidth], availableWidth), YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionWidth], possibleNodeWidth),
&childWidthMeasureMode, &childWidthMeasureMode,
&childWidth); &childWidth);
YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionHeight], availableHeight), YGConstrainMaxSizeForMode(YGValueToFloat(child->style.maxDimensions[YGDimensionHeight], possibleNodeHeight),
&childHeightMeasureMode, &childHeightMeasureMode,
&childHeight); &childHeight);
@@ -2228,14 +2242,14 @@ static void YGNodelayoutImpl(const YGNodeRef node,
direction, direction,
childWidthMeasureMode, childWidthMeasureMode,
childHeightMeasureMode, childHeightMeasureMode,
parentWidth, possibleNodeWidth,
parentHeight, possibleNodeHeight,
true, true,
"stretch"); "stretch");
} }
} else if (alignItem != YGAlignFlexStart) { } else if (alignItem != YGAlignFlexStart) {
const float remainingCrossDim = const float remainingCrossDim =
containerCrossAxis - YGNodeDimWithMargin(child, crossAxis, crossAxisSize); containerCrossAxis - YGNodeDimWithMargin(child, crossAxis, possibleNodeCrossDim);
if (alignItem == YGAlignCenter) { if (alignItem == YGAlignCenter) {
leadingCrossDim += remainingCrossDim / 2; leadingCrossDim += remainingCrossDim / 2;
@@ -2297,7 +2311,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
if (YGNodeIsLayoutDimDefined(child, crossAxis)) { if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
lineHeight = fmaxf(lineHeight, lineHeight = fmaxf(lineHeight,
child->layout.measuredDimensions[dim[crossAxis]] + child->layout.measuredDimensions[dim[crossAxis]] +
YGNodeMarginForAxis(child, crossAxis, crossAxisSize)); YGNodeMarginForAxis(child, crossAxis, possibleNodeCrossDim));
} }
} }
} }
@@ -2312,12 +2326,12 @@ static void YGNodelayoutImpl(const YGNodeRef node,
switch (YGNodeAlignItem(node, child)) { switch (YGNodeAlignItem(node, child)) {
case YGAlignFlexStart: { case YGAlignFlexStart: {
child->layout.position[pos[crossAxis]] = child->layout.position[pos[crossAxis]] =
currentLead + YGNodeLeadingMargin(child, crossAxis, crossAxisSize); currentLead + YGNodeLeadingMargin(child, crossAxis, possibleNodeCrossDim);
break; break;
} }
case YGAlignFlexEnd: { case YGAlignFlexEnd: {
child->layout.position[pos[crossAxis]] = child->layout.position[pos[crossAxis]] =
currentLead + lineHeight - YGNodeTrailingMargin(child, crossAxis, crossAxisSize) - currentLead + lineHeight - YGNodeTrailingMargin(child, crossAxis, possibleNodeCrossDim) -
child->layout.measuredDimensions[dim[crossAxis]]; child->layout.measuredDimensions[dim[crossAxis]];
break; break;
} }
@@ -2329,7 +2343,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
} }
case YGAlignStretch: { case YGAlignStretch: {
child->layout.position[pos[crossAxis]] = child->layout.position[pos[crossAxis]] =
currentLead + YGNodeLeadingMargin(child, crossAxis, crossAxisSize); currentLead + YGNodeLeadingMargin(child, crossAxis, possibleNodeCrossDim);
// TODO(prenaux): Correctly set the height of items with indefinite // TODO(prenaux): Correctly set the height of items with indefinite
// (auto) crossAxis dimension. // (auto) crossAxis dimension.
break; break;
@@ -2348,9 +2362,9 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// STEP 9: COMPUTING FINAL DIMENSIONS // STEP 9: COMPUTING FINAL DIMENSIONS
node->layout.measuredDimensions[YGDimensionWidth] = node->layout.measuredDimensions[YGDimensionWidth] =
YGNodeBoundAxis(node, YGFlexDirectionRow, availableWidth - marginAxisRow, availableWidth); YGNodeBoundAxis(node, YGFlexDirectionRow, availableWidth - marginAxisRow, parentWidth);
node->layout.measuredDimensions[YGDimensionHeight] = node->layout.measuredDimensions[YGDimensionHeight] =
YGNodeBoundAxis(node, YGFlexDirectionColumn, availableHeight - marginAxisColumn, availableHeight); YGNodeBoundAxis(node, YGFlexDirectionColumn, availableHeight - marginAxisColumn, parentHeight);
// If the user didn't specify a width or height for the node, set the // If the user didn't specify a width or height for the node, set the
// dimensions based on the children. // dimensions based on the children.
@@ -2358,11 +2372,11 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Clamp the size to the min/max size, if specified, and make sure it // Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount. // doesn't go below the padding and border amount.
node->layout.measuredDimensions[dim[mainAxis]] = node->layout.measuredDimensions[dim[mainAxis]] =
YGNodeBoundAxis(node, mainAxis, maxLineMainDim, mainAxisSize); YGNodeBoundAxis(node, mainAxis, maxLineMainDim, mainAxisParentSize);
} else if (measureModeMainDim == YGMeasureModeAtMost) { } else if (measureModeMainDim == YGMeasureModeAtMost) {
node->layout.measuredDimensions[dim[mainAxis]] = node->layout.measuredDimensions[dim[mainAxis]] =
fmaxf(fminf(availableInnerMainDim + paddingAndBorderAxisMain, fmaxf(fminf(availableInnerMainDim + paddingAndBorderAxisMain,
YGNodeBoundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim, mainAxisSize)), YGNodeBoundAxisWithinMinAndMax(node, mainAxis, maxLineMainDim, mainAxisParentSize)),
paddingAndBorderAxisMain); paddingAndBorderAxisMain);
} }
@@ -2370,13 +2384,13 @@ static void YGNodelayoutImpl(const YGNodeRef node,
// Clamp the size to the min/max size, if specified, and make sure it // Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount. // doesn't go below the padding and border amount.
node->layout.measuredDimensions[dim[crossAxis]] = node->layout.measuredDimensions[dim[crossAxis]] =
YGNodeBoundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross, crossAxisSize); YGNodeBoundAxis(node, crossAxis, totalLineCrossDim + paddingAndBorderAxisCross, crossAxisParentSize);
} else if (measureModeCrossDim == YGMeasureModeAtMost) { } else if (measureModeCrossDim == YGMeasureModeAtMost) {
node->layout.measuredDimensions[dim[crossAxis]] = node->layout.measuredDimensions[dim[crossAxis]] =
fmaxf(fminf(availableInnerCrossDim + paddingAndBorderAxisCross, fmaxf(fminf(availableInnerCrossDim + paddingAndBorderAxisCross,
YGNodeBoundAxisWithinMinAndMax(node, YGNodeBoundAxisWithinMinAndMax(node,
crossAxis, crossAxis,
totalLineCrossDim + paddingAndBorderAxisCross, crossAxisSize)), totalLineCrossDim + paddingAndBorderAxisCross, crossAxisParentSize)),
paddingAndBorderAxisCross); paddingAndBorderAxisCross);
} }