diff --git a/tests/YGFloatOptionalTest.cpp b/tests/YGFloatOptionalTest.cpp index 656c81f7..c35f7b2e 100644 --- a/tests/YGFloatOptionalTest.cpp +++ b/tests/YGFloatOptionalTest.cpp @@ -7,12 +7,10 @@ #include -#include +#include #include #include -using namespace facebook; - constexpr auto empty = YGFloatOptional{}; constexpr auto zero = YGFloatOptional{0.0f}; constexpr auto one = YGFloatOptional{1.0f}; @@ -194,13 +192,13 @@ TEST(YGFloatOptional, addition) { ASSERT_EQ(negative + empty, empty); } -TEST(YGFloatOptionalTest, maxOrDefined) { - ASSERT_EQ(yoga::maxOrDefined(empty, empty), empty); - ASSERT_EQ(yoga::maxOrDefined(empty, positive), positive); - ASSERT_EQ(yoga::maxOrDefined(negative, empty), negative); - ASSERT_EQ(yoga::maxOrDefined(negative, YGFloatOptional{-INFINITY}), negative); +TEST(YGFloatOptionalTest, YGFloatOptionalMax) { + ASSERT_EQ(YGFloatOptionalMax(empty, empty), empty); + ASSERT_EQ(YGFloatOptionalMax(empty, positive), positive); + ASSERT_EQ(YGFloatOptionalMax(negative, empty), negative); + ASSERT_EQ(YGFloatOptionalMax(negative, YGFloatOptional{-INFINITY}), negative); ASSERT_EQ( - yoga::maxOrDefined(YGFloatOptional{1.0f}, YGFloatOptional{1.125f}), + YGFloatOptionalMax(YGFloatOptional{1.0f}, YGFloatOptional{1.125f}), YGFloatOptional{1.125f}); } diff --git a/yoga/Utils.cpp b/yoga/Utils.cpp new file mode 100644 index 00000000..7cc94022 --- /dev/null +++ b/yoga/Utils.cpp @@ -0,0 +1,83 @@ +/* + * 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 "Utils.h" +#include + +using namespace facebook; + +YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction) { + return YGFlexDirectionIsColumn(flexDirection) + ? YGResolveFlexDirection(YGFlexDirectionRow, direction) + : YGFlexDirectionColumn; +} + +float YGFloatMax(const float a, const float b) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { + return fmaxf(a, b); + } + return yoga::isUndefined(a) ? b : a; +} + +float YGFloatMin(const float a, const float b) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { + return fminf(a, b); + } + + return yoga::isUndefined(a) ? b : a; +} + +bool YGValueEqual(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; +} + +bool YGFloatsEqual(const float a, const float b) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { + return fabs(a - b) < 0.0001f; + } + return yoga::isUndefined(a) && yoga::isUndefined(b); +} + +bool YGDoubleEqual(const double a, const double b) { + if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) { + return fabs(a - b) < 0.0001; + } + return yoga::isUndefined(a) && yoga::isUndefined(b); +} + +float YGFloatSanitize(const float val) { + return yoga::isUndefined(val) ? 0 : val; +} + +YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) { + if (op1 >= op2) { + return op1; + } + if (op2 > op1) { + return op2; + } + return op1.isUndefined() ? op2 : op1; +} + +void yoga::throwLogicalErrorWithMessage(const char* message) { +#if defined(__cpp_exceptions) + throw std::logic_error(message); +#else // !defined(__cpp_exceptions) + std::terminate(); +#endif // defined(__cpp_exceptions) +} diff --git a/yoga/Utils.h b/yoga/Utils.h new file mode 100644 index 00000000..bd8ab309 --- /dev/null +++ b/yoga/Utils.h @@ -0,0 +1,146 @@ +/* + * 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 + +// This struct is an helper model to hold the data for step 4 of flexbox algo, +// which is collecting the flex items in a line. +// +// - itemsOnLine: Number of items which can fit in a line considering the +// available Inner dimension, the flex items computed flexbasis and their +// margin. It may be different than the difference between start and end +// indicates because we skip over absolute-positioned items. +// +// - sizeConsumedOnCurrentLine: It is accumulation of the dimensions and margin +// of all the children on the current line. This will be used in order to +// either set the dimensions of the node if none already exist or to compute +// the remaining space left for the flexible children. +// +// - totalFlexGrowFactors: total flex grow factors of flex items which are to be +// laid in the current line +// +// - totalFlexShrinkFactors: total flex shrink factors of flex items which are +// to be laid in the current line +// +// - endOfLineIndex: Its the end index of the last flex item which was examined +// and it may or may not be part of the current line(as it may be absolutely +// positioned or including it may have caused to overshoot availableInnerDim) +// +// - relativeChildren: Maintain a vector of the child nodes that can shrink +// and/or grow. + +struct YGCollectFlexItemsRowValues { + uint32_t itemsOnLine; + float sizeConsumedOnCurrentLine; + float totalFlexGrowFactors; + float totalFlexShrinkScaledFactors; + uint32_t endOfLineIndex; + std::vector relativeChildren; + float remainingFreeSpace; + // The size of the mainDim for the row after considering size, padding, margin + // and border of flex items. This is used to calculate maxLineDim after going + // through all the rows to decide on the main axis size of owner. + float mainDim; + // The size of the crossDim for the row after considering size, padding, + // margin and border of flex items. Used for calculating containers crossSize. + float crossDim; +}; + +bool YGValueEqual(const YGValue& a, const YGValue& b); +inline bool YGValueEqual( + facebook::yoga::CompactValue a, + facebook::yoga::CompactValue b) { + return YGValueEqual((YGValue) a, (YGValue) b); +} + +// This custom float equality function returns true if either absolute +// difference between two floats is less than 0.0001f or both are undefined. +bool YGFloatsEqual(const float a, const float b); + +bool YGDoubleEqual(const double a, const double b); + +float YGFloatMax(const float a, const float b); + +YGFloatOptional YGFloatOptionalMax( + const YGFloatOptional op1, + const YGFloatOptional op2); + +float YGFloatMin(const float a, const float b); + +// This custom float comparison function compares the array of float with +// YGFloatsEqual, as the default float comparison operator will not work(Look +// at the comments of YGFloatsEqual function). +template +bool YGFloatArrayEqual( + const std::array& val1, + const std::array& val2) { + bool areEqual = true; + for (std::size_t i = 0; i < size && areEqual; ++i) { + areEqual = YGFloatsEqual(val1[i], val2[i]); + } + return areEqual; +} + +// This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise +float YGFloatSanitize(const float val); + +YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction); + +inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { + return flexDirection == YGFlexDirectionRow || + flexDirection == YGFlexDirectionRowReverse; +} + +inline YGFloatOptional YGResolveValue( + const YGValue value, + const float ownerSize) { + switch (value.unit) { + case YGUnitPoint: + return YGFloatOptional{value.value}; + case YGUnitPercent: + return YGFloatOptional{value.value * ownerSize * 0.01f}; + default: + return YGFloatOptional{}; + } +} + +inline YGFloatOptional YGResolveValue( + facebook::yoga::CompactValue value, + float ownerSize) { + return YGResolveValue((YGValue) value, ownerSize); +} + +inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { + return flexDirection == YGFlexDirectionColumn || + flexDirection == YGFlexDirectionColumnReverse; +} + +inline YGFlexDirection YGResolveFlexDirection( + const YGFlexDirection flexDirection, + const YGDirection direction) { + if (direction == YGDirectionRTL) { + if (flexDirection == YGFlexDirectionRow) { + return YGFlexDirectionRowReverse; + } else if (flexDirection == YGFlexDirectionRowReverse) { + return YGFlexDirectionRow; + } + } + + return flexDirection; +} + +inline YGFloatOptional YGResolveValueMargin( + facebook::yoga::CompactValue value, + const float ownerSize) { + return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize); +} diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 34032824..3fc4f23a 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -41,6 +41,8 @@ inline bool isUndefined(double value) { return std::isnan(value); } +void throwLogicalErrorWithMessage(const char* message); + } // namespace facebook::yoga extern const std::array trailing; @@ -147,3 +149,5 @@ public: static const float kDefaultFlexGrow = 0.0f; static const float kDefaultFlexShrink = 0.0f; static const float kWebDefaultFlexShrink = 1.0f; + +extern bool YGFloatsEqual(const float a, const float b); diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index 1179e7a7..c150be61 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -5,24 +5,20 @@ * LICENSE file in the root directory of this source tree. */ +#include +#include #include #include -#include -#include #include -#include #include -#include -#include -#include -#include #include #include -#include +#include #include -#include +#include +#include "event/event.h" using namespace facebook; using namespace facebook::yoga; @@ -1043,7 +1039,8 @@ static inline YGAlign YGNodeAlignItem( const YGAlign align = child->getStyle().alignSelf() == YGAlignAuto ? node->getStyle().alignItems() : child->getStyle().alignSelf(); - if (align == YGAlignBaseline && isColumn(node->getStyle().flexDirection())) { + if (align == YGAlignBaseline && + YGFlexDirectionIsColumn(node->getStyle().flexDirection())) { return YGAlignFlexStart; } return align; @@ -1098,7 +1095,7 @@ static float YGBaseline(yoga::Node* node, void* layoutContext) { } static bool YGIsBaselineLayout(const yoga::Node* node) { - if (isColumn(node->getStyle().flexDirection())) { + if (YGFlexDirectionIsColumn(node->getStyle().flexDirection())) { return false; } if (node->getStyle().alignItems() == YGAlignBaseline) { @@ -1158,15 +1155,15 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( YGFloatOptional min; YGFloatOptional max; - if (isColumn(axis)) { - min = yoga::resolveValue( + if (YGFlexDirectionIsColumn(axis)) { + min = YGResolveValue( node->getStyle().minDimensions()[YGDimensionHeight], axisSize); - max = yoga::resolveValue( + max = YGResolveValue( node->getStyle().maxDimensions()[YGDimensionHeight], axisSize); - } else if (isRow(axis)) { - min = yoga::resolveValue( + } else if (YGFlexDirectionIsRow(axis)) { + min = YGResolveValue( node->getStyle().minDimensions()[YGDimensionWidth], axisSize); - max = yoga::resolveValue( + max = YGResolveValue( node->getStyle().maxDimensions()[YGDimensionWidth], axisSize); } @@ -1189,7 +1186,7 @@ static inline float YGNodeBoundAxis( const float value, const float axisSize, const float widthSize) { - return yoga::maxOrDefined( + return YGFloatMax( YGNodeBoundAxisWithinMinAndMax( node, axis, YGFloatOptional{value}, axisSize) .unwrap(), @@ -1215,7 +1212,7 @@ static void YGConstrainMaxSizeForMode( YGMeasureMode* mode, float* size) { const YGFloatOptional maxSize = - yoga::resolveValue( + YGResolveValue( node->getStyle().maxDimensions()[dim[axis]], ownerAxisSize) + YGFloatOptional(node->getMarginForAxis(axis, ownerWidth)); switch (*mode) { @@ -1250,8 +1247,8 @@ static void YGNodeComputeFlexBasisForChild( const uint32_t depth, const uint32_t generationCount) { const YGFlexDirection mainAxis = - resolveDirection(node->getStyle().flexDirection(), direction); - const bool isMainAxisRow = isRow(mainAxis); + YGResolveFlexDirection(node->getStyle().flexDirection(), direction); + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); const float mainAxisSize = isMainAxisRow ? width : height; const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; @@ -1261,7 +1258,7 @@ static void YGNodeComputeFlexBasisForChild( YGMeasureMode childHeightMeasureMode; const YGFloatOptional resolvedFlexBasis = - yoga::resolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize); + YGResolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize); const bool isRowStyleDimDefined = YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, ownerWidth); const bool isColumnStyleDimDefined = @@ -1275,15 +1272,15 @@ static void YGNodeComputeFlexBasisForChild( const YGFloatOptional paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); child->setLayoutComputedFlexBasis( - yoga::maxOrDefined(resolvedFlexBasis, paddingAndBorder)); + YGFloatOptionalMax(resolvedFlexBasis, paddingAndBorder)); } } else if (isMainAxisRow && isRowStyleDimDefined) { // The width is definite, so use that as the flex basis. const YGFloatOptional paddingAndBorder = YGFloatOptional( YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth)); - child->setLayoutComputedFlexBasis(yoga::maxOrDefined( - yoga::resolveValue( + child->setLayoutComputedFlexBasis(YGFloatOptionalMax( + YGResolveValue( child->getResolvedDimensions()[YGDimensionWidth], ownerWidth), paddingAndBorder)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { @@ -1291,8 +1288,8 @@ static void YGNodeComputeFlexBasisForChild( const YGFloatOptional paddingAndBorder = YGFloatOptional(YGNodePaddingAndBorderForAxis( child, YGFlexDirectionColumn, ownerWidth)); - child->setLayoutComputedFlexBasis(yoga::maxOrDefined( - yoga::resolveValue( + child->setLayoutComputedFlexBasis(YGFloatOptionalMax( + YGResolveValue( child->getResolvedDimensions()[YGDimensionHeight], ownerHeight), paddingAndBorder)); } else { @@ -1310,7 +1307,7 @@ static void YGNodeComputeFlexBasisForChild( if (isRowStyleDimDefined) { childWidth = - yoga::resolveValue( + YGResolveValue( child->getResolvedDimensions()[YGDimensionWidth], ownerWidth) .unwrap() + marginRow; @@ -1318,7 +1315,7 @@ static void YGNodeComputeFlexBasisForChild( } if (isColumnStyleDimDefined) { childHeight = - yoga::resolveValue( + YGResolveValue( child->getResolvedDimensions()[YGDimensionHeight], ownerHeight) .unwrap() + marginColumn; @@ -1426,7 +1423,7 @@ static void YGNodeComputeFlexBasisForChild( depth, generationCount); - child->setLayoutComputedFlexBasis(YGFloatOptional(yoga::maxOrDefined( + child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax( child->getLayout().measuredDimensions[dim[mainAxis]], YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)))); } @@ -1446,9 +1443,9 @@ static void YGNodeAbsoluteLayoutChild( const uint32_t depth, const uint32_t generationCount) { const YGFlexDirection mainAxis = - resolveDirection(node->getStyle().flexDirection(), direction); - const YGFlexDirection crossAxis = resolveCrossDirection(mainAxis, direction); - const bool isMainAxisRow = isRow(mainAxis); + YGResolveFlexDirection(node->getStyle().flexDirection(), direction); + const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); float childWidth = YGUndefined; float childHeight = YGUndefined; @@ -1460,9 +1457,9 @@ static void YGNodeAbsoluteLayoutChild( child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap(); if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { - childWidth = yoga::resolveValue( - child->getResolvedDimensions()[YGDimensionWidth], width) - .unwrap() + + childWidth = + YGResolveValue(child->getResolvedDimensions()[YGDimensionWidth], width) + .unwrap() + marginRow; } else { // If the child doesn't have a specified width, compute the width based on @@ -1481,7 +1478,7 @@ static void YGNodeAbsoluteLayoutChild( } if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) { - childHeight = yoga::resolveValue( + childHeight = YGResolveValue( child->getResolvedDimensions()[YGDimensionHeight], height) .unwrap() + marginColumn; @@ -1700,10 +1697,10 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( // We want to make sure we don't call measure with negative size const float innerWidth = YGFloatIsUndefined(availableWidth) ? availableWidth - : yoga::maxOrDefined(0, availableWidth - paddingAndBorderAxisRow); + : YGFloatMax(0, availableWidth - paddingAndBorderAxisRow); const float innerHeight = YGFloatIsUndefined(availableHeight) ? availableHeight - : yoga::maxOrDefined(0, availableHeight - paddingAndBorderAxisColumn); + : YGFloatMax(0, availableHeight - paddingAndBorderAxisColumn); if (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly) { @@ -1876,20 +1873,20 @@ static float YGNodeCalculateAvailableInnerDim( if (!YGFloatIsUndefined(availableInnerDim)) { // We want to make sure our available height does not violate min and max // constraints - const YGFloatOptional minDimensionOptional = yoga::resolveValue( - node->getStyle().minDimensions()[dimension], ownerDim); + const YGFloatOptional minDimensionOptional = + YGResolveValue(node->getStyle().minDimensions()[dimension], ownerDim); const float minInnerDim = minDimensionOptional.isUndefined() ? 0.0f : minDimensionOptional.unwrap() - paddingAndBorder; - const YGFloatOptional maxDimensionOptional = yoga::resolveValue( - node->getStyle().maxDimensions()[dimension], ownerDim); + const YGFloatOptional maxDimensionOptional = + YGResolveValue(node->getStyle().maxDimensions()[dimension], ownerDim); const float maxInnerDim = maxDimensionOptional.isUndefined() ? FLT_MAX : maxDimensionOptional.unwrap() - paddingAndBorder; - availableInnerDim = yoga::maxOrDefined( - yoga::minOrDefined(availableInnerDim, maxInnerDim), minInnerDim); + availableInnerDim = + YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim); } return availableInnerDim; @@ -1913,7 +1910,7 @@ static float YGNodeComputeFlexBasisForChildren( YGNodeRef singleFlexChild = nullptr; const auto& children = node->getChildren(); YGMeasureMode measureModeMainDim = - isRow(mainAxis) ? widthMeasureMode : heightMeasureMode; + YGFlexDirectionIsRow(mainAxis) ? widthMeasureMode : heightMeasureMode; // If there is only one child with flexGrow + flexShrink it means we can set // the computedFlexBasis to 0 instead of measuring and shrinking / flexing the // child to exactly match the remaining space @@ -1921,8 +1918,8 @@ static float YGNodeComputeFlexBasisForChildren( for (auto child : children) { if (child->isNodeFlexible()) { if (singleFlexChild != nullptr || - yoga::inexactEquals(child->resolveFlexGrow(), 0.0f) || - yoga::inexactEquals(child->resolveFlexShrink(), 0.0f)) { + YGFloatsEqual(child->resolveFlexGrow(), 0.0f) || + YGFloatsEqual(child->resolveFlexShrink(), 0.0f)) { // There is already a flexible child, or this flexible child doesn't // have flexGrow and flexShrink, abort singleFlexChild = nullptr; @@ -1945,10 +1942,12 @@ static float YGNodeComputeFlexBasisForChildren( if (performLayout) { // Set the initial position (relative to the owner). const YGDirection childDirection = child->resolveDirection(direction); - const float mainDim = - isRow(mainAxis) ? availableInnerWidth : availableInnerHeight; - const float crossDim = - isRow(mainAxis) ? availableInnerHeight : availableInnerWidth; + const float mainDim = YGFlexDirectionIsRow(mainAxis) + ? availableInnerWidth + : availableInnerHeight; + const float crossDim = YGFlexDirectionIsRow(mainAxis) + ? availableInnerHeight + : availableInnerWidth; child->setPosition( childDirection, mainDim, crossDim, availableInnerWidth); } @@ -1990,7 +1989,7 @@ static float YGNodeComputeFlexBasisForChildren( // computedFlexBasis properly computed(To do this use // YGNodeComputeFlexBasisForChildren function). This function calculates // YGCollectFlexItemsRowMeasurement -static CollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( +static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( yoga::Node* const node, const YGDirection ownerDirection, const float mainAxisownerSize, @@ -1998,11 +1997,11 @@ static CollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( const float availableInnerMainDim, const uint32_t startOfLineIndex, const uint32_t lineCount) { - CollectFlexItemsRowValues flexAlgoRowMeasurement = {}; + YGCollectFlexItemsRowValues flexAlgoRowMeasurement = {}; flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size()); float sizeConsumedOnCurrentLineIncludingMinConstraint = 0; - const YGFlexDirection mainAxis = resolveDirection( + const YGFlexDirection mainAxis = YGResolveFlexDirection( node->getStyle().flexDirection(), node->resolveDirection(ownerDirection)); const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap; const float gap = node->getGapForAxis(mainAxis, availableInnerWidth).unwrap(); @@ -2082,7 +2081,7 @@ static CollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( // function the child nodes would have proper size. Prior using this function // please ensure that YGDistributeFreeSpaceFirstPass is called. static float YGDistributeFreeSpaceSecondPass( - CollectFlexItemsRowValues& collectedFlexItemsValues, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, yoga::Node* const node, const YGFlexDirection mainAxis, const YGFlexDirection crossAxis, @@ -2103,7 +2102,7 @@ static float YGDistributeFreeSpaceSecondPass( float flexShrinkScaledFactor = 0; float flexGrowFactor = 0; float deltaFreeSpace = 0; - const bool isMainAxisRow = isRow(mainAxis); + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap; for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { @@ -2203,7 +2202,7 @@ static float YGDistributeFreeSpaceSecondPass( : YGMeasureModeAtMost; } else { childCrossSize = - yoga::resolveValue( + YGResolveValue( currentRelativeChild->getResolvedDimension(dim[crossAxis]), availableInnerCrossDim) .unwrap() + @@ -2280,7 +2279,7 @@ static float YGDistributeFreeSpaceSecondPass( // whose min and max constraints are triggered, those flex item's clamped size // is removed from the remaingfreespace. static void YGDistributeFreeSpaceFirstPass( - CollectFlexItemsRowValues& collectedFlexItemsValues, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, const YGFlexDirection mainAxis, const float mainAxisownerSize, const float availableInnerMainDim, @@ -2387,7 +2386,7 @@ static void YGDistributeFreeSpaceFirstPass( // static void YGResolveFlexibleLength( yoga::Node* const node, - CollectFlexItemsRowValues& collectedFlexItemsValues, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, const YGFlexDirection mainAxis, const YGFlexDirection crossAxis, const float mainAxisownerSize, @@ -2438,7 +2437,7 @@ static void YGResolveFlexibleLength( static void YGJustifyMainAxis( yoga::Node* const node, - CollectFlexItemsRowValues& collectedFlexItemsValues, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, const uint32_t startOfLineIndex, const YGFlexDirection mainAxis, const YGFlexDirection crossAxis, @@ -2462,8 +2461,7 @@ static void YGJustifyMainAxis( if (measureModeMainDim == YGMeasureModeAtMost && collectedFlexItemsValues.remainingFreeSpace > 0) { if (!style.minDimensions()[dim[mainAxis]].isUndefined() && - !yoga::resolveValue( - style.minDimensions()[dim[mainAxis]], mainAxisownerSize) + !YGResolveValue(style.minDimensions()[dim[mainAxis]], mainAxisownerSize) .isUndefined()) { // This condition makes sure that if the size of main dimension(after // considering child nodes main dim, leading and trailing padding etc) @@ -2473,14 +2471,14 @@ static void YGJustifyMainAxis( // `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( + YGResolveValue( style.minDimensions()[dim[mainAxis]], mainAxisownerSize) .unwrap() - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; const float occupiedSpaceByChildNodes = availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace; - collectedFlexItemsValues.remainingFreeSpace = yoga::maxOrDefined( - 0, minAvailableMainDim - occupiedSpaceByChildNodes); + collectedFlexItemsValues.remainingFreeSpace = + YGFloatMax(0, minAvailableMainDim - occupiedSpaceByChildNodes); } else { collectedFlexItemsValues.remainingFreeSpace = 0; } @@ -2519,8 +2517,7 @@ static void YGJustifyMainAxis( case YGJustifySpaceBetween: if (collectedFlexItemsValues.itemsOnLine > 1) { betweenMainDim += - yoga::maxOrDefined( - collectedFlexItemsValues.remainingFreeSpace, 0) / + YGFloatMax(collectedFlexItemsValues.remainingFreeSpace, 0) / (collectedFlexItemsValues.itemsOnLine - 1); } break; @@ -2631,14 +2628,14 @@ static void YGJustifyMainAxis( ascent; maxAscentForCurrentLine = - yoga::maxOrDefined(maxAscentForCurrentLine, ascent); + YGFloatMax(maxAscentForCurrentLine, ascent); maxDescentForCurrentLine = - yoga::maxOrDefined(maxDescentForCurrentLine, descent); + YGFloatMax(maxDescentForCurrentLine, descent); } else { // The cross dimension is the max of the elements dimension since // there can only be one element in that cross dimension in the case // when the items are not baseline aligned - collectedFlexItemsValues.crossDim = yoga::maxOrDefined( + collectedFlexItemsValues.crossDim = YGFloatMax( collectedFlexItemsValues.crossDim, YGNodeDimWithMargin(child, crossAxis, availableInnerWidth)); } @@ -2762,9 +2759,9 @@ static void YGNodelayoutImpl( node->setLayoutDirection(direction); const YGFlexDirection flexRowDirection = - resolveDirection(YGFlexDirectionRow, direction); + YGResolveFlexDirection(YGFlexDirectionRow, direction); const YGFlexDirection flexColumnDirection = - resolveDirection(YGFlexDirectionColumn, direction); + YGResolveFlexDirection(YGFlexDirectionColumn, direction); const YGEdge startEdge = direction == YGDirectionLTR ? YGEdgeLeft : YGEdgeRight; @@ -2854,9 +2851,9 @@ static void YGNodelayoutImpl( // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM const YGFlexDirection mainAxis = - resolveDirection(node->getStyle().flexDirection(), direction); - const YGFlexDirection crossAxis = resolveCrossDirection(mainAxis, direction); - const bool isMainAxisRow = isRow(mainAxis); + YGResolveFlexDirection(node->getStyle().flexDirection(), direction); + const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); + const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap; const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; @@ -2951,7 +2948,7 @@ static void YGNodelayoutImpl( // Max main dimension of all the lines. float maxLineMainDim = 0; - CollectFlexItemsRowValues collectedFlexItemsValues; + YGCollectFlexItemsRowValues collectedFlexItemsValues; for (; endOfLineIndex < childCount; lineCount++, startOfLineIndex = endOfLineIndex) { collectedFlexItemsValues = YGCalculateCollectFlexItemsRowValues( @@ -2981,19 +2978,17 @@ static void YGNodelayoutImpl( const auto& minDimensions = node->getStyle().minDimensions(); const auto& maxDimensions = node->getStyle().maxDimensions(); const float minInnerWidth = - yoga::resolveValue(minDimensions[YGDimensionWidth], ownerWidth) - .unwrap() - + YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() - paddingAndBorderAxisRow; const float maxInnerWidth = - yoga::resolveValue(maxDimensions[YGDimensionWidth], ownerWidth) - .unwrap() - + YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() - paddingAndBorderAxisRow; const float minInnerHeight = - yoga::resolveValue(minDimensions[YGDimensionHeight], ownerHeight) + YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight) .unwrap() - paddingAndBorderAxisColumn; const float maxInnerHeight = - yoga::resolveValue(maxDimensions[YGDimensionHeight], ownerHeight) + YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight) .unwrap() - paddingAndBorderAxisColumn; @@ -3246,14 +3241,13 @@ static void YGNodelayoutImpl( if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto && child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { - leadingCrossDim += - yoga::maxOrDefined(0.0f, remainingCrossDim / 2); + leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim / 2); } else if ( child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { // No-Op } else if ( child->marginLeadingValue(crossAxis).unit == YGUnitAuto) { - leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim); + leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim); } else if (alignItem == YGAlignFlexStart) { // No-Op } else if (alignItem == YGAlignCenter) { @@ -3274,7 +3268,7 @@ static void YGNodelayoutImpl( const float appliedCrossGap = lineCount != 0 ? crossAxisGap : 0.0f; totalLineCrossDim += collectedFlexItemsValues.crossDim + appliedCrossGap; maxLineMainDim = - yoga::maxOrDefined(maxLineMainDim, collectedFlexItemsValues.mainDim); + YGFloatMax(maxLineMainDim, collectedFlexItemsValues.mainDim); } // STEP 8: MULTI-LINE CONTENT ALIGNMENT @@ -3337,7 +3331,7 @@ static void YGNodelayoutImpl( break; } if (YGNodeIsLayoutDimDefined(child, crossAxis)) { - lineHeight = yoga::maxOrDefined( + lineHeight = YGFloatMax( lineHeight, child->getLayout().measuredDimensions[dim[crossAxis]] + child->getMarginForAxis(crossAxis, availableInnerWidth) @@ -3357,10 +3351,10 @@ static void YGNodelayoutImpl( .unwrap() - ascent; maxAscentForCurrentLine = - yoga::maxOrDefined(maxAscentForCurrentLine, ascent); + YGFloatMax(maxAscentForCurrentLine, ascent); maxDescentForCurrentLine = - yoga::maxOrDefined(maxDescentForCurrentLine, descent); - lineHeight = yoga::maxOrDefined( + YGFloatMax(maxDescentForCurrentLine, descent); + lineHeight = YGFloatMax( lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine); } } @@ -3428,11 +3422,11 @@ static void YGNodelayoutImpl( .unwrap()) : lineHeight; - if (!(yoga::inexactEquals( + if (!(YGFloatsEqual( childWidth, child->getLayout() .measuredDimensions[YGDimensionWidth]) && - yoga::inexactEquals( + YGFloatsEqual( childHeight, child->getLayout() .measuredDimensions[YGDimensionHeight]))) { @@ -3516,8 +3510,8 @@ static void YGNodelayoutImpl( measureModeMainDim == YGMeasureModeAtMost && node->getStyle().overflow() == YGOverflowScroll) { node->setLayoutMeasuredDimension( - yoga::maxOrDefined( - yoga::minOrDefined( + YGFloatMax( + YGFloatMin( availableInnerMainDim + paddingAndBorderAxisMain, YGNodeBoundAxisWithinMinAndMax( node, @@ -3547,8 +3541,8 @@ static void YGNodelayoutImpl( measureModeCrossDim == YGMeasureModeAtMost && node->getStyle().overflow() == YGOverflowScroll) { node->setLayoutMeasuredDimension( - yoga::maxOrDefined( - yoga::minOrDefined( + YGFloatMax( + YGFloatMin( availableInnerCrossDim + paddingAndBorderAxisCross, YGNodeBoundAxisWithinMinAndMax( node, @@ -3665,7 +3659,7 @@ static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize( float size, float lastComputedSize) { return sizeMode == YGMeasureModeExactly && - yoga::inexactEquals(size, lastComputedSize); + YGFloatsEqual(size, lastComputedSize); } static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits( @@ -3675,7 +3669,7 @@ static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits( float lastComputedSize) { return sizeMode == YGMeasureModeAtMost && lastSizeMode == YGMeasureModeUndefined && - (size >= lastComputedSize || yoga::inexactEquals(size, lastComputedSize)); + (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize)); } static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( @@ -3688,7 +3682,7 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) && !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) && lastSize > size && - (lastComputedSize <= size || yoga::inexactEquals(size, lastComputedSize)); + (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize)); } YOGA_EXPORT float YGRoundValueToPixelGrid( @@ -3718,10 +3712,10 @@ YOGA_EXPORT float YGRoundValueToPixelGrid( // - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3 ++fractial; } - if (yoga::inexactEquals(fractial, 0)) { + if (YGDoubleEqual(fractial, 0)) { // First we check if the value is already rounded scaledValue = scaledValue - fractial; - } else if (yoga::inexactEquals(fractial, 1.0)) { + } else if (YGDoubleEqual(fractial, 1.0)) { scaledValue = scaledValue - fractial + 1.0; } else if (forceCeil) { // Next we check if we need to use forced rounding @@ -3732,7 +3726,7 @@ YOGA_EXPORT float YGRoundValueToPixelGrid( // Finally we just round the value scaledValue = scaledValue - fractial + (!YGDoubleIsUndefined(fractial) && - (fractial > 0.5 || yoga::inexactEquals(fractial, 0.5)) + (fractial > 0.5 || YGDoubleEqual(fractial, 0.5)) ? 1.0 : 0.0); } @@ -3780,9 +3774,9 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( : lastHeight; const bool hasSameWidthSpec = lastWidthMode == widthMode && - yoga::inexactEquals(effectiveLastWidth, effectiveWidth); + YGFloatsEqual(effectiveLastWidth, effectiveWidth); const bool hasSameHeightSpec = lastHeightMode == heightMode && - yoga::inexactEquals(effectiveLastHeight, effectiveHeight); + YGFloatsEqual(effectiveLastHeight, effectiveHeight); const bool widthIsCompatible = hasSameWidthSpec || @@ -3914,19 +3908,17 @@ bool YGLayoutNodeInternal( } } } else if (performLayout) { - if (yoga::inexactEquals( - layout->cachedLayout.availableWidth, availableWidth) && - yoga::inexactEquals( - layout->cachedLayout.availableHeight, availableHeight) && + if (YGFloatsEqual(layout->cachedLayout.availableWidth, availableWidth) && + YGFloatsEqual(layout->cachedLayout.availableHeight, availableHeight) && layout->cachedLayout.widthMeasureMode == widthMeasureMode && layout->cachedLayout.heightMeasureMode == heightMeasureMode) { cachedResults = &layout->cachedLayout; } } else { for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { - if (yoga::inexactEquals( + if (YGFloatsEqual( layout->cachedMeasurements[i].availableWidth, availableWidth) && - yoga::inexactEquals( + YGFloatsEqual( layout->cachedMeasurements[i].availableHeight, availableHeight) && layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && layout->cachedMeasurements[i].heightMeasureMode == @@ -4153,11 +4145,11 @@ static void YGRoundToPixelGrid( // whole number, we don't have any fraction To verify if the result is close // to whole number we want to check both floor and ceil numbers const bool hasFractionalWidth = - !yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && - !yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); + !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && + !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); const bool hasFractionalHeight = - !yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && - !yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0); + !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && + !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0); node->setLayoutDimension( YGRoundValueToPixelGrid( @@ -4207,15 +4199,15 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( const auto& maxDimensions = node->getStyle().maxDimensions(); if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { width = - (yoga::resolveValue( + (YGResolveValue( node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) .unwrap(); widthMeasureMode = YGMeasureModeExactly; - } else if (!yoga::resolveValue(maxDimensions[YGDimensionWidth], ownerWidth) + } else if (!YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth) .isUndefined()) { - width = yoga::resolveValue(maxDimensions[YGDimensionWidth], ownerWidth) - .unwrap(); + width = + YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap(); widthMeasureMode = YGMeasureModeAtMost; } else { width = ownerWidth; @@ -4226,16 +4218,16 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( float height = YGUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { - height = (yoga::resolveValue( + height = (YGResolveValue( node->getResolvedDimension(dim[YGFlexDirectionColumn]), ownerHeight) + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) .unwrap(); heightMeasureMode = YGMeasureModeExactly; - } else if (!yoga::resolveValue(maxDimensions[YGDimensionHeight], ownerHeight) + } else if (!YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight) .isUndefined()) { - height = yoga::resolveValue(maxDimensions[YGDimensionHeight], ownerHeight) - .unwrap(); + height = + YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight).unwrap(); heightMeasureMode = YGMeasureModeAtMost; } else { height = ownerHeight; @@ -4296,14 +4288,6 @@ YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { } } -static void fatalWithMessage(const char* message) { -#if defined(__cpp_exceptions) - throw std::logic_error(message); -#else - std::terminate(); -#endif -} - void YGAssert(const bool condition, const char* message) { if (!condition) { yoga::log( @@ -4312,7 +4296,7 @@ void YGAssert(const bool condition, const char* message) { nullptr, "%s\n", message); - fatalWithMessage(message); + throwLogicalErrorWithMessage(message); } } @@ -4327,7 +4311,7 @@ void YGAssertWithNode( nullptr, "%s\n", message); - fatalWithMessage(message); + throwLogicalErrorWithMessage(message); } } @@ -4342,7 +4326,7 @@ void YGAssertWithConfig( nullptr, "%s\n", message); - fatalWithMessage(message); + throwLogicalErrorWithMessage(message); } } diff --git a/yoga/algorithm/CollectFlexItemsRowValues.h b/yoga/algorithm/CollectFlexItemsRowValues.h deleted file mode 100644 index 58a3916a..00000000 --- a/yoga/algorithm/CollectFlexItemsRowValues.h +++ /dev/null @@ -1,58 +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 - -namespace facebook::yoga { - -// This struct is an helper model to hold the data for step 4 of flexbox algo, -// which is collecting the flex items in a line. -// -// - itemsOnLine: Number of items which can fit in a line considering the -// available Inner dimension, the flex items computed flexbasis and their -// margin. It may be different than the difference between start and end -// indicates because we skip over absolute-positioned items. -// -// - sizeConsumedOnCurrentLine: It is accumulation of the dimensions and margin -// of all the children on the current line. This will be used in order to -// either set the dimensions of the node if none already exist or to compute -// the remaining space left for the flexible children. -// -// - totalFlexGrowFactors: total flex grow factors of flex items which are to be -// laid in the current line -// -// - totalFlexShrinkFactors: total flex shrink factors of flex items which are -// to be laid in the current line -// -// - endOfLineIndex: Its the end index of the last flex item which was examined -// and it may or may not be part of the current line(as it may be absolutely -// positioned or including it may have caused to overshoot availableInnerDim) -// -// - relativeChildren: Maintain a vector of the child nodes that can shrink -// and/or grow. - -struct CollectFlexItemsRowValues { - uint32_t itemsOnLine; - float sizeConsumedOnCurrentLine; - float totalFlexGrowFactors; - float totalFlexShrinkScaledFactors; - uint32_t endOfLineIndex; - std::vector relativeChildren; - float remainingFreeSpace; - // The size of the mainDim for the row after considering size, padding, margin - // and border of flex items. This is used to calculate maxLineDim after going - // through all the rows to decide on the main axis size of owner. - float mainDim; - // The size of the crossDim for the row after considering size, padding, - // margin and border of flex items. Used for calculating containers crossSize. - float crossDim; -}; - -} // namespace facebook::yoga diff --git a/yoga/algorithm/FlexDirection.h b/yoga/algorithm/FlexDirection.h deleted file mode 100644 index ed17ce2b..00000000 --- a/yoga/algorithm/FlexDirection.h +++ /dev/null @@ -1,46 +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 { - -inline bool isRow(const YGFlexDirection flexDirection) { - return flexDirection == YGFlexDirectionRow || - flexDirection == YGFlexDirectionRowReverse; -} - -inline bool isColumn(const YGFlexDirection flexDirection) { - return flexDirection == YGFlexDirectionColumn || - flexDirection == YGFlexDirectionColumnReverse; -} - -inline YGFlexDirection resolveDirection( - const YGFlexDirection flexDirection, - const YGDirection direction) { - if (direction == YGDirectionRTL) { - if (flexDirection == YGFlexDirectionRow) { - return YGFlexDirectionRowReverse; - } else if (flexDirection == YGFlexDirectionRowReverse) { - return YGFlexDirectionRow; - } - } - - return flexDirection; -} - -inline YGFlexDirection resolveCrossDirection( - const YGFlexDirection flexDirection, - const YGDirection direction) { - return isColumn(flexDirection) - ? resolveDirection(YGFlexDirectionRow, direction) - : YGFlexDirectionColumn; -} - -} // namespace facebook::yoga diff --git a/yoga/algorithm/ResolveValue.h b/yoga/algorithm/ResolveValue.h deleted file mode 100644 index 033a2420..00000000 --- a/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 - -namespace facebook::yoga { - -inline YGFloatOptional resolveValue( - const YGValue value, - const float ownerSize) { - switch (value.unit) { - case YGUnitPoint: - return YGFloatOptional{value.value}; - case YGUnitPercent: - return YGFloatOptional{value.value * ownerSize * 0.01f}; - default: - return YGFloatOptional{}; - } -} - -inline YGFloatOptional resolveValue(CompactValue value, float ownerSize) { - return resolveValue((YGValue) value, ownerSize); -} - -} // namespace facebook::yoga diff --git a/yoga/debug/NodeToString.cpp b/yoga/debug/NodeToString.cpp index 0a033cdb..b3d6986d 100644 --- a/yoga/debug/NodeToString.cpp +++ b/yoga/debug/NodeToString.cpp @@ -12,8 +12,8 @@ #include #include -#include #include +#include namespace facebook::yoga { @@ -24,9 +24,8 @@ static void indent(std::string& base, uint32_t level) { } static bool areFourValuesEqual(const Style::Edges& four) { - return yoga::inexactEquals(four[0], four[1]) && - yoga::inexactEquals(four[0], four[2]) && - yoga::inexactEquals(four[0], four[3]); + return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) && + YGValueEqual(four[0], four[3]); } static void appendFormattedString(std::string& str, const char* fmt, ...) { @@ -81,7 +80,7 @@ static void appendNumberIfNotZero( const YGValue number) { if (number.unit == YGUnitAuto) { base.append(str + ": auto; "); - } else if (!yoga::inexactEquals(number.value, 0)) { + } else if (!YGFloatsEqual(number.value, 0)) { appendNumberIfNotUndefined(base, str, number); } } diff --git a/yoga/node/LayoutResults.cpp b/yoga/node/LayoutResults.cpp index 6446b8cb..d6611aa1 100644 --- a/yoga/node/LayoutResults.cpp +++ b/yoga/node/LayoutResults.cpp @@ -6,16 +6,16 @@ */ #include -#include +#include namespace facebook::yoga { bool LayoutResults::operator==(LayoutResults layout) const { - bool isEqual = yoga::inexactEquals(position, layout.position) && - yoga::inexactEquals(dimensions, layout.dimensions) && - yoga::inexactEquals(margin, layout.margin) && - yoga::inexactEquals(border, layout.border) && - yoga::inexactEquals(padding, layout.padding) && + bool isEqual = YGFloatArrayEqual(position, layout.position) && + YGFloatArrayEqual(dimensions, layout.dimensions) && + YGFloatArrayEqual(margin, layout.margin) && + YGFloatArrayEqual(border, layout.border) && + YGFloatArrayEqual(padding, layout.padding) && direction() == layout.direction() && hadOverflow() == layout.hadOverflow() && lastOwnerDirection == layout.lastOwnerDirection && diff --git a/yoga/node/Node.cpp b/yoga/node/Node.cpp index c30ee78e..f0b355cf 100644 --- a/yoga/node/Node.cpp +++ b/yoga/node/Node.cpp @@ -5,13 +5,10 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #include - -#include -#include -#include -#include +#include namespace facebook::yoga { @@ -113,7 +110,7 @@ CompactValue Node::computeColumnGap( YGFloatOptional Node::getLeadingPosition( const YGFlexDirection axis, const float axisSize) const { - auto leadingPosition = isRow(axis) + auto leadingPosition = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.position(), YGEdgeStart, @@ -121,13 +118,13 @@ YGFloatOptional Node::getLeadingPosition( CompactValue::ofZero()) : computeEdgeValueForColumn( style_.position(), leading[axis], CompactValue::ofZero()); - return yoga::resolveValue(leadingPosition, axisSize); + return YGResolveValue(leadingPosition, axisSize); } YGFloatOptional Node::getTrailingPosition( const YGFlexDirection axis, const float axisSize) const { - auto trailingPosition = isRow(axis) + auto trailingPosition = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.position(), YGEdgeEnd, @@ -135,11 +132,11 @@ YGFloatOptional Node::getTrailingPosition( CompactValue::ofZero()) : computeEdgeValueForColumn( style_.position(), trailing[axis], CompactValue::ofZero()); - return yoga::resolveValue(trailingPosition, axisSize); + return YGResolveValue(trailingPosition, axisSize); } bool Node::isLeadingPositionDefined(const YGFlexDirection axis) const { - auto leadingPosition = isRow(axis) + auto leadingPosition = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.position(), YGEdgeStart, @@ -151,7 +148,7 @@ bool Node::isLeadingPositionDefined(const YGFlexDirection axis) const { } bool Node::isTrailingPosDefined(const YGFlexDirection axis) const { - auto trailingPosition = isRow(axis) + auto trailingPosition = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.position(), YGEdgeEnd, @@ -165,26 +162,23 @@ bool Node::isTrailingPosDefined(const YGFlexDirection axis) const { YGFloatOptional Node::getLeadingMargin( const YGFlexDirection axis, const float widthSize) const { - auto leadingMargin = isRow(axis) + auto leadingMargin = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero()) : computeEdgeValueForColumn( style_.margin(), leading[axis], CompactValue::ofZero()); - return leadingMargin.isAuto() ? YGFloatOptional{0} - : yoga::resolveValue(leadingMargin, widthSize); + return YGResolveValueMargin(leadingMargin, widthSize); } YGFloatOptional Node::getTrailingMargin( const YGFlexDirection axis, const float widthSize) const { - auto trailingMargin = isRow(axis) + auto trailingMargin = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) : computeEdgeValueForColumn( style_.margin(), trailing[axis], CompactValue::ofZero()); - return trailingMargin.isAuto() - ? YGFloatOptional{0} - : yoga::resolveValue(trailingMargin, widthSize); + return YGResolveValueMargin(trailingMargin, widthSize); } YGFloatOptional Node::getMarginForAxis( @@ -196,10 +190,10 @@ YGFloatOptional Node::getMarginForAxis( YGFloatOptional Node::getGapForAxis( const YGFlexDirection axis, const float widthSize) const { - auto gap = isRow(axis) + auto gap = YGFlexDirectionIsRow(axis) ? computeColumnGap(style_.gap(), CompactValue::ofZero()) : computeRowGap(style_.gap(), CompactValue::ofZero()); - return yoga::resolveValue(gap, widthSize); + return YGResolveValue(gap, widthSize); } YGSize Node::measure( @@ -376,9 +370,9 @@ void Node::setPosition( const YGDirection directionRespectingRoot = owner_ != nullptr ? direction : YGDirectionLTR; const YGFlexDirection mainAxis = - yoga::resolveDirection(style_.flexDirection(), directionRespectingRoot); + YGResolveFlexDirection(style_.flexDirection(), directionRespectingRoot); const YGFlexDirection crossAxis = - yoga::resolveCrossDirection(mainAxis, directionRespectingRoot); + YGFlexDirectionCross(mainAxis, directionRespectingRoot); // Here we should check for `YGPositionTypeStatic` and in this case zero inset // properties (left, right, top, bottom, begin, end). @@ -405,7 +399,8 @@ void Node::setPosition( } YGValue Node::marginLeadingValue(const YGFlexDirection axis) const { - if (isRow(axis) && !style_.margin()[YGEdgeStart].isUndefined()) { + if (YGFlexDirectionIsRow(axis) && + !style_.margin()[YGEdgeStart].isUndefined()) { return style_.margin()[YGEdgeStart]; } else { return style_.margin()[leading[axis]]; @@ -413,7 +408,7 @@ YGValue Node::marginLeadingValue(const YGFlexDirection axis) const { } YGValue Node::marginTrailingValue(const YGFlexDirection axis) const { - if (isRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) { + if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) { return style_.margin()[YGEdgeEnd]; } else { return style_.margin()[trailing[axis]]; @@ -436,8 +431,7 @@ void Node::resolveDimension() { const Style& style = getStyle(); for (auto dim : {YGDimensionWidth, YGDimensionHeight}) { if (!style.maxDimensions()[dim].isUndefined() && - yoga::inexactEquals( - style.maxDimensions()[dim], style.minDimensions()[dim])) { + YGValueEqual(style.maxDimensions()[dim], style.minDimensions()[dim])) { resolvedDimensions_[dim] = style.maxDimensions()[dim]; } else { resolvedDimensions_[dim] = style.dimensions()[dim]; @@ -517,7 +511,7 @@ bool Node::isNodeFlexible() { } float Node::getLeadingBorder(const YGFlexDirection axis) const { - YGValue leadingBorder = isRow(axis) + YGValue leadingBorder = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero()) : computeEdgeValueForColumn( @@ -526,7 +520,7 @@ float Node::getLeadingBorder(const YGFlexDirection axis) const { } float Node::getTrailingBorder(const YGFlexDirection axis) const { - YGValue trailingBorder = isRow(axis) + YGValue trailingBorder = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) : computeEdgeValueForColumn( @@ -537,7 +531,7 @@ float Node::getTrailingBorder(const YGFlexDirection axis) const { YGFloatOptional Node::getLeadingPadding( const YGFlexDirection axis, const float widthSize) const { - auto leadingPadding = isRow(axis) + auto leadingPadding = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.padding(), YGEdgeStart, @@ -545,20 +539,20 @@ YGFloatOptional Node::getLeadingPadding( CompactValue::ofZero()) : computeEdgeValueForColumn( style_.padding(), leading[axis], CompactValue::ofZero()); - return yoga::maxOrDefined( - yoga::resolveValue(leadingPadding, widthSize), YGFloatOptional(0.0f)); + return YGFloatOptionalMax( + YGResolveValue(leadingPadding, widthSize), YGFloatOptional(0.0f)); } YGFloatOptional Node::getTrailingPadding( const YGFlexDirection axis, const float widthSize) const { - auto trailingPadding = isRow(axis) + auto trailingPadding = YGFlexDirectionIsRow(axis) ? computeEdgeValueForRow( style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) : computeEdgeValueForColumn( style_.padding(), trailing[axis], CompactValue::ofZero()); - return yoga::maxOrDefined( - yoga::resolveValue(trailingPadding, widthSize), YGFloatOptional(0.0f)); + return YGFloatOptionalMax( + YGResolveValue(trailingPadding, widthSize), YGFloatOptional(0.0f)); } YGFloatOptional Node::getLeadingPaddingAndBorder( diff --git a/yoga/numeric/Comparison.h b/yoga/numeric/Comparison.h deleted file mode 100644 index 4e9b3515..00000000 --- a/yoga/numeric/Comparison.h +++ /dev/null @@ -1,87 +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 -#include - -namespace facebook::yoga { - -inline float maxOrDefined(const float a, const float b) { - if (!std::isnan(a) && !std::isnan(b)) { - return fmaxf(a, b); - } - return std::isnan(a) ? b : a; -} - -inline float minOrDefined(const float a, const float b) { - if (!std::isnan(a) && !std::isnan(b)) { - return fminf(a, b); - } - - return std::isnan(a) ? b : a; -} - -inline YGFloatOptional maxOrDefined(YGFloatOptional op1, YGFloatOptional op2) { - if (op1 >= op2) { - return op1; - } - if (op2 > op1) { - return op2; - } - return op1.isUndefined() ? op2 : op1; -} - -// Custom equality functions using a hardcoded epsilon of 0.0001f, or returning -// true if both floats are NaN. -inline bool inexactEquals(const float a, const float b) { - if (!std::isnan(a) && !std::isnan(b)) { - return fabs(a - b) < 0.0001f; - } - return std::isnan(a) && std::isnan(b); -} - -inline bool inexactEquals(const double a, const double b) { - if (!std::isnan(a) && !std::isnan(b)) { - return fabs(a - b) < 0.0001; - } - return std::isnan(a) && std::isnan(b); -} - -inline bool inexactEquals(const YGValue& a, const YGValue& b) { - if (a.unit != b.unit) { - return false; - } - - if (a.unit == YGUnitUndefined || - (std::isnan(a.value) && std::isnan(b.value))) { - return true; - } - - return fabs(a.value - b.value) < 0.0001f; -} - -inline bool inexactEquals(CompactValue a, CompactValue b) { - return inexactEquals((YGValue) a, (YGValue) b); -} - -template -bool inexactEquals( - const std::array& val1, - const std::array& val2) { - bool areEqual = true; - for (std::size_t i = 0; i < Size && areEqual; ++i) { - areEqual = inexactEquals(val1[i], val2[i]); - } - return areEqual; -} - -} // namespace facebook::yoga diff --git a/yoga/style/Style.cpp b/yoga/style/Style.cpp index fc268347..806f2428 100644 --- a/yoga/style/Style.cpp +++ b/yoga/style/Style.cpp @@ -6,7 +6,7 @@ */ #include -#include +#include namespace facebook::yoga { @@ -21,7 +21,7 @@ bool operator==(const Style& lhs, const Style& rhs) { lhs.positionType() == rhs.positionType() && lhs.flexWrap() == rhs.flexWrap() && lhs.overflow() == rhs.overflow() && lhs.display() == rhs.display() && - yoga::inexactEquals(lhs.flexBasis(), rhs.flexBasis()) && + YGValueEqual(lhs.flexBasis(), rhs.flexBasis()) && lhs.margin() == rhs.margin() && lhs.position() == rhs.position() && lhs.padding() == rhs.padding() && lhs.border() == rhs.border() && lhs.gap() == rhs.gap() && lhs.dimensions() == rhs.dimensions() &&