mirror of
https://github.com/status-im/react-native.git
synced 2025-01-15 20:15:11 +00:00
Seperate function for second pass
Reviewed By: emilsjolander Differential Revision: D6833635 fbshipit-source-id: 7680a67db8bfe22f8fb86407159888882f3a3353
This commit is contained in:
parent
fda861a889
commit
ca91f0e3ac
@ -1701,6 +1701,183 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
|
|||||||
return flexAlgoRowMeasurement;
|
return flexAlgoRowMeasurement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void YGDistributeFreeSpaceSecondPass(
|
||||||
|
YGCollectFlexItemsRowValues& collectedFlexItemsValues,
|
||||||
|
const YGNodeRef node,
|
||||||
|
const YGFlexDirection mainAxis,
|
||||||
|
const YGFlexDirection crossAxis,
|
||||||
|
const float mainAxisParentSize,
|
||||||
|
const float availableInnerMainDim,
|
||||||
|
const float availableInnerCrossDim,
|
||||||
|
const float availableInnerWidth,
|
||||||
|
const float availableInnerHeight,
|
||||||
|
const bool flexBasisOverflows,
|
||||||
|
const YGMeasureMode measureModeCrossDim,
|
||||||
|
const bool performLayout,
|
||||||
|
const YGConfigRef config) {
|
||||||
|
float childFlexBasis = 0;
|
||||||
|
float flexShrinkScaledFactor = 0;
|
||||||
|
float flexGrowFactor = 0;
|
||||||
|
float deltaFreeSpace = 0;
|
||||||
|
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
|
||||||
|
const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap;
|
||||||
|
|
||||||
|
for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) {
|
||||||
|
childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
|
||||||
|
currentRelativeChild,
|
||||||
|
mainAxis,
|
||||||
|
currentRelativeChild->getLayout().computedFlexBasis,
|
||||||
|
mainAxisParentSize);
|
||||||
|
float updatedMainSize = childFlexBasis;
|
||||||
|
|
||||||
|
if (collectedFlexItemsValues.remainingFreeSpace < 0) {
|
||||||
|
flexShrinkScaledFactor =
|
||||||
|
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
||||||
|
// Is this child able to shrink?
|
||||||
|
if (flexShrinkScaledFactor != 0) {
|
||||||
|
float childSize;
|
||||||
|
|
||||||
|
if (collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
|
||||||
|
childSize = childFlexBasis + flexShrinkScaledFactor;
|
||||||
|
} else {
|
||||||
|
childSize = childFlexBasis +
|
||||||
|
(collectedFlexItemsValues.remainingFreeSpace /
|
||||||
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors) *
|
||||||
|
flexShrinkScaledFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatedMainSize = YGNodeBoundAxis(
|
||||||
|
currentRelativeChild,
|
||||||
|
mainAxis,
|
||||||
|
childSize,
|
||||||
|
availableInnerMainDim,
|
||||||
|
availableInnerWidth);
|
||||||
|
}
|
||||||
|
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
|
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
||||||
|
|
||||||
|
// Is this child able to grow?
|
||||||
|
if (flexGrowFactor != 0) {
|
||||||
|
updatedMainSize = YGNodeBoundAxis(
|
||||||
|
currentRelativeChild,
|
||||||
|
mainAxis,
|
||||||
|
childFlexBasis +
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
|
collectedFlexItemsValues.totalFlexGrowFactors *
|
||||||
|
flexGrowFactor,
|
||||||
|
availableInnerMainDim,
|
||||||
|
availableInnerWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deltaFreeSpace -= updatedMainSize - childFlexBasis;
|
||||||
|
|
||||||
|
const float marginMain = YGNodeMarginForAxis(
|
||||||
|
currentRelativeChild, mainAxis, availableInnerWidth);
|
||||||
|
const float marginCross = YGNodeMarginForAxis(
|
||||||
|
currentRelativeChild, crossAxis, availableInnerWidth);
|
||||||
|
|
||||||
|
float childCrossSize;
|
||||||
|
float childMainSize = updatedMainSize + marginMain;
|
||||||
|
YGMeasureMode childCrossMeasureMode;
|
||||||
|
YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
|
||||||
|
|
||||||
|
if (!YGFloatIsUndefined(currentRelativeChild->getStyle().aspectRatio)) {
|
||||||
|
childCrossSize = isMainAxisRow ? (childMainSize - marginMain) /
|
||||||
|
currentRelativeChild->getStyle().aspectRatio
|
||||||
|
: (childMainSize - marginMain) *
|
||||||
|
currentRelativeChild->getStyle().aspectRatio;
|
||||||
|
childCrossMeasureMode = YGMeasureModeExactly;
|
||||||
|
|
||||||
|
childCrossSize += marginCross;
|
||||||
|
} else if (
|
||||||
|
!YGFloatIsUndefined(availableInnerCrossDim) &&
|
||||||
|
!YGNodeIsStyleDimDefined(
|
||||||
|
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
||||||
|
measureModeCrossDim == YGMeasureModeExactly &&
|
||||||
|
!(isNodeFlexWrap && flexBasisOverflows) &&
|
||||||
|
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
|
||||||
|
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
|
||||||
|
YGUnitAuto &&
|
||||||
|
currentRelativeChild->marginTrailingValue(crossAxis).unit !=
|
||||||
|
YGUnitAuto) {
|
||||||
|
childCrossSize = availableInnerCrossDim;
|
||||||
|
childCrossMeasureMode = YGMeasureModeExactly;
|
||||||
|
} else if (!YGNodeIsStyleDimDefined(
|
||||||
|
currentRelativeChild, crossAxis, availableInnerCrossDim)) {
|
||||||
|
childCrossSize = availableInnerCrossDim;
|
||||||
|
childCrossMeasureMode = YGFloatIsUndefined(childCrossSize)
|
||||||
|
? YGMeasureModeUndefined
|
||||||
|
: YGMeasureModeAtMost;
|
||||||
|
} else {
|
||||||
|
childCrossSize =
|
||||||
|
YGResolveValue(
|
||||||
|
currentRelativeChild->getResolvedDimension(dim[crossAxis]),
|
||||||
|
availableInnerCrossDim) +
|
||||||
|
marginCross;
|
||||||
|
const bool isLoosePercentageMeasurement =
|
||||||
|
currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit ==
|
||||||
|
YGUnitPercent &&
|
||||||
|
measureModeCrossDim != YGMeasureModeExactly;
|
||||||
|
childCrossMeasureMode =
|
||||||
|
YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement
|
||||||
|
? YGMeasureModeUndefined
|
||||||
|
: YGMeasureModeExactly;
|
||||||
|
}
|
||||||
|
|
||||||
|
YGConstrainMaxSizeForMode(
|
||||||
|
currentRelativeChild,
|
||||||
|
mainAxis,
|
||||||
|
availableInnerMainDim,
|
||||||
|
availableInnerWidth,
|
||||||
|
&childMainMeasureMode,
|
||||||
|
&childMainSize);
|
||||||
|
YGConstrainMaxSizeForMode(
|
||||||
|
currentRelativeChild,
|
||||||
|
crossAxis,
|
||||||
|
availableInnerCrossDim,
|
||||||
|
availableInnerWidth,
|
||||||
|
&childCrossMeasureMode,
|
||||||
|
&childCrossSize);
|
||||||
|
|
||||||
|
const bool requiresStretchLayout =
|
||||||
|
!YGNodeIsStyleDimDefined(
|
||||||
|
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
||||||
|
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
|
||||||
|
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
|
||||||
|
YGUnitAuto &&
|
||||||
|
currentRelativeChild->marginTrailingValue(crossAxis).unit != YGUnitAuto;
|
||||||
|
|
||||||
|
const float childWidth = isMainAxisRow ? childMainSize : childCrossSize;
|
||||||
|
const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize;
|
||||||
|
|
||||||
|
const YGMeasureMode childWidthMeasureMode =
|
||||||
|
isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
|
||||||
|
const YGMeasureMode childHeightMeasureMode =
|
||||||
|
!isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
|
||||||
|
|
||||||
|
// Recursively call the layout algorithm for this child with the updated
|
||||||
|
// main size.
|
||||||
|
YGLayoutNodeInternal(
|
||||||
|
currentRelativeChild,
|
||||||
|
childWidth,
|
||||||
|
childHeight,
|
||||||
|
node->getLayout().direction,
|
||||||
|
childWidthMeasureMode,
|
||||||
|
childHeightMeasureMode,
|
||||||
|
availableInnerWidth,
|
||||||
|
availableInnerHeight,
|
||||||
|
performLayout && !requiresStretchLayout,
|
||||||
|
"flex",
|
||||||
|
config);
|
||||||
|
node->setLayoutHadOverflow(
|
||||||
|
node->getLayout().hadOverflow |
|
||||||
|
currentRelativeChild->getLayout().hadOverflow);
|
||||||
|
}
|
||||||
|
|
||||||
|
collectedFlexItemsValues.remainingFreeSpace += deltaFreeSpace;
|
||||||
|
}
|
||||||
|
|
||||||
// It distributes the free space to the flexible items, for those flexible items
|
// 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
|
// whose min and max constraints are triggered, the clamped size is removed from
|
||||||
// the remaingfreespace.
|
// the remaingfreespace.
|
||||||
@ -2126,15 +2303,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
-collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
-collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float originalRemainingFreeSpace =
|
|
||||||
collectedFlexItemsValues.remainingFreeSpace;
|
|
||||||
float deltaFreeSpace = 0;
|
|
||||||
|
|
||||||
if (!canSkipFlex) {
|
if (!canSkipFlex) {
|
||||||
float childFlexBasis;
|
|
||||||
float flexShrinkScaledFactor;
|
|
||||||
float flexGrowFactor;
|
|
||||||
|
|
||||||
// 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.
|
||||||
// The first pass finds the items whose min/max constraints trigger,
|
// The first pass finds the items whose min/max constraints trigger,
|
||||||
@ -2166,169 +2335,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
|
|||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
|
|
||||||
// Second pass: resolve the sizes of the flexible items
|
// Second pass: resolve the sizes of the flexible items
|
||||||
deltaFreeSpace = 0;
|
YGDistributeFreeSpaceSecondPass(
|
||||||
for (auto currentRelativeChild :
|
collectedFlexItemsValues,
|
||||||
collectedFlexItemsValues.relativeChildren) {
|
node,
|
||||||
childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
|
|
||||||
currentRelativeChild,
|
|
||||||
mainAxis,
|
mainAxis,
|
||||||
currentRelativeChild->getLayout().computedFlexBasis,
|
|
||||||
mainAxisParentSize);
|
|
||||||
float updatedMainSize = childFlexBasis;
|
|
||||||
|
|
||||||
if (collectedFlexItemsValues.remainingFreeSpace < 0) {
|
|
||||||
flexShrinkScaledFactor =
|
|
||||||
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
|
||||||
// Is this child able to shrink?
|
|
||||||
if (flexShrinkScaledFactor != 0) {
|
|
||||||
float childSize;
|
|
||||||
|
|
||||||
if (collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
|
|
||||||
childSize = childFlexBasis + flexShrinkScaledFactor;
|
|
||||||
} else {
|
|
||||||
childSize = childFlexBasis +
|
|
||||||
(collectedFlexItemsValues.remainingFreeSpace /
|
|
||||||
collectedFlexItemsValues.totalFlexShrinkScaledFactors) *
|
|
||||||
flexShrinkScaledFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
updatedMainSize = YGNodeBoundAxis(
|
|
||||||
currentRelativeChild,
|
|
||||||
mainAxis,
|
|
||||||
childSize,
|
|
||||||
availableInnerMainDim,
|
|
||||||
availableInnerWidth);
|
|
||||||
}
|
|
||||||
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
|
|
||||||
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
|
||||||
|
|
||||||
// Is this child able to grow?
|
|
||||||
if (flexGrowFactor != 0) {
|
|
||||||
updatedMainSize = YGNodeBoundAxis(
|
|
||||||
currentRelativeChild,
|
|
||||||
mainAxis,
|
|
||||||
childFlexBasis +
|
|
||||||
collectedFlexItemsValues.remainingFreeSpace /
|
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors *
|
|
||||||
flexGrowFactor,
|
|
||||||
availableInnerMainDim,
|
|
||||||
availableInnerWidth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deltaFreeSpace -= updatedMainSize - childFlexBasis;
|
|
||||||
|
|
||||||
const float marginMain = YGNodeMarginForAxis(
|
|
||||||
currentRelativeChild, mainAxis, availableInnerWidth);
|
|
||||||
const float marginCross = YGNodeMarginForAxis(
|
|
||||||
currentRelativeChild, crossAxis, availableInnerWidth);
|
|
||||||
|
|
||||||
float childCrossSize;
|
|
||||||
float childMainSize = updatedMainSize + marginMain;
|
|
||||||
YGMeasureMode childCrossMeasureMode;
|
|
||||||
YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
|
|
||||||
|
|
||||||
if (!YGFloatIsUndefined(currentRelativeChild->getStyle().aspectRatio)) {
|
|
||||||
childCrossSize = isMainAxisRow ? (childMainSize - marginMain) /
|
|
||||||
currentRelativeChild->getStyle().aspectRatio
|
|
||||||
: (childMainSize - marginMain) *
|
|
||||||
currentRelativeChild->getStyle().aspectRatio;
|
|
||||||
childCrossMeasureMode = YGMeasureModeExactly;
|
|
||||||
|
|
||||||
childCrossSize += marginCross;
|
|
||||||
} else if (
|
|
||||||
!YGFloatIsUndefined(availableInnerCrossDim) &&
|
|
||||||
!YGNodeIsStyleDimDefined(
|
|
||||||
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
|
||||||
measureModeCrossDim == YGMeasureModeExactly &&
|
|
||||||
!(isNodeFlexWrap && flexBasisOverflows) &&
|
|
||||||
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
|
|
||||||
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
|
|
||||||
YGUnitAuto &&
|
|
||||||
currentRelativeChild->marginTrailingValue(crossAxis).unit !=
|
|
||||||
YGUnitAuto) {
|
|
||||||
childCrossSize = availableInnerCrossDim;
|
|
||||||
childCrossMeasureMode = YGMeasureModeExactly;
|
|
||||||
} else if (!YGNodeIsStyleDimDefined(
|
|
||||||
currentRelativeChild,
|
|
||||||
crossAxis,
|
crossAxis,
|
||||||
availableInnerCrossDim)) {
|
mainAxisParentSize,
|
||||||
childCrossSize = availableInnerCrossDim;
|
|
||||||
childCrossMeasureMode = YGFloatIsUndefined(childCrossSize)
|
|
||||||
? YGMeasureModeUndefined
|
|
||||||
: YGMeasureModeAtMost;
|
|
||||||
} else {
|
|
||||||
childCrossSize =
|
|
||||||
YGResolveValue(
|
|
||||||
currentRelativeChild->getResolvedDimension(dim[crossAxis]),
|
|
||||||
availableInnerCrossDim) +
|
|
||||||
marginCross;
|
|
||||||
const bool isLoosePercentageMeasurement =
|
|
||||||
currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit ==
|
|
||||||
YGUnitPercent &&
|
|
||||||
measureModeCrossDim != YGMeasureModeExactly;
|
|
||||||
childCrossMeasureMode =
|
|
||||||
YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement
|
|
||||||
? YGMeasureModeUndefined
|
|
||||||
: YGMeasureModeExactly;
|
|
||||||
}
|
|
||||||
|
|
||||||
YGConstrainMaxSizeForMode(
|
|
||||||
currentRelativeChild,
|
|
||||||
mainAxis,
|
|
||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
availableInnerWidth,
|
|
||||||
&childMainMeasureMode,
|
|
||||||
&childMainSize);
|
|
||||||
YGConstrainMaxSizeForMode(
|
|
||||||
currentRelativeChild,
|
|
||||||
crossAxis,
|
|
||||||
availableInnerCrossDim,
|
availableInnerCrossDim,
|
||||||
availableInnerWidth,
|
availableInnerWidth,
|
||||||
&childCrossMeasureMode,
|
|
||||||
&childCrossSize);
|
|
||||||
|
|
||||||
const bool requiresStretchLayout =
|
|
||||||
!YGNodeIsStyleDimDefined(
|
|
||||||
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
|
||||||
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
|
|
||||||
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
|
|
||||||
YGUnitAuto &&
|
|
||||||
currentRelativeChild->marginTrailingValue(crossAxis).unit !=
|
|
||||||
YGUnitAuto;
|
|
||||||
|
|
||||||
const float childWidth = isMainAxisRow ? childMainSize : childCrossSize;
|
|
||||||
const float childHeight =
|
|
||||||
!isMainAxisRow ? childMainSize : childCrossSize;
|
|
||||||
|
|
||||||
const YGMeasureMode childWidthMeasureMode =
|
|
||||||
isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
|
|
||||||
const YGMeasureMode childHeightMeasureMode =
|
|
||||||
!isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
|
|
||||||
|
|
||||||
// Recursively call the layout algorithm for this child with the updated
|
|
||||||
// main size.
|
|
||||||
YGLayoutNodeInternal(
|
|
||||||
currentRelativeChild,
|
|
||||||
childWidth,
|
|
||||||
childHeight,
|
|
||||||
direction,
|
|
||||||
childWidthMeasureMode,
|
|
||||||
childHeightMeasureMode,
|
|
||||||
availableInnerWidth,
|
|
||||||
availableInnerHeight,
|
availableInnerHeight,
|
||||||
performLayout && !requiresStretchLayout,
|
flexBasisOverflows,
|
||||||
"flex",
|
measureModeCrossDim,
|
||||||
|
performLayout,
|
||||||
config);
|
config);
|
||||||
node->setLayoutHadOverflow(
|
|
||||||
node->getLayout().hadOverflow |
|
|
||||||
currentRelativeChild->getLayout().hadOverflow);
|
|
||||||
currentRelativeChild = currentRelativeChild->getNextChild();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
collectedFlexItemsValues.remainingFreeSpace =
|
|
||||||
originalRemainingFreeSpace + deltaFreeSpace;
|
|
||||||
node->setLayoutHadOverflow(
|
node->setLayoutHadOverflow(
|
||||||
node->getLayout().hadOverflow |
|
node->getLayout().hadOverflow |
|
||||||
(collectedFlexItemsValues.remainingFreeSpace < 0));
|
(collectedFlexItemsValues.remainingFreeSpace < 0));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user