Revert D48767465: C++ Cleanup 5/N: Reorganize Utils

Differential Revision:
D48767465

Original commit changeset: da7157953292

Original Phabricator Diff: D48767465

fbshipit-source-id: 0dd948e2c4e6b3aaeb6e197b28b565c0b385d033
This commit is contained in:
Zhiyao Zhou
2023-08-29 23:27:25 -07:00
committed by Facebook GitHub Bot
parent 7cf0483b17
commit 4c0e89e492
13 changed files with 398 additions and 413 deletions

View File

@@ -7,12 +7,10 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <yoga/numeric/Comparison.h> #include <yoga/Utils.h>
#include <yoga/YGFloatOptional.h> #include <yoga/YGFloatOptional.h>
#include <yoga/YGValue.h> #include <yoga/YGValue.h>
using namespace facebook;
constexpr auto empty = YGFloatOptional{}; constexpr auto empty = YGFloatOptional{};
constexpr auto zero = YGFloatOptional{0.0f}; constexpr auto zero = YGFloatOptional{0.0f};
constexpr auto one = YGFloatOptional{1.0f}; constexpr auto one = YGFloatOptional{1.0f};
@@ -194,13 +192,13 @@ TEST(YGFloatOptional, addition) {
ASSERT_EQ(negative + empty, empty); ASSERT_EQ(negative + empty, empty);
} }
TEST(YGFloatOptionalTest, maxOrDefined) { TEST(YGFloatOptionalTest, YGFloatOptionalMax) {
ASSERT_EQ(yoga::maxOrDefined(empty, empty), empty); ASSERT_EQ(YGFloatOptionalMax(empty, empty), empty);
ASSERT_EQ(yoga::maxOrDefined(empty, positive), positive); ASSERT_EQ(YGFloatOptionalMax(empty, positive), positive);
ASSERT_EQ(yoga::maxOrDefined(negative, empty), negative); ASSERT_EQ(YGFloatOptionalMax(negative, empty), negative);
ASSERT_EQ(yoga::maxOrDefined(negative, YGFloatOptional{-INFINITY}), negative); ASSERT_EQ(YGFloatOptionalMax(negative, YGFloatOptional{-INFINITY}), negative);
ASSERT_EQ( ASSERT_EQ(
yoga::maxOrDefined(YGFloatOptional{1.0f}, YGFloatOptional{1.125f}), YGFloatOptionalMax(YGFloatOptional{1.0f}, YGFloatOptional{1.125f}),
YGFloatOptional{1.125f}); YGFloatOptional{1.125f});
} }

83
yoga/Utils.cpp Normal file
View File

@@ -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 <stdexcept>
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)
}

146
yoga/Utils.h Normal file
View File

@@ -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 <yoga/node/Node.h>
#include <yoga/Yoga-internal.h>
#include <yoga/style/CompactValue.h>
// 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<facebook::yoga::Node*> 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 <std::size_t size>
bool YGFloatArrayEqual(
const std::array<float, size>& val1,
const std::array<float, size>& 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);
}

View File

@@ -41,6 +41,8 @@ inline bool isUndefined(double value) {
return std::isnan(value); return std::isnan(value);
} }
void throwLogicalErrorWithMessage(const char* message);
} // namespace facebook::yoga } // namespace facebook::yoga
extern const std::array<YGEdge, 4> trailing; extern const std::array<YGEdge, 4> trailing;
@@ -147,3 +149,5 @@ public:
static const float kDefaultFlexGrow = 0.0f; static const float kDefaultFlexGrow = 0.0f;
static const float kDefaultFlexShrink = 0.0f; static const float kDefaultFlexShrink = 0.0f;
static const float kWebDefaultFlexShrink = 1.0f; static const float kWebDefaultFlexShrink = 1.0f;
extern bool YGFloatsEqual(const float a, const float b);

View File

@@ -5,24 +5,20 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#include <float.h>
#include <string.h>
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <cfloat>
#include <cstring>
#include <memory> #include <memory>
#include <stdexcept>
#include <yoga/Yoga.h> #include <yoga/Yoga.h>
#include <yoga/Yoga-internal.h>
#include <yoga/algorithm/CollectFlexItemsRowValues.h>
#include <yoga/algorithm/FlexDirection.h>
#include <yoga/algorithm/ResolveValue.h>
#include <yoga/debug/Log.h> #include <yoga/debug/Log.h>
#include <yoga/debug/NodeToString.h> #include <yoga/debug/NodeToString.h>
#include <yoga/event/event.h> #include <yoga/Utils.h>
#include <yoga/node/Node.h> #include <yoga/node/Node.h>
#include <yoga/numeric/Comparison.h> #include <yoga/Yoga-internal.h>
#include "event/event.h"
using namespace facebook; using namespace facebook;
using namespace facebook::yoga; using namespace facebook::yoga;
@@ -1043,7 +1039,8 @@ static inline YGAlign YGNodeAlignItem(
const YGAlign align = child->getStyle().alignSelf() == YGAlignAuto const YGAlign align = child->getStyle().alignSelf() == YGAlignAuto
? node->getStyle().alignItems() ? node->getStyle().alignItems()
: child->getStyle().alignSelf(); : child->getStyle().alignSelf();
if (align == YGAlignBaseline && isColumn(node->getStyle().flexDirection())) { if (align == YGAlignBaseline &&
YGFlexDirectionIsColumn(node->getStyle().flexDirection())) {
return YGAlignFlexStart; return YGAlignFlexStart;
} }
return align; return align;
@@ -1098,7 +1095,7 @@ static float YGBaseline(yoga::Node* node, void* layoutContext) {
} }
static bool YGIsBaselineLayout(const yoga::Node* node) { static bool YGIsBaselineLayout(const yoga::Node* node) {
if (isColumn(node->getStyle().flexDirection())) { if (YGFlexDirectionIsColumn(node->getStyle().flexDirection())) {
return false; return false;
} }
if (node->getStyle().alignItems() == YGAlignBaseline) { if (node->getStyle().alignItems() == YGAlignBaseline) {
@@ -1158,15 +1155,15 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax(
YGFloatOptional min; YGFloatOptional min;
YGFloatOptional max; YGFloatOptional max;
if (isColumn(axis)) { if (YGFlexDirectionIsColumn(axis)) {
min = yoga::resolveValue( min = YGResolveValue(
node->getStyle().minDimensions()[YGDimensionHeight], axisSize); node->getStyle().minDimensions()[YGDimensionHeight], axisSize);
max = yoga::resolveValue( max = YGResolveValue(
node->getStyle().maxDimensions()[YGDimensionHeight], axisSize); node->getStyle().maxDimensions()[YGDimensionHeight], axisSize);
} else if (isRow(axis)) { } else if (YGFlexDirectionIsRow(axis)) {
min = yoga::resolveValue( min = YGResolveValue(
node->getStyle().minDimensions()[YGDimensionWidth], axisSize); node->getStyle().minDimensions()[YGDimensionWidth], axisSize);
max = yoga::resolveValue( max = YGResolveValue(
node->getStyle().maxDimensions()[YGDimensionWidth], axisSize); node->getStyle().maxDimensions()[YGDimensionWidth], axisSize);
} }
@@ -1189,7 +1186,7 @@ static inline float YGNodeBoundAxis(
const float value, const float value,
const float axisSize, const float axisSize,
const float widthSize) { const float widthSize) {
return yoga::maxOrDefined( return YGFloatMax(
YGNodeBoundAxisWithinMinAndMax( YGNodeBoundAxisWithinMinAndMax(
node, axis, YGFloatOptional{value}, axisSize) node, axis, YGFloatOptional{value}, axisSize)
.unwrap(), .unwrap(),
@@ -1215,7 +1212,7 @@ static void YGConstrainMaxSizeForMode(
YGMeasureMode* mode, YGMeasureMode* mode,
float* size) { float* size) {
const YGFloatOptional maxSize = const YGFloatOptional maxSize =
yoga::resolveValue( YGResolveValue(
node->getStyle().maxDimensions()[dim[axis]], ownerAxisSize) + node->getStyle().maxDimensions()[dim[axis]], ownerAxisSize) +
YGFloatOptional(node->getMarginForAxis(axis, ownerWidth)); YGFloatOptional(node->getMarginForAxis(axis, ownerWidth));
switch (*mode) { switch (*mode) {
@@ -1250,8 +1247,8 @@ static void YGNodeComputeFlexBasisForChild(
const uint32_t depth, const uint32_t depth,
const uint32_t generationCount) { const uint32_t generationCount) {
const YGFlexDirection mainAxis = const YGFlexDirection mainAxis =
resolveDirection(node->getStyle().flexDirection(), direction); YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
const bool isMainAxisRow = isRow(mainAxis); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
const float mainAxisSize = isMainAxisRow ? width : height; const float mainAxisSize = isMainAxisRow ? width : height;
const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight;
@@ -1261,7 +1258,7 @@ static void YGNodeComputeFlexBasisForChild(
YGMeasureMode childHeightMeasureMode; YGMeasureMode childHeightMeasureMode;
const YGFloatOptional resolvedFlexBasis = const YGFloatOptional resolvedFlexBasis =
yoga::resolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize); YGResolveValue(child->resolveFlexBasisPtr(), mainAxisownerSize);
const bool isRowStyleDimDefined = const bool isRowStyleDimDefined =
YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, ownerWidth); YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, ownerWidth);
const bool isColumnStyleDimDefined = const bool isColumnStyleDimDefined =
@@ -1275,15 +1272,15 @@ static void YGNodeComputeFlexBasisForChild(
const YGFloatOptional paddingAndBorder = YGFloatOptional( const YGFloatOptional paddingAndBorder = YGFloatOptional(
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth));
child->setLayoutComputedFlexBasis( child->setLayoutComputedFlexBasis(
yoga::maxOrDefined(resolvedFlexBasis, paddingAndBorder)); YGFloatOptionalMax(resolvedFlexBasis, paddingAndBorder));
} }
} else if (isMainAxisRow && isRowStyleDimDefined) { } else if (isMainAxisRow && isRowStyleDimDefined) {
// The width is definite, so use that as the flex basis. // The width is definite, so use that as the flex basis.
const YGFloatOptional paddingAndBorder = YGFloatOptional( const YGFloatOptional paddingAndBorder = YGFloatOptional(
YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth)); YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth));
child->setLayoutComputedFlexBasis(yoga::maxOrDefined( child->setLayoutComputedFlexBasis(YGFloatOptionalMax(
yoga::resolveValue( YGResolveValue(
child->getResolvedDimensions()[YGDimensionWidth], ownerWidth), child->getResolvedDimensions()[YGDimensionWidth], ownerWidth),
paddingAndBorder)); paddingAndBorder));
} else if (!isMainAxisRow && isColumnStyleDimDefined) { } else if (!isMainAxisRow && isColumnStyleDimDefined) {
@@ -1291,8 +1288,8 @@ static void YGNodeComputeFlexBasisForChild(
const YGFloatOptional paddingAndBorder = const YGFloatOptional paddingAndBorder =
YGFloatOptional(YGNodePaddingAndBorderForAxis( YGFloatOptional(YGNodePaddingAndBorderForAxis(
child, YGFlexDirectionColumn, ownerWidth)); child, YGFlexDirectionColumn, ownerWidth));
child->setLayoutComputedFlexBasis(yoga::maxOrDefined( child->setLayoutComputedFlexBasis(YGFloatOptionalMax(
yoga::resolveValue( YGResolveValue(
child->getResolvedDimensions()[YGDimensionHeight], ownerHeight), child->getResolvedDimensions()[YGDimensionHeight], ownerHeight),
paddingAndBorder)); paddingAndBorder));
} else { } else {
@@ -1310,7 +1307,7 @@ static void YGNodeComputeFlexBasisForChild(
if (isRowStyleDimDefined) { if (isRowStyleDimDefined) {
childWidth = childWidth =
yoga::resolveValue( YGResolveValue(
child->getResolvedDimensions()[YGDimensionWidth], ownerWidth) child->getResolvedDimensions()[YGDimensionWidth], ownerWidth)
.unwrap() + .unwrap() +
marginRow; marginRow;
@@ -1318,7 +1315,7 @@ static void YGNodeComputeFlexBasisForChild(
} }
if (isColumnStyleDimDefined) { if (isColumnStyleDimDefined) {
childHeight = childHeight =
yoga::resolveValue( YGResolveValue(
child->getResolvedDimensions()[YGDimensionHeight], ownerHeight) child->getResolvedDimensions()[YGDimensionHeight], ownerHeight)
.unwrap() + .unwrap() +
marginColumn; marginColumn;
@@ -1426,7 +1423,7 @@ static void YGNodeComputeFlexBasisForChild(
depth, depth,
generationCount); generationCount);
child->setLayoutComputedFlexBasis(YGFloatOptional(yoga::maxOrDefined( child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax(
child->getLayout().measuredDimensions[dim[mainAxis]], child->getLayout().measuredDimensions[dim[mainAxis]],
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)))); YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth))));
} }
@@ -1446,9 +1443,9 @@ static void YGNodeAbsoluteLayoutChild(
const uint32_t depth, const uint32_t depth,
const uint32_t generationCount) { const uint32_t generationCount) {
const YGFlexDirection mainAxis = const YGFlexDirection mainAxis =
resolveDirection(node->getStyle().flexDirection(), direction); YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
const YGFlexDirection crossAxis = resolveCrossDirection(mainAxis, direction); const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
const bool isMainAxisRow = isRow(mainAxis); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
float childWidth = YGUndefined; float childWidth = YGUndefined;
float childHeight = YGUndefined; float childHeight = YGUndefined;
@@ -1460,9 +1457,9 @@ static void YGNodeAbsoluteLayoutChild(
child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap(); child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap();
if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) { if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) {
childWidth = yoga::resolveValue( childWidth =
child->getResolvedDimensions()[YGDimensionWidth], width) YGResolveValue(child->getResolvedDimensions()[YGDimensionWidth], width)
.unwrap() + .unwrap() +
marginRow; marginRow;
} else { } else {
// If the child doesn't have a specified width, compute the width based on // 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)) { if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) {
childHeight = yoga::resolveValue( childHeight = YGResolveValue(
child->getResolvedDimensions()[YGDimensionHeight], height) child->getResolvedDimensions()[YGDimensionHeight], height)
.unwrap() + .unwrap() +
marginColumn; marginColumn;
@@ -1700,10 +1697,10 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(
// We want to make sure we don't call measure with negative size // We want to make sure we don't call measure with negative size
const float innerWidth = YGFloatIsUndefined(availableWidth) const float innerWidth = YGFloatIsUndefined(availableWidth)
? availableWidth ? availableWidth
: yoga::maxOrDefined(0, availableWidth - paddingAndBorderAxisRow); : YGFloatMax(0, availableWidth - paddingAndBorderAxisRow);
const float innerHeight = YGFloatIsUndefined(availableHeight) const float innerHeight = YGFloatIsUndefined(availableHeight)
? availableHeight ? availableHeight
: yoga::maxOrDefined(0, availableHeight - paddingAndBorderAxisColumn); : YGFloatMax(0, availableHeight - paddingAndBorderAxisColumn);
if (widthMeasureMode == YGMeasureModeExactly && if (widthMeasureMode == YGMeasureModeExactly &&
heightMeasureMode == YGMeasureModeExactly) { heightMeasureMode == YGMeasureModeExactly) {
@@ -1876,20 +1873,20 @@ static float YGNodeCalculateAvailableInnerDim(
if (!YGFloatIsUndefined(availableInnerDim)) { if (!YGFloatIsUndefined(availableInnerDim)) {
// We want to make sure our available height does not violate min and max // We want to make sure our available height does not violate min and max
// constraints // constraints
const YGFloatOptional minDimensionOptional = yoga::resolveValue( const YGFloatOptional minDimensionOptional =
node->getStyle().minDimensions()[dimension], ownerDim); YGResolveValue(node->getStyle().minDimensions()[dimension], ownerDim);
const float minInnerDim = minDimensionOptional.isUndefined() const float minInnerDim = minDimensionOptional.isUndefined()
? 0.0f ? 0.0f
: minDimensionOptional.unwrap() - paddingAndBorder; : minDimensionOptional.unwrap() - paddingAndBorder;
const YGFloatOptional maxDimensionOptional = yoga::resolveValue( const YGFloatOptional maxDimensionOptional =
node->getStyle().maxDimensions()[dimension], ownerDim); YGResolveValue(node->getStyle().maxDimensions()[dimension], ownerDim);
const float maxInnerDim = maxDimensionOptional.isUndefined() const float maxInnerDim = maxDimensionOptional.isUndefined()
? FLT_MAX ? FLT_MAX
: maxDimensionOptional.unwrap() - paddingAndBorder; : maxDimensionOptional.unwrap() - paddingAndBorder;
availableInnerDim = yoga::maxOrDefined( availableInnerDim =
yoga::minOrDefined(availableInnerDim, maxInnerDim), minInnerDim); YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim);
} }
return availableInnerDim; return availableInnerDim;
@@ -1913,7 +1910,7 @@ static float YGNodeComputeFlexBasisForChildren(
YGNodeRef singleFlexChild = nullptr; YGNodeRef singleFlexChild = nullptr;
const auto& children = node->getChildren(); const auto& children = node->getChildren();
YGMeasureMode measureModeMainDim = YGMeasureMode measureModeMainDim =
isRow(mainAxis) ? widthMeasureMode : heightMeasureMode; YGFlexDirectionIsRow(mainAxis) ? widthMeasureMode : heightMeasureMode;
// If there is only one child with flexGrow + flexShrink it means we can set // 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 // the computedFlexBasis to 0 instead of measuring and shrinking / flexing the
// child to exactly match the remaining space // child to exactly match the remaining space
@@ -1921,8 +1918,8 @@ static float YGNodeComputeFlexBasisForChildren(
for (auto child : children) { for (auto child : children) {
if (child->isNodeFlexible()) { if (child->isNodeFlexible()) {
if (singleFlexChild != nullptr || if (singleFlexChild != nullptr ||
yoga::inexactEquals(child->resolveFlexGrow(), 0.0f) || YGFloatsEqual(child->resolveFlexGrow(), 0.0f) ||
yoga::inexactEquals(child->resolveFlexShrink(), 0.0f)) { YGFloatsEqual(child->resolveFlexShrink(), 0.0f)) {
// There is already a flexible child, or this flexible child doesn't // There is already a flexible child, or this flexible child doesn't
// have flexGrow and flexShrink, abort // have flexGrow and flexShrink, abort
singleFlexChild = nullptr; singleFlexChild = nullptr;
@@ -1945,10 +1942,12 @@ static float YGNodeComputeFlexBasisForChildren(
if (performLayout) { if (performLayout) {
// Set the initial position (relative to the owner). // Set the initial position (relative to the owner).
const YGDirection childDirection = child->resolveDirection(direction); const YGDirection childDirection = child->resolveDirection(direction);
const float mainDim = const float mainDim = YGFlexDirectionIsRow(mainAxis)
isRow(mainAxis) ? availableInnerWidth : availableInnerHeight; ? availableInnerWidth
const float crossDim = : availableInnerHeight;
isRow(mainAxis) ? availableInnerHeight : availableInnerWidth; const float crossDim = YGFlexDirectionIsRow(mainAxis)
? availableInnerHeight
: availableInnerWidth;
child->setPosition( child->setPosition(
childDirection, mainDim, crossDim, availableInnerWidth); childDirection, mainDim, crossDim, availableInnerWidth);
} }
@@ -1990,7 +1989,7 @@ static float YGNodeComputeFlexBasisForChildren(
// computedFlexBasis properly computed(To do this use // computedFlexBasis properly computed(To do this use
// YGNodeComputeFlexBasisForChildren function). This function calculates // YGNodeComputeFlexBasisForChildren function). This function calculates
// YGCollectFlexItemsRowMeasurement // YGCollectFlexItemsRowMeasurement
static CollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
yoga::Node* const node, yoga::Node* const node,
const YGDirection ownerDirection, const YGDirection ownerDirection,
const float mainAxisownerSize, const float mainAxisownerSize,
@@ -1998,11 +1997,11 @@ static CollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
const float availableInnerMainDim, const float availableInnerMainDim,
const uint32_t startOfLineIndex, const uint32_t startOfLineIndex,
const uint32_t lineCount) { const uint32_t lineCount) {
CollectFlexItemsRowValues flexAlgoRowMeasurement = {}; YGCollectFlexItemsRowValues flexAlgoRowMeasurement = {};
flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size()); flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size());
float sizeConsumedOnCurrentLineIncludingMinConstraint = 0; float sizeConsumedOnCurrentLineIncludingMinConstraint = 0;
const YGFlexDirection mainAxis = resolveDirection( const YGFlexDirection mainAxis = YGResolveFlexDirection(
node->getStyle().flexDirection(), node->resolveDirection(ownerDirection)); node->getStyle().flexDirection(), node->resolveDirection(ownerDirection));
const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap; const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
const float gap = node->getGapForAxis(mainAxis, availableInnerWidth).unwrap(); 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 // function the child nodes would have proper size. Prior using this function
// please ensure that YGDistributeFreeSpaceFirstPass is called. // please ensure that YGDistributeFreeSpaceFirstPass is called.
static float YGDistributeFreeSpaceSecondPass( static float YGDistributeFreeSpaceSecondPass(
CollectFlexItemsRowValues& collectedFlexItemsValues, YGCollectFlexItemsRowValues& collectedFlexItemsValues,
yoga::Node* const node, yoga::Node* const node,
const YGFlexDirection mainAxis, const YGFlexDirection mainAxis,
const YGFlexDirection crossAxis, const YGFlexDirection crossAxis,
@@ -2103,7 +2102,7 @@ static float YGDistributeFreeSpaceSecondPass(
float flexShrinkScaledFactor = 0; float flexShrinkScaledFactor = 0;
float flexGrowFactor = 0; float flexGrowFactor = 0;
float deltaFreeSpace = 0; float deltaFreeSpace = 0;
const bool isMainAxisRow = isRow(mainAxis); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap; const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) {
@@ -2203,7 +2202,7 @@ static float YGDistributeFreeSpaceSecondPass(
: YGMeasureModeAtMost; : YGMeasureModeAtMost;
} else { } else {
childCrossSize = childCrossSize =
yoga::resolveValue( YGResolveValue(
currentRelativeChild->getResolvedDimension(dim[crossAxis]), currentRelativeChild->getResolvedDimension(dim[crossAxis]),
availableInnerCrossDim) availableInnerCrossDim)
.unwrap() + .unwrap() +
@@ -2280,7 +2279,7 @@ static float YGDistributeFreeSpaceSecondPass(
// whose min and max constraints are triggered, those flex item's clamped size // whose min and max constraints are triggered, those flex item's clamped size
// is removed from the remaingfreespace. // is removed from the remaingfreespace.
static void YGDistributeFreeSpaceFirstPass( static void YGDistributeFreeSpaceFirstPass(
CollectFlexItemsRowValues& collectedFlexItemsValues, YGCollectFlexItemsRowValues& collectedFlexItemsValues,
const YGFlexDirection mainAxis, const YGFlexDirection mainAxis,
const float mainAxisownerSize, const float mainAxisownerSize,
const float availableInnerMainDim, const float availableInnerMainDim,
@@ -2387,7 +2386,7 @@ static void YGDistributeFreeSpaceFirstPass(
// //
static void YGResolveFlexibleLength( static void YGResolveFlexibleLength(
yoga::Node* const node, yoga::Node* const node,
CollectFlexItemsRowValues& collectedFlexItemsValues, YGCollectFlexItemsRowValues& collectedFlexItemsValues,
const YGFlexDirection mainAxis, const YGFlexDirection mainAxis,
const YGFlexDirection crossAxis, const YGFlexDirection crossAxis,
const float mainAxisownerSize, const float mainAxisownerSize,
@@ -2438,7 +2437,7 @@ static void YGResolveFlexibleLength(
static void YGJustifyMainAxis( static void YGJustifyMainAxis(
yoga::Node* const node, yoga::Node* const node,
CollectFlexItemsRowValues& collectedFlexItemsValues, YGCollectFlexItemsRowValues& collectedFlexItemsValues,
const uint32_t startOfLineIndex, const uint32_t startOfLineIndex,
const YGFlexDirection mainAxis, const YGFlexDirection mainAxis,
const YGFlexDirection crossAxis, const YGFlexDirection crossAxis,
@@ -2462,8 +2461,7 @@ static void YGJustifyMainAxis(
if (measureModeMainDim == YGMeasureModeAtMost && if (measureModeMainDim == YGMeasureModeAtMost &&
collectedFlexItemsValues.remainingFreeSpace > 0) { collectedFlexItemsValues.remainingFreeSpace > 0) {
if (!style.minDimensions()[dim[mainAxis]].isUndefined() && if (!style.minDimensions()[dim[mainAxis]].isUndefined() &&
!yoga::resolveValue( !YGResolveValue(style.minDimensions()[dim[mainAxis]], mainAxisownerSize)
style.minDimensions()[dim[mainAxis]], mainAxisownerSize)
.isUndefined()) { .isUndefined()) {
// This condition makes sure that if the size of main dimension(after // This condition makes sure that if the size of main dimension(after
// considering child nodes main dim, leading and trailing padding etc) // 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 // `minAvailableMainDim` denotes minimum available space in which child
// can be laid out, it will exclude space consumed by padding and border. // can be laid out, it will exclude space consumed by padding and border.
const float minAvailableMainDim = const float minAvailableMainDim =
yoga::resolveValue( YGResolveValue(
style.minDimensions()[dim[mainAxis]], mainAxisownerSize) style.minDimensions()[dim[mainAxis]], mainAxisownerSize)
.unwrap() - .unwrap() -
leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; leadingPaddingAndBorderMain - trailingPaddingAndBorderMain;
const float occupiedSpaceByChildNodes = const float occupiedSpaceByChildNodes =
availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace; availableInnerMainDim - collectedFlexItemsValues.remainingFreeSpace;
collectedFlexItemsValues.remainingFreeSpace = yoga::maxOrDefined( collectedFlexItemsValues.remainingFreeSpace =
0, minAvailableMainDim - occupiedSpaceByChildNodes); YGFloatMax(0, minAvailableMainDim - occupiedSpaceByChildNodes);
} else { } else {
collectedFlexItemsValues.remainingFreeSpace = 0; collectedFlexItemsValues.remainingFreeSpace = 0;
} }
@@ -2519,8 +2517,7 @@ static void YGJustifyMainAxis(
case YGJustifySpaceBetween: case YGJustifySpaceBetween:
if (collectedFlexItemsValues.itemsOnLine > 1) { if (collectedFlexItemsValues.itemsOnLine > 1) {
betweenMainDim += betweenMainDim +=
yoga::maxOrDefined( YGFloatMax(collectedFlexItemsValues.remainingFreeSpace, 0) /
collectedFlexItemsValues.remainingFreeSpace, 0) /
(collectedFlexItemsValues.itemsOnLine - 1); (collectedFlexItemsValues.itemsOnLine - 1);
} }
break; break;
@@ -2631,14 +2628,14 @@ static void YGJustifyMainAxis(
ascent; ascent;
maxAscentForCurrentLine = maxAscentForCurrentLine =
yoga::maxOrDefined(maxAscentForCurrentLine, ascent); YGFloatMax(maxAscentForCurrentLine, ascent);
maxDescentForCurrentLine = maxDescentForCurrentLine =
yoga::maxOrDefined(maxDescentForCurrentLine, descent); YGFloatMax(maxDescentForCurrentLine, descent);
} else { } else {
// The cross dimension is the max of the elements dimension since // The cross dimension is the max of the elements dimension since
// there can only be one element in that cross dimension in the case // there can only be one element in that cross dimension in the case
// when the items are not baseline aligned // when the items are not baseline aligned
collectedFlexItemsValues.crossDim = yoga::maxOrDefined( collectedFlexItemsValues.crossDim = YGFloatMax(
collectedFlexItemsValues.crossDim, collectedFlexItemsValues.crossDim,
YGNodeDimWithMargin(child, crossAxis, availableInnerWidth)); YGNodeDimWithMargin(child, crossAxis, availableInnerWidth));
} }
@@ -2762,9 +2759,9 @@ static void YGNodelayoutImpl(
node->setLayoutDirection(direction); node->setLayoutDirection(direction);
const YGFlexDirection flexRowDirection = const YGFlexDirection flexRowDirection =
resolveDirection(YGFlexDirectionRow, direction); YGResolveFlexDirection(YGFlexDirectionRow, direction);
const YGFlexDirection flexColumnDirection = const YGFlexDirection flexColumnDirection =
resolveDirection(YGFlexDirectionColumn, direction); YGResolveFlexDirection(YGFlexDirectionColumn, direction);
const YGEdge startEdge = const YGEdge startEdge =
direction == YGDirectionLTR ? YGEdgeLeft : YGEdgeRight; direction == YGDirectionLTR ? YGEdgeLeft : YGEdgeRight;
@@ -2854,9 +2851,9 @@ static void YGNodelayoutImpl(
// STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM // STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM
const YGFlexDirection mainAxis = const YGFlexDirection mainAxis =
resolveDirection(node->getStyle().flexDirection(), direction); YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
const YGFlexDirection crossAxis = resolveCrossDirection(mainAxis, direction); const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
const bool isMainAxisRow = isRow(mainAxis); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap; const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight; const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight;
@@ -2951,7 +2948,7 @@ static void YGNodelayoutImpl(
// Max main dimension of all the lines. // Max main dimension of all the lines.
float maxLineMainDim = 0; float maxLineMainDim = 0;
CollectFlexItemsRowValues collectedFlexItemsValues; YGCollectFlexItemsRowValues collectedFlexItemsValues;
for (; endOfLineIndex < childCount; for (; endOfLineIndex < childCount;
lineCount++, startOfLineIndex = endOfLineIndex) { lineCount++, startOfLineIndex = endOfLineIndex) {
collectedFlexItemsValues = YGCalculateCollectFlexItemsRowValues( collectedFlexItemsValues = YGCalculateCollectFlexItemsRowValues(
@@ -2981,19 +2978,17 @@ static void YGNodelayoutImpl(
const auto& minDimensions = node->getStyle().minDimensions(); const auto& minDimensions = node->getStyle().minDimensions();
const auto& maxDimensions = node->getStyle().maxDimensions(); const auto& maxDimensions = node->getStyle().maxDimensions();
const float minInnerWidth = const float minInnerWidth =
yoga::resolveValue(minDimensions[YGDimensionWidth], ownerWidth) YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() -
.unwrap() -
paddingAndBorderAxisRow; paddingAndBorderAxisRow;
const float maxInnerWidth = const float maxInnerWidth =
yoga::resolveValue(maxDimensions[YGDimensionWidth], ownerWidth) YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() -
.unwrap() -
paddingAndBorderAxisRow; paddingAndBorderAxisRow;
const float minInnerHeight = const float minInnerHeight =
yoga::resolveValue(minDimensions[YGDimensionHeight], ownerHeight) YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight)
.unwrap() - .unwrap() -
paddingAndBorderAxisColumn; paddingAndBorderAxisColumn;
const float maxInnerHeight = const float maxInnerHeight =
yoga::resolveValue(maxDimensions[YGDimensionHeight], ownerHeight) YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight)
.unwrap() - .unwrap() -
paddingAndBorderAxisColumn; paddingAndBorderAxisColumn;
@@ -3246,14 +3241,13 @@ static void YGNodelayoutImpl(
if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto && if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto &&
child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
leadingCrossDim += leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim / 2);
yoga::maxOrDefined(0.0f, remainingCrossDim / 2);
} else if ( } else if (
child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { child->marginTrailingValue(crossAxis).unit == YGUnitAuto) {
// No-Op // No-Op
} else if ( } else if (
child->marginLeadingValue(crossAxis).unit == YGUnitAuto) { child->marginLeadingValue(crossAxis).unit == YGUnitAuto) {
leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim); leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim);
} else if (alignItem == YGAlignFlexStart) { } else if (alignItem == YGAlignFlexStart) {
// No-Op // No-Op
} else if (alignItem == YGAlignCenter) { } else if (alignItem == YGAlignCenter) {
@@ -3274,7 +3268,7 @@ static void YGNodelayoutImpl(
const float appliedCrossGap = lineCount != 0 ? crossAxisGap : 0.0f; const float appliedCrossGap = lineCount != 0 ? crossAxisGap : 0.0f;
totalLineCrossDim += collectedFlexItemsValues.crossDim + appliedCrossGap; totalLineCrossDim += collectedFlexItemsValues.crossDim + appliedCrossGap;
maxLineMainDim = maxLineMainDim =
yoga::maxOrDefined(maxLineMainDim, collectedFlexItemsValues.mainDim); YGFloatMax(maxLineMainDim, collectedFlexItemsValues.mainDim);
} }
// STEP 8: MULTI-LINE CONTENT ALIGNMENT // STEP 8: MULTI-LINE CONTENT ALIGNMENT
@@ -3337,7 +3331,7 @@ static void YGNodelayoutImpl(
break; break;
} }
if (YGNodeIsLayoutDimDefined(child, crossAxis)) { if (YGNodeIsLayoutDimDefined(child, crossAxis)) {
lineHeight = yoga::maxOrDefined( lineHeight = YGFloatMax(
lineHeight, lineHeight,
child->getLayout().measuredDimensions[dim[crossAxis]] + child->getLayout().measuredDimensions[dim[crossAxis]] +
child->getMarginForAxis(crossAxis, availableInnerWidth) child->getMarginForAxis(crossAxis, availableInnerWidth)
@@ -3357,10 +3351,10 @@ static void YGNodelayoutImpl(
.unwrap() - .unwrap() -
ascent; ascent;
maxAscentForCurrentLine = maxAscentForCurrentLine =
yoga::maxOrDefined(maxAscentForCurrentLine, ascent); YGFloatMax(maxAscentForCurrentLine, ascent);
maxDescentForCurrentLine = maxDescentForCurrentLine =
yoga::maxOrDefined(maxDescentForCurrentLine, descent); YGFloatMax(maxDescentForCurrentLine, descent);
lineHeight = yoga::maxOrDefined( lineHeight = YGFloatMax(
lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine); lineHeight, maxAscentForCurrentLine + maxDescentForCurrentLine);
} }
} }
@@ -3428,11 +3422,11 @@ static void YGNodelayoutImpl(
.unwrap()) .unwrap())
: lineHeight; : lineHeight;
if (!(yoga::inexactEquals( if (!(YGFloatsEqual(
childWidth, childWidth,
child->getLayout() child->getLayout()
.measuredDimensions[YGDimensionWidth]) && .measuredDimensions[YGDimensionWidth]) &&
yoga::inexactEquals( YGFloatsEqual(
childHeight, childHeight,
child->getLayout() child->getLayout()
.measuredDimensions[YGDimensionHeight]))) { .measuredDimensions[YGDimensionHeight]))) {
@@ -3516,8 +3510,8 @@ static void YGNodelayoutImpl(
measureModeMainDim == YGMeasureModeAtMost && measureModeMainDim == YGMeasureModeAtMost &&
node->getStyle().overflow() == YGOverflowScroll) { node->getStyle().overflow() == YGOverflowScroll) {
node->setLayoutMeasuredDimension( node->setLayoutMeasuredDimension(
yoga::maxOrDefined( YGFloatMax(
yoga::minOrDefined( YGFloatMin(
availableInnerMainDim + paddingAndBorderAxisMain, availableInnerMainDim + paddingAndBorderAxisMain,
YGNodeBoundAxisWithinMinAndMax( YGNodeBoundAxisWithinMinAndMax(
node, node,
@@ -3547,8 +3541,8 @@ static void YGNodelayoutImpl(
measureModeCrossDim == YGMeasureModeAtMost && measureModeCrossDim == YGMeasureModeAtMost &&
node->getStyle().overflow() == YGOverflowScroll) { node->getStyle().overflow() == YGOverflowScroll) {
node->setLayoutMeasuredDimension( node->setLayoutMeasuredDimension(
yoga::maxOrDefined( YGFloatMax(
yoga::minOrDefined( YGFloatMin(
availableInnerCrossDim + paddingAndBorderAxisCross, availableInnerCrossDim + paddingAndBorderAxisCross,
YGNodeBoundAxisWithinMinAndMax( YGNodeBoundAxisWithinMinAndMax(
node, node,
@@ -3665,7 +3659,7 @@ static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize(
float size, float size,
float lastComputedSize) { float lastComputedSize) {
return sizeMode == YGMeasureModeExactly && return sizeMode == YGMeasureModeExactly &&
yoga::inexactEquals(size, lastComputedSize); YGFloatsEqual(size, lastComputedSize);
} }
static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits( static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits(
@@ -3675,7 +3669,7 @@ static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits(
float lastComputedSize) { float lastComputedSize) {
return sizeMode == YGMeasureModeAtMost && return sizeMode == YGMeasureModeAtMost &&
lastSizeMode == YGMeasureModeUndefined && lastSizeMode == YGMeasureModeUndefined &&
(size >= lastComputedSize || yoga::inexactEquals(size, lastComputedSize)); (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize));
} }
static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
@@ -3688,7 +3682,7 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) && sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) &&
!YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) && !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) &&
lastSize > size && lastSize > size &&
(lastComputedSize <= size || yoga::inexactEquals(size, lastComputedSize)); (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize));
} }
YOGA_EXPORT float YGRoundValueToPixelGrid( YOGA_EXPORT float YGRoundValueToPixelGrid(
@@ -3718,10 +3712,10 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(
// - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3 // - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3
++fractial; ++fractial;
} }
if (yoga::inexactEquals(fractial, 0)) { if (YGDoubleEqual(fractial, 0)) {
// First we check if the value is already rounded // First we check if the value is already rounded
scaledValue = scaledValue - fractial; scaledValue = scaledValue - fractial;
} else if (yoga::inexactEquals(fractial, 1.0)) { } else if (YGDoubleEqual(fractial, 1.0)) {
scaledValue = scaledValue - fractial + 1.0; scaledValue = scaledValue - fractial + 1.0;
} else if (forceCeil) { } else if (forceCeil) {
// Next we check if we need to use forced rounding // Next we check if we need to use forced rounding
@@ -3732,7 +3726,7 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(
// Finally we just round the value // Finally we just round the value
scaledValue = scaledValue - fractial + scaledValue = scaledValue - fractial +
(!YGDoubleIsUndefined(fractial) && (!YGDoubleIsUndefined(fractial) &&
(fractial > 0.5 || yoga::inexactEquals(fractial, 0.5)) (fractial > 0.5 || YGDoubleEqual(fractial, 0.5))
? 1.0 ? 1.0
: 0.0); : 0.0);
} }
@@ -3780,9 +3774,9 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement(
: lastHeight; : lastHeight;
const bool hasSameWidthSpec = lastWidthMode == widthMode && const bool hasSameWidthSpec = lastWidthMode == widthMode &&
yoga::inexactEquals(effectiveLastWidth, effectiveWidth); YGFloatsEqual(effectiveLastWidth, effectiveWidth);
const bool hasSameHeightSpec = lastHeightMode == heightMode && const bool hasSameHeightSpec = lastHeightMode == heightMode &&
yoga::inexactEquals(effectiveLastHeight, effectiveHeight); YGFloatsEqual(effectiveLastHeight, effectiveHeight);
const bool widthIsCompatible = const bool widthIsCompatible =
hasSameWidthSpec || hasSameWidthSpec ||
@@ -3914,19 +3908,17 @@ bool YGLayoutNodeInternal(
} }
} }
} else if (performLayout) { } else if (performLayout) {
if (yoga::inexactEquals( if (YGFloatsEqual(layout->cachedLayout.availableWidth, availableWidth) &&
layout->cachedLayout.availableWidth, availableWidth) && YGFloatsEqual(layout->cachedLayout.availableHeight, availableHeight) &&
yoga::inexactEquals(
layout->cachedLayout.availableHeight, availableHeight) &&
layout->cachedLayout.widthMeasureMode == widthMeasureMode && layout->cachedLayout.widthMeasureMode == widthMeasureMode &&
layout->cachedLayout.heightMeasureMode == heightMeasureMode) { layout->cachedLayout.heightMeasureMode == heightMeasureMode) {
cachedResults = &layout->cachedLayout; cachedResults = &layout->cachedLayout;
} }
} else { } else {
for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) {
if (yoga::inexactEquals( if (YGFloatsEqual(
layout->cachedMeasurements[i].availableWidth, availableWidth) && layout->cachedMeasurements[i].availableWidth, availableWidth) &&
yoga::inexactEquals( YGFloatsEqual(
layout->cachedMeasurements[i].availableHeight, availableHeight) && layout->cachedMeasurements[i].availableHeight, availableHeight) &&
layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode &&
layout->cachedMeasurements[i].heightMeasureMode == 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 // 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 // to whole number we want to check both floor and ceil numbers
const bool hasFractionalWidth = const bool hasFractionalWidth =
!yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 0) &&
!yoga::inexactEquals(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0);
const bool hasFractionalHeight = const bool hasFractionalHeight =
!yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 0) &&
!yoga::inexactEquals(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0); !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0);
node->setLayoutDimension( node->setLayoutDimension(
YGRoundValueToPixelGrid( YGRoundValueToPixelGrid(
@@ -4207,15 +4199,15 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
const auto& maxDimensions = node->getStyle().maxDimensions(); const auto& maxDimensions = node->getStyle().maxDimensions();
if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) {
width = width =
(yoga::resolveValue( (YGResolveValue(
node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) +
node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) node->getMarginForAxis(YGFlexDirectionRow, ownerWidth))
.unwrap(); .unwrap();
widthMeasureMode = YGMeasureModeExactly; widthMeasureMode = YGMeasureModeExactly;
} else if (!yoga::resolveValue(maxDimensions[YGDimensionWidth], ownerWidth) } else if (!YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth)
.isUndefined()) { .isUndefined()) {
width = yoga::resolveValue(maxDimensions[YGDimensionWidth], ownerWidth) width =
.unwrap(); YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap();
widthMeasureMode = YGMeasureModeAtMost; widthMeasureMode = YGMeasureModeAtMost;
} else { } else {
width = ownerWidth; width = ownerWidth;
@@ -4226,16 +4218,16 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
float height = YGUndefined; float height = YGUndefined;
YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined;
if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) {
height = (yoga::resolveValue( height = (YGResolveValue(
node->getResolvedDimension(dim[YGFlexDirectionColumn]), node->getResolvedDimension(dim[YGFlexDirectionColumn]),
ownerHeight) + ownerHeight) +
node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth))
.unwrap(); .unwrap();
heightMeasureMode = YGMeasureModeExactly; heightMeasureMode = YGMeasureModeExactly;
} else if (!yoga::resolveValue(maxDimensions[YGDimensionHeight], ownerHeight) } else if (!YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight)
.isUndefined()) { .isUndefined()) {
height = yoga::resolveValue(maxDimensions[YGDimensionHeight], ownerHeight) height =
.unwrap(); YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight).unwrap();
heightMeasureMode = YGMeasureModeAtMost; heightMeasureMode = YGMeasureModeAtMost;
} else { } else {
height = ownerHeight; 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) { void YGAssert(const bool condition, const char* message) {
if (!condition) { if (!condition) {
yoga::log( yoga::log(
@@ -4312,7 +4296,7 @@ void YGAssert(const bool condition, const char* message) {
nullptr, nullptr,
"%s\n", "%s\n",
message); message);
fatalWithMessage(message); throwLogicalErrorWithMessage(message);
} }
} }
@@ -4327,7 +4311,7 @@ void YGAssertWithNode(
nullptr, nullptr,
"%s\n", "%s\n",
message); message);
fatalWithMessage(message); throwLogicalErrorWithMessage(message);
} }
} }
@@ -4342,7 +4326,7 @@ void YGAssertWithConfig(
nullptr, nullptr,
"%s\n", "%s\n",
message); message);
fatalWithMessage(message); throwLogicalErrorWithMessage(message);
} }
} }

View File

@@ -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 <vector>
#include <yoga/node/Node.h>
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<yoga::Node*> 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

View File

@@ -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 <yoga/Yoga.h>
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

View File

@@ -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 <yoga/Yoga.h>
#include <yoga/YGFloatOptional.h>
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

View File

@@ -12,8 +12,8 @@
#include <yoga/YGEnums.h> #include <yoga/YGEnums.h>
#include <yoga/debug/NodeToString.h> #include <yoga/debug/NodeToString.h>
#include <yoga/numeric/Comparison.h>
#include <yoga/Yoga-internal.h> #include <yoga/Yoga-internal.h>
#include <yoga/Utils.h>
namespace facebook::yoga { namespace facebook::yoga {
@@ -24,9 +24,8 @@ static void indent(std::string& base, uint32_t level) {
} }
static bool areFourValuesEqual(const Style::Edges& four) { static bool areFourValuesEqual(const Style::Edges& four) {
return yoga::inexactEquals(four[0], four[1]) && return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) &&
yoga::inexactEquals(four[0], four[2]) && YGValueEqual(four[0], four[3]);
yoga::inexactEquals(four[0], four[3]);
} }
static void appendFormattedString(std::string& str, const char* fmt, ...) { static void appendFormattedString(std::string& str, const char* fmt, ...) {
@@ -81,7 +80,7 @@ static void appendNumberIfNotZero(
const YGValue number) { const YGValue number) {
if (number.unit == YGUnitAuto) { if (number.unit == YGUnitAuto) {
base.append(str + ": auto; "); base.append(str + ": auto; ");
} else if (!yoga::inexactEquals(number.value, 0)) { } else if (!YGFloatsEqual(number.value, 0)) {
appendNumberIfNotUndefined(base, str, number); appendNumberIfNotUndefined(base, str, number);
} }
} }

View File

@@ -6,16 +6,16 @@
*/ */
#include <yoga/node/LayoutResults.h> #include <yoga/node/LayoutResults.h>
#include <yoga/numeric/Comparison.h> #include <yoga/Utils.h>
namespace facebook::yoga { namespace facebook::yoga {
bool LayoutResults::operator==(LayoutResults layout) const { bool LayoutResults::operator==(LayoutResults layout) const {
bool isEqual = yoga::inexactEquals(position, layout.position) && bool isEqual = YGFloatArrayEqual(position, layout.position) &&
yoga::inexactEquals(dimensions, layout.dimensions) && YGFloatArrayEqual(dimensions, layout.dimensions) &&
yoga::inexactEquals(margin, layout.margin) && YGFloatArrayEqual(margin, layout.margin) &&
yoga::inexactEquals(border, layout.border) && YGFloatArrayEqual(border, layout.border) &&
yoga::inexactEquals(padding, layout.padding) && YGFloatArrayEqual(padding, layout.padding) &&
direction() == layout.direction() && direction() == layout.direction() &&
hadOverflow() == layout.hadOverflow() && hadOverflow() == layout.hadOverflow() &&
lastOwnerDirection == layout.lastOwnerDirection && lastOwnerDirection == layout.lastOwnerDirection &&

View File

@@ -5,13 +5,10 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
#include <yoga/node/Node.h>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <yoga/Utils.h>
#include <yoga/algorithm/FlexDirection.h>
#include <yoga/algorithm/ResolveValue.h>
#include <yoga/node/Node.h>
#include <yoga/numeric/Comparison.h>
namespace facebook::yoga { namespace facebook::yoga {
@@ -113,7 +110,7 @@ CompactValue Node::computeColumnGap(
YGFloatOptional Node::getLeadingPosition( YGFloatOptional Node::getLeadingPosition(
const YGFlexDirection axis, const YGFlexDirection axis,
const float axisSize) const { const float axisSize) const {
auto leadingPosition = isRow(axis) auto leadingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.position(), style_.position(),
YGEdgeStart, YGEdgeStart,
@@ -121,13 +118,13 @@ YGFloatOptional Node::getLeadingPosition(
CompactValue::ofZero()) CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
style_.position(), leading[axis], CompactValue::ofZero()); style_.position(), leading[axis], CompactValue::ofZero());
return yoga::resolveValue(leadingPosition, axisSize); return YGResolveValue(leadingPosition, axisSize);
} }
YGFloatOptional Node::getTrailingPosition( YGFloatOptional Node::getTrailingPosition(
const YGFlexDirection axis, const YGFlexDirection axis,
const float axisSize) const { const float axisSize) const {
auto trailingPosition = isRow(axis) auto trailingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.position(), style_.position(),
YGEdgeEnd, YGEdgeEnd,
@@ -135,11 +132,11 @@ YGFloatOptional Node::getTrailingPosition(
CompactValue::ofZero()) CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
style_.position(), trailing[axis], CompactValue::ofZero()); style_.position(), trailing[axis], CompactValue::ofZero());
return yoga::resolveValue(trailingPosition, axisSize); return YGResolveValue(trailingPosition, axisSize);
} }
bool Node::isLeadingPositionDefined(const YGFlexDirection axis) const { bool Node::isLeadingPositionDefined(const YGFlexDirection axis) const {
auto leadingPosition = isRow(axis) auto leadingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.position(), style_.position(),
YGEdgeStart, YGEdgeStart,
@@ -151,7 +148,7 @@ bool Node::isLeadingPositionDefined(const YGFlexDirection axis) const {
} }
bool Node::isTrailingPosDefined(const YGFlexDirection axis) const { bool Node::isTrailingPosDefined(const YGFlexDirection axis) const {
auto trailingPosition = isRow(axis) auto trailingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.position(), style_.position(),
YGEdgeEnd, YGEdgeEnd,
@@ -165,26 +162,23 @@ bool Node::isTrailingPosDefined(const YGFlexDirection axis) const {
YGFloatOptional Node::getLeadingMargin( YGFloatOptional Node::getLeadingMargin(
const YGFlexDirection axis, const YGFlexDirection axis,
const float widthSize) const { const float widthSize) const {
auto leadingMargin = isRow(axis) auto leadingMargin = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero()) style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
style_.margin(), leading[axis], CompactValue::ofZero()); style_.margin(), leading[axis], CompactValue::ofZero());
return leadingMargin.isAuto() ? YGFloatOptional{0} return YGResolveValueMargin(leadingMargin, widthSize);
: yoga::resolveValue(leadingMargin, widthSize);
} }
YGFloatOptional Node::getTrailingMargin( YGFloatOptional Node::getTrailingMargin(
const YGFlexDirection axis, const YGFlexDirection axis,
const float widthSize) const { const float widthSize) const {
auto trailingMargin = isRow(axis) auto trailingMargin = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
style_.margin(), trailing[axis], CompactValue::ofZero()); style_.margin(), trailing[axis], CompactValue::ofZero());
return trailingMargin.isAuto() return YGResolveValueMargin(trailingMargin, widthSize);
? YGFloatOptional{0}
: yoga::resolveValue(trailingMargin, widthSize);
} }
YGFloatOptional Node::getMarginForAxis( YGFloatOptional Node::getMarginForAxis(
@@ -196,10 +190,10 @@ YGFloatOptional Node::getMarginForAxis(
YGFloatOptional Node::getGapForAxis( YGFloatOptional Node::getGapForAxis(
const YGFlexDirection axis, const YGFlexDirection axis,
const float widthSize) const { const float widthSize) const {
auto gap = isRow(axis) auto gap = YGFlexDirectionIsRow(axis)
? computeColumnGap(style_.gap(), CompactValue::ofZero()) ? computeColumnGap(style_.gap(), CompactValue::ofZero())
: computeRowGap(style_.gap(), CompactValue::ofZero()); : computeRowGap(style_.gap(), CompactValue::ofZero());
return yoga::resolveValue(gap, widthSize); return YGResolveValue(gap, widthSize);
} }
YGSize Node::measure( YGSize Node::measure(
@@ -376,9 +370,9 @@ void Node::setPosition(
const YGDirection directionRespectingRoot = const YGDirection directionRespectingRoot =
owner_ != nullptr ? direction : YGDirectionLTR; owner_ != nullptr ? direction : YGDirectionLTR;
const YGFlexDirection mainAxis = const YGFlexDirection mainAxis =
yoga::resolveDirection(style_.flexDirection(), directionRespectingRoot); YGResolveFlexDirection(style_.flexDirection(), directionRespectingRoot);
const YGFlexDirection crossAxis = const YGFlexDirection crossAxis =
yoga::resolveCrossDirection(mainAxis, directionRespectingRoot); YGFlexDirectionCross(mainAxis, directionRespectingRoot);
// Here we should check for `YGPositionTypeStatic` and in this case zero inset // Here we should check for `YGPositionTypeStatic` and in this case zero inset
// properties (left, right, top, bottom, begin, end). // properties (left, right, top, bottom, begin, end).
@@ -405,7 +399,8 @@ void Node::setPosition(
} }
YGValue Node::marginLeadingValue(const YGFlexDirection axis) const { 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]; return style_.margin()[YGEdgeStart];
} else { } else {
return style_.margin()[leading[axis]]; return style_.margin()[leading[axis]];
@@ -413,7 +408,7 @@ YGValue Node::marginLeadingValue(const YGFlexDirection axis) const {
} }
YGValue Node::marginTrailingValue(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]; return style_.margin()[YGEdgeEnd];
} else { } else {
return style_.margin()[trailing[axis]]; return style_.margin()[trailing[axis]];
@@ -436,8 +431,7 @@ void Node::resolveDimension() {
const Style& style = getStyle(); const Style& style = getStyle();
for (auto dim : {YGDimensionWidth, YGDimensionHeight}) { for (auto dim : {YGDimensionWidth, YGDimensionHeight}) {
if (!style.maxDimensions()[dim].isUndefined() && if (!style.maxDimensions()[dim].isUndefined() &&
yoga::inexactEquals( YGValueEqual(style.maxDimensions()[dim], style.minDimensions()[dim])) {
style.maxDimensions()[dim], style.minDimensions()[dim])) {
resolvedDimensions_[dim] = style.maxDimensions()[dim]; resolvedDimensions_[dim] = style.maxDimensions()[dim];
} else { } else {
resolvedDimensions_[dim] = style.dimensions()[dim]; resolvedDimensions_[dim] = style.dimensions()[dim];
@@ -517,7 +511,7 @@ bool Node::isNodeFlexible() {
} }
float Node::getLeadingBorder(const YGFlexDirection axis) const { float Node::getLeadingBorder(const YGFlexDirection axis) const {
YGValue leadingBorder = isRow(axis) YGValue leadingBorder = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero()) style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
@@ -526,7 +520,7 @@ float Node::getLeadingBorder(const YGFlexDirection axis) const {
} }
float Node::getTrailingBorder(const YGFlexDirection axis) const { float Node::getTrailingBorder(const YGFlexDirection axis) const {
YGValue trailingBorder = isRow(axis) YGValue trailingBorder = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
@@ -537,7 +531,7 @@ float Node::getTrailingBorder(const YGFlexDirection axis) const {
YGFloatOptional Node::getLeadingPadding( YGFloatOptional Node::getLeadingPadding(
const YGFlexDirection axis, const YGFlexDirection axis,
const float widthSize) const { const float widthSize) const {
auto leadingPadding = isRow(axis) auto leadingPadding = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.padding(), style_.padding(),
YGEdgeStart, YGEdgeStart,
@@ -545,20 +539,20 @@ YGFloatOptional Node::getLeadingPadding(
CompactValue::ofZero()) CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
style_.padding(), leading[axis], CompactValue::ofZero()); style_.padding(), leading[axis], CompactValue::ofZero());
return yoga::maxOrDefined( return YGFloatOptionalMax(
yoga::resolveValue(leadingPadding, widthSize), YGFloatOptional(0.0f)); YGResolveValue(leadingPadding, widthSize), YGFloatOptional(0.0f));
} }
YGFloatOptional Node::getTrailingPadding( YGFloatOptional Node::getTrailingPadding(
const YGFlexDirection axis, const YGFlexDirection axis,
const float widthSize) const { const float widthSize) const {
auto trailingPadding = isRow(axis) auto trailingPadding = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(
style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero()) style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
: computeEdgeValueForColumn( : computeEdgeValueForColumn(
style_.padding(), trailing[axis], CompactValue::ofZero()); style_.padding(), trailing[axis], CompactValue::ofZero());
return yoga::maxOrDefined( return YGFloatOptionalMax(
yoga::resolveValue(trailingPadding, widthSize), YGFloatOptional(0.0f)); YGResolveValue(trailingPadding, widthSize), YGFloatOptional(0.0f));
} }
YGFloatOptional Node::getLeadingPaddingAndBorder( YGFloatOptional Node::getLeadingPaddingAndBorder(

View File

@@ -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 <array>
#include <yoga/Yoga.h>
#include <yoga/YGFloatOptional.h>
#include <yoga/style/CompactValue.h>
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 <std::size_t Size, typename ElementT>
bool inexactEquals(
const std::array<ElementT, Size>& val1,
const std::array<ElementT, Size>& 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

View File

@@ -6,7 +6,7 @@
*/ */
#include <yoga/style/Style.h> #include <yoga/style/Style.h>
#include <yoga/numeric/Comparison.h> #include <yoga/Utils.h>
namespace facebook::yoga { namespace facebook::yoga {
@@ -21,7 +21,7 @@ bool operator==(const Style& lhs, const Style& rhs) {
lhs.positionType() == rhs.positionType() && lhs.positionType() == rhs.positionType() &&
lhs.flexWrap() == rhs.flexWrap() && lhs.overflow() == rhs.overflow() && lhs.flexWrap() == rhs.flexWrap() && lhs.overflow() == rhs.overflow() &&
lhs.display() == rhs.display() && lhs.display() == rhs.display() &&
yoga::inexactEquals(lhs.flexBasis(), rhs.flexBasis()) && YGValueEqual(lhs.flexBasis(), rhs.flexBasis()) &&
lhs.margin() == rhs.margin() && lhs.position() == rhs.position() && lhs.margin() == rhs.margin() && lhs.position() == rhs.position() &&
lhs.padding() == rhs.padding() && lhs.border() == rhs.border() && lhs.padding() == rhs.padding() && lhs.border() == rhs.border() &&
lhs.gap() == rhs.gap() && lhs.dimensions() == rhs.dimensions() && lhs.gap() == rhs.gap() && lhs.dimensions() == rhs.dimensions() &&