diff --git a/fbandroid/libraries/components/lib/yoga/src/main/cpp/yoga/Yoga-internal.h b/fbandroid/libraries/components/lib/yoga/src/main/cpp/yoga/Yoga-internal.h new file mode 100644 index 00000000..1e9aaa5f --- /dev/null +++ b/fbandroid/libraries/components/lib/yoga/src/main/cpp/yoga/Yoga-internal.h @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#pragma once +#include +#include +#include +#include +#include "Yoga.h" + +using YGVector = std::vector; + +YG_EXTERN_C_BEGIN + +WIN_EXPORT float YGRoundValueToPixelGrid( + const float value, + const float pointScaleFactor, + const bool forceCeil, + const bool forceFloor); + +YG_EXTERN_C_END + +extern const std::array trailing; +extern const std::array leading; +extern bool YGValueEqual(const YGValue a, const YGValue b); +extern const YGValue YGValueUndefined; +extern const YGValue YGValueAuto; +extern const YGValue YGValueZero; + +template +bool YGValueArrayEqual( + const std::array val1, + const std::array val2) { + bool areEqual = true; + for (uint32_t i = 0; i < size && areEqual; ++i) { + areEqual = YGValueEqual(val1[i], val2[i]); + } + return areEqual; +} + +const YGValue kYGValueUndefined = {YGUndefined, YGUnitUndefined}; +const YGValue kYGValueAuto = {YGUndefined, YGUnitAuto}; +const std::array kYGDefaultEdgeValuesUnit = { + {kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined}}; +const std::array kYGDefaultDimensionValuesAutoUnit = { + {kYGValueAuto, kYGValueAuto}}; +const std::array kYGDefaultDimensionValuesUnit = { + {kYGValueUndefined, kYGValueUndefined}}; + +struct YGCachedMeasurement { + float availableWidth; + float availableHeight; + YGMeasureMode widthMeasureMode; + YGMeasureMode heightMeasureMode; + + float computedWidth; + float computedHeight; + + bool operator==(YGCachedMeasurement measurement) const { + bool isEqual = widthMeasureMode == measurement.widthMeasureMode && + heightMeasureMode == measurement.heightMeasureMode; + + if (!std::isnan(availableWidth) || + !std::isnan(measurement.availableWidth)) { + isEqual = isEqual && availableWidth == measurement.availableWidth; + } + if (!std::isnan(availableHeight) || + !std::isnan(measurement.availableHeight)) { + isEqual = isEqual && availableHeight == measurement.availableHeight; + } + if (!std::isnan(computedWidth) || !std::isnan(measurement.computedWidth)) { + isEqual = isEqual && computedWidth == measurement.computedWidth; + } + if (!std::isnan(computedHeight) || + !std::isnan(measurement.computedHeight)) { + isEqual = isEqual && computedHeight == measurement.computedHeight; + } + + return isEqual; + } +}; + +// This value was chosen based on empiracle data. Even the most complicated +// layouts should not require more than 16 entries to fit within the cache. +#define YG_MAX_CACHED_RESULT_COUNT 16 + +struct YGConfig { + bool experimentalFeatures[YGExperimentalFeatureCount + 1]; + bool useWebDefaults; + bool useLegacyStretchBehaviour; + bool shouldDiffLayoutWithoutLegacyStretchBehaviour; + float pointScaleFactor; + YGLogger logger; + YGNodeClonedFunc cloneNodeCallback; + void* context; +}; + +static const float kDefaultFlexGrow = 0.0f; +static const float kDefaultFlexShrink = 0.0f; +static const float kWebDefaultFlexShrink = 1.0f; + +extern bool YGFloatsEqual(const float a, const float b); +extern bool YGValueEqual(const YGValue a, const YGValue b); +extern const YGValue* YGComputedEdgeValue( + const std::array& edges, + const YGEdge edge, + const YGValue* const defaultValue); diff --git a/fbcode/xplat/yoga/yoga/Yoga-internal.h b/fbcode/xplat/yoga/yoga/Yoga-internal.h new file mode 100644 index 00000000..e69de29b diff --git a/tests/YGStyleTest.cpp b/tests/YGStyleTest.cpp index 55814a05..5de45e45 100644 --- a/tests/YGStyleTest.cpp +++ b/tests/YGStyleTest.cpp @@ -7,6 +7,7 @@ #include #include +#include TEST(YogaTest, copy_style_same) { const YGNodeRef node0 = YGNodeNew(); diff --git a/yoga/YGNode.cpp b/yoga/YGNode.cpp index 56ce1b49..24a00a88 100644 --- a/yoga/YGNode.cpp +++ b/yoga/YGNode.cpp @@ -382,7 +382,7 @@ YGNode::YGNode() measure_(nullptr), baseline_(nullptr), dirtied_(nullptr), - style_(gYGNodeStyleDefaults), + style_(YGStyle()), layout_(gYGNodeLayoutDefaults), lineIndex_(0), parent_(nullptr), diff --git a/yoga/YGNode.h b/yoga/YGNode.h index b3e31256..452b8f31 100644 --- a/yoga/YGNode.h +++ b/yoga/YGNode.h @@ -7,7 +7,7 @@ #pragma once #include - +#include "YGStyle.h" #include "Yoga-internal.h" struct YGNode { diff --git a/yoga/YGStyle.cpp b/yoga/YGStyle.cpp new file mode 100644 index 00000000..516ce061 --- /dev/null +++ b/yoga/YGStyle.cpp @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "YGStyle.h" + +YGStyle::YGStyle() + : direction(YGDirectionInherit), + flexDirection(YGFlexDirectionColumn), + justifyContent(YGJustifyFlexStart), + alignContent(YGAlignFlexStart), + alignItems(YGAlignStretch), + alignSelf(YGAlignAuto), + positionType(YGPositionTypeRelative), + flexWrap(YGWrapNoWrap), + overflow(YGOverflowVisible), + display(YGDisplayFlex), + flex(YGUndefined), + flexGrow(YGUndefined), + flexShrink(YGUndefined), + flexBasis(kYGValueAuto), + margin(kYGDefaultEdgeValuesUnit), + position(kYGDefaultEdgeValuesUnit), + padding(kYGDefaultEdgeValuesUnit), + border(kYGDefaultEdgeValuesUnit), + dimensions(kYGDefaultDimensionValuesAutoUnit), + minDimensions(kYGDefaultDimensionValuesUnit), + maxDimensions(kYGDefaultDimensionValuesUnit), + aspectRatio(YGUndefined) {} + +// Yoga specific properties, not compatible with flexbox specification +bool YGStyle::operator==(const YGStyle& style) { + bool areNonFloatValuesEqual = direction == style.direction && + flexDirection == style.flexDirection && + justifyContent == style.justifyContent && + alignContent == style.alignContent && alignItems == style.alignItems && + alignSelf == style.alignSelf && positionType == style.positionType && + flexWrap == style.flexWrap && overflow == style.overflow && + display == style.display && YGValueEqual(flexBasis, style.flexBasis) && + YGValueArrayEqual(margin, style.margin) && + YGValueArrayEqual(position, style.position) && + YGValueArrayEqual(padding, style.padding) && + YGValueArrayEqual(border, style.border) && + YGValueArrayEqual(dimensions, style.dimensions) && + YGValueArrayEqual(minDimensions, style.minDimensions) && + YGValueArrayEqual(maxDimensions, style.maxDimensions); + + if (!(std::isnan(flex) && std::isnan(style.flex))) { + areNonFloatValuesEqual = areNonFloatValuesEqual && flex == style.flex; + } + + if (!(std::isnan(flexGrow) && std::isnan(style.flexGrow))) { + areNonFloatValuesEqual = + areNonFloatValuesEqual && flexGrow == style.flexGrow; + } + + if (!(std::isnan(flexShrink) && std::isnan(style.flexShrink))) { + areNonFloatValuesEqual = + areNonFloatValuesEqual && flexShrink == style.flexShrink; + } + + if (!(std::isnan(aspectRatio) && std::isnan(style.aspectRatio))) { + areNonFloatValuesEqual = + areNonFloatValuesEqual && aspectRatio == style.aspectRatio; + } + + return areNonFloatValuesEqual; +} + +bool YGStyle::operator!=(YGStyle style) { + return !(*this == style); +} + +YGStyle::~YGStyle() {} diff --git a/yoga/YGStyle.h b/yoga/YGStyle.h new file mode 100644 index 00000000..a95b4a29 --- /dev/null +++ b/yoga/YGStyle.h @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#pragma once +#include "Yoga-internal.h" +#include "Yoga.h" + +struct YGStyle { + YGDirection direction; + YGFlexDirection flexDirection; + YGJustify justifyContent; + YGAlign alignContent; + YGAlign alignItems; + YGAlign alignSelf; + YGPositionType positionType; + YGWrap flexWrap; + YGOverflow overflow; + YGDisplay display; + float flex; + float flexGrow; + float flexShrink; + YGValue flexBasis; + std::array margin; + std::array position; + std::array padding; + std::array border; + std::array dimensions; + std::array minDimensions; + std::array maxDimensions; + float aspectRatio; + + YGStyle(); + // Yoga specific properties, not compatible with flexbox specification + bool operator==(const YGStyle& style); + + bool operator!=(YGStyle style); + ~YGStyle(); +}; diff --git a/yoga/Yoga-internal.h b/yoga/Yoga-internal.h index 6432e6cf..b1bb0de3 100644 --- a/yoga/Yoga-internal.h +++ b/yoga/Yoga-internal.h @@ -10,7 +10,6 @@ #include #include #include - #include "Yoga.h" using YGVector = std::vector; @@ -42,6 +41,23 @@ bool YGValueArrayEqual( return areEqual; } +const YGValue kYGValueUndefined = {YGUndefined, YGUnitUndefined}; +const YGValue kYGValueAuto = {YGUndefined, YGUnitAuto}; +const std::array kYGDefaultEdgeValuesUnit = { + {kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined, + kYGValueUndefined}}; +const std::array kYGDefaultDimensionValuesAutoUnit = { + {kYGValueAuto, kYGValueAuto}}; +const std::array kYGDefaultDimensionValuesUnit = { + {kYGValueUndefined, kYGValueUndefined}}; + struct YGCachedMeasurement { float availableWidth; float availableHeight; @@ -141,74 +157,6 @@ struct YGLayout { } }; -struct YGStyle { - YGDirection direction; - YGFlexDirection flexDirection; - YGJustify justifyContent; - YGAlign alignContent; - YGAlign alignItems; - YGAlign alignSelf; - YGPositionType positionType; - YGWrap flexWrap; - YGOverflow overflow; - YGDisplay display; - float flex; - float flexGrow; - float flexShrink; - YGValue flexBasis; - std::array margin; - std::array position; - std::array padding; - std::array border; - std::array dimensions; - std::array minDimensions; - std::array maxDimensions; - - // Yoga specific properties, not compatible with flexbox specification - float aspectRatio; - bool operator==(YGStyle style) { - bool areNonFloatValuesEqual = direction == style.direction && - flexDirection == style.flexDirection && - justifyContent == style.justifyContent && - alignContent == style.alignContent && alignItems == style.alignItems && - alignSelf == style.alignSelf && positionType == style.positionType && - flexWrap == style.flexWrap && overflow == style.overflow && - display == style.display && YGValueEqual(flexBasis, style.flexBasis) && - YGValueArrayEqual(margin, style.margin) && - YGValueArrayEqual(position, style.position) && - YGValueArrayEqual(padding, style.padding) && - YGValueArrayEqual(border, style.border) && - YGValueArrayEqual(dimensions, style.dimensions) && - YGValueArrayEqual(minDimensions, style.minDimensions) && - YGValueArrayEqual(maxDimensions, style.maxDimensions); - - if (!(std::isnan(flex) && std::isnan(style.flex))) { - areNonFloatValuesEqual = areNonFloatValuesEqual && flex == style.flex; - } - - if (!(std::isnan(flexGrow) && std::isnan(style.flexGrow))) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && flexGrow == style.flexGrow; - } - - if (!(std::isnan(flexShrink) && std::isnan(style.flexShrink))) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && flexShrink == style.flexShrink; - } - - if (!(std::isnan(aspectRatio) && std::isnan(style.aspectRatio))) { - areNonFloatValuesEqual = - areNonFloatValuesEqual && aspectRatio == style.aspectRatio; - } - - return areNonFloatValuesEqual; - } - - bool operator!=(YGStyle style) { - return !(*this == style); - } -}; - struct YGConfig { bool experimentalFeatures[YGExperimentalFeatureCount + 1]; bool useWebDefaults; @@ -220,94 +168,10 @@ struct YGConfig { void* context; }; -#define YG_UNDEFINED_VALUES \ - { .value = YGUndefined, .unit = YGUnitUndefined } - -#define YG_AUTO_VALUES \ - { .value = YGUndefined, .unit = YGUnitAuto } - -#define YG_DEFAULT_EDGE_VALUES_UNIT \ - { \ - [YGEdgeLeft] = YG_UNDEFINED_VALUES, [YGEdgeTop] = YG_UNDEFINED_VALUES, \ - [YGEdgeRight] = YG_UNDEFINED_VALUES, [YGEdgeBottom] = YG_UNDEFINED_VALUES, \ - [YGEdgeStart] = YG_UNDEFINED_VALUES, [YGEdgeEnd] = YG_UNDEFINED_VALUES, \ - [YGEdgeHorizontal] = YG_UNDEFINED_VALUES, \ - [YGEdgeVertical] = YG_UNDEFINED_VALUES, [YGEdgeAll] = YG_UNDEFINED_VALUES, \ - } - -#define YG_DEFAULT_DIMENSION_VALUES \ - { [YGDimensionWidth] = YGUndefined, [YGDimensionHeight] = YGUndefined, } - -#define YG_DEFAULT_DIMENSION_VALUES_UNIT \ - { \ - [YGDimensionWidth] = YG_UNDEFINED_VALUES, \ - [YGDimensionHeight] = YG_UNDEFINED_VALUES, \ - } - -#define YG_DEFAULT_DIMENSION_VALUES_AUTO_UNIT \ - { [YGDimensionWidth] = YG_AUTO_VALUES, [YGDimensionHeight] = YG_AUTO_VALUES, } - static const float kDefaultFlexGrow = 0.0f; static const float kDefaultFlexShrink = 0.0f; static const float kWebDefaultFlexShrink = 1.0f; -static const YGStyle gYGNodeStyleDefaults = { - .direction = YGDirectionInherit, - .flexDirection = YGFlexDirectionColumn, - .justifyContent = YGJustifyFlexStart, - .alignContent = YGAlignFlexStart, - .alignItems = YGAlignStretch, - .alignSelf = YGAlignAuto, - .positionType = YGPositionTypeRelative, - .flexWrap = YGWrapNoWrap, - .overflow = YGOverflowVisible, - .display = YGDisplayFlex, - .flex = YGUndefined, - .flexGrow = YGUndefined, - .flexShrink = YGUndefined, - .flexBasis = YG_AUTO_VALUES, - .margin = {{YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES}}, - .position = {{YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES}}, - .padding = {{YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES}}, - .border = {{YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES, - YG_UNDEFINED_VALUES}}, - .dimensions = {{YG_AUTO_VALUES, YG_AUTO_VALUES}}, - .minDimensions = {{YG_UNDEFINED_VALUES, YG_UNDEFINED_VALUES}}, - .maxDimensions = {{YG_UNDEFINED_VALUES, YG_UNDEFINED_VALUES}}, - .aspectRatio = YGUndefined, -}; - static const YGLayout gYGNodeLayoutDefaults = { .position = {}, .dimensions = {{YGUndefined, YGUndefined}},