@@ -70,6 +70,8 @@ void CSSNodeInit(CSSNodeRef node) {
7070 node -> style .position [CSSPositionTop ] = CSSUndefined ;
7171 node -> style .position [CSSPositionRight ] = CSSUndefined ;
7272 node -> style .position [CSSPositionBottom ] = CSSUndefined ;
73+ node -> style .position [CSSPositionStart ] = CSSUndefined ;
74+ node -> style .position [CSSPositionEnd ] = CSSUndefined ;
7375
7476 node -> style .margin [CSSPositionStart ] = CSSUndefined ;
7577 node -> style .margin [CSSPositionEnd ] = CSSUndefined ;
@@ -173,6 +175,8 @@ CSS_NODE_STYLE_PROPERTY_IMPL(float, PositionLeft, positionLeft, position[CSSPosi
173175CSS_NODE_STYLE_PROPERTY_IMPL (float , PositionTop , positionTop , position [CSSPositionTop ]);
174176CSS_NODE_STYLE_PROPERTY_IMPL (float , PositionRight , positionRight , position [CSSPositionRight ]);
175177CSS_NODE_STYLE_PROPERTY_IMPL (float , PositionBottom , positionBottom , position [CSSPositionBottom ]);
178+ CSS_NODE_STYLE_PROPERTY_IMPL (float , PositionStart , positionStart , position [CSSPositionStart ]);
179+ CSS_NODE_STYLE_PROPERTY_IMPL (float , PositionEnd , positionEnd , position [CSSPositionEnd ]);
176180
177181CSS_NODE_STYLE_PROPERTY_IMPL (float , MarginLeft , marginLeft , margin [CSSPositionLeft ]);
178182CSS_NODE_STYLE_PROPERTY_IMPL (float , MarginTop , marginTop , margin [CSSPositionTop ]);
@@ -208,6 +212,7 @@ CSS_NODE_LAYOUT_PROPERTY_IMPL(float, Right, position[CSSPositionRight]);
208212CSS_NODE_LAYOUT_PROPERTY_IMPL (float , Bottom , position [CSSPositionBottom ]);
209213CSS_NODE_LAYOUT_PROPERTY_IMPL (float , Width , dimensions [CSSDimensionWidth ]);
210214CSS_NODE_LAYOUT_PROPERTY_IMPL (float , Height , dimensions [CSSDimensionHeight ]);
215+ CSS_NODE_LAYOUT_PROPERTY_IMPL (CSSDirection , Direction , direction );
211216
212217int gCurrentGenerationCount = 0 ;
213218
@@ -623,18 +628,36 @@ static bool isLayoutDimDefined(CSSNode* node, CSSFlexDirection axis) {
623628 return !isUndefined (value ) && value >= 0.0 ;
624629}
625630
626- static bool isPosDefined (CSSNode * node , CSSPosition position ) {
627- return !isUndefined (node -> style .position [position ]);
631+ static bool isLeadingPosDefined (CSSNode * node , CSSFlexDirection axis ) {
632+ return (isRowDirection (axis ) && !isUndefined (node -> style .position [CSSPositionStart ]))
633+ || !isUndefined (node -> style .position [leading [axis ]]);
634+ }
635+
636+ static bool isTrailingPosDefined (CSSNode * node , CSSFlexDirection axis ) {
637+ return (isRowDirection (axis ) && !isUndefined (node -> style .position [CSSPositionEnd ]))
638+ || !isUndefined (node -> style .position [trailing [axis ]]);
628639}
629640
630641static bool isMeasureDefined (CSSNode * node ) {
631642 return node -> measure ;
632643}
633644
634- static float getPosition (CSSNode * node , CSSPosition position ) {
635- float result = node -> style .position [position ];
636- if (!isUndefined (result )) {
637- return result ;
645+ static float getLeadingPosition (CSSNode * node , CSSFlexDirection axis ) {
646+ if (isRowDirection (axis ) && !isUndefined (node -> style .position [CSSPositionStart ])) {
647+ return node -> style .position [CSSPositionStart ];
648+ }
649+ if (!isUndefined (node -> style .position [leading [axis ]])) {
650+ return node -> style .position [leading [axis ]];
651+ }
652+ return 0 ;
653+ }
654+
655+ static float getTrailingPosition (CSSNode * node , CSSFlexDirection axis ) {
656+ if (isRowDirection (axis ) && !isUndefined (node -> style .position [CSSPositionEnd ])) {
657+ return node -> style .position [CSSPositionEnd ];
658+ }
659+ if (!isUndefined (node -> style .position [trailing [axis ]])) {
660+ return node -> style .position [trailing [axis ]];
638661 }
639662 return 0 ;
640663}
@@ -670,20 +693,18 @@ static float boundAxis(CSSNode* node, CSSFlexDirection axis, float value) {
670693}
671694
672695static void setTrailingPosition (CSSNode * node , CSSNode * child , CSSFlexDirection axis ) {
673- float size = child -> style .positionType == CSSPositionTypeAbsolute ?
674- 0 :
675- child -> layout .measuredDimensions [dim [axis ]];
696+ float size = child -> layout .measuredDimensions [dim [axis ]];
676697 child -> layout .position [trailing [axis ]] = node -> layout .measuredDimensions [dim [axis ]] - size - child -> layout .position [pos [axis ]];
677698}
678699
679700// If both left and right are defined, then use left. Otherwise return
680701// +left or -right depending on which is defined.
681702static float getRelativePosition (CSSNode * node , CSSFlexDirection axis ) {
682- float lead = node -> style . position [ leading [ axis ]] ;
703+ float lead = getLeadingPosition ( node , axis ) ;
683704 if (!isUndefined (lead )) {
684705 return lead ;
685706 }
686- return - getPosition (node , trailing [ axis ] );
707+ return - getTrailingPosition (node , axis );
687708}
688709
689710static void setPosition (CSSNode * node , CSSDirection direction ) {
@@ -1294,12 +1315,12 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
12941315 child = CSSNodeListGet (node -> children , i );
12951316
12961317 if (child -> style .positionType == CSSPositionTypeAbsolute &&
1297- isPosDefined (child , leading [ mainAxis ] )) {
1318+ isLeadingPosDefined (child , mainAxis )) {
12981319 if (performLayout ) {
12991320 // In case the child is position absolute and has left/top being
13001321 // defined, we override the position to whatever the user said
13011322 // (and margin/border).
1302- child -> layout .position [pos [mainAxis ]] = getPosition (child , leading [ mainAxis ] ) +
1323+ child -> layout .position [pos [mainAxis ]] = getLeadingPosition (child , mainAxis ) +
13031324 getLeadingBorder (node , mainAxis ) +
13041325 getLeadingMargin (child , mainAxis );
13051326 }
@@ -1361,8 +1382,8 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
13611382 if (child -> style .positionType == CSSPositionTypeAbsolute ) {
13621383 // If the child is absolutely positioned and has a top/left/bottom/right
13631384 // set, override all the previously computed positions to set it correctly.
1364- if (isPosDefined (child , leading [ crossAxis ] )) {
1365- child -> layout .position [pos [crossAxis ]] = getPosition (child , leading [ crossAxis ] ) +
1385+ if (isLeadingPosDefined (child , crossAxis )) {
1386+ child -> layout .position [pos [crossAxis ]] = getLeadingPosition (child , crossAxis ) +
13661387 getLeadingBorder (node , crossAxis ) +
13671388 getLeadingMargin (child , crossAxis );
13681389 } else {
@@ -1518,38 +1539,7 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
15181539 paddingAndBorderAxisCross );
15191540 }
15201541
1521- // STEP 10: SETTING TRAILING POSITIONS FOR CHILDREN
1522- if (performLayout ) {
1523- bool needsMainTrailingPos = false;
1524- bool needsCrossTrailingPos = false;
1525-
1526- if (mainAxis == CSSFlexDirectionRowReverse ||
1527- mainAxis == CSSFlexDirectionColumnReverse ) {
1528- needsMainTrailingPos = true;
1529- }
1530-
1531- if (crossAxis == CSSFlexDirectionRowReverse ||
1532- crossAxis == CSSFlexDirectionColumnReverse ) {
1533- needsCrossTrailingPos = true;
1534- }
1535-
1536- // Set trailing position if necessary.
1537- if (needsMainTrailingPos || needsCrossTrailingPos ) {
1538- for (i = 0 ; i < childCount ; ++ i ) {
1539- child = CSSNodeListGet (node -> children , i );
1540-
1541- if (needsMainTrailingPos ) {
1542- setTrailingPosition (node , child , mainAxis );
1543- }
1544-
1545- if (needsCrossTrailingPos ) {
1546- setTrailingPosition (node , child , crossAxis );
1547- }
1548- }
1549- }
1550- }
1551-
1552- // STEP 11: SIZING AND POSITIONING ABSOLUTE CHILDREN
1542+ // STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN
15531543 currentAbsoluteChild = firstAbsoluteChild ;
15541544 while (currentAbsoluteChild != NULL ) {
15551545 // Now that we know the bounds of the container, perform layout again on the
@@ -1563,10 +1553,10 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
15631553 childWidth = currentAbsoluteChild -> style .dimensions [CSSDimensionWidth ] + getMarginAxis (currentAbsoluteChild , CSSFlexDirectionRow );
15641554 } else {
15651555 // If the child doesn't have a specified width, compute the width based on the left/right offsets if they're defined.
1566- if (isPosDefined (currentAbsoluteChild , CSSPositionLeft ) && isPosDefined (currentAbsoluteChild , CSSPositionRight )) {
1556+ if (isLeadingPosDefined (currentAbsoluteChild , CSSFlexDirectionRow ) && isTrailingPosDefined (currentAbsoluteChild , CSSFlexDirectionRow )) {
15671557 childWidth = node -> layout .measuredDimensions [CSSDimensionWidth ] -
15681558 (getLeadingBorder (node , CSSFlexDirectionRow ) + getTrailingBorder (node , CSSFlexDirectionRow )) -
1569- (currentAbsoluteChild -> style . position [ CSSPositionLeft ] + currentAbsoluteChild -> style . position [ CSSPositionRight ] );
1559+ (getLeadingPosition ( currentAbsoluteChild , CSSFlexDirectionRow ) + getTrailingPosition ( currentAbsoluteChild , CSSFlexDirectionRow ) );
15701560 childWidth = boundAxis (currentAbsoluteChild , CSSFlexDirectionRow , childWidth );
15711561 }
15721562 }
@@ -1575,10 +1565,10 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
15751565 childHeight = currentAbsoluteChild -> style .dimensions [CSSDimensionHeight ] + getMarginAxis (currentAbsoluteChild , CSSFlexDirectionColumn );
15761566 } else {
15771567 // If the child doesn't have a specified height, compute the height based on the top/bottom offsets if they're defined.
1578- if (isPosDefined (currentAbsoluteChild , CSSPositionTop ) && isPosDefined (currentAbsoluteChild , CSSPositionBottom )) {
1568+ if (isLeadingPosDefined (currentAbsoluteChild , CSSFlexDirectionColumn ) && isTrailingPosDefined (currentAbsoluteChild , CSSFlexDirectionColumn )) {
15791569 childHeight = node -> layout .measuredDimensions [CSSDimensionHeight ] -
15801570 (getLeadingBorder (node , CSSFlexDirectionColumn ) + getTrailingBorder (node , CSSFlexDirectionColumn )) -
1581- (currentAbsoluteChild -> style . position [ CSSPositionTop ] + currentAbsoluteChild -> style . position [ CSSPositionBottom ] );
1571+ (getLeadingPosition ( currentAbsoluteChild , CSSFlexDirectionColumn ) + getTrailingPosition ( currentAbsoluteChild , CSSFlexDirectionColumn ) );
15821572 childHeight = boundAxis (currentAbsoluteChild , CSSFlexDirectionColumn , childHeight );
15831573 }
15841574 }
@@ -1613,25 +1603,56 @@ static void layoutNodeImpl(CSSNode* node, float availableWidth, float availableH
16131603
16141604 layoutNodeInternal (currentAbsoluteChild , childWidth , childHeight , direction , CSSMeasureModeExactly , CSSMeasureModeExactly , true, "abs-layout" );
16151605
1616- if (isPosDefined (currentAbsoluteChild , trailing [ CSSFlexDirectionRow ] ) &&
1617- !isPosDefined (currentAbsoluteChild , leading [ CSSFlexDirectionRow ] )) {
1618- currentAbsoluteChild -> layout .position [leading [CSSFlexDirectionRow ]] =
1619- node -> layout .measuredDimensions [dim [CSSFlexDirectionRow ]] -
1620- currentAbsoluteChild -> layout .measuredDimensions [dim [CSSFlexDirectionRow ]] -
1621- getPosition (currentAbsoluteChild , trailing [ CSSFlexDirectionRow ] );
1606+ if (isTrailingPosDefined (currentAbsoluteChild , mainAxis ) &&
1607+ !isLeadingPosDefined (currentAbsoluteChild , mainAxis )) {
1608+ currentAbsoluteChild -> layout .position [leading [mainAxis ]] =
1609+ node -> layout .measuredDimensions [dim [mainAxis ]] -
1610+ currentAbsoluteChild -> layout .measuredDimensions [dim [mainAxis ]] -
1611+ getTrailingPosition (currentAbsoluteChild , mainAxis );
16221612 }
16231613
1624- if (isPosDefined (currentAbsoluteChild , trailing [ CSSFlexDirectionColumn ] ) &&
1625- !isPosDefined (currentAbsoluteChild , leading [ CSSFlexDirectionColumn ] )) {
1626- currentAbsoluteChild -> layout .position [leading [CSSFlexDirectionColumn ]] =
1627- node -> layout .measuredDimensions [dim [CSSFlexDirectionColumn ]] -
1628- currentAbsoluteChild -> layout .measuredDimensions [dim [CSSFlexDirectionColumn ]] -
1629- getPosition (currentAbsoluteChild , trailing [ CSSFlexDirectionColumn ] );
1614+ if (isTrailingPosDefined (currentAbsoluteChild , crossAxis ) &&
1615+ !isLeadingPosDefined (currentAbsoluteChild , crossAxis )) {
1616+ currentAbsoluteChild -> layout .position [leading [crossAxis ]] =
1617+ node -> layout .measuredDimensions [dim [crossAxis ]] -
1618+ currentAbsoluteChild -> layout .measuredDimensions [dim [crossAxis ]] -
1619+ getTrailingPosition (currentAbsoluteChild , crossAxis );
16301620 }
16311621 }
16321622
16331623 currentAbsoluteChild = currentAbsoluteChild -> nextChild ;
16341624 }
1625+
1626+ // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
1627+ if (performLayout ) {
1628+ bool needsMainTrailingPos = false;
1629+ bool needsCrossTrailingPos = false;
1630+
1631+ if (mainAxis == CSSFlexDirectionRowReverse ||
1632+ mainAxis == CSSFlexDirectionColumnReverse ) {
1633+ needsMainTrailingPos = true;
1634+ }
1635+
1636+ if (crossAxis == CSSFlexDirectionRowReverse ||
1637+ crossAxis == CSSFlexDirectionColumnReverse ) {
1638+ needsCrossTrailingPos = true;
1639+ }
1640+
1641+ // Set trailing position if necessary.
1642+ if (needsMainTrailingPos || needsCrossTrailingPos ) {
1643+ for (i = 0 ; i < childCount ; ++ i ) {
1644+ child = CSSNodeListGet (node -> children , i );
1645+
1646+ if (needsMainTrailingPos ) {
1647+ setTrailingPosition (node , child , mainAxis );
1648+ }
1649+
1650+ if (needsCrossTrailingPos ) {
1651+ setTrailingPosition (node , child , crossAxis );
1652+ }
1653+ }
1654+ }
1655+ }
16351656}
16361657
16371658int gDepth = 0 ;
0 commit comments