Permalink
Browse files

Seperate function for second pass

Reviewed By: emilsjolander

Differential Revision: D6833635

fbshipit-source-id: 7680a67db8bfe22f8fb86407159888882f3a3353
  • Loading branch information...
priteshrnandgaonkar authored and facebook-github-bot committed Feb 5, 2018
1 parent fda861a commit ca91f0e3ac55cb1e7a0fa2399d594a47de80a100
Showing with 191 additions and 169 deletions.
  1. +191 −169 ReactCommon/yoga/yoga/Yoga.cpp
@@ -1701,6 +1701,183 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
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
// whose min and max constraints are triggered, the clamped size is removed from
// the remaingfreespace.
@@ -2126,15 +2303,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
-collectedFlexItemsValues.sizeConsumedOnCurrentLine;
}
const float originalRemainingFreeSpace =
collectedFlexItemsValues.remainingFreeSpace;
float deltaFreeSpace = 0;
if (!canSkipFlex) {
float childFlexBasis;
float flexShrinkScaledFactor;
float flexGrowFactor;
// Do two passes over the flex items to figure out how to distribute the
// remaining space.
// The first pass finds the items whose min/max constraints trigger,
@@ -2166,169 +2335,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
availableInnerWidth);
// Second pass: resolve the sizes of the flexible items
deltaFreeSpace = 0;
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,
direction,
childWidthMeasureMode,
childHeightMeasureMode,
availableInnerWidth,
availableInnerHeight,
performLayout && !requiresStretchLayout,
"flex",
config);
node->setLayoutHadOverflow(
node->getLayout().hadOverflow |
currentRelativeChild->getLayout().hadOverflow);
currentRelativeChild = currentRelativeChild->getNextChild();
}
YGDistributeFreeSpaceSecondPass(
collectedFlexItemsValues,
node,
mainAxis,
crossAxis,
mainAxisParentSize,
availableInnerMainDim,
availableInnerCrossDim,
availableInnerWidth,
availableInnerHeight,
flexBasisOverflows,
measureModeCrossDim,
performLayout,
config);
}
collectedFlexItemsValues.remainingFreeSpace =
originalRemainingFreeSpace + deltaFreeSpace;
node->setLayoutHadOverflow(
node->getLayout().hadOverflow |
(collectedFlexItemsValues.remainingFreeSpace < 0));

0 comments on commit ca91f0e

Please sign in to comment.