mirror of
https://github.com/status-im/react-native.git
synced 2025-01-15 03:56:03 +00:00
Replaced first pass with a function
Reviewed By: emilsjolander Differential Revision: D6819719 fbshipit-source-id: e5e77c21d1dca2255433da3388887d9db3f7b642
This commit is contained in:
parent
34b7ec82b5
commit
fda861a889
@ -44,6 +44,7 @@ struct YGCollectFlexItemsRowValues {
|
|||||||
float totalFlexShrinkScaledFactors;
|
float totalFlexShrinkScaledFactors;
|
||||||
float endOfLineIndex;
|
float endOfLineIndex;
|
||||||
std::vector<YGNodeRef> relativeChildren;
|
std::vector<YGNodeRef> relativeChildren;
|
||||||
|
float remainingFreeSpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool YGValueEqual(const YGValue a, const YGValue b);
|
bool YGValueEqual(const YGValue a, const YGValue b);
|
||||||
|
@ -1701,6 +1701,87 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
|
|||||||
return flexAlgoRowMeasurement;
|
return flexAlgoRowMeasurement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It distributes the free space to the flexible items, for those flexible items
|
||||||
|
// whose min and max constraints are triggered, the clamped size is removed from
|
||||||
|
// the remaingfreespace.
|
||||||
|
static void YGDistributeFreeSpaceFirstPass(
|
||||||
|
YGCollectFlexItemsRowValues& collectedFlexItemsValues,
|
||||||
|
const YGFlexDirection mainAxis,
|
||||||
|
const float mainAxisParentSize,
|
||||||
|
const float availableInnerMainDim,
|
||||||
|
const float availableInnerWidth) {
|
||||||
|
float flexShrinkScaledFactor = 0;
|
||||||
|
float flexGrowFactor = 0;
|
||||||
|
float baseMainSize = 0;
|
||||||
|
float boundMainSize = 0;
|
||||||
|
float deltaFreeSpace = 0;
|
||||||
|
|
||||||
|
for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) {
|
||||||
|
float childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
|
||||||
|
currentRelativeChild,
|
||||||
|
mainAxis,
|
||||||
|
currentRelativeChild->getLayout().computedFlexBasis,
|
||||||
|
mainAxisParentSize);
|
||||||
|
|
||||||
|
if (collectedFlexItemsValues.remainingFreeSpace < 0) {
|
||||||
|
flexShrinkScaledFactor =
|
||||||
|
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
||||||
|
|
||||||
|
// Is this child able to shrink?
|
||||||
|
if (flexShrinkScaledFactor != 0) {
|
||||||
|
baseMainSize = childFlexBasis +
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors *
|
||||||
|
flexShrinkScaledFactor;
|
||||||
|
boundMainSize = YGNodeBoundAxis(
|
||||||
|
currentRelativeChild,
|
||||||
|
mainAxis,
|
||||||
|
baseMainSize,
|
||||||
|
availableInnerMainDim,
|
||||||
|
availableInnerWidth);
|
||||||
|
if (baseMainSize != boundMainSize) {
|
||||||
|
// By excluding this item's size and flex factor from remaining,
|
||||||
|
// this item's
|
||||||
|
// min/max constraints should also trigger in the second pass
|
||||||
|
// resulting in the
|
||||||
|
// item's size calculation being identical in the first and second
|
||||||
|
// passes.
|
||||||
|
deltaFreeSpace += boundMainSize - childFlexBasis;
|
||||||
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors -=
|
||||||
|
flexShrinkScaledFactor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
|
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
||||||
|
|
||||||
|
// Is this child able to grow?
|
||||||
|
if (flexGrowFactor != 0) {
|
||||||
|
baseMainSize = childFlexBasis +
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
|
collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor;
|
||||||
|
boundMainSize = YGNodeBoundAxis(
|
||||||
|
currentRelativeChild,
|
||||||
|
mainAxis,
|
||||||
|
baseMainSize,
|
||||||
|
availableInnerMainDim,
|
||||||
|
availableInnerWidth);
|
||||||
|
|
||||||
|
if (baseMainSize != boundMainSize) {
|
||||||
|
// By excluding this item's size and flex factor from remaining,
|
||||||
|
// this item's
|
||||||
|
// min/max constraints should also trigger in the second pass
|
||||||
|
// resulting in the
|
||||||
|
// item's size calculation being identical in the first and second
|
||||||
|
// passes.
|
||||||
|
deltaFreeSpace += boundMainSize - childFlexBasis;
|
||||||
|
collectedFlexItemsValues.totalFlexGrowFactors -= flexGrowFactor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace -= deltaFreeSpace;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// This is the main routine that implements a subset of the flexbox layout
|
// This is the main routine that implements a subset of the flexbox layout
|
||||||
// algorithm
|
// algorithm
|
||||||
@ -2033,27 +2114,26 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float remainingFreeSpace = 0;
|
|
||||||
if (!sizeBasedOnContent && !YGFloatIsUndefined(availableInnerMainDim)) {
|
if (!sizeBasedOnContent && !YGFloatIsUndefined(availableInnerMainDim)) {
|
||||||
remainingFreeSpace = availableInnerMainDim -
|
collectedFlexItemsValues.remainingFreeSpace = availableInnerMainDim -
|
||||||
collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
||||||
} else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) {
|
} else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) {
|
||||||
// availableInnerMainDim is indefinite which means the node is being sized based on its
|
// availableInnerMainDim is indefinite which means the node is being sized based on its
|
||||||
// content.
|
// content.
|
||||||
// sizeConsumedOnCurrentLine is negative which means the node will allocate 0 points for
|
// sizeConsumedOnCurrentLine is negative which means the node will allocate 0 points for
|
||||||
// its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine.
|
// its content. Consequently, remainingFreeSpace is 0 - sizeConsumedOnCurrentLine.
|
||||||
remainingFreeSpace = -collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
collectedFlexItemsValues.remainingFreeSpace =
|
||||||
|
-collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float originalRemainingFreeSpace = remainingFreeSpace;
|
const float originalRemainingFreeSpace =
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace;
|
||||||
float deltaFreeSpace = 0;
|
float deltaFreeSpace = 0;
|
||||||
|
|
||||||
if (!canSkipFlex) {
|
if (!canSkipFlex) {
|
||||||
float childFlexBasis;
|
float childFlexBasis;
|
||||||
float flexShrinkScaledFactor;
|
float flexShrinkScaledFactor;
|
||||||
float flexGrowFactor;
|
float flexGrowFactor;
|
||||||
float baseMainSize;
|
|
||||||
float boundMainSize;
|
|
||||||
|
|
||||||
// Do two passes over the flex items to figure out how to distribute the
|
// Do two passes over the flex items to figure out how to distribute the
|
||||||
// remaining space.
|
// remaining space.
|
||||||
@ -2078,80 +2158,12 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
// concerns because we know exactly how many passes it'll do.
|
// concerns because we know exactly how many passes it'll do.
|
||||||
|
|
||||||
// First pass: detect the flex items whose min/max constraints trigger
|
// First pass: detect the flex items whose min/max constraints trigger
|
||||||
float deltaFlexShrinkScaledFactors = 0;
|
YGDistributeFreeSpaceFirstPass(
|
||||||
float deltaFlexGrowFactors = 0;
|
collectedFlexItemsValues,
|
||||||
|
mainAxis,
|
||||||
for (auto currentRelativeChild :
|
mainAxisParentSize,
|
||||||
collectedFlexItemsValues.relativeChildren) {
|
availableInnerMainDim,
|
||||||
childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
|
availableInnerWidth);
|
||||||
currentRelativeChild,
|
|
||||||
mainAxis,
|
|
||||||
currentRelativeChild->getLayout().computedFlexBasis,
|
|
||||||
mainAxisParentSize);
|
|
||||||
|
|
||||||
if (remainingFreeSpace < 0) {
|
|
||||||
flexShrinkScaledFactor =
|
|
||||||
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
|
||||||
|
|
||||||
// Is this child able to shrink?
|
|
||||||
if (flexShrinkScaledFactor != 0) {
|
|
||||||
baseMainSize = childFlexBasis +
|
|
||||||
remainingFreeSpace /
|
|
||||||
collectedFlexItemsValues.totalFlexShrinkScaledFactors *
|
|
||||||
flexShrinkScaledFactor;
|
|
||||||
boundMainSize = YGNodeBoundAxis(
|
|
||||||
currentRelativeChild,
|
|
||||||
mainAxis,
|
|
||||||
baseMainSize,
|
|
||||||
availableInnerMainDim,
|
|
||||||
availableInnerWidth);
|
|
||||||
if (baseMainSize != boundMainSize) {
|
|
||||||
// By excluding this item's size and flex factor from remaining,
|
|
||||||
// this item's
|
|
||||||
// min/max constraints should also trigger in the second pass
|
|
||||||
// resulting in the
|
|
||||||
// item's size calculation being identical in the first and second
|
|
||||||
// passes.
|
|
||||||
deltaFreeSpace -= boundMainSize - childFlexBasis;
|
|
||||||
deltaFlexShrinkScaledFactors -= flexShrinkScaledFactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (remainingFreeSpace > 0) {
|
|
||||||
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
|
||||||
|
|
||||||
// Is this child able to grow?
|
|
||||||
if (flexGrowFactor != 0) {
|
|
||||||
baseMainSize = childFlexBasis +
|
|
||||||
remainingFreeSpace /
|
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors *
|
|
||||||
flexGrowFactor;
|
|
||||||
boundMainSize = YGNodeBoundAxis(
|
|
||||||
currentRelativeChild,
|
|
||||||
mainAxis,
|
|
||||||
baseMainSize,
|
|
||||||
availableInnerMainDim,
|
|
||||||
availableInnerWidth);
|
|
||||||
|
|
||||||
if (baseMainSize != boundMainSize) {
|
|
||||||
// By excluding this item's size and flex factor from remaining,
|
|
||||||
// this item's
|
|
||||||
// min/max constraints should also trigger in the second pass
|
|
||||||
// resulting in the
|
|
||||||
// item's size calculation being identical in the first and second
|
|
||||||
// passes.
|
|
||||||
deltaFreeSpace -= boundMainSize - childFlexBasis;
|
|
||||||
deltaFlexGrowFactors -= flexGrowFactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentRelativeChild = currentRelativeChild->getNextChild();
|
|
||||||
}
|
|
||||||
|
|
||||||
collectedFlexItemsValues.totalFlexShrinkScaledFactors +=
|
|
||||||
deltaFlexShrinkScaledFactors;
|
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors += deltaFlexGrowFactors;
|
|
||||||
remainingFreeSpace += deltaFreeSpace;
|
|
||||||
|
|
||||||
// Second pass: resolve the sizes of the flexible items
|
// Second pass: resolve the sizes of the flexible items
|
||||||
deltaFreeSpace = 0;
|
deltaFreeSpace = 0;
|
||||||
@ -2164,7 +2176,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
mainAxisParentSize);
|
mainAxisParentSize);
|
||||||
float updatedMainSize = childFlexBasis;
|
float updatedMainSize = childFlexBasis;
|
||||||
|
|
||||||
if (remainingFreeSpace < 0) {
|
if (collectedFlexItemsValues.remainingFreeSpace < 0) {
|
||||||
flexShrinkScaledFactor =
|
flexShrinkScaledFactor =
|
||||||
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
||||||
// Is this child able to shrink?
|
// Is this child able to shrink?
|
||||||
@ -2175,7 +2187,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
childSize = childFlexBasis + flexShrinkScaledFactor;
|
childSize = childFlexBasis + flexShrinkScaledFactor;
|
||||||
} else {
|
} else {
|
||||||
childSize = childFlexBasis +
|
childSize = childFlexBasis +
|
||||||
(remainingFreeSpace /
|
(collectedFlexItemsValues.remainingFreeSpace /
|
||||||
collectedFlexItemsValues.totalFlexShrinkScaledFactors) *
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors) *
|
||||||
flexShrinkScaledFactor;
|
flexShrinkScaledFactor;
|
||||||
}
|
}
|
||||||
@ -2187,7 +2199,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
}
|
}
|
||||||
} else if (remainingFreeSpace > 0) {
|
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
||||||
|
|
||||||
// Is this child able to grow?
|
// Is this child able to grow?
|
||||||
@ -2196,7 +2208,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
currentRelativeChild,
|
currentRelativeChild,
|
||||||
mainAxis,
|
mainAxis,
|
||||||
childFlexBasis +
|
childFlexBasis +
|
||||||
remainingFreeSpace /
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors *
|
collectedFlexItemsValues.totalFlexGrowFactors *
|
||||||
flexGrowFactor,
|
flexGrowFactor,
|
||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
@ -2315,9 +2327,11 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingFreeSpace = originalRemainingFreeSpace + deltaFreeSpace;
|
collectedFlexItemsValues.remainingFreeSpace =
|
||||||
|
originalRemainingFreeSpace + deltaFreeSpace;
|
||||||
node->setLayoutHadOverflow(
|
node->setLayoutHadOverflow(
|
||||||
node->getLayout().hadOverflow | (remainingFreeSpace < 0));
|
node->getLayout().hadOverflow |
|
||||||
|
(collectedFlexItemsValues.remainingFreeSpace < 0));
|
||||||
|
|
||||||
// STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION
|
// STEP 6: MAIN-AXIS JUSTIFICATION & CROSS-AXIS SIZE DETERMINATION
|
||||||
|
|
||||||
@ -2331,20 +2345,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
// If we are using "at most" rules in the main axis. Calculate the remaining space when
|
// If we are using "at most" rules in the main axis. Calculate the remaining space when
|
||||||
// constraint by the min size defined for the main axis.
|
// constraint by the min size defined for the main axis.
|
||||||
|
|
||||||
if (measureModeMainDim == YGMeasureModeAtMost && remainingFreeSpace > 0) {
|
if (measureModeMainDim == YGMeasureModeAtMost &&
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
if (node->getStyle().minDimensions[dim[mainAxis]].unit !=
|
if (node->getStyle().minDimensions[dim[mainAxis]].unit !=
|
||||||
YGUnitUndefined &&
|
YGUnitUndefined &&
|
||||||
YGResolveValue(
|
YGResolveValue(
|
||||||
node->getStyle().minDimensions[dim[mainAxis]],
|
node->getStyle().minDimensions[dim[mainAxis]],
|
||||||
mainAxisParentSize) >= 0) {
|
mainAxisParentSize) >= 0) {
|
||||||
remainingFreeSpace = fmaxf(
|
collectedFlexItemsValues.remainingFreeSpace = fmaxf(
|
||||||
0,
|
0,
|
||||||
YGResolveValue(
|
YGResolveValue(
|
||||||
node->getStyle().minDimensions[dim[mainAxis]],
|
node->getStyle().minDimensions[dim[mainAxis]],
|
||||||
mainAxisParentSize) -
|
mainAxisParentSize) -
|
||||||
(availableInnerMainDim - remainingFreeSpace));
|
(availableInnerMainDim -
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace));
|
||||||
} else {
|
} else {
|
||||||
remainingFreeSpace = 0;
|
collectedFlexItemsValues.remainingFreeSpace = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2371,14 +2387,15 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
if (numberOfAutoMarginsOnCurrentLine == 0) {
|
if (numberOfAutoMarginsOnCurrentLine == 0) {
|
||||||
switch (justifyContent) {
|
switch (justifyContent) {
|
||||||
case YGJustifyCenter:
|
case YGJustifyCenter:
|
||||||
leadingMainDim = remainingFreeSpace / 2;
|
leadingMainDim = collectedFlexItemsValues.remainingFreeSpace / 2;
|
||||||
break;
|
break;
|
||||||
case YGJustifyFlexEnd:
|
case YGJustifyFlexEnd:
|
||||||
leadingMainDim = remainingFreeSpace;
|
leadingMainDim = collectedFlexItemsValues.remainingFreeSpace;
|
||||||
break;
|
break;
|
||||||
case YGJustifySpaceBetween:
|
case YGJustifySpaceBetween:
|
||||||
if (collectedFlexItemsValues.itemsOnLine > 1) {
|
if (collectedFlexItemsValues.itemsOnLine > 1) {
|
||||||
betweenMainDim = fmaxf(remainingFreeSpace, 0) /
|
betweenMainDim =
|
||||||
|
fmaxf(collectedFlexItemsValues.remainingFreeSpace, 0) /
|
||||||
(collectedFlexItemsValues.itemsOnLine - 1);
|
(collectedFlexItemsValues.itemsOnLine - 1);
|
||||||
} else {
|
} else {
|
||||||
betweenMainDim = 0;
|
betweenMainDim = 0;
|
||||||
@ -2386,14 +2403,14 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
break;
|
break;
|
||||||
case YGJustifySpaceEvenly:
|
case YGJustifySpaceEvenly:
|
||||||
// Space is distributed evenly across all elements
|
// Space is distributed evenly across all elements
|
||||||
betweenMainDim =
|
betweenMainDim = collectedFlexItemsValues.remainingFreeSpace /
|
||||||
remainingFreeSpace / (collectedFlexItemsValues.itemsOnLine + 1);
|
(collectedFlexItemsValues.itemsOnLine + 1);
|
||||||
leadingMainDim = betweenMainDim;
|
leadingMainDim = betweenMainDim;
|
||||||
break;
|
break;
|
||||||
case YGJustifySpaceAround:
|
case YGJustifySpaceAround:
|
||||||
// Space on the edges is half of the space between elements
|
// Space on the edges is half of the space between elements
|
||||||
betweenMainDim =
|
betweenMainDim = collectedFlexItemsValues.remainingFreeSpace /
|
||||||
remainingFreeSpace / collectedFlexItemsValues.itemsOnLine;
|
collectedFlexItemsValues.itemsOnLine;
|
||||||
leadingMainDim = betweenMainDim / 2;
|
leadingMainDim = betweenMainDim / 2;
|
||||||
break;
|
break;
|
||||||
case YGJustifyFlexStart:
|
case YGJustifyFlexStart:
|
||||||
@ -2427,7 +2444,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
// do not take part in that phase.
|
// do not take part in that phase.
|
||||||
if (child->getStyle().positionType == YGPositionTypeRelative) {
|
if (child->getStyle().positionType == YGPositionTypeRelative) {
|
||||||
if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
|
if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
|
||||||
mainDim += remainingFreeSpace / numberOfAutoMarginsOnCurrentLine;
|
mainDim += collectedFlexItemsValues.remainingFreeSpace /
|
||||||
|
numberOfAutoMarginsOnCurrentLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (performLayout) {
|
if (performLayout) {
|
||||||
@ -2437,7 +2455,8 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) {
|
if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) {
|
||||||
mainDim += remainingFreeSpace / numberOfAutoMarginsOnCurrentLine;
|
mainDim += collectedFlexItemsValues.remainingFreeSpace /
|
||||||
|
numberOfAutoMarginsOnCurrentLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canSkipFlex) {
|
if (canSkipFlex) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user