@@ -259,7 +259,8 @@ static void _CSSNodeMarkDirty(const CSSNodeRef node) {
259
259
}
260
260
261
261
void CSSNodeSetMeasureFunc (const CSSNodeRef node , CSSMeasureFunc measureFunc ) {
262
- CSS_ASSERT (CSSNodeChildCount (node ) == 0 , "Cannot set measure function: Nodes with measure functions cannot have children." );
262
+ CSS_ASSERT (CSSNodeChildCount (node ) == 0 ,
263
+ "Cannot set measure function: Nodes with measure functions cannot have children." );
263
264
node -> measure = measureFunc ;
264
265
}
265
266
@@ -269,7 +270,8 @@ CSSMeasureFunc CSSNodeGetMeasureFunc(const CSSNodeRef node) {
269
270
270
271
void CSSNodeInsertChild (const CSSNodeRef node , const CSSNodeRef child , const uint32_t index ) {
271
272
CSS_ASSERT (child -> parent == NULL , "Child already has a parent, it must be removed first." );
272
- CSS_ASSERT (node -> measure == NULL , "Cannot add child: Nodes with measure functions cannot have children." );
273
+ CSS_ASSERT (node -> measure == NULL ,
274
+ "Cannot add child: Nodes with measure functions cannot have children." );
273
275
CSSNodeListInsert (& node -> children , child , index );
274
276
child -> parent = node ;
275
277
_CSSNodeMarkDirty (node );
@@ -1367,6 +1369,26 @@ static void layoutNodeImpl(const CSSNodeRef node,
1367
1369
const float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight ;
1368
1370
const float availableInnerCrossDim = isMainAxisRow ? availableInnerHeight : availableInnerWidth ;
1369
1371
1372
+ // If there is only one child with flexGrow + flexShrink it means we can set the
1373
+ // computedFlexBasis to 0 instead of measuring and shrinking / flexing the child to exactly
1374
+ // match the remaining space
1375
+ CSSNodeRef singleFlexChild = NULL ;
1376
+ if ((isMainAxisRow && widthMeasureMode != CSSMeasureModeUndefined ) ||
1377
+ (!isMainAxisRow && heightMeasureMode != CSSMeasureModeUndefined )) {
1378
+ for (uint32_t i = 0 ; i < childCount ; i ++ ) {
1379
+ const CSSNodeRef child = CSSNodeGetChild (node , i );
1380
+ if (singleFlexChild ) {
1381
+ if (isFlex (child )) {
1382
+ // There is already a flexible child, abort.
1383
+ singleFlexChild = NULL ;
1384
+ break ;
1385
+ }
1386
+ } else if (CSSNodeStyleGetFlexGrow (child ) > 0 && CSSNodeStyleGetFlexShrink (child ) > 0 ) {
1387
+ singleFlexChild = child ;
1388
+ }
1389
+ }
1390
+ }
1391
+
1370
1392
// STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM
1371
1393
for (uint32_t i = 0 ; i < childCount ; i ++ ) {
1372
1394
const CSSNodeRef child = CSSNodeListGet (node -> children , i );
@@ -1391,13 +1413,17 @@ static void layoutNodeImpl(const CSSNodeRef node,
1391
1413
currentAbsoluteChild = child ;
1392
1414
child -> nextChild = NULL ;
1393
1415
} else {
1394
- computeChildFlexBasis (node ,
1395
- child ,
1396
- availableInnerWidth ,
1397
- widthMeasureMode ,
1398
- availableInnerHeight ,
1399
- heightMeasureMode ,
1400
- direction );
1416
+ if (child == singleFlexChild ) {
1417
+ child -> layout .computedFlexBasis = 0 ;
1418
+ } else {
1419
+ computeChildFlexBasis (node ,
1420
+ child ,
1421
+ availableInnerWidth ,
1422
+ widthMeasureMode ,
1423
+ availableInnerHeight ,
1424
+ heightMeasureMode ,
1425
+ direction );
1426
+ }
1401
1427
}
1402
1428
}
1403
1429
@@ -2133,17 +2159,17 @@ static inline bool newMeasureSizeIsStricterAndStillValid(CSSMeasureMode sizeMode
2133
2159
}
2134
2160
2135
2161
bool CSSNodeCanUseCachedMeasurement (const CSSMeasureMode widthMode ,
2136
- const float width ,
2137
- const CSSMeasureMode heightMode ,
2138
- const float height ,
2139
- const CSSMeasureMode lastWidthMode ,
2140
- const float lastWidth ,
2141
- const CSSMeasureMode lastHeightMode ,
2142
- const float lastHeight ,
2143
- const float lastComputedWidth ,
2144
- const float lastComputedHeight ,
2145
- const float marginRow ,
2146
- const float marginColumn ) {
2162
+ const float width ,
2163
+ const CSSMeasureMode heightMode ,
2164
+ const float height ,
2165
+ const CSSMeasureMode lastWidthMode ,
2166
+ const float lastWidth ,
2167
+ const CSSMeasureMode lastHeightMode ,
2168
+ const float lastHeight ,
2169
+ const float lastComputedWidth ,
2170
+ const float lastComputedHeight ,
2171
+ const float marginRow ,
2172
+ const float marginColumn ) {
2147
2173
if (lastComputedHeight < 0 || lastComputedWidth < 0 ) {
2148
2174
return false;
2149
2175
}
@@ -2161,19 +2187,16 @@ bool CSSNodeCanUseCachedMeasurement(const CSSMeasureMode widthMode,
2161
2187
newMeasureSizeIsStricterAndStillValid (
2162
2188
widthMode , width - marginRow , lastWidthMode , lastWidth , lastComputedWidth );
2163
2189
2164
- const bool heightIsCompatible = hasSameHeightSpec ||
2165
- newSizeIsExactAndMatchesOldMeasuredSize (heightMode ,
2166
- height - marginColumn ,
2167
- lastComputedHeight ) ||
2168
- oldSizeIsUnspecifiedAndStillFits (heightMode ,
2190
+ const bool heightIsCompatible =
2191
+ hasSameHeightSpec || newSizeIsExactAndMatchesOldMeasuredSize (heightMode ,
2169
2192
height - marginColumn ,
2170
- lastHeightMode ,
2171
2193
lastComputedHeight ) ||
2172
- newMeasureSizeIsStricterAndStillValid (heightMode ,
2173
- height - marginColumn ,
2174
- lastHeightMode ,
2175
- lastHeight ,
2176
- lastComputedHeight );
2194
+ oldSizeIsUnspecifiedAndStillFits (heightMode ,
2195
+ height - marginColumn ,
2196
+ lastHeightMode ,
2197
+ lastComputedHeight ) ||
2198
+ newMeasureSizeIsStricterAndStillValid (
2199
+ heightMode , height - marginColumn , lastHeightMode , lastHeight , lastComputedHeight );
2177
2200
2178
2201
return widthIsCompatible && heightIsCompatible ;
2179
2202
}
0 commit comments