From 8362a0687fce069feb7dd07443dc399962f42d0f Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Tue, 19 Dec 2023 11:43:57 -0800 Subject: [PATCH] yoga::resolveValue -> Length::resolve (#41939) Summary: X-link: https://github.com/facebook/yoga/pull/1520 This code originates as `YGValueResolve`, used to compute a YGValue to a length in points, using a reference for 100%. This moves it to `Style::Length`, so we can encapsulate parts of it (for style value functions), and make the API more cohesive now that we can do C++ style OOP with it. Changelog: [Internal] Reviewed By: joevilches Differential Revision: D51796973 --- .../yoga/yoga/algorithm/AbsoluteLayout.cpp | 13 +-- .../yoga/yoga/algorithm/BoundAxis.h | 13 +-- .../yoga/yoga/algorithm/CalculateLayout.cpp | 99 ++++++++----------- .../yoga/yoga/algorithm/ResolveValue.h | 28 ------ .../ReactCommon/yoga/yoga/node/Node.cpp | 27 +++-- .../ReactCommon/yoga/yoga/style/StyleLength.h | 11 +++ 6 files changed, 74 insertions(+), 117 deletions(-) delete mode 100644 packages/react-native/ReactCommon/yoga/yoga/algorithm/ResolveValue.h diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp index e9b9aec1f23f39..abeab5c1603871 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.cpp @@ -9,7 +9,6 @@ #include #include #include -#include namespace facebook::yoga { @@ -323,10 +322,9 @@ void layoutAbsoluteChild( child->getMarginForAxis(FlexDirection::Column, containingBlockWidth); if (child->styleDefinesDimension(FlexDirection::Row, containingBlockWidth)) { - childWidth = - yoga::resolveValue( - child->getResolvedDimension(Dimension::Width), containingBlockWidth) - .unwrap() + + childWidth = child->getResolvedDimension(Dimension::Width) + .resolve(containingBlockWidth) + .unwrap() + marginRow; } else { // If the child doesn't have a specified width, compute the width based on @@ -352,9 +350,8 @@ void layoutAbsoluteChild( if (child->styleDefinesDimension( FlexDirection::Column, containingBlockHeight)) { - childHeight = yoga::resolveValue( - child->getResolvedDimension(Dimension::Height), - containingBlockHeight) + childHeight = child->getResolvedDimension(Dimension::Height) + .resolve(containingBlockHeight) .unwrap() + marginColumn; } else { diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h b/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h index b5d1be53b649a6..3fda50b11e0a1a 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include #include @@ -36,15 +35,11 @@ inline FloatOptional boundAxisWithinMinAndMax( FloatOptional max; if (isColumn(axis)) { - min = yoga::resolveValue( - node->getStyle().minDimension(Dimension::Height), axisSize); - max = yoga::resolveValue( - node->getStyle().maxDimension(Dimension::Height), axisSize); + min = node->getStyle().minDimension(Dimension::Height).resolve(axisSize); + max = node->getStyle().maxDimension(Dimension::Height).resolve(axisSize); } else if (isRow(axis)) { - min = yoga::resolveValue( - node->getStyle().minDimension(Dimension::Width), axisSize); - max = yoga::resolveValue( - node->getStyle().maxDimension(Dimension::Width), axisSize); + min = node->getStyle().minDimension(Dimension::Width).resolve(axisSize); + max = node->getStyle().maxDimension(Dimension::Width).resolve(axisSize); } if (max >= FloatOptional{0} && value > max) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 0d970ca9005d4a..9d5c1b58e350ee 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -52,15 +51,14 @@ bool calculateLayoutInternal( const uint32_t generationCount); static void constrainMaxSizeForMode( - const yoga::Node* const node, - const enum FlexDirection axis, - const float ownerAxisSize, - const float ownerWidth, - SizingMode* mode, - float* size) { + const yoga::Node* node, + FlexDirection axis, + float ownerAxisSize, + float ownerWidth, + /*in_out*/ SizingMode* mode, + /*in_out*/ float* size) { const FloatOptional maxSize = - yoga::resolveValue( - node->getStyle().maxDimension(dimension(axis)), ownerAxisSize) + + node->getStyle().maxDimension(dimension(axis)).resolve(ownerAxisSize) + FloatOptional(node->getMarginForAxis(axis, ownerWidth)); switch (*mode) { case SizingMode::StretchFit: @@ -103,7 +101,7 @@ static void computeFlexBasisForChild( SizingMode childHeightSizingMode; const FloatOptional resolvedFlexBasis = - yoga::resolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize); + child->resolveFlexBasisPtr().resolve(mainAxisownerSize); const bool isRowStyleDimDefined = child->styleDefinesDimension(FlexDirection::Row, ownerWidth); const bool isColumnStyleDimDefined = @@ -125,16 +123,14 @@ static void computeFlexBasisForChild( paddingAndBorderForAxis(child, FlexDirection::Row, ownerWidth)); child->setLayoutComputedFlexBasis(yoga::maxOrDefined( - yoga::resolveValue( - child->getResolvedDimension(Dimension::Width), ownerWidth), + child->getResolvedDimension(Dimension::Width).resolve(ownerWidth), paddingAndBorder)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { // The height is definite, so use that as the flex basis. const FloatOptional paddingAndBorder = FloatOptional( paddingAndBorderForAxis(child, FlexDirection::Column, ownerWidth)); child->setLayoutComputedFlexBasis(yoga::maxOrDefined( - yoga::resolveValue( - child->getResolvedDimension(Dimension::Height), ownerHeight), + child->getResolvedDimension(Dimension::Height).resolve(ownerHeight), paddingAndBorder)); } else { // Compute the flex basis and hypothetical main size (i.e. the clamped flex @@ -149,18 +145,16 @@ static void computeFlexBasisForChild( child->getMarginForAxis(FlexDirection::Column, ownerWidth); if (isRowStyleDimDefined) { - childWidth = - yoga::resolveValue( - child->getResolvedDimension(Dimension::Width), ownerWidth) - .unwrap() + + childWidth = child->getResolvedDimension(Dimension::Width) + .resolve(ownerWidth) + .unwrap() + marginRow; childWidthSizingMode = SizingMode::StretchFit; } if (isColumnStyleDimDefined) { - childHeight = - yoga::resolveValue( - child->getResolvedDimension(Dimension::Height), ownerHeight) - .unwrap() + + childHeight = child->getResolvedDimension(Dimension::Height) + .resolve(ownerHeight) + .unwrap() + marginColumn; childHeightSizingMode = SizingMode::StretchFit; } @@ -477,13 +471,13 @@ static float calculateAvailableInnerDimension( // We want to make sure our available height does not violate min and max // constraints const FloatOptional minDimensionOptional = - yoga::resolveValue(node->getStyle().minDimension(dimension), ownerDim); + node->getStyle().minDimension(dimension).resolve(ownerDim); const float minInnerDim = minDimensionOptional.isUndefined() ? 0.0f : minDimensionOptional.unwrap() - paddingAndBorder; const FloatOptional maxDimensionOptional = - yoga::resolveValue(node->getStyle().maxDimension(dimension), ownerDim); + node->getStyle().maxDimension(dimension).resolve(ownerDim); const float maxInnerDim = maxDimensionOptional.isUndefined() ? FLT_MAX @@ -700,9 +694,8 @@ static float distributeFreeSpaceSecondPass( : SizingMode::FitContent; } else { childCrossSize = - yoga::resolveValue( - currentLineChild->getResolvedDimension(dimension(crossAxis)), - availableInnerCrossDim) + currentLineChild->getResolvedDimension(dimension(crossAxis)) + .resolve(availableInnerCrossDim) .unwrap() + marginCross; const bool isLoosePercentageMeasurement = @@ -954,8 +947,8 @@ static void justifyMainAxis( if (sizingModeMainDim == SizingMode::FitContent && flexLine.layout.remainingFreeSpace > 0) { if (style.minDimension(dimension(mainAxis)).isDefined() && - yoga::resolveValue( - style.minDimension(dimension(mainAxis)), mainAxisownerSize) + style.minDimension(dimension(mainAxis)) + .resolve(mainAxisownerSize) .isDefined()) { // This condition makes sure that if the size of main dimension(after // considering child nodes main dim, leading and trailing padding etc) @@ -964,10 +957,9 @@ static void justifyMainAxis( // `minAvailableMainDim` denotes minimum available space in which child // can be laid out, it will exclude space consumed by padding and border. - const float minAvailableMainDim = - yoga::resolveValue( - style.minDimension(dimension(mainAxis)), mainAxisownerSize) - .unwrap() - + const float minAvailableMainDim = style.minDimension(dimension(mainAxis)) + .resolve(mainAxisownerSize) + .unwrap() - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; const float occupiedSpaceByChildNodes = availableInnerMainDim - flexLine.layout.remainingFreeSpace; @@ -1446,20 +1438,16 @@ static void calculateLayoutImpl( if (sizingModeMainDim != SizingMode::StretchFit) { const auto& style = node->getStyle(); const float minInnerWidth = - yoga::resolveValue(style.minDimension(Dimension::Width), ownerWidth) - .unwrap() - + style.minDimension(Dimension::Width).resolve(ownerWidth).unwrap() - paddingAndBorderAxisRow; const float maxInnerWidth = - yoga::resolveValue(style.maxDimension(Dimension::Width), ownerWidth) - .unwrap() - + style.maxDimension(Dimension::Width).resolve(ownerWidth).unwrap() - paddingAndBorderAxisRow; const float minInnerHeight = - yoga::resolveValue(style.minDimension(Dimension::Height), ownerHeight) - .unwrap() - + style.minDimension(Dimension::Height).resolve(ownerHeight).unwrap() - paddingAndBorderAxisColumn; const float maxInnerHeight = - yoga::resolveValue(style.maxDimension(Dimension::Height), ownerHeight) - .unwrap() - + style.maxDimension(Dimension::Height).resolve(ownerHeight).unwrap() - paddingAndBorderAxisColumn; const float minInnerMainDim = @@ -1748,9 +1736,8 @@ static void calculateLayoutImpl( const float unclampedCrossDim = sizingModeCrossDim == SizingMode::StretchFit ? availableInnerCrossDim + paddingAndBorderAxisCross : node->styleDefinesDimension(crossAxis, crossAxisownerSize) - ? yoga::resolveValue( - node->getResolvedDimension(dimension(crossAxis)), - crossAxisownerSize) + ? node->getResolvedDimension(dimension(crossAxis)) + .resolve(crossAxisownerSize) .unwrap() : totalLineCrossDim + paddingAndBorderAxisCross; @@ -2442,17 +2429,15 @@ void calculateLayout( const auto& style = node->getStyle(); if (node->styleDefinesDimension(FlexDirection::Row, ownerWidth)) { width = - (yoga::resolveValue( - node->getResolvedDimension(dimension(FlexDirection::Row)), - ownerWidth) + (node->getResolvedDimension(dimension(FlexDirection::Row)) + .resolve(ownerWidth) .unwrap() + node->getMarginForAxis(FlexDirection::Row, ownerWidth)); widthSizingMode = SizingMode::StretchFit; - } else if (yoga::resolveValue( - style.maxDimension(Dimension::Width), ownerWidth) + } else if (style.maxDimension(Dimension::Width) + .resolve(ownerWidth) .isDefined()) { - width = yoga::resolveValue(style.maxDimension(Dimension::Width), ownerWidth) - .unwrap(); + width = style.maxDimension(Dimension::Width).resolve(ownerWidth).unwrap(); widthSizingMode = SizingMode::FitContent; } else { width = ownerWidth; @@ -2464,18 +2449,16 @@ void calculateLayout( SizingMode heightSizingMode = SizingMode::MaxContent; if (node->styleDefinesDimension(FlexDirection::Column, ownerHeight)) { height = - (yoga::resolveValue( - node->getResolvedDimension(dimension(FlexDirection::Column)), - ownerHeight) + (node->getResolvedDimension(dimension(FlexDirection::Column)) + .resolve(ownerHeight) .unwrap() + node->getMarginForAxis(FlexDirection::Column, ownerWidth)); heightSizingMode = SizingMode::StretchFit; - } else if (yoga::resolveValue( - style.maxDimension(Dimension::Height), ownerHeight) + } else if (style.maxDimension(Dimension::Height) + .resolve(ownerHeight) .isDefined()) { height = - yoga::resolveValue(style.maxDimension(Dimension::Height), ownerHeight) - .unwrap(); + style.maxDimension(Dimension::Height).resolve(ownerHeight).unwrap(); heightSizingMode = SizingMode::FitContent; } else { height = ownerHeight; diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/ResolveValue.h b/packages/react-native/ReactCommon/yoga/yoga/algorithm/ResolveValue.h deleted file mode 100644 index 4ff89184ed5ac2..00000000000000 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/ResolveValue.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 - -#include -#include - -namespace facebook::yoga { - -inline FloatOptional resolveValue(Style::Length length, float ownerSize) { - switch (length.unit()) { - case Unit::Point: - return length.value(); - case Unit::Percent: - return FloatOptional{length.value().unwrap() * ownerSize * 0.01f}; - default: - return FloatOptional{}; - } -} - -} // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index 0af0aea65c7ac6..e09c8e8295c185 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -166,7 +165,7 @@ float Node::getFlexStartPosition( flexStartEdge(axis)) : computeEdgeValueForColumn<&Style::position>(flexStartEdge(axis)); - return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f); + return leadingPosition.resolve(axisSize).unwrapOrDefault(0.0f); } float Node::getInlineStartPosition( @@ -178,7 +177,7 @@ float Node::getInlineStartPosition( ? computeEdgeValueForRow<&Style::position>(Edge::Start, startEdge) : computeEdgeValueForColumn<&Style::position>(startEdge); - return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f); + return leadingPosition.resolve(axisSize).unwrapOrDefault(0.0f); } float Node::getFlexEndPosition( @@ -191,7 +190,7 @@ float Node::getFlexEndPosition( flexEndEdge(axis)) : computeEdgeValueForColumn<&Style::position>(flexEndEdge(axis)); - return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f); + return trailingPosition.resolve(axisSize).unwrapOrDefault(0.0f); } float Node::getInlineEndPosition( @@ -203,7 +202,7 @@ float Node::getInlineEndPosition( ? computeEdgeValueForRow<&Style::position>(Edge::End, endEdge) : computeEdgeValueForColumn<&Style::position>(endEdge); - return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f); + return trailingPosition.resolve(axisSize).unwrapOrDefault(0.0f); } float Node::getFlexStartMargin( @@ -216,7 +215,7 @@ float Node::getFlexStartMargin( flexStartEdge(axis)) : computeEdgeValueForColumn<&Style::margin>(flexStartEdge(axis)); - return resolveValue(leadingMargin, widthSize).unwrapOrDefault(0.0f); + return leadingMargin.resolve(widthSize).unwrapOrDefault(0.0f); } float Node::getInlineStartMargin( @@ -228,7 +227,7 @@ float Node::getInlineStartMargin( ? computeEdgeValueForRow<&Style::margin>(Edge::Start, startEdge) : computeEdgeValueForColumn<&Style::margin>(startEdge); - return resolveValue(leadingMargin, widthSize).unwrapOrDefault(0.0f); + return leadingMargin.resolve(widthSize).unwrapOrDefault(0.0f); } float Node::getFlexEndMargin( @@ -241,7 +240,7 @@ float Node::getFlexEndMargin( flexEndEdge(axis)) : computeEdgeValueForColumn<&Style::margin>(flexEndEdge(axis)); - return resolveValue(trailingMargin, widthSize).unwrapOrDefault(0.0f); + return trailingMargin.resolve(widthSize).unwrapOrDefault(0.0f); } float Node::getInlineEndMargin( @@ -253,7 +252,7 @@ float Node::getInlineEndMargin( ? computeEdgeValueForRow<&Style::margin>(Edge::End, endEdge) : computeEdgeValueForColumn<&Style::margin>(endEdge); - return resolveValue(trailingMargin, widthSize).unwrapOrDefault(0.0f); + return trailingMargin.resolve(widthSize).unwrapOrDefault(0.0f); } float Node::getInlineStartBorder(FlexDirection axis, Direction direction) @@ -304,7 +303,7 @@ float Node::getInlineStartPadding( ? computeEdgeValueForRow<&Style::padding>(Edge::Start, startEdge) : computeEdgeValueForColumn<&Style::padding>(startEdge); - return maxOrDefined(resolveValue(leadingPadding, widthSize).unwrap(), 0.0f); + return maxOrDefined(leadingPadding.resolve(widthSize).unwrap(), 0.0f); } float Node::getFlexStartPadding( @@ -317,7 +316,7 @@ float Node::getFlexStartPadding( flexStartEdge(axis)) : computeEdgeValueForColumn<&Style::padding>(flexStartEdge(axis)); - return maxOrDefined(resolveValue(leadingPadding, widthSize).unwrap(), 0.0f); + return maxOrDefined(leadingPadding.resolve(widthSize).unwrap(), 0.0f); } float Node::getInlineEndPadding( @@ -329,7 +328,7 @@ float Node::getInlineEndPadding( ? computeEdgeValueForRow<&Style::padding>(Edge::End, endEdge) : computeEdgeValueForColumn<&Style::padding>(endEdge); - return maxOrDefined(resolveValue(trailingPadding, widthSize).unwrap(), 0.0f); + return maxOrDefined(trailingPadding.resolve(widthSize).unwrap(), 0.0f); } float Node::getFlexEndPadding( @@ -342,7 +341,7 @@ float Node::getFlexEndPadding( flexEndEdge(axis)) : computeEdgeValueForColumn<&Style::padding>(flexEndEdge(axis)); - return maxOrDefined(resolveValue(trailingPadding, widthSize).unwrap(), 0.0f); + return maxOrDefined(trailingPadding.resolve(widthSize).unwrap(), 0.0f); } float Node::getInlineStartPaddingAndBorder( @@ -393,7 +392,7 @@ 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(resolveValue(gap, 0.0f /*ownerSize*/).unwrap(), 0.0f); + return maxOrDefined(gap.resolve(0.0f /*ownerSize*/).unwrap(), 0.0f); } YGSize Node::measure( diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h index 7212e573d19719..242698abf4e49b 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h @@ -71,6 +71,17 @@ class StyleLength { return unit_; } + constexpr FloatOptional resolve(float referenceLength) { + switch (unit_) { + case Unit::Point: + return value_; + case Unit::Percent: + return FloatOptional{value_.unwrap() * referenceLength * 0.01f}; + default: + return FloatOptional{}; + } + } + explicit constexpr operator YGValue() const { return YGValue{value_.unwrap(), unscopedEnum(unit_)}; }