From b7ad6ed815b0c3e2c0b46f585e37900710fe304b Mon Sep 17 00:00:00 2001 From: Atul R Date: Sun, 7 Mar 2021 15:11:54 +0100 Subject: [PATCH] bump yoga native --- src/cpp/include/deps/yoga/BitUtils.h | 66 + src/cpp/include/deps/yoga/Bitfield.h | 144 - src/cpp/include/deps/yoga/CompactValue.h | 24 +- src/cpp/include/deps/yoga/Utils.cpp | 21 +- src/cpp/include/deps/yoga/Utils.h | 52 +- src/cpp/include/deps/yoga/YGConfig.cpp | 21 +- src/cpp/include/deps/yoga/YGConfig.h | 28 +- src/cpp/include/deps/yoga/YGEnums.cpp | 2 + src/cpp/include/deps/yoga/YGEnums.h | 109 +- src/cpp/include/deps/yoga/YGFloatOptional.h | 19 +- src/cpp/include/deps/yoga/YGLayout.cpp | 4 +- src/cpp/include/deps/yoga/YGLayout.h | 66 +- src/cpp/include/deps/yoga/YGNode.cpp | 223 +- src/cpp/include/deps/yoga/YGNode.h | 121 +- src/cpp/include/deps/yoga/YGNodePrint.cpp | 134 +- src/cpp/include/deps/yoga/YGNodePrint.h | 11 +- src/cpp/include/deps/yoga/YGStyle.cpp | 12 +- src/cpp/include/deps/yoga/YGStyle.h | 151 +- src/cpp/include/deps/yoga/YGValue.h | 20 +- src/cpp/include/deps/yoga/Yoga-internal.h | 42 +- src/cpp/include/deps/yoga/Yoga.cpp | 2485 ++++++++++------- src/cpp/include/deps/yoga/Yoga.h | 171 +- src/cpp/include/deps/yoga/event/event.cpp | 11 +- src/cpp/include/deps/yoga/event/event.h | 15 +- .../deps/yoga/internal/experiments-inl.h | 16 +- .../deps/yoga/internal/experiments.cpp | 9 +- .../include/deps/yoga/internal/experiments.h | 6 +- src/cpp/include/deps/yoga/log.cpp | 48 +- src/cpp/include/deps/yoga/log.h | 22 +- 29 files changed, 2437 insertions(+), 1616 deletions(-) create mode 100644 src/cpp/include/deps/yoga/BitUtils.h delete mode 100644 src/cpp/include/deps/yoga/Bitfield.h diff --git a/src/cpp/include/deps/yoga/BitUtils.h b/src/cpp/include/deps/yoga/BitUtils.h new file mode 100644 index 000000000..1c32e9ecc --- /dev/null +++ b/src/cpp/include/deps/yoga/BitUtils.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) Facebook, Inc. and its 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 "YGEnums.h" + +namespace facebook { +namespace yoga { + +namespace detail { + +constexpr size_t log2ceilFn(size_t n) { + return n < 1 ? 0 : (1 + log2ceilFn(n / 2)); +} + +constexpr int mask(size_t bitWidth, size_t index) { + return ((1 << bitWidth) - 1) << index; +} + +// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL +template +constexpr size_t bitWidthFn() { + static_assert( + enums::count() > 0, "Enums must have at least one entries"); + return log2ceilFn(enums::count() - 1); +} + +template +constexpr Enum getEnumData(int flags, size_t index) { + return static_cast((flags & mask(bitWidthFn(), index)) >> index); +} + +template +void setEnumData(uint32_t& flags, size_t index, int newValue) { + flags = (flags & ~mask(bitWidthFn(), index)) | + ((newValue << index) & (mask(bitWidthFn(), index))); +} + +template +void setEnumData(uint8_t& flags, size_t index, int newValue) { + flags = (flags & ~mask(bitWidthFn(), index)) | + ((newValue << index) & (mask(bitWidthFn(), index))); +} + +constexpr bool getBooleanData(int flags, size_t index) { + return (flags >> index) & 1; +} + +inline void setBooleanData(uint8_t& flags, size_t index, bool value) { + if (value) { + flags |= 1 << index; + } else { + flags &= ~(1 << index); + } +} + +} // namespace detail +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/Bitfield.h b/src/cpp/include/deps/yoga/Bitfield.h deleted file mode 100644 index f7fe5d736..000000000 --- a/src/cpp/include/deps/yoga/Bitfield.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its 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 { -namespace yoga { - -namespace detail { - -constexpr size_t log2ceil(size_t n) { - return n < 1 ? 0 : (1 + log2ceil(n / 2)); -} - -// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL -template -constexpr size_t bitWidth() { - static_assert(enums::count() > 0, - "Enums must have at least one entries"); - return log2ceil(enums::count() - 1); -} - -// Number of bits needed for a boolean -template <> -constexpr size_t bitWidth() { - return 1; -} - -template -struct BitTraits {}; - -template -struct BitTraits { - // Base cases - static constexpr size_t width(size_t) { return 0; } - static constexpr size_t shift(size_t) { return 0; } -}; - -template -struct BitTraits { - using Rest = BitTraits; - - static constexpr size_t width(size_t idx) { - return idx == 0 ? bitWidth() : Rest::width(idx - 1); - } - - static constexpr size_t shift(size_t idx) { - return idx == 0 ? Rest::width(0) + Rest::shift(0) : Rest::shift(idx - 1); - } - - static constexpr U mask(size_t idx) { - return ((U{1} << width(idx)) - 1) << shift(idx); - } -}; - -template -struct IndexedType { - using Type = typename IndexedType::Type; -}; - -template -struct IndexedType<0, T, Ts...> { - using Type = T; -}; - -} // namespace detail - -template -class Bitfield { - static_assert(std::is_integral::value, - "Bitfield needs an integral storage type"); - static_assert(std::is_unsigned::value, - "Bitfield needs an unsigned storage type"); - static_assert(sizeof...(Fields) > 0, "Bitfield needs at least one member"); - - using BitTraits = detail::BitTraits; - -#if !defined(_MSC_VER) || _MSC_VER > 1914 - static_assert(BitTraits::shift(0) + BitTraits::width(0) <= - std::numeric_limits::digits, - "Specified storage type is too narrow to hold all types"); -#endif - - template - using TypeAt = typename detail::IndexedType::Type; - - template - static constexpr Storage initStorage(Value value, Values... values) { - return ((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx)) | - initStorage(values...); - } - - template - static constexpr Storage initStorage() { - return Storage{0}; - } - - Storage storage_ = 0; - - public: - template - class Ref { - Bitfield& bitfield_; - - public: - Ref(Bitfield& bitfield) : bitfield_(bitfield) {} - Ref& operator=(TypeAt value) { - bitfield_.storage_ = - (bitfield_.storage_ & ~BitTraits::mask(Idx)) | - ((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx)); - return *this; - } - operator TypeAt() const { - return const_cast(bitfield_).at(); - } - }; - - constexpr Bitfield() = default; - constexpr Bitfield(Fields... values) : storage_{initStorage<0>(values...)} {} - - template - constexpr TypeAt at() const { - return static_cast>((storage_ & BitTraits::mask(Idx)) >> - BitTraits::shift(Idx)); - } - - template - Ref at() { - return {*this}; - } -}; - -} // namespace yoga -} // namespace facebook diff --git a/src/cpp/include/deps/yoga/CompactValue.h b/src/cpp/include/deps/yoga/CompactValue.h index e0879398b..f398668e2 100644 --- a/src/cpp/include/deps/yoga/CompactValue.h +++ b/src/cpp/include/deps/yoga/CompactValue.h @@ -7,13 +7,12 @@ #pragma once +#include "YGValue.h" +#include "YGMacros.h" #include #include #include -#include "YGMacros.h" -#include "YGValue.h" - static_assert( std::numeric_limits::is_iec559, "facebook::yoga::detail::CompactValue only works with IEEE754 floats"); @@ -44,7 +43,7 @@ namespace detail { class YOGA_EXPORT CompactValue { friend constexpr bool operator==(CompactValue, CompactValue) noexcept; - public: +public: static constexpr auto LOWER_BOUND = 1.08420217e-19f; static constexpr auto UPPER_BOUND_POINT = 36893485948395847680.0f; static constexpr auto UPPER_BOUND_PERCENT = 18446742974197923840.0f; @@ -126,18 +125,19 @@ class YOGA_EXPORT CompactValue { data.repr &= ~PERCENT_BIT; data.repr += BIAS; - return YGValue{data.value, - payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint}; + return YGValue{ + data.value, payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint}; } bool isUndefined() const noexcept { - return (payload_.repr != AUTO_BITS && payload_.repr != ZERO_BITS_POINT && - payload_.repr != ZERO_BITS_PERCENT && std::isnan(payload_.value)); + return ( + payload_.repr != AUTO_BITS && payload_.repr != ZERO_BITS_POINT && + payload_.repr != ZERO_BITS_PERCENT && std::isnan(payload_.value)); } bool isAuto() const noexcept { return payload_.repr == AUTO_BITS; } - private: +private: union Payload { float value; uint32_t repr; @@ -179,6 +179,6 @@ constexpr bool operator!=(CompactValue a, CompactValue b) noexcept { return !(a == b); } -} // namespace detail -} // namespace yoga -} // namespace facebook +} // namespace detail +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/Utils.cpp b/src/cpp/include/deps/yoga/Utils.cpp index 7c1ef8462..edb198d25 100644 --- a/src/cpp/include/deps/yoga/Utils.cpp +++ b/src/cpp/include/deps/yoga/Utils.cpp @@ -6,14 +6,16 @@ */ #include "Utils.h" +#include using namespace facebook; -YGFlexDirection YGFlexDirectionCross(const YGFlexDirection flexDirection, - const YGDirection direction) { +YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction) { return YGFlexDirectionIsColumn(flexDirection) - ? YGResolveFlexDirection(YGFlexDirectionRow, direction) - : YGFlexDirectionColumn; + ? YGResolveFlexDirection(YGFlexDirectionRow, direction) + : YGFlexDirectionColumn; } float YGFloatMax(const float a, const float b) { @@ -51,6 +53,13 @@ bool YGFloatsEqual(const float a, const float b) { 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.0001f; + } + return yoga::isUndefined(a) && yoga::isUndefined(b); +} + float YGFloatSanitize(const float val) { return yoga::isUndefined(val) ? 0 : val; } @@ -64,3 +73,7 @@ YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) { } return op1.isUndefined() ? op2 : op1; } + +void throwLogicalErrorWithMessage(const char* message) { + throw std::logic_error(message); +} diff --git a/src/cpp/include/deps/yoga/Utils.h b/src/cpp/include/deps/yoga/Utils.h index 47ae49c84..57e1d45d9 100644 --- a/src/cpp/include/deps/yoga/Utils.h +++ b/src/cpp/include/deps/yoga/Utils.h @@ -6,9 +6,9 @@ */ #pragma once -#include "CompactValue.h" #include "YGNode.h" #include "Yoga-internal.h" +#include "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. @@ -54,19 +54,23 @@ struct YGCollectFlexItemsRowValues { }; bool YGValueEqual(const YGValue& a, const YGValue& b); -inline bool YGValueEqual(facebook::yoga::detail::CompactValue a, - facebook::yoga::detail::CompactValue b) { - return YGValueEqual((YGValue)a, (YGValue)b); +inline bool YGValueEqual( + facebook::yoga::detail::CompactValue a, + facebook::yoga::detail::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); +YGFloatOptional YGFloatOptionalMax( + const YGFloatOptional op1, + const YGFloatOptional op2); float YGFloatMin(const float a, const float b); @@ -74,8 +78,9 @@ float YGFloatMin(const float a, const float b); // 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 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]); @@ -86,16 +91,18 @@ bool YGFloatArrayEqual(const std::array& val1, // 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); +YGFlexDirection YGFlexDirectionCross( + const YGFlexDirection flexDirection, + const YGDirection direction); inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) { return flexDirection == YGFlexDirectionRow || - flexDirection == YGFlexDirectionRowReverse; + flexDirection == YGFlexDirectionRowReverse; } -inline YGFloatOptional YGResolveValue(const YGValue value, - const float ownerSize) { +inline YGFloatOptional YGResolveValue( + const YGValue value, + const float ownerSize) { switch (value.unit) { case YGUnitPoint: return YGFloatOptional{value.value}; @@ -106,18 +113,20 @@ inline YGFloatOptional YGResolveValue(const YGValue value, } } -inline YGFloatOptional YGResolveValue(yoga::detail::CompactValue value, - float ownerSize) { - return YGResolveValue((YGValue)value, ownerSize); +inline YGFloatOptional YGResolveValue( + yoga::detail::CompactValue value, + float ownerSize) { + return YGResolveValue((YGValue) value, ownerSize); } inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) { return flexDirection == YGFlexDirectionColumn || - flexDirection == YGFlexDirectionColumnReverse; + flexDirection == YGFlexDirectionColumnReverse; } inline YGFlexDirection YGResolveFlexDirection( - const YGFlexDirection flexDirection, const YGDirection direction) { + const YGFlexDirection flexDirection, + const YGDirection direction) { if (direction == YGDirectionRTL) { if (flexDirection == YGFlexDirectionRow) { return YGFlexDirectionRowReverse; @@ -129,7 +138,10 @@ inline YGFlexDirection YGResolveFlexDirection( return flexDirection; } -inline YGFloatOptional YGResolveValueMargin(yoga::detail::CompactValue value, - const float ownerSize) { +inline YGFloatOptional YGResolveValueMargin( + yoga::detail::CompactValue value, + const float ownerSize) { return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize); } + +void throwLogicalErrorWithMessage(const char* message); diff --git a/src/cpp/include/deps/yoga/YGConfig.cpp b/src/cpp/include/deps/yoga/YGConfig.cpp index 10345e8d7..fb72e80cf 100644 --- a/src/cpp/include/deps/yoga/YGConfig.cpp +++ b/src/cpp/include/deps/yoga/YGConfig.cpp @@ -12,8 +12,13 @@ YGConfig::YGConfig(YGLogger logger) : cloneNodeCallback_{nullptr} { loggerUsesContext_ = false; } -void YGConfig::log(YGConfig* config, YGNode* node, YGLogLevel logLevel, - void* logContext, const char* format, va_list args) { +void YGConfig::log( + YGConfig* config, + YGNode* node, + YGLogLevel logLevel, + void* logContext, + const char* format, + va_list args) { if (loggerUsesContext_) { logger_.withContext(config, node, logLevel, logContext, format, args); } else { @@ -21,14 +26,16 @@ void YGConfig::log(YGConfig* config, YGNode* node, YGLogLevel logLevel, } } -YGNodeRef YGConfig::cloneNode(YGNodeRef node, YGNodeRef owner, int childIndex, - void* cloneContext) { +YGNodeRef YGConfig::cloneNode( + YGNodeRef node, + YGNodeRef owner, + int childIndex, + void* cloneContext) { YGNodeRef clone = nullptr; if (cloneNodeCallback_.noContext != nullptr) { clone = cloneNodeUsesContext_ - ? cloneNodeCallback_.withContext(node, owner, childIndex, - cloneContext) - : cloneNodeCallback_.noContext(node, owner, childIndex); + ? cloneNodeCallback_.withContext(node, owner, childIndex, cloneContext) + : cloneNodeCallback_.noContext(node, owner, childIndex); } if (clone == nullptr) { clone = YGNodeClone(node); diff --git a/src/cpp/include/deps/yoga/YGConfig.h b/src/cpp/include/deps/yoga/YGConfig.h index 656e87045..e87d67586 100644 --- a/src/cpp/include/deps/yoga/YGConfig.h +++ b/src/cpp/include/deps/yoga/YGConfig.h @@ -10,13 +10,20 @@ #include "Yoga.h" struct YOGA_EXPORT YGConfig { - using LogWithContextFn = int (*)(YGConfigRef config, YGNodeRef node, - YGLogLevel level, void* context, - const char* format, va_list args); - using CloneWithContextFn = YGNodeRef (*)(YGNodeRef node, YGNodeRef owner, - int childIndex, void* cloneContext); + using LogWithContextFn = int (*)( + YGConfigRef config, + YGNodeRef node, + YGLogLevel level, + void* context, + const char* format, + va_list args); + using CloneWithContextFn = YGNodeRef (*)( + YGNodeRef node, + YGNodeRef owner, + int childIndex, + void* cloneContext); - private: +private: union { CloneWithContextFn withContext; YGCloneNodeFunc noContext; @@ -28,7 +35,7 @@ struct YOGA_EXPORT YGConfig { bool cloneNodeUsesContext_; bool loggerUsesContext_; - public: +public: bool useWebDefaults = false; bool useLegacyStretchBehaviour = false; bool shouldDiffLayoutWithoutLegacyStretchBehaviour = false; @@ -50,8 +57,11 @@ struct YOGA_EXPORT YGConfig { } void setLogger(std::nullptr_t) { setLogger(YGLogger{nullptr}); } - YGNodeRef cloneNode(YGNodeRef node, YGNodeRef owner, int childIndex, - void* cloneContext); + YGNodeRef cloneNode( + YGNodeRef node, + YGNodeRef owner, + int childIndex, + void* cloneContext); void setCloneNodeCallback(YGCloneNodeFunc cloneNode) { cloneNodeCallback_.noContext = cloneNode; cloneNodeUsesContext_ = false; diff --git a/src/cpp/include/deps/yoga/YGEnums.cpp b/src/cpp/include/deps/yoga/YGEnums.cpp index 3c1301297..c01d3d94b 100644 --- a/src/cpp/include/deps/yoga/YGEnums.cpp +++ b/src/cpp/include/deps/yoga/YGEnums.cpp @@ -179,6 +179,8 @@ const char* YGOverflowToString(const YGOverflow value) { const char* YGPositionTypeToString(const YGPositionType value) { switch (value) { + case YGPositionTypeStatic: + return "static"; case YGPositionTypeRelative: return "relative"; case YGPositionTypeAbsolute: diff --git a/src/cpp/include/deps/yoga/YGEnums.h b/src/cpp/include/deps/yoga/YGEnums.h index c8dabd1ff..3dc458dcb 100644 --- a/src/cpp/include/deps/yoga/YGEnums.h +++ b/src/cpp/include/deps/yoga/YGEnums.h @@ -15,18 +15,18 @@ namespace yoga { namespace enums { template -constexpr int count(); // can't use `= delete` due to a defect in clang < 3.9 +constexpr int count(); // can't use `= delete` due to a defect in clang < 3.9 namespace detail { template constexpr int n() { return sizeof...(xs); } -} // namespace detail +} // namespace detail -} // namespace enums -} // namespace yoga -} // namespace facebook +} // namespace enums +} // namespace yoga +} // namespace facebook #endif #define YG_ENUM_DECL(NAME, ...) \ @@ -54,49 +54,98 @@ constexpr int n() { YG_EXTERN_C_BEGIN -YG_ENUM_SEQ_DECL(YGAlign, YGAlignAuto, YGAlignFlexStart, YGAlignCenter, - YGAlignFlexEnd, YGAlignStretch, YGAlignBaseline, - YGAlignSpaceBetween, YGAlignSpaceAround); +YG_ENUM_SEQ_DECL( + YGAlign, + YGAlignAuto, + YGAlignFlexStart, + YGAlignCenter, + YGAlignFlexEnd, + YGAlignStretch, + YGAlignBaseline, + YGAlignSpaceBetween, + YGAlignSpaceAround); YG_ENUM_SEQ_DECL(YGDimension, YGDimensionWidth, YGDimensionHeight) -YG_ENUM_SEQ_DECL(YGDirection, YGDirectionInherit, YGDirectionLTR, - YGDirectionRTL) +YG_ENUM_SEQ_DECL( + YGDirection, + YGDirectionInherit, + YGDirectionLTR, + YGDirectionRTL) YG_ENUM_SEQ_DECL(YGDisplay, YGDisplayFlex, YGDisplayNone) -YG_ENUM_SEQ_DECL(YGEdge, YGEdgeLeft, YGEdgeTop, YGEdgeRight, YGEdgeBottom, - YGEdgeStart, YGEdgeEnd, YGEdgeHorizontal, YGEdgeVertical, - YGEdgeAll) +YG_ENUM_SEQ_DECL( + YGEdge, + YGEdgeLeft, + YGEdgeTop, + YGEdgeRight, + YGEdgeBottom, + YGEdgeStart, + YGEdgeEnd, + YGEdgeHorizontal, + YGEdgeVertical, + YGEdgeAll) YG_ENUM_SEQ_DECL(YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis) -YG_ENUM_SEQ_DECL(YGFlexDirection, YGFlexDirectionColumn, - YGFlexDirectionColumnReverse, YGFlexDirectionRow, - YGFlexDirectionRowReverse) +YG_ENUM_SEQ_DECL( + YGFlexDirection, + YGFlexDirectionColumn, + YGFlexDirectionColumnReverse, + YGFlexDirectionRow, + YGFlexDirectionRowReverse) -YG_ENUM_SEQ_DECL(YGJustify, YGJustifyFlexStart, YGJustifyCenter, - YGJustifyFlexEnd, YGJustifySpaceBetween, YGJustifySpaceAround, - YGJustifySpaceEvenly) +YG_ENUM_SEQ_DECL( + YGJustify, + YGJustifyFlexStart, + YGJustifyCenter, + YGJustifyFlexEnd, + YGJustifySpaceBetween, + YGJustifySpaceAround, + YGJustifySpaceEvenly) -YG_ENUM_SEQ_DECL(YGLogLevel, YGLogLevelError, YGLogLevelWarn, YGLogLevelInfo, - YGLogLevelDebug, YGLogLevelVerbose, YGLogLevelFatal) +YG_ENUM_SEQ_DECL( + YGLogLevel, + YGLogLevelError, + YGLogLevelWarn, + YGLogLevelInfo, + YGLogLevelDebug, + YGLogLevelVerbose, + YGLogLevelFatal) -YG_ENUM_SEQ_DECL(YGMeasureMode, YGMeasureModeUndefined, YGMeasureModeExactly, - YGMeasureModeAtMost) +YG_ENUM_SEQ_DECL( + YGMeasureMode, + YGMeasureModeUndefined, + YGMeasureModeExactly, + YGMeasureModeAtMost) YG_ENUM_SEQ_DECL(YGNodeType, YGNodeTypeDefault, YGNodeTypeText) -YG_ENUM_SEQ_DECL(YGOverflow, YGOverflowVisible, YGOverflowHidden, - YGOverflowScroll) +YG_ENUM_SEQ_DECL( + YGOverflow, + YGOverflowVisible, + YGOverflowHidden, + YGOverflowScroll) -YG_ENUM_SEQ_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute) +YG_ENUM_SEQ_DECL( + YGPositionType, + YGPositionTypeStatic, + YGPositionTypeRelative, + YGPositionTypeAbsolute) -YG_ENUM_DECL(YGPrintOptions, YGPrintOptionsLayout = 1, YGPrintOptionsStyle = 2, - YGPrintOptionsChildren = 4) +YG_ENUM_DECL( + YGPrintOptions, + YGPrintOptionsLayout = 1, + YGPrintOptionsStyle = 2, + YGPrintOptionsChildren = 4) -YG_ENUM_SEQ_DECL(YGUnit, YGUnitUndefined, YGUnitPoint, YGUnitPercent, - YGUnitAuto) +YG_ENUM_SEQ_DECL( + YGUnit, + YGUnitUndefined, + YGUnitPoint, + YGUnitPercent, + YGUnitAuto) YG_ENUM_SEQ_DECL(YGWrap, YGWrapNoWrap, YGWrapWrap, YGWrapWrapReverse) diff --git a/src/cpp/include/deps/yoga/YGFloatOptional.h b/src/cpp/include/deps/yoga/YGFloatOptional.h index 1ddf1360a..e4cf0284b 100644 --- a/src/cpp/include/deps/yoga/YGFloatOptional.h +++ b/src/cpp/include/deps/yoga/YGFloatOptional.h @@ -9,14 +9,13 @@ #include #include - #include "Yoga-internal.h" struct YGFloatOptional { - private: +private: float value_ = std::numeric_limits::quiet_NaN(); - public: +public: explicit constexpr YGFloatOptional(float value) : value_(value) {} constexpr YGFloatOptional() = default; @@ -30,7 +29,7 @@ struct YGFloatOptional { inline bool operator==(YGFloatOptional lhs, YGFloatOptional rhs) { return lhs.unwrap() == rhs.unwrap() || - (lhs.isUndefined() && rhs.isUndefined()); + (lhs.isUndefined() && rhs.isUndefined()); } inline bool operator!=(YGFloatOptional lhs, YGFloatOptional rhs) { return !(lhs == rhs); @@ -39,10 +38,16 @@ inline bool operator!=(YGFloatOptional lhs, YGFloatOptional rhs) { inline bool operator==(YGFloatOptional lhs, float rhs) { return lhs == YGFloatOptional{rhs}; } -inline bool operator!=(YGFloatOptional lhs, float rhs) { return !(lhs == rhs); } +inline bool operator!=(YGFloatOptional lhs, float rhs) { + return !(lhs == rhs); +} -inline bool operator==(float lhs, YGFloatOptional rhs) { return rhs == lhs; } -inline bool operator!=(float lhs, YGFloatOptional rhs) { return !(lhs == rhs); } +inline bool operator==(float lhs, YGFloatOptional rhs) { + return rhs == lhs; +} +inline bool operator!=(float lhs, YGFloatOptional rhs) { + return !(lhs == rhs); +} inline YGFloatOptional operator+(YGFloatOptional lhs, YGFloatOptional rhs) { return YGFloatOptional{lhs.unwrap() + rhs.unwrap()}; diff --git a/src/cpp/include/deps/yoga/YGLayout.cpp b/src/cpp/include/deps/yoga/YGLayout.cpp index cdce719cb..e43213cdc 100644 --- a/src/cpp/include/deps/yoga/YGLayout.cpp +++ b/src/cpp/include/deps/yoga/YGLayout.cpp @@ -6,14 +6,12 @@ */ #include "YGLayout.h" - #include "Utils.h" using namespace facebook; bool YGLayout::operator==(YGLayout layout) const { - bool isEqual = - YGFloatArrayEqual(position, layout.position) && + bool isEqual = YGFloatArrayEqual(position, layout.position) && YGFloatArrayEqual(dimensions, layout.dimensions) && YGFloatArrayEqual(margin, layout.margin) && YGFloatArrayEqual(border, layout.border) && diff --git a/src/cpp/include/deps/yoga/YGLayout.h b/src/cpp/include/deps/yoga/YGLayout.h index f39baf0ba..b7604d8e2 100644 --- a/src/cpp/include/deps/yoga/YGLayout.h +++ b/src/cpp/include/deps/yoga/YGLayout.h @@ -6,10 +6,12 @@ */ #pragma once -#include "Bitfield.h" +#include "BitUtils.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" +using namespace facebook::yoga; + struct YGLayout { std::array position = {}; std::array dimensions = {{YGUndefined, YGUndefined}}; @@ -17,22 +19,24 @@ struct YGLayout { std::array border = {}; std::array padding = {}; - private: - static constexpr size_t directionIdx = 0; - static constexpr size_t didUseLegacyFlagIdx = 1; - static constexpr size_t doesLegacyStretchFlagAffectsLayoutIdx = 2; - static constexpr size_t hadOverflowIdx = 3; - facebook::yoga::Bitfield flags_ = { - YGDirectionInherit, false, false, false}; +private: + static constexpr size_t directionOffset = 0; + static constexpr size_t didUseLegacyFlagOffset = + directionOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t doesLegacyStretchFlagAffectsLayoutOffset = + didUseLegacyFlagOffset + 1; + static constexpr size_t hadOverflowOffset = + doesLegacyStretchFlagAffectsLayoutOffset + 1; + uint8_t flags = 0; - public: +public: uint32_t computedFlexBasisGeneration = 0; YGFloatOptional computedFlexBasis = {}; // Instead of recomputing the entire layout every single time, we cache some // information to break early when nothing changed uint32_t generationCount = 0; - YGDirection lastOwnerDirection = (YGDirection)-1; + YGDirection lastOwnerDirection = YGDirectionInherit; uint32_t nextCachedMeasurementsIndex = 0; std::array @@ -41,27 +45,41 @@ struct YGLayout { YGCachedMeasurement cachedLayout = YGCachedMeasurement(); - YGDirection direction() const { return flags_.at(); } - decltype(flags_)::Ref direction() { - return flags_.at(); + YGDirection direction() const { + return facebook::yoga::detail::getEnumData( + flags, directionOffset); } - bool didUseLegacyFlag() const { return flags_.at(); } - decltype(flags_)::Ref didUseLegacyFlag() { - return flags_.at(); + void setDirection(YGDirection direction) { + facebook::yoga::detail::setEnumData( + flags, directionOffset, direction); + } + + bool didUseLegacyFlag() const { + return facebook::yoga::detail::getBooleanData( + flags, didUseLegacyFlagOffset); + } + + void setDidUseLegacyFlag(bool val) { + facebook::yoga::detail::setBooleanData(flags, didUseLegacyFlagOffset, val); } bool doesLegacyStretchFlagAffectsLayout() const { - return flags_.at(); - } - decltype(flags_)::Ref - doesLegacyStretchFlagAffectsLayout() { - return flags_.at(); + return facebook::yoga::detail::getBooleanData( + flags, doesLegacyStretchFlagAffectsLayoutOffset); } - bool hadOverflow() const { return flags_.at(); } - decltype(flags_)::Ref hadOverflow() { - return flags_.at(); + void setDoesLegacyStretchFlagAffectsLayout(bool val) { + facebook::yoga::detail::setBooleanData( + flags, doesLegacyStretchFlagAffectsLayoutOffset, val); + } + + bool hadOverflow() const { + return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset); + } + void setHadOverflow(bool hadOverflow) { + facebook::yoga::detail::setBooleanData( + flags, hadOverflowOffset, hadOverflow); } bool operator==(YGLayout layout) const; diff --git a/src/cpp/include/deps/yoga/YGNode.cpp b/src/cpp/include/deps/yoga/YGNode.cpp index 2df2ecaa5..1ee1bde62 100644 --- a/src/cpp/include/deps/yoga/YGNode.cpp +++ b/src/cpp/include/deps/yoga/YGNode.cpp @@ -6,10 +6,8 @@ */ #include "YGNode.h" - #include #include - #include "CompactValue.h" #include "Utils.h" @@ -18,7 +16,7 @@ using facebook::yoga::detail::CompactValue; YGNode::YGNode(YGNode&& node) { context_ = node.context_; - flags_ = node.flags_; + flags = node.flags; measure_ = node.measure_; baseline_ = node.baseline_; print_ = node.print_; @@ -31,7 +29,7 @@ YGNode::YGNode(YGNode&& node) { config_ = node.config_; resolvedDimensions_ = node.resolvedDimensions_; for (auto c : children_) { - c->setOwner(c); + c->setOwner(this); } } @@ -44,7 +42,7 @@ YGNode::YGNode(const YGNode& node, YGConfigRef config) : YGNode{node} { void YGNode::print(void* printContext) { if (print_.noContext != nullptr) { - if (flags_.at()) { + if (facebook::yoga::detail::getBooleanData(flags, printUsesContext_)) { print_.withContext(this, printContext); } else { print_.noContext(this); @@ -52,104 +50,114 @@ void YGNode::print(void* printContext) { } } -YGFloatOptional YGNode::getLeadingPosition(const YGFlexDirection axis, - const float axisSize) const { +YGFloatOptional YGNode::getLeadingPosition( + const YGFlexDirection axis, + const float axisSize) const { if (YGFlexDirectionIsRow(axis)) { - auto leadingPosition = YGComputedEdgeValue(style_.position(), YGEdgeStart, - CompactValue::ofUndefined()); + auto leadingPosition = YGComputedEdgeValue( + style_.position(), YGEdgeStart, CompactValue::ofUndefined()); if (!leadingPosition.isUndefined()) { return YGResolveValue(leadingPosition, axisSize); } } - auto leadingPosition = YGComputedEdgeValue(style_.position(), leading[axis], - CompactValue::ofUndefined()); + auto leadingPosition = YGComputedEdgeValue( + style_.position(), leading[axis], CompactValue::ofUndefined()); return leadingPosition.isUndefined() - ? YGFloatOptional{0} - : YGResolveValue(leadingPosition, axisSize); + ? YGFloatOptional{0} + : YGResolveValue(leadingPosition, axisSize); } -YGFloatOptional YGNode::getTrailingPosition(const YGFlexDirection axis, - const float axisSize) const { +YGFloatOptional YGNode::getTrailingPosition( + const YGFlexDirection axis, + const float axisSize) const { if (YGFlexDirectionIsRow(axis)) { - auto trailingPosition = YGComputedEdgeValue(style_.position(), YGEdgeEnd, - CompactValue::ofUndefined()); + auto trailingPosition = YGComputedEdgeValue( + style_.position(), YGEdgeEnd, CompactValue::ofUndefined()); if (!trailingPosition.isUndefined()) { return YGResolveValue(trailingPosition, axisSize); } } - auto trailingPosition = YGComputedEdgeValue(style_.position(), trailing[axis], - CompactValue::ofUndefined()); + auto trailingPosition = YGComputedEdgeValue( + style_.position(), trailing[axis], CompactValue::ofUndefined()); return trailingPosition.isUndefined() - ? YGFloatOptional{0} - : YGResolveValue(trailingPosition, axisSize); + ? YGFloatOptional{0} + : YGResolveValue(trailingPosition, axisSize); } bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const { return (YGFlexDirectionIsRow(axis) && - !YGComputedEdgeValue(style_.position(), YGEdgeStart, - CompactValue::ofUndefined()) + !YGComputedEdgeValue( + style_.position(), YGEdgeStart, CompactValue::ofUndefined()) .isUndefined()) || - !YGComputedEdgeValue(style_.position(), leading[axis], - CompactValue::ofUndefined()) - .isUndefined(); + !YGComputedEdgeValue( + style_.position(), leading[axis], CompactValue::ofUndefined()) + .isUndefined(); } bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const { return (YGFlexDirectionIsRow(axis) && - !YGComputedEdgeValue(style_.position(), YGEdgeEnd, - CompactValue::ofUndefined()) + !YGComputedEdgeValue( + style_.position(), YGEdgeEnd, CompactValue::ofUndefined()) .isUndefined()) || - !YGComputedEdgeValue(style_.position(), trailing[axis], - CompactValue::ofUndefined()) - .isUndefined(); + !YGComputedEdgeValue( + style_.position(), trailing[axis], CompactValue::ofUndefined()) + .isUndefined(); } -YGFloatOptional YGNode::getLeadingMargin(const YGFlexDirection axis, - const float widthSize) const { +YGFloatOptional YGNode::getLeadingMargin( + const YGFlexDirection axis, + const float widthSize) const { if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeStart].isUndefined()) { return YGResolveValueMargin(style_.margin()[YGEdgeStart], widthSize); } return YGResolveValueMargin( - YGComputedEdgeValue(style_.margin(), leading[axis], - CompactValue::ofZero()), + YGComputedEdgeValue( + style_.margin(), leading[axis], CompactValue::ofZero()), widthSize); } -YGFloatOptional YGNode::getTrailingMargin(const YGFlexDirection axis, - const float widthSize) const { +YGFloatOptional YGNode::getTrailingMargin( + const YGFlexDirection axis, + const float widthSize) const { if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) { return YGResolveValueMargin(style_.margin()[YGEdgeEnd], widthSize); } return YGResolveValueMargin( - YGComputedEdgeValue(style_.margin(), trailing[axis], - CompactValue::ofZero()), + YGComputedEdgeValue( + style_.margin(), trailing[axis], CompactValue::ofZero()), widthSize); } -YGFloatOptional YGNode::getMarginForAxis(const YGFlexDirection axis, - const float widthSize) const { +YGFloatOptional YGNode::getMarginForAxis( + const YGFlexDirection axis, + const float widthSize) const { return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize); } -YGSize YGNode::measure(float width, YGMeasureMode widthMode, float height, - YGMeasureMode heightMode, void* layoutContext) { - return flags_.at() - ? measure_.withContext(this, width, widthMode, height, heightMode, - layoutContext) - : measure_.noContext(this, width, widthMode, height, heightMode); +YGSize YGNode::measure( + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode, + void* layoutContext) { + + return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_) + ? measure_.withContext( + this, width, widthMode, height, heightMode, layoutContext) + : measure_.noContext(this, width, widthMode, height, heightMode); } float YGNode::baseline(float width, float height, void* layoutContext) { - return flags_.at() - ? baseline_.withContext(this, width, height, layoutContext) - : baseline_.noContext(this, width, height); + return facebook::yoga::detail::getBooleanData(flags, baselineUsesContext_) + ? baseline_.withContext(this, width, height, layoutContext) + : baseline_.noContext(this, width, height); } // Setters @@ -158,10 +166,11 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) { if (measureFunc.noContext == nullptr) { // TODO: t18095186 Move nodeType to opt-in function and mark appropriate // places in Litho - flags_.at() = YGNodeTypeDefault; + setNodeType(YGNodeTypeDefault); } else { YGAssertWithNode( - this, children_.size() == 0, + this, + children_.size() == 0, "Cannot set measure function: Nodes with measure functions cannot have " "children."); // TODO: t18095186 Move nodeType to opt-in function and mark appropriate @@ -173,14 +182,14 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) { } void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) { - flags_.at() = false; + facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, false); decltype(YGNode::measure_) m; m.noContext = measureFunc; setMeasureFunc(m); } YOGA_EXPORT void YGNode::setMeasureFunc(MeasureWithContextFn measureFunc) { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, true); decltype(YGNode::measure_) m; m.withContext = measureFunc; setMeasureFunc(m); @@ -199,10 +208,10 @@ void YGNode::insertChild(YGNodeRef child, uint32_t index) { } void YGNode::setDirty(bool isDirty) { - if (isDirty == flags_.at()) { + if (isDirty == facebook::yoga::detail::getBooleanData(flags, isDirty_)) { return; } - flags_.at() = isDirty; + facebook::yoga::detail::setBooleanData(flags, isDirty_, isDirty); if (isDirty && dirtied_) { dirtied_(this); } @@ -223,7 +232,7 @@ void YGNode::removeChild(uint32_t index) { } void YGNode::setLayoutDirection(YGDirection direction) { - layout_.direction() = direction; + layout_.setDirection(direction); } void YGNode::setLayoutMargin(float margin, int index) { @@ -261,7 +270,7 @@ void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) { } void YGNode::setLayoutHadOverflow(bool hadOverflow) { - layout_.hadOverflow() = hadOverflow; + layout_.setHadOverflow(hadOverflow); } void YGNode::setLayoutDimension(float dimension, int index) { @@ -270,8 +279,9 @@ void YGNode::setLayoutDimension(float dimension, int index) { // If both left and right are defined, then use left. Otherwise return +left or // -right depending on which is defined. -YGFloatOptional YGNode::relativePosition(const YGFlexDirection axis, - const float axisSize) const { +YGFloatOptional YGNode::relativePosition( + const YGFlexDirection axis, + const float axisSize) const { if (isLeadingPositionDefined(axis)) { return getLeadingPosition(axis, axisSize); } @@ -283,8 +293,11 @@ YGFloatOptional YGNode::relativePosition(const YGFlexDirection axis, return trailingPosition; } -void YGNode::setPosition(const YGDirection direction, const float mainSize, - const float crossSize, const float ownerWidth) { +void YGNode::setPosition( + const YGDirection direction, + const float mainSize, + const float crossSize, + const float ownerWidth) { /* Root nodes should be always layouted as LTR, so we don't return negative * values. */ const YGDirection directionRespectingRoot = @@ -294,6 +307,9 @@ void YGNode::setPosition(const YGDirection direction, const float mainSize, const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, directionRespectingRoot); + // Here we should check for `YGPositionTypeStatic` and in this case zero inset + // properties (left, right, top, bottom, begin, end). + // https://www.w3.org/TR/css-position-3/#valdef-position-static const YGFloatOptional relativePositionMain = relativePosition(mainAxis, mainSize); const YGFloatOptional relativePositionCross = @@ -338,7 +354,9 @@ YGValue YGNode::resolveFlexBasisPtr() const { return flexBasis; } if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) { - return flags_.at() ? YGValueAuto : YGValueZero; + return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) + ? YGValueAuto + : YGValueZero; } return YGValueAuto; } @@ -377,7 +395,7 @@ void YGNode::cloneChildrenIfNeeded(void* cloneContext) { } void YGNode::markDirtyAndPropogate() { - if (!flags_.at()) { + if (!facebook::yoga::detail::getBooleanData(flags, isDirty_)) { setDirty(true); setLayoutComputedFlexBasis(YGFloatOptional()); if (owner_) { @@ -387,7 +405,7 @@ void YGNode::markDirtyAndPropogate() { } void YGNode::markDirtyAndPropogateDownwards() { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, isDirty_, true); for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) { childNode->markDirtyAndPropogateDownwards(); }); @@ -414,17 +432,19 @@ float YGNode::resolveFlexShrink() const { if (!style_.flexShrink().isUndefined()) { return style_.flexShrink().unwrap(); } - if (!flags_.at() && !style_.flex().isUndefined() && - style_.flex().unwrap() < 0.0f) { + if (!facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) && + !style_.flex().isUndefined() && style_.flex().unwrap() < 0.0f) { return -style_.flex().unwrap(); } - return flags_.at() ? kWebDefaultFlexShrink - : kDefaultFlexShrink; + return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) + ? kWebDefaultFlexShrink + : kDefaultFlexShrink; } bool YGNode::isNodeFlexible() { - return ((style_.positionType() == YGPositionTypeRelative) && - (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); + return ( + (style_.positionType() != YGPositionTypeAbsolute) && + (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); } float YGNode::getLeadingBorder(const YGFlexDirection axis) const { @@ -437,8 +457,8 @@ float YGNode::getLeadingBorder(const YGFlexDirection axis) const { } } - leadingBorder = YGComputedEdgeValue(style_.border(), leading[axis], - CompactValue::ofZero()); + leadingBorder = YGComputedEdgeValue( + style_.border(), leading[axis], CompactValue::ofZero()); return YGFloatMax(leadingBorder.value, 0.0f); } @@ -452,13 +472,14 @@ float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const { } } - trailingBorder = YGComputedEdgeValue(style_.border(), trailing[flexDirection], - CompactValue::ofZero()); + trailingBorder = YGComputedEdgeValue( + style_.border(), trailing[flexDirection], CompactValue::ofZero()); return YGFloatMax(trailingBorder.value, 0.0f); } -YGFloatOptional YGNode::getLeadingPadding(const YGFlexDirection axis, - const float widthSize) const { +YGFloatOptional YGNode::getLeadingPadding( + const YGFlexDirection axis, + const float widthSize) const { const YGFloatOptional paddingEdgeStart = YGResolveValue(style_.padding()[YGEdgeStart], widthSize); if (YGFlexDirectionIsRow(axis) && @@ -467,39 +488,42 @@ YGFloatOptional YGNode::getLeadingPadding(const YGFlexDirection axis, return paddingEdgeStart; } - YGFloatOptional resolvedValue = - YGResolveValue(YGComputedEdgeValue(style_.padding(), leading[axis], - CompactValue::ofZero()), - widthSize); + YGFloatOptional resolvedValue = YGResolveValue( + YGComputedEdgeValue( + style_.padding(), leading[axis], CompactValue::ofZero()), + widthSize); return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); } -YGFloatOptional YGNode::getTrailingPadding(const YGFlexDirection axis, - const float widthSize) const { +YGFloatOptional YGNode::getTrailingPadding( + const YGFlexDirection axis, + const float widthSize) const { const YGFloatOptional paddingEdgeEnd = YGResolveValue(style_.padding()[YGEdgeEnd], widthSize); if (YGFlexDirectionIsRow(axis) && paddingEdgeEnd >= YGFloatOptional{0.0f}) { return paddingEdgeEnd; } - YGFloatOptional resolvedValue = - YGResolveValue(YGComputedEdgeValue(style_.padding(), trailing[axis], - CompactValue::ofZero()), - widthSize); + YGFloatOptional resolvedValue = YGResolveValue( + YGComputedEdgeValue( + style_.padding(), trailing[axis], CompactValue::ofZero()), + widthSize); return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f)); } YGFloatOptional YGNode::getLeadingPaddingAndBorder( - const YGFlexDirection axis, const float widthSize) const { + const YGFlexDirection axis, + const float widthSize) const { return getLeadingPadding(axis, widthSize) + - YGFloatOptional(getLeadingBorder(axis)); + YGFloatOptional(getLeadingBorder(axis)); } YGFloatOptional YGNode::getTrailingPaddingAndBorder( - const YGFlexDirection axis, const float widthSize) const { + const YGFlexDirection axis, + const float widthSize) const { return getTrailingPadding(axis, widthSize) + - YGFloatOptional(getTrailingBorder(axis)); + YGFloatOptional(getTrailingBorder(axis)); } bool YGNode::didUseLegacyFlag() { @@ -518,11 +542,11 @@ bool YGNode::didUseLegacyFlag() { void YGNode::setLayoutDoesLegacyFlagAffectsLayout( bool doesLegacyFlagAffectsLayout) { - layout_.doesLegacyStretchFlagAffectsLayout() = doesLegacyFlagAffectsLayout; + layout_.setDoesLegacyStretchFlagAffectsLayout(doesLegacyFlagAffectsLayout); } void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) { - layout_.didUseLegacyFlag() = didUseLegacyFlag; + layout_.setDidUseLegacyFlag(didUseLegacyFlag); } bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const { @@ -550,14 +574,17 @@ bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const { } void YGNode::reset() { - YGAssertWithNode(this, children_.size() == 0, - "Cannot reset a node which still has children attached"); - YGAssertWithNode(this, owner_ == nullptr, - "Cannot reset a node still attached to a owner"); + YGAssertWithNode( + this, + children_.size() == 0, + "Cannot reset a node which still has children attached"); + YGAssertWithNode( + this, owner_ == nullptr, "Cannot reset a node still attached to a owner"); clearChildren(); - auto webDefaults = flags_.at(); + auto webDefaults = + facebook::yoga::detail::getBooleanData(flags, useWebDefaults_); *this = YGNode{getConfig()}; if (webDefaults) { useWebDefaults(); diff --git a/src/cpp/include/deps/yoga/YGNode.h b/src/cpp/include/deps/yoga/YGNode.h index b45e70c54..63d98fe3a 100644 --- a/src/cpp/include/deps/yoga/YGNode.h +++ b/src/cpp/include/deps/yoga/YGNode.h @@ -6,27 +6,28 @@ */ #pragma once -#include + +#ifdef __cplusplus #include - -#include "Bitfield.h" +#include +#include "BitUtils.h" #include "CompactValue.h" #include "YGConfig.h" #include "YGLayout.h" -#include "YGMacros.h" #include "YGStyle.h" +#include "YGMacros.h" #include "Yoga-internal.h" YGConfigRef YGConfigGetDefault(); struct YOGA_EXPORT YGNode { - using MeasureWithContextFn = YGSize (*)(YGNode*, float, YGMeasureMode, float, - YGMeasureMode, void*); + using MeasureWithContextFn = + YGSize (*)(YGNode*, float, YGMeasureMode, float, YGMeasureMode, void*); using BaselineWithContextFn = float (*)(YGNode*, float, float, void*); using PrintWithContextFn = void (*)(YGNode*, void*); - private: +private: static constexpr size_t hasNewLayout_ = 0; static constexpr size_t isReferenceBaseline_ = 1; static constexpr size_t isDirty_ = 2; @@ -37,10 +38,7 @@ struct YOGA_EXPORT YGNode { static constexpr size_t useWebDefaults_ = 7; void* context_ = nullptr; - using Flags = facebook::yoga::Bitfield; - Flags flags_ = {true, false, false, YGNodeTypeDefault, - false, false, false, false}; + uint8_t flags = 1; uint8_t reserved_ = 0; union { YGMeasureFunc noContext; @@ -64,20 +62,21 @@ struct YOGA_EXPORT YGNode { std::array resolvedDimensions_ = { {YGValueUndefined, YGValueUndefined}}; - YGFloatOptional relativePosition(const YGFlexDirection axis, - const float axisSize) const; + YGFloatOptional relativePosition( + const YGFlexDirection axis, + const float axisSize) const; void setMeasureFunc(decltype(measure_)); void setBaselineFunc(decltype(baseline_)); void useWebDefaults() { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, useWebDefaults_, true); style_.flexDirection() = YGFlexDirectionRow; style_.alignContent() = YGAlignStretch; } // DANGER DANGER DANGER! - // If the the node assigned to has children, we'd either have to deallocate + // If the node assigned to has children, we'd either have to deallocate // them (potentially incorrect) or ignore them (danger of leaks). Only ever // use this after checking that there are no children. // DO NOT CHANGE THE VISIBILITY OF THIS METHOD! @@ -85,14 +84,14 @@ struct YOGA_EXPORT YGNode { using CompactValue = facebook::yoga::detail::CompactValue; - public: +public: YGNode() : YGNode{YGConfigGetDefault()} {} explicit YGNode(const YGConfigRef config) : config_{config} { if (config->useWebDefaults) { useWebDefaults(); } }; - ~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree + ~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree YGNode(YGNode&&); @@ -115,9 +114,13 @@ struct YOGA_EXPORT YGNode { void print(void*); - bool getHasNewLayout() const { return flags_.at(); } + bool getHasNewLayout() const { + return facebook::yoga::detail::getBooleanData(flags, hasNewLayout_); + } - YGNodeType getNodeType() const { return flags_.at(); } + YGNodeType getNodeType() const { + return facebook::yoga::detail::getEnumData(flags, nodeType_); + } bool hasMeasureFunc() const noexcept { return measure_.noContext != nullptr; } @@ -143,7 +146,9 @@ struct YOGA_EXPORT YGNode { uint32_t getLineIndex() const { return lineIndex_; } - bool isReferenceBaseline() { return flags_.at(); } + bool isReferenceBaseline() { + return facebook::yoga::detail::getBooleanData(flags, isReferenceBaseline_); + } // returns the YGNodeRef that owns this YGNode. An owner is used to identify // the YogaTree that a YGNode belongs to. This method will return the parent @@ -176,7 +181,9 @@ struct YOGA_EXPORT YGNode { YGConfigRef getConfig() const { return config_; } - bool isDirty() const { return flags_.at(); } + bool isDirty() const { + return facebook::yoga::detail::getBooleanData(flags, isDirty_); + } std::array getResolvedDimensions() const { return resolvedDimensions_; @@ -187,47 +194,59 @@ struct YOGA_EXPORT YGNode { } // Methods related to positions, margin, padding and border - YGFloatOptional getLeadingPosition(const YGFlexDirection axis, - const float axisSize) const; + YGFloatOptional getLeadingPosition( + const YGFlexDirection axis, + const float axisSize) const; bool isLeadingPositionDefined(const YGFlexDirection axis) const; bool isTrailingPosDefined(const YGFlexDirection axis) const; - YGFloatOptional getTrailingPosition(const YGFlexDirection axis, - const float axisSize) const; - YGFloatOptional getLeadingMargin(const YGFlexDirection axis, - const float widthSize) const; - YGFloatOptional getTrailingMargin(const YGFlexDirection axis, - const float widthSize) const; + YGFloatOptional getTrailingPosition( + const YGFlexDirection axis, + const float axisSize) const; + YGFloatOptional getLeadingMargin( + const YGFlexDirection axis, + const float widthSize) const; + YGFloatOptional getTrailingMargin( + const YGFlexDirection axis, + const float widthSize) const; float getLeadingBorder(const YGFlexDirection flexDirection) const; float getTrailingBorder(const YGFlexDirection flexDirection) const; - YGFloatOptional getLeadingPadding(const YGFlexDirection axis, - const float widthSize) const; - YGFloatOptional getTrailingPadding(const YGFlexDirection axis, - const float widthSize) const; - YGFloatOptional getLeadingPaddingAndBorder(const YGFlexDirection axis, - const float widthSize) const; - YGFloatOptional getTrailingPaddingAndBorder(const YGFlexDirection axis, - const float widthSize) const; - YGFloatOptional getMarginForAxis(const YGFlexDirection axis, - const float widthSize) const; + YGFloatOptional getLeadingPadding( + const YGFlexDirection axis, + const float widthSize) const; + YGFloatOptional getTrailingPadding( + const YGFlexDirection axis, + const float widthSize) const; + YGFloatOptional getLeadingPaddingAndBorder( + const YGFlexDirection axis, + const float widthSize) const; + YGFloatOptional getTrailingPaddingAndBorder( + const YGFlexDirection axis, + const float widthSize) const; + YGFloatOptional getMarginForAxis( + const YGFlexDirection axis, + const float widthSize) const; // Setters void setContext(void* context) { context_ = context; } void setPrintFunc(YGPrintFunc printFunc) { print_.noContext = printFunc; - flags_.at() = false; + facebook::yoga::detail::setBooleanData(flags, printUsesContext_, false); } void setPrintFunc(PrintWithContextFn printFunc) { print_.withContext = printFunc; - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, printUsesContext_, true); } void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); } void setHasNewLayout(bool hasNewLayout) { - flags_.at() = hasNewLayout; + facebook::yoga::detail::setBooleanData(flags, hasNewLayout_, hasNewLayout); } - void setNodeType(YGNodeType nodeType) { flags_.at() = nodeType; } + void setNodeType(YGNodeType nodeType) { + return facebook::yoga::detail::setEnumData( + flags, nodeType_, nodeType); + } void setMeasureFunc(YGMeasureFunc measureFunc); void setMeasureFunc(MeasureWithContextFn); @@ -236,11 +255,11 @@ struct YOGA_EXPORT YGNode { } void setBaselineFunc(YGBaselineFunc baseLineFunc) { - flags_.at() = false; + facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, false); baseline_.noContext = baseLineFunc; } void setBaselineFunc(BaselineWithContextFn baseLineFunc) { - flags_.at() = true; + facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, true); baseline_.withContext = baseLineFunc; } void setBaselineFunc(std::nullptr_t) { @@ -256,7 +275,8 @@ struct YOGA_EXPORT YGNode { void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; } void setIsReferenceBaseline(bool isReferenceBaseline) { - flags_.at() = isReferenceBaseline; + facebook::yoga::detail::setBooleanData( + flags, isReferenceBaseline_, isReferenceBaseline); } void setOwner(YGNodeRef owner) { owner_ = owner; } @@ -280,8 +300,11 @@ struct YOGA_EXPORT YGNode { void setLayoutBorder(float border, int index); void setLayoutPadding(float padding, int index); void setLayoutPosition(float position, int index); - void setPosition(const YGDirection direction, const float mainSize, - const float crossSize, const float ownerWidth); + void setPosition( + const YGDirection direction, + const float mainSize, + const float crossSize, + const float ownerWidth); void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout); void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag); void markDirtyAndPropogateDownwards(); @@ -310,3 +333,5 @@ struct YOGA_EXPORT YGNode { bool isLayoutTreeEqualToNode(const YGNode& node) const; void reset(); }; + +#endif diff --git a/src/cpp/include/deps/yoga/YGNodePrint.cpp b/src/cpp/include/deps/yoga/YGNodePrint.cpp index a894271be..26efa4858 100644 --- a/src/cpp/include/deps/yoga/YGNodePrint.cpp +++ b/src/cpp/include/deps/yoga/YGNodePrint.cpp @@ -7,13 +7,11 @@ #ifdef DEBUG #include "YGNodePrint.h" - #include - -#include "Utils.h" #include "YGEnums.h" #include "YGNode.h" #include "Yoga-internal.h" +#include "Utils.h" namespace facebook { namespace yoga { @@ -27,7 +25,7 @@ static void indent(string& base, uint32_t level) { static bool areFourValuesEqual(const YGStyle::Edges& four) { return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) && - YGValueEqual(four[0], four[3]); + YGValueEqual(four[0], four[3]); } static void appendFormatedString(string& str, const char* fmt, ...) { @@ -43,35 +41,43 @@ static void appendFormatedString(string& str, const char* fmt, ...) { str.append(result); } -static void appendFloatOptionalIfDefined(string& base, const string key, - const YGFloatOptional num) { +static void appendFloatOptionalIfDefined( + string& base, + const string key, + const YGFloatOptional num) { if (!num.isUndefined()) { appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap()); } } -static void appendNumberIfNotUndefined(string& base, const string key, - const YGValue number) { +static void appendNumberIfNotUndefined( + string& base, + const string key, + const YGValue number) { if (number.unit != YGUnitUndefined) { if (number.unit == YGUnitAuto) { base.append(key + ": auto; "); } else { string unit = number.unit == YGUnitPoint ? "px" : "%%"; - appendFormatedString(base, "%s: %g%s; ", key.c_str(), number.value, - unit.c_str()); + appendFormatedString( + base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str()); } } } -static void appendNumberIfNotAuto(string& base, const string& key, - const YGValue number) { +static void appendNumberIfNotAuto( + string& base, + const string& key, + const YGValue number) { if (number.unit != YGUnitAuto) { appendNumberIfNotUndefined(base, key, number); } } -static void appendNumberIfNotZero(string& base, const string& str, - const YGValue number) { +static void appendNumberIfNotZero( + string& base, + const string& str, + const YGValue number) { if (number.unit == YGUnitAuto) { base.append(str + ": auto; "); } else if (!YGFloatsEqual(number.value, 0)) { @@ -79,8 +85,10 @@ static void appendNumberIfNotZero(string& base, const string& str, } } -static void appendEdges(string& base, const string& key, - const YGStyle::Edges& edges) { +static void appendEdges( + string& base, + const string& key, + const YGStyle::Edges& edges) { if (areFourValuesEqual(edges)) { appendNumberIfNotZero(base, key, edges[YGEdgeLeft]); } else { @@ -91,29 +99,35 @@ static void appendEdges(string& base, const string& key, } } -static void appendEdgeIfNotUndefined(string& base, const string& str, - const YGStyle::Edges& edges, - const YGEdge edge) { +static void appendEdgeIfNotUndefined( + string& base, + const string& str, + const YGStyle::Edges& edges, + const YGEdge edge) { appendNumberIfNotUndefined( - base, str, + base, + str, YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined())); } -void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options, - uint32_t level) { +void YGNodeToString( + std::string& str, + YGNodeRef node, + YGPrintOptions options, + uint32_t level) { indent(str, level); appendFormatedString(str, "
getLayout().dimensions[YGDimensionWidth]); - appendFormatedString(str, "height: %g; ", - node->getLayout().dimensions[YGDimensionHeight]); - appendFormatedString(str, "top: %g; ", - node->getLayout().position[YGEdgeTop]); - appendFormatedString(str, "left: %g;", - node->getLayout().position[YGEdgeLeft]); + appendFormatedString( + str, "width: %g; ", node->getLayout().dimensions[YGDimensionWidth]); + appendFormatedString( + str, "height: %g; ", node->getLayout().dimensions[YGDimensionHeight]); + appendFormatedString( + str, "top: %g; ", node->getLayout().position[YGEdgeTop]); + appendFormatedString( + str, "left: %g;", node->getLayout().position[YGEdgeLeft]); appendFormatedString(str, "\" "); } @@ -121,24 +135,28 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options, appendFormatedString(str, "style=\""); const auto& style = node->getStyle(); if (style.flexDirection() != YGNode().getStyle().flexDirection()) { - appendFormatedString(str, "flex-direction: %s; ", - YGFlexDirectionToString(style.flexDirection())); + appendFormatedString( + str, + "flex-direction: %s; ", + YGFlexDirectionToString(style.flexDirection())); } if (style.justifyContent() != YGNode().getStyle().justifyContent()) { - appendFormatedString(str, "justify-content: %s; ", - YGJustifyToString(style.justifyContent())); + appendFormatedString( + str, + "justify-content: %s; ", + YGJustifyToString(style.justifyContent())); } if (style.alignItems() != YGNode().getStyle().alignItems()) { - appendFormatedString(str, "align-items: %s; ", - YGAlignToString(style.alignItems())); + appendFormatedString( + str, "align-items: %s; ", YGAlignToString(style.alignItems())); } if (style.alignContent() != YGNode().getStyle().alignContent()) { - appendFormatedString(str, "align-content: %s; ", - YGAlignToString(style.alignContent())); + appendFormatedString( + str, "align-content: %s; ", YGAlignToString(style.alignContent())); } if (style.alignSelf() != YGNode().getStyle().alignSelf()) { - appendFormatedString(str, "align-self: %s; ", - YGAlignToString(style.alignSelf())); + appendFormatedString( + str, "align-self: %s; ", YGAlignToString(style.alignSelf())); } appendFloatOptionalIfDefined(str, "flex-grow", style.flexGrow()); appendFloatOptionalIfDefined(str, "flex-shrink", style.flexShrink()); @@ -146,18 +164,18 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options, appendFloatOptionalIfDefined(str, "flex", style.flex()); if (style.flexWrap() != YGNode().getStyle().flexWrap()) { - appendFormatedString(str, "flex-wrap: %s; ", - YGWrapToString(style.flexWrap())); + appendFormatedString( + str, "flex-wrap: %s; ", YGWrapToString(style.flexWrap())); } if (style.overflow() != YGNode().getStyle().overflow()) { - appendFormatedString(str, "overflow: %s; ", - YGOverflowToString(style.overflow())); + appendFormatedString( + str, "overflow: %s; ", YGOverflowToString(style.overflow())); } if (style.display() != YGNode().getStyle().display()) { - appendFormatedString(str, "display: %s; ", - YGDisplayToString(style.display())); + appendFormatedString( + str, "display: %s; ", YGDisplayToString(style.display())); } appendEdges(str, "margin", style.margin()); appendEdges(str, "padding", style.padding()); @@ -165,18 +183,18 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options, appendNumberIfNotAuto(str, "width", style.dimensions()[YGDimensionWidth]); appendNumberIfNotAuto(str, "height", style.dimensions()[YGDimensionHeight]); - appendNumberIfNotAuto(str, "max-width", - style.maxDimensions()[YGDimensionWidth]); - appendNumberIfNotAuto(str, "max-height", - style.maxDimensions()[YGDimensionHeight]); - appendNumberIfNotAuto(str, "min-width", - style.minDimensions()[YGDimensionWidth]); - appendNumberIfNotAuto(str, "min-height", - style.minDimensions()[YGDimensionHeight]); + appendNumberIfNotAuto( + str, "max-width", style.maxDimensions()[YGDimensionWidth]); + appendNumberIfNotAuto( + str, "max-height", style.maxDimensions()[YGDimensionHeight]); + appendNumberIfNotAuto( + str, "min-width", style.minDimensions()[YGDimensionWidth]); + appendNumberIfNotAuto( + str, "min-height", style.minDimensions()[YGDimensionHeight]); if (style.positionType() != YGNode().getStyle().positionType()) { - appendFormatedString(str, "position: %s; ", - YGPositionTypeToString(style.positionType())); + appendFormatedString( + str, "position: %s; ", YGPositionTypeToString(style.positionType())); } appendEdgeIfNotUndefined(str, "left", style.position(), YGEdgeLeft); @@ -202,6 +220,6 @@ void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options, } appendFormatedString(str, "
"); } -} // namespace yoga -} // namespace facebook +} // namespace yoga +} // namespace facebook #endif diff --git a/src/cpp/include/deps/yoga/YGNodePrint.h b/src/cpp/include/deps/yoga/YGNodePrint.h index 4f1d96351..3db504b46 100644 --- a/src/cpp/include/deps/yoga/YGNodePrint.h +++ b/src/cpp/include/deps/yoga/YGNodePrint.h @@ -14,9 +14,12 @@ namespace facebook { namespace yoga { -void YGNodeToString(std::string& str, YGNodeRef node, YGPrintOptions options, - uint32_t level); +void YGNodeToString( + std::string& str, + YGNodeRef node, + YGPrintOptions options, + uint32_t level); -} // namespace yoga -} // namespace facebook +} // namespace yoga +} // namespace facebook #endif diff --git a/src/cpp/include/deps/yoga/YGStyle.cpp b/src/cpp/include/deps/yoga/YGStyle.cpp index b53f7ed82..e8033bdf4 100644 --- a/src/cpp/include/deps/yoga/YGStyle.cpp +++ b/src/cpp/include/deps/yoga/YGStyle.cpp @@ -6,13 +6,11 @@ */ #include "YGStyle.h" - #include "Utils.h" // Yoga specific properties, not compatible with flexbox specification bool operator==(const YGStyle& lhs, const YGStyle& rhs) { - bool areNonFloatValuesEqual = - lhs.direction() == rhs.direction() && + bool areNonFloatValuesEqual = lhs.direction() == rhs.direction() && lhs.flexDirection() == rhs.flexDirection() && lhs.justifyContent() == rhs.justifyContent() && lhs.alignContent() == rhs.alignContent() && @@ -29,22 +27,20 @@ bool operator==(const YGStyle& lhs, const YGStyle& rhs) { lhs.maxDimensions() == rhs.maxDimensions(); areNonFloatValuesEqual = areNonFloatValuesEqual && - lhs.flex().isUndefined() == rhs.flex().isUndefined(); + lhs.flex().isUndefined() == rhs.flex().isUndefined(); if (areNonFloatValuesEqual && !lhs.flex().isUndefined() && !rhs.flex().isUndefined()) { areNonFloatValuesEqual = areNonFloatValuesEqual && lhs.flex() == rhs.flex(); } - areNonFloatValuesEqual = - areNonFloatValuesEqual && + areNonFloatValuesEqual = areNonFloatValuesEqual && lhs.flexGrow().isUndefined() == rhs.flexGrow().isUndefined(); if (areNonFloatValuesEqual && !lhs.flexGrow().isUndefined()) { areNonFloatValuesEqual = areNonFloatValuesEqual && lhs.flexGrow() == rhs.flexGrow(); } - areNonFloatValuesEqual = - areNonFloatValuesEqual && + areNonFloatValuesEqual = areNonFloatValuesEqual && lhs.flexShrink().isUndefined() == rhs.flexShrink().isUndefined(); if (areNonFloatValuesEqual && !rhs.flexShrink().isUndefined()) { areNonFloatValuesEqual = diff --git a/src/cpp/include/deps/yoga/YGStyle.h b/src/cpp/include/deps/yoga/YGStyle.h index 0f044da82..aab7599cc 100644 --- a/src/cpp/include/deps/yoga/YGStyle.h +++ b/src/cpp/include/deps/yoga/YGStyle.h @@ -6,17 +6,19 @@ */ #pragma once + +#ifdef __cplusplus + #include #include #include #include - -#include "Bitfield.h" #include "CompactValue.h" #include "YGEnums.h" #include "YGFloatOptional.h" #include "Yoga-internal.h" #include "Yoga.h" +#include "BitUtils.h" class YOGA_EXPORT YGStyle { template @@ -24,10 +26,23 @@ class YOGA_EXPORT YGStyle { facebook::yoga::detail::Values()>; using CompactValue = facebook::yoga::detail::CompactValue; - public: +public: using Dimensions = Values; using Edges = Values; + template + struct BitfieldRef { + YGStyle& style; + size_t offset; + operator T() const { + return facebook::yoga::detail::getEnumData(style.flags, offset); + } + BitfieldRef& operator=(T x) { + facebook::yoga::detail::setEnumData(style.flags, offset, x); + return *this; + } + }; + template struct Ref { YGStyle& style; @@ -56,35 +71,40 @@ class YOGA_EXPORT YGStyle { style.*Prop = values; return *this; } - operator const Values &() const { return style.*Prop; } + operator const Values&() const { return style.*Prop; } Ref operator[](Idx idx) { return {style, idx}; } CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; } }; - YGStyle() = default; + YGStyle() { + alignContent() = YGAlignFlexStart; + alignItems() = YGAlignStretch; + } ~YGStyle() = default; - private: - static constexpr size_t directionIdx = 0; - static constexpr size_t flexDirectionIdx = 1; - static constexpr size_t justifyContentIdx = 2; - static constexpr size_t alignContentIdx = 3; - static constexpr size_t alignItemsIdx = 4; - static constexpr size_t alignSelfIdx = 5; - static constexpr size_t positionTypeIdx = 6; - static constexpr size_t flexWrapIdx = 7; - static constexpr size_t overflowIdx = 8; - static constexpr size_t displayIdx = 9; - using Flags = - facebook::yoga::Bitfield; +private: + static constexpr size_t directionOffset = 0; + static constexpr size_t flexdirectionOffset = + directionOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t justifyContentOffset = flexdirectionOffset + + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t alignContentOffset = + justifyContentOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t alignItemsOffset = + alignContentOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t alignSelfOffset = + alignItemsOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t positionTypeOffset = + alignSelfOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t flexWrapOffset = + positionTypeOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t overflowOffset = + flexWrapOffset + facebook::yoga::detail::bitWidthFn(); + static constexpr size_t displayOffset = + overflowOffset + facebook::yoga::detail::bitWidthFn(); + + uint32_t flags = 0; - Flags flags_ = {YGDirectionInherit, YGFlexDirectionColumn, - YGJustifyFlexStart, YGAlignFlexStart, - YGAlignStretch, YGAlignAuto, - YGPositionTypeRelative, YGWrapNoWrap, - YGOverflowVisible, YGDisplayFlex}; YGFloatOptional flex_ = {}; YGFloatOptional flexGrow_ = {}; YGFloatOptional flexShrink_ = {}; @@ -99,49 +119,72 @@ class YOGA_EXPORT YGStyle { // Yoga specific properties, not compatible with flexbox specification YGFloatOptional aspectRatio_ = {}; - public: +public: // for library users needing a type using ValueRepr = std::remove_reference::type; - YGDirection direction() const { return flags_.at(); } - Flags::Ref direction() { return flags_.at(); } + YGDirection direction() const { + return facebook::yoga::detail::getEnumData( + flags, directionOffset); + } + BitfieldRef direction() { return {*this, directionOffset}; } YGFlexDirection flexDirection() const { - return flags_.at(); + return facebook::yoga::detail::getEnumData( + flags, flexdirectionOffset); } - Flags::Ref flexDirection() { - return flags_.at(); + BitfieldRef flexDirection() { + return {*this, flexdirectionOffset}; } - YGJustify justifyContent() const { return flags_.at(); } - Flags::Ref justifyContent() { - return flags_.at(); + YGJustify justifyContent() const { + return facebook::yoga::detail::getEnumData( + flags, justifyContentOffset); + } + BitfieldRef justifyContent() { + return {*this, justifyContentOffset}; } - YGAlign alignContent() const { return flags_.at(); } - Flags::Ref alignContent() { - return flags_.at(); + YGAlign alignContent() const { + return facebook::yoga::detail::getEnumData( + flags, alignContentOffset); + } + BitfieldRef alignContent() { return {*this, alignContentOffset}; } + + YGAlign alignItems() const { + return facebook::yoga::detail::getEnumData( + flags, alignItemsOffset); + } + BitfieldRef alignItems() { return {*this, alignItemsOffset}; } + + YGAlign alignSelf() const { + return facebook::yoga::detail::getEnumData(flags, alignSelfOffset); + } + BitfieldRef alignSelf() { return {*this, alignSelfOffset}; } + + YGPositionType positionType() const { + return facebook::yoga::detail::getEnumData( + flags, positionTypeOffset); + } + BitfieldRef positionType() { + return {*this, positionTypeOffset}; } - YGAlign alignItems() const { return flags_.at(); } - Flags::Ref alignItems() { return flags_.at(); } - - YGAlign alignSelf() const { return flags_.at(); } - Flags::Ref alignSelf() { return flags_.at(); } - - YGPositionType positionType() const { return flags_.at(); } - Flags::Ref positionType() { - return flags_.at(); + YGWrap flexWrap() const { + return facebook::yoga::detail::getEnumData(flags, flexWrapOffset); } + BitfieldRef flexWrap() { return {*this, flexWrapOffset}; } - YGWrap flexWrap() const { return flags_.at(); } - Flags::Ref flexWrap() { return flags_.at(); } + YGOverflow overflow() const { + return facebook::yoga::detail::getEnumData( + flags, overflowOffset); + } + BitfieldRef overflow() { return {*this, overflowOffset}; } - YGOverflow overflow() const { return flags_.at(); } - Flags::Ref overflow() { return flags_.at(); } - - YGDisplay display() const { return flags_.at(); } - Flags::Ref display() { return flags_.at(); } + YGDisplay display() const { + return facebook::yoga::detail::getEnumData(flags, displayOffset); + } + BitfieldRef display() { return {*this, displayOffset}; } YGFloatOptional flex() const { return flex_; } Ref flex() { return {*this}; } @@ -189,3 +232,5 @@ YOGA_EXPORT bool operator==(const YGStyle& lhs, const YGStyle& rhs); YOGA_EXPORT inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) { return !(lhs == rhs); } + +#endif diff --git a/src/cpp/include/deps/yoga/YGValue.h b/src/cpp/include/deps/yoga/YGValue.h index fee1570bd..a20009784 100644 --- a/src/cpp/include/deps/yoga/YGValue.h +++ b/src/cpp/include/deps/yoga/YGValue.h @@ -8,19 +8,26 @@ #pragma once #include - #include "YGEnums.h" #include "YGMacros.h" +#if defined(_MSC_VER) && defined(__clang__) +#define COMPILING_WITH_CLANG_ON_WINDOWS +#endif +#if defined(COMPILING_WITH_CLANG_ON_WINDOWS) +#include +constexpr float YGUndefined = std::numeric_limits::quiet_NaN(); +#else YG_EXTERN_C_BEGIN // Not defined in MSVC++ #ifndef NAN static const uint32_t __nan = 0x7fc00000; -#define NAN (*(const float*)__nan) +#define NAN (*(const float*) __nan) #endif #define YGUndefined NAN +#endif typedef struct YGValue { float value; @@ -31,7 +38,10 @@ YOGA_EXPORT extern const YGValue YGValueAuto; YOGA_EXPORT extern const YGValue YGValueUndefined; YOGA_EXPORT extern const YGValue YGValueZero; +#if !defined(COMPILING_WITH_CLANG_ON_WINDOWS) YG_EXTERN_C_END +#endif +#undef COMPILING_WITH_CLANG_ON_WINDOWS #ifdef __cplusplus @@ -78,8 +88,8 @@ inline YGValue operator"" _percent(unsigned long long value) { return operator"" _percent(static_cast(value)); } -} // namespace literals -} // namespace yoga -} // namespace facebook +} // namespace literals +} // namespace yoga +} // namespace facebook #endif diff --git a/src/cpp/include/deps/yoga/Yoga-internal.h b/src/cpp/include/deps/yoga/Yoga-internal.h index 5d1b83d5f..1a22f24c9 100644 --- a/src/cpp/include/deps/yoga/Yoga-internal.h +++ b/src/cpp/include/deps/yoga/Yoga-internal.h @@ -10,7 +10,6 @@ #include #include #include - #include "CompactValue.h" #include "Yoga.h" @@ -18,20 +17,24 @@ using YGVector = std::vector; YG_EXTERN_C_BEGIN -void YGNodeCalculateLayoutWithContext(YGNodeRef node, float availableWidth, - float availableHeight, - YGDirection ownerDirection, - void* layoutContext); +void YGNodeCalculateLayoutWithContext( + YGNodeRef node, + float availableWidth, + float availableHeight, + YGDirection ownerDirection, + void* layoutContext); YG_EXTERN_C_END namespace facebook { namespace yoga { -inline bool isUndefined(float value) { return std::isnan(value); } +inline bool isUndefined(float value) { + return std::isnan(value); +} -} // namespace yoga -} // namespace facebook +} // namespace yoga +} // namespace facebook using namespace facebook; @@ -51,16 +54,16 @@ struct YGCachedMeasurement { float computedHeight; YGCachedMeasurement() - : availableWidth(0), - availableHeight(0), - widthMeasureMode((YGMeasureMode)-1), - heightMeasureMode((YGMeasureMode)-1), + : availableWidth(-1), + availableHeight(-1), + widthMeasureMode(YGMeasureModeUndefined), + heightMeasureMode(YGMeasureModeUndefined), computedWidth(-1), computedHeight(-1) {} bool operator==(YGCachedMeasurement measurement) const { bool isEqual = widthMeasureMode == measurement.widthMeasureMode && - heightMeasureMode == measurement.heightMeasureMode; + heightMeasureMode == measurement.heightMeasureMode; if (!yoga::isUndefined(availableWidth) || !yoga::isUndefined(measurement.availableWidth)) { @@ -93,10 +96,10 @@ namespace detail { template class Values { - private: +private: std::array values_; - public: +public: Values() = default; explicit Values(const YGValue& defaultValue) noexcept { values_.fill(defaultValue); @@ -132,9 +135,9 @@ class Values { Values& operator=(const Values& other) = default; }; -} // namespace detail -} // namespace yoga -} // namespace facebook +} // namespace detail +} // namespace yoga +} // namespace facebook static const float kDefaultFlexGrow = 0.0f; static const float kDefaultFlexShrink = 0.0f; @@ -144,4 +147,5 @@ extern bool YGFloatsEqual(const float a, const float b); extern facebook::yoga::detail::CompactValue YGComputedEdgeValue( const facebook::yoga::detail::Values< facebook::yoga::enums::count()>& edges, - YGEdge edge, facebook::yoga::detail::CompactValue defaultValue); + YGEdge edge, + facebook::yoga::detail::CompactValue defaultValue); diff --git a/src/cpp/include/deps/yoga/Yoga.cpp b/src/cpp/include/deps/yoga/Yoga.cpp index 883b0a5f7..2db6be21d 100644 --- a/src/cpp/include/deps/yoga/Yoga.cpp +++ b/src/cpp/include/deps/yoga/Yoga.cpp @@ -6,20 +6,17 @@ */ #include "Yoga.h" - +#include "log.h" #include #include - #include #include #include - #include "Utils.h" #include "YGNode.h" #include "YGNodePrint.h" #include "Yoga-internal.h" #include "event/event.h" -#include "log.h" #ifdef _MSC_VER #include @@ -35,17 +32,29 @@ using namespace facebook::yoga; using detail::Log; #ifdef ANDROID -static int YGAndroidLog(const YGConfigRef config, const YGNodeRef node, - YGLogLevel level, const char* format, va_list args); +static int YGAndroidLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args); #else -static int YGDefaultLog(const YGConfigRef config, const YGNodeRef node, - YGLogLevel level, const char* format, va_list args); +static int YGDefaultLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args); #endif #ifdef ANDROID #include -static int YGAndroidLog(const YGConfigRef config, const YGNodeRef node, - YGLogLevel level, const char* format, va_list args) { +static int YGAndroidLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args) { int androidLevel = YGLogLevelDebug; switch (level) { case YGLogLevelFatal: @@ -71,10 +80,14 @@ static int YGAndroidLog(const YGConfigRef config, const YGNodeRef node, return result; } #else -#define YG_UNUSED(x) (void)(x); +#define YG_UNUSED(x) (void) (x); -static int YGDefaultLog(const YGConfigRef config, const YGNodeRef node, - YGLogLevel level, const char* format, va_list args) { +static int YGDefaultLog( + const YGConfigRef config, + const YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args) { YG_UNUSED(config); YG_UNUSED(node); switch (level) { @@ -97,9 +110,10 @@ YOGA_EXPORT bool YGFloatIsUndefined(const float value) { return facebook::yoga::isUndefined(value); } -detail::CompactValue YGComputedEdgeValue(const YGStyle::Edges& edges, - YGEdge edge, - detail::CompactValue defaultValue) { +detail::CompactValue YGComputedEdgeValue( + const YGStyle::Edges& edges, + YGEdge edge, + detail::CompactValue defaultValue) { if (!edges[edge].isUndefined()) { return edges[edge]; } @@ -138,8 +152,9 @@ YOGA_EXPORT bool YGNodeHasMeasureFunc(YGNodeRef node) { return node->hasMeasureFunc(); } -YOGA_EXPORT void YGNodeSetMeasureFunc(YGNodeRef node, - YGMeasureFunc measureFunc) { +YOGA_EXPORT void YGNodeSetMeasureFunc( + YGNodeRef node, + YGMeasureFunc measureFunc) { node->setMeasureFunc(measureFunc); } @@ -147,8 +162,9 @@ YOGA_EXPORT bool YGNodeHasBaselineFunc(YGNodeRef node) { return node->hasBaselineFunc(); } -YOGA_EXPORT void YGNodeSetBaselineFunc(YGNodeRef node, - YGBaselineFunc baselineFunc) { +YOGA_EXPORT void YGNodeSetBaselineFunc( + YGNodeRef node, + YGBaselineFunc baselineFunc) { node->setBaselineFunc(baselineFunc); } @@ -156,8 +172,9 @@ YOGA_EXPORT YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node) { return node->getDirtied(); } -YOGA_EXPORT void YGNodeSetDirtiedFunc(YGNodeRef node, - YGDirtiedFunc dirtiedFunc) { +YOGA_EXPORT void YGNodeSetDirtiedFunc( + YGNodeRef node, + YGDirtiedFunc dirtiedFunc) { node->setDirtiedFunc(dirtiedFunc); } @@ -185,7 +202,9 @@ YOGA_EXPORT void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType) { return node->setNodeType(nodeType); } -YOGA_EXPORT bool YGNodeIsDirty(YGNodeRef node) { return node->isDirty(); } +YOGA_EXPORT bool YGNodeIsDirty(YGNodeRef node) { + return node->isDirty(); +} YOGA_EXPORT bool YGNodeLayoutGetDidUseLegacyFlag(const YGNodeRef node) { return node->didUseLegacyFlag(); @@ -200,8 +219,8 @@ int32_t gConfigInstanceCount = 0; YOGA_EXPORT WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) { const YGNodeRef node = new YGNode{config}; - YGAssertWithConfig(config, node != nullptr, - "Could not allocate memory for node"); + YGAssertWithConfig( + config, node != nullptr, "Could not allocate memory for node"); Event::publish(node, {config}); return node; @@ -218,8 +237,10 @@ YOGA_EXPORT YGNodeRef YGNodeNew(void) { YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) { YGNodeRef node = new YGNode(*oldNode); - YGAssertWithConfig(oldNode->getConfig(), node != nullptr, - "Could not allocate memory for node"); + YGAssertWithConfig( + oldNode->getConfig(), + node != nullptr, + "Could not allocate memory for node"); Event::publish(node, {node->getConfig()}); node->setOwner(nullptr); return node; @@ -228,9 +249,6 @@ YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) { static YGConfigRef YGConfigClone(const YGConfig& oldConfig) { const YGConfigRef config = new YGConfig(oldConfig); YGAssert(config != nullptr, "Could not allocate memory for config"); - if (config == nullptr) { - abort(); - } gConfigInstanceCount++; return config; } @@ -282,8 +300,9 @@ static void YGConfigFreeRecursive(const YGNodeRef root) { } } -YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(const YGNodeRef root, - YGNodeCleanupFunc cleanup) { +YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( + const YGNodeRef root, + YGNodeCleanupFunc cleanup) { uint32_t skipped = 0; while (YGNodeGetChildCount(root) > skipped) { const YGNodeRef child = YGNodeGetChild(root, skipped); @@ -305,9 +324,13 @@ YOGA_EXPORT void YGNodeFreeRecursive(const YGNodeRef root) { return YGNodeFreeRecursiveWithCleanupFunc(root, nullptr); } -YOGA_EXPORT void YGNodeReset(YGNodeRef node) { node->reset(); } +YOGA_EXPORT void YGNodeReset(YGNodeRef node) { + node->reset(); +} -int32_t YGConfigGetInstanceCount(void) { return gConfigInstanceCount; } +int32_t YGConfigGetInstanceCount(void) { + return gConfigInstanceCount; +} YOGA_EXPORT YGConfigRef YGConfigNew(void) { #ifdef ANDROID @@ -328,8 +351,9 @@ void YGConfigCopy(const YGConfigRef dest, const YGConfigRef src) { memcpy(dest, src, sizeof(YGConfig)); } -YOGA_EXPORT void YGNodeSetIsReferenceBaseline(YGNodeRef node, - bool isReferenceBaseline) { +YOGA_EXPORT void YGNodeSetIsReferenceBaseline( + YGNodeRef node, + bool isReferenceBaseline) { if (node->isReferenceBaseline() != isReferenceBaseline) { node->setIsReferenceBaseline(isReferenceBaseline); node->markDirtyAndPropogate(); @@ -340,13 +364,18 @@ YOGA_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node) { return node->isReferenceBaseline(); } -YOGA_EXPORT void YGNodeInsertChild(const YGNodeRef owner, const YGNodeRef child, - const uint32_t index) { - YGAssertWithNode(owner, child->getOwner() == nullptr, - "Child already has a owner, it must be removed first."); +YOGA_EXPORT void YGNodeInsertChild( + const YGNodeRef owner, + const YGNodeRef child, + const uint32_t index) { + YGAssertWithNode( + owner, + child->getOwner() == nullptr, + "Child already has a owner, it must be removed first."); YGAssertWithNode( - owner, !owner->hasMeasureFunc(), + owner, + !owner->hasMeasureFunc(), "Cannot add child: Nodes with measure functions cannot have children."); owner->insertChild(child, index); @@ -354,8 +383,17 @@ YOGA_EXPORT void YGNodeInsertChild(const YGNodeRef owner, const YGNodeRef child, owner->markDirtyAndPropogate(); } -YOGA_EXPORT void YGNodeRemoveChild(const YGNodeRef owner, - const YGNodeRef excludedChild) { +YOGA_EXPORT void YGNodeSwapChild( + const YGNodeRef owner, + const YGNodeRef child, + const uint32_t index) { + owner->replaceChild(child, index); + child->setOwner(owner); +} + +YOGA_EXPORT void YGNodeRemoveChild( + const YGNodeRef owner, + const YGNodeRef excludedChild) { if (YGNodeGetChildCount(owner) == 0) { // This is an empty set. Nothing to remove. return; @@ -367,7 +405,7 @@ YOGA_EXPORT void YGNodeRemoveChild(const YGNodeRef owner, auto childOwner = excludedChild->getOwner(); if (owner->removeChild(excludedChild)) { if (owner == childOwner) { - excludedChild->setLayout({}); // layout is no longer valid + excludedChild->setLayout({}); // layout is no longer valid excludedChild->setOwner(nullptr); } owner->markDirtyAndPropogate(); @@ -386,7 +424,7 @@ YOGA_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef owner) { // set is unique. for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef oldChild = YGNodeGetChild(owner, i); - oldChild->setLayout(YGNode().getLayout()); // layout is no longer valid + oldChild->setLayout(YGNode().getLayout()); // layout is no longer valid oldChild->setOwner(nullptr); } owner->clearChildren(); @@ -399,8 +437,9 @@ YOGA_EXPORT void YGNodeRemoveAllChildren(const YGNodeRef owner) { owner->markDirtyAndPropogate(); } -static void YGNodeSetChildrenInternal(YGNodeRef const owner, - const std::vector& children) { +static void YGNodeSetChildrenInternal( + YGNodeRef const owner, + const std::vector& children) { if (!owner) { return; } @@ -433,19 +472,22 @@ static void YGNodeSetChildrenInternal(YGNodeRef const owner, } } -YOGA_EXPORT void YGNodeSetChildren(const YGNodeRef owner, const YGNodeRef c[], - const uint32_t count) { +YOGA_EXPORT void YGNodeSetChildren( + const YGNodeRef owner, + const YGNodeRef c[], + const uint32_t count) { const YGVector children = {c, c + count}; YGNodeSetChildrenInternal(owner, children); } -YOGA_EXPORT void YGNodeSetChildren(YGNodeRef const owner, - const std::vector& children) { +YOGA_EXPORT void YGNodeSetChildren( + YGNodeRef const owner, + const std::vector& children) { YGNodeSetChildrenInternal(owner, children); } -YOGA_EXPORT YGNodeRef YGNodeGetChild(const YGNodeRef node, - const uint32_t index) { +YOGA_EXPORT YGNodeRef +YGNodeGetChild(const YGNodeRef node, const uint32_t index) { if (index < node->getChildren().size()) { return node->getChild(index); } @@ -465,15 +507,18 @@ YOGA_EXPORT YGNodeRef YGNodeGetParent(const YGNodeRef node) { } YOGA_EXPORT void YGNodeMarkDirty(const YGNodeRef node) { - YGAssertWithNode(node, node->hasMeasureFunc(), - "Only leaf nodes with custom measure functions" - "should manually mark themselves as dirty"); + YGAssertWithNode( + node, + node->hasMeasureFunc(), + "Only leaf nodes with custom measure functions" + "should manually mark themselves as dirty"); node->markDirtyAndPropogate(); } -YOGA_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, - const YGNodeRef srcNode) { +YOGA_EXPORT void YGNodeCopyStyle( + const YGNodeRef dstNode, + const YGNodeRef srcNode) { if (!(dstNode->getStyle() == srcNode->getStyle())) { dstNode->setStyle(srcNode->getStyle()); dstNode->markDirtyAndPropogate(); @@ -482,22 +527,25 @@ YOGA_EXPORT void YGNodeCopyStyle(const YGNodeRef dstNode, YOGA_EXPORT float YGNodeStyleGetFlexGrow(const YGNodeConstRef node) { return node->getStyle().flexGrow().isUndefined() - ? kDefaultFlexGrow - : node->getStyle().flexGrow().unwrap(); + ? kDefaultFlexGrow + : node->getStyle().flexGrow().unwrap(); } YOGA_EXPORT float YGNodeStyleGetFlexShrink(const YGNodeConstRef node) { return node->getStyle().flexShrink().isUndefined() - ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink - : kDefaultFlexShrink) - : node->getStyle().flexShrink().unwrap(); + ? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink + : kDefaultFlexShrink) + : node->getStyle().flexShrink().unwrap(); } namespace { template -void updateStyle(YGNode* node, T value, NeedsUpdate&& needsUpdate, - Update&& update) { +void updateStyle( + YGNode* node, + T value, + NeedsUpdate&& needsUpdate, + Update&& update) { if (needsUpdate(node->getStyle(), value)) { update(node->getStyle(), value); node->markDirtyAndPropogate(); @@ -507,21 +555,27 @@ void updateStyle(YGNode* node, T value, NeedsUpdate&& needsUpdate, template void updateStyle(YGNode* node, Ref (YGStyle::*prop)(), T value) { updateStyle( - node, value, [prop](YGStyle& s, T x) { return (s.*prop)() != x; }, + node, + value, + [prop](YGStyle& s, T x) { return (s.*prop)() != x; }, [prop](YGStyle& s, T x) { (s.*prop)() = x; }); } template -void updateIndexedStyleProp(YGNode* node, Ref (YGStyle::*prop)(), Idx idx, - detail::CompactValue value) { +void updateIndexedStyleProp( + YGNode* node, + Ref (YGStyle::*prop)(), + Idx idx, + detail::CompactValue value) { using detail::CompactValue; updateStyle( - node, value, + node, + value, [idx, prop](YGStyle& s, CompactValue x) { return (s.*prop)()[idx] != x; }, [idx, prop](YGStyle& s, CompactValue x) { (s.*prop)()[idx] = x; }); } -} // namespace +} // namespace // MSVC has trouble inferring the return type of pointer to member functions // with const and non-const overloads, instead of preferring the non-const @@ -530,8 +584,9 @@ void updateIndexedStyleProp(YGNode* node, Ref (YGStyle::*prop)(), Idx idx, // decltype, MSVC will prefer the non-const version. #define MSVC_HINT(PROP) decltype(YGStyle{}.PROP()) -YOGA_EXPORT void YGNodeStyleSetDirection(const YGNodeRef node, - const YGDirection value) { +YOGA_EXPORT void YGNodeStyleSetDirection( + const YGNodeRef node, + const YGDirection value) { updateStyle(node, &YGStyle::direction, value); } YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { @@ -539,77 +594,86 @@ YOGA_EXPORT YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { } YOGA_EXPORT void YGNodeStyleSetFlexDirection( - const YGNodeRef node, const YGFlexDirection flexDirection) { - updateStyle(node, &YGStyle::flexDirection, - flexDirection); + const YGNodeRef node, + const YGFlexDirection flexDirection) { + updateStyle( + node, &YGStyle::flexDirection, flexDirection); } YOGA_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { return node->getStyle().flexDirection(); } -YOGA_EXPORT void YGNodeStyleSetJustifyContent(const YGNodeRef node, - const YGJustify justifyContent) { - updateStyle(node, &YGStyle::justifyContent, - justifyContent); +YOGA_EXPORT void YGNodeStyleSetJustifyContent( + const YGNodeRef node, + const YGJustify justifyContent) { + updateStyle( + node, &YGStyle::justifyContent, justifyContent); } YOGA_EXPORT YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { return node->getStyle().justifyContent(); } -YOGA_EXPORT void YGNodeStyleSetAlignContent(const YGNodeRef node, - const YGAlign alignContent) { - updateStyle(node, &YGStyle::alignContent, - alignContent); +YOGA_EXPORT void YGNodeStyleSetAlignContent( + const YGNodeRef node, + const YGAlign alignContent) { + updateStyle( + node, &YGStyle::alignContent, alignContent); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { return node->getStyle().alignContent(); } -YOGA_EXPORT void YGNodeStyleSetAlignItems(const YGNodeRef node, - const YGAlign alignItems) { +YOGA_EXPORT void YGNodeStyleSetAlignItems( + const YGNodeRef node, + const YGAlign alignItems) { updateStyle(node, &YGStyle::alignItems, alignItems); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { return node->getStyle().alignItems(); } -YOGA_EXPORT void YGNodeStyleSetAlignSelf(const YGNodeRef node, - const YGAlign alignSelf) { +YOGA_EXPORT void YGNodeStyleSetAlignSelf( + const YGNodeRef node, + const YGAlign alignSelf) { updateStyle(node, &YGStyle::alignSelf, alignSelf); } YOGA_EXPORT YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { return node->getStyle().alignSelf(); } -YOGA_EXPORT void YGNodeStyleSetPositionType(const YGNodeRef node, - const YGPositionType positionType) { - updateStyle(node, &YGStyle::positionType, - positionType); +YOGA_EXPORT void YGNodeStyleSetPositionType( + const YGNodeRef node, + const YGPositionType positionType) { + updateStyle( + node, &YGStyle::positionType, positionType); } YOGA_EXPORT YGPositionType YGNodeStyleGetPositionType(const YGNodeConstRef node) { return node->getStyle().positionType(); } -YOGA_EXPORT void YGNodeStyleSetFlexWrap(const YGNodeRef node, - const YGWrap flexWrap) { +YOGA_EXPORT void YGNodeStyleSetFlexWrap( + const YGNodeRef node, + const YGWrap flexWrap) { updateStyle(node, &YGStyle::flexWrap, flexWrap); } YOGA_EXPORT YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { return node->getStyle().flexWrap(); } -YOGA_EXPORT void YGNodeStyleSetOverflow(const YGNodeRef node, - const YGOverflow overflow) { +YOGA_EXPORT void YGNodeStyleSetOverflow( + const YGNodeRef node, + const YGOverflow overflow) { updateStyle(node, &YGStyle::overflow, overflow); } YOGA_EXPORT YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { return node->getStyle().overflow(); } -YOGA_EXPORT void YGNodeStyleSetDisplay(const YGNodeRef node, - const YGDisplay display) { +YOGA_EXPORT void YGNodeStyleSetDisplay( + const YGNodeRef node, + const YGDisplay display) { updateStyle(node, &YGStyle::display, display); } YOGA_EXPORT YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) { @@ -624,22 +688,24 @@ YOGA_EXPORT void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { // TODO(T26792433): Change the API to accept YGFloatOptional. YOGA_EXPORT float YGNodeStyleGetFlex(const YGNodeConstRef node) { return node->getStyle().flex().isUndefined() - ? YGUndefined - : node->getStyle().flex().unwrap(); + ? YGUndefined + : node->getStyle().flex().unwrap(); } // TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetFlexGrow(const YGNodeRef node, - const float flexGrow) { - updateStyle(node, &YGStyle::flexGrow, - YGFloatOptional{flexGrow}); +YOGA_EXPORT void YGNodeStyleSetFlexGrow( + const YGNodeRef node, + const float flexGrow) { + updateStyle( + node, &YGStyle::flexGrow, YGFloatOptional{flexGrow}); } // TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetFlexShrink(const YGNodeRef node, - const float flexShrink) { - updateStyle(node, &YGStyle::flexShrink, - YGFloatOptional{flexShrink}); +YOGA_EXPORT void YGNodeStyleSetFlexShrink( + const YGNodeRef node, + const float flexShrink) { + updateStyle( + node, &YGStyle::flexShrink, YGFloatOptional{flexShrink}); } YOGA_EXPORT YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { @@ -651,85 +717,102 @@ YOGA_EXPORT YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { return flexBasis; } -YOGA_EXPORT void YGNodeStyleSetFlexBasis(const YGNodeRef node, - const float flexBasis) { +YOGA_EXPORT void YGNodeStyleSetFlexBasis( + const YGNodeRef node, + const float flexBasis) { auto value = detail::CompactValue::ofMaybe(flexBasis); updateStyle(node, &YGStyle::flexBasis, value); } -YOGA_EXPORT void YGNodeStyleSetFlexBasisPercent(const YGNodeRef node, - const float flexBasisPercent) { +YOGA_EXPORT void YGNodeStyleSetFlexBasisPercent( + const YGNodeRef node, + const float flexBasisPercent) { auto value = detail::CompactValue::ofMaybe(flexBasisPercent); updateStyle(node, &YGStyle::flexBasis, value); } YOGA_EXPORT void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { - updateStyle(node, &YGStyle::flexBasis, - detail::CompactValue::ofAuto()); + updateStyle( + node, &YGStyle::flexBasis, detail::CompactValue::ofAuto()); } -YOGA_EXPORT void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, - float points) { +YOGA_EXPORT void YGNodeStyleSetPosition( + YGNodeRef node, + YGEdge edge, + float points) { auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp(node, &YGStyle::position, edge, - value); + updateIndexedStyleProp( + node, &YGStyle::position, edge, value); } -YOGA_EXPORT void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, - float percent) { +YOGA_EXPORT void YGNodeStyleSetPositionPercent( + YGNodeRef node, + YGEdge edge, + float percent) { auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp(node, &YGStyle::position, edge, - value); + updateIndexedStyleProp( + node, &YGStyle::position, edge, value); } YOGA_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { return node->getStyle().position()[edge]; } -YOGA_EXPORT void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, - float points) { +YOGA_EXPORT void YGNodeStyleSetMargin( + YGNodeRef node, + YGEdge edge, + float points) { auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp(node, &YGStyle::margin, edge, - value); + updateIndexedStyleProp( + node, &YGStyle::margin, edge, value); } -YOGA_EXPORT void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, - float percent) { +YOGA_EXPORT void YGNodeStyleSetMarginPercent( + YGNodeRef node, + YGEdge edge, + float percent) { auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp(node, &YGStyle::margin, edge, - value); + updateIndexedStyleProp( + node, &YGStyle::margin, edge, value); } YOGA_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) { - updateIndexedStyleProp(node, &YGStyle::margin, edge, - detail::CompactValue::ofAuto()); + updateIndexedStyleProp( + node, &YGStyle::margin, edge, detail::CompactValue::ofAuto()); } YOGA_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { return node->getStyle().margin()[edge]; } -YOGA_EXPORT void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, - float points) { +YOGA_EXPORT void YGNodeStyleSetPadding( + YGNodeRef node, + YGEdge edge, + float points) { auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp(node, &YGStyle::padding, edge, - value); + updateIndexedStyleProp( + node, &YGStyle::padding, edge, value); } -YOGA_EXPORT void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, - float percent) { +YOGA_EXPORT void YGNodeStyleSetPaddingPercent( + YGNodeRef node, + YGEdge edge, + float percent) { auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp(node, &YGStyle::padding, edge, - value); + updateIndexedStyleProp( + node, &YGStyle::padding, edge, value); } YOGA_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { return node->getStyle().padding()[edge]; } // TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetBorder(const YGNodeRef node, const YGEdge edge, - const float border) { +YOGA_EXPORT void YGNodeStyleSetBorder( + const YGNodeRef node, + const YGEdge edge, + const float border) { auto value = detail::CompactValue::ofMaybe(border); - updateIndexedStyleProp(node, &YGStyle::border, edge, - value); + updateIndexedStyleProp( + node, &YGStyle::border, edge, value); } -YOGA_EXPORT float YGNodeStyleGetBorder(const YGNodeConstRef node, - const YGEdge edge) { +YOGA_EXPORT float YGNodeStyleGetBorder( + const YGNodeConstRef node, + const YGEdge edge) { auto border = node->getStyle().border()[edge]; if (border.isUndefined() || border.isAuto()) { // TODO(T26792433): Rather than returning YGUndefined, change the api to @@ -749,26 +832,29 @@ YOGA_EXPORT float YGNodeStyleGetAspectRatio(const YGNodeConstRef node) { } // TODO(T26792433): Change the API to accept YGFloatOptional. -YOGA_EXPORT void YGNodeStyleSetAspectRatio(const YGNodeRef node, - const float aspectRatio) { - updateStyle(node, &YGStyle::aspectRatio, - YGFloatOptional{aspectRatio}); +YOGA_EXPORT void YGNodeStyleSetAspectRatio( + const YGNodeRef node, + const float aspectRatio) { + updateStyle( + node, &YGStyle::aspectRatio, YGFloatOptional{aspectRatio}); } YOGA_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, float points) { auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp(node, &YGStyle::dimensions, - YGDimensionWidth, value); + updateIndexedStyleProp( + node, &YGStyle::dimensions, YGDimensionWidth, value); } YOGA_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, float percent) { auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp(node, &YGStyle::dimensions, - YGDimensionWidth, value); + updateIndexedStyleProp( + node, &YGStyle::dimensions, YGDimensionWidth, value); } YOGA_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node) { - updateIndexedStyleProp(node, &YGStyle::dimensions, - YGDimensionWidth, - detail::CompactValue::ofAuto()); + updateIndexedStyleProp( + node, + &YGStyle::dimensions, + YGDimensionWidth, + detail::CompactValue::ofAuto()); } YOGA_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { return node->getStyle().dimensions()[YGDimensionWidth]; @@ -776,31 +862,35 @@ YOGA_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { YOGA_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, float points) { auto value = detail::CompactValue::ofMaybe(points); - updateIndexedStyleProp(node, &YGStyle::dimensions, - YGDimensionHeight, value); + updateIndexedStyleProp( + node, &YGStyle::dimensions, YGDimensionHeight, value); } YOGA_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, float percent) { auto value = detail::CompactValue::ofMaybe(percent); - updateIndexedStyleProp(node, &YGStyle::dimensions, - YGDimensionHeight, value); + updateIndexedStyleProp( + node, &YGStyle::dimensions, YGDimensionHeight, value); } YOGA_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node) { - updateIndexedStyleProp(node, &YGStyle::dimensions, - YGDimensionHeight, - detail::CompactValue::ofAuto()); + updateIndexedStyleProp( + node, + &YGStyle::dimensions, + YGDimensionHeight, + detail::CompactValue::ofAuto()); } YOGA_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { return node->getStyle().dimensions()[YGDimensionHeight]; } -YOGA_EXPORT void YGNodeStyleSetMinWidth(const YGNodeRef node, - const float minWidth) { +YOGA_EXPORT void YGNodeStyleSetMinWidth( + const YGNodeRef node, + const float minWidth) { auto value = detail::CompactValue::ofMaybe(minWidth); updateIndexedStyleProp( node, &YGStyle::minDimensions, YGDimensionWidth, value); } -YOGA_EXPORT void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, - const float minWidth) { +YOGA_EXPORT void YGNodeStyleSetMinWidthPercent( + const YGNodeRef node, + const float minWidth) { auto value = detail::CompactValue::ofMaybe(minWidth); updateIndexedStyleProp( node, &YGStyle::minDimensions, YGDimensionWidth, value); @@ -809,14 +899,16 @@ YOGA_EXPORT YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { return node->getStyle().minDimensions()[YGDimensionWidth]; }; -YOGA_EXPORT void YGNodeStyleSetMinHeight(const YGNodeRef node, - const float minHeight) { +YOGA_EXPORT void YGNodeStyleSetMinHeight( + const YGNodeRef node, + const float minHeight) { auto value = detail::CompactValue::ofMaybe(minHeight); updateIndexedStyleProp( node, &YGStyle::minDimensions, YGDimensionHeight, value); } -YOGA_EXPORT void YGNodeStyleSetMinHeightPercent(const YGNodeRef node, - const float minHeight) { +YOGA_EXPORT void YGNodeStyleSetMinHeightPercent( + const YGNodeRef node, + const float minHeight) { auto value = detail::CompactValue::ofMaybe(minHeight); updateIndexedStyleProp( node, &YGStyle::minDimensions, YGDimensionHeight, value); @@ -825,14 +917,16 @@ YOGA_EXPORT YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { return node->getStyle().minDimensions()[YGDimensionHeight]; }; -YOGA_EXPORT void YGNodeStyleSetMaxWidth(const YGNodeRef node, - const float maxWidth) { +YOGA_EXPORT void YGNodeStyleSetMaxWidth( + const YGNodeRef node, + const float maxWidth) { auto value = detail::CompactValue::ofMaybe(maxWidth); updateIndexedStyleProp( node, &YGStyle::maxDimensions, YGDimensionWidth, value); } -YOGA_EXPORT void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, - const float maxWidth) { +YOGA_EXPORT void YGNodeStyleSetMaxWidthPercent( + const YGNodeRef node, + const float maxWidth) { auto value = detail::CompactValue::ofMaybe(maxWidth); updateIndexedStyleProp( node, &YGStyle::maxDimensions, YGDimensionWidth, value); @@ -841,14 +935,16 @@ YOGA_EXPORT YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { return node->getStyle().maxDimensions()[YGDimensionWidth]; }; -YOGA_EXPORT void YGNodeStyleSetMaxHeight(const YGNodeRef node, - const float maxHeight) { +YOGA_EXPORT void YGNodeStyleSetMaxHeight( + const YGNodeRef node, + const float maxHeight) { auto value = detail::CompactValue::ofMaybe(maxHeight); updateIndexedStyleProp( node, &YGStyle::maxDimensions, YGDimensionHeight, value); } -YOGA_EXPORT void YGNodeStyleSetMaxHeightPercent(const YGNodeRef node, - const float maxHeight) { +YOGA_EXPORT void YGNodeStyleSetMaxHeightPercent( + const YGNodeRef node, + const float maxHeight) { auto value = detail::CompactValue::ofMaybe(maxHeight); updateIndexedStyleProp( node, &YGStyle::maxDimensions, YGDimensionHeight, value); @@ -862,29 +958,31 @@ YOGA_EXPORT YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { return node->getLayout().instanceName; \ } -#define YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(type, name, instanceName) \ - YOGA_EXPORT type YGNodeLayoutGet##name(const YGNodeRef node, \ - const YGEdge edge) { \ - YGAssertWithNode(node, edge <= YGEdgeEnd, \ - "Cannot get layout properties of multi-edge shorthands"); \ - \ - if (edge == YGEdgeStart) { \ - if (node->getLayout().direction() == YGDirectionRTL) { \ - return node->getLayout().instanceName[YGEdgeRight]; \ - } else { \ - return node->getLayout().instanceName[YGEdgeLeft]; \ - } \ - } \ - \ - if (edge == YGEdgeEnd) { \ - if (node->getLayout().direction() == YGDirectionRTL) { \ - return node->getLayout().instanceName[YGEdgeLeft]; \ - } else { \ - return node->getLayout().instanceName[YGEdgeRight]; \ - } \ - } \ - \ - return node->getLayout().instanceName[edge]; \ +#define YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(type, name, instanceName) \ + YOGA_EXPORT type YGNodeLayoutGet##name( \ + const YGNodeRef node, const YGEdge edge) { \ + YGAssertWithNode( \ + node, \ + edge <= YGEdgeEnd, \ + "Cannot get layout properties of multi-edge shorthands"); \ + \ + if (edge == YGEdgeStart) { \ + if (node->getLayout().direction() == YGDirectionRTL) { \ + return node->getLayout().instanceName[YGEdgeRight]; \ + } else { \ + return node->getLayout().instanceName[YGEdgeLeft]; \ + } \ + } \ + \ + if (edge == YGEdgeEnd) { \ + if (node->getLayout().direction() == YGDirectionRTL) { \ + return node->getLayout().instanceName[YGEdgeLeft]; \ + } else { \ + return node->getLayout().instanceName[YGEdgeRight]; \ + } \ + } \ + \ + return node->getLayout().instanceName[edge]; \ } YG_NODE_LAYOUT_PROPERTY_IMPL(float, Left, position[YGEdgeLeft]); @@ -908,24 +1006,34 @@ YOGA_EXPORT bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout( std::atomic gCurrentGenerationCount(0); bool YGLayoutNodeInternal( - const YGNodeRef node, const float availableWidth, - const float availableHeight, const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, const YGMeasureMode heightMeasureMode, - const float ownerWidth, const float ownerHeight, const bool performLayout, - const LayoutPassReason reason, const YGConfigRef config, - LayoutData& layoutMarkerData, void* const layoutContext, - const uint32_t depth, const uint32_t generationCount); + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const LayoutPassReason reason, + const YGConfigRef config, + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount); #ifdef DEBUG -static void YGNodePrintInternal(const YGNodeRef node, - const YGPrintOptions options) { +static void YGNodePrintInternal( + const YGNodeRef node, + const YGPrintOptions options) { std::string str; facebook::yoga::YGNodeToString(str, node, options, 0); Log::log(node, YGLogLevelDebug, nullptr, str.c_str()); } -YOGA_EXPORT void YGNodePrint(const YGNodeRef node, - const YGPrintOptions options) { +YOGA_EXPORT void YGNodePrint( + const YGNodeRef node, + const YGPrintOptions options) { YGNodePrintInternal(node, options); } #endif @@ -945,9 +1053,10 @@ static const std::array pos = {{ static const std::array dim = { {YGDimensionHeight, YGDimensionHeight, YGDimensionWidth, YGDimensionWidth}}; -static inline float YGNodePaddingAndBorderForAxis(const YGNodeConstRef node, - const YGFlexDirection axis, - const float widthSize) { +static inline float YGNodePaddingAndBorderForAxis( + const YGNodeConstRef node, + const YGFlexDirection axis, + const float widthSize) { return (node->getLeadingPaddingAndBorder(axis, widthSize) + node->getTrailingPaddingAndBorder(axis, widthSize)) .unwrap(); @@ -955,8 +1064,8 @@ static inline float YGNodePaddingAndBorderForAxis(const YGNodeConstRef node, static inline YGAlign YGNodeAlignItem(const YGNode* node, const YGNode* child) { const YGAlign align = child->getStyle().alignSelf() == YGAlignAuto - ? node->getStyle().alignItems() - : child->getStyle().alignSelf(); + ? node->getStyle().alignItems() + : child->getStyle().alignSelf(); if (align == YGAlignBaseline && YGFlexDirectionIsColumn(node->getStyle().flexDirection())) { return YGAlignFlexStart; @@ -966,16 +1075,20 @@ static inline YGAlign YGNodeAlignItem(const YGNode* node, const YGNode* child) { static float YGBaseline(const YGNodeRef node, void* layoutContext) { if (node->hasBaselineFunc()) { + Event::publish(node); const float baseline = node->baseline( node->getLayout().measuredDimensions[YGDimensionWidth], - node->getLayout().measuredDimensions[YGDimensionHeight], layoutContext); + node->getLayout().measuredDimensions[YGDimensionHeight], + layoutContext); Event::publish(node); - YGAssertWithNode(node, !YGFloatIsUndefined(baseline), - "Expect custom baseline function to not return NaN"); + YGAssertWithNode( + node, + !YGFloatIsUndefined(baseline), + "Expect custom baseline function to not return NaN"); return baseline; } @@ -1018,7 +1131,7 @@ static bool YGIsBaselineLayout(const YGNodeRef node) { const uint32_t childCount = YGNodeGetChildCount(node); for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeGetChild(node, i); - if (child->getStyle().positionType() == YGPositionTypeRelative && + if (child->getStyle().positionType() != YGPositionTypeAbsolute && child->getStyle().alignSelf() == YGAlignBaseline) { return true; } @@ -1027,53 +1140,58 @@ static bool YGIsBaselineLayout(const YGNodeRef node) { return false; } -static inline float YGNodeDimWithMargin(const YGNodeRef node, - const YGFlexDirection axis, - const float widthSize) { +static inline float YGNodeDimWithMargin( + const YGNodeRef node, + const YGFlexDirection axis, + const float widthSize) { return node->getLayout().measuredDimensions[dim[axis]] + - (node->getLeadingMargin(axis, widthSize) + - node->getTrailingMargin(axis, widthSize)) - .unwrap(); + (node->getLeadingMargin(axis, widthSize) + + node->getTrailingMargin(axis, widthSize)) + .unwrap(); } -static inline bool YGNodeIsStyleDimDefined(const YGNodeRef node, - const YGFlexDirection axis, - const float ownerSize) { +static inline bool YGNodeIsStyleDimDefined( + const YGNodeRef node, + const YGFlexDirection axis, + const float ownerSize) { bool isUndefined = YGFloatIsUndefined(node->getResolvedDimension(dim[axis]).value); - return !(node->getResolvedDimension(dim[axis]).unit == YGUnitAuto || - node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined || - (node->getResolvedDimension(dim[axis]).unit == YGUnitPoint && - !isUndefined && - node->getResolvedDimension(dim[axis]).value < 0.0f) || - (node->getResolvedDimension(dim[axis]).unit == YGUnitPercent && - !isUndefined && - (node->getResolvedDimension(dim[axis]).value < 0.0f || - YGFloatIsUndefined(ownerSize)))); + return !( + node->getResolvedDimension(dim[axis]).unit == YGUnitAuto || + node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined || + (node->getResolvedDimension(dim[axis]).unit == YGUnitPoint && + !isUndefined && node->getResolvedDimension(dim[axis]).value < 0.0f) || + (node->getResolvedDimension(dim[axis]).unit == YGUnitPercent && + !isUndefined && + (node->getResolvedDimension(dim[axis]).value < 0.0f || + YGFloatIsUndefined(ownerSize)))); } -static inline bool YGNodeIsLayoutDimDefined(const YGNodeRef node, - const YGFlexDirection axis) { +static inline bool YGNodeIsLayoutDimDefined( + const YGNodeRef node, + const YGFlexDirection axis) { const float value = node->getLayout().measuredDimensions[dim[axis]]; return !YGFloatIsUndefined(value) && value >= 0.0f; } static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( - const YGNodeConstRef node, const YGFlexDirection axis, - const YGFloatOptional value, const float axisSize) { + const YGNodeConstRef node, + const YGFlexDirection axis, + const YGFloatOptional value, + const float axisSize) { YGFloatOptional min; YGFloatOptional max; if (YGFlexDirectionIsColumn(axis)) { - min = YGResolveValue(node->getStyle().minDimensions()[YGDimensionHeight], - axisSize); - max = YGResolveValue(node->getStyle().maxDimensions()[YGDimensionHeight], - axisSize); + min = YGResolveValue( + node->getStyle().minDimensions()[YGDimensionHeight], axisSize); + max = YGResolveValue( + node->getStyle().maxDimensions()[YGDimensionHeight], axisSize); } else if (YGFlexDirectionIsRow(axis)) { - min = YGResolveValue(node->getStyle().minDimensions()[YGDimensionWidth], - axisSize); - max = YGResolveValue(node->getStyle().maxDimensions()[YGDimensionWidth], - axisSize); + min = YGResolveValue( + node->getStyle().minDimensions()[YGDimensionWidth], axisSize); + max = YGResolveValue( + node->getStyle().maxDimensions()[YGDimensionWidth], axisSize); } if (max >= YGFloatOptional{0} && value > max) { @@ -1089,40 +1207,47 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax( // Like YGNodeBoundAxisWithinMinAndMax but also ensures that the value doesn't // go below the padding and border amount. -static inline float YGNodeBoundAxis(const YGNodeRef node, - const YGFlexDirection axis, - const float value, const float axisSize, - const float widthSize) { - return YGFloatMax(YGNodeBoundAxisWithinMinAndMax( - node, axis, YGFloatOptional{value}, axisSize) - .unwrap(), - YGNodePaddingAndBorderForAxis(node, axis, widthSize)); +static inline float YGNodeBoundAxis( + const YGNodeRef node, + const YGFlexDirection axis, + const float value, + const float axisSize, + const float widthSize) { + return YGFloatMax( + YGNodeBoundAxisWithinMinAndMax( + node, axis, YGFloatOptional{value}, axisSize) + .unwrap(), + YGNodePaddingAndBorderForAxis(node, axis, widthSize)); } -static void YGNodeSetChildTrailingPosition(const YGNodeRef node, - const YGNodeRef child, - const YGFlexDirection axis) { +static void YGNodeSetChildTrailingPosition( + const YGNodeRef node, + const YGNodeRef child, + const YGFlexDirection axis) { const float size = child->getLayout().measuredDimensions[dim[axis]]; - child->setLayoutPosition(node->getLayout().measuredDimensions[dim[axis]] - - size - child->getLayout().position[pos[axis]], - trailing[axis]); + child->setLayoutPosition( + node->getLayout().measuredDimensions[dim[axis]] - size - + child->getLayout().position[pos[axis]], + trailing[axis]); } -static void YGConstrainMaxSizeForMode(const YGNodeConstRef node, - const enum YGFlexDirection axis, - const float ownerAxisSize, - const float ownerWidth, - YGMeasureMode* mode, float* size) { +static void YGConstrainMaxSizeForMode( + const YGNodeConstRef node, + const enum YGFlexDirection axis, + const float ownerAxisSize, + const float ownerWidth, + YGMeasureMode* mode, + float* size) { const YGFloatOptional maxSize = - YGResolveValue(node->getStyle().maxDimensions()[dim[axis]], - ownerAxisSize) + + YGResolveValue( + node->getStyle().maxDimensions()[dim[axis]], ownerAxisSize) + YGFloatOptional(node->getMarginForAxis(axis, ownerWidth)); switch (*mode) { case YGMeasureModeExactly: case YGMeasureModeAtMost: *size = (maxSize.isUndefined() || *size < maxSize.unwrap()) - ? *size - : maxSize.unwrap(); + ? *size + : maxSize.unwrap(); break; case YGMeasureModeUndefined: if (!maxSize.isUndefined()) { @@ -1134,12 +1259,20 @@ static void YGConstrainMaxSizeForMode(const YGNodeConstRef node, } static void YGNodeComputeFlexBasisForChild( - const YGNodeRef node, const YGNodeRef child, const float width, - const YGMeasureMode widthMode, const float height, const float ownerWidth, - const float ownerHeight, const YGMeasureMode heightMode, - const YGDirection direction, const YGConfigRef config, - LayoutData& layoutMarkerData, void* const layoutContext, - const uint32_t depth, const uint32_t generationCount) { + const YGNodeRef node, + const YGNodeRef child, + const float width, + const YGMeasureMode widthMode, + const float height, + const float ownerWidth, + const float ownerHeight, + const YGMeasureMode heightMode, + const YGDirection direction, + const YGConfigRef config, + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { const YGFlexDirection mainAxis = YGResolveFlexDirection(node->getStyle().flexDirection(), direction); const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis); @@ -1174,8 +1307,8 @@ static void YGNodeComputeFlexBasisForChild( YGNodePaddingAndBorderForAxis(child, YGFlexDirectionRow, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( - YGResolveValue(child->getResolvedDimensions()[YGDimensionWidth], - ownerWidth), + YGResolveValue( + child->getResolvedDimensions()[YGDimensionWidth], ownerWidth), paddingAndBorder)); } else if (!isMainAxisRow && isColumnStyleDimDefined) { // The height is definite, so use that as the flex basis. @@ -1183,8 +1316,8 @@ static void YGNodeComputeFlexBasisForChild( YGFloatOptional(YGNodePaddingAndBorderForAxis( child, YGFlexDirectionColumn, ownerWidth)); child->setLayoutComputedFlexBasis(YGFloatOptionalMax( - YGResolveValue(child->getResolvedDimensions()[YGDimensionHeight], - ownerHeight), + YGResolveValue( + child->getResolvedDimensions()[YGDimensionHeight], ownerHeight), paddingAndBorder)); } else { // Compute the flex basis and hypothetical main size (i.e. the clamped flex @@ -1201,16 +1334,16 @@ static void YGNodeComputeFlexBasisForChild( if (isRowStyleDimDefined) { childWidth = - YGResolveValue(child->getResolvedDimensions()[YGDimensionWidth], - ownerWidth) + YGResolveValue( + child->getResolvedDimensions()[YGDimensionWidth], ownerWidth) .unwrap() + marginRow; childWidthMeasureMode = YGMeasureModeExactly; } if (isColumnStyleDimDefined) { childHeight = - YGResolveValue(child->getResolvedDimensions()[YGDimensionHeight], - ownerHeight) + YGResolveValue( + child->getResolvedDimensions()[YGDimensionHeight], ownerHeight) .unwrap() + marginColumn; childHeightMeasureMode = YGMeasureModeExactly; @@ -1237,13 +1370,13 @@ static void YGNodeComputeFlexBasisForChild( const auto& childStyle = child->getStyle(); if (!childStyle.aspectRatio().isUndefined()) { if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) { - childHeight = marginColumn + (childWidth - marginRow) / - childStyle.aspectRatio().unwrap(); + childHeight = marginColumn + + (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); childHeightMeasureMode = YGMeasureModeExactly; - } else if (isMainAxisRow && - childHeightMeasureMode == YGMeasureModeExactly) { - childWidth = marginRow + (childHeight - marginColumn) * - childStyle.aspectRatio().unwrap(); + } else if ( + isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) { + childWidth = marginRow + + (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); childWidthMeasureMode = YGMeasureModeExactly; } } @@ -1284,18 +1417,38 @@ static void YGNodeComputeFlexBasisForChild( } } - YGConstrainMaxSizeForMode(child, YGFlexDirectionRow, ownerWidth, ownerWidth, - &childWidthMeasureMode, &childWidth); - YGConstrainMaxSizeForMode(child, YGFlexDirectionColumn, ownerHeight, - ownerWidth, &childHeightMeasureMode, - &childHeight); + YGConstrainMaxSizeForMode( + child, + YGFlexDirectionRow, + ownerWidth, + ownerWidth, + &childWidthMeasureMode, + &childWidth); + YGConstrainMaxSizeForMode( + child, + YGFlexDirectionColumn, + ownerHeight, + ownerWidth, + &childHeightMeasureMode, + &childHeight); // Measure the child YGLayoutNodeInternal( - child, childWidth, childHeight, direction, childWidthMeasureMode, - childHeightMeasureMode, ownerWidth, ownerHeight, false, - LayoutPassReason::kMeasureChild, config, layoutMarkerData, - layoutContext, depth, generationCount); + child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + ownerWidth, + ownerHeight, + false, + LayoutPassReason::kMeasureChild, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax( child->getLayout().measuredDimensions[dim[mainAxis]], @@ -1305,11 +1458,17 @@ static void YGNodeComputeFlexBasisForChild( } static void YGNodeAbsoluteLayoutChild( - const YGNodeRef node, const YGNodeRef child, const float width, - const YGMeasureMode widthMode, const float height, - const YGDirection direction, const YGConfigRef config, - LayoutData& layoutMarkerData, void* const layoutContext, - const uint32_t depth, const uint32_t generationCount) { + const YGNodeRef node, + const YGNodeRef child, + const float width, + const YGMeasureMode widthMode, + const float height, + const YGDirection direction, + const YGConfigRef config, + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { const YGFlexDirection mainAxis = YGResolveFlexDirection(node->getStyle().flexDirection(), direction); const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction); @@ -1335,11 +1494,11 @@ static void YGNodeAbsoluteLayoutChild( if (child->isLeadingPositionDefined(YGFlexDirectionRow) && child->isTrailingPosDefined(YGFlexDirectionRow)) { childWidth = node->getLayout().measuredDimensions[YGDimensionWidth] - - (node->getLeadingBorder(YGFlexDirectionRow) + - node->getTrailingBorder(YGFlexDirectionRow)) - - (child->getLeadingPosition(YGFlexDirectionRow, width) + - child->getTrailingPosition(YGFlexDirectionRow, width)) - .unwrap(); + (node->getLeadingBorder(YGFlexDirectionRow) + + node->getTrailingBorder(YGFlexDirectionRow)) - + (child->getLeadingPosition(YGFlexDirectionRow, width) + + child->getTrailingPosition(YGFlexDirectionRow, width)) + .unwrap(); childWidth = YGNodeBoundAxis(child, YGFlexDirectionRow, childWidth, width, width); } @@ -1349,20 +1508,20 @@ static void YGNodeAbsoluteLayoutChild( childHeight = YGResolveValue( child->getResolvedDimensions()[YGDimensionHeight], height) .unwrap() + - marginColumn; + marginColumn; } else { // If the child doesn't have a specified height, compute the height based on // the top/bottom offsets if they're defined. if (child->isLeadingPositionDefined(YGFlexDirectionColumn) && child->isTrailingPosDefined(YGFlexDirectionColumn)) { childHeight = node->getLayout().measuredDimensions[YGDimensionHeight] - - (node->getLeadingBorder(YGFlexDirectionColumn) + - node->getTrailingBorder(YGFlexDirectionColumn)) - - (child->getLeadingPosition(YGFlexDirectionColumn, height) + - child->getTrailingPosition(YGFlexDirectionColumn, height)) - .unwrap(); - childHeight = YGNodeBoundAxis(child, YGFlexDirectionColumn, childHeight, - height, width); + (node->getLeadingBorder(YGFlexDirectionColumn) + + node->getTrailingBorder(YGFlexDirectionColumn)) - + (child->getLeadingPosition(YGFlexDirectionColumn, height) + + child->getTrailingPosition(YGFlexDirectionColumn, height)) + .unwrap(); + childHeight = YGNodeBoundAxis( + child, YGFlexDirectionColumn, childHeight, height, width); } } @@ -1373,11 +1532,11 @@ static void YGNodeAbsoluteLayoutChild( if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) { if (!childStyle.aspectRatio().isUndefined()) { if (YGFloatIsUndefined(childWidth)) { - childWidth = marginRow + (childHeight - marginColumn) * - childStyle.aspectRatio().unwrap(); + childWidth = marginRow + + (childHeight - marginColumn) * childStyle.aspectRatio().unwrap(); } else if (YGFloatIsUndefined(childHeight)) { - childHeight = marginColumn + (childWidth - marginRow) / - childStyle.aspectRatio().unwrap(); + childHeight = marginColumn + + (childWidth - marginRow) / childStyle.aspectRatio().unwrap(); } } } @@ -1385,11 +1544,11 @@ static void YGNodeAbsoluteLayoutChild( // If we're still missing one or the other dimension, measure the content. if (YGFloatIsUndefined(childWidth) || YGFloatIsUndefined(childHeight)) { childWidthMeasureMode = YGFloatIsUndefined(childWidth) - ? YGMeasureModeUndefined - : YGMeasureModeExactly; + ? YGMeasureModeUndefined + : YGMeasureModeExactly; childHeightMeasureMode = YGFloatIsUndefined(childHeight) - ? YGMeasureModeUndefined - : YGMeasureModeExactly; + ? YGMeasureModeUndefined + : YGMeasureModeExactly; // If the size of the owner is defined then try to constrain the absolute // child to that size as well. This allows text within the absolute child to @@ -1403,21 +1562,43 @@ static void YGNodeAbsoluteLayoutChild( } YGLayoutNodeInternal( - child, childWidth, childHeight, direction, childWidthMeasureMode, - childHeightMeasureMode, childWidth, childHeight, false, - LayoutPassReason::kAbsMeasureChild, config, layoutMarkerData, - layoutContext, depth, generationCount); + child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + childWidth, + childHeight, + false, + LayoutPassReason::kAbsMeasureChild, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] + - child->getMarginForAxis(YGFlexDirectionRow, width).unwrap(); - childHeight = - child->getLayout().measuredDimensions[YGDimensionHeight] + + child->getMarginForAxis(YGFlexDirectionRow, width).unwrap(); + childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] + child->getMarginForAxis(YGFlexDirectionColumn, width).unwrap(); } - YGLayoutNodeInternal(child, childWidth, childHeight, direction, - YGMeasureModeExactly, YGMeasureModeExactly, childWidth, - childHeight, true, LayoutPassReason::kAbsLayout, config, - layoutMarkerData, layoutContext, depth, generationCount); + YGLayoutNodeInternal( + child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + childWidth, + childHeight, + true, + LayoutPassReason::kAbsLayout, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); if (child->isTrailingPosDefined(mainAxis) && !child->isLeadingPositionDefined(mainAxis)) { @@ -1429,15 +1610,17 @@ static void YGNodeAbsoluteLayoutChild( child->getTrailingPosition(mainAxis, isMainAxisRow ? width : height) .unwrap(), leading[mainAxis]); - } else if (!child->isLeadingPositionDefined(mainAxis) && - node->getStyle().justifyContent() == YGJustifyCenter) { + } else if ( + !child->isLeadingPositionDefined(mainAxis) && + node->getStyle().justifyContent() == YGJustifyCenter) { child->setLayoutPosition( (node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]]) / 2.0f, leading[mainAxis]); - } else if (!child->isLeadingPositionDefined(mainAxis) && - node->getStyle().justifyContent() == YGJustifyFlexEnd) { + } else if ( + !child->isLeadingPositionDefined(mainAxis) && + node->getStyle().justifyContent() == YGJustifyFlexEnd) { child->setLayoutPosition( (node->getLayout().measuredDimensions[dim[mainAxis]] - child->getLayout().measuredDimensions[dim[mainAxis]]), @@ -1456,16 +1639,18 @@ static void YGNodeAbsoluteLayoutChild( .unwrap(), leading[crossAxis]); - } else if (!child->isLeadingPositionDefined(crossAxis) && - YGNodeAlignItem(node, child) == YGAlignCenter) { + } else if ( + !child->isLeadingPositionDefined(crossAxis) && + YGNodeAlignItem(node, child) == YGAlignCenter) { child->setLayoutPosition( (node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]]) / 2.0f, leading[crossAxis]); - } else if (!child->isLeadingPositionDefined(crossAxis) && - ((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^ - (node->getStyle().flexWrap() == YGWrapWrapReverse))) { + } else if ( + !child->isLeadingPositionDefined(crossAxis) && + ((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^ + (node->getStyle().flexWrap() == YGWrapWrapReverse))) { child->setLayoutPosition( (node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().measuredDimensions[dim[crossAxis]]), @@ -1474,53 +1659,75 @@ static void YGNodeAbsoluteLayoutChild( } static void YGNodeWithMeasureFuncSetMeasuredDimensions( - const YGNodeRef node, const float availableWidth, - const float availableHeight, const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, const float ownerWidth, - const float ownerHeight, LayoutData& layoutMarkerData, - void* const layoutContext, const LayoutPassReason reason) { - YGAssertWithNode(node, node->hasMeasureFunc(), - "Expected node to have custom measure function"); + const YGNodeRef node, + float availableWidth, + float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + LayoutData& layoutMarkerData, + void* const layoutContext, + const LayoutPassReason reason) { + YGAssertWithNode( + node, + node->hasMeasureFunc(), + "Expected node to have custom measure function"); + + if (widthMeasureMode == YGMeasureModeUndefined) { + availableWidth = YGUndefined; + } + if (heightMeasureMode == YGMeasureModeUndefined) { + availableHeight = YGUndefined; + } const float paddingAndBorderAxisRow = - YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth); - const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis( - node, YGFlexDirectionColumn, availableWidth); + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); + const float paddingAndBorderAxisColumn = + YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth); const float marginAxisRow = - node->getMarginForAxis(YGFlexDirectionRow, availableWidth).unwrap(); + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); const float marginAxisColumn = - node->getMarginForAxis(YGFlexDirectionColumn, availableWidth).unwrap(); + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); // We want to make sure we don't call measure with negative size const float innerWidth = YGFloatIsUndefined(availableWidth) - ? availableWidth - : YGFloatMax(0, availableWidth - marginAxisRow - - paddingAndBorderAxisRow); - const float innerHeight = - YGFloatIsUndefined(availableHeight) - ? availableHeight - : YGFloatMax(0, availableHeight - marginAxisColumn - - paddingAndBorderAxisColumn); + ? availableWidth + : YGFloatMax(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow); + const float innerHeight = YGFloatIsUndefined(availableHeight) + ? availableHeight + : YGFloatMax( + 0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn); if (widthMeasureMode == YGMeasureModeExactly && heightMeasureMode == YGMeasureModeExactly) { // Don't bother sizing the text if both dimensions are already defined. node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionRow, - availableWidth - marginAxisRow, ownerWidth, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), YGDimensionWidth); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionColumn, - availableHeight - marginAxisColumn, ownerHeight, - ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), YGDimensionHeight); } else { Event::publish(node); // Measure the text under the current constraints. - const YGSize measuredSize = - node->measure(innerWidth, widthMeasureMode, innerHeight, - heightMeasureMode, layoutContext); + const YGSize measuredSize = node->measure( + innerWidth, + widthMeasureMode, + innerHeight, + heightMeasureMode, + layoutContext); layoutMarkerData.measureCallbacks += 1; layoutMarkerData.measureCallbackReasonsCount[static_cast(reason)] += @@ -1528,25 +1735,37 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( Event::publish( node, - {layoutContext, innerWidth, widthMeasureMode, innerHeight, - heightMeasureMode, measuredSize.width, measuredSize.height, reason}); + {layoutContext, + innerWidth, + widthMeasureMode, + innerHeight, + heightMeasureMode, + measuredSize.width, + measuredSize.height, + reason}); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionRow, - (widthMeasureMode == YGMeasureModeUndefined || - widthMeasureMode == YGMeasureModeAtMost) - ? measuredSize.width + paddingAndBorderAxisRow - : availableWidth - marginAxisRow, - ownerWidth, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + (widthMeasureMode == YGMeasureModeUndefined || + widthMeasureMode == YGMeasureModeAtMost) + ? measuredSize.width + paddingAndBorderAxisRow + : availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), YGDimensionWidth); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionColumn, - (heightMeasureMode == YGMeasureModeUndefined || - heightMeasureMode == YGMeasureModeAtMost) - ? measuredSize.height + paddingAndBorderAxisColumn - : availableHeight - marginAxisColumn, - ownerHeight, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + (heightMeasureMode == YGMeasureModeUndefined || + heightMeasureMode == YGMeasureModeAtMost) + ? measuredSize.height + paddingAndBorderAxisColumn + : availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), YGDimensionHeight); } } @@ -1554,9 +1773,12 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions( // For nodes with no children, use the available values if they were provided, // or the minimum size as indicated by the padding and border sizes. static void YGNodeEmptyContainerSetMeasuredDimensions( - const YGNodeRef node, const float availableWidth, - const float availableHeight, const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, const float ownerWidth, + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, const float ownerHeight) { const float paddingAndBorderAxisRow = YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth); @@ -1568,28 +1790,37 @@ static void YGNodeEmptyContainerSetMeasuredDimensions( node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap(); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionRow, - (widthMeasureMode == YGMeasureModeUndefined || - widthMeasureMode == YGMeasureModeAtMost) - ? paddingAndBorderAxisRow - : availableWidth - marginAxisRow, - ownerWidth, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + (widthMeasureMode == YGMeasureModeUndefined || + widthMeasureMode == YGMeasureModeAtMost) + ? paddingAndBorderAxisRow + : availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), YGDimensionWidth); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionColumn, - (heightMeasureMode == YGMeasureModeUndefined || - heightMeasureMode == YGMeasureModeAtMost) - ? paddingAndBorderAxisColumn - : availableHeight - marginAxisColumn, - ownerHeight, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + (heightMeasureMode == YGMeasureModeUndefined || + heightMeasureMode == YGMeasureModeAtMost) + ? paddingAndBorderAxisColumn + : availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), YGDimensionHeight); } static bool YGNodeFixedSizeSetMeasuredDimensions( - const YGNodeRef node, const float availableWidth, - const float availableHeight, const YGMeasureMode widthMeasureMode, - const YGMeasureMode heightMeasureMode, const float ownerWidth, + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, const float ownerHeight) { if ((!YGFloatIsUndefined(availableWidth) && widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) || @@ -1603,23 +1834,29 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap(); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionRow, - YGFloatIsUndefined(availableWidth) || - (widthMeasureMode == YGMeasureModeAtMost && - availableWidth < 0.0f) - ? 0.0f - : availableWidth - marginAxisRow, - ownerWidth, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + YGFloatIsUndefined(availableWidth) || + (widthMeasureMode == YGMeasureModeAtMost && + availableWidth < 0.0f) + ? 0.0f + : availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), YGDimensionWidth); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionColumn, - YGFloatIsUndefined(availableHeight) || - (heightMeasureMode == YGMeasureModeAtMost && - availableHeight < 0.0f) - ? 0.0f - : availableHeight - marginAxisColumn, - ownerHeight, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + YGFloatIsUndefined(availableHeight) || + (heightMeasureMode == YGMeasureModeAtMost && + availableHeight < 0.0f) + ? 0.0f + : availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), YGDimensionHeight); return true; } @@ -1627,29 +1864,33 @@ static bool YGNodeFixedSizeSetMeasuredDimensions( return false; } -static void YGZeroOutLayoutRecursivly(const YGNodeRef node, - void* layoutContext) { +static void YGZeroOutLayoutRecursivly( + const YGNodeRef node, + void* layoutContext) { node->getLayout() = {}; node->setLayoutDimension(0, 0); node->setLayoutDimension(0, 1); node->setHasNewLayout(true); - node->iterChildrenAfterCloningIfNeeded(YGZeroOutLayoutRecursivly, - layoutContext); + node->iterChildrenAfterCloningIfNeeded( + YGZeroOutLayoutRecursivly, layoutContext); } -static float YGNodeCalculateAvailableInnerDim(const YGNodeConstRef node, - YGFlexDirection axis, - float availableDim, - float ownerDim) { +static float YGNodeCalculateAvailableInnerDim( + const YGNodeConstRef node, + YGFlexDirection axis, + float availableDim, + float ownerDim, + float ownerDimForMarginPadding) { YGFlexDirection direction = YGFlexDirectionIsRow(axis) ? YGFlexDirectionRow : YGFlexDirectionColumn; YGDimension dimension = YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight; - const float margin = node->getMarginForAxis(direction, ownerDim).unwrap(); + const float margin = + node->getMarginForAxis(direction, ownerDimForMarginPadding).unwrap(); const float paddingAndBorder = - YGNodePaddingAndBorderForAxis(node, direction, ownerDim); + YGNodePaddingAndBorderForAxis(node, direction, ownerDimForMarginPadding); float availableInnerDim = availableDim - margin - paddingAndBorder; // Max dimension overrides predefined dimension value; Min dimension in turn @@ -1659,18 +1900,16 @@ static float YGNodeCalculateAvailableInnerDim(const YGNodeConstRef node, // constraints const YGFloatOptional minDimensionOptional = YGResolveValue(node->getStyle().minDimensions()[dimension], ownerDim); - const float minInnerDim = - minDimensionOptional.isUndefined() - ? 0.0f - : minDimensionOptional.unwrap() - paddingAndBorder; + const float minInnerDim = minDimensionOptional.isUndefined() + ? 0.0f + : minDimensionOptional.unwrap() - paddingAndBorder; const YGFloatOptional maxDimensionOptional = YGResolveValue(node->getStyle().maxDimensions()[dimension], ownerDim); - const float maxInnerDim = - maxDimensionOptional.isUndefined() - ? FLT_MAX - : maxDimensionOptional.unwrap() - paddingAndBorder; + const float maxInnerDim = maxDimensionOptional.isUndefined() + ? FLT_MAX + : maxDimensionOptional.unwrap() - paddingAndBorder; availableInnerDim = YGFloatMax(YGFloatMin(availableInnerDim, maxInnerDim), minInnerDim); } @@ -1679,12 +1918,19 @@ static float YGNodeCalculateAvailableInnerDim(const YGNodeConstRef node, } static float YGNodeComputeFlexBasisForChildren( - const YGNodeRef node, const float availableInnerWidth, - const float availableInnerHeight, YGMeasureMode widthMeasureMode, - YGMeasureMode heightMeasureMode, YGDirection direction, - YGFlexDirection mainAxis, const YGConfigRef config, bool performLayout, - LayoutData& layoutMarkerData, void* const layoutContext, - const uint32_t depth, const uint32_t generationCount) { + const YGNodeRef node, + const float availableInnerWidth, + const float availableInnerHeight, + YGMeasureMode widthMeasureMode, + YGMeasureMode heightMeasureMode, + YGDirection direction, + YGFlexDirection mainAxis, + const YGConfigRef config, + bool performLayout, + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount) { float totalOuterFlexBasis = 0.0f; YGNodeRef singleFlexChild = nullptr; const YGVector& children = node->getChildren(); @@ -1722,13 +1968,13 @@ static float YGNodeComputeFlexBasisForChildren( // Set the initial position (relative to the owner). const YGDirection childDirection = child->resolveDirection(direction); const float mainDim = YGFlexDirectionIsRow(mainAxis) - ? availableInnerWidth - : availableInnerHeight; + ? availableInnerWidth + : availableInnerHeight; const float crossDim = YGFlexDirectionIsRow(mainAxis) - ? availableInnerHeight - : availableInnerWidth; - child->setPosition(childDirection, mainDim, crossDim, - availableInnerWidth); + ? availableInnerHeight + : availableInnerWidth; + child->setPosition( + childDirection, mainDim, crossDim, availableInnerWidth); } if (child->getStyle().positionType() == YGPositionTypeAbsolute) { @@ -1739,10 +1985,20 @@ static float YGNodeComputeFlexBasisForChildren( child->setLayoutComputedFlexBasis(YGFloatOptional(0)); } else { YGNodeComputeFlexBasisForChild( - node, child, availableInnerWidth, widthMeasureMode, - availableInnerHeight, availableInnerWidth, availableInnerHeight, - heightMeasureMode, direction, config, layoutMarkerData, layoutContext, - depth, generationCount); + node, + child, + availableInnerWidth, + widthMeasureMode, + availableInnerHeight, + availableInnerWidth, + availableInnerHeight, + heightMeasureMode, + direction, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); } totalOuterFlexBasis += @@ -1759,9 +2015,12 @@ static float YGNodeComputeFlexBasisForChildren( // YGNodeComputeFlexBasisForChildren function). This function calculates // YGCollectFlexItemsRowMeasurement static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( - const YGNodeRef& node, const YGDirection ownerDirection, - const float mainAxisownerSize, const float availableInnerWidth, - const float availableInnerMainDim, const uint32_t startOfLineIndex, + const YGNodeRef& node, + const YGDirection ownerDirection, + const float mainAxisownerSize, + const float availableInnerWidth, + const float availableInnerMainDim, + const uint32_t startOfLineIndex, const uint32_t lineCount) { YGCollectFlexItemsRowValues flexAlgoRowMeasurement = {}; flexAlgoRowMeasurement.relativeChildren.reserve(node->getChildren().size()); @@ -1783,9 +2042,11 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( const float childMarginMainAxis = child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap(); const float flexBasisWithMinAndMaxConstraints = - YGNodeBoundAxisWithinMinAndMax(child, mainAxis, - child->getLayout().computedFlexBasis, - mainAxisownerSize) + YGNodeBoundAxisWithinMinAndMax( + child, + mainAxis, + child->getLayout().computedFlexBasis, + mainAxisownerSize) .unwrap(); // If this is a multi-line flow and this item pushes us over the available @@ -1837,14 +2098,22 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues( // function the child nodes would have proper size. Prior using this function // please ensure that YGDistributeFreeSpaceFirstPass is called. static float YGDistributeFreeSpaceSecondPass( - YGCollectFlexItemsRowValues& collectedFlexItemsValues, const YGNodeRef node, - const YGFlexDirection mainAxis, const YGFlexDirection crossAxis, - const float mainAxisownerSize, const float availableInnerMainDim, - const float availableInnerCrossDim, const float availableInnerWidth, - const float availableInnerHeight, const bool flexBasisOverflows, - const YGMeasureMode measureModeCrossDim, const bool performLayout, - const YGConfigRef config, LayoutData& layoutMarkerData, - void* const layoutContext, const uint32_t depth, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, + const YGNodeRef node, + const YGFlexDirection mainAxis, + const YGFlexDirection crossAxis, + const float mainAxisownerSize, + const float availableInnerMainDim, + const float availableInnerCrossDim, + const float availableInnerWidth, + const float availableInnerHeight, + const bool flexBasisOverflows, + const YGMeasureMode measureModeCrossDim, + const bool performLayout, + const YGConfigRef config, + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, const uint32_t generationCount) { float childFlexBasis = 0; float flexShrinkScaledFactor = 0; @@ -1855,7 +2124,8 @@ static float YGDistributeFreeSpaceSecondPass( for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { childFlexBasis = YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, mainAxis, + currentRelativeChild, + mainAxis, currentRelativeChild->getLayout().computedFlexBasis, mainAxisownerSize) .unwrap(); @@ -1875,28 +2145,34 @@ static float YGDistributeFreeSpaceSecondPass( childSize = childFlexBasis + flexShrinkScaledFactor; } else { childSize = childFlexBasis + - (collectedFlexItemsValues.remainingFreeSpace / - collectedFlexItemsValues.totalFlexShrinkScaledFactors) * - flexShrinkScaledFactor; + (collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.totalFlexShrinkScaledFactors) * + flexShrinkScaledFactor; } - updatedMainSize = - YGNodeBoundAxis(currentRelativeChild, mainAxis, childSize, - availableInnerMainDim, availableInnerWidth); + updatedMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + childSize, + availableInnerMainDim, + availableInnerWidth); } - } else if (!YGFloatIsUndefined( - collectedFlexItemsValues.remainingFreeSpace) && - collectedFlexItemsValues.remainingFreeSpace > 0) { + } else if ( + !YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && + collectedFlexItemsValues.remainingFreeSpace > 0) { flexGrowFactor = currentRelativeChild->resolveFlexGrow(); // Is this child able to grow? if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) { updatedMainSize = YGNodeBoundAxis( - currentRelativeChild, mainAxis, - childFlexBasis + collectedFlexItemsValues.remainingFreeSpace / - collectedFlexItemsValues.totalFlexGrowFactors * - flexGrowFactor, - availableInnerMainDim, availableInnerWidth); + currentRelativeChild, + mainAxis, + childFlexBasis + + collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.totalFlexGrowFactors * + flexGrowFactor, + availableInnerMainDim, + availableInnerWidth); } } @@ -1916,31 +2192,31 @@ static float YGDistributeFreeSpaceSecondPass( const auto& childStyle = currentRelativeChild->getStyle(); if (!childStyle.aspectRatio().isUndefined()) { - childCrossSize = isMainAxisRow ? (childMainSize - marginMain) / - childStyle.aspectRatio().unwrap() - : (childMainSize - marginMain) * - childStyle.aspectRatio().unwrap(); + childCrossSize = isMainAxisRow + ? (childMainSize - marginMain) / childStyle.aspectRatio().unwrap() + : (childMainSize - marginMain) * childStyle.aspectRatio().unwrap(); childCrossMeasureMode = YGMeasureModeExactly; childCrossSize += marginCross; - } else if (!YGFloatIsUndefined(availableInnerCrossDim) && - !YGNodeIsStyleDimDefined(currentRelativeChild, crossAxis, - availableInnerCrossDim) && - measureModeCrossDim == YGMeasureModeExactly && - !(isNodeFlexWrap && flexBasisOverflows) && - YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch && - currentRelativeChild->marginLeadingValue(crossAxis).unit != - YGUnitAuto && - currentRelativeChild->marginTrailingValue(crossAxis).unit != - YGUnitAuto) { + } else if ( + !YGFloatIsUndefined(availableInnerCrossDim) && + !YGNodeIsStyleDimDefined( + currentRelativeChild, crossAxis, availableInnerCrossDim) && + measureModeCrossDim == YGMeasureModeExactly && + !(isNodeFlexWrap && flexBasisOverflows) && + YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch && + currentRelativeChild->marginLeadingValue(crossAxis).unit != + YGUnitAuto && + currentRelativeChild->marginTrailingValue(crossAxis).unit != + YGUnitAuto) { childCrossSize = availableInnerCrossDim; childCrossMeasureMode = YGMeasureModeExactly; - } else if (!YGNodeIsStyleDimDefined(currentRelativeChild, crossAxis, - availableInnerCrossDim)) { + } else if (!YGNodeIsStyleDimDefined( + currentRelativeChild, crossAxis, availableInnerCrossDim)) { childCrossSize = availableInnerCrossDim; childCrossMeasureMode = YGFloatIsUndefined(childCrossSize) - ? YGMeasureModeUndefined - : YGMeasureModeAtMost; + ? YGMeasureModeUndefined + : YGMeasureModeAtMost; } else { childCrossSize = YGResolveValue( @@ -1954,20 +2230,28 @@ static float YGDistributeFreeSpaceSecondPass( measureModeCrossDim != YGMeasureModeExactly; childCrossMeasureMode = YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement - ? YGMeasureModeUndefined - : YGMeasureModeExactly; + ? YGMeasureModeUndefined + : YGMeasureModeExactly; } - YGConstrainMaxSizeForMode(currentRelativeChild, mainAxis, - availableInnerMainDim, availableInnerWidth, - &childMainMeasureMode, &childMainSize); - YGConstrainMaxSizeForMode(currentRelativeChild, crossAxis, - availableInnerCrossDim, availableInnerWidth, - &childCrossMeasureMode, &childCrossSize); + YGConstrainMaxSizeForMode( + currentRelativeChild, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainMeasureMode, + &childMainSize); + YGConstrainMaxSizeForMode( + currentRelativeChild, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossMeasureMode, + &childCrossSize); const bool requiresStretchLayout = - !YGNodeIsStyleDimDefined(currentRelativeChild, crossAxis, - availableInnerCrossDim) && + !YGNodeIsStyleDimDefined( + currentRelativeChild, crossAxis, availableInnerCrossDim) && YGNodeAlignItem(node, currentRelativeChild) == YGAlignStretch && currentRelativeChild->marginLeadingValue(crossAxis).unit != YGUnitAuto && @@ -1984,16 +2268,26 @@ static float YGDistributeFreeSpaceSecondPass( const bool isLayoutPass = performLayout && !requiresStretchLayout; // Recursively call the layout algorithm for this child with the updated // main size. - YGLayoutNodeInternal(currentRelativeChild, childWidth, childHeight, - node->getLayout().direction(), childWidthMeasureMode, - childHeightMeasureMode, availableInnerWidth, - availableInnerHeight, isLayoutPass, - isLayoutPass ? LayoutPassReason::kFlexLayout - : LayoutPassReason::kFlexMeasure, - config, layoutMarkerData, layoutContext, depth, - generationCount); - node->setLayoutHadOverflow(node->getLayout().hadOverflow() | - currentRelativeChild->getLayout().hadOverflow()); + YGLayoutNodeInternal( + currentRelativeChild, + childWidth, + childHeight, + node->getLayout().direction(), + childWidthMeasureMode, + childHeightMeasureMode, + availableInnerWidth, + availableInnerHeight, + isLayoutPass, + isLayoutPass ? LayoutPassReason::kFlexLayout + : LayoutPassReason::kFlexMeasure, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); + node->setLayoutHadOverflow( + node->getLayout().hadOverflow() | + currentRelativeChild->getLayout().hadOverflow()); } return deltaFreeSpace; } @@ -2003,8 +2297,10 @@ static float YGDistributeFreeSpaceSecondPass( // is removed from the remaingfreespace. static void YGDistributeFreeSpaceFirstPass( YGCollectFlexItemsRowValues& collectedFlexItemsValues, - const YGFlexDirection mainAxis, const float mainAxisownerSize, - const float availableInnerMainDim, const float availableInnerWidth) { + const YGFlexDirection mainAxis, + const float mainAxisownerSize, + const float availableInnerMainDim, + const float availableInnerWidth) { float flexShrinkScaledFactor = 0; float flexGrowFactor = 0; float baseMainSize = 0; @@ -2014,7 +2310,8 @@ static void YGDistributeFreeSpaceFirstPass( for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) { float childFlexBasis = YGNodeBoundAxisWithinMinAndMax( - currentRelativeChild, mainAxis, + currentRelativeChild, + mainAxis, currentRelativeChild->getLayout().computedFlexBasis, mainAxisownerSize) .unwrap(); @@ -2026,14 +2323,16 @@ static void YGDistributeFreeSpaceFirstPass( // Is this child able to shrink? if (!YGFloatIsUndefined(flexShrinkScaledFactor) && flexShrinkScaledFactor != 0) { - baseMainSize = - childFlexBasis + + baseMainSize = childFlexBasis + collectedFlexItemsValues.remainingFreeSpace / collectedFlexItemsValues.totalFlexShrinkScaledFactors * flexShrinkScaledFactor; - boundMainSize = - YGNodeBoundAxis(currentRelativeChild, mainAxis, baseMainSize, - availableInnerMainDim, availableInnerWidth); + boundMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); if (!YGFloatIsUndefined(baseMainSize) && !YGFloatIsUndefined(boundMainSize) && baseMainSize != boundMainSize) { @@ -2043,23 +2342,26 @@ static void YGDistributeFreeSpaceFirstPass( // first and second passes. deltaFreeSpace += boundMainSize - childFlexBasis; collectedFlexItemsValues.totalFlexShrinkScaledFactors -= - flexShrinkScaledFactor; + (-currentRelativeChild->resolveFlexShrink() * + currentRelativeChild->getLayout().computedFlexBasis.unwrap()); } } - } else if (!YGFloatIsUndefined( - collectedFlexItemsValues.remainingFreeSpace) && - collectedFlexItemsValues.remainingFreeSpace > 0) { + } else if ( + !YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) && + collectedFlexItemsValues.remainingFreeSpace > 0) { flexGrowFactor = currentRelativeChild->resolveFlexGrow(); // Is this child able to grow? if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) { - baseMainSize = - childFlexBasis + collectedFlexItemsValues.remainingFreeSpace / - collectedFlexItemsValues.totalFlexGrowFactors * - flexGrowFactor; - boundMainSize = - YGNodeBoundAxis(currentRelativeChild, mainAxis, baseMainSize, - availableInnerMainDim, availableInnerWidth); + baseMainSize = childFlexBasis + + collectedFlexItemsValues.remainingFreeSpace / + collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor; + boundMainSize = YGNodeBoundAxis( + currentRelativeChild, + mainAxis, + baseMainSize, + availableInnerMainDim, + availableInnerWidth); if (!YGFloatIsUndefined(baseMainSize) && !YGFloatIsUndefined(boundMainSize) && @@ -2100,27 +2402,50 @@ static void YGDistributeFreeSpaceFirstPass( // assigned to them. // static void YGResolveFlexibleLength( - const YGNodeRef node, YGCollectFlexItemsRowValues& collectedFlexItemsValues, - const YGFlexDirection mainAxis, const YGFlexDirection crossAxis, - const float mainAxisownerSize, const float availableInnerMainDim, - const float availableInnerCrossDim, const float availableInnerWidth, - const float availableInnerHeight, const bool flexBasisOverflows, - const YGMeasureMode measureModeCrossDim, const bool performLayout, - const YGConfigRef config, LayoutData& layoutMarkerData, - void* const layoutContext, const uint32_t depth, + const YGNodeRef node, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, + const YGFlexDirection mainAxis, + const YGFlexDirection crossAxis, + const float mainAxisownerSize, + const float availableInnerMainDim, + const float availableInnerCrossDim, + const float availableInnerWidth, + const float availableInnerHeight, + const bool flexBasisOverflows, + const YGMeasureMode measureModeCrossDim, + const bool performLayout, + const YGConfigRef config, + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, const uint32_t generationCount) { const float originalFreeSpace = collectedFlexItemsValues.remainingFreeSpace; // First pass: detect the flex items whose min/max constraints trigger - YGDistributeFreeSpaceFirstPass(collectedFlexItemsValues, mainAxis, - mainAxisownerSize, availableInnerMainDim, - availableInnerWidth); + YGDistributeFreeSpaceFirstPass( + collectedFlexItemsValues, + mainAxis, + mainAxisownerSize, + availableInnerMainDim, + availableInnerWidth); // Second pass: resolve the sizes of the flexible items const float distributedFreeSpace = YGDistributeFreeSpaceSecondPass( - collectedFlexItemsValues, node, mainAxis, crossAxis, mainAxisownerSize, - availableInnerMainDim, availableInnerCrossDim, availableInnerWidth, - availableInnerHeight, flexBasisOverflows, measureModeCrossDim, - performLayout, config, layoutMarkerData, layoutContext, depth, + collectedFlexItemsValues, + node, + mainAxis, + crossAxis, + mainAxisownerSize, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + availableInnerHeight, + flexBasisOverflows, + measureModeCrossDim, + performLayout, + config, + layoutMarkerData, + layoutContext, + depth, generationCount); collectedFlexItemsValues.remainingFreeSpace = @@ -2128,13 +2453,20 @@ static void YGResolveFlexibleLength( } static void YGJustifyMainAxis( - const YGNodeRef node, YGCollectFlexItemsRowValues& collectedFlexItemsValues, - const uint32_t startOfLineIndex, const YGFlexDirection mainAxis, - const YGFlexDirection crossAxis, const YGMeasureMode measureModeMainDim, - const YGMeasureMode measureModeCrossDim, const float mainAxisownerSize, - const float ownerWidth, const float availableInnerMainDim, - const float availableInnerCrossDim, const float availableInnerWidth, - const bool performLayout, void* const layoutContext) { + const YGNodeRef node, + YGCollectFlexItemsRowValues& collectedFlexItemsValues, + const uint32_t startOfLineIndex, + const YGFlexDirection mainAxis, + const YGFlexDirection crossAxis, + const YGMeasureMode measureModeMainDim, + const YGMeasureMode measureModeCrossDim, + const float mainAxisownerSize, + const float ownerWidth, + const float availableInnerMainDim, + const float availableInnerCrossDim, + const float availableInnerWidth, + const bool performLayout, + void* const layoutContext) { const auto& style = node->getStyle(); const float leadingPaddingAndBorderMain = node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap(); @@ -2155,8 +2487,8 @@ 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 = - YGResolveValue(style.minDimensions()[dim[mainAxis]], - mainAxisownerSize) + YGResolveValue( + style.minDimensions()[dim[mainAxis]], mainAxisownerSize) .unwrap() - leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; const float occupiedSpaceByChildNodes = @@ -2170,9 +2502,10 @@ static void YGJustifyMainAxis( int numberOfAutoMarginsOnCurrentLine = 0; for (uint32_t i = startOfLineIndex; - i < collectedFlexItemsValues.endOfLineIndex; i++) { + i < collectedFlexItemsValues.endOfLineIndex; + i++) { const YGNodeRef child = node->getChild(i); - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) { numberOfAutoMarginsOnCurrentLine++; } @@ -2209,13 +2542,13 @@ static void YGJustifyMainAxis( case YGJustifySpaceEvenly: // Space is distributed evenly across all elements betweenMainDim = collectedFlexItemsValues.remainingFreeSpace / - (collectedFlexItemsValues.itemsOnLine + 1); + (collectedFlexItemsValues.itemsOnLine + 1); leadingMainDim = betweenMainDim; break; case YGJustifySpaceAround: // Space on the edges is half of the space between elements betweenMainDim = collectedFlexItemsValues.remainingFreeSpace / - collectedFlexItemsValues.itemsOnLine; + collectedFlexItemsValues.itemsOnLine; leadingMainDim = betweenMainDim / 2; break; case YGJustifyFlexStart: @@ -2231,7 +2564,8 @@ static void YGJustifyMainAxis( float maxDescentForCurrentLine = 0; bool isNodeBaselineLayout = YGIsBaselineLayout(node); for (uint32_t i = startOfLineIndex; - i < collectedFlexItemsValues.endOfLineIndex; i++) { + i < collectedFlexItemsValues.endOfLineIndex; + i++) { const YGNodeRef child = node->getChild(i); const YGStyle& childStyle = child->getStyle(); const YGLayout childLayout = child->getLayout(); @@ -2255,7 +2589,7 @@ static void YGJustifyMainAxis( // Now that we placed the element, we need to update the variables. // We need to do that only for relative elements. Absolute elements do not // take part in that phase. - if (childStyle.positionType() == YGPositionTypeRelative) { + if (childStyle.positionType() != YGPositionTypeAbsolute) { if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) { collectedFlexItemsValues.mainDim += collectedFlexItemsValues.remainingFreeSpace / @@ -2263,9 +2597,10 @@ static void YGJustifyMainAxis( } if (performLayout) { - child->setLayoutPosition(childLayout.position[pos[mainAxis]] + - collectedFlexItemsValues.mainDim, - pos[mainAxis]); + child->setLayoutPosition( + childLayout.position[pos[mainAxis]] + + collectedFlexItemsValues.mainDim, + pos[mainAxis]); } if (child->marginTrailingValue(mainAxis).unit == YGUnitAuto) { @@ -2279,31 +2614,29 @@ static void YGJustifyMainAxis( // If we skipped the flex step, then we can't rely on the measuredDims // because they weren't computed. This means we can't call // YGNodeDimWithMargin. - collectedFlexItemsValues.mainDim += - betweenMainDim + + collectedFlexItemsValues.mainDim += betweenMainDim + child->getMarginForAxis(mainAxis, availableInnerWidth).unwrap() + childLayout.computedFlexBasis.unwrap(); collectedFlexItemsValues.crossDim = availableInnerCrossDim; } else { // The main dimension is the sum of all the elements dimension plus // the spacing. - collectedFlexItemsValues.mainDim += - betweenMainDim + + collectedFlexItemsValues.mainDim += betweenMainDim + YGNodeDimWithMargin(child, mainAxis, availableInnerWidth); if (isNodeBaselineLayout) { // If the child is baseline aligned then the cross dimension is // calculated by adding maxAscent and maxDescent from the baseline. const float ascent = YGBaseline(child, layoutContext) + - child - ->getLeadingMargin(YGFlexDirectionColumn, - availableInnerWidth) - .unwrap(); + child + ->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth) + .unwrap(); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + child - ->getMarginForAxis(YGFlexDirectionColumn, - availableInnerWidth) + ->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth) .unwrap() - ascent; @@ -2321,10 +2654,10 @@ static void YGJustifyMainAxis( } } } else if (performLayout) { - child->setLayoutPosition(childLayout.position[pos[mainAxis]] + - node->getLeadingBorder(mainAxis) + - leadingMainDim, - pos[mainAxis]); + child->setLayoutPosition( + childLayout.position[pos[mainAxis]] + + node->getLeadingBorder(mainAxis) + leadingMainDim, + pos[mainAxis]); } } } @@ -2402,25 +2735,35 @@ static void YGJustifyMainAxis( // mode of YGMeasureModeUndefined in that dimension. // static void YGNodelayoutImpl( - const YGNodeRef node, const float availableWidth, - const float availableHeight, const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, const YGMeasureMode heightMeasureMode, - const float ownerWidth, const float ownerHeight, const bool performLayout, - const YGConfigRef config, LayoutData& layoutMarkerData, - void* const layoutContext, const uint32_t depth, - const uint32_t generationCount, const LayoutPassReason reason) { - YGAssertWithNode(node, - YGFloatIsUndefined(availableWidth) - ? widthMeasureMode == YGMeasureModeUndefined - : true, - "availableWidth is indefinite so widthMeasureMode must be " - "YGMeasureModeUndefined"); - YGAssertWithNode(node, - YGFloatIsUndefined(availableHeight) - ? heightMeasureMode == YGMeasureModeUndefined - : true, - "availableHeight is indefinite so heightMeasureMode must be " - "YGMeasureModeUndefined"); + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const YGConfigRef config, + LayoutData& layoutMarkerData, + void* const layoutContext, + const uint32_t depth, + const uint32_t generationCount, + const LayoutPassReason reason) { + YGAssertWithNode( + node, + YGFloatIsUndefined(availableWidth) + ? widthMeasureMode == YGMeasureModeUndefined + : true, + "availableWidth is indefinite so widthMeasureMode must be " + "YGMeasureModeUndefined"); + YGAssertWithNode( + node, + YGFloatIsUndefined(availableHeight) + ? heightMeasureMode == YGMeasureModeUndefined + : true, + "availableHeight is indefinite so heightMeasureMode must be " + "YGMeasureModeUndefined"); (performLayout ? layoutMarkerData.layouts : layoutMarkerData.measures) += 1; @@ -2450,8 +2793,8 @@ static void YGNodelayoutImpl( node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), startEdge); node->setLayoutBorder(node->getTrailingBorder(flexRowDirection), endEdge); node->setLayoutBorder(node->getLeadingBorder(flexColumnDirection), YGEdgeTop); - node->setLayoutBorder(node->getTrailingBorder(flexColumnDirection), - YGEdgeBottom); + node->setLayoutBorder( + node->getTrailingBorder(flexColumnDirection), YGEdgeBottom); node->setLayoutPadding( node->getLeadingPadding(flexRowDirection, ownerWidth).unwrap(), @@ -2467,17 +2810,29 @@ static void YGNodelayoutImpl( if (node->hasMeasureFunc()) { YGNodeWithMeasureFuncSetMeasuredDimensions( - node, availableWidth, availableHeight, widthMeasureMode, - heightMeasureMode, ownerWidth, ownerHeight, layoutMarkerData, - layoutContext, reason); + node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + layoutMarkerData, + layoutContext, + reason); return; } const uint32_t childCount = YGNodeGetChildCount(node); if (childCount == 0) { YGNodeEmptyContainerSetMeasuredDimensions( - node, availableWidth, availableHeight, widthMeasureMode, - heightMeasureMode, ownerWidth, ownerHeight); + node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight); return; } @@ -2485,8 +2840,13 @@ static void YGNodelayoutImpl( // if we already know the size if (!performLayout && YGNodeFixedSizeSetMeasuredDimensions( - node, availableWidth, availableHeight, widthMeasureMode, - heightMeasureMode, ownerWidth, ownerHeight)) { + node, + availableWidth, + availableHeight, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight)) { return; } @@ -2549,9 +2909,9 @@ static void YGNodelayoutImpl( // STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS float availableInnerWidth = YGNodeCalculateAvailableInnerDim( - node, YGFlexDirectionRow, availableWidth, ownerWidth); + node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth); float availableInnerHeight = YGNodeCalculateAvailableInnerDim( - node, YGFlexDirectionColumn, availableHeight, ownerHeight); + node, YGFlexDirectionColumn, availableHeight, ownerHeight, ownerWidth); float availableInnerMainDim = isMainAxisRow ? availableInnerWidth : availableInnerHeight; @@ -2561,14 +2921,23 @@ static void YGNodelayoutImpl( // STEP 3: DETERMINE FLEX BASIS FOR EACH ITEM float totalOuterFlexBasis = YGNodeComputeFlexBasisForChildren( - node, availableInnerWidth, availableInnerHeight, widthMeasureMode, - heightMeasureMode, direction, mainAxis, config, performLayout, - layoutMarkerData, layoutContext, depth, generationCount); + node, + availableInnerWidth, + availableInnerHeight, + widthMeasureMode, + heightMeasureMode, + direction, + mainAxis, + config, + performLayout, + layoutMarkerData, + layoutContext, + depth, + generationCount); - const bool flexBasisOverflows = - measureModeMainDim == YGMeasureModeUndefined - ? false - : totalOuterFlexBasis > availableInnerMainDim; + const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined + ? false + : totalOuterFlexBasis > availableInnerMainDim; if (isNodeFlexWrap && flexBasisOverflows && measureModeMainDim == YGMeasureModeAtMost) { measureModeMainDim = YGMeasureModeExactly; @@ -2591,8 +2960,13 @@ static void YGNodelayoutImpl( for (; endOfLineIndex < childCount; lineCount++, startOfLineIndex = endOfLineIndex) { collectedFlexItemsValues = YGCalculateCollectFlexItemsRowValues( - node, ownerDirection, mainAxisownerSize, availableInnerWidth, - availableInnerMainDim, startOfLineIndex, lineCount); + node, + ownerDirection, + mainAxisownerSize, + availableInnerWidth, + availableInnerMainDim, + startOfLineIndex, + lineCount); endOfLineIndex = collectedFlexItemsValues.endOfLineIndex; // If we don't need to measure the cross axis, we can skip the entire flex @@ -2613,9 +2987,10 @@ static void YGNodelayoutImpl( collectedFlexItemsValues.sizeConsumedOnCurrentLine < minInnerMainDim) { availableInnerMainDim = minInnerMainDim; - } else if (!YGFloatIsUndefined(maxInnerMainDim) && - collectedFlexItemsValues.sizeConsumedOnCurrentLine > - maxInnerMainDim) { + } else if ( + !YGFloatIsUndefined(maxInnerMainDim) && + collectedFlexItemsValues.sizeConsumedOnCurrentLine > + maxInnerMainDim) { availableInnerMainDim = maxInnerMainDim; } else { if (!node->getConfig()->useLegacyStretchBehaviour && @@ -2639,8 +3014,7 @@ static void YGNodelayoutImpl( } if (!sizeBasedOnContent && !YGFloatIsUndefined(availableInnerMainDim)) { - collectedFlexItemsValues.remainingFreeSpace = - availableInnerMainDim - + collectedFlexItemsValues.remainingFreeSpace = availableInnerMainDim - collectedFlexItemsValues.sizeConsumedOnCurrentLine; } else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) { // availableInnerMainDim is indefinite which means the node is being sized @@ -2653,11 +3027,23 @@ static void YGNodelayoutImpl( if (!canSkipFlex) { YGResolveFlexibleLength( - node, collectedFlexItemsValues, mainAxis, crossAxis, - mainAxisownerSize, availableInnerMainDim, availableInnerCrossDim, - availableInnerWidth, availableInnerHeight, flexBasisOverflows, - measureModeCrossDim, performLayout, config, layoutMarkerData, - layoutContext, depth, generationCount); + node, + collectedFlexItemsValues, + mainAxis, + crossAxis, + mainAxisownerSize, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + availableInnerHeight, + flexBasisOverflows, + measureModeCrossDim, + performLayout, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); } node->setLayoutHadOverflow( @@ -2671,21 +3057,34 @@ static void YGNodelayoutImpl( // of items that are aligned "stretch". We need to compute these stretch // values and set the final positions. - YGJustifyMainAxis(node, collectedFlexItemsValues, startOfLineIndex, - mainAxis, crossAxis, measureModeMainDim, - measureModeCrossDim, mainAxisownerSize, ownerWidth, - availableInnerMainDim, availableInnerCrossDim, - availableInnerWidth, performLayout, layoutContext); + YGJustifyMainAxis( + node, + collectedFlexItemsValues, + startOfLineIndex, + mainAxis, + crossAxis, + measureModeMainDim, + measureModeCrossDim, + mainAxisownerSize, + ownerWidth, + availableInnerMainDim, + availableInnerCrossDim, + availableInnerWidth, + performLayout, + layoutContext); float containerCrossAxis = availableInnerCrossDim; if (measureModeCrossDim == YGMeasureModeUndefined || measureModeCrossDim == YGMeasureModeAtMost) { // Compute the cross axis from the max cross dimension of the children. - containerCrossAxis = YGNodeBoundAxis(node, crossAxis, - collectedFlexItemsValues.crossDim + - paddingAndBorderAxisCross, - crossAxisownerSize, ownerWidth) - - paddingAndBorderAxisCross; + containerCrossAxis = + YGNodeBoundAxis( + node, + crossAxis, + collectedFlexItemsValues.crossDim + paddingAndBorderAxisCross, + crossAxisownerSize, + ownerWidth) - + paddingAndBorderAxisCross; } // If there's no flex wrap, the cross dimension is defined by the container. @@ -2696,9 +3095,11 @@ static void YGNodelayoutImpl( // Clamp to the min/max size specified on the container. collectedFlexItemsValues.crossDim = YGNodeBoundAxis( - node, crossAxis, + node, + crossAxis, collectedFlexItemsValues.crossDim + paddingAndBorderAxisCross, - crossAxisownerSize, ownerWidth) - + crossAxisownerSize, + ownerWidth) - paddingAndBorderAxisCross; // STEP 7: CROSS-AXIS ALIGNMENT @@ -2750,21 +3151,18 @@ static void YGNodelayoutImpl( child->marginTrailingValue(crossAxis).unit != YGUnitAuto) { // If the child defines a definite size for its cross axis, there's // no need to stretch. - if (!YGNodeIsStyleDimDefined(child, crossAxis, - availableInnerCrossDim)) { + if (!YGNodeIsStyleDimDefined( + child, crossAxis, availableInnerCrossDim)) { float childMainSize = child->getLayout().measuredDimensions[dim[mainAxis]]; const auto& childStyle = child->getStyle(); - float childCrossSize = - !childStyle.aspectRatio().isUndefined() - ? child->getMarginForAxis(crossAxis, availableInnerWidth) - .unwrap() + - (isMainAxisRow - ? childMainSize / - childStyle.aspectRatio().unwrap() - : childMainSize * - childStyle.aspectRatio().unwrap()) - : collectedFlexItemsValues.crossDim; + float childCrossSize = !childStyle.aspectRatio().isUndefined() + ? child->getMarginForAxis(crossAxis, availableInnerWidth) + .unwrap() + + (isMainAxisRow + ? childMainSize / childStyle.aspectRatio().unwrap() + : childMainSize * childStyle.aspectRatio().unwrap()) + : collectedFlexItemsValues.crossDim; childMainSize += child->getMarginForAxis(mainAxis, availableInnerWidth) @@ -2772,12 +3170,20 @@ static void YGNodelayoutImpl( YGMeasureMode childMainMeasureMode = YGMeasureModeExactly; YGMeasureMode childCrossMeasureMode = YGMeasureModeExactly; - YGConstrainMaxSizeForMode(child, mainAxis, availableInnerMainDim, - availableInnerWidth, - &childMainMeasureMode, &childMainSize); YGConstrainMaxSizeForMode( - child, crossAxis, availableInnerCrossDim, availableInnerWidth, - &childCrossMeasureMode, &childCrossSize); + child, + mainAxis, + availableInnerMainDim, + availableInnerWidth, + &childMainMeasureMode, + &childMainSize); + YGConstrainMaxSizeForMode( + child, + crossAxis, + availableInnerCrossDim, + availableInnerWidth, + &childCrossMeasureMode, + &childCrossSize); const float childWidth = isMainAxisRow ? childMainSize : childCrossSize; @@ -2789,35 +3195,44 @@ static void YGNodelayoutImpl( alignContent != YGAlignStretch && isNodeFlexWrap; const YGMeasureMode childWidthMeasureMode = YGFloatIsUndefined(childWidth) || - (!isMainAxisRow && crossAxisDoesNotGrow) - ? YGMeasureModeUndefined - : YGMeasureModeExactly; + (!isMainAxisRow && crossAxisDoesNotGrow) + ? YGMeasureModeUndefined + : YGMeasureModeExactly; const YGMeasureMode childHeightMeasureMode = YGFloatIsUndefined(childHeight) || - (isMainAxisRow && crossAxisDoesNotGrow) - ? YGMeasureModeUndefined - : YGMeasureModeExactly; + (isMainAxisRow && crossAxisDoesNotGrow) + ? YGMeasureModeUndefined + : YGMeasureModeExactly; YGLayoutNodeInternal( - child, childWidth, childHeight, direction, - childWidthMeasureMode, childHeightMeasureMode, - availableInnerWidth, availableInnerHeight, true, - LayoutPassReason::kStretch, config, layoutMarkerData, - layoutContext, depth, generationCount); + child, + childWidth, + childHeight, + direction, + childWidthMeasureMode, + childHeightMeasureMode, + availableInnerWidth, + availableInnerHeight, + true, + LayoutPassReason::kStretch, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); } } else { - const float remainingCrossDim = - containerCrossAxis - + const float remainingCrossDim = containerCrossAxis - YGNodeDimWithMargin(child, crossAxis, availableInnerWidth); if (child->marginLeadingValue(crossAxis).unit == YGUnitAuto && child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim / 2); - } else if (child->marginTrailingValue(crossAxis).unit == - YGUnitAuto) { + } else if ( + child->marginTrailingValue(crossAxis).unit == YGUnitAuto) { // No-Op - } else if (child->marginLeadingValue(crossAxis).unit == - YGUnitAuto) { + } else if ( + child->marginLeadingValue(crossAxis).unit == YGUnitAuto) { leadingCrossDim += YGFloatMax(0.0f, remainingCrossDim); } else if (alignItem == YGAlignFlexStart) { // No-Op @@ -2828,9 +3243,10 @@ static void YGNodelayoutImpl( } } // And we apply the position - child->setLayoutPosition(child->getLayout().position[pos[crossAxis]] + - totalLineCrossDim + leadingCrossDim, - pos[crossAxis]); + child->setLayoutPosition( + child->getLayout().position[pos[crossAxis]] + totalLineCrossDim + + leadingCrossDim, + pos[crossAxis]); } } } @@ -2895,7 +3311,7 @@ static void YGNodelayoutImpl( if (child->getStyle().display() == YGDisplayNone) { continue; } - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { if (child->getLineIndex() != i) { break; } @@ -2908,15 +3324,15 @@ static void YGNodelayoutImpl( } if (YGNodeAlignItem(node, child) == YGAlignBaseline) { const float ascent = YGBaseline(child, layoutContext) + - child - ->getLeadingMargin(YGFlexDirectionColumn, - availableInnerWidth) - .unwrap(); + child + ->getLeadingMargin( + YGFlexDirectionColumn, availableInnerWidth) + .unwrap(); const float descent = child->getLayout().measuredDimensions[YGDimensionHeight] + child - ->getMarginForAxis(YGFlexDirectionColumn, - availableInnerWidth) + ->getMarginForAxis( + YGFlexDirectionColumn, availableInnerWidth) .unwrap() - ascent; maxAscentForCurrentLine = @@ -2937,7 +3353,7 @@ static void YGNodelayoutImpl( if (child->getStyle().display() == YGDisplayNone) { continue; } - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { switch (YGNodeAlignItem(node, child)) { case YGAlignFlexStart: { child->setLayoutPosition( @@ -2974,27 +3390,21 @@ static void YGNodelayoutImpl( // Remeasure child with the line height as it as been only // measured with the owners height yet. - if (!YGNodeIsStyleDimDefined(child, crossAxis, - availableInnerCrossDim)) { - const float childWidth = - isMainAxisRow - ? (child->getLayout() - .measuredDimensions[YGDimensionWidth] + - child - ->getMarginForAxis(mainAxis, - availableInnerWidth) - .unwrap()) - : lineHeight; + if (!YGNodeIsStyleDimDefined( + child, crossAxis, availableInnerCrossDim)) { + const float childWidth = isMainAxisRow + ? (child->getLayout() + .measuredDimensions[YGDimensionWidth] + + child->getMarginForAxis(mainAxis, availableInnerWidth) + .unwrap()) + : lineHeight; - const float childHeight = - !isMainAxisRow - ? (child->getLayout() - .measuredDimensions[YGDimensionHeight] + - child - ->getMarginForAxis(crossAxis, - availableInnerWidth) - .unwrap()) - : lineHeight; + const float childHeight = !isMainAxisRow + ? (child->getLayout() + .measuredDimensions[YGDimensionHeight] + + child->getMarginForAxis(crossAxis, availableInnerWidth) + .unwrap()) + : lineHeight; if (!(YGFloatsEqual( childWidth, @@ -3005,11 +3415,20 @@ static void YGNodelayoutImpl( child->getLayout() .measuredDimensions[YGDimensionHeight]))) { YGLayoutNodeInternal( - child, childWidth, childHeight, direction, - YGMeasureModeExactly, YGMeasureModeExactly, - availableInnerWidth, availableInnerHeight, true, - LayoutPassReason::kMultilineStretch, config, - layoutMarkerData, layoutContext, depth, + child, + childWidth, + childHeight, + direction, + YGMeasureModeExactly, + YGMeasureModeExactly, + availableInnerWidth, + availableInnerHeight, + true, + LayoutPassReason::kMultilineStretch, + config, + layoutMarkerData, + layoutContext, + depth, generationCount); } } @@ -3020,8 +3439,8 @@ static void YGNodelayoutImpl( currentLead + maxAscentForCurrentLine - YGBaseline(child, layoutContext) + child - ->getLeadingPosition(YGFlexDirectionColumn, - availableInnerCrossDim) + ->getLeadingPosition( + YGFlexDirectionColumn, availableInnerCrossDim) .unwrap(), YGEdgeTop); @@ -3042,14 +3461,21 @@ static void YGNodelayoutImpl( // STEP 9: COMPUTING FINAL DIMENSIONS node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionRow, availableWidth - marginAxisRow, - ownerWidth, ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionRow, + availableWidth - marginAxisRow, + ownerWidth, + ownerWidth), YGDimensionWidth); node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, YGFlexDirectionColumn, - availableHeight - marginAxisColumn, ownerHeight, - ownerWidth), + YGNodeBoundAxis( + node, + YGFlexDirectionColumn, + availableHeight - marginAxisColumn, + ownerHeight, + ownerWidth), YGDimensionHeight); // If the user didn't specify a width or height for the node, set the @@ -3060,19 +3486,23 @@ static void YGNodelayoutImpl( // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, mainAxis, maxLineMainDim, mainAxisownerSize, - ownerWidth), + YGNodeBoundAxis( + node, mainAxis, maxLineMainDim, mainAxisownerSize, ownerWidth), dim[mainAxis]); - } else if (measureModeMainDim == YGMeasureModeAtMost && - node->getStyle().overflow() == YGOverflowScroll) { + } else if ( + measureModeMainDim == YGMeasureModeAtMost && + node->getStyle().overflow() == YGOverflowScroll) { node->setLayoutMeasuredDimension( YGFloatMax( - YGFloatMin(availableInnerMainDim + paddingAndBorderAxisMain, - YGNodeBoundAxisWithinMinAndMax( - node, mainAxis, YGFloatOptional{maxLineMainDim}, - mainAxisownerSize) - .unwrap()), + YGFloatMin( + availableInnerMainDim + paddingAndBorderAxisMain, + YGNodeBoundAxisWithinMinAndMax( + node, + mainAxis, + YGFloatOptional{maxLineMainDim}, + mainAxisownerSize) + .unwrap()), paddingAndBorderAxisMain), dim[mainAxis]); } @@ -3083,22 +3513,28 @@ static void YGNodelayoutImpl( // Clamp the size to the min/max size, if specified, and make sure it // doesn't go below the padding and border amount. node->setLayoutMeasuredDimension( - YGNodeBoundAxis(node, crossAxis, - totalLineCrossDim + paddingAndBorderAxisCross, - crossAxisownerSize, ownerWidth), + YGNodeBoundAxis( + node, + crossAxis, + totalLineCrossDim + paddingAndBorderAxisCross, + crossAxisownerSize, + ownerWidth), dim[crossAxis]); - } else if (measureModeCrossDim == YGMeasureModeAtMost && - node->getStyle().overflow() == YGOverflowScroll) { + } else if ( + measureModeCrossDim == YGMeasureModeAtMost && + node->getStyle().overflow() == YGOverflowScroll) { node->setLayoutMeasuredDimension( YGFloatMax( - YGFloatMin(availableInnerCrossDim + paddingAndBorderAxisCross, - YGNodeBoundAxisWithinMinAndMax( - node, crossAxis, - YGFloatOptional{totalLineCrossDim + - paddingAndBorderAxisCross}, - crossAxisownerSize) - .unwrap()), + YGFloatMin( + availableInnerCrossDim + paddingAndBorderAxisCross, + YGNodeBoundAxisWithinMinAndMax( + node, + crossAxis, + YGFloatOptional{ + totalLineCrossDim + paddingAndBorderAxisCross}, + crossAxisownerSize) + .unwrap()), paddingAndBorderAxisCross), dim[crossAxis]); } @@ -3108,7 +3544,7 @@ static void YGNodelayoutImpl( if (performLayout && node->getStyle().flexWrap() == YGWrapWrapReverse) { for (uint32_t i = 0; i < childCount; i++) { const YGNodeRef child = YGNodeGetChild(node, i); - if (child->getStyle().positionType() == YGPositionTypeRelative) { + if (child->getStyle().positionType() != YGPositionTypeAbsolute) { child->setLayoutPosition( node->getLayout().measuredDimensions[dim[crossAxis]] - child->getLayout().position[pos[crossAxis]] - @@ -3125,17 +3561,23 @@ static void YGNodelayoutImpl( continue; } YGNodeAbsoluteLayoutChild( - node, child, availableInnerWidth, + node, + child, + availableInnerWidth, isMainAxisRow ? measureModeMainDim : measureModeCrossDim, - availableInnerHeight, direction, config, layoutMarkerData, - layoutContext, depth, generationCount); + availableInnerHeight, + direction, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount); } // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN const bool needsMainTrailingPos = mainAxis == YGFlexDirectionRowReverse || - mainAxis == YGFlexDirectionColumnReverse; - const bool needsCrossTrailingPos = - crossAxis == YGFlexDirectionRowReverse || + mainAxis == YGFlexDirectionColumnReverse; + const bool needsCrossTrailingPos = crossAxis == YGFlexDirectionRowReverse || crossAxis == YGFlexDirectionColumnReverse; // Set trailing position if necessary. @@ -3172,12 +3614,13 @@ static const char* YGSpacer(const unsigned long level) { } } -static const char* YGMeasureModeName(const YGMeasureMode mode, - const bool performLayout) { +static const char* YGMeasureModeName( + const YGMeasureMode mode, + const bool performLayout) { constexpr auto N = enums::count(); const char* kMeasureModeNames[N] = {"UNDEFINED", "EXACTLY", "AT_MOST"}; - const char* kLayoutModeNames[N] = {"LAY_UNDEFINED", "LAY_EXACTLY", - "LAY_AT_MOST"}; + const char* kLayoutModeNames[N] = { + "LAY_UNDEFINED", "LAY_EXACTLY", "LAY_AT_MOST"}; if (mode >= N) { return ""; @@ -3187,37 +3630,45 @@ static const char* YGMeasureModeName(const YGMeasureMode mode, } static inline bool YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize( - YGMeasureMode sizeMode, float size, float lastComputedSize) { + YGMeasureMode sizeMode, + float size, + float lastComputedSize) { return sizeMode == YGMeasureModeExactly && - YGFloatsEqual(size, lastComputedSize); + YGFloatsEqual(size, lastComputedSize); } static inline bool YGMeasureModeOldSizeIsUnspecifiedAndStillFits( - YGMeasureMode sizeMode, float size, YGMeasureMode lastSizeMode, + YGMeasureMode sizeMode, + float size, + YGMeasureMode lastSizeMode, float lastComputedSize) { return sizeMode == YGMeasureModeAtMost && - lastSizeMode == YGMeasureModeUndefined && - (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize)); + lastSizeMode == YGMeasureModeUndefined && + (size >= lastComputedSize || YGFloatsEqual(size, lastComputedSize)); } static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( - YGMeasureMode sizeMode, float size, YGMeasureMode lastSizeMode, - float lastSize, float lastComputedSize) { + YGMeasureMode sizeMode, + float size, + YGMeasureMode lastSizeMode, + float lastSize, + float lastComputedSize) { return lastSizeMode == YGMeasureModeAtMost && - sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) && - !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) && - lastSize > size && - (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize)); + sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) && + !YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) && + lastSize > size && + (lastComputedSize <= size || YGFloatsEqual(size, lastComputedSize)); } -YOGA_EXPORT float YGRoundValueToPixelGrid(const float value, - const float pointScaleFactor, - const bool forceCeil, - const bool forceFloor) { - double scaledValue = ((double)value) * pointScaleFactor; +YOGA_EXPORT float YGRoundValueToPixelGrid( + const double value, + const double pointScaleFactor, + const bool forceCeil, + const bool forceFloor) { + double scaledValue = ((double) value) * pointScaleFactor; // We want to calculate `fractial` such that `floor(scaledValue) = scaledValue // - fractial`. - float fractial = fmodf(scaledValue, 1.0f); + double fractial = fmod(scaledValue, 1.0f); if (fractial < 0) { // This branch is for handling negative numbers for `value`. // @@ -3236,10 +3687,10 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(const float value, // - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3 ++fractial; } - if (YGFloatsEqual(fractial, 0)) { + if (YGDoubleEqual(fractial, 0)) { // First we check if the value is already rounded scaledValue = scaledValue - fractial; - } else if (YGFloatsEqual(fractial, 1.0f)) { + } else if (YGDoubleEqual(fractial, 1.0f)) { scaledValue = scaledValue - fractial + 1.0f; } else if (forceCeil) { // Next we check if we need to use forced rounding @@ -3249,54 +3700,55 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(const float value, } else { // Finally we just round the value scaledValue = scaledValue - fractial + - (!YGFloatIsUndefined(fractial) && - (fractial > 0.5f || YGFloatsEqual(fractial, 0.5f)) - ? 1.0f - : 0.0f); + (!YGFloatIsUndefined(fractial) && + (fractial > 0.5f || YGDoubleEqual(fractial, 0.5f)) + ? 1.0f + : 0.0f); } return (YGFloatIsUndefined(scaledValue) || YGFloatIsUndefined(pointScaleFactor)) - ? YGUndefined - : scaledValue / pointScaleFactor; + ? YGUndefined + : scaledValue / pointScaleFactor; } YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( - const YGMeasureMode widthMode, const float width, - const YGMeasureMode heightMode, const float height, - const YGMeasureMode lastWidthMode, const float lastWidth, - const YGMeasureMode lastHeightMode, const float lastHeight, - const float lastComputedWidth, const float lastComputedHeight, - const float marginRow, const float marginColumn, const YGConfigRef config) { + const YGMeasureMode widthMode, + const float width, + const YGMeasureMode heightMode, + const float height, + const YGMeasureMode lastWidthMode, + const float lastWidth, + const YGMeasureMode lastHeightMode, + const float lastHeight, + const float lastComputedWidth, + const float lastComputedHeight, + const float marginRow, + const float marginColumn, + const YGConfigRef config) { if ((!YGFloatIsUndefined(lastComputedHeight) && lastComputedHeight < 0) || (!YGFloatIsUndefined(lastComputedWidth) && lastComputedWidth < 0)) { return false; } bool useRoundedComparison = config != nullptr && config->pointScaleFactor != 0; - const float effectiveWidth = - useRoundedComparison ? YGRoundValueToPixelGrid( - width, config->pointScaleFactor, false, false) - : width; - const float effectiveHeight = - useRoundedComparison ? YGRoundValueToPixelGrid( - height, config->pointScaleFactor, false, false) - : height; - const float effectiveLastWidth = - useRoundedComparison - ? YGRoundValueToPixelGrid(lastWidth, config->pointScaleFactor, false, - false) - : lastWidth; - const float effectiveLastHeight = - useRoundedComparison - ? YGRoundValueToPixelGrid(lastHeight, config->pointScaleFactor, false, - false) - : lastHeight; + const float effectiveWidth = useRoundedComparison + ? YGRoundValueToPixelGrid(width, config->pointScaleFactor, false, false) + : width; + const float effectiveHeight = useRoundedComparison + ? YGRoundValueToPixelGrid(height, config->pointScaleFactor, false, false) + : height; + const float effectiveLastWidth = useRoundedComparison + ? YGRoundValueToPixelGrid( + lastWidth, config->pointScaleFactor, false, false) + : lastWidth; + const float effectiveLastHeight = useRoundedComparison + ? YGRoundValueToPixelGrid( + lastHeight, config->pointScaleFactor, false, false) + : lastHeight; - const bool hasSameWidthSpec = - lastWidthMode == widthMode && + const bool hasSameWidthSpec = lastWidthMode == widthMode && YGFloatsEqual(effectiveLastWidth, effectiveWidth); - const bool hasSameHeightSpec = - lastHeightMode == heightMode && + const bool hasSameHeightSpec = lastHeightMode == heightMode && YGFloatsEqual(effectiveLastHeight, effectiveHeight); const bool widthIsCompatible = @@ -3306,7 +3758,10 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( YGMeasureModeOldSizeIsUnspecifiedAndStillFits( widthMode, width - marginRow, lastWidthMode, lastComputedWidth) || YGMeasureModeNewMeasureSizeIsStricterAndStillValid( - widthMode, width - marginRow, lastWidthMode, lastWidth, + widthMode, + width - marginRow, + lastWidthMode, + lastWidth, lastComputedWidth); const bool heightIsCompatible = @@ -3314,10 +3769,15 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( YGMeasureModeSizeIsExactAndMatchesOldMeasuredSize( heightMode, height - marginColumn, lastComputedHeight) || YGMeasureModeOldSizeIsUnspecifiedAndStillFits( - heightMode, height - marginColumn, lastHeightMode, + heightMode, + height - marginColumn, + lastHeightMode, lastComputedHeight) || YGMeasureModeNewMeasureSizeIsStricterAndStillValid( - heightMode, height - marginColumn, lastHeightMode, lastHeight, + heightMode, + height - marginColumn, + lastHeightMode, + lastHeight, lastComputedHeight); return widthIsCompatible && heightIsCompatible; @@ -3332,12 +3792,20 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement( // Return parameter is true if layout was performed, false if skipped // bool YGLayoutNodeInternal( - const YGNodeRef node, const float availableWidth, - const float availableHeight, const YGDirection ownerDirection, - const YGMeasureMode widthMeasureMode, const YGMeasureMode heightMeasureMode, - const float ownerWidth, const float ownerHeight, const bool performLayout, - const LayoutPassReason reason, const YGConfigRef config, - LayoutData& layoutMarkerData, void* const layoutContext, uint32_t depth, + const YGNodeRef node, + const float availableWidth, + const float availableHeight, + const YGDirection ownerDirection, + const YGMeasureMode widthMeasureMode, + const YGMeasureMode heightMeasureMode, + const float ownerWidth, + const float ownerHeight, + const bool performLayout, + const LayoutPassReason reason, + const YGConfigRef config, + LayoutData& layoutMarkerData, + void* const layoutContext, + uint32_t depth, const uint32_t generationCount) { YGLayout* layout = &node->getLayout(); @@ -3350,8 +3818,10 @@ bool YGLayoutNodeInternal( if (needToVisitNode) { // Invalidate the cached results. layout->nextCachedMeasurementsIndex = 0; - layout->cachedLayout.widthMeasureMode = (YGMeasureMode)-1; - layout->cachedLayout.heightMeasureMode = (YGMeasureMode)-1; + layout->cachedLayout.availableWidth = -1; + layout->cachedLayout.availableHeight = -1; + layout->cachedLayout.widthMeasureMode = YGMeasureModeUndefined; + layout->cachedLayout.heightMeasureMode = YGMeasureModeUndefined; layout->cachedLayout.computedWidth = -1; layout->cachedLayout.computedHeight = -1; } @@ -3374,27 +3844,37 @@ bool YGLayoutNodeInternal( // First, try to use the layout cache. if (YGNodeCanUseCachedMeasurement( - widthMeasureMode, availableWidth, heightMeasureMode, - availableHeight, layout->cachedLayout.widthMeasureMode, + widthMeasureMode, + availableWidth, + heightMeasureMode, + availableHeight, + layout->cachedLayout.widthMeasureMode, layout->cachedLayout.availableWidth, layout->cachedLayout.heightMeasureMode, layout->cachedLayout.availableHeight, layout->cachedLayout.computedWidth, - layout->cachedLayout.computedHeight, marginAxisRow, - marginAxisColumn, config)) { + layout->cachedLayout.computedHeight, + marginAxisRow, + marginAxisColumn, + config)) { cachedResults = &layout->cachedLayout; } else { // Try to use the measurement cache. for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { if (YGNodeCanUseCachedMeasurement( - widthMeasureMode, availableWidth, heightMeasureMode, - availableHeight, layout->cachedMeasurements[i].widthMeasureMode, + widthMeasureMode, + availableWidth, + heightMeasureMode, + availableHeight, + layout->cachedMeasurements[i].widthMeasureMode, layout->cachedMeasurements[i].availableWidth, layout->cachedMeasurements[i].heightMeasureMode, layout->cachedMeasurements[i].availableHeight, layout->cachedMeasurements[i].computedWidth, - layout->cachedMeasurements[i].computedHeight, marginAxisRow, - marginAxisColumn, config)) { + layout->cachedMeasurements[i].computedHeight, + marginAxisRow, + marginAxisColumn, + config)) { cachedResults = &layout->cachedMeasurements[i]; break; } @@ -3409,10 +3889,10 @@ bool YGLayoutNodeInternal( } } else { for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { - if (YGFloatsEqual(layout->cachedMeasurements[i].availableWidth, - availableWidth) && - YGFloatsEqual(layout->cachedMeasurements[i].availableHeight, - availableHeight) && + if (YGFloatsEqual( + layout->cachedMeasurements[i].availableWidth, availableWidth) && + YGFloatsEqual( + layout->cachedMeasurements[i].availableHeight, availableHeight) && layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && layout->cachedMeasurements[i].heightMeasureMode == heightMeasureMode) { @@ -3431,52 +3911,94 @@ bool YGLayoutNodeInternal( : layoutMarkerData.cachedMeasures) += 1; if (gPrintChanges && gPrintSkips) { - Log::log(node, YGLogLevelVerbose, nullptr, "%s%d.{[skipped] ", - YGSpacer(depth), depth); + Log::log( + node, + YGLogLevelVerbose, + nullptr, + "%s%d.{[skipped] ", + YGSpacer(depth), + depth); node->print(layoutContext); - Log::log(node, YGLogLevelVerbose, nullptr, - "wm: %s, hm: %s, aw: %f ah: %f => d: (%f, %f) %s\n", - YGMeasureModeName(widthMeasureMode, performLayout), - YGMeasureModeName(heightMeasureMode, performLayout), - availableWidth, availableHeight, cachedResults->computedWidth, - cachedResults->computedHeight, LayoutPassReasonToString(reason)); + Log::log( + node, + YGLogLevelVerbose, + nullptr, + "wm: %s, hm: %s, aw: %f ah: %f => d: (%f, %f) %s\n", + YGMeasureModeName(widthMeasureMode, performLayout), + YGMeasureModeName(heightMeasureMode, performLayout), + availableWidth, + availableHeight, + cachedResults->computedWidth, + cachedResults->computedHeight, + LayoutPassReasonToString(reason)); } } else { if (gPrintChanges) { - Log::log(node, YGLogLevelVerbose, nullptr, "%s%d.{%s", YGSpacer(depth), - depth, needToVisitNode ? "*" : ""); + Log::log( + node, + YGLogLevelVerbose, + nullptr, + "%s%d.{%s", + YGSpacer(depth), + depth, + needToVisitNode ? "*" : ""); node->print(layoutContext); - Log::log(node, YGLogLevelVerbose, nullptr, - "wm: %s, hm: %s, aw: %f ah: %f %s\n", - YGMeasureModeName(widthMeasureMode, performLayout), - YGMeasureModeName(heightMeasureMode, performLayout), - availableWidth, availableHeight, - LayoutPassReasonToString(reason)); + Log::log( + node, + YGLogLevelVerbose, + nullptr, + "wm: %s, hm: %s, aw: %f ah: %f %s\n", + YGMeasureModeName(widthMeasureMode, performLayout), + YGMeasureModeName(heightMeasureMode, performLayout), + availableWidth, + availableHeight, + LayoutPassReasonToString(reason)); } - YGNodelayoutImpl(node, availableWidth, availableHeight, ownerDirection, - widthMeasureMode, heightMeasureMode, ownerWidth, - ownerHeight, performLayout, config, layoutMarkerData, - layoutContext, depth, generationCount, reason); + YGNodelayoutImpl( + node, + availableWidth, + availableHeight, + ownerDirection, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + performLayout, + config, + layoutMarkerData, + layoutContext, + depth, + generationCount, + reason); if (gPrintChanges) { - Log::log(node, YGLogLevelVerbose, nullptr, "%s%d.}%s", YGSpacer(depth), - depth, needToVisitNode ? "*" : ""); + Log::log( + node, + YGLogLevelVerbose, + nullptr, + "%s%d.}%s", + YGSpacer(depth), + depth, + needToVisitNode ? "*" : ""); node->print(layoutContext); - Log::log(node, YGLogLevelVerbose, nullptr, - "wm: %s, hm: %s, d: (%f, %f) %s\n", - YGMeasureModeName(widthMeasureMode, performLayout), - YGMeasureModeName(heightMeasureMode, performLayout), - layout->measuredDimensions[YGDimensionWidth], - layout->measuredDimensions[YGDimensionHeight], - LayoutPassReasonToString(reason)); + Log::log( + node, + YGLogLevelVerbose, + nullptr, + "wm: %s, hm: %s, d: (%f, %f) %s\n", + YGMeasureModeName(widthMeasureMode, performLayout), + YGMeasureModeName(heightMeasureMode, performLayout), + layout->measuredDimensions[YGDimensionWidth], + layout->measuredDimensions[YGDimensionHeight], + LayoutPassReasonToString(reason)); } layout->lastOwnerDirection = ownerDirection; if (cachedResults == nullptr) { if (layout->nextCachedMeasurementsIndex + 1 > - (uint32_t)layoutMarkerData.maxMeasureCache) { + (uint32_t) layoutMarkerData.maxMeasureCache) { layoutMarkerData.maxMeasureCache = layout->nextCachedMeasurementsIndex + 1; } @@ -3526,8 +4048,8 @@ bool YGLayoutNodeInternal( LayoutType layoutType; if (performLayout) { layoutType = !needToVisitNode && cachedResults == &layout->cachedLayout - ? LayoutType::kCachedLayout - : LayoutType::kLayout; + ? LayoutType::kCachedLayout + : LayoutType::kLayout; } else { layoutType = cachedResults != nullptr ? LayoutType::kCachedMeasure : LayoutType::kMeasure; @@ -3537,10 +4059,13 @@ bool YGLayoutNodeInternal( return (needToVisitNode || cachedResults == nullptr); } -YOGA_EXPORT void YGConfigSetPointScaleFactor(const YGConfigRef config, - const float pixelsInPoint) { - YGAssertWithConfig(config, pixelsInPoint >= 0.0f, - "Scale factor should not be less than zero"); +YOGA_EXPORT void YGConfigSetPointScaleFactor( + const YGConfigRef config, + const float pixelsInPoint) { + YGAssertWithConfig( + config, + pixelsInPoint >= 0.0f, + "Scale factor should not be less than zero"); // We store points for Pixel as we will use it for rounding if (pixelsInPoint == 0.0f) { @@ -3551,25 +4076,26 @@ YOGA_EXPORT void YGConfigSetPointScaleFactor(const YGConfigRef config, } } -static void YGRoundToPixelGrid(const YGNodeRef node, - const float pointScaleFactor, - const float absoluteLeft, - const float absoluteTop) { +static void YGRoundToPixelGrid( + const YGNodeRef node, + const double pointScaleFactor, + const double absoluteLeft, + const double absoluteTop) { if (pointScaleFactor == 0.0f) { return; } - const float nodeLeft = node->getLayout().position[YGEdgeLeft]; - const float nodeTop = node->getLayout().position[YGEdgeTop]; + const double nodeLeft = node->getLayout().position[YGEdgeLeft]; + const double nodeTop = node->getLayout().position[YGEdgeTop]; - const float nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; - const float nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; + const double nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; + const double nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; - const float absoluteNodeLeft = absoluteLeft + nodeLeft; - const float absoluteNodeTop = absoluteTop + nodeTop; + const double absoluteNodeLeft = absoluteLeft + nodeLeft; + const double absoluteNodeTop = absoluteTop + nodeTop; - const float absoluteNodeRight = absoluteNodeLeft + nodeWidth; - const float absoluteNodeBottom = absoluteNodeTop + nodeHeight; + const double absoluteNodeRight = absoluteNodeLeft + nodeWidth; + const double absoluteNodeBottom = absoluteNodeTop + nodeHeight; // If a node has a custom measure function we never want to round down its // size as this could lead to unwanted text truncation. @@ -3587,32 +4113,39 @@ static void YGRoundToPixelGrid(const YGNodeRef node, // 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 = - !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 0) && - !YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 1.0); + !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 0) && + !YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0); const bool hasFractionalHeight = - !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 0) && - !YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 1.0); + !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 0) && + !YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0); node->setLayoutDimension( - YGRoundValueToPixelGrid(absoluteNodeRight, pointScaleFactor, - (textRounding && hasFractionalWidth), - (textRounding && !hasFractionalWidth)) - - YGRoundValueToPixelGrid(absoluteNodeLeft, pointScaleFactor, false, - textRounding), + YGRoundValueToPixelGrid( + absoluteNodeRight, + pointScaleFactor, + (textRounding && hasFractionalWidth), + (textRounding && !hasFractionalWidth)) - + YGRoundValueToPixelGrid( + absoluteNodeLeft, pointScaleFactor, false, textRounding), YGDimensionWidth); node->setLayoutDimension( - YGRoundValueToPixelGrid(absoluteNodeBottom, pointScaleFactor, - (textRounding && hasFractionalHeight), - (textRounding && !hasFractionalHeight)) - - YGRoundValueToPixelGrid(absoluteNodeTop, pointScaleFactor, false, - textRounding), + YGRoundValueToPixelGrid( + absoluteNodeBottom, + pointScaleFactor, + (textRounding && hasFractionalHeight), + (textRounding && !hasFractionalHeight)) - + YGRoundValueToPixelGrid( + absoluteNodeTop, pointScaleFactor, false, textRounding), YGDimensionHeight); const uint32_t childCount = YGNodeGetChildCount(node); for (uint32_t i = 0; i < childCount; i++) { - YGRoundToPixelGrid(YGNodeGetChild(node, i), pointScaleFactor, - absoluteNodeLeft, absoluteNodeTop); + YGRoundToPixelGrid( + YGNodeGetChild(node, i), + pointScaleFactor, + absoluteNodeLeft, + absoluteNodeTop); } } @@ -3624,8 +4157,12 @@ static void unsetUseLegacyFlagRecursively(YGNodeRef node) { } YOGA_EXPORT void YGNodeCalculateLayoutWithContext( - const YGNodeRef node, const float ownerWidth, const float ownerHeight, - const YGDirection ownerDirection, void* layoutContext) { + const YGNodeRef node, + const float ownerWidth, + const float ownerHeight, + const YGDirection ownerDirection, + void* layoutContext) { + Event::publish(node, {layoutContext}); LayoutData markerData = {}; @@ -3638,10 +4175,11 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( YGMeasureMode widthMeasureMode = YGMeasureModeUndefined; const auto& maxDimensions = node->getStyle().maxDimensions(); if (YGNodeIsStyleDimDefined(node, YGFlexDirectionRow, ownerWidth)) { - width = (YGResolveValue(node->getResolvedDimension(dim[YGFlexDirectionRow]), - ownerWidth) + - node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) - .unwrap(); + width = + (YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionRow]), ownerWidth) + + node->getMarginForAxis(YGFlexDirectionRow, ownerWidth)) + .unwrap(); widthMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth) .isUndefined()) { @@ -3657,11 +4195,11 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( float height = YGUndefined; YGMeasureMode heightMeasureMode = YGMeasureModeUndefined; if (YGNodeIsStyleDimDefined(node, YGFlexDirectionColumn, ownerHeight)) { - height = - (YGResolveValue(node->getResolvedDimension(dim[YGFlexDirectionColumn]), - ownerHeight) + - node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) - .unwrap(); + height = (YGResolveValue( + node->getResolvedDimension(dim[YGFlexDirectionColumn]), + ownerHeight) + + node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth)) + .unwrap(); heightMeasureMode = YGMeasureModeExactly; } else if (!YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight) .isUndefined()) { @@ -3674,21 +4212,32 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( : YGMeasureModeExactly; } if (YGLayoutNodeInternal( - node, width, height, ownerDirection, widthMeasureMode, - heightMeasureMode, ownerWidth, ownerHeight, true, - LayoutPassReason::kInitial, node->getConfig(), markerData, + node, + width, + height, + ownerDirection, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + true, + LayoutPassReason::kInitial, + node->getConfig(), + markerData, layoutContext, - 0, // tree root + 0, // tree root gCurrentGenerationCount.load(std::memory_order_relaxed))) { - node->setPosition(node->getLayout().direction(), ownerWidth, ownerHeight, - ownerWidth); + node->setPosition( + node->getLayout().direction(), ownerWidth, ownerHeight, ownerWidth); YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f); #ifdef DEBUG if (node->getConfig()->printTree) { YGNodePrint( - node, (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | - YGPrintOptionsStyle)); + node, + (YGPrintOptions)( + YGPrintOptionsLayout | YGPrintOptionsChildren | + YGPrintOptionsStyle)); } #endif } @@ -3713,18 +4262,31 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( unsetUseLegacyFlagRecursively(nodeWithoutLegacyFlag); LayoutData layoutMarkerData = {}; if (YGLayoutNodeInternal( - nodeWithoutLegacyFlag, width, height, ownerDirection, - widthMeasureMode, heightMeasureMode, ownerWidth, ownerHeight, true, - LayoutPassReason::kInitial, nodeWithoutLegacyFlag->getConfig(), - layoutMarkerData, layoutContext, - 0, // tree root + nodeWithoutLegacyFlag, + width, + height, + ownerDirection, + widthMeasureMode, + heightMeasureMode, + ownerWidth, + ownerHeight, + true, + LayoutPassReason::kInitial, + nodeWithoutLegacyFlag->getConfig(), + layoutMarkerData, + layoutContext, + 0, // tree root gCurrentGenerationCount.load(std::memory_order_relaxed))) { nodeWithoutLegacyFlag->setPosition( - nodeWithoutLegacyFlag->getLayout().direction(), ownerWidth, - ownerHeight, ownerWidth); - YGRoundToPixelGrid(nodeWithoutLegacyFlag, - nodeWithoutLegacyFlag->getConfig()->pointScaleFactor, - 0.0f, 0.0f); + nodeWithoutLegacyFlag->getLayout().direction(), + ownerWidth, + ownerHeight, + ownerWidth); + YGRoundToPixelGrid( + nodeWithoutLegacyFlag, + nodeWithoutLegacyFlag->getConfig()->pointScaleFactor, + 0.0f, + 0.0f); // Set whether the two layouts are different or not. auto neededLegacyStretchBehaviour = @@ -3735,8 +4297,9 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( if (nodeWithoutLegacyFlag->getConfig()->printTree) { YGNodePrint( nodeWithoutLegacyFlag, - (YGPrintOptions)(YGPrintOptionsLayout | YGPrintOptionsChildren | - YGPrintOptionsStyle)); + (YGPrintOptions)( + YGPrintOptionsLayout | YGPrintOptionsChildren | + YGPrintOptionsStyle)); } #endif } @@ -3745,12 +4308,13 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext( } } -YOGA_EXPORT void YGNodeCalculateLayout(const YGNodeRef node, - const float ownerWidth, - const float ownerHeight, - const YGDirection ownerDirection) { - YGNodeCalculateLayoutWithContext(node, ownerWidth, ownerHeight, - ownerDirection, nullptr); +YOGA_EXPORT void YGNodeCalculateLayout( + const YGNodeRef node, + const float ownerWidth, + const float ownerHeight, + const YGDirection ownerDirection) { + YGNodeCalculateLayoutWithContext( + node, ownerWidth, ownerHeight, ownerDirection, nullptr); } YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { @@ -3766,48 +4330,60 @@ YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) { } YOGA_EXPORT void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( - const YGConfigRef config, const bool shouldDiffLayout) { + const YGConfigRef config, + const bool shouldDiffLayout) { config->shouldDiffLayoutWithoutLegacyStretchBehaviour = shouldDiffLayout; } void YGAssert(const bool condition, const char* message) { if (!condition) { Log::log(YGNodeRef{nullptr}, YGLogLevelFatal, nullptr, "%s\n", message); + throwLogicalErrorWithMessage(message); } } -void YGAssertWithNode(const YGNodeRef node, const bool condition, - const char* message) { +void YGAssertWithNode( + const YGNodeRef node, + const bool condition, + const char* message) { if (!condition) { Log::log(node, YGLogLevelFatal, nullptr, "%s\n", message); + throwLogicalErrorWithMessage(message); } } -void YGAssertWithConfig(const YGConfigRef config, const bool condition, - const char* message) { +void YGAssertWithConfig( + const YGConfigRef config, + const bool condition, + const char* message) { if (!condition) { Log::log(config, YGLogLevelFatal, nullptr, "%s\n", message); + throwLogicalErrorWithMessage(message); } } YOGA_EXPORT void YGConfigSetExperimentalFeatureEnabled( - const YGConfigRef config, const YGExperimentalFeature feature, + const YGConfigRef config, + const YGExperimentalFeature feature, const bool enabled) { config->experimentalFeatures[feature] = enabled; } inline bool YGConfigIsExperimentalFeatureEnabled( - const YGConfigRef config, const YGExperimentalFeature feature) { + const YGConfigRef config, + const YGExperimentalFeature feature) { return config->experimentalFeatures[feature]; } -YOGA_EXPORT void YGConfigSetUseWebDefaults(const YGConfigRef config, - const bool enabled) { +YOGA_EXPORT void YGConfigSetUseWebDefaults( + const YGConfigRef config, + const bool enabled) { config->useWebDefaults = enabled; } YOGA_EXPORT void YGConfigSetUseLegacyStretchBehaviour( - const YGConfigRef config, const bool useLegacyStretchBehaviour) { + const YGConfigRef config, + const bool useLegacyStretchBehaviour) { config->useLegacyStretchBehaviour = useLegacyStretchBehaviour; } @@ -3823,21 +4399,24 @@ YOGA_EXPORT void* YGConfigGetContext(const YGConfigRef config) { return config->context; } -YOGA_EXPORT void YGConfigSetCloneNodeFunc(const YGConfigRef config, - const YGCloneNodeFunc callback) { +YOGA_EXPORT void YGConfigSetCloneNodeFunc( + const YGConfigRef config, + const YGCloneNodeFunc callback) { config->setCloneNodeCallback(callback); } static void YGTraverseChildrenPreOrder( - const YGVector& children, const std::function& f) { + const YGVector& children, + const std::function& f) { for (YGNodeRef node : children) { f(node); YGTraverseChildrenPreOrder(node->getChildren(), f); } } -void YGTraversePreOrder(YGNodeRef const node, - std::function&& f) { +void YGTraversePreOrder( + YGNodeRef const node, + std::function&& f) { if (!node) { return; } diff --git a/src/cpp/include/deps/yoga/Yoga.h b/src/cpp/include/deps/yoga/Yoga.h index 347bc5a5c..87901a280 100644 --- a/src/cpp/include/deps/yoga/Yoga.h +++ b/src/cpp/include/deps/yoga/Yoga.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -// v1.18.0 + #pragma once #include @@ -34,30 +34,45 @@ typedef struct YGConfig* YGConfigRef; typedef struct YGNode* YGNodeRef; typedef const struct YGNode* YGNodeConstRef; -typedef YGSize (*YGMeasureFunc)(YGNodeRef node, float width, - YGMeasureMode widthMode, float height, - YGMeasureMode heightMode); +typedef YGSize (*YGMeasureFunc)( + YGNodeRef node, + float width, + YGMeasureMode widthMode, + float height, + YGMeasureMode heightMode); typedef float (*YGBaselineFunc)(YGNodeRef node, float width, float height); typedef void (*YGDirtiedFunc)(YGNodeRef node); typedef void (*YGPrintFunc)(YGNodeRef node); typedef void (*YGNodeCleanupFunc)(YGNodeRef node); -typedef int (*YGLogger)(YGConfigRef config, YGNodeRef node, YGLogLevel level, - const char* format, va_list args); -typedef YGNodeRef (*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, - int childIndex); +typedef int (*YGLogger)( + YGConfigRef config, + YGNodeRef node, + YGLogLevel level, + const char* format, + va_list args); +typedef YGNodeRef ( + *YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex); // YGNode WIN_EXPORT YGNodeRef YGNodeNew(void); WIN_EXPORT YGNodeRef YGNodeNewWithConfig(YGConfigRef config); WIN_EXPORT YGNodeRef YGNodeClone(YGNodeRef node); WIN_EXPORT void YGNodeFree(YGNodeRef node); -WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(YGNodeRef node, - YGNodeCleanupFunc cleanup); +WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc( + YGNodeRef node, + YGNodeCleanupFunc cleanup); WIN_EXPORT void YGNodeFreeRecursive(YGNodeRef node); WIN_EXPORT void YGNodeReset(YGNodeRef node); -WIN_EXPORT void YGNodeInsertChild(YGNodeRef node, YGNodeRef child, - uint32_t index); +WIN_EXPORT void YGNodeInsertChild( + YGNodeRef node, + YGNodeRef child, + uint32_t index); + +WIN_EXPORT void YGNodeSwapChild( + YGNodeRef node, + YGNodeRef child, + uint32_t index); WIN_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child); WIN_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node); @@ -65,17 +80,22 @@ WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index); WIN_EXPORT YGNodeRef YGNodeGetOwner(YGNodeRef node); WIN_EXPORT YGNodeRef YGNodeGetParent(YGNodeRef node); WIN_EXPORT uint32_t YGNodeGetChildCount(YGNodeRef node); -WIN_EXPORT void YGNodeSetChildren(YGNodeRef owner, const YGNodeRef children[], - uint32_t count); +WIN_EXPORT void YGNodeSetChildren( + YGNodeRef owner, + const YGNodeRef children[], + uint32_t count); -WIN_EXPORT void YGNodeSetIsReferenceBaseline(YGNodeRef node, - bool isReferenceBaseline); +WIN_EXPORT void YGNodeSetIsReferenceBaseline( + YGNodeRef node, + bool isReferenceBaseline); WIN_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node); -WIN_EXPORT void YGNodeCalculateLayout(YGNodeRef node, float availableWidth, - float availableHeight, - YGDirection ownerDirection); +WIN_EXPORT void YGNodeCalculateLayout( + YGNodeRef node, + float availableWidth, + float availableHeight, + YGDirection ownerDirection); // Mark a node as dirty. Only valid for nodes with a custom measure function // set. @@ -96,10 +116,18 @@ WIN_EXPORT void YGNodePrint(YGNodeRef node, YGPrintOptions options); WIN_EXPORT bool YGFloatIsUndefined(float value); WIN_EXPORT bool YGNodeCanUseCachedMeasurement( - YGMeasureMode widthMode, float width, YGMeasureMode heightMode, - float height, YGMeasureMode lastWidthMode, float lastWidth, - YGMeasureMode lastHeightMode, float lastHeight, float lastComputedWidth, - float lastComputedHeight, float marginRow, float marginColumn, + YGMeasureMode widthMode, + float width, + YGMeasureMode heightMode, + float height, + YGMeasureMode lastWidthMode, + float lastWidth, + YGMeasureMode lastHeightMode, + float lastHeight, + float lastComputedWidth, + float lastComputedHeight, + float marginRow, + float marginColumn, YGConfigRef config); WIN_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeRef srcNode); @@ -124,16 +152,19 @@ bool YGNodeLayoutGetDidUseLegacyFlag(YGNodeRef node); WIN_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction); WIN_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node); -WIN_EXPORT void YGNodeStyleSetFlexDirection(YGNodeRef node, - YGFlexDirection flexDirection); +WIN_EXPORT void YGNodeStyleSetFlexDirection( + YGNodeRef node, + YGFlexDirection flexDirection); WIN_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(YGNodeConstRef node); -WIN_EXPORT void YGNodeStyleSetJustifyContent(YGNodeRef node, - YGJustify justifyContent); +WIN_EXPORT void YGNodeStyleSetJustifyContent( + YGNodeRef node, + YGJustify justifyContent); WIN_EXPORT YGJustify YGNodeStyleGetJustifyContent(YGNodeConstRef node); -WIN_EXPORT void YGNodeStyleSetAlignContent(YGNodeRef node, - YGAlign alignContent); +WIN_EXPORT void YGNodeStyleSetAlignContent( + YGNodeRef node, + YGAlign alignContent); WIN_EXPORT YGAlign YGNodeStyleGetAlignContent(YGNodeConstRef node); WIN_EXPORT void YGNodeStyleSetAlignItems(YGNodeRef node, YGAlign alignItems); @@ -142,8 +173,9 @@ WIN_EXPORT YGAlign YGNodeStyleGetAlignItems(YGNodeConstRef node); WIN_EXPORT void YGNodeStyleSetAlignSelf(YGNodeRef node, YGAlign alignSelf); WIN_EXPORT YGAlign YGNodeStyleGetAlignSelf(YGNodeConstRef node); -WIN_EXPORT void YGNodeStyleSetPositionType(YGNodeRef node, - YGPositionType positionType); +WIN_EXPORT void YGNodeStyleSetPositionType( + YGNodeRef node, + YGPositionType positionType); WIN_EXPORT YGPositionType YGNodeStyleGetPositionType(YGNodeConstRef node); WIN_EXPORT void YGNodeStyleSetFlexWrap(YGNodeRef node, YGWrap flexWrap); @@ -169,22 +201,32 @@ WIN_EXPORT void YGNodeStyleSetFlexBasisPercent(YGNodeRef node, float flexBasis); WIN_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node); WIN_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node); -WIN_EXPORT void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, - float position); -WIN_EXPORT void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, - float position); +WIN_EXPORT void YGNodeStyleSetPosition( + YGNodeRef node, + YGEdge edge, + float position); +WIN_EXPORT void YGNodeStyleSetPositionPercent( + YGNodeRef node, + YGEdge edge, + float position); WIN_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge); WIN_EXPORT void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float margin); -WIN_EXPORT void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, - float margin); +WIN_EXPORT void YGNodeStyleSetMarginPercent( + YGNodeRef node, + YGEdge edge, + float margin); WIN_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge); WIN_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge); -WIN_EXPORT void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, - float padding); -WIN_EXPORT void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, - float padding); +WIN_EXPORT void YGNodeStyleSetPadding( + YGNodeRef node, + YGEdge edge, + float padding); +WIN_EXPORT void YGNodeStyleSetPaddingPercent( + YGNodeRef node, + YGEdge edge, + float padding); WIN_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge); WIN_EXPORT void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, float border); @@ -254,16 +296,22 @@ WIN_EXPORT float YGNodeLayoutGetPadding(YGNodeRef node, YGEdge edge); WIN_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger); WIN_EXPORT void YGAssert(bool condition, const char* message); -WIN_EXPORT void YGAssertWithNode(YGNodeRef node, bool condition, - const char* message); -WIN_EXPORT void YGAssertWithConfig(YGConfigRef config, bool condition, - const char* message); +WIN_EXPORT void YGAssertWithNode( + YGNodeRef node, + bool condition, + const char* message); +WIN_EXPORT void YGAssertWithConfig( + YGConfigRef config, + bool condition, + const char* message); // Set this to number of pixels in 1 point to round calculation results If you // want to avoid rounding - set PointScaleFactor to 0 -WIN_EXPORT void YGConfigSetPointScaleFactor(YGConfigRef config, - float pixelsInPoint); +WIN_EXPORT void YGConfigSetPointScaleFactor( + YGConfigRef config, + float pixelsInPoint); void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( - YGConfigRef config, bool shouldDiffLayout); + YGConfigRef config, + bool shouldDiffLayout); // Yoga previously had an error where containers would take the maximum space // possible instead of the minimum like they are supposed to. In practice this @@ -271,7 +319,8 @@ void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour( // was such a long-standing bug we must allow legacy users to switch back to // this behaviour. WIN_EXPORT void YGConfigSetUseLegacyStretchBehaviour( - YGConfigRef config, bool useLegacyStretchBehaviour); + YGConfigRef config, + bool useLegacyStretchBehaviour); // YGConfig WIN_EXPORT YGConfigRef YGConfigNew(void); @@ -280,17 +329,21 @@ WIN_EXPORT void YGConfigCopy(YGConfigRef dest, YGConfigRef src); WIN_EXPORT int32_t YGConfigGetInstanceCount(void); WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled( - YGConfigRef config, YGExperimentalFeature feature, bool enabled); + YGConfigRef config, + YGExperimentalFeature feature, + bool enabled); WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled( - YGConfigRef config, YGExperimentalFeature feature); + YGConfigRef config, + YGExperimentalFeature feature); // Using the web defaults is the preferred configuration for new projects. Usage // of non web defaults should be considered as legacy. WIN_EXPORT void YGConfigSetUseWebDefaults(YGConfigRef config, bool enabled); WIN_EXPORT bool YGConfigGetUseWebDefaults(YGConfigRef config); -WIN_EXPORT void YGConfigSetCloneNodeFunc(YGConfigRef config, - YGCloneNodeFunc callback); +WIN_EXPORT void YGConfigSetCloneNodeFunc( + YGConfigRef config, + YGCloneNodeFunc callback); // Export only for C# WIN_EXPORT YGConfigRef YGConfigGetDefault(void); @@ -298,8 +351,11 @@ WIN_EXPORT YGConfigRef YGConfigGetDefault(void); WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context); WIN_EXPORT void* YGConfigGetContext(YGConfigRef config); -WIN_EXPORT float YGRoundValueToPixelGrid(float value, float pointScaleFactor, - bool forceCeil, bool forceFloor); +WIN_EXPORT float YGRoundValueToPixelGrid( + double value, + double pointScaleFactor, + bool forceCeil, + bool forceFloor); YG_EXTERN_C_END @@ -309,8 +365,9 @@ YG_EXTERN_C_END #include // Calls f on each node in the tree including the given node argument. -void YGTraversePreOrder(YGNodeRef node, - std::function&& f); +void YGTraversePreOrder( + YGNodeRef node, + std::function&& f); void YGNodeSetChildren(YGNodeRef owner, const std::vector& children); diff --git a/src/cpp/include/deps/yoga/event/event.cpp b/src/cpp/include/deps/yoga/event/event.cpp index 087fff936..3af3e83a0 100644 --- a/src/cpp/include/deps/yoga/event/event.cpp +++ b/src/cpp/include/deps/yoga/event/event.cpp @@ -6,10 +6,8 @@ */ #include "event.h" - #include #include -#include namespace facebook { namespace yoga { @@ -61,7 +59,7 @@ Node* push(Node* newHead) { return oldHead; } -} // namespace +} // namespace void Event::reset() { auto head = push(nullptr); @@ -78,10 +76,11 @@ void Event::subscribe(std::function&& subscriber) { void Event::publish(const YGNode& node, Type eventType, const Data& eventData) { for (auto subscriber = subscribers.load(std::memory_order_relaxed); - subscriber != nullptr; subscriber = subscriber->next) { + subscriber != nullptr; + subscriber = subscriber->next) { subscriber->subscriber(node, eventType, eventData); } } -} // namespace yoga -} // namespace facebook +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/event/event.h b/src/cpp/include/deps/yoga/event/event.h index 65ea75750..404ec3766 100644 --- a/src/cpp/include/deps/yoga/event/event.h +++ b/src/cpp/include/deps/yoga/event/event.h @@ -7,12 +7,11 @@ #pragma once -#include - -#include -#include #include #include +#include +#include +#include struct YGConfig; struct YGNode; @@ -74,7 +73,7 @@ struct YOGA_EXPORT Event { class Data { const void* data_; - public: + public: template Data(const TypedData& data) : data_{&data} {} @@ -100,7 +99,7 @@ struct YOGA_EXPORT Event { publish(*node, eventData); } - private: +private: static void publish(const YGNode&, Type, const Data&); }; @@ -143,5 +142,5 @@ struct Event::TypedData { void* layoutContext; }; -} // namespace yoga -} // namespace facebook +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/internal/experiments-inl.h b/src/cpp/include/deps/yoga/internal/experiments-inl.h index 4aa038532..959d9c332 100644 --- a/src/cpp/include/deps/yoga/internal/experiments-inl.h +++ b/src/cpp/include/deps/yoga/internal/experiments-inl.h @@ -7,24 +7,26 @@ #pragma once -#include - #include "experiments.h" +#include + namespace facebook { namespace yoga { namespace internal { namespace detail { extern std::bitset enabledExperiments; -} // namespace detail +} // namespace detail inline bool isEnabled(Experiment experiment) { return detail::enabledExperiments.test(static_cast(experiment)); } -inline void disableAllExperiments() { detail::enabledExperiments = 0; } +inline void disableAllExperiments() { + detail::enabledExperiments = 0; +} -} // namespace internal -} // namespace yoga -} // namespace facebook +} // namespace internal +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/internal/experiments.cpp b/src/cpp/include/deps/yoga/internal/experiments.cpp index 7412a47c0..16f196d5e 100644 --- a/src/cpp/include/deps/yoga/internal/experiments.cpp +++ b/src/cpp/include/deps/yoga/internal/experiments.cpp @@ -6,7 +6,6 @@ */ #include "experiments.h" - #include "experiments-inl.h" namespace facebook { @@ -17,7 +16,7 @@ namespace detail { std::bitset enabledExperiments = 0; -} // namespace detail +} // namespace detail void enable(Experiment experiment) { detail::enabledExperiments.set(static_cast(experiment)); @@ -34,6 +33,6 @@ bool toggle(Experiment experiment) { return previousState; } -} // namespace internal -} // namespace yoga -} // namespace facebook +} // namespace internal +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/internal/experiments.h b/src/cpp/include/deps/yoga/internal/experiments.h index 13b4e4017..1bdb7014b 100644 --- a/src/cpp/include/deps/yoga/internal/experiments.h +++ b/src/cpp/include/deps/yoga/internal/experiments.h @@ -21,6 +21,6 @@ void enable(Experiment); void disable(Experiment); bool toggle(Experiment); -} // namespace internal -} // namespace yoga -} // namespace facebook +} // namespace internal +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/log.cpp b/src/cpp/include/deps/yoga/log.cpp index 00ca08f2d..eb3da039c 100644 --- a/src/cpp/include/deps/yoga/log.cpp +++ b/src/cpp/include/deps/yoga/log.cpp @@ -7,9 +7,9 @@ #include "log.h" +#include "Yoga.h" #include "YGConfig.h" #include "YGNode.h" -#include "Yoga.h" namespace facebook { namespace yoga { @@ -17,34 +17,48 @@ namespace detail { namespace { -void vlog(YGConfig* config, YGNode* node, YGLogLevel level, void* context, - const char* format, va_list args) { +void vlog( + YGConfig* config, + YGNode* node, + YGLogLevel level, + void* context, + const char* format, + va_list args) { YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault(); logConfig->log(logConfig, node, level, context, format, args); - - if (level == YGLogLevelFatal) { - abort(); - } } -} // namespace +} // namespace -YOGA_EXPORT void Log::log(YGNode* node, YGLogLevel level, void* context, - const char* format, ...) noexcept { +YOGA_EXPORT void Log::log( + YGNode* node, + YGLogLevel level, + void* context, + const char* format, + ...) noexcept { va_list args; va_start(args, format); - vlog(node == nullptr ? nullptr : node->getConfig(), node, level, context, - format, args); + vlog( + node == nullptr ? nullptr : node->getConfig(), + node, + level, + context, + format, + args); va_end(args); } -void Log::log(YGConfig* config, YGLogLevel level, void* context, - const char* format, ...) noexcept { +void Log::log( + YGConfig* config, + YGLogLevel level, + void* context, + const char* format, + ...) noexcept { va_list args; va_start(args, format); vlog(config, nullptr, level, context, format, args); va_end(args); } -} // namespace detail -} // namespace yoga -} // namespace facebook +} // namespace detail +} // namespace yoga +} // namespace facebook diff --git a/src/cpp/include/deps/yoga/log.h b/src/cpp/include/deps/yoga/log.h index ab608f19a..ae33744c5 100644 --- a/src/cpp/include/deps/yoga/log.h +++ b/src/cpp/include/deps/yoga/log.h @@ -18,13 +18,21 @@ namespace yoga { namespace detail { struct Log { - static void log(YGNode* node, YGLogLevel level, void*, const char* message, - ...) noexcept; + static void log( + YGNode* node, + YGLogLevel level, + void*, + const char* message, + ...) noexcept; - static void log(YGConfig* config, YGLogLevel level, void*, const char* format, - ...) noexcept; + static void log( + YGConfig* config, + YGLogLevel level, + void*, + const char* format, + ...) noexcept; }; -} // namespace detail -} // namespace yoga -} // namespace facebook +} // namespace detail +} // namespace yoga +} // namespace facebook