Skip to content

Commit ca91f0e

Browse files
Seperate function for second pass
Reviewed By: emilsjolander Differential Revision: D6833635 fbshipit-source-id: 7680a67db8bfe22f8fb86407159888882f3a3353
1 parent fda861a commit ca91f0e

File tree

1 file changed

+191
-169
lines changed

1 file changed

+191
-169
lines changed

ReactCommon/yoga/yoga/Yoga.cpp

+191-169
Original file line numberDiff line numberDiff line change
@@ -1701,6 +1701,183 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
17011701
return flexAlgoRowMeasurement;
17021702
}
17031703

1704+
static void YGDistributeFreeSpaceSecondPass(
1705+
YGCollectFlexItemsRowValues& collectedFlexItemsValues,
1706+
const YGNodeRef node,
1707+
const YGFlexDirection mainAxis,
1708+
const YGFlexDirection crossAxis,
1709+
const float mainAxisParentSize,
1710+
const float availableInnerMainDim,
1711+
const float availableInnerCrossDim,
1712+
const float availableInnerWidth,
1713+
const float availableInnerHeight,
1714+
const bool flexBasisOverflows,
1715+
const YGMeasureMode measureModeCrossDim,
1716+
const bool performLayout,
1717+
const YGConfigRef config) {
1718+
float childFlexBasis = 0;
1719+
float flexShrinkScaledFactor = 0;
1720+
float flexGrowFactor = 0;
1721+
float deltaFreeSpace = 0;
1722+
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
1723+
const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap;
1724+
1725+
for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) {
1726+
childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
1727+
currentRelativeChild,
1728+
mainAxis,
1729+
currentRelativeChild->getLayout().computedFlexBasis,
1730+
mainAxisParentSize);
1731+
float updatedMainSize = childFlexBasis;
1732+
1733+
if (collectedFlexItemsValues.remainingFreeSpace < 0) {
1734+
flexShrinkScaledFactor =
1735+
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
1736+
// Is this child able to shrink?
1737+
if (flexShrinkScaledFactor != 0) {
1738+
float childSize;
1739+
1740+
if (collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
1741+
childSize = childFlexBasis + flexShrinkScaledFactor;
1742+
} else {
1743+
childSize = childFlexBasis +
1744+
(collectedFlexItemsValues.remainingFreeSpace /
1745+
collectedFlexItemsValues.totalFlexShrinkScaledFactors) *
1746+
flexShrinkScaledFactor;
1747+
}
1748+
1749+
updatedMainSize = YGNodeBoundAxis(
1750+
currentRelativeChild,
1751+
mainAxis,
1752+
childSize,
1753+
availableInnerMainDim,
1754+
availableInnerWidth);
1755+
}
1756+
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
1757+
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
1758+
1759+
// Is this child able to grow?
1760+
if (flexGrowFactor != 0) {
1761+
updatedMainSize = YGNodeBoundAxis(
1762+
currentRelativeChild,
1763+
mainAxis,
1764+
childFlexBasis +
1765+
collectedFlexItemsValues.remainingFreeSpace /
1766+
collectedFlexItemsValues.totalFlexGrowFactors *
1767+
flexGrowFactor,
1768+
availableInnerMainDim,
1769+
availableInnerWidth);
1770+
}
1771+
}
1772+
1773+
deltaFreeSpace -= updatedMainSize - childFlexBasis;
1774+
1775+
const float marginMain = YGNodeMarginForAxis(
1776+
currentRelativeChild, mainAxis, availableInnerWidth);
1777+
const float marginCross = YGNodeMarginForAxis(
1778+
currentRelativeChild, crossAxis, availableInnerWidth);
1779+
1780+
float childCrossSize;
1781+
float childMainSize = updatedMainSize + marginMain;
1782+
YGMeasureMode childCrossMeasureMode;
1783+
YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
1784+
1785+
if (!YGFloatIsUndefined(currentRelativeChild->getStyle().aspectRatio)) {
1786+
childCrossSize = isMainAxisRow ? (childMainSize - marginMain) /
1787+
currentRelativeChild->getStyle().aspectRatio
1788+
: (childMainSize - marginMain) *
1789+
currentRelativeChild->getStyle().aspectRatio;
1790+
childCrossMeasureMode = YGMeasureModeExactly;
1791+
1792+
childCrossSize += marginCross;
1793+
} else if (
1794+
!YGFloatIsUndefined(availableInnerCrossDim) &&
1795+
!YGNodeIsStyleDimDefined(
1796+
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
1797+
measureModeCrossDim == YGMeasureModeExactly &&
1798+
!(isNodeFlexWrap && flexBasisOverflows) &&
1799+
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
1800+
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
1801+
YGUnitAuto &&
1802+
currentRelativeChild->marginTrailingValue(crossAxis).unit !=
1803+
YGUnitAuto) {
1804+
childCrossSize = availableInnerCrossDim;
1805+
childCrossMeasureMode = YGMeasureModeExactly;
1806+
} else if (!YGNodeIsStyleDimDefined(
1807+
currentRelativeChild, crossAxis, availableInnerCrossDim)) {
1808+
childCrossSize = availableInnerCrossDim;
1809+
childCrossMeasureMode = YGFloatIsUndefined(childCrossSize)
1810+
? YGMeasureModeUndefined
1811+
: YGMeasureModeAtMost;
1812+
} else {
1813+
childCrossSize =
1814+
YGResolveValue(
1815+
currentRelativeChild->getResolvedDimension(dim[crossAxis]),
1816+
availableInnerCrossDim) +
1817+
marginCross;
1818+
const bool isLoosePercentageMeasurement =
1819+
currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit ==
1820+
YGUnitPercent &&
1821+
measureModeCrossDim != YGMeasureModeExactly;
1822+
childCrossMeasureMode =
1823+
YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement
1824+
? YGMeasureModeUndefined
1825+
: YGMeasureModeExactly;
1826+
}
1827+
1828+
YGConstrainMaxSizeForMode(
1829+
currentRelativeChild,
1830+
mainAxis,
1831+
availableInnerMainDim,
1832+
availableInnerWidth,
1833+
&childMainMeasureMode,
1834+
&childMainSize);
1835+
YGConstrainMaxSizeForMode(
1836+
currentRelativeChild,
1837+
crossAxis,
1838+
availableInnerCrossDim,
1839+
availableInnerWidth,
1840+
&childCrossMeasureMode,
1841+
&childCrossSize);
1842+
1843+
const bool requiresStretchLayout =
1844+
!YGNodeIsStyleDimDefined(
1845+
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
1846+
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
1847+
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
1848+
YGUnitAuto &&
1849+
currentRelativeChild->marginTrailingValue(crossAxis).unit != YGUnitAuto;
1850+
1851+
const float childWidth = isMainAxisRow ? childMainSize : childCrossSize;
1852+
const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize;
1853+
1854+
const YGMeasureMode childWidthMeasureMode =
1855+
isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
1856+
const YGMeasureMode childHeightMeasureMode =
1857+
!isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
1858+
1859+
// Recursively call the layout algorithm for this child with the updated
1860+
// main size.
1861+
YGLayoutNodeInternal(
1862+
currentRelativeChild,
1863+
childWidth,
1864+
childHeight,
1865+
node->getLayout().direction,
1866+
childWidthMeasureMode,
1867+
childHeightMeasureMode,
1868+
availableInnerWidth,
1869+
availableInnerHeight,
1870+
performLayout && !requiresStretchLayout,
1871+
"flex",
1872+
config);
1873+
node->setLayoutHadOverflow(
1874+
node->getLayout().hadOverflow |
1875+
currentRelativeChild->getLayout().hadOverflow);
1876+
}
1877+
1878+
collectedFlexItemsValues.remainingFreeSpace += deltaFreeSpace;
1879+
}
1880+
17041881
// It distributes the free space to the flexible items, for those flexible items
17051882
// whose min and max constraints are triggered, the clamped size is removed from
17061883
// the remaingfreespace.
@@ -2126,15 +2303,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
21262303
-collectedFlexItemsValues.sizeConsumedOnCurrentLine;
21272304
}
21282305

2129-
const float originalRemainingFreeSpace =
2130-
collectedFlexItemsValues.remainingFreeSpace;
2131-
float deltaFreeSpace = 0;
2132-
21332306
if (!canSkipFlex) {
2134-
float childFlexBasis;
2135-
float flexShrinkScaledFactor;
2136-
float flexGrowFactor;
2137-
21382307
// Do two passes over the flex items to figure out how to distribute the
21392308
// remaining space.
21402309
// The first pass finds the items whose min/max constraints trigger,
@@ -2166,169 +2335,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
21662335
availableInnerWidth);
21672336

21682337
// Second pass: resolve the sizes of the flexible items
2169-
deltaFreeSpace = 0;
2170-
for (auto currentRelativeChild :
2171-
collectedFlexItemsValues.relativeChildren) {
2172-
childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
2173-
currentRelativeChild,
2174-
mainAxis,
2175-
currentRelativeChild->getLayout().computedFlexBasis,
2176-
mainAxisParentSize);
2177-
float updatedMainSize = childFlexBasis;
2178-
2179-
if (collectedFlexItemsValues.remainingFreeSpace < 0) {
2180-
flexShrinkScaledFactor =
2181-
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
2182-
// Is this child able to shrink?
2183-
if (flexShrinkScaledFactor != 0) {
2184-
float childSize;
2185-
2186-
if (collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
2187-
childSize = childFlexBasis + flexShrinkScaledFactor;
2188-
} else {
2189-
childSize = childFlexBasis +
2190-
(collectedFlexItemsValues.remainingFreeSpace /
2191-
collectedFlexItemsValues.totalFlexShrinkScaledFactors) *
2192-
flexShrinkScaledFactor;
2193-
}
2194-
2195-
updatedMainSize = YGNodeBoundAxis(
2196-
currentRelativeChild,
2197-
mainAxis,
2198-
childSize,
2199-
availableInnerMainDim,
2200-
availableInnerWidth);
2201-
}
2202-
} else if (collectedFlexItemsValues.remainingFreeSpace > 0) {
2203-
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
2204-
2205-
// Is this child able to grow?
2206-
if (flexGrowFactor != 0) {
2207-
updatedMainSize = YGNodeBoundAxis(
2208-
currentRelativeChild,
2209-
mainAxis,
2210-
childFlexBasis +
2211-
collectedFlexItemsValues.remainingFreeSpace /
2212-
collectedFlexItemsValues.totalFlexGrowFactors *
2213-
flexGrowFactor,
2214-
availableInnerMainDim,
2215-
availableInnerWidth);
2216-
}
2217-
}
2218-
2219-
deltaFreeSpace -= updatedMainSize - childFlexBasis;
2220-
2221-
const float marginMain = YGNodeMarginForAxis(
2222-
currentRelativeChild, mainAxis, availableInnerWidth);
2223-
const float marginCross = YGNodeMarginForAxis(
2224-
currentRelativeChild, crossAxis, availableInnerWidth);
2225-
2226-
float childCrossSize;
2227-
float childMainSize = updatedMainSize + marginMain;
2228-
YGMeasureMode childCrossMeasureMode;
2229-
YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
2230-
2231-
if (!YGFloatIsUndefined(currentRelativeChild->getStyle().aspectRatio)) {
2232-
childCrossSize = isMainAxisRow ? (childMainSize - marginMain) /
2233-
currentRelativeChild->getStyle().aspectRatio
2234-
: (childMainSize - marginMain) *
2235-
currentRelativeChild->getStyle().aspectRatio;
2236-
childCrossMeasureMode = YGMeasureModeExactly;
2237-
2238-
childCrossSize += marginCross;
2239-
} else if (
2240-
!YGFloatIsUndefined(availableInnerCrossDim) &&
2241-
!YGNodeIsStyleDimDefined(
2242-
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
2243-
measureModeCrossDim == YGMeasureModeExactly &&
2244-
!(isNodeFlexWrap && flexBasisOverflows) &&
2245-
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
2246-
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
2247-
YGUnitAuto &&
2248-
currentRelativeChild->marginTrailingValue(crossAxis).unit !=
2249-
YGUnitAuto) {
2250-
childCrossSize = availableInnerCrossDim;
2251-
childCrossMeasureMode = YGMeasureModeExactly;
2252-
} else if (!YGNodeIsStyleDimDefined(
2253-
currentRelativeChild,
2254-
crossAxis,
2255-
availableInnerCrossDim)) {
2256-
childCrossSize = availableInnerCrossDim;
2257-
childCrossMeasureMode = YGFloatIsUndefined(childCrossSize)
2258-
? YGMeasureModeUndefined
2259-
: YGMeasureModeAtMost;
2260-
} else {
2261-
childCrossSize =
2262-
YGResolveValue(
2263-
currentRelativeChild->getResolvedDimension(dim[crossAxis]),
2264-
availableInnerCrossDim) +
2265-
marginCross;
2266-
const bool isLoosePercentageMeasurement =
2267-
currentRelativeChild->getResolvedDimension(dim[crossAxis]).unit ==
2268-
YGUnitPercent &&
2269-
measureModeCrossDim != YGMeasureModeExactly;
2270-
childCrossMeasureMode =
2271-
YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement
2272-
? YGMeasureModeUndefined
2273-
: YGMeasureModeExactly;
2274-
}
2275-
2276-
YGConstrainMaxSizeForMode(
2277-
currentRelativeChild,
2278-
mainAxis,
2279-
availableInnerMainDim,
2280-
availableInnerWidth,
2281-
&childMainMeasureMode,
2282-
&childMainSize);
2283-
YGConstrainMaxSizeForMode(
2284-
currentRelativeChild,
2285-
crossAxis,
2286-
availableInnerCrossDim,
2287-
availableInnerWidth,
2288-
&childCrossMeasureMode,
2289-
&childCrossSize);
2290-
2291-
const bool requiresStretchLayout =
2292-
!YGNodeIsStyleDimDefined(
2293-
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
2294-
YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch &&
2295-
currentRelativeChild->marginLeadingValue(crossAxis).unit !=
2296-
YGUnitAuto &&
2297-
currentRelativeChild->marginTrailingValue(crossAxis).unit !=
2298-
YGUnitAuto;
2299-
2300-
const float childWidth = isMainAxisRow ? childMainSize : childCrossSize;
2301-
const float childHeight =
2302-
!isMainAxisRow ? childMainSize : childCrossSize;
2303-
2304-
const YGMeasureMode childWidthMeasureMode =
2305-
isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
2306-
const YGMeasureMode childHeightMeasureMode =
2307-
!isMainAxisRow ? childMainMeasureMode : childCrossMeasureMode;
2308-
2309-
// Recursively call the layout algorithm for this child with the updated
2310-
// main size.
2311-
YGLayoutNodeInternal(
2312-
currentRelativeChild,
2313-
childWidth,
2314-
childHeight,
2315-
direction,
2316-
childWidthMeasureMode,
2317-
childHeightMeasureMode,
2318-
availableInnerWidth,
2319-
availableInnerHeight,
2320-
performLayout && !requiresStretchLayout,
2321-
"flex",
2322-
config);
2323-
node->setLayoutHadOverflow(
2324-
node->getLayout().hadOverflow |
2325-
currentRelativeChild->getLayout().hadOverflow);
2326-
currentRelativeChild = currentRelativeChild->getNextChild();
2327-
}
2338+
YGDistributeFreeSpaceSecondPass(
2339+
collectedFlexItemsValues,
2340+
node,
2341+
mainAxis,
2342+
crossAxis,
2343+
mainAxisParentSize,
2344+
availableInnerMainDim,
2345+
availableInnerCrossDim,
2346+
availableInnerWidth,
2347+
availableInnerHeight,
2348+
flexBasisOverflows,
2349+
measureModeCrossDim,
2350+
performLayout,
2351+
config);
23282352
}
23292353

2330-
collectedFlexItemsValues.remainingFreeSpace =
2331-
originalRemainingFreeSpace + deltaFreeSpace;
23322354
node->setLayoutHadOverflow(
23332355
node->getLayout().hadOverflow |
23342356
(collectedFlexItemsValues.remainingFreeSpace < 0));

0 commit comments

Comments
 (0)