diff --git a/yoga/YGNodeLayout.cpp b/yoga/YGNodeLayout.cpp index d2477f72..93fcf0ad 100644 --- a/yoga/YGNodeLayout.cpp +++ b/yoga/YGNodeLayout.cpp @@ -25,39 +25,39 @@ float getResolvedLayoutProperty(const YGNodeConstRef nodeRef, const Edge edge) { if (edge == Edge::Start) { if (node->getLayout().direction() == Direction::RTL) { - return (node->getLayout().*LayoutMember)(Edge::Right); + return (node->getLayout().*LayoutMember)(PhysicalEdge::Right); } else { - return (node->getLayout().*LayoutMember)(Edge::Left); + return (node->getLayout().*LayoutMember)(PhysicalEdge::Left); } } if (edge == Edge::End) { if (node->getLayout().direction() == Direction::RTL) { - return (node->getLayout().*LayoutMember)(Edge::Left); + return (node->getLayout().*LayoutMember)(PhysicalEdge::Left); } else { - return (node->getLayout().*LayoutMember)(Edge::Right); + return (node->getLayout().*LayoutMember)(PhysicalEdge::Right); } } - return (node->getLayout().*LayoutMember)(edge); + return (node->getLayout().*LayoutMember)(static_cast(edge)); } } // namespace float YGNodeLayoutGetLeft(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position(Edge::Left); + return resolveRef(node)->getLayout().position(PhysicalEdge::Left); } float YGNodeLayoutGetTop(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position(Edge::Top); + return resolveRef(node)->getLayout().position(PhysicalEdge::Top); } float YGNodeLayoutGetRight(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position(Edge::Right); + return resolveRef(node)->getLayout().position(PhysicalEdge::Right); } float YGNodeLayoutGetBottom(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position(Edge::Bottom); + return resolveRef(node)->getLayout().position(PhysicalEdge::Bottom); } float YGNodeLayoutGetWidth(const YGNodeConstRef node) { diff --git a/yoga/algorithm/AbsoluteLayout.cpp b/yoga/algorithm/AbsoluteLayout.cpp index 163569e4..ccec8f18 100644 --- a/yoga/algorithm/AbsoluteLayout.cpp +++ b/yoga/algorithm/AbsoluteLayout.cpp @@ -20,7 +20,8 @@ static inline void setFlexStartLayoutPosition( const FlexDirection axis, const float containingBlockWidth) { child->setLayoutPosition( - child->getFlexStartMargin(axis, direction, containingBlockWidth) + + child->style().computeFlexStartMargin( + axis, direction, containingBlockWidth) + parent->getLayout().border(flexStartEdge(axis)) + parent->getLayout().padding(flexStartEdge(axis)), flexStartEdge(axis)); @@ -36,7 +37,8 @@ static inline void setFlexEndLayoutPosition( getPositionOfOppositeEdge( parent->getLayout().border(flexEndEdge(axis)) + parent->getLayout().padding(flexEndEdge(axis)) + - child->getFlexEndMargin(axis, direction, containingBlockWidth), + child->style().computeFlexEndMargin( + axis, direction, containingBlockWidth), axis, parent, child), @@ -57,12 +59,13 @@ static inline void setCenterLayoutPosition( parent->getLayout().padding(flexEndEdge(axis)); const float childOuterSize = child->getLayout().measuredDimension(dimension(axis)) + - child->getMarginForAxis(axis, containingBlockWidth); + child->style().computeMarginForAxis(axis, containingBlockWidth); child->setLayoutPosition( (parentContentBoxSize - childOuterSize) / 2.0f + parent->getLayout().border(flexStartEdge(axis)) + parent->getLayout().padding(flexStartEdge(axis)) + - child->getFlexStartMargin(axis, direction, containingBlockWidth), + child->style().computeFlexStartMargin( + axis, direction, containingBlockWidth), flexStartEdge(axis)); } @@ -150,30 +153,32 @@ static void positionAbsoluteChildLegacy( : ((resolveChildAlignment(parent, child) == Align::FlexEnd) ^ (parent->style().flexWrap() == Wrap::WrapReverse)); - if (child->isFlexEndPositionDefined(axis, direction) && - !child->isFlexStartPositionDefined(axis, direction)) { + if (child->style().isFlexEndPositionDefined(axis, direction) && + !child->style().isFlexStartPositionDefined(axis, direction)) { child->setLayoutPosition( containingNode->getLayout().measuredDimension(dimension(axis)) - child->getLayout().measuredDimension(dimension(axis)) - - containingNode->getFlexEndBorder(axis, direction) - - child->getFlexEndMargin( + containingNode->style().computeFlexEndBorder(axis, direction) - + child->style().computeFlexEndMargin( axis, direction, isAxisRow ? containingBlockWidth : containingBlockHeight) - - child->getFlexEndPosition( + child->style().computeFlexEndPosition( axis, direction, isAxisRow ? containingBlockWidth : containingBlockHeight), flexStartEdge(axis)); } else if ( - !child->isFlexStartPositionDefined(axis, direction) && shouldCenter) { + !child->style().isFlexStartPositionDefined(axis, direction) && + shouldCenter) { child->setLayoutPosition( (parent->getLayout().measuredDimension(dimension(axis)) - child->getLayout().measuredDimension(dimension(axis))) / 2.0f, flexStartEdge(axis)); } else if ( - !child->isFlexStartPositionDefined(axis, direction) && shouldFlexEnd) { + !child->style().isFlexStartPositionDefined(axis, direction) && + shouldFlexEnd) { child->setLayoutPosition( (parent->getLayout().measuredDimension(dimension(axis)) - child->getLayout().measuredDimension(dimension(axis))), @@ -218,11 +223,13 @@ static void positionAbsoluteChildImpl( // to the flex-start edge because this algorithm works by positioning on the // flex-start edge and then filling in the flex-end direction at the end if // necessary. - if (child->isInlineStartPositionDefined(axis, direction)) { + if (child->style().isInlineStartPositionDefined(axis, direction)) { const float positionRelativeToInlineStart = - child->getInlineStartPosition(axis, direction, containingBlockSize) + - containingNode->getInlineStartBorder(axis, direction) + - child->getInlineStartMargin(axis, direction, containingBlockSize); + child->style().computeInlineStartPosition( + axis, direction, containingBlockSize) + + containingNode->style().computeInlineStartBorder(axis, direction) + + child->style().computeInlineStartMargin( + axis, direction, containingBlockSize); const float positionRelativeToFlexStart = inlineStartEdge(axis, direction) != flexStartEdge(axis) ? getPositionOfOppositeEdge( @@ -230,13 +237,15 @@ static void positionAbsoluteChildImpl( : positionRelativeToInlineStart; child->setLayoutPosition(positionRelativeToFlexStart, flexStartEdge(axis)); - } else if (child->isInlineEndPositionDefined(axis, direction)) { + } else if (child->style().isInlineEndPositionDefined(axis, direction)) { const float positionRelativeToInlineStart = containingNode->getLayout().measuredDimension(dimension(axis)) - child->getLayout().measuredDimension(dimension(axis)) - - containingNode->getInlineEndBorder(axis, direction) - - child->getInlineEndMargin(axis, direction, containingBlockSize) - - child->getInlineEndPosition(axis, direction, containingBlockSize); + containingNode->style().computeInlineEndBorder(axis, direction) - + child->style().computeInlineEndMargin( + axis, direction, containingBlockSize) - + child->style().computeInlineEndPosition( + axis, direction, containingBlockSize); const float positionRelativeToFlexStart = inlineStartEdge(axis, direction) != flexStartEdge(axis) ? getPositionOfOppositeEdge( @@ -303,10 +312,10 @@ void layoutAbsoluteChild( SizingMode childWidthSizingMode = SizingMode::MaxContent; SizingMode childHeightSizingMode = SizingMode::MaxContent; - auto marginRow = - child->getMarginForAxis(FlexDirection::Row, containingBlockWidth); - auto marginColumn = - child->getMarginForAxis(FlexDirection::Column, containingBlockWidth); + auto marginRow = child->style().computeMarginForAxis( + FlexDirection::Row, containingBlockWidth); + auto marginColumn = child->style().computeMarginForAxis( + FlexDirection::Column, containingBlockWidth); if (child->hasDefiniteLength(Dimension::Width, containingBlockWidth)) { childWidth = child->getResolvedDimension(Dimension::Width) @@ -316,15 +325,19 @@ void layoutAbsoluteChild( } else { // If the child doesn't have a specified width, compute the width based on // the left/right offsets if they're defined. - if (child->isFlexStartPositionDefined(FlexDirection::Row, direction) && - child->isFlexEndPositionDefined(FlexDirection::Row, direction)) { + if (child->style().isFlexStartPositionDefined( + FlexDirection::Row, direction) && + child->style().isFlexEndPositionDefined( + FlexDirection::Row, direction)) { childWidth = containingNode->getLayout().measuredDimension(Dimension::Width) - - (containingNode->getFlexStartBorder(FlexDirection::Row, direction) + - containingNode->getFlexEndBorder(FlexDirection::Row, direction)) - - (child->getFlexStartPosition( + (containingNode->style().computeFlexStartBorder( + FlexDirection::Row, direction) + + containingNode->style().computeFlexEndBorder( + FlexDirection::Row, direction)) - + (child->style().computeFlexStartPosition( FlexDirection::Row, direction, containingBlockWidth) + - child->getFlexEndPosition( + child->style().computeFlexEndPosition( FlexDirection::Row, direction, containingBlockWidth)); childWidth = boundAxis( child, @@ -343,16 +356,19 @@ void layoutAbsoluteChild( } else { // If the child doesn't have a specified height, compute the height based // on the top/bottom offsets if they're defined. - if (child->isFlexStartPositionDefined(FlexDirection::Column, direction) && - child->isFlexEndPositionDefined(FlexDirection::Column, direction)) { + if (child->style().isFlexStartPositionDefined( + FlexDirection::Column, direction) && + child->style().isFlexEndPositionDefined( + FlexDirection::Column, direction)) { childHeight = containingNode->getLayout().measuredDimension(Dimension::Height) - - (containingNode->getFlexStartBorder( + (containingNode->style().computeFlexStartBorder( FlexDirection::Column, direction) + - containingNode->getFlexEndBorder(FlexDirection::Column, direction)) - - (child->getFlexStartPosition( + containingNode->style().computeFlexEndBorder( + FlexDirection::Column, direction)) - + (child->style().computeFlexStartPosition( FlexDirection::Column, direction, containingBlockHeight) + - child->getFlexEndPosition( + child->style().computeFlexEndPosition( FlexDirection::Column, direction, containingBlockHeight)); childHeight = boundAxis( child, @@ -414,9 +430,11 @@ void layoutAbsoluteChild( depth, generationCount); childWidth = child->getLayout().measuredDimension(Dimension::Width) + - child->getMarginForAxis(FlexDirection::Row, containingBlockWidth); + child->style().computeMarginForAxis( + FlexDirection::Row, containingBlockWidth); childHeight = child->getLayout().measuredDimension(Dimension::Height) + - child->getMarginForAxis(FlexDirection::Column, containingBlockWidth); + child->style().computeMarginForAxis( + FlexDirection::Column, containingBlockWidth); } calculateLayoutInternal( @@ -479,11 +497,12 @@ void layoutAbsoluteDescendants( const float containingBlockWidth = absoluteErrata ? containingNodeAvailableInnerWidth : containingNode->getLayout().measuredDimension(Dimension::Width) - - containingNode->getBorderForAxis(FlexDirection::Row); + containingNode->style().computeBorderForAxis(FlexDirection::Row); const float containingBlockHeight = absoluteErrata ? containingNodeAvailableInnerHeight : containingNode->getLayout().measuredDimension(Dimension::Height) - - containingNode->getBorderForAxis(FlexDirection::Column); + containingNode->style().computeBorderForAxis( + FlexDirection::Column); layoutAbsoluteChild( containingNode, diff --git a/yoga/algorithm/Baseline.cpp b/yoga/algorithm/Baseline.cpp index 297b0522..61cf7dd1 100644 --- a/yoga/algorithm/Baseline.cpp +++ b/yoga/algorithm/Baseline.cpp @@ -57,7 +57,7 @@ float calculateBaseline(const yoga::Node* node) { } const float baseline = calculateBaseline(baselineChild); - return baseline + baselineChild->getLayout().position(Edge::Top); + return baseline + baselineChild->getLayout().position(PhysicalEdge::Top); } bool isBaselineLayout(const yoga::Node* node) { diff --git a/yoga/algorithm/BoundAxis.h b/yoga/algorithm/BoundAxis.h index 7b5144d0..482a7374 100644 --- a/yoga/algorithm/BoundAxis.h +++ b/yoga/algorithm/BoundAxis.h @@ -22,8 +22,10 @@ inline float paddingAndBorderForAxis( const float widthSize) { // The total padding/border for a given axis does not depend on the direction // so hardcoding LTR here to avoid piping direction to this function - return node->getInlineStartPaddingAndBorder(axis, Direction::LTR, widthSize) + - node->getInlineEndPaddingAndBorder(axis, Direction::LTR, widthSize); + return node->style().computeInlineStartPaddingAndBorder( + axis, Direction::LTR, widthSize) + + node->style().computeInlineEndPaddingAndBorder( + axis, Direction::LTR, widthSize); } inline FloatOptional boundAxisWithinMinAndMax( diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 24e0f491..4bc2ad69 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -45,7 +45,7 @@ static void constrainMaxSizeForMode( /*in_out*/ float* size) { const FloatOptional maxSize = node->style().maxDimension(dimension(axis)).resolve(ownerAxisSize) + - FloatOptional(node->getMarginForAxis(axis, ownerWidth)); + FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth)); switch (*mode) { case SizingMode::StretchFit: case SizingMode::FitContent: @@ -126,9 +126,10 @@ static void computeFlexBasisForChild( childWidthSizingMode = SizingMode::MaxContent; childHeightSizingMode = SizingMode::MaxContent; - auto marginRow = child->getMarginForAxis(FlexDirection::Row, ownerWidth); + auto marginRow = + child->style().computeMarginForAxis(FlexDirection::Row, ownerWidth); auto marginColumn = - child->getMarginForAxis(FlexDirection::Column, ownerWidth); + child->style().computeMarginForAxis(FlexDirection::Column, ownerWidth); if (isRowStyleDimDefined) { childWidth = child->getResolvedDimension(Dimension::Width) @@ -274,12 +275,12 @@ static void measureNodeWithMeasureFunc( } const auto& layout = node->getLayout(); - const float paddingAndBorderAxisRow = layout.padding(Edge::Left) + - layout.padding(Edge::Right) + layout.border(Edge::Left) + - layout.border(Edge::Right); - const float paddingAndBorderAxisColumn = layout.padding(Edge::Top) + - layout.padding(Edge::Bottom) + layout.border(Edge::Top) + - layout.border(Edge::Bottom); + const float paddingAndBorderAxisRow = layout.padding(PhysicalEdge::Left) + + layout.padding(PhysicalEdge::Right) + layout.border(PhysicalEdge::Left) + + layout.border(PhysicalEdge::Right); + const float paddingAndBorderAxisColumn = layout.padding(PhysicalEdge::Top) + + layout.padding(PhysicalEdge::Bottom) + layout.border(PhysicalEdge::Top) + + layout.border(PhysicalEdge::Bottom); // We want to make sure we don't call measure with negative size const float innerWidth = yoga::isUndefined(availableWidth) @@ -369,8 +370,9 @@ static void measureNodeWithoutChildren( float width = availableWidth; if (widthSizingMode == SizingMode::MaxContent || widthSizingMode == SizingMode::FitContent) { - width = layout.padding(Edge::Left) + layout.padding(Edge::Right) + - layout.border(Edge::Left) + layout.border(Edge::Right); + width = layout.padding(PhysicalEdge::Left) + + layout.padding(PhysicalEdge::Right) + + layout.border(PhysicalEdge::Left) + layout.border(PhysicalEdge::Right); } node->setLayoutMeasuredDimension( boundAxis(node, FlexDirection::Row, width, ownerWidth, ownerWidth), @@ -379,8 +381,9 @@ static void measureNodeWithoutChildren( float height = availableHeight; if (heightSizingMode == SizingMode::MaxContent || heightSizingMode == SizingMode::FitContent) { - height = layout.padding(Edge::Top) + layout.padding(Edge::Bottom) + - layout.border(Edge::Top) + layout.border(Edge::Bottom); + height = layout.padding(PhysicalEdge::Top) + + layout.padding(PhysicalEdge::Bottom) + + layout.border(PhysicalEdge::Top) + layout.border(PhysicalEdge::Bottom); } node->setLayoutMeasuredDimension( boundAxis(node, FlexDirection::Column, height, ownerHeight, ownerWidth), @@ -555,7 +558,7 @@ static float computeFlexBasisForChildren( totalOuterFlexBasis += (child->getLayout().computedFlexBasis.unwrap() + - child->getMarginForAxis(mainAxis, availableInnerWidth)); + child->style().computeMarginForAxis(mainAxis, availableInnerWidth)); } return totalOuterFlexBasis; @@ -570,6 +573,7 @@ static float distributeFreeSpaceSecondPass( yoga::Node* const node, const FlexDirection mainAxis, const FlexDirection crossAxis, + const Direction direction, const float mainAxisownerSize, const float availableInnerMainDim, const float availableInnerCrossDim, @@ -642,10 +646,10 @@ static float distributeFreeSpaceSecondPass( deltaFreeSpace += updatedMainSize - childFlexBasis; - const float marginMain = - currentLineChild->getMarginForAxis(mainAxis, availableInnerWidth); - const float marginCross = - currentLineChild->getMarginForAxis(crossAxis, availableInnerWidth); + const float marginMain = currentLineChild->style().computeMarginForAxis( + mainAxis, availableInnerWidth); + const float marginCross = currentLineChild->style().computeMarginForAxis( + crossAxis, availableInnerWidth); float childCrossSize; float childMainSize = updatedMainSize + marginMain; @@ -667,9 +671,9 @@ static float distributeFreeSpaceSecondPass( sizingModeCrossDim == SizingMode::StretchFit && !(isNodeFlexWrap && mainAxisOverflows) && resolveChildAlignment(node, currentLineChild) == Align::Stretch && - currentLineChild->getFlexStartMarginValue(crossAxis).unit() != - Unit::Auto && - currentLineChild->marginTrailingValue(crossAxis).unit() != Unit::Auto) { + !currentLineChild->style().flexStartMarginIsAuto( + crossAxis, direction) && + !currentLineChild->style().flexEndMarginIsAuto(crossAxis, direction)) { childCrossSize = availableInnerCrossDim; childCrossSizingMode = SizingMode::StretchFit; } else if (!currentLineChild->hasDefiniteLength( @@ -713,9 +717,9 @@ static float distributeFreeSpaceSecondPass( !currentLineChild->hasDefiniteLength( dimension(crossAxis), availableInnerCrossDim) && resolveChildAlignment(node, currentLineChild) == Align::Stretch && - currentLineChild->getFlexStartMarginValue(crossAxis).unit() != - Unit::Auto && - currentLineChild->marginTrailingValue(crossAxis).unit() != Unit::Auto; + !currentLineChild->style().flexStartMarginIsAuto( + crossAxis, direction) && + !currentLineChild->style().flexEndMarginIsAuto(crossAxis, direction); const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; @@ -861,6 +865,7 @@ static void resolveFlexibleLength( FlexLine& flexLine, const FlexDirection mainAxis, const FlexDirection crossAxis, + const Direction direction, const float mainAxisownerSize, const float availableInnerMainDim, const float availableInnerCrossDim, @@ -887,6 +892,7 @@ static void resolveFlexibleLength( node, mainAxis, crossAxis, + direction, mainAxisownerSize, availableInnerMainDim, availableInnerCrossDim, @@ -920,11 +926,13 @@ static void justifyMainAxis( const auto& style = node->style(); const float leadingPaddingAndBorderMain = - node->getFlexStartPaddingAndBorder(mainAxis, direction, ownerWidth); + node->style().computeFlexStartPaddingAndBorder( + mainAxis, direction, ownerWidth); const float trailingPaddingAndBorderMain = - node->getFlexEndPaddingAndBorder(mainAxis, direction, ownerWidth); + node->style().computeFlexEndPaddingAndBorder( + mainAxis, direction, ownerWidth); - const float gap = node->getGapForAxis(mainAxis); + const float gap = node->style().computeGapForAxis(mainAxis); // If we are using "at most" rules in the main axis, make sure that // remainingFreeSpace is 0 when min main dimension is not given if (sizingModeMainDim == SizingMode::FitContent && @@ -957,10 +965,10 @@ static void justifyMainAxis( for (size_t i = startOfLineIndex; i < flexLine.endOfLineIndex; i++) { auto child = node->getChild(i); if (child->style().positionType() != PositionType::Absolute) { - if (child->getFlexStartMarginValue(mainAxis).unit() == Unit::Auto) { + if (child->style().flexStartMarginIsAuto(mainAxis, direction)) { numberOfAutoMarginsOnCurrentLine++; } - if (child->marginTrailingValue(mainAxis).unit() == Unit::Auto) { + if (child->style().flexEndMarginIsAuto(mainAxis, direction)) { numberOfAutoMarginsOnCurrentLine++; } } @@ -1019,17 +1027,18 @@ static void justifyMainAxis( continue; } if (childStyle.positionType() == PositionType::Absolute && - child->isInlineStartPositionDefined(mainAxis, direction)) { + child->style().isInlineStartPositionDefined(mainAxis, direction)) { if (performLayout) { // In case the child is position absolute and has left/top being // defined, we override the position to whatever the user said (and // margin/border). child->setLayoutPosition( - child->getInlineStartPosition( + child->style().computeInlineStartPosition( mainAxis, direction, availableInnerMainDim) + - node->getInlineStartBorder(mainAxis, direction) + - child->getInlineStartMargin( + node->style().computeInlineStartBorder(mainAxis, direction) + + child->style().computeInlineStartMargin( mainAxis, direction, availableInnerWidth), + // FIXME T175195745: Mismatched edge flexStartEdge(mainAxis)); } } else { @@ -1037,7 +1046,7 @@ static void justifyMainAxis( // We need to do that only for relative elements. Absolute elements do not // take part in that phase. if (childStyle.positionType() != PositionType::Absolute) { - if (child->getFlexStartMarginValue(mainAxis).unit() == Unit::Auto) { + if (child->style().flexStartMarginIsAuto(mainAxis, direction)) { flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / static_cast(numberOfAutoMarginsOnCurrentLine); } @@ -1053,7 +1062,7 @@ static void justifyMainAxis( flexLine.layout.mainDim += betweenMainDim; } - if (child->marginTrailingValue(mainAxis).unit() == Unit::Auto) { + if (child->style().flexEndMarginIsAuto(mainAxis, direction)) { flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / static_cast(numberOfAutoMarginsOnCurrentLine); } @@ -1063,8 +1072,8 @@ static void justifyMainAxis( // If we skipped the flex step, then we can't rely on the measuredDims // because they weren't computed. This means we can't call // dimensionWithMargin. - flexLine.layout.mainDim += - child->getMarginForAxis(mainAxis, availableInnerWidth) + + flexLine.layout.mainDim += child->style().computeMarginForAxis( + mainAxis, availableInnerWidth) + childLayout.computedFlexBasis.unwrap(); flexLine.layout.crossDim = availableInnerCrossDim; } else { @@ -1077,11 +1086,11 @@ static void justifyMainAxis( // If the child is baseline aligned then the cross dimension is // calculated by adding maxAscent and maxDescent from the baseline. const float ascent = calculateBaseline(child) + - child->getInlineStartMargin( + child->style().computeInlineStartMargin( FlexDirection::Column, direction, availableInnerWidth); const float descent = child->getLayout().measuredDimension(Dimension::Height) + - child->getMarginForAxis( + child->style().computeMarginForAxis( FlexDirection::Column, availableInnerWidth) - ascent; @@ -1101,7 +1110,7 @@ static void justifyMainAxis( } else if (performLayout) { child->setLayoutPosition( childLayout.position(flexStartEdge(mainAxis)) + - node->getInlineStartBorder(mainAxis, direction) + + node->style().computeFlexStartBorder(mainAxis, direction) + leadingMainDim, flexStartEdge(mainAxis)); } @@ -1211,46 +1220,56 @@ static void calculateLayoutImpl( const FlexDirection flexColumnDirection = resolveDirection(FlexDirection::Column, direction); - const Edge startEdge = direction == Direction::LTR ? Edge::Left : Edge::Right; - const Edge endEdge = direction == Direction::LTR ? Edge::Right : Edge::Left; + const auto startEdge = + direction == Direction::LTR ? PhysicalEdge::Left : PhysicalEdge::Right; + const auto endEdge = + direction == Direction::LTR ? PhysicalEdge::Right : PhysicalEdge::Left; - const float marginRowLeading = - node->getInlineStartMargin(flexRowDirection, direction, ownerWidth); + const float marginRowLeading = node->style().computeInlineStartMargin( + flexRowDirection, direction, ownerWidth); node->setLayoutMargin(marginRowLeading, startEdge); - const float marginRowTrailing = - node->getInlineEndMargin(flexRowDirection, direction, ownerWidth); + const float marginRowTrailing = node->style().computeInlineEndMargin( + flexRowDirection, direction, ownerWidth); node->setLayoutMargin(marginRowTrailing, endEdge); - const float marginColumnLeading = - node->getInlineStartMargin(flexColumnDirection, direction, ownerWidth); - node->setLayoutMargin(marginColumnLeading, Edge::Top); - const float marginColumnTrailing = - node->getInlineEndMargin(flexColumnDirection, direction, ownerWidth); - node->setLayoutMargin(marginColumnTrailing, Edge::Bottom); + const float marginColumnLeading = node->style().computeInlineStartMargin( + flexColumnDirection, direction, ownerWidth); + node->setLayoutMargin(marginColumnLeading, PhysicalEdge::Top); + const float marginColumnTrailing = node->style().computeInlineEndMargin( + flexColumnDirection, direction, ownerWidth); + node->setLayoutMargin(marginColumnTrailing, PhysicalEdge::Bottom); const float marginAxisRow = marginRowLeading + marginRowTrailing; const float marginAxisColumn = marginColumnLeading + marginColumnTrailing; node->setLayoutBorder( - node->getInlineStartBorder(flexRowDirection, direction), startEdge); + node->style().computeInlineStartBorder(flexRowDirection, direction), + startEdge); node->setLayoutBorder( - node->getInlineEndBorder(flexRowDirection, direction), endEdge); + node->style().computeInlineEndBorder(flexRowDirection, direction), + endEdge); node->setLayoutBorder( - node->getInlineStartBorder(flexColumnDirection, direction), Edge::Top); + node->style().computeInlineStartBorder(flexColumnDirection, direction), + PhysicalEdge::Top); node->setLayoutBorder( - node->getInlineEndBorder(flexColumnDirection, direction), Edge::Bottom); + node->style().computeInlineEndBorder(flexColumnDirection, direction), + PhysicalEdge::Bottom); node->setLayoutPadding( - node->getInlineStartPadding(flexRowDirection, direction, ownerWidth), + node->style().computeInlineStartPadding( + flexRowDirection, direction, ownerWidth), startEdge); node->setLayoutPadding( - node->getInlineEndPadding(flexRowDirection, direction, ownerWidth), + node->style().computeInlineEndPadding( + flexRowDirection, direction, ownerWidth), endEdge); node->setLayoutPadding( - node->getInlineStartPadding(flexColumnDirection, direction, ownerWidth), - Edge::Top); + node->style().computeInlineStartPadding( + flexColumnDirection, direction, ownerWidth), + PhysicalEdge::Top); node->setLayoutPadding( - node->getInlineEndPadding(flexColumnDirection, direction, ownerWidth), - Edge::Bottom); + node->style().computeInlineEndPadding( + flexColumnDirection, direction, ownerWidth), + PhysicalEdge::Bottom); if (node->hasMeasureFunc()) { measureNodeWithMeasureFunc( @@ -1314,7 +1333,8 @@ static void calculateLayoutImpl( const float paddingAndBorderAxisCross = paddingAndBorderForAxis(node, crossAxis, ownerWidth); const float leadingPaddingAndBorderCross = - node->getInlineStartPaddingAndBorder(crossAxis, direction, ownerWidth); + node->style().computeInlineStartPaddingAndBorder( + crossAxis, direction, ownerWidth); SizingMode sizingModeMainDim = isMainAxisRow ? widthSizingMode : heightSizingMode; @@ -1364,8 +1384,8 @@ static void calculateLayoutImpl( generationCount); if (childCount > 1) { - totalMainDim += - node->getGapForAxis(mainAxis) * static_cast(childCount - 1); + totalMainDim += node->style().computeGapForAxis(mainAxis) * + static_cast(childCount - 1); } const bool mainAxisOverflows = @@ -1388,7 +1408,7 @@ static void calculateLayoutImpl( // Accumulated cross dimensions of all lines so far. float totalLineCrossDim = 0; - const float crossAxisGap = node->getGapForAxis(crossAxis); + const float crossAxisGap = node->style().computeGapForAxis(crossAxis); // Max main dimension of all the lines. float maxLineMainDim = 0; @@ -1481,6 +1501,7 @@ static void calculateLayoutImpl( flexLine, mainAxis, crossAxis, + direction, mainAxisownerSize, availableInnerMainDim, availableInnerCrossDim, @@ -1568,14 +1589,16 @@ static void calculateLayoutImpl( // top/left/bottom/right set, override all the previously computed // positions to set it correctly. const bool isChildLeadingPosDefined = - child->isInlineStartPositionDefined(crossAxis, direction); + child->style().isInlineStartPositionDefined(crossAxis, direction); if (isChildLeadingPosDefined) { child->setLayoutPosition( - child->getInlineStartPosition( + child->style().computeInlineStartPosition( crossAxis, direction, availableInnerCrossDim) + - node->getInlineStartBorder(crossAxis, direction) + - child->getInlineStartMargin( + node->style().computeInlineStartBorder( + crossAxis, direction) + + child->style().computeInlineStartMargin( crossAxis, direction, availableInnerWidth), + // FIXME T175195745: Mismatched edge flexStartEdge(crossAxis)); } // If leading position is not defined or calculations result in Nan, @@ -1584,9 +1607,10 @@ static void calculateLayoutImpl( yoga::isUndefined( child->getLayout().position(flexStartEdge(crossAxis)))) { child->setLayoutPosition( - node->getInlineStartBorder(crossAxis, direction) + - child->getInlineStartMargin( + node->style().computeInlineStartBorder(crossAxis, direction) + + child->style().computeInlineStartMargin( crossAxis, direction, availableInnerWidth), + // FIXME T175195745: Mismatched edge flexStartEdge(crossAxis)); } } else { @@ -1601,8 +1625,8 @@ static void calculateLayoutImpl( // time, this time forcing the cross-axis size to be the computed // cross size for the current line. if (alignItem == Align::Stretch && - child->getFlexStartMarginValue(crossAxis).unit() != Unit::Auto && - child->marginTrailingValue(crossAxis).unit() != Unit::Auto) { + !child->style().flexStartMarginIsAuto(crossAxis, direction) && + !child->style().flexEndMarginIsAuto(crossAxis, direction)) { // If the child defines a definite size for its cross axis, there's // no need to stretch. if (!child->hasDefiniteLength( @@ -1611,14 +1635,15 @@ static void calculateLayoutImpl( child->getLayout().measuredDimension(dimension(mainAxis)); const auto& childStyle = child->style(); float childCrossSize = childStyle.aspectRatio().isDefined() - ? child->getMarginForAxis(crossAxis, availableInnerWidth) + + ? child->style().computeMarginForAxis( + crossAxis, availableInnerWidth) + (isMainAxisRow ? childMainSize / childStyle.aspectRatio().unwrap() : childMainSize * childStyle.aspectRatio().unwrap()) : flexLine.layout.crossDim; - childMainSize += - child->getMarginForAxis(mainAxis, availableInnerWidth); + childMainSize += child->style().computeMarginForAxis( + mainAxis, availableInnerWidth); SizingMode childMainSizingMode = SizingMode::StretchFit; SizingMode childCrossSizingMode = SizingMode::StretchFit; @@ -1675,17 +1700,15 @@ static void calculateLayoutImpl( const float remainingCrossDim = containerCrossAxis - child->dimensionWithMargin(crossAxis, availableInnerWidth); - if (child->getFlexStartMarginValue(crossAxis).unit() == - Unit::Auto && - child->marginTrailingValue(crossAxis).unit() == Unit::Auto) { + if (child->style().flexStartMarginIsAuto(crossAxis, direction) && + child->style().flexEndMarginIsAuto(crossAxis, direction)) { leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim / 2); - } else if ( - child->marginTrailingValue(crossAxis).unit() == Unit::Auto) { + } else if (child->style().flexEndMarginIsAuto( + crossAxis, direction)) { // No-Op - } else if ( - child->getFlexStartMarginValue(crossAxis).unit() == - Unit::Auto) { + } else if (child->style().flexStartMarginIsAuto( + crossAxis, direction)) { leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim); } else if (alignItem == Align::FlexStart) { // No-Op @@ -1795,15 +1818,16 @@ static void calculateLayoutImpl( lineHeight = yoga::maxOrDefined( lineHeight, child->getLayout().measuredDimension(dimension(crossAxis)) + - child->getMarginForAxis(crossAxis, availableInnerWidth)); + child->style().computeMarginForAxis( + crossAxis, availableInnerWidth)); } if (resolveChildAlignment(node, child) == Align::Baseline) { const float ascent = calculateBaseline(child) + - child->getInlineStartMargin( + child->style().computeInlineStartMargin( FlexDirection::Column, direction, availableInnerWidth); const float descent = child->getLayout().measuredDimension(Dimension::Height) + - child->getMarginForAxis( + child->style().computeMarginForAxis( FlexDirection::Column, availableInnerWidth) - ascent; maxAscentForCurrentLine = @@ -1829,18 +1853,20 @@ static void calculateLayoutImpl( case Align::FlexStart: { child->setLayoutPosition( currentLead + - child->getInlineStartMargin( + child->style().computeInlineStartMargin( crossAxis, direction, availableInnerWidth), + // FIXME T175195745: Mismatched edge flexStartEdge(crossAxis)); break; } case Align::FlexEnd: { child->setLayoutPosition( currentLead + lineHeight - - child->getInlineEndMargin( + child->style().computeInlineEndMargin( crossAxis, direction, availableInnerWidth) - child->getLayout().measuredDimension( dimension(crossAxis)), + // FIXME T175195745: Mismatched edge flexStartEdge(crossAxis)); break; } @@ -1856,8 +1882,9 @@ static void calculateLayoutImpl( case Align::Stretch: { child->setLayoutPosition( currentLead + - child->getInlineStartMargin( + child->style().computeInlineStartMargin( crossAxis, direction, availableInnerWidth), + // FIXME T175195745: Mismatched edge flexStartEdge(crossAxis)); // Remeasure child with the line height as it as been only @@ -1867,13 +1894,14 @@ static void calculateLayoutImpl( const float childWidth = isMainAxisRow ? (child->getLayout().measuredDimension( Dimension::Width) + - child->getMarginForAxis(mainAxis, availableInnerWidth)) + child->style().computeMarginForAxis( + mainAxis, availableInnerWidth)) : leadPerLine + lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout().measuredDimension( Dimension::Height) + - child->getMarginForAxis( + child->style().computeMarginForAxis( crossAxis, availableInnerWidth)) : leadPerLine + lineHeight; @@ -1907,11 +1935,11 @@ static void calculateLayoutImpl( child->setLayoutPosition( currentLead + maxAscentForCurrentLine - calculateBaseline(child) + - child->getInlineStartPosition( + child->style().computeInlineStartPosition( FlexDirection::Column, direction, availableInnerCrossDim), - Edge::Top); + PhysicalEdge::Top); break; } @@ -2123,9 +2151,9 @@ bool calculateLayoutInternal( // measurements if at all possible. if (node->hasMeasureFunc()) { const float marginAxisRow = - node->getMarginForAxis(FlexDirection::Row, ownerWidth); + node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth); const float marginAxisColumn = - node->getMarginForAxis(FlexDirection::Column, ownerWidth); + node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth); // First, try to use the layout cache. if (canUseCachedMeasurement( @@ -2295,7 +2323,7 @@ void calculateLayout( (node->getResolvedDimension(dimension(FlexDirection::Row)) .resolve(ownerWidth) .unwrap() + - node->getMarginForAxis(FlexDirection::Row, ownerWidth)); + node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth)); widthSizingMode = SizingMode::StretchFit; } else if (style.maxDimension(Dimension::Width) .resolve(ownerWidth) @@ -2315,7 +2343,7 @@ void calculateLayout( (node->getResolvedDimension(dimension(FlexDirection::Column)) .resolve(ownerHeight) .unwrap() + - node->getMarginForAxis(FlexDirection::Column, ownerWidth)); + node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth)); heightSizingMode = SizingMode::StretchFit; } else if (style.maxDimension(Dimension::Height) .resolve(ownerHeight) diff --git a/yoga/algorithm/FlexDirection.h b/yoga/algorithm/FlexDirection.h index 5bc5880a..1dcc9394 100644 --- a/yoga/algorithm/FlexDirection.h +++ b/yoga/algorithm/FlexDirection.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace facebook::yoga { @@ -49,83 +50,59 @@ inline FlexDirection resolveCrossDirection( : FlexDirection::Column; } -inline Edge flexStartEdge(const FlexDirection flexDirection) { +inline PhysicalEdge flexStartEdge(FlexDirection flexDirection) { switch (flexDirection) { case FlexDirection::Column: - return Edge::Top; + return PhysicalEdge::Top; case FlexDirection::ColumnReverse: - return Edge::Bottom; + return PhysicalEdge::Bottom; case FlexDirection::Row: - return Edge::Left; + return PhysicalEdge::Left; case FlexDirection::RowReverse: - return Edge::Right; + return PhysicalEdge::Right; } fatalWithMessage("Invalid FlexDirection"); } -inline Edge flexEndEdge(const FlexDirection flexDirection) { +inline PhysicalEdge flexEndEdge(FlexDirection flexDirection) { switch (flexDirection) { case FlexDirection::Column: - return Edge::Bottom; + return PhysicalEdge::Bottom; case FlexDirection::ColumnReverse: - return Edge::Top; + return PhysicalEdge::Top; case FlexDirection::Row: - return Edge::Right; + return PhysicalEdge::Right; case FlexDirection::RowReverse: - return Edge::Left; + return PhysicalEdge::Left; } fatalWithMessage("Invalid FlexDirection"); } -inline Edge inlineStartEdge( - const FlexDirection flexDirection, - const Direction direction) { - if (isRow(flexDirection)) { - return direction == Direction::RTL ? Edge::Right : Edge::Left; - } - - return Edge::Top; -} - -inline Edge inlineEndEdge( - const FlexDirection flexDirection, - const Direction direction) { - if (isRow(flexDirection)) { - return direction == Direction::RTL ? Edge::Left : Edge::Right; - } - - return Edge::Bottom; -} - -/** - * The physical edges that Edge::Start and Edge::End correspond to (e.g. - * left/right) are soley dependent on the direction. However, there are cases - * where we want the flex start/end edge (i.e. which edge is the start/end - * for laying out flex items), which can be distinct from the corresponding - * inline edge. In these cases we need to know which "relative edge" - * (Edge::Start/Edge::End) corresponds to the said flex start/end edge as these - * relative edges can be used instead of physical ones when defining certain - * attributes like border or padding. - */ -inline Edge flexStartRelativeEdge( +inline PhysicalEdge inlineStartEdge( FlexDirection flexDirection, Direction direction) { - const Edge leadLayoutEdge = inlineStartEdge(flexDirection, direction); - const Edge leadFlexItemEdge = flexStartEdge(flexDirection); - return leadLayoutEdge == leadFlexItemEdge ? Edge::Start : Edge::End; + if (isRow(flexDirection)) { + return direction == Direction::RTL ? PhysicalEdge::Right + : PhysicalEdge::Left; + } + + return PhysicalEdge::Top; } -inline Edge flexEndRelativeEdge( +inline PhysicalEdge inlineEndEdge( FlexDirection flexDirection, Direction direction) { - const Edge trailLayoutEdge = inlineEndEdge(flexDirection, direction); - const Edge trailFlexItemEdge = flexEndEdge(flexDirection); - return trailLayoutEdge == trailFlexItemEdge ? Edge::End : Edge::Start; + if (isRow(flexDirection)) { + return direction == Direction::RTL ? PhysicalEdge::Left + : PhysicalEdge::Right; + } + + return PhysicalEdge::Bottom; } -inline Dimension dimension(const FlexDirection flexDirection) { +inline Dimension dimension(FlexDirection flexDirection) { switch (flexDirection) { case FlexDirection::Column: return Dimension::Height; diff --git a/yoga/algorithm/FlexLine.cpp b/yoga/algorithm/FlexLine.cpp index 8d333eb0..69ae351e 100644 --- a/yoga/algorithm/FlexLine.cpp +++ b/yoga/algorithm/FlexLine.cpp @@ -34,7 +34,7 @@ FlexLine calculateFlexLine( const FlexDirection mainAxis = resolveDirection( node->style().flexDirection(), node->resolveDirection(ownerDirection)); const bool isNodeFlexWrap = node->style().flexWrap() != Wrap::NoWrap; - const float gap = node->getGapForAxis(mainAxis); + const float gap = node->style().computeGapForAxis(mainAxis); // Add items to the current line until it's full or we run out of items. for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { @@ -53,7 +53,7 @@ FlexLine calculateFlexLine( child->setLineIndex(lineCount); const float childMarginMainAxis = - child->getMarginForAxis(mainAxis, availableInnerWidth); + child->style().computeMarginForAxis(mainAxis, availableInnerWidth); const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap; const float flexBasisWithMinAndMaxConstraints = boundAxisWithinMinAndMax( diff --git a/yoga/algorithm/PixelGrid.cpp b/yoga/algorithm/PixelGrid.cpp index b84cd7db..7a694565 100644 --- a/yoga/algorithm/PixelGrid.cpp +++ b/yoga/algorithm/PixelGrid.cpp @@ -68,8 +68,8 @@ void roundLayoutResultsToPixelGrid( const double absoluteTop) { const auto pointScaleFactor = node->getConfig()->getPointScaleFactor(); - const double nodeLeft = node->getLayout().position(Edge::Left); - const double nodeTop = node->getLayout().position(Edge::Top); + const double nodeLeft = node->getLayout().position(PhysicalEdge::Left); + const double nodeTop = node->getLayout().position(PhysicalEdge::Top); const double nodeWidth = node->getLayout().dimension(Dimension::Width); const double nodeHeight = node->getLayout().dimension(Dimension::Height); @@ -87,11 +87,11 @@ void roundLayoutResultsToPixelGrid( node->setLayoutPosition( roundValueToPixelGrid(nodeLeft, pointScaleFactor, false, textRounding), - Edge::Left); + PhysicalEdge::Left); node->setLayoutPosition( roundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding), - Edge::Top); + PhysicalEdge::Top); // We multiply dimension by scale factor and if the result is close to the // whole number, we don't have any fraction To verify if the result is close diff --git a/yoga/debug/NodeToString.cpp b/yoga/debug/NodeToString.cpp index ec37d741..39264fea 100644 --- a/yoga/debug/NodeToString.cpp +++ b/yoga/debug/NodeToString.cpp @@ -106,9 +106,9 @@ void nodeToString( appendFormattedString( str, "height: %g; ", node->getLayout().dimension(Dimension::Height)); appendFormattedString( - str, "top: %g; ", node->getLayout().position(Edge::Top)); + str, "top: %g; ", node->getLayout().position(PhysicalEdge::Top)); appendFormattedString( - str, "left: %g;", node->getLayout().position(Edge::Left)); + str, "left: %g;", node->getLayout().position(PhysicalEdge::Left)); appendFormattedString(str, "\" "); } diff --git a/yoga/enums/PhysicalEdge.h b/yoga/enums/PhysicalEdge.h new file mode 100644 index 00000000..21e37d2c --- /dev/null +++ b/yoga/enums/PhysicalEdge.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook::yoga { + +enum class PhysicalEdge : uint32_t { + Left = yoga::to_underlying(Edge::Left), + Top = yoga::to_underlying(Edge::Top), + Right = yoga::to_underlying(Edge::Right), + Bottom = yoga::to_underlying(Edge::Bottom), +}; + +} // namespace facebook::yoga diff --git a/yoga/node/LayoutResults.h b/yoga/node/LayoutResults.h index 819ec1e4..f42c2779 100644 --- a/yoga/node/LayoutResults.h +++ b/yoga/node/LayoutResults.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -68,44 +69,36 @@ struct LayoutResults { measuredDimensions_[yoga::to_underlying(axis)] = dimension; } - float position(Edge cardinalEdge) const { - assertCardinalEdge(cardinalEdge); - return position_[yoga::to_underlying(cardinalEdge)]; + float position(PhysicalEdge physicalEdge) const { + return position_[yoga::to_underlying(physicalEdge)]; } - void setPosition(Edge cardinalEdge, float dimension) { - assertCardinalEdge(cardinalEdge); - position_[yoga::to_underlying(cardinalEdge)] = dimension; + void setPosition(PhysicalEdge physicalEdge, float dimension) { + position_[yoga::to_underlying(physicalEdge)] = dimension; } - float margin(Edge cardinalEdge) const { - assertCardinalEdge(cardinalEdge); - return margin_[yoga::to_underlying(cardinalEdge)]; + float margin(PhysicalEdge physicalEdge) const { + return margin_[yoga::to_underlying(physicalEdge)]; } - void setMargin(Edge cardinalEdge, float dimension) { - assertCardinalEdge(cardinalEdge); - margin_[yoga::to_underlying(cardinalEdge)] = dimension; + void setMargin(PhysicalEdge physicalEdge, float dimension) { + margin_[yoga::to_underlying(physicalEdge)] = dimension; } - float border(Edge cardinalEdge) const { - assertCardinalEdge(cardinalEdge); - return border_[yoga::to_underlying(cardinalEdge)]; + float border(PhysicalEdge physicalEdge) const { + return border_[yoga::to_underlying(physicalEdge)]; } - void setBorder(Edge cardinalEdge, float dimension) { - assertCardinalEdge(cardinalEdge); - border_[yoga::to_underlying(cardinalEdge)] = dimension; + void setBorder(PhysicalEdge physicalEdge, float dimension) { + border_[yoga::to_underlying(physicalEdge)] = dimension; } - float padding(Edge cardinalEdge) const { - assertCardinalEdge(cardinalEdge); - return padding_[yoga::to_underlying(cardinalEdge)]; + float padding(PhysicalEdge physicalEdge) const { + return padding_[yoga::to_underlying(physicalEdge)]; } - void setPadding(Edge cardinalEdge, float dimension) { - assertCardinalEdge(cardinalEdge); - padding_[yoga::to_underlying(cardinalEdge)] = dimension; + void setPadding(PhysicalEdge physicalEdge, float dimension) { + padding_[yoga::to_underlying(physicalEdge)] = dimension; } bool operator==(LayoutResults layout) const; @@ -114,11 +107,6 @@ struct LayoutResults { } private: - static inline void assertCardinalEdge(Edge edge) { - assertFatal( - static_cast(edge) <= 3, "Edge must be top/left/bottom/right"); - } - Direction direction_ : bitCount() = Direction::Inherit; bool hadOverflow_ : 1 = false; diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index a4770ec8..c431940e 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -49,326 +48,6 @@ Node::Node(Node&& node) { } } -// TODO: Edge value resolution should be moved to `yoga::Style` -template -Style::Length Node::computeEdgeValueForRow(Edge rowEdge, Edge edge) const { - if ((style_.*Field)(rowEdge).isDefined()) { - return (style_.*Field)(rowEdge); - } else if ((style_.*Field)(edge).isDefined()) { - return (style_.*Field)(edge); - } else if ((style_.*Field)(Edge::Horizontal).isDefined()) { - return (style_.*Field)(Edge::Horizontal); - } else { - return (style_.*Field)(Edge::All); - } -} - -// TODO: Edge value resolution should be moved to `yoga::Style` -template -Style::Length Node::computeEdgeValueForColumn(Edge edge) const { - if ((style_.*Field)(edge).isDefined()) { - return (style_.*Field)(edge); - } else if ((style_.*Field)(Edge::Vertical).isDefined()) { - return (style_.*Field)(Edge::Vertical); - } else { - return (style_.*Field)(Edge::All); - } -} - -Edge Node::getInlineStartEdge(FlexDirection flexDirection, Direction direction) - const { - return inlineStartEdge(flexDirection, direction); -} - -Edge Node::getInlineEndEdge(FlexDirection flexDirection, Direction direction) - const { - return inlineEndEdge(flexDirection, direction); -} - -Edge Node::getFlexStartRelativeEdge( - FlexDirection flexDirection, - Direction direction) const { - return flexStartRelativeEdge(flexDirection, direction); -} - -Edge Node::getFlexEndRelativeEdge( - FlexDirection flexDirection, - Direction direction) const { - return flexEndRelativeEdge(flexDirection, direction); -} - -bool Node::isFlexStartPositionDefined(FlexDirection axis, Direction direction) - const { - auto leadingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>( - getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis)) - : computeEdgeValueForColumn<&Style::position>(flexStartEdge(axis)); - - return leadingPosition.isDefined(); -} - -bool Node::isInlineStartPositionDefined(FlexDirection axis, Direction direction) - const { - Edge startEdge = getInlineStartEdge(axis, direction); - Style::Length leadingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>(Edge::Start, startEdge) - : computeEdgeValueForColumn<&Style::position>(startEdge); - - return leadingPosition.isDefined(); -} - -bool Node::isFlexEndPositionDefined(FlexDirection axis, Direction direction) - const { - auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>( - getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis)) - : computeEdgeValueForColumn<&Style::position>(flexEndEdge(axis)); - - return !trailingPosition.isUndefined(); -} - -bool Node::isInlineEndPositionDefined(FlexDirection axis, Direction direction) - const { - Edge endEdge = getInlineEndEdge(axis, direction); - Style::Length trailingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>(Edge::End, endEdge) - : computeEdgeValueForColumn<&Style::position>(endEdge); - - return trailingPosition.isDefined(); -} - -float Node::getFlexStartPosition( - FlexDirection axis, - Direction direction, - float axisSize) const { - auto leadingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>( - getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis)) - : computeEdgeValueForColumn<&Style::position>(flexStartEdge(axis)); - - return leadingPosition.resolve(axisSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineStartPosition( - FlexDirection axis, - Direction direction, - float axisSize) const { - Edge startEdge = getInlineStartEdge(axis, direction); - Style::Length leadingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>(Edge::Start, startEdge) - : computeEdgeValueForColumn<&Style::position>(startEdge); - - return leadingPosition.resolve(axisSize).unwrapOrDefault(0.0f); -} - -float Node::getFlexEndPosition( - FlexDirection axis, - Direction direction, - float axisSize) const { - auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>( - getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis)) - : computeEdgeValueForColumn<&Style::position>(flexEndEdge(axis)); - - return trailingPosition.resolve(axisSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineEndPosition( - FlexDirection axis, - Direction direction, - float axisSize) const { - Edge endEdge = getInlineEndEdge(axis, direction); - Style::Length trailingPosition = isRow(axis) - ? computeEdgeValueForRow<&Style::position>(Edge::End, endEdge) - : computeEdgeValueForColumn<&Style::position>(endEdge); - - return trailingPosition.resolve(axisSize).unwrapOrDefault(0.0f); -} - -float Node::getFlexStartMargin( - FlexDirection axis, - Direction direction, - float widthSize) const { - auto leadingMargin = isRow(axis) - ? computeEdgeValueForRow<&Style::margin>( - getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis)) - : computeEdgeValueForColumn<&Style::margin>(flexStartEdge(axis)); - - return leadingMargin.resolve(widthSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineStartMargin( - FlexDirection axis, - Direction direction, - float widthSize) const { - Edge startEdge = getInlineStartEdge(axis, direction); - Style::Length leadingMargin = isRow(axis) - ? computeEdgeValueForRow<&Style::margin>(Edge::Start, startEdge) - : computeEdgeValueForColumn<&Style::margin>(startEdge); - - return leadingMargin.resolve(widthSize).unwrapOrDefault(0.0f); -} - -float Node::getFlexEndMargin( - FlexDirection axis, - Direction direction, - float widthSize) const { - auto trailingMargin = isRow(axis) - ? computeEdgeValueForRow<&Style::margin>( - getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis)) - : computeEdgeValueForColumn<&Style::margin>(flexEndEdge(axis)); - - return trailingMargin.resolve(widthSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineEndMargin( - FlexDirection axis, - Direction direction, - float widthSize) const { - Edge endEdge = getInlineEndEdge(axis, direction); - Style::Length trailingMargin = isRow(axis) - ? computeEdgeValueForRow<&Style::margin>(Edge::End, endEdge) - : computeEdgeValueForColumn<&Style::margin>(endEdge); - - return trailingMargin.resolve(widthSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineStartBorder(FlexDirection axis, Direction direction) - const { - Edge startEdge = getInlineStartEdge(axis, direction); - Style::Length leadingBorder = isRow(axis) - ? computeEdgeValueForRow<&Style::border>(Edge::Start, startEdge) - : computeEdgeValueForColumn<&Style::border>(startEdge); - - return maxOrDefined(leadingBorder.value().unwrap(), 0.0f); -} - -float Node::getFlexStartBorder(FlexDirection axis, Direction direction) const { - Style::Length leadingBorder = isRow(axis) - ? computeEdgeValueForRow<&Style::border>( - getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis)) - : computeEdgeValueForColumn<&Style::border>(flexStartEdge(axis)); - - return maxOrDefined(leadingBorder.value().unwrap(), 0.0f); -} - -float Node::getInlineEndBorder(FlexDirection axis, Direction direction) const { - Edge endEdge = getInlineEndEdge(axis, direction); - Style::Length trailingBorder = isRow(axis) - ? computeEdgeValueForRow<&Style::border>(Edge::End, endEdge) - : computeEdgeValueForColumn<&Style::border>(endEdge); - - return maxOrDefined(trailingBorder.value().unwrap(), 0.0f); -} - -float Node::getFlexEndBorder(FlexDirection axis, Direction direction) const { - Style::Length trailingBorder = isRow(axis) - ? computeEdgeValueForRow<&Style::border>( - getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis)) - : computeEdgeValueForColumn<&Style::border>(flexEndEdge(axis)); - - return maxOrDefined(trailingBorder.value().unwrap(), 0.0f); -} - -float Node::getInlineStartPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - Edge startEdge = getInlineStartEdge(axis, direction); - Style::Length leadingPadding = isRow(axis) - ? computeEdgeValueForRow<&Style::padding>(Edge::Start, startEdge) - : computeEdgeValueForColumn<&Style::padding>(startEdge); - - return maxOrDefined(leadingPadding.resolve(widthSize).unwrap(), 0.0f); -} - -float Node::getFlexStartPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - auto leadingPadding = isRow(axis) - ? computeEdgeValueForRow<&Style::padding>( - getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis)) - : computeEdgeValueForColumn<&Style::padding>(flexStartEdge(axis)); - - return maxOrDefined(leadingPadding.resolve(widthSize).unwrap(), 0.0f); -} - -float Node::getInlineEndPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - Edge endEdge = getInlineEndEdge(axis, direction); - Style::Length trailingPadding = isRow(axis) - ? computeEdgeValueForRow<&Style::padding>(Edge::End, endEdge) - : computeEdgeValueForColumn<&Style::padding>(endEdge); - - return maxOrDefined(trailingPadding.resolve(widthSize).unwrap(), 0.0f); -} - -float Node::getFlexEndPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - auto trailingPadding = isRow(axis) - ? computeEdgeValueForRow<&Style::padding>( - getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis)) - : computeEdgeValueForColumn<&Style::padding>(flexEndEdge(axis)); - - return maxOrDefined(trailingPadding.resolve(widthSize).unwrap(), 0.0f); -} - -float Node::getInlineStartPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getInlineStartPadding(axis, direction, widthSize) + - getInlineStartBorder(axis, direction); -} - -float Node::getFlexStartPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getFlexStartPadding(axis, direction, widthSize) + - getFlexStartBorder(axis, direction); -} - -float Node::getInlineEndPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getInlineEndPadding(axis, direction, widthSize) + - getInlineEndBorder(axis, direction); -} - -float Node::getFlexEndPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getFlexEndPadding(axis, direction, widthSize) + - getFlexEndBorder(axis, direction); -} - -float Node::getBorderForAxis(FlexDirection axis) const { - return getInlineStartBorder(axis, Direction::LTR) + - getInlineEndBorder(axis, Direction::LTR); -} - -float Node::getMarginForAxis(FlexDirection axis, float widthSize) const { - // 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 getInlineStartMargin(axis, Direction::LTR, widthSize) + - getInlineEndMargin(axis, Direction::LTR, widthSize); -} - -float Node::getGapForAxis(FlexDirection axis) const { - auto gap = isRow(axis) ? style_.resolveColumnGap() : style_.resolveRowGap(); - // TODO: Validate percentage gap, and expose ability to set percentage to - // public API - return maxOrDefined(gap.resolve(0.0f /*ownerSize*/).unwrap(), 0.0f); -} - YGSize Node::measure( float width, MeasureMode widthMode, @@ -386,7 +65,7 @@ float Node::dimensionWithMargin( const FlexDirection axis, const float widthSize) { return getLayout().measuredDimension(dimension(axis)) + - getMarginForAxis(axis, widthSize); + style_.computeMarginForAxis(axis, widthSize); } bool Node::isLayoutDimensionDefined(const FlexDirection axis) { @@ -470,15 +149,15 @@ void Node::setLayoutDirection(Direction direction) { layout_.setDirection(direction); } -void Node::setLayoutMargin(float margin, Edge edge) { +void Node::setLayoutMargin(float margin, PhysicalEdge edge) { layout_.setMargin(edge, margin); } -void Node::setLayoutBorder(float border, Edge edge) { +void Node::setLayoutBorder(float border, PhysicalEdge edge) { layout_.setBorder(edge, border); } -void Node::setLayoutPadding(float padding, Edge edge) { +void Node::setLayoutPadding(float padding, PhysicalEdge edge) { layout_.setPadding(edge, padding); } @@ -490,7 +169,7 @@ void Node::setLayoutComputedFlexBasis(const FloatOptional computedFlexBasis) { layout_.computedFlexBasis = computedFlexBasis; } -void Node::setLayoutPosition(float position, Edge edge) { +void Node::setLayoutPosition(float position, PhysicalEdge edge) { layout_.setPosition(edge, position); } @@ -523,11 +202,11 @@ float Node::relativePosition( if (style_.positionType() == PositionType::Static) { return 0; } - if (isInlineStartPositionDefined(axis, direction)) { - return getInlineStartPosition(axis, direction, axisSize); + if (style_.isInlineStartPositionDefined(axis, direction)) { + return style_.computeInlineStartPosition(axis, direction, axisSize); } - return -1 * getInlineEndPosition(axis, direction, axisSize); + return -1 * style_.computeInlineEndPosition(axis, direction, axisSize); } void Node::setPosition( @@ -551,45 +230,29 @@ void Node::setPosition( const float relativePositionCross = relativePosition(crossAxis, directionRespectingRoot, crossSize); - const Edge mainAxisLeadingEdge = getInlineStartEdge(mainAxis, direction); - const Edge mainAxisTrailingEdge = getInlineEndEdge(mainAxis, direction); - const Edge crossAxisLeadingEdge = getInlineStartEdge(crossAxis, direction); - const Edge crossAxisTrailingEdge = getInlineEndEdge(crossAxis, direction); + const auto mainAxisLeadingEdge = inlineStartEdge(mainAxis, direction); + const auto mainAxisTrailingEdge = inlineEndEdge(mainAxis, direction); + const auto crossAxisLeadingEdge = inlineStartEdge(crossAxis, direction); + const auto crossAxisTrailingEdge = inlineEndEdge(crossAxis, direction); setLayoutPosition( - (getInlineStartMargin(mainAxis, direction, ownerWidth) + + (style_.computeInlineStartMargin(mainAxis, direction, ownerWidth) + relativePositionMain), mainAxisLeadingEdge); setLayoutPosition( - (getInlineEndMargin(mainAxis, direction, ownerWidth) + + (style_.computeInlineEndMargin(mainAxis, direction, ownerWidth) + relativePositionMain), mainAxisTrailingEdge); setLayoutPosition( - (getInlineStartMargin(crossAxis, direction, ownerWidth) + + (style_.computeInlineStartMargin(crossAxis, direction, ownerWidth) + relativePositionCross), crossAxisLeadingEdge); setLayoutPosition( - (getInlineEndMargin(crossAxis, direction, ownerWidth) + + (style_.computeInlineEndMargin(crossAxis, direction, ownerWidth) + relativePositionCross), crossAxisTrailingEdge); } -Style::Length Node::getFlexStartMarginValue(FlexDirection axis) const { - if (isRow(axis) && style_.margin(Edge::Start).isDefined()) { - return style_.margin(Edge::Start); - } else { - return style_.margin(flexStartEdge(axis)); - } -} - -Style::Length Node::marginTrailingValue(FlexDirection axis) const { - if (isRow(axis) && style_.margin(Edge::End).isDefined()) { - return style_.margin(Edge::End); - } else { - return style_.margin(flexEndEdge(axis)); - } -} - Style::Length Node::resolveFlexBasisPtr() const { Style::Length flexBasis = style_.flexBasis(); if (flexBasis.unit() != Unit::Auto && flexBasis.unit() != Unit::Undefined) { diff --git a/yoga/node/Node.h b/yoga/node/Node.h index 178434b4..d2fdb20a 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -155,89 +156,6 @@ class YG_EXPORT Node : public ::YGNode { return resolvedDimensions_[static_cast(dimension)]; } - // Methods related to positions, margin, padding and border - bool isFlexStartPositionDefined(FlexDirection axis, Direction direction) - const; - bool isInlineStartPositionDefined(FlexDirection axis, Direction direction) - const; - bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const; - bool isInlineEndPositionDefined(FlexDirection axis, Direction direction) - const; - float getFlexStartPosition( - FlexDirection axis, - Direction direction, - float axisSize) const; - float getInlineStartPosition( - FlexDirection axis, - Direction direction, - float axisSize) const; - float getFlexEndPosition( - FlexDirection axis, - Direction direction, - float axisSize) const; - float getInlineEndPosition( - FlexDirection axis, - Direction direction, - float axisSize) const; - float getFlexStartMargin( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getInlineStartMargin( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getFlexEndMargin( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getInlineEndMargin( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getFlexStartBorder(FlexDirection flexDirection, Direction direction) - const; - float getInlineStartBorder(FlexDirection flexDirection, Direction direction) - const; - float getFlexEndBorder(FlexDirection flexDirection, Direction direction) - const; - float getInlineEndBorder(FlexDirection flexDirection, Direction direction) - const; - float getFlexStartPadding( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getInlineStartPadding( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getFlexEndPadding( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getInlineEndPadding( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getFlexStartPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getInlineStartPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getFlexEndPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getInlineEndPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const; - float getBorderForAxis(FlexDirection axis) const; - float getMarginForAxis(FlexDirection axis, float widthSize) const; - float getGapForAxis(FlexDirection axis) const; // Setters void setContext(void* context) { @@ -303,10 +221,10 @@ class YG_EXPORT Node : public ::YGNode { void setLayoutHadOverflow(bool hadOverflow); void setLayoutDimension(float LengthValue, Dimension dimension); void setLayoutDirection(Direction direction); - void setLayoutMargin(float margin, Edge edge); - void setLayoutBorder(float border, Edge edge); - void setLayoutPadding(float padding, Edge edge); - void setLayoutPosition(float position, Edge edge); + void setLayoutMargin(float margin, PhysicalEdge edge); + void setLayoutBorder(float border, PhysicalEdge edge); + void setLayoutPadding(float padding, PhysicalEdge edge); + void setLayoutPosition(float position, PhysicalEdge edge); void setPosition( const Direction direction, const float mainSize, @@ -314,8 +232,6 @@ class YG_EXPORT Node : public ::YGNode { const float ownerWidth); // Other methods - Style::Length getFlexStartMarginValue(FlexDirection axis) const; - Style::Length marginTrailingValue(FlexDirection axis) const; Style::Length resolveFlexBasisPtr() const; void resolveDimension(); Direction resolveDirection(const Direction ownerDirection); @@ -344,26 +260,11 @@ class YG_EXPORT Node : public ::YGNode { Direction direction, const float axisSize) const; - Edge getInlineStartEdge(FlexDirection flexDirection, Direction direction) - const; - Edge getInlineEndEdge(FlexDirection flexDirection, Direction direction) const; - Edge getFlexStartRelativeEdge( - FlexDirection flexDirection, - Direction direction) const; - Edge getFlexEndRelativeEdge(FlexDirection flexDirection, Direction direction) - const; - void useWebDefaults() { style_.setFlexDirection(FlexDirection::Row); style_.setAlignContent(Align::Stretch); } - template - Style::Length computeEdgeValueForColumn(Edge edge) const; - - template - Style::Length computeEdgeValueForRow(Edge rowEdge, Edge edge) const; - bool hasNewLayout_ : 1 = true; bool isReferenceBaseline_ : 1 = false; bool isDirty_ : 1 = false; diff --git a/yoga/style/Style.h b/yoga/style/Style.h index 29933375..aae189a7 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -14,6 +14,7 @@ #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -201,36 +203,241 @@ class YG_EXPORT Style { aspectRatio_ = value; } - Style::Length resolveColumnGap() const { - if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) { - return (Style::Length)gap_[yoga::to_underlying(Gutter::Column)]; - } else { - return (Style::Length)gap_[yoga::to_underlying(Gutter::All)]; - } - } - - Style::Length resolveRowGap() const { - if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) { - return (Style::Length)gap_[yoga::to_underlying(Gutter::Row)]; - } else { - return (Style::Length)gap_[yoga::to_underlying(Gutter::All)]; - } - } - bool horizontalInsetsDefined() const { - return position_[YGEdge::YGEdgeLeft].isDefined() || - position_[YGEdge::YGEdgeRight].isDefined() || - position_[YGEdge::YGEdgeAll].isDefined() || - position_[YGEdge::YGEdgeHorizontal].isDefined() || - position_[YGEdge::YGEdgeStart].isDefined() || - position_[YGEdge::YGEdgeEnd].isDefined(); + return position_[yoga::to_underlying(Edge::Left)].isDefined() || + position_[yoga::to_underlying(Edge::Right)].isDefined() || + position_[yoga::to_underlying(Edge::All)].isDefined() || + position_[yoga::to_underlying(Edge::Horizontal)].isDefined() || + position_[yoga::to_underlying(Edge::Start)].isDefined() || + position_[yoga::to_underlying(Edge::End)].isDefined(); } bool verticalInsetsDefined() const { - return position_[YGEdge::YGEdgeTop].isDefined() || - position_[YGEdge::YGEdgeBottom].isDefined() || - position_[YGEdge::YGEdgeAll].isDefined() || - position_[YGEdge::YGEdgeVertical].isDefined(); + return position_[yoga::to_underlying(Edge::Top)].isDefined() || + position_[yoga::to_underlying(Edge::Bottom)].isDefined() || + position_[yoga::to_underlying(Edge::All)].isDefined() || + position_[yoga::to_underlying(Edge::Vertical)].isDefined(); + } + + bool isFlexStartPositionDefined(FlexDirection axis, Direction direction) + const { + return computePosition(flexStartEdge(axis), direction).isDefined(); + } + + bool isInlineStartPositionDefined(FlexDirection axis, Direction direction) + const { + return computePosition(inlineStartEdge(axis, direction), direction) + .isDefined(); + } + + bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const { + return computePosition(flexEndEdge(axis), direction).isDefined(); + } + + bool isInlineEndPositionDefined(FlexDirection axis, Direction direction) + const { + return computePosition(inlineEndEdge(axis, direction), direction) + .isDefined(); + } + + float computeFlexStartPosition( + FlexDirection axis, + Direction direction, + float axisSize) const { + return computePosition(flexStartEdge(axis), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0f); + } + + float computeInlineStartPosition( + FlexDirection axis, + Direction direction, + float axisSize) const { + return computePosition(inlineStartEdge(axis, direction), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0f); + } + + float computeFlexEndPosition( + FlexDirection axis, + Direction direction, + float axisSize) const { + return computePosition(flexEndEdge(axis), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0f); + } + + float computeInlineEndPosition( + FlexDirection axis, + Direction direction, + float axisSize) const { + return computePosition(inlineEndEdge(axis, direction), direction) + .resolve(axisSize) + .unwrapOrDefault(0.0f); + } + + float computeFlexStartMargin( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeMargin(flexStartEdge(axis), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0f); + } + + float computeInlineStartMargin( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeMargin(inlineStartEdge(axis, direction), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0f); + } + + float computeFlexEndMargin( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeMargin(flexEndEdge(axis), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0f); + } + + float computeInlineEndMargin( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeMargin(inlineEndEdge(axis, direction), direction) + .resolve(widthSize) + .unwrapOrDefault(0.0f); + } + + float computeFlexStartBorder(FlexDirection axis, Direction direction) const { + return computeBorder(flexStartEdge(axis), direction) + .resolve(0.0f) + .unwrapOrDefault(0.0f); + } + + float computeInlineStartBorder(FlexDirection axis, Direction direction) + const { + return computeBorder(inlineStartEdge(axis, direction), direction) + .resolve(0.0f) + .unwrapOrDefault(0.0f); + } + + float computeFlexEndBorder(FlexDirection axis, Direction direction) const { + return computeBorder(flexEndEdge(axis), direction) + .resolve(0.0f) + .unwrapOrDefault(0.0f); + } + + float computeInlineEndBorder(FlexDirection axis, Direction direction) const { + return computeBorder(inlineEndEdge(axis, direction), direction) + .resolve(0.0f) + .unwrapOrDefault(0.0f); + } + + float computeFlexStartPadding( + FlexDirection axis, + Direction direction, + float widthSize) const { + return maxOrDefined( + computePadding(flexStartEdge(axis), direction) + .resolve(widthSize) + .unwrap(), + 0.0f); + } + + float computeInlineStartPadding( + FlexDirection axis, + Direction direction, + float widthSize) const { + return maxOrDefined( + computePadding(inlineStartEdge(axis, direction), direction) + .resolve(widthSize) + .unwrap(), + 0.0f); + } + + float computeFlexEndPadding( + FlexDirection axis, + Direction direction, + float widthSize) const { + return maxOrDefined( + computePadding(flexEndEdge(axis), direction) + .resolve(widthSize) + .unwrap(), + 0.0f); + } + + float computeInlineEndPadding( + FlexDirection axis, + Direction direction, + float widthSize) const { + return maxOrDefined( + computePadding(inlineEndEdge(axis, direction), direction) + .resolve(widthSize) + .unwrap(), + 0.0f); + } + + float computeInlineStartPaddingAndBorder( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeInlineStartPadding(axis, direction, widthSize) + + computeInlineStartBorder(axis, direction); + } + + float computeFlexStartPaddingAndBorder( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeFlexStartPadding(axis, direction, widthSize) + + computeFlexStartBorder(axis, direction); + } + + float computeInlineEndPaddingAndBorder( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeInlineEndPadding(axis, direction, widthSize) + + computeInlineEndBorder(axis, direction); + } + + float computeFlexEndPaddingAndBorder( + FlexDirection axis, + Direction direction, + float widthSize) const { + return computeFlexEndPadding(axis, direction, widthSize) + + computeFlexEndBorder(axis, direction); + } + + float computeBorderForAxis(FlexDirection axis) const { + return computeInlineStartBorder(axis, Direction::LTR) + + computeInlineEndBorder(axis, Direction::LTR); + } + + float computeMarginForAxis(FlexDirection axis, float widthSize) const { + // 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 computeInlineStartMargin(axis, Direction::LTR, widthSize) + + computeInlineEndMargin(axis, Direction::LTR, widthSize); + } + + float computeGapForAxis(FlexDirection axis) const { + auto gap = isRow(axis) ? computeColumnGap() : computeRowGap(); + // TODO: Validate percentage gap, and expose ability to set percentage to + // public API + return maxOrDefined(gap.resolve(0.0f /*ownerSize*/).unwrap(), 0.0f); + } + + bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const { + return computeMargin(flexStartEdge(axis), direction).isAuto(); + } + + bool flexEndMarginIsAuto(FlexDirection axis, Direction direction) const { + return computeMargin(flexEndEdge(axis), direction).isAuto(); } bool operator==(const Style& other) const { @@ -265,6 +472,138 @@ class YG_EXPORT Style { using Edges = std::array()>; using Gutters = std::array()>; + Style::Length computeColumnGap() const { + if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) { + return (Style::Length)gap_[yoga::to_underlying(Gutter::Column)]; + } else { + return (Style::Length)gap_[yoga::to_underlying(Gutter::All)]; + } + } + + Style::Length computeRowGap() const { + if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) { + return (Style::Length)gap_[yoga::to_underlying(Gutter::Row)]; + } else { + return (Style::Length)gap_[yoga::to_underlying(Gutter::All)]; + } + } + + Style::Length computeLeftEdge(const Edges& edges, Direction layoutDirection) + const { + if (layoutDirection == Direction::LTR && + edges[yoga::to_underlying(Edge::Start)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Start)]; + } else if ( + layoutDirection == Direction::RTL && + edges[yoga::to_underlying(Edge::End)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::End)]; + } else if (edges[yoga::to_underlying(Edge::Left)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Left)]; + } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Horizontal)]; + } else { + return (Style::Length)edges[yoga::to_underlying(Edge::All)]; + } + } + + Style::Length computeTopEdge(const Edges& edges) const { + if (edges[yoga::to_underlying(Edge::Top)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Top)]; + } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Vertical)]; + } else { + return (Style::Length)edges[yoga::to_underlying(Edge::All)]; + } + } + + Style::Length computeRightEdge(const Edges& edges, Direction layoutDirection) + const { + if (layoutDirection == Direction::LTR && + edges[yoga::to_underlying(Edge::End)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::End)]; + } else if ( + layoutDirection == Direction::RTL && + edges[yoga::to_underlying(Edge::Start)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Start)]; + } else if (edges[yoga::to_underlying(Edge::Right)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Right)]; + } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Horizontal)]; + } else { + return (Style::Length)edges[yoga::to_underlying(Edge::All)]; + } + } + + Style::Length computeBottomEdge(const Edges& edges) const { + if (edges[yoga::to_underlying(Edge::Bottom)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Bottom)]; + } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) { + return (Style::Length)edges[yoga::to_underlying(Edge::Vertical)]; + } else { + return (Style::Length)edges[yoga::to_underlying(Edge::All)]; + } + } + + Style::Length computePosition(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(position_, direction); + case PhysicalEdge::Top: + return computeTopEdge(position_); + case PhysicalEdge::Right: + return computeRightEdge(position_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(position_); + } + + fatalWithMessage("Invalid physical edge"); + } + + Style::Length computeMargin(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(margin_, direction); + case PhysicalEdge::Top: + return computeTopEdge(margin_); + case PhysicalEdge::Right: + return computeRightEdge(margin_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(margin_); + } + + fatalWithMessage("Invalid physical edge"); + } + + Style::Length computePadding(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(padding_, direction); + case PhysicalEdge::Top: + return computeTopEdge(padding_); + case PhysicalEdge::Right: + return computeRightEdge(padding_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(padding_); + } + + fatalWithMessage("Invalid physical edge"); + } + + Style::Length computeBorder(PhysicalEdge edge, Direction direction) const { + switch (edge) { + case PhysicalEdge::Left: + return computeLeftEdge(border_, direction); + case PhysicalEdge::Top: + return computeTopEdge(border_); + case PhysicalEdge::Right: + return computeRightEdge(border_, direction); + case PhysicalEdge::Bottom: + return computeBottomEdge(border_); + } + + fatalWithMessage("Invalid physical edge"); + } + Direction direction_ : bitCount() = Direction::Inherit; FlexDirection flexDirection_ : bitCount() = FlexDirection::Column;