diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index d2d56b7d20..dc9f785eac 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -54,8 +54,7 @@ static inline float dimensionWithMargin( const FlexDirection axis, const float widthSize) { return node->getLayout().measuredDimension(dimension(axis)) + - (node->getLeadingMargin(axis, widthSize) + - node->getTrailingMargin(axis, widthSize)); + node->getMarginForAxis(axis, widthSize); } static inline bool styleDefinesDimension( @@ -453,7 +452,8 @@ static void layoutAbsoluteChild( node->getLayout().measuredDimension(dimension(mainAxis)) - child->getLayout().measuredDimension(dimension(mainAxis)) - node->getTrailingBorder(mainAxis) - - child->getTrailingMargin(mainAxis, isMainAxisRow ? width : height) - + child->getTrailingMargin( + mainAxis, direction, isMainAxisRow ? width : height) - child->getTrailingPosition( mainAxis, isMainAxisRow ? width : height), leadingEdge(mainAxis)); @@ -483,6 +483,7 @@ static void layoutAbsoluteChild( node->getLeadingBorder(mainAxis) + child->getLeadingMargin( mainAxis, + direction, node->getLayout().measuredDimension(dimension(mainAxis))), leadingEdge(mainAxis)); } @@ -494,7 +495,7 @@ static void layoutAbsoluteChild( child->getLayout().measuredDimension(dimension(crossAxis)) - node->getTrailingBorder(crossAxis) - child->getTrailingMargin( - crossAxis, isMainAxisRow ? height : width) - + crossAxis, direction, isMainAxisRow ? height : width) - child->getTrailingPosition( crossAxis, isMainAxisRow ? height : width), leadingEdge(crossAxis)); @@ -526,6 +527,7 @@ static void layoutAbsoluteChild( node->getLeadingBorder(crossAxis) + child->getLeadingMargin( crossAxis, + direction, node->getLayout().measuredDimension(dimension(crossAxis))), leadingEdge(crossAxis)); } @@ -1186,6 +1188,7 @@ static void justifyMainAxis( const size_t startOfLineIndex, const FlexDirection mainAxis, const FlexDirection crossAxis, + const Direction direction, const MeasureMode measureModeMainDim, const MeasureMode measureModeCrossDim, const float mainAxisownerSize, @@ -1303,7 +1306,8 @@ static void justifyMainAxis( child->setLayoutPosition( child->getLeadingPosition(mainAxis, availableInnerMainDim) + node->getLeadingBorder(mainAxis) + - child->getLeadingMargin(mainAxis, availableInnerWidth), + child->getLeadingMargin( + mainAxis, direction, availableInnerWidth), leadingEdge(mainAxis)); } } else { @@ -1352,7 +1356,7 @@ static void justifyMainAxis( // calculated by adding maxAscent and maxDescent from the baseline. const float ascent = calculateBaseline(child) + child->getLeadingMargin( - FlexDirection::Column, availableInnerWidth); + FlexDirection::Column, direction, availableInnerWidth); const float descent = child->getLayout().measuredDimension(Dimension::Height) + child->getMarginForAxis( @@ -1498,16 +1502,16 @@ static void calculateLayoutImpl( const YGEdge endEdge = direction == Direction::LTR ? YGEdgeRight : YGEdgeLeft; const float marginRowLeading = - node->getLeadingMargin(flexRowDirection, ownerWidth); + node->getLeadingMargin(flexRowDirection, direction, ownerWidth); node->setLayoutMargin(marginRowLeading, startEdge); const float marginRowTrailing = - node->getTrailingMargin(flexRowDirection, ownerWidth); + node->getTrailingMargin(flexRowDirection, direction, ownerWidth); node->setLayoutMargin(marginRowTrailing, endEdge); const float marginColumnLeading = - node->getLeadingMargin(flexColumnDirection, ownerWidth); + node->getLeadingMargin(flexColumnDirection, direction, ownerWidth); node->setLayoutMargin(marginColumnLeading, YGEdgeTop); const float marginColumnTrailing = - node->getTrailingMargin(flexColumnDirection, ownerWidth); + node->getTrailingMargin(flexColumnDirection, direction, ownerWidth); node->setLayoutMargin(marginColumnTrailing, YGEdgeBottom); const float marginAxisRow = marginRowLeading + marginRowTrailing; @@ -1793,6 +1797,7 @@ static void calculateLayoutImpl( startOfLineIndex, mainAxis, crossAxis, + direction, measureModeMainDim, measureModeCrossDim, mainAxisownerSize, @@ -1849,7 +1854,8 @@ static void calculateLayoutImpl( child->setLayoutPosition( child->getLeadingPosition(crossAxis, availableInnerCrossDim) + node->getLeadingBorder(crossAxis) + - child->getLeadingMargin(crossAxis, availableInnerWidth), + child->getLeadingMargin( + crossAxis, direction, availableInnerWidth), leadingEdge(crossAxis)); } // If leading position is not defined or calculations result in Nan, @@ -1859,7 +1865,8 @@ static void calculateLayoutImpl( child->getLayout().position[leadingEdge(crossAxis)])) { child->setLayoutPosition( node->getLeadingBorder(crossAxis) + - child->getLeadingMargin(crossAxis, availableInnerWidth), + child->getLeadingMargin( + crossAxis, direction, availableInnerWidth), leadingEdge(crossAxis)); } } else { @@ -2053,7 +2060,7 @@ static void calculateLayoutImpl( if (resolveChildAlignment(node, child) == Align::Baseline) { const float ascent = calculateBaseline(child) + child->getLeadingMargin( - FlexDirection::Column, availableInnerWidth); + FlexDirection::Column, direction, availableInnerWidth); const float descent = child->getLayout().measuredDimension(Dimension::Height) + child->getMarginForAxis( @@ -2083,7 +2090,8 @@ static void calculateLayoutImpl( case Align::FlexStart: { child->setLayoutPosition( currentLead + - child->getLeadingMargin(crossAxis, availableInnerWidth), + child->getLeadingMargin( + crossAxis, direction, availableInnerWidth), leadingEdge(crossAxis)); break; } @@ -2091,7 +2099,7 @@ static void calculateLayoutImpl( child->setLayoutPosition( currentLead + lineHeight - child->getTrailingMargin( - crossAxis, availableInnerWidth) - + crossAxis, direction, availableInnerWidth) - child->getLayout().measuredDimension( dimension(crossAxis)), leadingEdge(crossAxis)); @@ -2109,7 +2117,8 @@ static void calculateLayoutImpl( case Align::Stretch: { child->setLayoutPosition( currentLead + - child->getLeadingMargin(crossAxis, availableInnerWidth), + child->getLeadingMargin( + crossAxis, direction, availableInnerWidth), leadingEdge(crossAxis)); // Remeasure child with the line height as it as been only diff --git a/yoga/algorithm/FlexDirection.h b/yoga/algorithm/FlexDirection.h index 010bfed409..7dd2b4cce7 100644 --- a/yoga/algorithm/FlexDirection.h +++ b/yoga/algorithm/FlexDirection.h @@ -77,6 +77,26 @@ inline YGEdge trailingEdge(const FlexDirection flexDirection) { fatalWithMessage("Invalid FlexDirection"); } +inline YGEdge leadingLayoutEdge( + const FlexDirection flexDirection, + const Direction direction) { + if (isRow(flexDirection)) { + return direction == Direction::RTL ? YGEdgeRight : YGEdgeLeft; + } + + return YGEdgeTop; +} + +inline YGEdge trailingLayoutEdge( + const FlexDirection flexDirection, + const Direction direction) { + if (isRow(flexDirection)) { + return direction == Direction::RTL ? YGEdgeLeft : YGEdgeRight; + } + + return YGEdgeBottom; +} + inline Dimension dimension(const FlexDirection flexDirection) { switch (flexDirection) { case FlexDirection::Column: diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index d84aac542f..c7cee82930 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -83,6 +83,22 @@ CompactValue Node::computeEdgeValueForColumn( } } +YGEdge Node::getLeadingLayoutEdgeUsingErrata( + FlexDirection flexDirection, + Direction direction) const { + return hasErrata(Errata::StartingEndingEdgeFromFlexDirection) + ? leadingEdge(flexDirection) + : leadingLayoutEdge(flexDirection, direction); +} + +YGEdge Node::getTrailingLayoutEdgeUsingErrata( + FlexDirection flexDirection, + Direction direction) const { + return hasErrata(Errata::StartingEndingEdgeFromFlexDirection) + ? trailingEdge(flexDirection) + : trailingLayoutEdge(flexDirection, direction); +} + bool Node::isLeadingPositionDefined(FlexDirection axis) const { auto leadingPosition = isRow(axis) ? computeEdgeValueForRow( @@ -117,18 +133,26 @@ float Node::getTrailingPosition(FlexDirection axis, float axisSize) const { return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f); } -float Node::getLeadingMargin(FlexDirection axis, float widthSize) const { +float Node::getLeadingMargin( + FlexDirection axis, + Direction direction, + float widthSize) const { + const YGEdge startEdge = getLeadingLayoutEdgeUsingErrata(axis, direction); auto leadingMargin = isRow(axis) - ? computeEdgeValueForRow(style_.margin(), YGEdgeStart, leadingEdge(axis)) - : computeEdgeValueForColumn(style_.margin(), leadingEdge(axis)); + ? computeEdgeValueForRow(style_.margin(), YGEdgeStart, startEdge) + : computeEdgeValueForColumn(style_.margin(), startEdge); return resolveValue(leadingMargin, widthSize).unwrapOrDefault(0.0f); } -float Node::getTrailingMargin(FlexDirection axis, float widthSize) const { +float Node::getTrailingMargin( + FlexDirection axis, + Direction direction, + float widthSize) const { + const YGEdge endEdge = getTrailingLayoutEdgeUsingErrata(axis, direction); auto trailingMargin = isRow(axis) - ? computeEdgeValueForRow(style_.margin(), YGEdgeEnd, trailingEdge(axis)) - : computeEdgeValueForColumn(style_.margin(), trailingEdge(axis)); + ? computeEdgeValueForRow(style_.margin(), YGEdgeEnd, endEdge) + : computeEdgeValueForColumn(style_.margin(), endEdge); return resolveValue(trailingMargin, widthSize).unwrapOrDefault(0.0f); } @@ -176,7 +200,10 @@ float Node::getTrailingPaddingAndBorder(FlexDirection axis, float widthSize) } float Node::getMarginForAxis(FlexDirection axis, float widthSize) const { - return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); + // The total margin for a given axis does not depend on the direction + // so hardcoding LTR here to avoid piping direction to this function + return getLeadingMargin(axis, Direction::LTR, widthSize) + + getTrailingMargin(axis, Direction::LTR, widthSize); } float Node::getGapForAxis(FlexDirection axis) const { @@ -360,18 +387,31 @@ void Node::setPosition( const float relativePositionMain = relativePosition(mainAxis, mainSize); const float relativePositionCross = relativePosition(crossAxis, crossSize); + const YGEdge mainAxisLeadingEdge = + getLeadingLayoutEdgeUsingErrata(mainAxis, direction); + const YGEdge mainAxisTrailingEdge = + getTrailingLayoutEdgeUsingErrata(mainAxis, direction); + const YGEdge crossAxisLeadingEdge = + getLeadingLayoutEdgeUsingErrata(crossAxis, direction); + const YGEdge crossAxisTrailingEdge = + getTrailingLayoutEdgeUsingErrata(crossAxis, direction); + setLayoutPosition( - (getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain), - leadingEdge(mainAxis)); + (getLeadingMargin(mainAxis, direction, ownerWidth) + + relativePositionMain), + mainAxisLeadingEdge); setLayoutPosition( - (getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain), - trailingEdge(mainAxis)); + (getTrailingMargin(mainAxis, direction, ownerWidth) + + relativePositionMain), + mainAxisTrailingEdge); setLayoutPosition( - (getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross), - leadingEdge(crossAxis)); + (getLeadingMargin(crossAxis, direction, ownerWidth) + + relativePositionCross), + crossAxisLeadingEdge); setLayoutPosition( - (getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross), - trailingEdge(crossAxis)); + (getTrailingMargin(crossAxis, direction, ownerWidth) + + relativePositionCross), + crossAxisTrailingEdge); } YGValue Node::marginLeadingValue(FlexDirection axis) const { diff --git a/yoga/node/Node.h b/yoga/node/Node.h index bf1f89f332..4aaf0f7b3c 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -50,6 +50,13 @@ class YG_EXPORT Node : public ::YGNode { float relativePosition(FlexDirection axis, const float axisSize) const; + YGEdge getLeadingLayoutEdgeUsingErrata( + FlexDirection flexDirection, + Direction direction) const; + YGEdge getTrailingLayoutEdgeUsingErrata( + FlexDirection flexDirection, + Direction direction) const; + void useWebDefaults() { style_.flexDirection() = FlexDirection::Row; style_.alignContent() = Align::Stretch; @@ -193,8 +200,14 @@ class YG_EXPORT Node : public ::YGNode { bool isTrailingPosDefined(FlexDirection axis) const; float getLeadingPosition(FlexDirection axis, float axisSize) const; float getTrailingPosition(FlexDirection axis, float axisSize) const; - float getLeadingMargin(FlexDirection axis, float widthSize) const; - float getTrailingMargin(FlexDirection axis, float widthSize) const; + float getLeadingMargin( + FlexDirection axis, + Direction direction, + float widthSize) const; + float getTrailingMargin( + FlexDirection axis, + Direction direction, + float widthSize) const; float getLeadingBorder(FlexDirection flexDirection) const; float getTrailingBorder(FlexDirection flexDirection) const; float getLeadingPadding(FlexDirection axis, float widthSize) const;