@@ -1701,6 +1701,183 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
1701
1701
return flexAlgoRowMeasurement;
1702
1702
}
1703
1703
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
+
1704
1881
// It distributes the free space to the flexible items, for those flexible items
1705
1882
// whose min and max constraints are triggered, the clamped size is removed from
1706
1883
// the remaingfreespace.
@@ -2126,15 +2303,7 @@ static void YGNodelayoutImpl(const YGNodeRef node,
2126
2303
-collectedFlexItemsValues.sizeConsumedOnCurrentLine ;
2127
2304
}
2128
2305
2129
- const float originalRemainingFreeSpace =
2130
- collectedFlexItemsValues.remainingFreeSpace ;
2131
- float deltaFreeSpace = 0 ;
2132
-
2133
2306
if (!canSkipFlex) {
2134
- float childFlexBasis;
2135
- float flexShrinkScaledFactor;
2136
- float flexGrowFactor;
2137
-
2138
2307
// Do two passes over the flex items to figure out how to distribute the
2139
2308
// remaining space.
2140
2309
// The first pass finds the items whose min/max constraints trigger,
@@ -2166,169 +2335,22 @@ static void YGNodelayoutImpl(const YGNodeRef node,
2166
2335
availableInnerWidth);
2167
2336
2168
2337
// 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);
2328
2352
}
2329
2353
2330
- collectedFlexItemsValues.remainingFreeSpace =
2331
- originalRemainingFreeSpace + deltaFreeSpace;
2332
2354
node->setLayoutHadOverflow (
2333
2355
node->getLayout ().hadOverflow |
2334
2356
(collectedFlexItemsValues.remainingFreeSpace < 0 ));
0 commit comments