From aeed3c6b65570f0afd29bd410bede74cdd360a56 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Fri, 22 Sep 2023 00:50:59 -0700 Subject: [PATCH 1/4] C++ style enums 16/N: Dimension Summary: Replaces all usages of YGDimension with Dimension. Adds `yoga::to_underlying` to act like `std::to_underlying`, added in C++ 23. This enum is oddly only used internally, and is never an input to the public API, but it handled as any other public generated enum. Potentially some more cleanup to do there. Differential Revision: D49475409 fbshipit-source-id: 92cd33e38268f5a3b7a98bbcea0cbc61b87f9360 --- yoga/Yoga.cpp | 44 ++++++------- yoga/algorithm/Baseline.cpp | 6 +- yoga/algorithm/BoundAxis.h | 9 +-- yoga/algorithm/CalculateLayout.cpp | 102 ++++++++++++++--------------- yoga/algorithm/FlexDirection.h | 11 ++-- yoga/algorithm/PixelGrid.cpp | 8 +-- yoga/debug/NodeToString.cpp | 16 ++--- yoga/enums/YogaEnums.h | 8 +++ yoga/node/LayoutResults.h | 17 ++--- yoga/node/Node.cpp | 11 ++-- yoga/node/Node.h | 9 ++- yoga/style/Style.h | 27 ++++---- 12 files changed, 139 insertions(+), 129 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 038ac653a9..a0119acc8b 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -662,97 +662,97 @@ void YGNodeStyleSetAspectRatio(const YGNodeRef node, const float aspectRatio) { void YGNodeStyleSetWidth(YGNodeRef node, float points) { auto value = CompactValue::ofMaybe(points); updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, YGDimensionWidth, value); + node, Dimension::Width, value); } void YGNodeStyleSetWidthPercent(YGNodeRef node, float percent) { auto value = CompactValue::ofMaybe(percent); updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, YGDimensionWidth, value); + node, Dimension::Width, value); } void YGNodeStyleSetWidthAuto(YGNodeRef node) { updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, YGDimensionWidth, CompactValue::ofAuto()); + node, Dimension::Width, CompactValue::ofAuto()); } YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { - return resolveRef(node)->getStyle().dimension(YGDimensionWidth); + return resolveRef(node)->getStyle().dimension(Dimension::Width); } void YGNodeStyleSetHeight(YGNodeRef node, float points) { auto value = CompactValue::ofMaybe(points); updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, YGDimensionHeight, value); + node, Dimension::Height, value); } void YGNodeStyleSetHeightPercent(YGNodeRef node, float percent) { auto value = CompactValue::ofMaybe(percent); updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, YGDimensionHeight, value); + node, Dimension::Height, value); } void YGNodeStyleSetHeightAuto(YGNodeRef node) { updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, YGDimensionHeight, CompactValue::ofAuto()); + node, Dimension::Height, CompactValue::ofAuto()); } YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { - return resolveRef(node)->getStyle().dimension(YGDimensionHeight); + return resolveRef(node)->getStyle().dimension(Dimension::Height); } void YGNodeStyleSetMinWidth(const YGNodeRef node, const float minWidth) { auto value = CompactValue::ofMaybe(minWidth); updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, YGDimensionWidth, value); + node, Dimension::Width, value); } void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) { auto value = CompactValue::ofMaybe(minWidth); updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, YGDimensionWidth, value); + node, Dimension::Width, value); } YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().minDimension(YGDimensionWidth); + return resolveRef(node)->getStyle().minDimension(Dimension::Width); } void YGNodeStyleSetMinHeight(const YGNodeRef node, const float minHeight) { auto value = CompactValue::ofMaybe(minHeight); updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, YGDimensionHeight, value); + node, Dimension::Height, value); } void YGNodeStyleSetMinHeightPercent( const YGNodeRef node, const float minHeight) { auto value = CompactValue::ofMaybe(minHeight); updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, YGDimensionHeight, value); + node, Dimension::Height, value); } YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().minDimension(YGDimensionHeight); + return resolveRef(node)->getStyle().minDimension(Dimension::Height); } void YGNodeStyleSetMaxWidth(const YGNodeRef node, const float maxWidth) { auto value = CompactValue::ofMaybe(maxWidth); updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, YGDimensionWidth, value); + node, Dimension::Width, value); } void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) { auto value = CompactValue::ofMaybe(maxWidth); updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, YGDimensionWidth, value); + node, Dimension::Width, value); } YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().maxDimension(YGDimensionWidth); + return resolveRef(node)->getStyle().maxDimension(Dimension::Width); } void YGNodeStyleSetMaxHeight(const YGNodeRef node, const float maxHeight) { auto value = CompactValue::ofMaybe(maxHeight); updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, YGDimensionHeight, value); + node, Dimension::Height, value); } void YGNodeStyleSetMaxHeightPercent( const YGNodeRef node, const float maxHeight) { auto value = CompactValue::ofMaybe(maxHeight); updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, YGDimensionHeight, value); + node, Dimension::Height, value); } YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().maxDimension(YGDimensionHeight); + return resolveRef(node)->getStyle().maxDimension(Dimension::Height); } namespace { @@ -805,11 +805,11 @@ float YGNodeLayoutGetBottom(const YGNodeConstRef node) { } float YGNodeLayoutGetWidth(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().dimension(YGDimensionWidth); + return resolveRef(node)->getLayout().dimension(Dimension::Width); } float YGNodeLayoutGetHeight(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().dimension(YGDimensionHeight); + return resolveRef(node)->getLayout().dimension(Dimension::Height); } YGDirection YGNodeLayoutGetDirection(const YGNodeConstRef node) { diff --git a/yoga/algorithm/Baseline.cpp b/yoga/algorithm/Baseline.cpp index 90a3506a27..aea316c035 100644 --- a/yoga/algorithm/Baseline.cpp +++ b/yoga/algorithm/Baseline.cpp @@ -19,8 +19,8 @@ float calculateBaseline(const yoga::Node* node) { Event::publish(node); const float baseline = node->baseline( - node->getLayout().measuredDimension(YGDimensionWidth), - node->getLayout().measuredDimension(YGDimensionHeight)); + node->getLayout().measuredDimension(Dimension::Width), + node->getLayout().measuredDimension(Dimension::Height)); Event::publish(node); @@ -53,7 +53,7 @@ float calculateBaseline(const yoga::Node* node) { } if (baselineChild == nullptr) { - return node->getLayout().measuredDimension(YGDimensionHeight); + return node->getLayout().measuredDimension(Dimension::Height); } const float baseline = calculateBaseline(baselineChild); diff --git a/yoga/algorithm/BoundAxis.h b/yoga/algorithm/BoundAxis.h index 22489398c4..0972fe2933 100644 --- a/yoga/algorithm/BoundAxis.h +++ b/yoga/algorithm/BoundAxis.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -35,14 +36,14 @@ inline FloatOptional boundAxisWithinMinAndMax( if (isColumn(axis)) { min = yoga::resolveValue( - node->getStyle().minDimension(YGDimensionHeight), axisSize); + node->getStyle().minDimension(Dimension::Height), axisSize); max = yoga::resolveValue( - node->getStyle().maxDimension(YGDimensionHeight), axisSize); + node->getStyle().maxDimension(Dimension::Height), axisSize); } else if (isRow(axis)) { min = yoga::resolveValue( - node->getStyle().minDimension(YGDimensionWidth), axisSize); + node->getStyle().minDimension(Dimension::Width), axisSize); max = yoga::resolveValue( - node->getStyle().maxDimension(YGDimensionWidth), axisSize); + node->getStyle().maxDimension(Dimension::Width), axisSize); } if (max >= FloatOptional{0} && value > max) { diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 113baf61f5..1d0b2d09a4 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -169,7 +169,7 @@ static void computeFlexBasisForChild( child->setLayoutComputedFlexBasis(yoga::maxOrDefined( yoga::resolveValue( - child->getResolvedDimension(YGDimensionWidth), ownerWidth), + child->getResolvedDimension(Dimension::Width), ownerWidth), paddingAndBorder)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { // The height is definite, so use that as the flex basis. @@ -177,7 +177,7 @@ static void computeFlexBasisForChild( paddingAndBorderForAxis(child, FlexDirection::Column, ownerWidth)); child->setLayoutComputedFlexBasis(yoga::maxOrDefined( yoga::resolveValue( - child->getResolvedDimension(YGDimensionHeight), ownerHeight), + child->getResolvedDimension(Dimension::Height), ownerHeight), paddingAndBorder)); } else { // Compute the flex basis and hypothetical main size (i.e. the clamped flex @@ -195,7 +195,7 @@ static void computeFlexBasisForChild( if (isRowStyleDimDefined) { childWidth = yoga::resolveValue( - child->getResolvedDimension(YGDimensionWidth), ownerWidth) + child->getResolvedDimension(Dimension::Width), ownerWidth) .unwrap() + marginRow; childWidthMeasureMode = MeasureMode::Exactly; @@ -203,7 +203,7 @@ static void computeFlexBasisForChild( if (isColumnStyleDimDefined) { childHeight = yoga::resolveValue( - child->getResolvedDimension(YGDimensionHeight), ownerHeight) + child->getResolvedDimension(Dimension::Height), ownerHeight) .unwrap() + marginColumn; childHeightMeasureMode = MeasureMode::Exactly; @@ -341,7 +341,7 @@ static void layoutAbsoluteChild( if (styleDefinesDimension(child, FlexDirection::Row, width)) { childWidth = - yoga::resolveValue(child->getResolvedDimension(YGDimensionWidth), width) + yoga::resolveValue(child->getResolvedDimension(Dimension::Width), width) .unwrap() + marginRow; } else { @@ -349,7 +349,7 @@ static void layoutAbsoluteChild( // the left/right offsets if they're defined. if (child->isLeadingPositionDefined(FlexDirection::Row) && child->isTrailingPosDefined(FlexDirection::Row)) { - childWidth = node->getLayout().measuredDimension(YGDimensionWidth) - + childWidth = node->getLayout().measuredDimension(Dimension::Width) - (node->getLeadingBorder(FlexDirection::Row) + node->getTrailingBorder(FlexDirection::Row)) - (child->getLeadingPosition(FlexDirection::Row, width) + @@ -362,7 +362,7 @@ static void layoutAbsoluteChild( if (styleDefinesDimension(child, FlexDirection::Column, height)) { childHeight = yoga::resolveValue( - child->getResolvedDimension(YGDimensionHeight), height) + child->getResolvedDimension(Dimension::Height), height) .unwrap() + marginColumn; } else { @@ -370,7 +370,7 @@ static void layoutAbsoluteChild( // the top/bottom offsets if they're defined. if (child->isLeadingPositionDefined(FlexDirection::Column) && child->isTrailingPosDefined(FlexDirection::Column)) { - childHeight = node->getLayout().measuredDimension(YGDimensionHeight) - + childHeight = node->getLayout().measuredDimension(Dimension::Height) - (node->getLeadingBorder(FlexDirection::Column) + node->getTrailingBorder(FlexDirection::Column)) - (child->getLeadingPosition(FlexDirection::Column, height) + @@ -431,9 +431,9 @@ static void layoutAbsoluteChild( layoutMarkerData, depth, generationCount); - childWidth = child->getLayout().measuredDimension(YGDimensionWidth) + + childWidth = child->getLayout().measuredDimension(Dimension::Width) + child->getMarginForAxis(FlexDirection::Row, width).unwrap(); - childHeight = child->getLayout().measuredDimension(YGDimensionHeight) + + childHeight = child->getLayout().measuredDimension(Dimension::Height) + child->getMarginForAxis(FlexDirection::Column, width).unwrap(); } @@ -587,7 +587,7 @@ static void measureNodeWithMeasureFunc( node->setLayoutMeasuredDimension( boundAxis( node, FlexDirection::Row, availableWidth, ownerWidth, ownerWidth), - YGDimensionWidth); + Dimension::Width); node->setLayoutMeasuredDimension( boundAxis( node, @@ -595,7 +595,7 @@ static void measureNodeWithMeasureFunc( availableHeight, ownerHeight, ownerWidth), - YGDimensionHeight); + Dimension::Height); } else { Event::publish(node); @@ -627,7 +627,7 @@ static void measureNodeWithMeasureFunc( : availableWidth, ownerWidth, ownerWidth), - YGDimensionWidth); + Dimension::Width); node->setLayoutMeasuredDimension( boundAxis( @@ -639,7 +639,7 @@ static void measureNodeWithMeasureFunc( : availableHeight, ownerHeight, ownerWidth), - YGDimensionHeight); + Dimension::Height); } } @@ -664,7 +664,7 @@ static void measureNodeWithoutChildren( } node->setLayoutMeasuredDimension( boundAxis(node, FlexDirection::Row, width, ownerWidth, ownerWidth), - YGDimensionWidth); + Dimension::Width); float height = availableHeight; if (heightMeasureMode == MeasureMode::Undefined || @@ -674,7 +674,7 @@ static void measureNodeWithoutChildren( } node->setLayoutMeasuredDimension( boundAxis(node, FlexDirection::Column, height, ownerHeight, ownerWidth), - YGDimensionHeight); + Dimension::Height); } static bool measureNodeWithFixedSize( @@ -702,7 +702,7 @@ static bool measureNodeWithFixedSize( : availableWidth, ownerWidth, ownerWidth), - YGDimensionWidth); + Dimension::Width); node->setLayoutMeasuredDimension( boundAxis( @@ -715,7 +715,7 @@ static bool measureNodeWithFixedSize( : availableHeight, ownerHeight, ownerWidth), - YGDimensionHeight); + Dimension::Height); return true; } @@ -724,8 +724,8 @@ static bool measureNodeWithFixedSize( static void zeroOutLayoutRecursively(yoga::Node* const node) { node->getLayout() = {}; - node->setLayoutDimension(0, YGDimensionWidth); - node->setLayoutDimension(0, YGDimensionHeight); + node->setLayoutDimension(0, Dimension::Width); + node->setLayoutDimension(0, Dimension::Height); node->setHasNewLayout(true); node->cloneChildrenIfNeeded(); @@ -736,7 +736,7 @@ static void zeroOutLayoutRecursively(yoga::Node* const node) { static float calculateAvailableInnerDimension( const yoga::Node* const node, - const YGDimension dimension, + const Dimension dimension, const float availableDim, const float paddingAndBorder, const float ownerDim) { @@ -1373,7 +1373,7 @@ static void justifyMainAxis( FlexDirection::Column, availableInnerWidth) .unwrap(); const float descent = - child->getLayout().measuredDimension(YGDimensionHeight) + + child->getLayout().measuredDimension(Dimension::Height) + child ->getMarginForAxis( FlexDirection::Column, availableInnerWidth) @@ -1632,13 +1632,13 @@ static void calculateLayoutImpl( float availableInnerWidth = calculateAvailableInnerDimension( node, - YGDimensionWidth, + Dimension::Width, availableWidth - marginAxisRow, paddingAndBorderAxisRow, ownerWidth); float availableInnerHeight = calculateAvailableInnerDimension( node, - YGDimensionHeight, + Dimension::Height, availableHeight - marginAxisColumn, paddingAndBorderAxisColumn, ownerHeight); @@ -1725,19 +1725,19 @@ static void calculateLayoutImpl( if (measureModeMainDim != MeasureMode::Exactly) { const auto& style = node->getStyle(); const float minInnerWidth = - yoga::resolveValue(style.minDimension(YGDimensionWidth), ownerWidth) + yoga::resolveValue(style.minDimension(Dimension::Width), ownerWidth) .unwrap() - paddingAndBorderAxisRow; const float maxInnerWidth = - yoga::resolveValue(style.maxDimension(YGDimensionWidth), ownerWidth) + yoga::resolveValue(style.maxDimension(Dimension::Width), ownerWidth) .unwrap() - paddingAndBorderAxisRow; const float minInnerHeight = - yoga::resolveValue(style.minDimension(YGDimensionHeight), ownerHeight) + yoga::resolveValue(style.minDimension(Dimension::Height), ownerHeight) .unwrap() - paddingAndBorderAxisColumn; const float maxInnerHeight = - yoga::resolveValue(style.maxDimension(YGDimensionHeight), ownerHeight) + yoga::resolveValue(style.maxDimension(Dimension::Height), ownerHeight) .unwrap() - paddingAndBorderAxisColumn; @@ -2089,7 +2089,7 @@ static void calculateLayoutImpl( FlexDirection::Column, availableInnerWidth) .unwrap(); const float descent = - child->getLayout().measuredDimension(YGDimensionHeight) + + child->getLayout().measuredDimension(Dimension::Height) + child ->getMarginForAxis( FlexDirection::Column, availableInnerWidth) @@ -2156,14 +2156,14 @@ static void calculateLayoutImpl( child, crossAxis, availableInnerCrossDim)) { const float childWidth = isMainAxisRow ? (child->getLayout().measuredDimension( - YGDimensionWidth) + + Dimension::Width) + child->getMarginForAxis(mainAxis, availableInnerWidth) .unwrap()) : lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout().measuredDimension( - YGDimensionHeight) + + Dimension::Height) + child->getMarginForAxis(crossAxis, availableInnerWidth) .unwrap()) : lineHeight; @@ -2171,11 +2171,11 @@ static void calculateLayoutImpl( if (!(yoga::inexactEquals( childWidth, child->getLayout().measuredDimension( - YGDimensionWidth)) && + Dimension::Width)) && yoga::inexactEquals( childHeight, child->getLayout().measuredDimension( - YGDimensionHeight)))) { + Dimension::Height)))) { calculateLayoutInternal( child, childWidth, @@ -2227,7 +2227,7 @@ static void calculateLayoutImpl( availableWidth - marginAxisRow, ownerWidth, ownerWidth), - YGDimensionWidth); + Dimension::Width); node->setLayoutMeasuredDimension( boundAxis( @@ -2236,7 +2236,7 @@ static void calculateLayoutImpl( availableHeight - marginAxisColumn, ownerHeight, ownerWidth), - YGDimensionHeight); + Dimension::Height); // If the user didn't specify a width or height for the node, set the // dimensions based on the children. @@ -2329,11 +2329,11 @@ static void calculateLayoutImpl( node, child, absolutePercentageAgainstPaddingEdge - ? node->getLayout().measuredDimension(YGDimensionWidth) + ? node->getLayout().measuredDimension(Dimension::Width) : availableInnerWidth, isMainAxisRow ? measureModeMainDim : measureModeCrossDim, absolutePercentageAgainstPaddingEdge - ? node->getLayout().measuredDimension(YGDimensionHeight) + ? node->getLayout().measuredDimension(Dimension::Height) : availableInnerHeight, direction, layoutMarkerData, @@ -2516,9 +2516,9 @@ bool calculateLayoutInternal( if (!needToVisitNode && cachedResults != nullptr) { layout->setMeasuredDimension( - YGDimensionWidth, cachedResults->computedWidth); + Dimension::Width, cachedResults->computedWidth); layout->setMeasuredDimension( - YGDimensionHeight, cachedResults->computedHeight); + Dimension::Height, cachedResults->computedHeight); (performLayout ? layoutMarkerData.cachedLayouts : layoutMarkerData.cachedMeasures) += 1; @@ -2594,8 +2594,8 @@ bool calculateLayoutInternal( "wm: %s, hm: %s, d: (%f, %f) %s\n", measureModeName(widthMeasureMode, performLayout), measureModeName(heightMeasureMode, performLayout), - layout->measuredDimension(YGDimensionWidth), - layout->measuredDimension(YGDimensionHeight), + layout->measuredDimension(Dimension::Width), + layout->measuredDimension(Dimension::Height), LayoutPassReasonToString(reason)); } @@ -2630,19 +2630,19 @@ bool calculateLayoutInternal( newCacheEntry->widthMeasureMode = widthMeasureMode; newCacheEntry->heightMeasureMode = heightMeasureMode; newCacheEntry->computedWidth = - layout->measuredDimension(YGDimensionWidth); + layout->measuredDimension(Dimension::Width); newCacheEntry->computedHeight = - layout->measuredDimension(YGDimensionHeight); + layout->measuredDimension(Dimension::Height); } } if (performLayout) { node->setLayoutDimension( - node->getLayout().measuredDimension(YGDimensionWidth), - YGDimensionWidth); + node->getLayout().measuredDimension(Dimension::Width), + Dimension::Width); node->setLayoutDimension( - node->getLayout().measuredDimension(YGDimensionHeight), - YGDimensionHeight); + node->getLayout().measuredDimension(Dimension::Height), + Dimension::Height); node->setHasNewLayout(true); node->setDirty(false); @@ -2688,9 +2688,9 @@ void calculateLayout( .unwrap(); widthMeasureMode = MeasureMode::Exactly; } else if (!yoga::resolveValue( - style.maxDimension(YGDimensionWidth), ownerWidth) + style.maxDimension(Dimension::Width), ownerWidth) .isUndefined()) { - width = yoga::resolveValue(style.maxDimension(YGDimensionWidth), ownerWidth) + width = yoga::resolveValue(style.maxDimension(Dimension::Width), ownerWidth) .unwrap(); widthMeasureMode = MeasureMode::AtMost; } else { @@ -2709,10 +2709,10 @@ void calculateLayout( .unwrap(); heightMeasureMode = MeasureMode::Exactly; } else if (!yoga::resolveValue( - style.maxDimension(YGDimensionHeight), ownerHeight) + style.maxDimension(Dimension::Height), ownerHeight) .isUndefined()) { height = - yoga::resolveValue(style.maxDimension(YGDimensionHeight), ownerHeight) + yoga::resolveValue(style.maxDimension(Dimension::Height), ownerHeight) .unwrap(); heightMeasureMode = MeasureMode::AtMost; } else { diff --git a/yoga/algorithm/FlexDirection.h b/yoga/algorithm/FlexDirection.h index 1eb98ea1ed..010bfed409 100644 --- a/yoga/algorithm/FlexDirection.h +++ b/yoga/algorithm/FlexDirection.h @@ -10,6 +10,7 @@ #include #include +#include #include namespace facebook::yoga { @@ -76,16 +77,16 @@ inline YGEdge trailingEdge(const FlexDirection flexDirection) { fatalWithMessage("Invalid FlexDirection"); } -inline YGDimension dimension(const FlexDirection flexDirection) { +inline Dimension dimension(const FlexDirection flexDirection) { switch (flexDirection) { case FlexDirection::Column: - return YGDimensionHeight; + return Dimension::Height; case FlexDirection::ColumnReverse: - return YGDimensionHeight; + return Dimension::Height; case FlexDirection::Row: - return YGDimensionWidth; + return Dimension::Width; case FlexDirection::RowReverse: - return YGDimensionWidth; + return Dimension::Width; } fatalWithMessage("Invalid FlexDirection"); diff --git a/yoga/algorithm/PixelGrid.cpp b/yoga/algorithm/PixelGrid.cpp index f602a94e28..5e44c2cc8d 100644 --- a/yoga/algorithm/PixelGrid.cpp +++ b/yoga/algorithm/PixelGrid.cpp @@ -71,8 +71,8 @@ void roundLayoutResultsToPixelGrid( const double nodeLeft = node->getLayout().position[YGEdgeLeft]; const double nodeTop = node->getLayout().position[YGEdgeTop]; - const double nodeWidth = node->getLayout().dimension(YGDimensionWidth); - const double nodeHeight = node->getLayout().dimension(YGDimensionHeight); + const double nodeWidth = node->getLayout().dimension(Dimension::Width); + const double nodeHeight = node->getLayout().dimension(Dimension::Height); const double absoluteNodeLeft = absoluteLeft + nodeLeft; const double absoluteNodeTop = absoluteTop + nodeTop; @@ -111,7 +111,7 @@ void roundLayoutResultsToPixelGrid( (textRounding && !hasFractionalWidth)) - roundValueToPixelGrid( absoluteNodeLeft, pointScaleFactor, false, textRounding), - YGDimensionWidth); + Dimension::Width); node->setLayoutDimension( roundValueToPixelGrid( @@ -121,7 +121,7 @@ void roundLayoutResultsToPixelGrid( (textRounding && !hasFractionalHeight)) - roundValueToPixelGrid( absoluteNodeTop, pointScaleFactor, false, textRounding), - YGDimensionHeight); + Dimension::Height); } for (yoga::Node* child : node->getChildren()) { diff --git a/yoga/debug/NodeToString.cpp b/yoga/debug/NodeToString.cpp index 0ae3f17f32..9eb090116e 100644 --- a/yoga/debug/NodeToString.cpp +++ b/yoga/debug/NodeToString.cpp @@ -127,9 +127,9 @@ void nodeToString( if ((options & PrintOptions::Layout) == PrintOptions::Layout) { appendFormattedString(str, "layout=\""); appendFormattedString( - str, "width: %g; ", node->getLayout().dimension(YGDimensionWidth)); + str, "width: %g; ", node->getLayout().dimension(Dimension::Width)); appendFormattedString( - str, "height: %g; ", node->getLayout().dimension(YGDimensionHeight)); + str, "height: %g; ", node->getLayout().dimension(Dimension::Height)); appendFormattedString( str, "top: %g; ", node->getLayout().position[YGEdgeTop]); appendFormattedString( @@ -193,16 +193,16 @@ void nodeToString( appendNumberIfNotUndefined(str, "row-gap", style.gap()[YGGutterRow]); } - appendNumberIfNotAuto(str, "width", style.dimension(YGDimensionWidth)); - appendNumberIfNotAuto(str, "height", style.dimension(YGDimensionHeight)); + appendNumberIfNotAuto(str, "width", style.dimension(Dimension::Width)); + appendNumberIfNotAuto(str, "height", style.dimension(Dimension::Height)); appendNumberIfNotAuto( - str, "max-width", style.maxDimension(YGDimensionWidth)); + str, "max-width", style.maxDimension(Dimension::Width)); appendNumberIfNotAuto( - str, "max-height", style.maxDimension(YGDimensionHeight)); + str, "max-height", style.maxDimension(Dimension::Height)); appendNumberIfNotAuto( - str, "min-width", style.minDimension(YGDimensionWidth)); + str, "min-width", style.minDimension(Dimension::Width)); appendNumberIfNotAuto( - str, "min-height", style.minDimension(YGDimensionHeight)); + str, "min-height", style.minDimension(Dimension::Height)); if (style.positionType() != yoga::Node{}.getStyle().positionType()) { appendFormattedString( diff --git a/yoga/enums/YogaEnums.h b/yoga/enums/YogaEnums.h index 9621244813..7cbf94b72f 100644 --- a/yoga/enums/YogaEnums.h +++ b/yoga/enums/YogaEnums.h @@ -7,6 +7,8 @@ #pragma once +#include + namespace facebook::yoga { template @@ -15,4 +17,10 @@ constexpr inline int32_t ordinalCount(); template constexpr inline int32_t bitCount(); +// Polyfill of C++ 23 to_underlying() +// https://en.cppreference.com/w/cpp/utility/to_underlying +constexpr auto to_underlying(auto e) noexcept { + return static_cast>(e); +} + } // namespace facebook::yoga diff --git a/yoga/node/LayoutResults.h b/yoga/node/LayoutResults.h index df00993c1a..8b324e6454 100644 --- a/yoga/node/LayoutResults.h +++ b/yoga/node/LayoutResults.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -63,20 +64,20 @@ struct LayoutResults { hadOverflow_ = hadOverflow; } - float dimension(YGDimension axis) const { - return dimensions_[axis]; + float dimension(Dimension axis) const { + return dimensions_[yoga::to_underlying(axis)]; } - void setDimension(YGDimension axis, float dimension) { - dimensions_[axis] = dimension; + void setDimension(Dimension axis, float dimension) { + dimensions_[yoga::to_underlying(axis)] = dimension; } - float measuredDimension(YGDimension axis) const { - return measuredDimensions_[axis]; + float measuredDimension(Dimension axis) const { + return measuredDimensions_[yoga::to_underlying(axis)]; } - void setMeasuredDimension(YGDimension axis, float dimension) { - measuredDimensions_[axis] = dimension; + void setMeasuredDimension(Dimension axis, float dimension) { + measuredDimensions_[yoga::to_underlying(axis)] = dimension; } bool operator==(LayoutResults layout) const; diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index 215b5f38de..908e1aebdc 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -339,7 +339,7 @@ void Node::setLayoutComputedFlexBasisGeneration( void Node::setLayoutMeasuredDimension( float measuredDimension, - YGDimension dimension) { + Dimension dimension) { layout_.setMeasuredDimension(dimension, measuredDimension); } @@ -347,7 +347,7 @@ void Node::setLayoutHadOverflow(bool hadOverflow) { layout_.setHadOverflow(hadOverflow); } -void Node::setLayoutDimension(float dimensionValue, YGDimension dimension) { +void Node::setLayoutDimension(float dimensionValue, Dimension dimension) { layout_.setDimension(dimension, dimensionValue); } @@ -433,14 +433,13 @@ YGValue Node::resolveFlexBasisPtr() const { } void Node::resolveDimension() { - using namespace yoga; const Style& style = getStyle(); - for (auto dim : {YGDimensionWidth, YGDimensionHeight}) { + for (auto dim : {Dimension::Width, Dimension::Height}) { if (!style.maxDimension(dim).isUndefined() && yoga::inexactEquals(style.maxDimension(dim), style.minDimension(dim))) { - resolvedDimensions_[dim] = style.maxDimension(dim); + resolvedDimensions_[yoga::to_underlying(dim)] = style.maxDimension(dim); } else { - resolvedDimensions_[dim] = style.dimension(dim); + resolvedDimensions_[yoga::to_underlying(dim)] = style.dimension(dim); } } } diff --git a/yoga/node/Node.h b/yoga/node/Node.h index 359df8514e..2c89159673 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -175,7 +176,7 @@ class YG_EXPORT Node : public ::YGNode { return resolvedDimensions_; } - YGValue getResolvedDimension(YGDimension dimension) const { + YGValue getResolvedDimension(Dimension dimension) const { return resolvedDimensions_[static_cast(dimension)]; } @@ -293,11 +294,9 @@ class YG_EXPORT Node : public ::YGNode { void setLayoutComputedFlexBasis(const FloatOptional computedFlexBasis); void setLayoutComputedFlexBasisGeneration( uint32_t computedFlexBasisGeneration); - void setLayoutMeasuredDimension( - float measuredDimension, - YGDimension dimension); + void setLayoutMeasuredDimension(float measuredDimension, Dimension dimension); void setLayoutHadOverflow(bool hadOverflow); - void setLayoutDimension(float dimensionValue, YGDimension dimension); + void setLayoutDimension(float dimensionValue, Dimension dimension); void setLayoutDirection(Direction direction); void setLayoutMargin(float margin, YGEdge edge); void setLayoutBorder(float border, YGEdge edge); diff --git a/yoga/style/Style.h b/yoga/style/Style.h index c280c62745..781832e3ac 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -33,7 +34,7 @@ class YG_EXPORT Style { using Values = std::array()>; public: - using Dimensions = Values; + using Dimensions = Values; using Edges = Values; using Gutters = Values; @@ -280,25 +281,25 @@ class YG_EXPORT Style { return {*this}; } - CompactValue dimension(YGDimension axis) const { - return dimensions_[axis]; + CompactValue dimension(Dimension axis) const { + return dimensions_[yoga::to_underlying(axis)]; } - void setDimension(YGDimension axis, CompactValue value) { - dimensions_[axis] = value; + void setDimension(Dimension axis, CompactValue value) { + dimensions_[yoga::to_underlying(axis)] = value; } - CompactValue minDimension(YGDimension axis) const { - return minDimensions_[axis]; + CompactValue minDimension(Dimension axis) const { + return minDimensions_[yoga::to_underlying(axis)]; } - void setMinDimension(YGDimension axis, CompactValue value) { - minDimensions_[axis] = value; + void setMinDimension(Dimension axis, CompactValue value) { + minDimensions_[yoga::to_underlying(axis)] = value; } - CompactValue maxDimension(YGDimension axis) const { - return maxDimensions_[axis]; + CompactValue maxDimension(Dimension axis) const { + return maxDimensions_[yoga::to_underlying(axis)]; } - void setMaxDimension(YGDimension axis, CompactValue value) { - maxDimensions_[axis] = value; + void setMaxDimension(Dimension axis, CompactValue value) { + maxDimensions_[yoga::to_underlying(axis)] = value; } // Yoga specific properties, not compatible with flexbox specification From fa5c16e7a8de4e56990d8375b906e4ebcad38933 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Fri, 22 Sep 2023 00:50:59 -0700 Subject: [PATCH 2/4] Fix handling of negative flex gap Summary: I noticed that we weren't clamping negative flex gap values to zero. This fixes that bug. Differential Revision: D49530494 fbshipit-source-id: 0f1f86a5fbed698f4ab307e3eb5a75f94904989b --- gentest/gentest.js | 2 +- tests/FlexGapTest.cpp | 93 ++++++++++++++++++++++++++++++ yoga/algorithm/CalculateLayout.cpp | 7 +-- yoga/algorithm/FlexLine.cpp | 2 +- yoga/node/Node.cpp | 12 ++-- yoga/node/Node.h | 3 +- 6 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 tests/FlexGapTest.cpp diff --git a/gentest/gentest.js b/gentest/gentest.js index 83fd4ee254..8cca900420 100755 --- a/gentest/gentest.js +++ b/gentest/gentest.js @@ -701,7 +701,7 @@ function calculateTree(root, roundToPixelGrid) { function getYogaStyle(node) { // TODO: Relying on computed style means we cannot test shorthand props like - // "padding", "margin", "gap". + // "padding", "margin", "gap", or negative values. return [ 'direction', 'flex-direction', diff --git a/tests/FlexGapTest.cpp b/tests/FlexGapTest.cpp new file mode 100644 index 0000000000..9699145a79 --- /dev/null +++ b/tests/FlexGapTest.cpp @@ -0,0 +1,93 @@ +/* + * 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. + */ + +#include +#include + +// TODO: move this to a fixture based test once it supports parsing negative +// values +TEST(FlexGap, gap_negative_value) { + const YGConfigRef config = YGConfigNew(); + + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetGap(root, YGGutterAll, -20); + YGNodeStyleSetHeight(root, 200); + + const YGNodeRef root_child0 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child0, 20); + YGNodeInsertChild(root, root_child0, 0); + + const YGNodeRef root_child1 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child1, 20); + YGNodeInsertChild(root, root_child1, 1); + + const YGNodeRef root_child2 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child2, 20); + YGNodeInsertChild(root, root_child2, 2); + + const YGNodeRef root_child3 = YGNodeNewWithConfig(config); + YGNodeStyleSetWidth(root_child3, 20); + YGNodeInsertChild(root, root_child3, 3); + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child3)); + + YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionRTL); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root)); + ASSERT_FLOAT_EQ(80, YGNodeLayoutGetWidth(root)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root)); + + ASSERT_FLOAT_EQ(60, YGNodeLayoutGetLeft(root_child0)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child0)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child0)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child0)); + + ASSERT_FLOAT_EQ(40, YGNodeLayoutGetLeft(root_child1)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child1)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child1)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child1)); + + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetLeft(root_child2)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child2)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child2)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child2)); + + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetLeft(root_child3)); + ASSERT_FLOAT_EQ(0, YGNodeLayoutGetTop(root_child3)); + ASSERT_FLOAT_EQ(20, YGNodeLayoutGetWidth(root_child3)); + ASSERT_FLOAT_EQ(200, YGNodeLayoutGetHeight(root_child3)); + + YGNodeFreeRecursive(root); + + YGConfigFree(config); +} diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 1d0b2d09a4..384de71358 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -1215,7 +1215,7 @@ static void justifyMainAxis( node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); const float trailingPaddingAndBorderMain = node->getTrailingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); - const float gap = node->getGapForAxis(mainAxis, ownerWidth).unwrap(); + const float gap = node->getGapForAxis(mainAxis, ownerWidth); // 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 (measureModeMainDim == MeasureMode::AtMost && @@ -1666,8 +1666,7 @@ static void calculateLayoutImpl( generationCount); if (childCount > 1) { - totalMainDim += - node->getGapForAxis(mainAxis, availableInnerCrossDim).unwrap() * + totalMainDim += node->getGapForAxis(mainAxis, availableInnerCrossDim) * static_cast(childCount - 1); } @@ -1692,7 +1691,7 @@ static void calculateLayoutImpl( float totalLineCrossDim = 0; const float crossAxisGap = - node->getGapForAxis(crossAxis, availableInnerCrossDim).unwrap(); + node->getGapForAxis(crossAxis, availableInnerCrossDim); // Max main dimension of all the lines. float maxLineMainDim = 0; diff --git a/yoga/algorithm/FlexLine.cpp b/yoga/algorithm/FlexLine.cpp index f254a7a573..aab71aa20d 100644 --- a/yoga/algorithm/FlexLine.cpp +++ b/yoga/algorithm/FlexLine.cpp @@ -33,7 +33,7 @@ FlexLine calculateFlexLine( const FlexDirection mainAxis = resolveDirection( node->getStyle().flexDirection(), node->resolveDirection(ownerDirection)); const bool isNodeFlexWrap = node->getStyle().flexWrap() != Wrap::NoWrap; - const float gap = node->getGapForAxis(mainAxis, availableInnerWidth).unwrap(); + const float gap = node->getGapForAxis(mainAxis, availableInnerWidth); // Add items to the current line until it's full or we run out of items. for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index 908e1aebdc..782c68385e 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -202,13 +202,13 @@ FloatOptional Node::getMarginForAxis( return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); } -FloatOptional Node::getGapForAxis( - const FlexDirection axis, - const float widthSize) const { +float Node::getGapForAxis(const FlexDirection axis, const float widthSize) + const { auto gap = isRow(axis) - ? computeColumnGap(style_.gap(), CompactValue::ofZero()) - : computeRowGap(style_.gap(), CompactValue::ofZero()); - return yoga::resolveValue(gap, widthSize); + ? computeColumnGap(style_.gap(), CompactValue::ofUndefined()) + : computeRowGap(style_.gap(), CompactValue::ofUndefined()); + auto resolvedGap = yoga::resolveValue(gap, widthSize); + return maxOrDefined(resolvedGap.unwrap(), 0); } YGSize Node::measure( diff --git a/yoga/node/Node.h b/yoga/node/Node.h index 2c89159673..09c05ebedf 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -231,8 +231,7 @@ class YG_EXPORT Node : public ::YGNode { FloatOptional getMarginForAxis( const FlexDirection axis, const float widthSize) const; - FloatOptional getGapForAxis(const FlexDirection axis, const float widthSize) - const; + float getGapForAxis(const FlexDirection axis, const float widthSize) const; // Setters void setContext(void* context) { From ad2228eeed7cd4dc86f0d73068adcc4ee0b63232 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Fri, 22 Sep 2023 00:50:59 -0700 Subject: [PATCH 3/4] Remove usage of Gutters arrays and YGGutter as index Summary: Similar in vain to D49362819, we want to stop exposing pre-resolved CompactValue, and allow enum class usage without becoming annoying. This also simplifies gap resolution a bit. I moved this to Style, to make it clear we aren't relying on any node state. I plan to do some similar cleanup for other resolution later. Differential Revision: D49530923 fbshipit-source-id: 73191aef09d30f8790b9b4d88c582b318b7b8dbc --- yoga/Yoga.cpp | 4 ++-- yoga/algorithm/CalculateLayout.cpp | 9 ++++---- yoga/algorithm/FlexLine.cpp | 2 +- yoga/debug/NodeToString.cpp | 16 ++++--------- yoga/node/Node.cpp | 37 +++++------------------------- yoga/node/Node.h | 10 +------- yoga/style/Style.h | 24 +++++++++++++++---- 7 files changed, 39 insertions(+), 63 deletions(-) diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index a0119acc8b..865a984e58 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -635,11 +635,11 @@ void YGNodeStyleSetGap( const YGGutter gutter, const float gapLength) { auto length = CompactValue::ofMaybe(gapLength); - updateIndexedStyleProp(node, &Style::gap, gutter, length); + updateIndexedStyleProp<&Style::gap, &Style::setGap>(node, gutter, length); } float YGNodeStyleGetGap(const YGNodeConstRef node, const YGGutter gutter) { - auto gapLength = resolveRef(node)->getStyle().gap()[gutter]; + auto gapLength = resolveRef(node)->getStyle().gap(gutter); if (gapLength.isUndefined() || gapLength.isAuto()) { return YGUndefined; } diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 384de71358..21a6729f36 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -1215,7 +1215,7 @@ static void justifyMainAxis( node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); const float trailingPaddingAndBorderMain = node->getTrailingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); - const float gap = node->getGapForAxis(mainAxis, ownerWidth); + const float gap = node->getGapForAxis(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 (measureModeMainDim == MeasureMode::AtMost && @@ -1666,8 +1666,8 @@ static void calculateLayoutImpl( generationCount); if (childCount > 1) { - totalMainDim += node->getGapForAxis(mainAxis, availableInnerCrossDim) * - static_cast(childCount - 1); + totalMainDim += + node->getGapForAxis(mainAxis) * static_cast(childCount - 1); } const bool mainAxisOverflows = @@ -1690,8 +1690,7 @@ static void calculateLayoutImpl( // Accumulated cross dimensions of all lines so far. float totalLineCrossDim = 0; - const float crossAxisGap = - node->getGapForAxis(crossAxis, availableInnerCrossDim); + const float crossAxisGap = node->getGapForAxis(crossAxis); // Max main dimension of all the lines. float maxLineMainDim = 0; diff --git a/yoga/algorithm/FlexLine.cpp b/yoga/algorithm/FlexLine.cpp index aab71aa20d..a9c044eef3 100644 --- a/yoga/algorithm/FlexLine.cpp +++ b/yoga/algorithm/FlexLine.cpp @@ -33,7 +33,7 @@ FlexLine calculateFlexLine( const FlexDirection mainAxis = resolveDirection( node->getStyle().flexDirection(), node->resolveDirection(ownerDirection)); const bool isNodeFlexWrap = node->getStyle().flexWrap() != Wrap::NoWrap; - const float gap = node->getGapForAxis(mainAxis, availableInnerWidth); + const float gap = node->getGapForAxis(mainAxis); // Add items to the current line until it's full or we run out of items. for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) { diff --git a/yoga/debug/NodeToString.cpp b/yoga/debug/NodeToString.cpp index 9eb090116e..429c2305d3 100644 --- a/yoga/debug/NodeToString.cpp +++ b/yoga/debug/NodeToString.cpp @@ -180,17 +180,11 @@ void nodeToString( appendEdges(str, "padding", style.padding()); appendEdges(str, "border", style.border()); - if (yoga::Node::computeColumnGap( - style.gap(), CompactValue::ofUndefined()) != - yoga::Node::computeColumnGap( - yoga::Node{}.getStyle().gap(), CompactValue::ofUndefined())) { - appendNumberIfNotUndefined( - str, "column-gap", style.gap()[YGGutterColumn]); - } - if (yoga::Node::computeRowGap(style.gap(), CompactValue::ofUndefined()) != - yoga::Node::computeRowGap( - yoga::Node{}.getStyle().gap(), CompactValue::ofUndefined())) { - appendNumberIfNotUndefined(str, "row-gap", style.gap()[YGGutterRow]); + if (!style.gap(YGGutterAll).isUndefined()) { + appendNumberIfNotUndefined(str, "gap", style.gap(YGGutterAll)); + } else { + appendNumberIfNotUndefined(str, "column-gap", style.gap(YGGutterColumn)); + appendNumberIfNotUndefined(str, "row-gap", style.gap(YGGutterRow)); } appendNumberIfNotAuto(str, "width", style.dimension(Dimension::Width)); diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index 782c68385e..8600a8ba61 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -89,30 +89,6 @@ CompactValue Node::computeEdgeValueForColumn( } } -CompactValue Node::computeRowGap( - const Style::Gutters& gutters, - CompactValue defaultValue) { - if (!gutters[YGGutterRow].isUndefined()) { - return gutters[YGGutterRow]; - } else if (!gutters[YGGutterAll].isUndefined()) { - return gutters[YGGutterAll]; - } else { - return defaultValue; - } -} - -CompactValue Node::computeColumnGap( - const Style::Gutters& gutters, - CompactValue defaultValue) { - if (!gutters[YGGutterColumn].isUndefined()) { - return gutters[YGGutterColumn]; - } else if (!gutters[YGGutterAll].isUndefined()) { - return gutters[YGGutterAll]; - } else { - return defaultValue; - } -} - FloatOptional Node::getLeadingPosition( const FlexDirection axis, const float axisSize) const { @@ -202,13 +178,12 @@ FloatOptional Node::getMarginForAxis( return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); } -float Node::getGapForAxis(const FlexDirection axis, const float widthSize) - const { - auto gap = isRow(axis) - ? computeColumnGap(style_.gap(), CompactValue::ofUndefined()) - : computeRowGap(style_.gap(), CompactValue::ofUndefined()); - auto resolvedGap = yoga::resolveValue(gap, widthSize); - return maxOrDefined(resolvedGap.unwrap(), 0); +float Node::getGapForAxis(const FlexDirection axis) const { + auto gap = isRow(axis) ? style_.resolveColumnGap() : style_.resolveRowGap(); + // TODO: Validate percentage gap, and expose ability to set percentage to + // public API + auto resolvedGap = yoga::resolveValue(gap, 0.0f /*ownerSize*/); + return maxOrDefined(resolvedGap.unwrap(), 0.0f); } YGSize Node::measure( diff --git a/yoga/node/Node.h b/yoga/node/Node.h index 09c05ebedf..a98128220e 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -191,14 +191,6 @@ class YG_EXPORT Node : public ::YGNode { YGEdge edge, CompactValue defaultValue); - static CompactValue computeRowGap( - const Style::Gutters& gutters, - CompactValue defaultValue); - - static CompactValue computeColumnGap( - const Style::Gutters& gutters, - CompactValue defaultValue); - // Methods related to positions, margin, padding and border FloatOptional getLeadingPosition( const FlexDirection axis, @@ -231,7 +223,7 @@ class YG_EXPORT Node : public ::YGNode { FloatOptional getMarginForAxis( const FlexDirection axis, const float widthSize) const; - float getGapForAxis(const FlexDirection axis, const float widthSize) const; + float getGapForAxis(const FlexDirection axis) const; // Setters void setContext(void* context) { diff --git a/yoga/style/Style.h b/yoga/style/Style.h index 781832e3ac..c8d7109d82 100644 --- a/yoga/style/Style.h +++ b/yoga/style/Style.h @@ -274,11 +274,11 @@ class YG_EXPORT Style { return {*this}; } - const Gutters& gap() const { - return gap_; + CompactValue gap(YGGutter gutter) const { + return gap_[to_underlying(gutter)]; } - IdxRef gap() { - return {*this}; + void setGap(YGGutter gutter, CompactValue value) { + gap_[to_underlying(gutter)] = value; } CompactValue dimension(Dimension axis) const { @@ -310,6 +310,22 @@ class YG_EXPORT Style { return {*this}; } + CompactValue resolveColumnGap() const { + if (!gap_[to_underlying(YGGutterColumn)].isUndefined()) { + return gap_[to_underlying(YGGutterColumn)]; + } else { + return gap_[to_underlying(YGGutterAll)]; + } + } + + CompactValue resolveRowGap() const { + if (!gap_[to_underlying(YGGutterRow)].isUndefined()) { + return gap_[to_underlying(YGGutterRow)]; + } else { + return gap_[to_underlying(YGGutterAll)]; + } + } + bool operator==(const Style& other) const { return flags == other.flags && inexactEquals(flex_, other.flex_) && inexactEquals(flexGrow_, other.flexGrow_) && From 28468401b0d65a0d35e3b204dcdbe54e57c8756c Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Fri, 22 Sep 2023 00:51:44 -0700 Subject: [PATCH 4/4] Fix style resolution functions returning FloatOptional Summary: These functions all ensure their returns are defined, but return FloatOptional anyway, making their callers have to deal with that possibility. Return `float` instead of `FloatOptional`, and do some additional cleanup. Differential Revision: D49531421 fbshipit-source-id: 60a7072b811c57298220de3a95c81ab0e666088e --- yoga/algorithm/BoundAxis.h | 6 +- yoga/algorithm/CalculateLayout.cpp | 201 +++++++++------------- yoga/algorithm/FlexLine.cpp | 2 +- yoga/debug/NodeToString.cpp | 11 +- yoga/node/Node.cpp | 268 ++++++++++------------------- yoga/node/Node.h | 59 ++----- 6 files changed, 204 insertions(+), 343 deletions(-) diff --git a/yoga/algorithm/BoundAxis.h b/yoga/algorithm/BoundAxis.h index 0972fe2933..02b7b03e5e 100644 --- a/yoga/algorithm/BoundAxis.h +++ b/yoga/algorithm/BoundAxis.h @@ -21,9 +21,9 @@ inline float paddingAndBorderForAxis( const yoga::Node* const node, const FlexDirection axis, const float widthSize) { - return (node->getLeadingPaddingAndBorder(axis, widthSize) + - node->getTrailingPaddingAndBorder(axis, widthSize)) - .unwrap(); + return ( + node->getLeadingPaddingAndBorder(axis, widthSize) + + node->getTrailingPaddingAndBorder(axis, widthSize)); } inline FloatOptional boundAxisWithinMinAndMax( diff --git a/yoga/algorithm/CalculateLayout.cpp b/yoga/algorithm/CalculateLayout.cpp index 21a6729f36..f13af3a277 100644 --- a/yoga/algorithm/CalculateLayout.cpp +++ b/yoga/algorithm/CalculateLayout.cpp @@ -55,8 +55,7 @@ static inline float dimensionWithMargin( const float widthSize) { return node->getLayout().measuredDimension(dimension(axis)) + (node->getLeadingMargin(axis, widthSize) + - node->getTrailingMargin(axis, widthSize)) - .unwrap(); + node->getTrailingMargin(axis, widthSize)); } static inline bool styleDefinesDimension( @@ -187,10 +186,9 @@ static void computeFlexBasisForChild( childWidthMeasureMode = MeasureMode::Undefined; childHeightMeasureMode = MeasureMode::Undefined; - auto marginRow = - child->getMarginForAxis(FlexDirection::Row, ownerWidth).unwrap(); + auto marginRow = child->getMarginForAxis(FlexDirection::Row, ownerWidth); auto marginColumn = - child->getMarginForAxis(FlexDirection::Column, ownerWidth).unwrap(); + child->getMarginForAxis(FlexDirection::Column, ownerWidth); if (isRowStyleDimDefined) { childWidth = @@ -335,9 +333,8 @@ static void layoutAbsoluteChild( MeasureMode childWidthMeasureMode = MeasureMode::Undefined; MeasureMode childHeightMeasureMode = MeasureMode::Undefined; - auto marginRow = child->getMarginForAxis(FlexDirection::Row, width).unwrap(); - auto marginColumn = - child->getMarginForAxis(FlexDirection::Column, width).unwrap(); + auto marginRow = child->getMarginForAxis(FlexDirection::Row, width); + auto marginColumn = child->getMarginForAxis(FlexDirection::Column, width); if (styleDefinesDimension(child, FlexDirection::Row, width)) { childWidth = @@ -353,8 +350,7 @@ static void layoutAbsoluteChild( (node->getLeadingBorder(FlexDirection::Row) + node->getTrailingBorder(FlexDirection::Row)) - (child->getLeadingPosition(FlexDirection::Row, width) + - child->getTrailingPosition(FlexDirection::Row, width)) - .unwrap(); + child->getTrailingPosition(FlexDirection::Row, width)); childWidth = boundAxis(child, FlexDirection::Row, childWidth, width, width); } @@ -374,8 +370,7 @@ static void layoutAbsoluteChild( (node->getLeadingBorder(FlexDirection::Column) + node->getTrailingBorder(FlexDirection::Column)) - (child->getLeadingPosition(FlexDirection::Column, height) + - child->getTrailingPosition(FlexDirection::Column, height)) - .unwrap(); + child->getTrailingPosition(FlexDirection::Column, height)); childHeight = boundAxis(child, FlexDirection::Column, childHeight, height, width); } @@ -432,9 +427,9 @@ static void layoutAbsoluteChild( depth, generationCount); childWidth = child->getLayout().measuredDimension(Dimension::Width) + - child->getMarginForAxis(FlexDirection::Row, width).unwrap(); + child->getMarginForAxis(FlexDirection::Row, width); childHeight = child->getLayout().measuredDimension(Dimension::Height) + - child->getMarginForAxis(FlexDirection::Column, width).unwrap(); + child->getMarginForAxis(FlexDirection::Column, width); } calculateLayoutInternal( @@ -458,10 +453,9 @@ static void layoutAbsoluteChild( node->getLayout().measuredDimension(dimension(mainAxis)) - child->getLayout().measuredDimension(dimension(mainAxis)) - node->getTrailingBorder(mainAxis) - - child->getTrailingMargin(mainAxis, isMainAxisRow ? width : height) - .unwrap() - - child->getTrailingPosition(mainAxis, isMainAxisRow ? width : height) - .unwrap(), + child->getTrailingMargin(mainAxis, isMainAxisRow ? width : height) - + child->getTrailingPosition( + mainAxis, isMainAxisRow ? width : height), leadingEdge(mainAxis)); } else if ( !child->isLeadingPositionDefined(mainAxis) && @@ -484,15 +478,12 @@ static void layoutAbsoluteChild( child->isLeadingPositionDefined(mainAxis)) { child->setLayoutPosition( child->getLeadingPosition( - mainAxis, - node->getLayout().measuredDimension(dimension(mainAxis))) - .unwrap() + + mainAxis, + node->getLayout().measuredDimension(dimension(mainAxis))) + node->getLeadingBorder(mainAxis) + - child - ->getLeadingMargin( - mainAxis, - node->getLayout().measuredDimension(dimension(mainAxis))) - .unwrap(), + child->getLeadingMargin( + mainAxis, + node->getLayout().measuredDimension(dimension(mainAxis))), leadingEdge(mainAxis)); } @@ -502,11 +493,10 @@ static void layoutAbsoluteChild( node->getLayout().measuredDimension(dimension(crossAxis)) - child->getLayout().measuredDimension(dimension(crossAxis)) - node->getTrailingBorder(crossAxis) - - child->getTrailingMargin(crossAxis, isMainAxisRow ? height : width) - .unwrap() - - child - ->getTrailingPosition(crossAxis, isMainAxisRow ? height : width) - .unwrap(), + child->getTrailingMargin( + crossAxis, isMainAxisRow ? height : width) - + child->getTrailingPosition( + crossAxis, isMainAxisRow ? height : width), leadingEdge(crossAxis)); } else if ( @@ -531,15 +521,12 @@ static void layoutAbsoluteChild( child->isLeadingPositionDefined(crossAxis)) { child->setLayoutPosition( child->getLeadingPosition( - crossAxis, - node->getLayout().measuredDimension(dimension(crossAxis))) - .unwrap() + + crossAxis, + node->getLayout().measuredDimension(dimension(crossAxis))) + node->getLeadingBorder(crossAxis) + - child - ->getLeadingMargin( - crossAxis, - node->getLayout().measuredDimension(dimension(crossAxis))) - .unwrap(), + child->getLeadingMargin( + crossAxis, + node->getLayout().measuredDimension(dimension(crossAxis))), leadingEdge(crossAxis)); } } @@ -844,9 +831,8 @@ static float computeFlexBasisForChildren( } totalOuterFlexBasis += - (child->getLayout().computedFlexBasis + - child->getMarginForAxis(mainAxis, availableInnerWidth)) - .unwrap(); + (child->getLayout().computedFlexBasis.unwrap() + + child->getMarginForAxis(mainAxis, availableInnerWidth)); } return totalOuterFlexBasis; @@ -934,11 +920,9 @@ static float distributeFreeSpaceSecondPass( deltaFreeSpace += updatedMainSize - childFlexBasis; const float marginMain = - currentLineChild->getMarginForAxis(mainAxis, availableInnerWidth) - .unwrap(); + currentLineChild->getMarginForAxis(mainAxis, availableInnerWidth); const float marginCross = - currentLineChild->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap(); + currentLineChild->getMarginForAxis(crossAxis, availableInnerWidth); float childCrossSize; float childMainSize = updatedMainSize + marginMain; @@ -1212,9 +1196,9 @@ static void justifyMainAxis( const bool performLayout) { const auto& style = node->getStyle(); const float leadingPaddingAndBorderMain = - node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); + node->getLeadingPaddingAndBorder(mainAxis, ownerWidth); const float trailingPaddingAndBorderMain = - node->getTrailingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); + node->getTrailingPaddingAndBorder(mainAxis, ownerWidth); const float gap = node->getGapForAxis(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 @@ -1317,10 +1301,9 @@ static void justifyMainAxis( // defined, we override the position to whatever the user said (and // margin/border). child->setLayoutPosition( - child->getLeadingPosition(mainAxis, availableInnerMainDim) - .unwrap() + + child->getLeadingPosition(mainAxis, availableInnerMainDim) + node->getLeadingBorder(mainAxis) + - child->getLeadingMargin(mainAxis, availableInnerWidth).unwrap(), + child->getLeadingMargin(mainAxis, availableInnerWidth), leadingEdge(mainAxis)); } } else { @@ -1355,7 +1338,7 @@ static void justifyMainAxis( // because they weren't computed. This means we can't call // dimensionWithMargin. flexLine.layout.mainDim += - child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap() + + child->getMarginForAxis(mainAxis, availableInnerWidth) + childLayout.computedFlexBasis.unwrap(); flexLine.layout.crossDim = availableInnerCrossDim; } else { @@ -1368,16 +1351,12 @@ 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 - ->getLeadingMargin( - FlexDirection::Column, availableInnerWidth) - .unwrap(); + child->getLeadingMargin( + FlexDirection::Column, availableInnerWidth); const float descent = child->getLayout().measuredDimension(Dimension::Height) + - child - ->getMarginForAxis( - FlexDirection::Column, availableInnerWidth) - .unwrap() - + child->getMarginForAxis( + FlexDirection::Column, availableInnerWidth) - ascent; maxAscentForCurrentLine = @@ -1519,16 +1498,16 @@ static void calculateLayoutImpl( const YGEdge endEdge = direction == Direction::LTR ? YGEdgeRight : YGEdgeLeft; const float marginRowLeading = - node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap(); + node->getLeadingMargin(flexRowDirection, ownerWidth); node->setLayoutMargin(marginRowLeading, startEdge); const float marginRowTrailing = - node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap(); + node->getTrailingMargin(flexRowDirection, ownerWidth); node->setLayoutMargin(marginRowTrailing, endEdge); const float marginColumnLeading = - node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap(); + node->getLeadingMargin(flexColumnDirection, ownerWidth); node->setLayoutMargin(marginColumnLeading, YGEdgeTop); const float marginColumnTrailing = - node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap(); + node->getTrailingMargin(flexColumnDirection, ownerWidth); node->setLayoutMargin(marginColumnTrailing, YGEdgeBottom); const float marginAxisRow = marginRowLeading + marginRowTrailing; @@ -1541,16 +1520,13 @@ static void calculateLayoutImpl( node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); node->setLayoutPadding( - node->getLeadingPadding(flexRowDirection, ownerWidth).unwrap(), - startEdge); + node->getLeadingPadding(flexRowDirection, ownerWidth), startEdge); node->setLayoutPadding( - node->getTrailingPadding(flexRowDirection, ownerWidth).unwrap(), endEdge); + node->getTrailingPadding(flexRowDirection, ownerWidth), endEdge); node->setLayoutPadding( - node->getLeadingPadding(flexColumnDirection, ownerWidth).unwrap(), - YGEdgeTop); + node->getLeadingPadding(flexColumnDirection, ownerWidth), YGEdgeTop); node->setLayoutPadding( - node->getTrailingPadding(flexColumnDirection, ownerWidth).unwrap(), - YGEdgeBottom); + node->getTrailingPadding(flexColumnDirection, ownerWidth), YGEdgeBottom); if (node->hasMeasureFunc()) { measureNodeWithMeasureFunc( @@ -1612,9 +1588,9 @@ static void calculateLayoutImpl( const float paddingAndBorderAxisMain = paddingAndBorderForAxis(node, mainAxis, ownerWidth); const float leadingPaddingAndBorderCross = - node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); + node->getLeadingPaddingAndBorder(crossAxis, ownerWidth); const float trailingPaddingAndBorderCross = - node->getTrailingPaddingAndBorder(crossAxis, ownerWidth).unwrap(); + node->getTrailingPaddingAndBorder(crossAxis, ownerWidth); const float paddingAndBorderAxisCross = leadingPaddingAndBorderCross + trailingPaddingAndBorderCross; @@ -1871,11 +1847,9 @@ static void calculateLayoutImpl( child->isLeadingPositionDefined(crossAxis); if (isChildLeadingPosDefined) { child->setLayoutPosition( - child->getLeadingPosition(crossAxis, availableInnerCrossDim) - .unwrap() + + child->getLeadingPosition(crossAxis, availableInnerCrossDim) + node->getLeadingBorder(crossAxis) + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), + child->getLeadingMargin(crossAxis, availableInnerWidth), leadingEdge(crossAxis)); } // If leading position is not defined or calculations result in Nan, @@ -1885,8 +1859,7 @@ static void calculateLayoutImpl( child->getLayout().position[leadingEdge(crossAxis)])) { child->setLayoutPosition( node->getLeadingBorder(crossAxis) + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), + child->getLeadingMargin(crossAxis, availableInnerWidth), leadingEdge(crossAxis)); } } else { @@ -1911,16 +1884,14 @@ static void calculateLayoutImpl( child->getLayout().measuredDimension(dimension(mainAxis)); const auto& childStyle = child->getStyle(); float childCrossSize = !childStyle.aspectRatio().isUndefined() - ? child->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap() + + ? child->getMarginForAxis(crossAxis, availableInnerWidth) + (isMainAxisRow ? childMainSize / childStyle.aspectRatio().unwrap() : childMainSize * childStyle.aspectRatio().unwrap()) : flexLine.layout.crossDim; childMainSize += - child->getMarginForAxis(mainAxis, availableInnerWidth) - .unwrap(); + child->getMarginForAxis(mainAxis, availableInnerWidth); MeasureMode childMainMeasureMode = MeasureMode::Exactly; MeasureMode childCrossMeasureMode = MeasureMode::Exactly; @@ -2077,21 +2048,16 @@ static void calculateLayoutImpl( lineHeight = yoga::maxOrDefined( lineHeight, child->getLayout().measuredDimension(dimension(crossAxis)) + - child->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap()); + child->getMarginForAxis(crossAxis, availableInnerWidth)); } if (resolveChildAlignment(node, child) == Align::Baseline) { const float ascent = calculateBaseline(child) + - child - ->getLeadingMargin( - FlexDirection::Column, availableInnerWidth) - .unwrap(); + child->getLeadingMargin( + FlexDirection::Column, availableInnerWidth); const float descent = child->getLayout().measuredDimension(Dimension::Height) + - child - ->getMarginForAxis( - FlexDirection::Column, availableInnerWidth) - .unwrap() - + child->getMarginForAxis( + FlexDirection::Column, availableInnerWidth) - ascent; maxAscentForCurrentLine = yoga::maxOrDefined(maxAscentForCurrentLine, ascent); @@ -2117,16 +2083,15 @@ static void calculateLayoutImpl( case Align::FlexStart: { child->setLayoutPosition( currentLead + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), + child->getLeadingMargin(crossAxis, availableInnerWidth), leadingEdge(crossAxis)); break; } case Align::FlexEnd: { child->setLayoutPosition( currentLead + lineHeight - - child->getTrailingMargin(crossAxis, availableInnerWidth) - .unwrap() - + child->getTrailingMargin( + crossAxis, availableInnerWidth) - child->getLayout().measuredDimension( dimension(crossAxis)), leadingEdge(crossAxis)); @@ -2144,8 +2109,7 @@ static void calculateLayoutImpl( case Align::Stretch: { child->setLayoutPosition( currentLead + - child->getLeadingMargin(crossAxis, availableInnerWidth) - .unwrap(), + child->getLeadingMargin(crossAxis, availableInnerWidth), leadingEdge(crossAxis)); // Remeasure child with the line height as it as been only @@ -2155,15 +2119,14 @@ static void calculateLayoutImpl( const float childWidth = isMainAxisRow ? (child->getLayout().measuredDimension( Dimension::Width) + - child->getMarginForAxis(mainAxis, availableInnerWidth) - .unwrap()) + child->getMarginForAxis(mainAxis, availableInnerWidth)) : lineHeight; const float childHeight = !isMainAxisRow ? (child->getLayout().measuredDimension( Dimension::Height) + - child->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap()) + child->getMarginForAxis( + crossAxis, availableInnerWidth)) : lineHeight; if (!(yoga::inexactEquals( @@ -2196,10 +2159,8 @@ static void calculateLayoutImpl( child->setLayoutPosition( currentLead + maxAscentForCurrentLine - calculateBaseline(child) + - child - ->getLeadingPosition( - FlexDirection::Column, availableInnerCrossDim) - .unwrap(), + child->getLeadingPosition( + FlexDirection::Column, availableInnerCrossDim), YGEdgeTop); break; @@ -2446,9 +2407,9 @@ bool calculateLayoutInternal( // measurements if at all possible. if (node->hasMeasureFunc()) { const float marginAxisRow = - node->getMarginForAxis(FlexDirection::Row, ownerWidth).unwrap(); + node->getMarginForAxis(FlexDirection::Row, ownerWidth); const float marginAxisColumn = - node->getMarginForAxis(FlexDirection::Column, ownerWidth).unwrap(); + node->getMarginForAxis(FlexDirection::Column, ownerWidth); // First, try to use the layout cache. if (canUseCachedMeasurement( @@ -2679,11 +2640,12 @@ void calculateLayout( MeasureMode widthMeasureMode = MeasureMode::Undefined; const auto& style = node->getStyle(); if (styleDefinesDimension(node, FlexDirection::Row, ownerWidth)) { - width = (yoga::resolveValue( - node->getResolvedDimension(dimension(FlexDirection::Row)), - ownerWidth) + - node->getMarginForAxis(FlexDirection::Row, ownerWidth)) - .unwrap(); + width = + (yoga::resolveValue( + node->getResolvedDimension(dimension(FlexDirection::Row)), + ownerWidth) + .unwrap() + + node->getMarginForAxis(FlexDirection::Row, ownerWidth)); widthMeasureMode = MeasureMode::Exactly; } else if (!yoga::resolveValue( style.maxDimension(Dimension::Width), ownerWidth) @@ -2700,11 +2662,12 @@ void calculateLayout( float height = YGUndefined; MeasureMode heightMeasureMode = MeasureMode::Undefined; if (styleDefinesDimension(node, FlexDirection::Column, ownerHeight)) { - height = (yoga::resolveValue( - node->getResolvedDimension(dimension(FlexDirection::Column)), - ownerHeight) + - node->getMarginForAxis(FlexDirection::Column, ownerWidth)) - .unwrap(); + height = + (yoga::resolveValue( + node->getResolvedDimension(dimension(FlexDirection::Column)), + ownerHeight) + .unwrap() + + node->getMarginForAxis(FlexDirection::Column, ownerWidth)); heightMeasureMode = MeasureMode::Exactly; } else if (!yoga::resolveValue( style.maxDimension(Dimension::Height), ownerHeight) diff --git a/yoga/algorithm/FlexLine.cpp b/yoga/algorithm/FlexLine.cpp index a9c044eef3..d5ccf13640 100644 --- a/yoga/algorithm/FlexLine.cpp +++ b/yoga/algorithm/FlexLine.cpp @@ -47,7 +47,7 @@ FlexLine calculateFlexLine( child->setLineIndex(lineCount); const float childMarginMainAxis = - child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap(); + child->getMarginForAxis(mainAxis, availableInnerWidth); const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap; const float flexBasisWithMinAndMaxConstraints = boundAxisWithinMinAndMax( diff --git a/yoga/debug/NodeToString.cpp b/yoga/debug/NodeToString.cpp index 429c2305d3..0b8e180d96 100644 --- a/yoga/debug/NodeToString.cpp +++ b/yoga/debug/NodeToString.cpp @@ -91,9 +91,8 @@ static void appendEdges( const std::string& key, const Style::Edges& edges) { if (areFourValuesEqual(edges)) { - auto edgeValue = yoga::Node::computeEdgeValueForColumn( - edges, YGEdgeLeft, CompactValue::ofZero()); - appendNumberIfNotZero(base, key, edgeValue); + auto edgeValue = yoga::Node::computeEdgeValueForColumn(edges, YGEdgeLeft); + appendNumberIfNotUndefined(base, key, edgeValue); } else { for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) { std::string str = key + "-" + YGEdgeToString(static_cast(edge)); @@ -109,10 +108,8 @@ static void appendEdgeIfNotUndefined( const YGEdge edge) { // TODO: this doesn't take RTL / YGEdgeStart / YGEdgeEnd into account auto value = (edge == YGEdgeLeft || edge == YGEdgeRight) - ? yoga::Node::computeEdgeValueForRow( - edges, edge, edge, CompactValue::ofUndefined()) - : yoga::Node::computeEdgeValueForColumn( - edges, edge, CompactValue::ofUndefined()); + ? yoga::Node::computeEdgeValueForRow(edges, edge, edge) + : yoga::Node::computeEdgeValueForColumn(edges, edge); appendNumberIfNotUndefined(base, str, value); } diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index 8600a8ba61..5cffa65c77 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -59,131 +59,131 @@ void Node::print() { CompactValue Node::computeEdgeValueForRow( const Style::Edges& edges, YGEdge rowEdge, - YGEdge edge, - CompactValue defaultValue) { + YGEdge edge) { if (!edges[rowEdge].isUndefined()) { return edges[rowEdge]; } else if (!edges[edge].isUndefined()) { return edges[edge]; } else if (!edges[YGEdgeHorizontal].isUndefined()) { return edges[YGEdgeHorizontal]; - } else if (!edges[YGEdgeAll].isUndefined()) { - return edges[YGEdgeAll]; } else { - return defaultValue; + return edges[YGEdgeAll]; } } CompactValue Node::computeEdgeValueForColumn( const Style::Edges& edges, - YGEdge edge, - CompactValue defaultValue) { + YGEdge edge) { if (!edges[edge].isUndefined()) { return edges[edge]; } else if (!edges[YGEdgeVertical].isUndefined()) { return edges[YGEdgeVertical]; - } else if (!edges[YGEdgeAll].isUndefined()) { - return edges[YGEdgeAll]; } else { - return defaultValue; + return edges[YGEdgeAll]; } } -FloatOptional Node::getLeadingPosition( - const FlexDirection axis, - const float axisSize) const { +bool Node::isLeadingPositionDefined(FlexDirection axis) const { auto leadingPosition = isRow(axis) ? computeEdgeValueForRow( - style_.position(), - YGEdgeStart, - leadingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.position(), leadingEdge(axis), CompactValue::ofZero()); - return yoga::resolveValue(leadingPosition, axisSize); -} - -FloatOptional Node::getTrailingPosition( - const FlexDirection axis, - const float axisSize) const { + style_.position(), YGEdgeStart, leadingEdge(axis)) + : computeEdgeValueForColumn(style_.position(), leadingEdge(axis)); + + return !leadingPosition.isUndefined(); +} + +bool Node::isTrailingPosDefined(FlexDirection axis) const { auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow( - style_.position(), - YGEdgeEnd, - trailingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.position(), trailingEdge(axis), CompactValue::ofZero()); - return yoga::resolveValue(trailingPosition, axisSize); + ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, trailingEdge(axis)) + : computeEdgeValueForColumn(style_.position(), trailingEdge(axis)); + + return !trailingPosition.isUndefined(); } -bool Node::isLeadingPositionDefined(const FlexDirection axis) const { +float Node::getLeadingPosition(FlexDirection axis, float axisSize) const { auto leadingPosition = isRow(axis) ? computeEdgeValueForRow( - style_.position(), - YGEdgeStart, - leadingEdge(axis), - CompactValue::ofUndefined()) - : computeEdgeValueForColumn( - style_.position(), leadingEdge(axis), CompactValue::ofUndefined()); - return !leadingPosition.isUndefined(); + style_.position(), YGEdgeStart, leadingEdge(axis)) + : computeEdgeValueForColumn(style_.position(), leadingEdge(axis)); + + return maxOrDefined(resolveValue(leadingPosition, axisSize).unwrap(), 0.0f); } -bool Node::isTrailingPosDefined(const FlexDirection axis) const { +float Node::getTrailingPosition(FlexDirection axis, float axisSize) const { auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow( - style_.position(), - YGEdgeEnd, - trailingEdge(axis), - CompactValue::ofUndefined()) - : computeEdgeValueForColumn( - style_.position(), trailingEdge(axis), CompactValue::ofUndefined()); - return !trailingPosition.isUndefined(); + ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, trailingEdge(axis)) + : computeEdgeValueForColumn(style_.position(), trailingEdge(axis)); + + return maxOrDefined(resolveValue(trailingPosition, axisSize).unwrap(), 0.0f); } -FloatOptional Node::getLeadingMargin( - const FlexDirection axis, - const float widthSize) const { +float Node::getLeadingMargin(FlexDirection axis, float widthSize) const { auto leadingMargin = isRow(axis) - ? computeEdgeValueForRow( - style_.margin(), - YGEdgeStart, - leadingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.margin(), leadingEdge(axis), CompactValue::ofZero()); - return leadingMargin.isAuto() ? FloatOptional{0} - : yoga::resolveValue(leadingMargin, widthSize); -} - -FloatOptional Node::getTrailingMargin( - const FlexDirection axis, - const float widthSize) const { + ? computeEdgeValueForRow(style_.margin(), YGEdgeStart, leadingEdge(axis)) + : computeEdgeValueForColumn(style_.margin(), leadingEdge(axis)); + + return maxOrDefined(resolveValue(leadingMargin, widthSize).unwrap(), 0.0f); +} + +float Node::getTrailingMargin(FlexDirection axis, float widthSize) const { auto trailingMargin = isRow(axis) - ? computeEdgeValueForRow( - style_.margin(), - YGEdgeEnd, - trailingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.margin(), trailingEdge(axis), CompactValue::ofZero()); - return trailingMargin.isAuto() - ? FloatOptional{0} - : yoga::resolveValue(trailingMargin, widthSize); -} - -FloatOptional Node::getMarginForAxis( - const FlexDirection axis, - const float widthSize) const { + ? computeEdgeValueForRow(style_.margin(), YGEdgeEnd, trailingEdge(axis)) + : computeEdgeValueForColumn(style_.margin(), trailingEdge(axis)); + + return maxOrDefined(resolveValue(trailingMargin, widthSize).unwrap(), 0.0f); +} + +float Node::getLeadingBorder(FlexDirection axis) const { + YGValue leadingBorder = isRow(axis) + ? computeEdgeValueForRow(style_.border(), YGEdgeStart, leadingEdge(axis)) + : computeEdgeValueForColumn(style_.border(), leadingEdge(axis)); + + return maxOrDefined(leadingBorder.value, 0.0f); +} + +float Node::getTrailingBorder(FlexDirection axis) const { + YGValue trailingBorder = isRow(axis) + ? computeEdgeValueForRow(style_.border(), YGEdgeEnd, trailingEdge(axis)) + : computeEdgeValueForColumn(style_.border(), trailingEdge(axis)); + + return maxOrDefined(trailingBorder.value, 0.0f); +} + +float Node::getLeadingPadding(FlexDirection axis, float widthSize) const { + auto leadingPadding = isRow(axis) + ? computeEdgeValueForRow(style_.padding(), YGEdgeStart, leadingEdge(axis)) + : computeEdgeValueForColumn(style_.padding(), leadingEdge(axis)); + + return maxOrDefined(resolveValue(leadingPadding, widthSize).unwrap(), 0.0f); +} + +float Node::getTrailingPadding(FlexDirection axis, float widthSize) const { + auto trailingPadding = isRow(axis) + ? computeEdgeValueForRow(style_.padding(), YGEdgeEnd, trailingEdge(axis)) + : computeEdgeValueForColumn(style_.padding(), trailingEdge(axis)); + + return maxOrDefined(resolveValue(trailingPadding, widthSize).unwrap(), 0.0f); +} + +float Node::getLeadingPaddingAndBorder(FlexDirection axis, float widthSize) + const { + return getLeadingPadding(axis, widthSize) + getLeadingBorder(axis); +} + +float Node::getTrailingPaddingAndBorder(FlexDirection axis, float widthSize) + const { + return getTrailingPadding(axis, widthSize) + getTrailingBorder(axis); +} + +float Node::getMarginForAxis(FlexDirection axis, float widthSize) const { return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); } -float Node::getGapForAxis(const FlexDirection axis) const { +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 - auto resolvedGap = yoga::resolveValue(gap, 0.0f /*ownerSize*/); - return maxOrDefined(resolvedGap.unwrap(), 0.0f); + return maxOrDefined(resolveValue(gap, 0.0f /*ownerSize*/).unwrap(), 0.0f); } YGSize Node::measure( @@ -328,18 +328,12 @@ void Node::setLayoutDimension(float dimensionValue, Dimension dimension) { // If both left and right are defined, then use left. Otherwise return +left or // -right depending on which is defined. -FloatOptional Node::relativePosition( - const FlexDirection axis, - const float axisSize) const { +float Node::relativePosition(FlexDirection axis, float axisSize) const { if (isLeadingPositionDefined(axis)) { return getLeadingPosition(axis, axisSize); } - FloatOptional trailingPosition = getTrailingPosition(axis, axisSize); - if (!trailingPosition.isUndefined()) { - trailingPosition = FloatOptional{-1 * trailingPosition.unwrap()}; - } - return trailingPosition; + return -1 * getTrailingPosition(axis, axisSize); } void Node::setPosition( @@ -359,28 +353,24 @@ void Node::setPosition( // Here we should check for `PositionType::Static` and in this case zero inset // properties (left, right, top, bottom, begin, end). // https://www.w3.org/TR/css-position-3/#valdef-position-static - const FloatOptional relativePositionMain = - relativePosition(mainAxis, mainSize); - const FloatOptional relativePositionCross = - relativePosition(crossAxis, crossSize); + const float relativePositionMain = relativePosition(mainAxis, mainSize); + const float relativePositionCross = relativePosition(crossAxis, crossSize); setLayoutPosition( - (getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), + (getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain), leadingEdge(mainAxis)); setLayoutPosition( - (getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(), + (getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain), trailingEdge(mainAxis)); setLayoutPosition( - (getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross) - .unwrap(), + (getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross), leadingEdge(crossAxis)); setLayoutPosition( - (getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross) - .unwrap(), + (getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross), trailingEdge(crossAxis)); } -YGValue Node::marginLeadingValue(const FlexDirection axis) const { +YGValue Node::marginLeadingValue(FlexDirection axis) const { if (isRow(axis) && !style_.margin()[YGEdgeStart].isUndefined()) { return style_.margin()[YGEdgeStart]; } else { @@ -388,7 +378,7 @@ YGValue Node::marginLeadingValue(const FlexDirection axis) const { } } -YGValue Node::marginTrailingValue(const FlexDirection axis) const { +YGValue Node::marginTrailingValue(FlexDirection axis) const { if (isRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) { return style_.margin()[YGEdgeEnd]; } else { @@ -498,74 +488,6 @@ bool Node::isNodeFlexible() { (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); } -float Node::getLeadingBorder(const FlexDirection axis) const { - YGValue leadingBorder = isRow(axis) - ? computeEdgeValueForRow( - style_.border(), - YGEdgeStart, - leadingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.border(), leadingEdge(axis), CompactValue::ofZero()); - return fmaxf(leadingBorder.value, 0.0f); -} - -float Node::getTrailingBorder(const FlexDirection axis) const { - YGValue trailingBorder = isRow(axis) - ? computeEdgeValueForRow( - style_.border(), - YGEdgeEnd, - trailingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.border(), trailingEdge(axis), CompactValue::ofZero()); - return fmaxf(trailingBorder.value, 0.0f); -} - -FloatOptional Node::getLeadingPadding( - const FlexDirection axis, - const float widthSize) const { - auto leadingPadding = isRow(axis) - ? computeEdgeValueForRow( - style_.padding(), - YGEdgeStart, - leadingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.padding(), leadingEdge(axis), CompactValue::ofZero()); - return yoga::maxOrDefined( - yoga::resolveValue(leadingPadding, widthSize), FloatOptional(0.0f)); -} - -FloatOptional Node::getTrailingPadding( - const FlexDirection axis, - const float widthSize) const { - auto trailingPadding = isRow(axis) - ? computeEdgeValueForRow( - style_.padding(), - YGEdgeEnd, - trailingEdge(axis), - CompactValue::ofZero()) - : computeEdgeValueForColumn( - style_.padding(), trailingEdge(axis), CompactValue::ofZero()); - return yoga::maxOrDefined( - yoga::resolveValue(trailingPadding, widthSize), FloatOptional(0.0f)); -} - -FloatOptional Node::getLeadingPaddingAndBorder( - const FlexDirection axis, - const float widthSize) const { - return getLeadingPadding(axis, widthSize) + - FloatOptional(getLeadingBorder(axis)); -} - -FloatOptional Node::getTrailingPaddingAndBorder( - const FlexDirection axis, - const float widthSize) const { - return getTrailingPadding(axis, widthSize) + - FloatOptional(getTrailingBorder(axis)); -} - void Node::reset() { yoga::assertFatalWithNode( this, diff --git a/yoga/node/Node.h b/yoga/node/Node.h index a98128220e..bf1f89f332 100644 --- a/yoga/node/Node.h +++ b/yoga/node/Node.h @@ -48,8 +48,7 @@ class YG_EXPORT Node : public ::YGNode { std::array resolvedDimensions_ = { {YGValueUndefined, YGValueUndefined}}; - FloatOptional relativePosition(const FlexDirection axis, const float axisSize) - const; + float relativePosition(FlexDirection axis, const float axisSize) const; void useWebDefaults() { style_.flexDirection() = FlexDirection::Row; @@ -182,48 +181,28 @@ class YG_EXPORT Node : public ::YGNode { static CompactValue computeEdgeValueForColumn( const Style::Edges& edges, - YGEdge edge, - CompactValue defaultValue); + YGEdge edge); static CompactValue computeEdgeValueForRow( const Style::Edges& edges, YGEdge rowEdge, - YGEdge edge, - CompactValue defaultValue); + YGEdge edge); // Methods related to positions, margin, padding and border - FloatOptional getLeadingPosition( - const FlexDirection axis, - const float axisSize) const; - bool isLeadingPositionDefined(const FlexDirection axis) const; - bool isTrailingPosDefined(const FlexDirection axis) const; - FloatOptional getTrailingPosition( - const FlexDirection axis, - const float axisSize) const; - FloatOptional getLeadingMargin( - const FlexDirection axis, - const float widthSize) const; - FloatOptional getTrailingMargin( - const FlexDirection axis, - const float widthSize) const; - float getLeadingBorder(const FlexDirection flexDirection) const; - float getTrailingBorder(const FlexDirection flexDirection) const; - FloatOptional getLeadingPadding( - const FlexDirection axis, - const float widthSize) const; - FloatOptional getTrailingPadding( - const FlexDirection axis, - const float widthSize) const; - FloatOptional getLeadingPaddingAndBorder( - const FlexDirection axis, - const float widthSize) const; - FloatOptional getTrailingPaddingAndBorder( - const FlexDirection axis, - const float widthSize) const; - FloatOptional getMarginForAxis( - const FlexDirection axis, - const float widthSize) const; - float getGapForAxis(const FlexDirection axis) const; + bool isLeadingPositionDefined(FlexDirection axis) const; + 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 getLeadingBorder(FlexDirection flexDirection) const; + float getTrailingBorder(FlexDirection flexDirection) const; + float getLeadingPadding(FlexDirection axis, float widthSize) const; + float getTrailingPadding(FlexDirection axis, float widthSize) const; + float getLeadingPaddingAndBorder(FlexDirection axis, float widthSize) const; + float getTrailingPaddingAndBorder(FlexDirection axis, float widthSize) const; + float getMarginForAxis(FlexDirection axis, float widthSize) const; + float getGapForAxis(FlexDirection axis) const; // Setters void setContext(void* context) { @@ -301,8 +280,8 @@ class YG_EXPORT Node : public ::YGNode { void markDirtyAndPropagateDownwards(); // Other methods - YGValue marginLeadingValue(const FlexDirection axis) const; - YGValue marginTrailingValue(const FlexDirection axis) const; + YGValue marginLeadingValue(FlexDirection axis) const; + YGValue marginTrailingValue(FlexDirection axis) const; YGValue resolveFlexBasisPtr() const; void resolveDimension(); Direction resolveDirection(const Direction ownerDirection);