diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index 24b75a79942d49..0278dbf8a909e3 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -82,18 +82,19 @@ inline yoga::FloatOptional yogaOptionalFloatFromFloat(Float value) { } inline std::optional optionalFloatFromYogaValue( - const YGValue value, + const yoga::Style::Length& length, std::optional base = {}) { - switch (value.unit) { - case YGUnitUndefined: + switch (length.unit()) { + case yoga::Unit::Undefined: return {}; - case YGUnitPoint: - return floatFromYogaFloat(value.value); - case YGUnitPercent: + case yoga::Unit::Point: + return floatFromYogaOptionalFloat(length.value()); + case yoga::Unit::Percent: return base.has_value() - ? std::optional(base.value() * floatFromYogaFloat(value.value)) + ? std::optional( + base.value() * floatFromYogaOptionalFloat(length.value())) : std::optional(); - case YGUnitAuto: + case yoga::Unit::Auto: return {}; } } @@ -417,7 +418,7 @@ inline void fromRawValue( } else if (value.hasType()) { const auto stringValue = (std::string)value; if (stringValue == "auto") { - result = YGValueAuto; + result = yoga::value::ofAuto(); return; } else { if (stringValue.back() == '%') { @@ -436,16 +437,16 @@ inline void fromRawValue( } } } - result = YGValueUndefined; + result = yoga::value::undefined(); } inline void fromRawValue( const PropsParserContext& context, const RawValue& value, YGValue& result) { - yoga::Style::Length ygValue{}; - fromRawValue(context, value, ygValue); - result = ygValue; + yoga::Style::Length length{}; + fromRawValue(context, value, length); + result = (YGValue)length; } inline void fromRawValue( @@ -772,15 +773,15 @@ inline std::string toString(const yoga::Display& value) { return YGDisplayToString(yoga::unscopedEnum(value)); } -inline std::string toString(const YGValue& value) { - switch (value.unit) { - case YGUnitUndefined: +inline std::string toString(const yoga::Style::Length& length) { + switch (length.unit()) { + case yoga::Unit::Undefined: return "undefined"; - case YGUnitPoint: - return folly::to(value.value); - case YGUnitPercent: - return folly::to(value.value) + "%"; - case YGUnitAuto: + case yoga::Unit::Point: + return std::to_string(length.value().unwrap()); + case yoga::Unit::Percent: + return std::to_string(length.value().unwrap()) + "%"; + case yoga::Unit::Auto: return "auto"; } } @@ -790,7 +791,7 @@ inline std::string toString(const yoga::FloatOptional& value) { return "undefined"; } - return folly::to(floatFromYogaFloat(value.unwrap())); + return std::to_string(value.unwrap()); } inline std::string toString(const LayoutConformance& value) { diff --git a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp index 14f2dc3062270e..8ccb94e3026b4f 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.cpp @@ -195,11 +195,7 @@ void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { } YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { - YGValue flexBasis = resolveRef(node)->getStyle().flexBasis(); - if (flexBasis.unit == YGUnitUndefined || flexBasis.unit == YGUnitAuto) { - flexBasis.value = YGUndefined; - } - return flexBasis; + return (YGValue)resolveRef(node)->getStyle().flexBasis(); } void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float points) { @@ -213,7 +209,7 @@ void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float percent) { } YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().position(scopedEnum(edge)); + return (YGValue)resolveRef(node)->getStyle().position(scopedEnum(edge)); } void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) { @@ -232,7 +228,7 @@ void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) { } YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().margin(scopedEnum(edge)); + return (YGValue)resolveRef(node)->getStyle().margin(scopedEnum(edge)); } void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) { @@ -246,7 +242,7 @@ void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) { } YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().padding(scopedEnum(edge)); + return (YGValue)resolveRef(node)->getStyle().padding(scopedEnum(edge)); } void YGNodeStyleSetBorder( @@ -309,7 +305,7 @@ void YGNodeStyleSetWidthAuto(YGNodeRef node) { } YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { - return resolveRef(node)->getStyle().dimension(Dimension::Width); + return (YGValue)resolveRef(node)->getStyle().dimension(Dimension::Width); } void YGNodeStyleSetHeight(YGNodeRef node, float points) { @@ -328,7 +324,7 @@ void YGNodeStyleSetHeightAuto(YGNodeRef node) { } YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { - return resolveRef(node)->getStyle().dimension(Dimension::Height); + return (YGValue)resolveRef(node)->getStyle().dimension(Dimension::Height); } void YGNodeStyleSetMinWidth(const YGNodeRef node, const float minWidth) { @@ -342,7 +338,7 @@ void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) { } YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().minDimension(Dimension::Width); + return (YGValue)resolveRef(node)->getStyle().minDimension(Dimension::Width); } void YGNodeStyleSetMinHeight(const YGNodeRef node, const float minHeight) { @@ -358,7 +354,7 @@ void YGNodeStyleSetMinHeightPercent( } YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().minDimension(Dimension::Height); + return (YGValue)resolveRef(node)->getStyle().minDimension(Dimension::Height); } void YGNodeStyleSetMaxWidth(const YGNodeRef node, const float maxWidth) { @@ -372,7 +368,7 @@ void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) { } YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().maxDimension(Dimension::Width); + return (YGValue)resolveRef(node)->getStyle().maxDimension(Dimension::Width); } void YGNodeStyleSetMaxHeight(const YGNodeRef node, const float maxHeight) { @@ -388,5 +384,5 @@ void YGNodeStyleSetMaxHeightPercent( } YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { - return resolveRef(node)->getStyle().maxDimension(Dimension::Height); + return (YGValue)resolveRef(node)->getStyle().maxDimension(Dimension::Height); } 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 ea7a090317bf12..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 @@ -687,9 +681,9 @@ static float distributeFreeSpaceSecondPass( sizingModeCrossDim == SizingMode::StretchFit && !(isNodeFlexWrap && mainAxisOverflows) && resolveChildAlignment(node, currentLineChild) == Align::Stretch && - currentLineChild->getFlexStartMarginValue(crossAxis).unit != - YGUnitAuto && - currentLineChild->marginTrailingValue(crossAxis).unit != YGUnitAuto) { + currentLineChild->getFlexStartMarginValue(crossAxis).unit() != + Unit::Auto && + currentLineChild->marginTrailingValue(crossAxis).unit() != Unit::Auto) { childCrossSize = availableInnerCrossDim; childCrossSizingMode = SizingMode::StretchFit; } else if (!currentLineChild->styleDefinesDimension( @@ -700,14 +694,13 @@ 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 = - currentLineChild->getResolvedDimension(dimension(crossAxis)).unit == - YGUnitPercent && + currentLineChild->getResolvedDimension(dimension(crossAxis)).unit() == + Unit::Percent && sizingModeCrossDim != SizingMode::StretchFit; childCrossSizingMode = yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement @@ -733,9 +726,9 @@ static float distributeFreeSpaceSecondPass( const bool requiresStretchLayout = !currentLineChild->styleDefinesDimension( crossAxis, availableInnerCrossDim) && resolveChildAlignment(node, currentLineChild) == Align::Stretch && - currentLineChild->getFlexStartMarginValue(crossAxis).unit != - YGUnitAuto && - currentLineChild->marginTrailingValue(crossAxis).unit != YGUnitAuto; + currentLineChild->getFlexStartMarginValue(crossAxis).unit() != + Unit::Auto && + currentLineChild->marginTrailingValue(crossAxis).unit() != Unit::Auto; const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize; @@ -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; @@ -982,10 +974,10 @@ static void justifyMainAxis( for (size_t i = startOfLineIndex; i < flexLine.endOfLineIndex; i++) { auto child = node->getChild(i); if (child->getStyle().positionType() != PositionType::Absolute) { - if (child->getFlexStartMarginValue(mainAxis).unit == YGUnitAuto) { + if (child->getFlexStartMarginValue(mainAxis).unit() == Unit::Auto) { numberOfAutoMarginsOnCurrentLine++; } - if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) { + if (child->marginTrailingValue(mainAxis).unit() == Unit::Auto) { numberOfAutoMarginsOnCurrentLine++; } } @@ -1062,7 +1054,7 @@ static void justifyMainAxis( // We need to do that only for relative elements. Absolute elements do not // take part in that phase. if (childStyle.positionType() != PositionType::Absolute) { - if (child->getFlexStartMarginValue(mainAxis).unit == YGUnitAuto) { + if (child->getFlexStartMarginValue(mainAxis).unit() == Unit::Auto) { flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / static_cast(numberOfAutoMarginsOnCurrentLine); } @@ -1078,7 +1070,7 @@ static void justifyMainAxis( flexLine.layout.mainDim += betweenMainDim; } - if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) { + if (child->marginTrailingValue(mainAxis).unit() == Unit::Auto) { flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace / static_cast(numberOfAutoMarginsOnCurrentLine); } @@ -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 = @@ -1630,8 +1618,8 @@ static void calculateLayoutImpl( // time, this time forcing the cross-axis size to be the computed // cross size for the current line. if (alignItem == Align::Stretch && - child->getFlexStartMarginValue(crossAxis).unit != YGUnitAuto && - child->marginTrailingValue(crossAxis).unit != YGUnitAuto) { + child->getFlexStartMarginValue(crossAxis).unit() != Unit::Auto && + child->marginTrailingValue(crossAxis).unit() != Unit::Auto) { // If the child defines a definite size for its cross axis, there's // no need to stretch. if (!child->styleDefinesDimension( @@ -1704,15 +1692,17 @@ static void calculateLayoutImpl( const float remainingCrossDim = containerCrossAxis - child->dimensionWithMargin(crossAxis, availableInnerWidth); - if (child->getFlexStartMarginValue(crossAxis).unit == YGUnitAuto && - child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { + if (child->getFlexStartMarginValue(crossAxis).unit() == + Unit::Auto && + child->marginTrailingValue(crossAxis).unit() == Unit::Auto) { leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim / 2); } else if ( - child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { + child->marginTrailingValue(crossAxis).unit() == Unit::Auto) { // No-Op } else if ( - child->getFlexStartMarginValue(crossAxis).unit == YGUnitAuto) { + child->getFlexStartMarginValue(crossAxis).unit() == + Unit::Auto) { leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim); } else if (alignItem == Align::FlexStart) { // No-Op @@ -1746,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; @@ -2440,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; @@ -2462,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 a2d650b237a0cb..00000000000000 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/ResolveValue.h +++ /dev/null @@ -1,32 +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(const YGValue value, const float ownerSize) { - switch (value.unit) { - case YGUnitPoint: - return FloatOptional{value.value}; - case YGUnitPercent: - return FloatOptional{value.value * ownerSize * 0.01f}; - default: - return FloatOptional{}; - } -} - -inline FloatOptional resolveValue(Style::Length value, float ownerSize) { - return resolveValue((YGValue)value, ownerSize); -} - -} // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/debug/NodeToString.cpp b/packages/react-native/ReactCommon/yoga/yoga/debug/NodeToString.cpp index 18e8aeec659b50..c084c5a77dd43d 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/debug/NodeToString.cpp +++ b/packages/react-native/ReactCommon/yoga/yoga/debug/NodeToString.cpp @@ -46,14 +46,18 @@ static void appendFloatOptionalIfDefined( static void appendNumberIfNotUndefined( std::string& base, const std::string key, - const YGValue number) { - if (number.unit != YGUnitUndefined) { - if (number.unit == YGUnitAuto) { + const Style::Length& number) { + if (number.unit() != Unit::Undefined) { + if (number.unit() == Unit::Auto) { base.append(key + ": auto; "); } else { - std::string unit = number.unit == YGUnitPoint ? "px" : "%%"; + std::string unit = number.unit() == Unit::Point ? "px" : "%%"; appendFormattedString( - base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str()); + base, + "%s: %g%s; ", + key.c_str(), + number.value().unwrap(), + unit.c_str()); } } } @@ -61,8 +65,8 @@ static void appendNumberIfNotUndefined( static void appendNumberIfNotAuto( std::string& base, const std::string& key, - const YGValue number) { - if (number.unit != YGUnitAuto) { + const Style::Length& number) { + if (number.unit() != Unit::Auto) { appendNumberIfNotUndefined(base, key, number); } } @@ -70,10 +74,10 @@ static void appendNumberIfNotAuto( static void appendNumberIfNotZero( std::string& base, const std::string& str, - const YGValue number) { - if (number.unit == YGUnitAuto) { + const Style::Length& number) { + if (number.unit() == Unit::Auto) { base.append(str + ": auto; "); - } else if (!yoga::inexactEquals(number.value, 0)) { + } else if (!yoga::inexactEquals(number.value().unwrap(), 0)) { appendNumberIfNotUndefined(base, str, number); } } diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index 36eefbb52518dd..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 @@ -127,8 +126,8 @@ bool Node::isFlexStartPositionDefined(FlexDirection axis, Direction direction) bool Node::isInlineStartPositionDefined(FlexDirection axis, Direction direction) const { - const Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingPosition = isRow(axis) + Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); + Style::Length leadingPosition = isRow(axis) ? computeEdgeValueForRow<&Style::position>(Edge::Start, startEdge) : computeEdgeValueForColumn<&Style::position>(startEdge); @@ -148,8 +147,8 @@ bool Node::isFlexEndPositionDefined(FlexDirection axis, Direction direction) bool Node::isInlineEndPositionDefined(FlexDirection axis, Direction direction) const { - const Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingPosition = isRow(axis) + Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); + Style::Length trailingPosition = isRow(axis) ? computeEdgeValueForRow<&Style::position>(Edge::End, endEdge) : computeEdgeValueForColumn<&Style::position>(endEdge); @@ -166,19 +165,19 @@ 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( FlexDirection axis, Direction direction, float axisSize) const { - const Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingPosition = isRow(axis) + Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); + Style::Length leadingPosition = isRow(axis) ? 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,19 +190,19 @@ 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( FlexDirection axis, Direction direction, float axisSize) const { - const Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingPosition = isRow(axis) + Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); + Style::Length trailingPosition = isRow(axis) ? 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,19 +215,19 @@ 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( FlexDirection axis, Direction direction, float widthSize) const { - const Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingMargin = isRow(axis) + Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); + Style::Length leadingMargin = isRow(axis) ? 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,70 +240,70 @@ 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( FlexDirection axis, Direction direction, float widthSize) const { - const Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingMargin = isRow(axis) + Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); + Style::Length trailingMargin = isRow(axis) ? 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) const { - const Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - YGValue leadingBorder = isRow(axis) + Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); + Style::Length leadingBorder = isRow(axis) ? computeEdgeValueForRow<&Style::border>(Edge::Start, startEdge) : computeEdgeValueForColumn<&Style::border>(startEdge); - return maxOrDefined(leadingBorder.value, 0.0f); + return maxOrDefined(leadingBorder.value().unwrap(), 0.0f); } float Node::getFlexStartBorder(FlexDirection axis, Direction direction) const { - YGValue leadingBorder = isRow(axis) + Style::Length leadingBorder = isRow(axis) ? computeEdgeValueForRow<&Style::border>( getFlexStartRelativeEdgeUsingErrata(axis, direction), flexStartEdge(axis)) : computeEdgeValueForColumn<&Style::border>(flexStartEdge(axis)); - return maxOrDefined(leadingBorder.value, 0.0f); + return maxOrDefined(leadingBorder.value().unwrap(), 0.0f); } float Node::getInlineEndBorder(FlexDirection axis, Direction direction) const { - const Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - YGValue trailingBorder = isRow(axis) + Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); + Style::Length trailingBorder = isRow(axis) ? computeEdgeValueForRow<&Style::border>(Edge::End, endEdge) : computeEdgeValueForColumn<&Style::border>(endEdge); - return maxOrDefined(trailingBorder.value, 0.0f); + return maxOrDefined(trailingBorder.value().unwrap(), 0.0f); } float Node::getFlexEndBorder(FlexDirection axis, Direction direction) const { - YGValue trailingBorder = isRow(axis) + Style::Length trailingBorder = isRow(axis) ? computeEdgeValueForRow<&Style::border>( getFlexEndRelativeEdgeUsingErrata(axis, direction), flexEndEdge(axis)) : computeEdgeValueForColumn<&Style::border>(flexEndEdge(axis)); - return maxOrDefined(trailingBorder.value, 0.0f); + return maxOrDefined(trailingBorder.value().unwrap(), 0.0f); } float Node::getInlineStartPadding( FlexDirection axis, Direction direction, float widthSize) const { - const Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingPadding = isRow(axis) + Edge startEdge = getInlineStartEdgeUsingErrata(axis, direction); + Style::Length leadingPadding = isRow(axis) ? 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,19 +316,19 @@ 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( FlexDirection axis, Direction direction, float widthSize) const { - const Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingPadding = isRow(axis) + Edge endEdge = getInlineEndEdgeUsingErrata(axis, direction); + Style::Length trailingPadding = isRow(axis) ? 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( @@ -424,16 +423,18 @@ bool Node::isLayoutDimensionDefined(const FlexDirection axis) { bool Node::styleDefinesDimension( const FlexDirection axis, const float ownerSize) { - bool isDefined = yoga::isDefined(getResolvedDimension(dimension(axis)).value); - auto resolvedDimension = getResolvedDimension(dimension(axis)); + if (!resolvedDimension.isDefined()) { + return false; + } + return !( - resolvedDimension.unit == YGUnitAuto || - resolvedDimension.unit == YGUnitUndefined || - (resolvedDimension.unit == YGUnitPoint && isDefined && - resolvedDimension.value < 0.0f) || - (resolvedDimension.unit == YGUnitPercent && isDefined && - (resolvedDimension.value < 0.0f || yoga::isUndefined(ownerSize)))); + resolvedDimension.isAuto() || + (resolvedDimension.unit() == Unit::Point && + resolvedDimension.value().unwrap() < 0.0f) || + (resolvedDimension.unit() == Unit::Percent && + (resolvedDimension.value().unwrap() < 0.0f || + yoga::isUndefined(ownerSize)))); } // Setters @@ -621,7 +622,7 @@ void Node::setPosition( crossAxisTrailingEdge); } -YGValue Node::getFlexStartMarginValue(FlexDirection axis) const { +Style::Length Node::getFlexStartMarginValue(FlexDirection axis) const { if (isRow(axis) && style_.margin(Edge::Start).isDefined()) { return style_.margin(Edge::Start); } else { @@ -629,7 +630,7 @@ YGValue Node::getFlexStartMarginValue(FlexDirection axis) const { } } -YGValue Node::marginTrailingValue(FlexDirection axis) const { +Style::Length Node::marginTrailingValue(FlexDirection axis) const { if (isRow(axis) && style_.margin(Edge::End).isDefined()) { return style_.margin(Edge::End); } else { @@ -637,15 +638,15 @@ YGValue Node::marginTrailingValue(FlexDirection axis) const { } } -YGValue Node::resolveFlexBasisPtr() const { - YGValue flexBasis = style_.flexBasis(); - if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) { +Style::Length Node::resolveFlexBasisPtr() const { + Style::Length flexBasis = style_.flexBasis(); + if (flexBasis.unit() != Unit::Auto && flexBasis.unit() != Unit::Undefined) { return flexBasis; } if (style_.flex().isDefined() && style_.flex().unwrap() > 0.0f) { - return config_->useWebDefaults() ? YGValueAuto : YGValueZero; + return config_->useWebDefaults() ? value::ofAuto() : value::points(0); } - return YGValueAuto; + return value::ofAuto(); } void Node::resolveDimension() { diff --git a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h index bbde5eac362d0f..19a52668942871 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h +++ b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h @@ -45,8 +45,8 @@ class YG_EXPORT Node : public ::YGNode { Node* owner_ = nullptr; std::vector children_ = {}; const Config* config_; - std::array resolvedDimensions_ = { - {YGValueUndefined, YGValueUndefined}}; + std::array resolvedDimensions_ = { + {value::undefined(), value::undefined()}}; float relativePosition( FlexDirection axis, @@ -199,11 +199,11 @@ class YG_EXPORT Node : public ::YGNode { return isDirty_; } - std::array getResolvedDimensions() const { + std::array getResolvedDimensions() const { return resolvedDimensions_; } - YGValue getResolvedDimension(Dimension dimension) const { + Style::Length getResolvedDimension(Dimension dimension) const { return resolvedDimensions_[static_cast(dimension)]; } @@ -366,9 +366,9 @@ class YG_EXPORT Node : public ::YGNode { const float ownerWidth); // Other methods - YGValue getFlexStartMarginValue(FlexDirection axis) const; - YGValue marginTrailingValue(FlexDirection axis) const; - YGValue resolveFlexBasisPtr() const; + Style::Length getFlexStartMarginValue(FlexDirection axis) const; + Style::Length marginTrailingValue(FlexDirection axis) const; + Style::Length resolveFlexBasisPtr() const; void resolveDimension(); Direction resolveDirection(const Direction ownerDirection); void clearChildren(); diff --git a/packages/react-native/ReactCommon/yoga/yoga/numeric/Comparison.h b/packages/react-native/ReactCommon/yoga/yoga/numeric/Comparison.h index 729589b934a8a2..0e23a837b956d4 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/numeric/Comparison.h +++ b/packages/react-native/ReactCommon/yoga/yoga/numeric/Comparison.h @@ -24,6 +24,14 @@ constexpr bool isDefined(std::floating_point auto value) { return !isUndefined(value); } +/** + * Constexpr version of `std::isinf` before C++ 23 + */ +constexpr bool isinf(auto value) { + return value == +std::numeric_limits::infinity() || + value == -std::numeric_limits::infinity(); +} + constexpr auto maxOrDefined( std::floating_point auto a, std::floating_point auto b) { @@ -59,19 +67,6 @@ inline bool inexactEquals(double a, double b) { return yoga::isUndefined(a) && yoga::isUndefined(b); } -inline bool inexactEquals(const YGValue& a, const YGValue& b) { - if (a.unit != b.unit) { - return false; - } - - if (a.unit == YGUnitUndefined || - (yoga::isUndefined(a.value) && yoga::isUndefined(b.value))) { - return true; - } - - return fabs(a.value - b.value) < 0.0001f; -} - template bool inexactEquals( const std::array& val1, diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/CompactValue.h b/packages/react-native/ReactCommon/yoga/yoga/style/CompactValue.h index d7884e1d6f5dfd..e80f2a9f22f574 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/CompactValue.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/CompactValue.h @@ -16,6 +16,7 @@ #include #include +#include static_assert( std::numeric_limits::is_iec559, @@ -42,7 +43,7 @@ namespace facebook::yoga { // 0x40000000 0x7f7fffff // - Zero is supported, negative zero is not // - values outside of the representable range are clamped -class YG_EXPORT CompactValue { +class CompactValue { friend constexpr bool operator==(CompactValue, CompactValue) noexcept; public: @@ -50,31 +51,6 @@ class YG_EXPORT CompactValue { static constexpr auto UPPER_BOUND_POINT = 36893485948395847680.0f; static constexpr auto UPPER_BOUND_PERCENT = 18446742974197923840.0f; - template - static CompactValue of(float value) noexcept { - if (yoga::isUndefined(value) || std::isinf(value)) { - return ofUndefined(); - } - - if (value == 0.0f || (value < LOWER_BOUND && value > -LOWER_BOUND)) { - constexpr auto zero = - Unit == YGUnitPercent ? ZERO_BITS_PERCENT : ZERO_BITS_POINT; - return {zero}; - } - - constexpr auto upperBound = - Unit == YGUnitPercent ? UPPER_BOUND_PERCENT : UPPER_BOUND_POINT; - if (value > upperBound || value < -upperBound) { - value = copysignf(upperBound, value); - } - - uint32_t unitBit = Unit == YGUnitPercent ? PERCENT_BIT : 0; - auto data = std::bit_cast(value); - data -= BIAS; - data |= unitBit; - return {data}; - } - static constexpr CompactValue ofUndefined() noexcept { return CompactValue{}; } @@ -83,46 +59,48 @@ class YG_EXPORT CompactValue { return CompactValue{AUTO_BITS}; } - constexpr CompactValue() noexcept : repr_(0x7FC00000) {} + constexpr CompactValue() noexcept = default; - CompactValue(const YGValue& x) noexcept : repr_(uint32_t{0}) { - switch (x.unit) { - case YGUnitUndefined: + explicit constexpr CompactValue(const StyleLength& x) noexcept { + switch (x.unit()) { + case Unit::Undefined: *this = ofUndefined(); break; - case YGUnitAuto: + case Unit::Auto: *this = ofAuto(); break; - case YGUnitPoint: - *this = of(x.value); + case Unit::Point: + *this = of(x.value().unwrap()); break; - case YGUnitPercent: - *this = of(x.value); + case Unit::Percent: + *this = of(x.value().unwrap()); break; } } - operator YGValue() const noexcept { + explicit operator StyleLength() const noexcept { + if (repr_ == 0x7FC00000) { + return value::undefined(); + } + switch (repr_) { case AUTO_BITS: - return YGValueAuto; + return value::ofAuto(); case ZERO_BITS_POINT: - return YGValue{0.0f, YGUnitPoint}; + return value::points(0); case ZERO_BITS_PERCENT: - return YGValue{0.0f, YGUnitPercent}; - } - - if (std::isnan(std::bit_cast(repr_))) { - return YGValueUndefined; + return value::percent(0); } auto data = repr_; data &= ~PERCENT_BIT; data += BIAS; - return YGValue{ - std::bit_cast(data), - repr_ & 0x40000000 ? YGUnitPercent : YGUnitPoint}; + if (repr_ & 0x40000000) { + return value::percent(std::bit_cast(data)); + } else { + return value::points(std::bit_cast(data)); + } } bool isUndefined() const noexcept { @@ -140,7 +118,28 @@ class YG_EXPORT CompactValue { } private: - uint32_t repr_; + template + static CompactValue of(float value) noexcept { + if (value == 0.0f || (value < LOWER_BOUND && value > -LOWER_BOUND)) { + constexpr auto zero = + UnitT == Unit::Percent ? ZERO_BITS_PERCENT : ZERO_BITS_POINT; + return {zero}; + } + + constexpr auto upperBound = + UnitT == Unit::Percent ? UPPER_BOUND_PERCENT : UPPER_BOUND_POINT; + if (value > upperBound || value < -upperBound) { + value = copysignf(upperBound, value); + } + + uint32_t unitBit = UnitT == Unit::Percent ? PERCENT_BIT : 0; + auto data = std::bit_cast(value); + data -= BIAS; + data |= unitBit; + return {data}; + } + + uint32_t repr_{0x7FC00000}; static constexpr uint32_t BIAS = 0x20000000; static constexpr uint32_t PERCENT_BIT = 0x40000000; @@ -159,9 +158,9 @@ class YG_EXPORT CompactValue { }; template <> -CompactValue CompactValue::of(float) noexcept = delete; +CompactValue CompactValue::of(float) noexcept = delete; template <> -CompactValue CompactValue::of(float) noexcept = delete; +CompactValue CompactValue::of(float) noexcept = delete; constexpr bool operator==(CompactValue a, CompactValue b) noexcept { return a.repr_ == b.repr_; @@ -172,7 +171,7 @@ constexpr bool operator!=(CompactValue a, CompactValue b) noexcept { } inline bool inexactEquals(CompactValue a, CompactValue b) { - return inexactEquals((YGValue)a, (YGValue)b); + return inexactEquals((StyleLength)a, (StyleLength)b); } } // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h index b7fd8335d648ec..2993337539178d 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/style/Style.h +++ b/packages/react-native/ReactCommon/yoga/yoga/style/Style.h @@ -24,31 +24,17 @@ #include #include #include +#include #include #include #include -#include +#include namespace facebook::yoga { class YG_EXPORT Style { public: - /** - * Style::Length represents a CSS Value which may be one of: - * 1. Undefined - * 2. A keyword (e.g. auto) - * 3. A CSS value: - * a. value (e.g. 10px) - * b. value of a reference - * 4. (soon) A math function which returns a value - * - * References: - * 1. https://www.w3.org/TR/css-values-4/#lengths - * 2. https://www.w3.org/TR/css-values-4/#percentage-value - * 3. https://www.w3.org/TR/css-values-4/#mixed-percentages - * 4. https://www.w3.org/TR/css-values-4/#math - */ - using Length = CompactValue; + using Length = StyleLength; static constexpr float DefaultFlexGrow = 0.0f; static constexpr float DefaultFlexShrink = 0.0f; @@ -146,66 +132,66 @@ class YG_EXPORT Style { } Style::Length flexBasis() const { - return flexBasis_; + return (Style::Length)flexBasis_; } void setFlexBasis(Style::Length value) { - flexBasis_ = value; + flexBasis_ = CompactValue(value); } Style::Length margin(Edge edge) const { - return margin_[yoga::to_underlying(edge)]; + return (Style::Length)margin_[yoga::to_underlying(edge)]; } void setMargin(Edge edge, Style::Length value) { - margin_[yoga::to_underlying(edge)] = value; + margin_[yoga::to_underlying(edge)] = CompactValue(value); } Style::Length position(Edge edge) const { - return position_[yoga::to_underlying(edge)]; + return (Style::Length)position_[yoga::to_underlying(edge)]; } void setPosition(Edge edge, Style::Length value) { - position_[yoga::to_underlying(edge)] = value; + position_[yoga::to_underlying(edge)] = CompactValue(value); } Style::Length padding(Edge edge) const { - return padding_[yoga::to_underlying(edge)]; + return (Style::Length)padding_[yoga::to_underlying(edge)]; } void setPadding(Edge edge, Style::Length value) { - padding_[yoga::to_underlying(edge)] = value; + padding_[yoga::to_underlying(edge)] = CompactValue(value); } Style::Length border(Edge edge) const { - return border_[yoga::to_underlying(edge)]; + return (Style::Length)border_[yoga::to_underlying(edge)]; } void setBorder(Edge edge, Style::Length value) { - border_[yoga::to_underlying(edge)] = value; + border_[yoga::to_underlying(edge)] = CompactValue(value); } Style::Length gap(Gutter gutter) const { - return gap_[yoga::to_underlying(gutter)]; + return (Style::Length)gap_[yoga::to_underlying(gutter)]; } void setGap(Gutter gutter, Style::Length value) { - gap_[yoga::to_underlying(gutter)] = value; + gap_[yoga::to_underlying(gutter)] = CompactValue(value); } Style::Length dimension(Dimension axis) const { - return dimensions_[yoga::to_underlying(axis)]; + return (Style::Length)dimensions_[yoga::to_underlying(axis)]; } void setDimension(Dimension axis, Style::Length value) { - dimensions_[yoga::to_underlying(axis)] = value; + dimensions_[yoga::to_underlying(axis)] = CompactValue(value); } Style::Length minDimension(Dimension axis) const { - return minDimensions_[yoga::to_underlying(axis)]; + return (Style::Length)minDimensions_[yoga::to_underlying(axis)]; } void setMinDimension(Dimension axis, Style::Length value) { - minDimensions_[yoga::to_underlying(axis)] = value; + minDimensions_[yoga::to_underlying(axis)] = CompactValue(value); } Style::Length maxDimension(Dimension axis) const { - return maxDimensions_[yoga::to_underlying(axis)]; + return (Style::Length)maxDimensions_[yoga::to_underlying(axis)]; } void setMaxDimension(Dimension axis, Style::Length value) { - maxDimensions_[yoga::to_underlying(axis)] = value; + maxDimensions_[yoga::to_underlying(axis)] = CompactValue(value); } FloatOptional aspectRatio() const { @@ -217,17 +203,17 @@ class YG_EXPORT Style { Style::Length resolveColumnGap() const { if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) { - return gap_[yoga::to_underlying(Gutter::Column)]; + return (Style::Length)gap_[yoga::to_underlying(Gutter::Column)]; } else { - return gap_[yoga::to_underlying(Gutter::All)]; + return (Style::Length)gap_[yoga::to_underlying(Gutter::All)]; } } Style::Length resolveRowGap() const { if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) { - return gap_[yoga::to_underlying(Gutter::Row)]; + return (Style::Length)gap_[yoga::to_underlying(Gutter::Row)]; } else { - return gap_[yoga::to_underlying(Gutter::All)]; + return (Style::Length)gap_[yoga::to_underlying(Gutter::All)]; } } @@ -275,9 +261,9 @@ class YG_EXPORT Style { } private: - using Dimensions = std::array()>; - using Edges = std::array()>; - using Gutters = std::array()>; + using Dimensions = std::array()>; + using Edges = std::array()>; + using Gutters = std::array()>; Direction direction_ : bitCount() = Direction::Inherit; FlexDirection flexDirection_ @@ -295,13 +281,13 @@ class YG_EXPORT Style { FloatOptional flex_{}; FloatOptional flexGrow_{}; FloatOptional flexShrink_{}; - Style::Length flexBasis_{value::ofAuto()}; + CompactValue flexBasis_{CompactValue::ofAuto()}; Edges margin_{}; Edges position_{}; Edges padding_{}; Edges border_{}; Gutters gap_{}; - Dimensions dimensions_{value::ofAuto(), value::ofAuto()}; + Dimensions dimensions_{CompactValue::ofAuto(), CompactValue::ofAuto()}; Dimensions minDimensions_{}; Dimensions maxDimensions_{}; FloatOptional aspectRatio_{}; diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h new file mode 100644 index 00000000000000..242698abf4e49b --- /dev/null +++ b/packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h @@ -0,0 +1,139 @@ +/* + * 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 + +namespace facebook::yoga { + +/** + * Style::Length represents a CSS Value which may be one of: + * 1. Undefined + * 2. A keyword (e.g. auto) + * 3. A CSS value: + * a. value (e.g. 10px) + * b. value of a reference + * 4. (soon) A math function which returns a value + * + * References: + * 1. https://www.w3.org/TR/css-values-4/#lengths + * 2. https://www.w3.org/TR/css-values-4/#percentage-value + * 3. https://www.w3.org/TR/css-values-4/#mixed-percentages + * 4. https://www.w3.org/TR/css-values-4/#math + */ +class StyleLength { + public: + constexpr StyleLength() = default; + + constexpr static StyleLength points(float value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleLength{FloatOptional{value}, Unit::Point}; + } + + constexpr static StyleLength percent(float value) { + return yoga::isUndefined(value) || yoga::isinf(value) + ? undefined() + : StyleLength{FloatOptional{value}, Unit::Percent}; + } + + constexpr static StyleLength ofAuto() { + return StyleLength{{}, Unit::Auto}; + } + + constexpr static StyleLength undefined() { + return StyleLength{{}, Unit::Undefined}; + } + + constexpr bool isAuto() const { + return unit_ == Unit::Auto; + } + + constexpr bool isUndefined() const { + return unit_ == Unit::Undefined; + } + + constexpr bool isDefined() const { + return !isUndefined(); + } + + constexpr FloatOptional value() const { + return value_; + } + + constexpr Unit unit() const { + 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_)}; + } + + constexpr bool operator==(const StyleLength& rhs) const { + return value_ == rhs.value_ && unit_ == rhs.unit_; + } + + private: + // We intentionally do not allow direct construction using value and unit, to + // avoid invalid, or redundant combinations. + constexpr StyleLength(FloatOptional value, Unit unit) + : value_(value), unit_(unit) {} + + FloatOptional value_{}; + Unit unit_{Unit::Undefined}; +}; + +inline bool inexactEquals(const StyleLength& a, const StyleLength& b) { + return a.unit() == b.unit() && inexactEquals(a.value(), b.value()); +} + +namespace value { + +/** + * Canonical unit (one YGUnitPoint) + */ +constexpr StyleLength points(float value) { + return StyleLength::points(value); +} + +/** + * Percent of reference + */ +constexpr StyleLength percent(float value) { + return StyleLength::percent(value); +} + +/** + * "auto" keyword + */ +constexpr StyleLength ofAuto() { + return StyleLength::ofAuto(); +} + +/** + * Undefined + */ +constexpr StyleLength undefined() { + return StyleLength::undefined(); +} + +} // namespace value + +} // namespace facebook::yoga diff --git a/packages/react-native/ReactCommon/yoga/yoga/style/ValueFactories.h b/packages/react-native/ReactCommon/yoga/yoga/style/ValueFactories.h deleted file mode 100644 index 65486347b0a52c..00000000000000 --- a/packages/react-native/ReactCommon/yoga/yoga/style/ValueFactories.h +++ /dev/null @@ -1,42 +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 - -namespace facebook::yoga::value { - -/** - * Canonical unit (one YGUnitPoint) - */ -inline CompactValue points(float value) { - return CompactValue::of(value); -} - -/** - * Percent of reference - */ -inline CompactValue percent(float value) { - return CompactValue::of(value); -} - -/** - * "auto" keyword - */ -inline CompactValue ofAuto() { - return CompactValue::ofAuto(); -} - -/** - * Undefined - */ -inline CompactValue undefined() { - return CompactValue::ofUndefined(); -} - -} // namespace facebook::yoga::value