@@ -451,11 +451,16 @@ static float getDimWithMargin(css_node_t *node, css_flex_direction_t axis) {
451451 getTrailingMargin (node , axis );
452452}
453453
454- static bool isDimDefined (css_node_t * node , css_flex_direction_t axis ) {
454+ static bool isStyleDimDefined (css_node_t * node , css_flex_direction_t axis ) {
455455 float value = node -> style .dimensions [dim [axis ]];
456456 return !isUndefined (value ) && value >= 0.0 ;
457457}
458458
459+ static bool isLayoutDimDefined (css_node_t * node , css_flex_direction_t axis ) {
460+ float value = node -> layout .dimensions [dim [axis ]];
461+ return !isUndefined (value ) && value >= 0.0 ;
462+ }
463+
459464static bool isPosDefined (css_node_t * node , css_position_t position ) {
460465 return !isUndefined (node -> style .position [position ]);
461466}
@@ -499,11 +504,11 @@ static float boundAxis(css_node_t *node, css_flex_direction_t axis, float value)
499504// When the user specifically sets a value for width or height
500505static void setDimensionFromStyle (css_node_t * node , css_flex_direction_t axis ) {
501506 // The parent already computed us a width or height. We just skip it
502- if (! isUndefined (node -> layout . dimensions [ dim [ axis ]] )) {
507+ if (isLayoutDimDefined (node , axis )) {
503508 return ;
504509 }
505510 // We only run if there's a width or height defined
506- if (!isDimDefined (node , axis )) {
511+ if (!isStyleDimDefined (node , axis )) {
507512 return ;
508513 }
509514
@@ -561,10 +566,10 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
561566 float paddingAndBorderAxisColumn = getPaddingAndBorderAxis (node , CSS_FLEX_DIRECTION_COLUMN );
562567
563568 if (isMeasureDefined (node )) {
564- bool isResolvedRowDimDefined = ! isUndefined (node -> layout . dimensions [ dim [ resolvedRowAxis ]] );
569+ bool isResolvedRowDimDefined = isLayoutDimDefined (node , resolvedRowAxis );
565570
566571 float width = CSS_UNDEFINED ;
567- if (isDimDefined (node , resolvedRowAxis )) {
572+ if (isStyleDimDefined (node , resolvedRowAxis )) {
568573 width = node -> style .dimensions [CSS_WIDTH ];
569574 } else if (isResolvedRowDimDefined ) {
570575 width = node -> layout .dimensions [dim [resolvedRowAxis ]];
@@ -575,9 +580,9 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
575580 width -= paddingAndBorderAxisResolvedRow ;
576581
577582 float height = CSS_UNDEFINED ;
578- if (isDimDefined (node , CSS_FLEX_DIRECTION_COLUMN )) {
583+ if (isStyleDimDefined (node , CSS_FLEX_DIRECTION_COLUMN )) {
579584 height = node -> style .dimensions [CSS_HEIGHT ];
580- } else if (! isUndefined (node -> layout . dimensions [ dim [ CSS_FLEX_DIRECTION_COLUMN ]] )) {
585+ } else if (isLayoutDimDefined (node , CSS_FLEX_DIRECTION_COLUMN )) {
581586 height = node -> layout .dimensions [dim [CSS_FLEX_DIRECTION_COLUMN ]];
582587 } else {
583588 height = parentMaxHeight -
@@ -588,8 +593,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
588593 // We only need to give a dimension for the text if we haven't got any
589594 // for it computed yet. It can either be from the style attribute or because
590595 // the element is flexible.
591- bool isRowUndefined = !isDimDefined (node , resolvedRowAxis ) && !isResolvedRowDimDefined ;
592- bool isColumnUndefined = !isDimDefined (node , CSS_FLEX_DIRECTION_COLUMN ) &&
596+ bool isRowUndefined = !isStyleDimDefined (node , resolvedRowAxis ) && !isResolvedRowDimDefined ;
597+ bool isColumnUndefined = !isStyleDimDefined (node , CSS_FLEX_DIRECTION_COLUMN ) &&
593598 isUndefined (node -> layout .dimensions [dim [CSS_FLEX_DIRECTION_COLUMN ]]);
594599
595600 // Let's not measure the text if we already know both dimensions
@@ -623,8 +628,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
623628 float paddingAndBorderAxisMain = getPaddingAndBorderAxis (node , mainAxis );
624629 float paddingAndBorderAxisCross = getPaddingAndBorderAxis (node , crossAxis );
625630
626- bool isMainDimDefined = ! isUndefined (node -> layout . dimensions [ dim [ mainAxis ]] );
627- bool isCrossDimDefined = ! isUndefined (node -> layout . dimensions [ dim [ crossAxis ]] );
631+ bool isMainDimDefined = isLayoutDimDefined (node , mainAxis );
632+ bool isCrossDimDefined = isLayoutDimDefined (node , crossAxis );
628633 bool isMainRowDirection = isRowDirection (mainAxis );
629634
630635 int i ;
@@ -686,8 +691,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
686691 float mainDim = leadingPaddingAndBorderMain ;
687692 float crossDim = 0 ;
688693
689- float maxWidth ;
690- float maxHeight ;
694+ float maxWidth = CSS_UNDEFINED ;
695+ float maxHeight = CSS_UNDEFINED ;
691696 for (i = startLine ; i < childCount ; ++ i ) {
692697 child = node -> get_child (node -> context , i );
693698 child -> line_index = linesCount ;
@@ -702,7 +707,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
702707 if (alignItem == CSS_ALIGN_STRETCH &&
703708 child -> style .position_type == CSS_POSITION_RELATIVE &&
704709 isCrossDimDefined &&
705- !isDimDefined (child , crossAxis )) {
710+ !isStyleDimDefined (child , crossAxis )) {
706711 child -> layout .dimensions [dim [crossAxis ]] = fmaxf (
707712 boundAxis (child , crossAxis , node -> layout .dimensions [dim [crossAxis ]] -
708713 paddingAndBorderAxisCross - getMarginAxis (child , crossAxis )),
@@ -724,8 +729,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
724729 // left and right or top and bottom).
725730 for (ii = 0 ; ii < 2 ; ii ++ ) {
726731 axis = (ii != 0 ) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN ;
727- if (! isUndefined (node -> layout . dimensions [ dim [ axis ]] ) &&
728- !isDimDefined (child , axis ) &&
732+ if (isLayoutDimDefined (node , axis ) &&
733+ !isStyleDimDefined (child , axis ) &&
729734 isPosDefined (child , leading [axis ]) &&
730735 isPosDefined (child , trailing [axis ])) {
731736 child -> layout .dimensions [dim [axis ]] = fmaxf (
@@ -771,7 +776,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
771776 maxHeight = CSS_UNDEFINED ;
772777
773778 if (!isMainRowDirection ) {
774- if (isDimDefined (node , resolvedRowAxis )) {
779+ if (isLayoutDimDefined (node , resolvedRowAxis )) {
775780 maxWidth = node -> layout .dimensions [dim [resolvedRowAxis ]] -
776781 paddingAndBorderAxisResolvedRow ;
777782 } else {
@@ -780,7 +785,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
780785 paddingAndBorderAxisResolvedRow ;
781786 }
782787 } else {
783- if (isDimDefined (node , CSS_FLEX_DIRECTION_COLUMN )) {
788+ if (isLayoutDimDefined (node , CSS_FLEX_DIRECTION_COLUMN )) {
784789 maxHeight = node -> layout .dimensions [dim [CSS_FLEX_DIRECTION_COLUMN ]] -
785790 paddingAndBorderAxisColumn ;
786791 } else {
@@ -831,7 +836,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
831836 if (isSimpleStackCross &&
832837 (child -> style .position_type != CSS_POSITION_RELATIVE ||
833838 (alignItem != CSS_ALIGN_STRETCH && alignItem != CSS_ALIGN_FLEX_START ) ||
834- isUndefined ( child -> layout . dimensions [ dim [ crossAxis ]] ))) {
839+ ( alignItem == CSS_ALIGN_STRETCH && ! isCrossDimDefined ))) {
835840 isSimpleStackCross = false;
836841 firstComplexCross = i ;
837842 }
@@ -914,7 +919,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
914919 );
915920
916921 maxWidth = CSS_UNDEFINED ;
917- if (isDimDefined (node , resolvedRowAxis )) {
922+ if (isLayoutDimDefined (node , resolvedRowAxis )) {
918923 maxWidth = node -> layout .dimensions [dim [resolvedRowAxis ]] -
919924 paddingAndBorderAxisResolvedRow ;
920925 } else if (!isMainRowDirection ) {
@@ -923,7 +928,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
923928 paddingAndBorderAxisResolvedRow ;
924929 }
925930 maxHeight = CSS_UNDEFINED ;
926- if (isDimDefined (node , CSS_FLEX_DIRECTION_COLUMN )) {
931+ if (isLayoutDimDefined (node , CSS_FLEX_DIRECTION_COLUMN )) {
927932 maxHeight = node -> layout .dimensions [dim [CSS_FLEX_DIRECTION_COLUMN ]] -
928933 paddingAndBorderAxisColumn ;
929934 } else if (isMainRowDirection ) {
@@ -1041,15 +1046,31 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
10411046 css_align_t alignItem = getAlignItem (node , child );
10421047 /*eslint-enable */
10431048 if (alignItem == CSS_ALIGN_STRETCH ) {
1044- // You can only stretch if the dimension has not already been set
1049+ // You can only stretch if the dimension has not already been defined
10451050 // previously.
1046- if (isUndefined (child -> layout .dimensions [dim [crossAxis ]])) {
1051+ if (!isStyleDimDefined (child , crossAxis )) {
1052+ float dimCrossAxis = child -> layout .dimensions [dim [crossAxis ]];
10471053 child -> layout .dimensions [dim [crossAxis ]] = fmaxf (
10481054 boundAxis (child , crossAxis , containerCrossAxis -
10491055 paddingAndBorderAxisCross - getMarginAxis (child , crossAxis )),
10501056 // You never want to go smaller than padding
10511057 getPaddingAndBorderAxis (child , crossAxis )
10521058 );
1059+
1060+ // If the size has changed, and this child has children we need to re-layout this child
1061+ if (dimCrossAxis != child -> layout .dimensions [dim [crossAxis ]] && child -> children_count > 0 ) {
1062+ // Reset child margins before re-layout as they are added back in layoutNode and would be doubled
1063+ child -> layout .position [leading [mainAxis ]] -= getLeadingMargin (child , mainAxis ) +
1064+ getRelativePosition (child , mainAxis );
1065+ child -> layout .position [trailing [mainAxis ]] -= getTrailingMargin (child , mainAxis ) +
1066+ getRelativePosition (child , mainAxis );
1067+ child -> layout .position [leading [crossAxis ]] -= getLeadingMargin (child , crossAxis ) +
1068+ getRelativePosition (child , crossAxis );
1069+ child -> layout .position [trailing [crossAxis ]] -= getTrailingMargin (child , crossAxis ) +
1070+ getRelativePosition (child , crossAxis );
1071+
1072+ layoutNode (child , maxWidth , maxHeight , direction );
1073+ }
10531074 }
10541075 } else if (alignItem != CSS_ALIGN_FLEX_START ) {
10551076 // The remaining space between the parent dimensions+padding and child
@@ -1127,7 +1148,7 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
11271148 if (child -> line_index != i ) {
11281149 break ;
11291150 }
1130- if (! isUndefined (child -> layout . dimensions [ dim [ crossAxis ]] )) {
1151+ if (isLayoutDimDefined (child , crossAxis )) {
11311152 lineHeight = fmaxf (
11321153 lineHeight ,
11331154 child -> layout .dimensions [dim [crossAxis ]] + getMarginAxis (child , crossAxis )
@@ -1220,8 +1241,8 @@ static void layoutNodeImpl(css_node_t *node, float parentMaxWidth, float parentM
12201241 for (ii = 0 ; ii < 2 ; ii ++ ) {
12211242 axis = (ii != 0 ) ? CSS_FLEX_DIRECTION_ROW : CSS_FLEX_DIRECTION_COLUMN ;
12221243
1223- if (! isUndefined (node -> layout . dimensions [ dim [ axis ]] ) &&
1224- !isDimDefined (currentAbsoluteChild , axis ) &&
1244+ if (isLayoutDimDefined (node , axis ) &&
1245+ !isStyleDimDefined (currentAbsoluteChild , axis ) &&
12251246 isPosDefined (currentAbsoluteChild , leading [axis ]) &&
12261247 isPosDefined (currentAbsoluteChild , trailing [axis ])) {
12271248 currentAbsoluteChild -> layout .dimensions [dim [axis ]] = fmaxf (
@@ -1261,8 +1282,8 @@ void layoutNode(css_node_t *node, float parentMaxWidth, float parentMaxHeight, c
12611282 !node -> is_dirty (node -> context ) &&
12621283 eq (layout -> last_requested_dimensions [CSS_WIDTH ], layout -> dimensions [CSS_WIDTH ]) &&
12631284 eq (layout -> last_requested_dimensions [CSS_HEIGHT ], layout -> dimensions [CSS_HEIGHT ]) &&
1264- eq (layout -> last_parent_max_width , parentMaxWidth );
1265- eq (layout -> last_parent_max_height , parentMaxHeight );
1285+ eq (layout -> last_parent_max_width , parentMaxWidth ) &&
1286+ eq (layout -> last_parent_max_height , parentMaxHeight ) &&
12661287 eq (layout -> last_direction , direction );
12671288
12681289 if (skipLayout ) {
@@ -1277,6 +1298,10 @@ void layoutNode(css_node_t *node, float parentMaxWidth, float parentMaxHeight, c
12771298 layout -> last_parent_max_height = parentMaxHeight ;
12781299 layout -> last_direction = direction ;
12791300
1301+ for (int i = 0 , childCount = node -> children_count ; i < childCount ; i ++ ) {
1302+ resetNodeLayout (node -> get_child (node -> context , i ));
1303+ }
1304+
12801305 layoutNodeImpl (node , parentMaxWidth , parentMaxHeight , parentDirection );
12811306
12821307 layout -> last_dimensions [CSS_WIDTH ] = layout -> dimensions [CSS_WIDTH ];
@@ -1285,3 +1310,10 @@ void layoutNode(css_node_t *node, float parentMaxWidth, float parentMaxHeight, c
12851310 layout -> last_position [CSS_LEFT ] = layout -> position [CSS_LEFT ];
12861311 }
12871312}
1313+
1314+ void resetNodeLayout (css_node_t * node ) {
1315+ node -> layout .dimensions [CSS_WIDTH ] = CSS_UNDEFINED ;
1316+ node -> layout .dimensions [CSS_HEIGHT ] = CSS_UNDEFINED ;
1317+ node -> layout .position [CSS_LEFT ] = 0 ;
1318+ node -> layout .position [CSS_TOP ] = 0 ;
1319+ }
0 commit comments