From aa65e92121e86fbe978e10db80e04fb4999479ef Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Sat, 30 Sep 2023 21:09:13 -0700 Subject: [PATCH] Fix handling of negative flex gap (#39596) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39596 X-link: https://github.com/facebook/yoga/pull/1405 I noticed that we weren't clamping negative flex gap values to zero. This fixes that bug. Reviewed By: rshest Differential Revision: D49530494 fbshipit-source-id: 069db7312f72a085c5c4b01ead7bc66a353a07e5 --- .../yoga/yoga/algorithm/CalculateLayout.cpp | 7 +++---- .../ReactCommon/yoga/yoga/algorithm/FlexLine.cpp | 2 +- .../react-native/ReactCommon/yoga/yoga/node/Node.cpp | 12 ++++++------ .../react-native/ReactCommon/yoga/yoga/node/Node.h | 3 +-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp index 1d0b2d09a44..384de713588 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.cpp +++ b/packages/react-native/ReactCommon/yoga/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/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp b/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp index f254a7a5739..aab71aa20d6 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.cpp +++ b/packages/react-native/ReactCommon/yoga/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/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp b/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp index 908e1aebdc9..782c68385e0 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.cpp +++ b/packages/react-native/ReactCommon/yoga/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/packages/react-native/ReactCommon/yoga/yoga/node/Node.h b/packages/react-native/ReactCommon/yoga/yoga/node/Node.h index 2c89159673f..09c05ebedfa 100644 --- a/packages/react-native/ReactCommon/yoga/yoga/node/Node.h +++ b/packages/react-native/ReactCommon/yoga/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) {