C++ Cleanup 8/N: Yoga-internal (#1355)
Summary: Pull Request resolved: https://github.com/facebook/yoga/pull/1355 X-link: https://github.com/facebook/react-native/pull/39198 ## This diff This splits up `Yoga-internal.h` which has become a grab bag. The actual header is left, with the purpose of being a private C ABI for bindings, but everything else is moved to a place more appropriate or removed. A few notes: 1. `yoga::isUndefined` is replaced with `std::isnan` to avoid a layer of indirection (we will never be able to change its representation anyway). Internal usages of `YGFloatIsUndefined` are also replaced with `std::isnan` since the previous being at a library boundary means I'm not sure it can be inlined/. 2. `leading`, `trailing` arrays are factored into proper functions 3. `Values` is replaced entirely with `std::array`, since most of it was unused. ## This stack The organization of the C++ internals of Yoga are in need of attention. 1. Some of the C++ internals are namespaced, but others not. 2. Some of the namespaces include `detail`, but are meant to be used outside of the translation unit (FB Clang Tidy rules warn on any usage of these) 2. Most of the files are in a flat hierarchy, except for event tracing in its own folder 3. Some files and functions begin with YG, others don’t 4. Some functions are uppercase, others are not 5. Almost all of the interesting logic is in Yoga.cpp, and the file is too large to reason about 6. There are multiple grab bag files where folks put random functions they need in (Utils, BitUtils, Yoga-Internal.h) 7. There is no clear indication from file structure or type naming what is private vs not 8. Handles like `YGNodeRef` and `YGConfigRef` can be used to access internals just by importing headers This stack does some much needed spring cleaning: 1. All non-public headers and C++ implementation details are in separate folders from the root level `yoga`. This will give us room to split up logic and add more files without too large a flat hierarchy 3. All private C++ internals are under the `facebook::yoga` namespace. Details namespaces are only ever used within the same header, as they are intended 4. Utils files are split 5. Most C++ internals drop the YG prefix 6. Most C++ internal function names are all lower camel case 7. We start to split up Yoga.cpp 8. Every header beginning with YG or at the top-level directory is public and C only, with the exception of Yoga-Internal.h which has non-public functions for bindings 9. It is not possible to use private APIs without static casting handles to internal classes This will give us more leeway to continue splitting monolithic files, and consistent guidelines for style in new files as well. These changes should not be breaking to any project using only public Yoga headers. This includes every usage of Yoga in fbsource except for RN Fabric which is currently tied to internals. This refactor should make that boundary clearer. Reviewed By: rshest Differential Revision: D48769241 fbshipit-source-id: 5b8e2192309539e7c133c3b3b29b445b59dd5835
This commit is contained in:
committed by
Facebook GitHub Bot
parent
31b6c0ddc9
commit
7be985d97c
@@ -15,6 +15,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include "YogaJniException.h"
|
#include "YogaJniException.h"
|
||||||
|
|
||||||
|
#include <yoga/Yoga-internal.h>
|
||||||
|
|
||||||
// TODO: Reconcile missing layoutContext functionality from callbacks in the C
|
// TODO: Reconcile missing layoutContext functionality from callbacks in the C
|
||||||
// API and use that
|
// API and use that
|
||||||
#include <yoga/node/Node.h>
|
#include <yoga/node/Node.h>
|
||||||
|
@@ -8,14 +8,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
|
|
||||||
#include <yoga/style/CompactValue.h>
|
|
||||||
|
|
||||||
YG_EXTERN_C_BEGIN
|
YG_EXTERN_C_BEGIN
|
||||||
|
|
||||||
void YGNodeCalculateLayoutWithContext(
|
void YGNodeCalculateLayoutWithContext(
|
||||||
@@ -30,120 +27,3 @@ void YGNodeCalculateLayoutWithContext(
|
|||||||
void YGNodeDeallocate(YGNodeRef node);
|
void YGNodeDeallocate(YGNodeRef node);
|
||||||
|
|
||||||
YG_EXTERN_C_END
|
YG_EXTERN_C_END
|
||||||
|
|
||||||
namespace facebook::yoga {
|
|
||||||
|
|
||||||
inline bool isUndefined(float value) {
|
|
||||||
return std::isnan(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isUndefined(double value) {
|
|
||||||
return std::isnan(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace facebook::yoga
|
|
||||||
|
|
||||||
extern const std::array<YGEdge, 4> trailing;
|
|
||||||
extern const std::array<YGEdge, 4> leading;
|
|
||||||
extern const YGValue YGValueUndefined;
|
|
||||||
extern const YGValue YGValueAuto;
|
|
||||||
extern const YGValue YGValueZero;
|
|
||||||
|
|
||||||
struct YGCachedMeasurement {
|
|
||||||
float availableWidth;
|
|
||||||
float availableHeight;
|
|
||||||
YGMeasureMode widthMeasureMode;
|
|
||||||
YGMeasureMode heightMeasureMode;
|
|
||||||
|
|
||||||
float computedWidth;
|
|
||||||
float computedHeight;
|
|
||||||
|
|
||||||
YGCachedMeasurement()
|
|
||||||
: availableWidth(-1),
|
|
||||||
availableHeight(-1),
|
|
||||||
widthMeasureMode(YGMeasureModeUndefined),
|
|
||||||
heightMeasureMode(YGMeasureModeUndefined),
|
|
||||||
computedWidth(-1),
|
|
||||||
computedHeight(-1) {}
|
|
||||||
|
|
||||||
bool operator==(YGCachedMeasurement measurement) const {
|
|
||||||
using namespace facebook;
|
|
||||||
|
|
||||||
bool isEqual = widthMeasureMode == measurement.widthMeasureMode &&
|
|
||||||
heightMeasureMode == measurement.heightMeasureMode;
|
|
||||||
|
|
||||||
if (!yoga::isUndefined(availableWidth) ||
|
|
||||||
!yoga::isUndefined(measurement.availableWidth)) {
|
|
||||||
isEqual = isEqual && availableWidth == measurement.availableWidth;
|
|
||||||
}
|
|
||||||
if (!yoga::isUndefined(availableHeight) ||
|
|
||||||
!yoga::isUndefined(measurement.availableHeight)) {
|
|
||||||
isEqual = isEqual && availableHeight == measurement.availableHeight;
|
|
||||||
}
|
|
||||||
if (!yoga::isUndefined(computedWidth) ||
|
|
||||||
!yoga::isUndefined(measurement.computedWidth)) {
|
|
||||||
isEqual = isEqual && computedWidth == measurement.computedWidth;
|
|
||||||
}
|
|
||||||
if (!yoga::isUndefined(computedHeight) ||
|
|
||||||
!yoga::isUndefined(measurement.computedHeight)) {
|
|
||||||
isEqual = isEqual && computedHeight == measurement.computedHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isEqual;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This value was chosen based on empirical data:
|
|
||||||
// 98% of analyzed layouts require less than 8 entries.
|
|
||||||
#define YG_MAX_CACHED_RESULT_COUNT 8
|
|
||||||
|
|
||||||
namespace facebook::yoga::detail {
|
|
||||||
|
|
||||||
template <size_t Size>
|
|
||||||
class Values {
|
|
||||||
private:
|
|
||||||
std::array<CompactValue, Size> values_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Values() = default;
|
|
||||||
Values(const Values& other) = default;
|
|
||||||
|
|
||||||
explicit Values(const YGValue& defaultValue) noexcept {
|
|
||||||
values_.fill(defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
const CompactValue& operator[](size_t i) const noexcept { return values_[i]; }
|
|
||||||
CompactValue& operator[](size_t i) noexcept { return values_[i]; }
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
YGValue get() const noexcept {
|
|
||||||
return std::get<I>(values_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
void set(YGValue& value) noexcept {
|
|
||||||
std::get<I>(values_) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t I>
|
|
||||||
void set(YGValue&& value) noexcept {
|
|
||||||
set<I>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Values& other) const noexcept {
|
|
||||||
for (size_t i = 0; i < Size; ++i) {
|
|
||||||
if (values_[i] != other.values_[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Values& operator=(const Values& other) = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace facebook::yoga::detail
|
|
||||||
|
|
||||||
static const float kDefaultFlexGrow = 0.0f;
|
|
||||||
static const float kDefaultFlexShrink = 0.0f;
|
|
||||||
static const float kWebDefaultFlexShrink = 1.0f;
|
|
||||||
|
162
yoga/Yoga.cpp
162
yoga/Yoga.cpp
@@ -8,6 +8,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -102,12 +103,8 @@ static int YGDefaultLog(
|
|||||||
#undef YG_UNUSED
|
#undef YG_UNUSED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline bool YGDoubleIsUndefined(const double value) {
|
|
||||||
return facebook::yoga::isUndefined(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
YOGA_EXPORT bool YGFloatIsUndefined(const float value) {
|
YOGA_EXPORT bool YGFloatIsUndefined(const float value) {
|
||||||
return facebook::yoga::isUndefined(value);
|
return yoga::isUndefined(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) {
|
YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) {
|
||||||
@@ -483,15 +480,15 @@ YOGA_EXPORT void YGNodeCopyStyle(
|
|||||||
YOGA_EXPORT float YGNodeStyleGetFlexGrow(const YGNodeConstRef nodeRef) {
|
YOGA_EXPORT float YGNodeStyleGetFlexGrow(const YGNodeConstRef nodeRef) {
|
||||||
auto node = static_cast<const yoga::Node*>(nodeRef);
|
auto node = static_cast<const yoga::Node*>(nodeRef);
|
||||||
return node->getStyle().flexGrow().isUndefined()
|
return node->getStyle().flexGrow().isUndefined()
|
||||||
? kDefaultFlexGrow
|
? Style::DefaultFlexGrow
|
||||||
: node->getStyle().flexGrow().unwrap();
|
: node->getStyle().flexGrow().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
YOGA_EXPORT float YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) {
|
YOGA_EXPORT float YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) {
|
||||||
auto node = static_cast<const yoga::Node*>(nodeRef);
|
auto node = static_cast<const yoga::Node*>(nodeRef);
|
||||||
return node->getStyle().flexShrink().isUndefined()
|
return node->getStyle().flexShrink().isUndefined()
|
||||||
? (node->getConfig()->useWebDefaults() ? kWebDefaultFlexShrink
|
? (node->getConfig()->useWebDefaults() ? Style::WebDefaultFlexShrink
|
||||||
: kDefaultFlexShrink)
|
: Style::DefaultFlexShrink)
|
||||||
: node->getStyle().flexShrink().unwrap();
|
: node->getStyle().flexShrink().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,11 +1010,6 @@ YOGA_EXPORT void YGNodePrint(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const std::array<YGEdge, 4> leading = {
|
|
||||||
{YGEdgeTop, YGEdgeBottom, YGEdgeLeft, YGEdgeRight}};
|
|
||||||
|
|
||||||
const std::array<YGEdge, 4> trailing = {
|
|
||||||
{YGEdgeBottom, YGEdgeTop, YGEdgeRight, YGEdgeLeft}};
|
|
||||||
static const std::array<YGEdge, 4> pos = {{
|
static const std::array<YGEdge, 4> pos = {{
|
||||||
YGEdgeTop,
|
YGEdgeTop,
|
||||||
YGEdgeBottom,
|
YGEdgeBottom,
|
||||||
@@ -1063,7 +1055,7 @@ static float YGBaseline(yoga::Node* node, void* layoutContext) {
|
|||||||
|
|
||||||
YGAssertWithNode(
|
YGAssertWithNode(
|
||||||
node,
|
node,
|
||||||
!YGFloatIsUndefined(baseline),
|
!yoga::isUndefined(baseline),
|
||||||
"Expect custom baseline function to not return NaN");
|
"Expect custom baseline function to not return NaN");
|
||||||
return baseline;
|
return baseline;
|
||||||
}
|
}
|
||||||
@@ -1131,7 +1123,7 @@ static inline bool YGNodeIsStyleDimDefined(
|
|||||||
const YGFlexDirection axis,
|
const YGFlexDirection axis,
|
||||||
const float ownerSize) {
|
const float ownerSize) {
|
||||||
bool isUndefined =
|
bool isUndefined =
|
||||||
YGFloatIsUndefined(node->getResolvedDimension(dim[axis]).value);
|
yoga::isUndefined(node->getResolvedDimension(dim[axis]).value);
|
||||||
return !(
|
return !(
|
||||||
node->getResolvedDimension(dim[axis]).unit == YGUnitAuto ||
|
node->getResolvedDimension(dim[axis]).unit == YGUnitAuto ||
|
||||||
node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined ||
|
node->getResolvedDimension(dim[axis]).unit == YGUnitUndefined ||
|
||||||
@@ -1140,14 +1132,14 @@ static inline bool YGNodeIsStyleDimDefined(
|
|||||||
(node->getResolvedDimension(dim[axis]).unit == YGUnitPercent &&
|
(node->getResolvedDimension(dim[axis]).unit == YGUnitPercent &&
|
||||||
!isUndefined &&
|
!isUndefined &&
|
||||||
(node->getResolvedDimension(dim[axis]).value < 0.0f ||
|
(node->getResolvedDimension(dim[axis]).value < 0.0f ||
|
||||||
YGFloatIsUndefined(ownerSize))));
|
yoga::isUndefined(ownerSize))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool YGNodeIsLayoutDimDefined(
|
static inline bool YGNodeIsLayoutDimDefined(
|
||||||
const yoga::Node* const node,
|
const yoga::Node* const node,
|
||||||
const YGFlexDirection axis) {
|
const YGFlexDirection axis) {
|
||||||
const float value = node->getLayout().measuredDimensions[dim[axis]];
|
const float value = node->getLayout().measuredDimensions[dim[axis]];
|
||||||
return !YGFloatIsUndefined(value) && value >= 0.0f;
|
return !yoga::isUndefined(value) && value >= 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FloatOptional YGNodeBoundAxisWithinMinAndMax(
|
static FloatOptional YGNodeBoundAxisWithinMinAndMax(
|
||||||
@@ -1203,7 +1195,7 @@ static void YGNodeSetChildTrailingPosition(
|
|||||||
child->setLayoutPosition(
|
child->setLayoutPosition(
|
||||||
node->getLayout().measuredDimensions[dim[axis]] - size -
|
node->getLayout().measuredDimensions[dim[axis]] - size -
|
||||||
child->getLayout().position[pos[axis]],
|
child->getLayout().position[pos[axis]],
|
||||||
trailing[axis]);
|
trailingEdge(axis));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void YGConstrainMaxSizeForMode(
|
static void YGConstrainMaxSizeForMode(
|
||||||
@@ -1266,7 +1258,7 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
const bool isColumnStyleDimDefined =
|
const bool isColumnStyleDimDefined =
|
||||||
YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, ownerHeight);
|
YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, ownerHeight);
|
||||||
|
|
||||||
if (!resolvedFlexBasis.isUndefined() && !YGFloatIsUndefined(mainAxisSize)) {
|
if (!resolvedFlexBasis.isUndefined() && !yoga::isUndefined(mainAxisSize)) {
|
||||||
if (child->getLayout().computedFlexBasis.isUndefined() ||
|
if (child->getLayout().computedFlexBasis.isUndefined() ||
|
||||||
(child->getConfig()->isExperimentalFeatureEnabled(
|
(child->getConfig()->isExperimentalFeatureEnabled(
|
||||||
YGExperimentalFeatureWebFlexBasis) &&
|
YGExperimentalFeatureWebFlexBasis) &&
|
||||||
@@ -1328,7 +1320,7 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
// major browsers appear to implement the following logic.
|
// major browsers appear to implement the following logic.
|
||||||
if ((!isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
|
if ((!isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
|
||||||
node->getStyle().overflow() != YGOverflowScroll) {
|
node->getStyle().overflow() != YGOverflowScroll) {
|
||||||
if (YGFloatIsUndefined(childWidth) && !YGFloatIsUndefined(width)) {
|
if (yoga::isUndefined(childWidth) && !yoga::isUndefined(width)) {
|
||||||
childWidth = width;
|
childWidth = width;
|
||||||
childWidthMeasureMode = YGMeasureModeAtMost;
|
childWidthMeasureMode = YGMeasureModeAtMost;
|
||||||
}
|
}
|
||||||
@@ -1336,7 +1328,7 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
|
|
||||||
if ((isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
|
if ((isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
|
||||||
node->getStyle().overflow() != YGOverflowScroll) {
|
node->getStyle().overflow() != YGOverflowScroll) {
|
||||||
if (YGFloatIsUndefined(childHeight) && !YGFloatIsUndefined(height)) {
|
if (yoga::isUndefined(childHeight) && !yoga::isUndefined(height)) {
|
||||||
childHeight = height;
|
childHeight = height;
|
||||||
childHeightMeasureMode = YGMeasureModeAtMost;
|
childHeightMeasureMode = YGMeasureModeAtMost;
|
||||||
}
|
}
|
||||||
@@ -1360,7 +1352,7 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
// the cross axis to be measured exactly with the available inner width
|
// the cross axis to be measured exactly with the available inner width
|
||||||
|
|
||||||
const bool hasExactWidth =
|
const bool hasExactWidth =
|
||||||
!YGFloatIsUndefined(width) && widthMode == YGMeasureModeExactly;
|
!yoga::isUndefined(width) && widthMode == YGMeasureModeExactly;
|
||||||
const bool childWidthStretch =
|
const bool childWidthStretch =
|
||||||
YGNodeAlignItem(node, child) == YGAlignStretch &&
|
YGNodeAlignItem(node, child) == YGAlignStretch &&
|
||||||
childWidthMeasureMode != YGMeasureModeExactly;
|
childWidthMeasureMode != YGMeasureModeExactly;
|
||||||
@@ -1376,7 +1368,7 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool hasExactHeight =
|
const bool hasExactHeight =
|
||||||
!YGFloatIsUndefined(height) && heightMode == YGMeasureModeExactly;
|
!yoga::isUndefined(height) && heightMode == YGMeasureModeExactly;
|
||||||
const bool childHeightStretch =
|
const bool childHeightStretch =
|
||||||
YGNodeAlignItem(node, child) == YGAlignStretch &&
|
YGNodeAlignItem(node, child) == YGAlignStretch &&
|
||||||
childHeightMeasureMode != YGMeasureModeExactly;
|
childHeightMeasureMode != YGMeasureModeExactly;
|
||||||
@@ -1504,12 +1496,12 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
// ratio calculation. One dimension being the anchor and the other being
|
// ratio calculation. One dimension being the anchor and the other being
|
||||||
// flexible.
|
// flexible.
|
||||||
const auto& childStyle = child->getStyle();
|
const auto& childStyle = child->getStyle();
|
||||||
if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) {
|
if (yoga::isUndefined(childWidth) ^ yoga::isUndefined(childHeight)) {
|
||||||
if (!childStyle.aspectRatio().isUndefined()) {
|
if (!childStyle.aspectRatio().isUndefined()) {
|
||||||
if (YGFloatIsUndefined(childWidth)) {
|
if (yoga::isUndefined(childWidth)) {
|
||||||
childWidth = marginRow +
|
childWidth = marginRow +
|
||||||
(childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
|
(childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
|
||||||
} else if (YGFloatIsUndefined(childHeight)) {
|
} else if (yoga::isUndefined(childHeight)) {
|
||||||
childHeight = marginColumn +
|
childHeight = marginColumn +
|
||||||
(childWidth - marginRow) / childStyle.aspectRatio().unwrap();
|
(childWidth - marginRow) / childStyle.aspectRatio().unwrap();
|
||||||
}
|
}
|
||||||
@@ -1517,11 +1509,11 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we're still missing one or the other dimension, measure the content.
|
// If we're still missing one or the other dimension, measure the content.
|
||||||
if (YGFloatIsUndefined(childWidth) || YGFloatIsUndefined(childHeight)) {
|
if (yoga::isUndefined(childWidth) || yoga::isUndefined(childHeight)) {
|
||||||
childWidthMeasureMode = YGFloatIsUndefined(childWidth)
|
childWidthMeasureMode = yoga::isUndefined(childWidth)
|
||||||
? YGMeasureModeUndefined
|
? YGMeasureModeUndefined
|
||||||
: YGMeasureModeExactly;
|
: YGMeasureModeExactly;
|
||||||
childHeightMeasureMode = YGFloatIsUndefined(childHeight)
|
childHeightMeasureMode = yoga::isUndefined(childHeight)
|
||||||
? YGMeasureModeUndefined
|
? YGMeasureModeUndefined
|
||||||
: YGMeasureModeExactly;
|
: YGMeasureModeExactly;
|
||||||
|
|
||||||
@@ -1529,8 +1521,8 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
// child to that size as well. This allows text within the absolute child to
|
// child to that size as well. This allows text within the absolute child to
|
||||||
// wrap to the size of its owner. This is the same behavior as many browsers
|
// wrap to the size of its owner. This is the same behavior as many browsers
|
||||||
// implement.
|
// implement.
|
||||||
if (!isMainAxisRow && YGFloatIsUndefined(childWidth) &&
|
if (!isMainAxisRow && yoga::isUndefined(childWidth) &&
|
||||||
widthMode != YGMeasureModeUndefined && !YGFloatIsUndefined(width) &&
|
widthMode != YGMeasureModeUndefined && !yoga::isUndefined(width) &&
|
||||||
width > 0) {
|
width > 0) {
|
||||||
childWidth = width;
|
childWidth = width;
|
||||||
childWidthMeasureMode = YGMeasureModeAtMost;
|
childWidthMeasureMode = YGMeasureModeAtMost;
|
||||||
@@ -1585,7 +1577,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
.unwrap() -
|
.unwrap() -
|
||||||
child->getTrailingPosition(mainAxis, isMainAxisRow ? width : height)
|
child->getTrailingPosition(mainAxis, isMainAxisRow ? width : height)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
leading[mainAxis]);
|
leadingEdge(mainAxis));
|
||||||
} else if (
|
} else if (
|
||||||
!child->isLeadingPositionDefined(mainAxis) &&
|
!child->isLeadingPositionDefined(mainAxis) &&
|
||||||
node->getStyle().justifyContent() == YGJustifyCenter) {
|
node->getStyle().justifyContent() == YGJustifyCenter) {
|
||||||
@@ -1593,14 +1585,14 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
(node->getLayout().measuredDimensions[dim[mainAxis]] -
|
(node->getLayout().measuredDimensions[dim[mainAxis]] -
|
||||||
child->getLayout().measuredDimensions[dim[mainAxis]]) /
|
child->getLayout().measuredDimensions[dim[mainAxis]]) /
|
||||||
2.0f,
|
2.0f,
|
||||||
leading[mainAxis]);
|
leadingEdge(mainAxis));
|
||||||
} else if (
|
} else if (
|
||||||
!child->isLeadingPositionDefined(mainAxis) &&
|
!child->isLeadingPositionDefined(mainAxis) &&
|
||||||
node->getStyle().justifyContent() == YGJustifyFlexEnd) {
|
node->getStyle().justifyContent() == YGJustifyFlexEnd) {
|
||||||
child->setLayoutPosition(
|
child->setLayoutPosition(
|
||||||
(node->getLayout().measuredDimensions[dim[mainAxis]] -
|
(node->getLayout().measuredDimensions[dim[mainAxis]] -
|
||||||
child->getLayout().measuredDimensions[dim[mainAxis]]),
|
child->getLayout().measuredDimensions[dim[mainAxis]]),
|
||||||
leading[mainAxis]);
|
leadingEdge(mainAxis));
|
||||||
} else if (
|
} else if (
|
||||||
node->getConfig()->isExperimentalFeatureEnabled(
|
node->getConfig()->isExperimentalFeatureEnabled(
|
||||||
YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge) &&
|
YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge) &&
|
||||||
@@ -1615,7 +1607,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
mainAxis,
|
mainAxis,
|
||||||
node->getLayout().measuredDimensions[dim[mainAxis]])
|
node->getLayout().measuredDimensions[dim[mainAxis]])
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
leading[mainAxis]);
|
leadingEdge(mainAxis));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child->isTrailingPosDefined(crossAxis) &&
|
if (child->isTrailingPosDefined(crossAxis) &&
|
||||||
@@ -1629,7 +1621,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
child
|
child
|
||||||
->getTrailingPosition(crossAxis, isMainAxisRow ? height : width)
|
->getTrailingPosition(crossAxis, isMainAxisRow ? height : width)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
leading[crossAxis]);
|
leadingEdge(crossAxis));
|
||||||
|
|
||||||
} else if (
|
} else if (
|
||||||
!child->isLeadingPositionDefined(crossAxis) &&
|
!child->isLeadingPositionDefined(crossAxis) &&
|
||||||
@@ -1638,7 +1630,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
(node->getLayout().measuredDimensions[dim[crossAxis]] -
|
(node->getLayout().measuredDimensions[dim[crossAxis]] -
|
||||||
child->getLayout().measuredDimensions[dim[crossAxis]]) /
|
child->getLayout().measuredDimensions[dim[crossAxis]]) /
|
||||||
2.0f,
|
2.0f,
|
||||||
leading[crossAxis]);
|
leadingEdge(crossAxis));
|
||||||
} else if (
|
} else if (
|
||||||
!child->isLeadingPositionDefined(crossAxis) &&
|
!child->isLeadingPositionDefined(crossAxis) &&
|
||||||
((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^
|
((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^
|
||||||
@@ -1646,7 +1638,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
child->setLayoutPosition(
|
child->setLayoutPosition(
|
||||||
(node->getLayout().measuredDimensions[dim[crossAxis]] -
|
(node->getLayout().measuredDimensions[dim[crossAxis]] -
|
||||||
child->getLayout().measuredDimensions[dim[crossAxis]]),
|
child->getLayout().measuredDimensions[dim[crossAxis]]),
|
||||||
leading[crossAxis]);
|
leadingEdge(crossAxis));
|
||||||
} else if (
|
} else if (
|
||||||
node->getConfig()->isExperimentalFeatureEnabled(
|
node->getConfig()->isExperimentalFeatureEnabled(
|
||||||
YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge) &&
|
YGExperimentalFeatureAbsolutePercentageAgainstPaddingEdge) &&
|
||||||
@@ -1662,7 +1654,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
crossAxis,
|
crossAxis,
|
||||||
node->getLayout().measuredDimensions[dim[crossAxis]])
|
node->getLayout().measuredDimensions[dim[crossAxis]])
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
leading[crossAxis]);
|
leadingEdge(crossAxis));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1697,10 +1689,10 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(
|
|||||||
padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom];
|
padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom];
|
||||||
|
|
||||||
// We want to make sure we don't call measure with negative size
|
// We want to make sure we don't call measure with negative size
|
||||||
const float innerWidth = YGFloatIsUndefined(availableWidth)
|
const float innerWidth = yoga::isUndefined(availableWidth)
|
||||||
? availableWidth
|
? availableWidth
|
||||||
: yoga::maxOrDefined(0, availableWidth - paddingAndBorderAxisRow);
|
: yoga::maxOrDefined(0, availableWidth - paddingAndBorderAxisRow);
|
||||||
const float innerHeight = YGFloatIsUndefined(availableHeight)
|
const float innerHeight = yoga::isUndefined(availableHeight)
|
||||||
? availableHeight
|
? availableHeight
|
||||||
: yoga::maxOrDefined(0, availableHeight - paddingAndBorderAxisColumn);
|
: yoga::maxOrDefined(0, availableHeight - paddingAndBorderAxisColumn);
|
||||||
|
|
||||||
@@ -1814,9 +1806,9 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(
|
|||||||
const YGMeasureMode heightMeasureMode,
|
const YGMeasureMode heightMeasureMode,
|
||||||
const float ownerWidth,
|
const float ownerWidth,
|
||||||
const float ownerHeight) {
|
const float ownerHeight) {
|
||||||
if ((!YGFloatIsUndefined(availableWidth) &&
|
if ((!yoga::isUndefined(availableWidth) &&
|
||||||
widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) ||
|
widthMeasureMode == YGMeasureModeAtMost && availableWidth <= 0.0f) ||
|
||||||
(!YGFloatIsUndefined(availableHeight) &&
|
(!yoga::isUndefined(availableHeight) &&
|
||||||
heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) ||
|
heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) ||
|
||||||
(widthMeasureMode == YGMeasureModeExactly &&
|
(widthMeasureMode == YGMeasureModeExactly &&
|
||||||
heightMeasureMode == YGMeasureModeExactly)) {
|
heightMeasureMode == YGMeasureModeExactly)) {
|
||||||
@@ -1824,7 +1816,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(
|
|||||||
YGNodeBoundAxis(
|
YGNodeBoundAxis(
|
||||||
node,
|
node,
|
||||||
YGFlexDirectionRow,
|
YGFlexDirectionRow,
|
||||||
YGFloatIsUndefined(availableWidth) ||
|
yoga::isUndefined(availableWidth) ||
|
||||||
(widthMeasureMode == YGMeasureModeAtMost &&
|
(widthMeasureMode == YGMeasureModeAtMost &&
|
||||||
availableWidth < 0.0f)
|
availableWidth < 0.0f)
|
||||||
? 0.0f
|
? 0.0f
|
||||||
@@ -1837,7 +1829,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(
|
|||||||
YGNodeBoundAxis(
|
YGNodeBoundAxis(
|
||||||
node,
|
node,
|
||||||
YGFlexDirectionColumn,
|
YGFlexDirectionColumn,
|
||||||
YGFloatIsUndefined(availableHeight) ||
|
yoga::isUndefined(availableHeight) ||
|
||||||
(heightMeasureMode == YGMeasureModeAtMost &&
|
(heightMeasureMode == YGMeasureModeAtMost &&
|
||||||
availableHeight < 0.0f)
|
availableHeight < 0.0f)
|
||||||
? 0.0f
|
? 0.0f
|
||||||
@@ -1872,7 +1864,7 @@ static float YGNodeCalculateAvailableInnerDim(
|
|||||||
float availableInnerDim = availableDim - paddingAndBorder;
|
float availableInnerDim = availableDim - paddingAndBorder;
|
||||||
// Max dimension overrides predefined dimension value; Min dimension in turn
|
// Max dimension overrides predefined dimension value; Min dimension in turn
|
||||||
// overrides both of the above
|
// overrides both of the above
|
||||||
if (!YGFloatIsUndefined(availableInnerDim)) {
|
if (!yoga::isUndefined(availableInnerDim)) {
|
||||||
// We want to make sure our available height does not violate min and max
|
// We want to make sure our available height does not violate min and max
|
||||||
// constraints
|
// constraints
|
||||||
const FloatOptional minDimensionOptional = yoga::resolveValue(
|
const FloatOptional minDimensionOptional = yoga::resolveValue(
|
||||||
@@ -2114,7 +2106,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
float updatedMainSize = childFlexBasis;
|
float updatedMainSize = childFlexBasis;
|
||||||
|
|
||||||
if (!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
if (!yoga::isUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
||||||
collectedFlexItemsValues.remainingFreeSpace < 0) {
|
collectedFlexItemsValues.remainingFreeSpace < 0) {
|
||||||
flexShrinkScaledFactor =
|
flexShrinkScaledFactor =
|
||||||
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
||||||
@@ -2122,7 +2114,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
if (flexShrinkScaledFactor != 0) {
|
if (flexShrinkScaledFactor != 0) {
|
||||||
float childSize;
|
float childSize;
|
||||||
|
|
||||||
if (!YGFloatIsUndefined(
|
if (!yoga::isUndefined(
|
||||||
collectedFlexItemsValues.totalFlexShrinkScaledFactors) &&
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors) &&
|
||||||
collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
|
collectedFlexItemsValues.totalFlexShrinkScaledFactors == 0) {
|
||||||
childSize = childFlexBasis + flexShrinkScaledFactor;
|
childSize = childFlexBasis + flexShrinkScaledFactor;
|
||||||
@@ -2141,12 +2133,12 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
!yoga::isUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
||||||
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
||||||
|
|
||||||
// Is this child able to grow?
|
// Is this child able to grow?
|
||||||
if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) {
|
if (!yoga::isUndefined(flexGrowFactor) && flexGrowFactor != 0) {
|
||||||
updatedMainSize = YGNodeBoundAxis(
|
updatedMainSize = YGNodeBoundAxis(
|
||||||
currentRelativeChild,
|
currentRelativeChild,
|
||||||
mainAxis,
|
mainAxis,
|
||||||
@@ -2182,7 +2174,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
|
|
||||||
childCrossSize += marginCross;
|
childCrossSize += marginCross;
|
||||||
} else if (
|
} else if (
|
||||||
!YGFloatIsUndefined(availableInnerCrossDim) &&
|
!yoga::isUndefined(availableInnerCrossDim) &&
|
||||||
!YGNodeIsStyleDimDefined(
|
!YGNodeIsStyleDimDefined(
|
||||||
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
currentRelativeChild, crossAxis, availableInnerCrossDim) &&
|
||||||
measureModeCrossDim == YGMeasureModeExactly &&
|
measureModeCrossDim == YGMeasureModeExactly &&
|
||||||
@@ -2197,7 +2189,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
} else if (!YGNodeIsStyleDimDefined(
|
} else if (!YGNodeIsStyleDimDefined(
|
||||||
currentRelativeChild, crossAxis, availableInnerCrossDim)) {
|
currentRelativeChild, crossAxis, availableInnerCrossDim)) {
|
||||||
childCrossSize = availableInnerCrossDim;
|
childCrossSize = availableInnerCrossDim;
|
||||||
childCrossMeasureMode = YGFloatIsUndefined(childCrossSize)
|
childCrossMeasureMode = yoga::isUndefined(childCrossSize)
|
||||||
? YGMeasureModeUndefined
|
? YGMeasureModeUndefined
|
||||||
: YGMeasureModeAtMost;
|
: YGMeasureModeAtMost;
|
||||||
} else {
|
} else {
|
||||||
@@ -2212,7 +2204,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
YGUnitPercent &&
|
YGUnitPercent &&
|
||||||
measureModeCrossDim != YGMeasureModeExactly;
|
measureModeCrossDim != YGMeasureModeExactly;
|
||||||
childCrossMeasureMode =
|
childCrossMeasureMode =
|
||||||
YGFloatIsUndefined(childCrossSize) || isLoosePercentageMeasurement
|
yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement
|
||||||
? YGMeasureModeUndefined
|
? YGMeasureModeUndefined
|
||||||
: YGMeasureModeExactly;
|
: YGMeasureModeExactly;
|
||||||
}
|
}
|
||||||
@@ -2304,7 +2296,7 @@ static void YGDistributeFreeSpaceFirstPass(
|
|||||||
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
-currentRelativeChild->resolveFlexShrink() * childFlexBasis;
|
||||||
|
|
||||||
// Is this child able to shrink?
|
// Is this child able to shrink?
|
||||||
if (!YGFloatIsUndefined(flexShrinkScaledFactor) &&
|
if (!yoga::isUndefined(flexShrinkScaledFactor) &&
|
||||||
flexShrinkScaledFactor != 0) {
|
flexShrinkScaledFactor != 0) {
|
||||||
baseMainSize = childFlexBasis +
|
baseMainSize = childFlexBasis +
|
||||||
collectedFlexItemsValues.remainingFreeSpace /
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
@@ -2316,8 +2308,8 @@ static void YGDistributeFreeSpaceFirstPass(
|
|||||||
baseMainSize,
|
baseMainSize,
|
||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
if (!YGFloatIsUndefined(baseMainSize) &&
|
if (!yoga::isUndefined(baseMainSize) &&
|
||||||
!YGFloatIsUndefined(boundMainSize) &&
|
!yoga::isUndefined(boundMainSize) &&
|
||||||
baseMainSize != boundMainSize) {
|
baseMainSize != boundMainSize) {
|
||||||
// By excluding this item's size and flex factor from remaining, this
|
// By excluding this item's size and flex factor from remaining, this
|
||||||
// item's min/max constraints should also trigger in the second pass
|
// item's min/max constraints should also trigger in the second pass
|
||||||
@@ -2330,12 +2322,12 @@ static void YGDistributeFreeSpaceFirstPass(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
!YGFloatIsUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
!yoga::isUndefined(collectedFlexItemsValues.remainingFreeSpace) &&
|
||||||
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
collectedFlexItemsValues.remainingFreeSpace > 0) {
|
||||||
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
flexGrowFactor = currentRelativeChild->resolveFlexGrow();
|
||||||
|
|
||||||
// Is this child able to grow?
|
// Is this child able to grow?
|
||||||
if (!YGFloatIsUndefined(flexGrowFactor) && flexGrowFactor != 0) {
|
if (!yoga::isUndefined(flexGrowFactor) && flexGrowFactor != 0) {
|
||||||
baseMainSize = childFlexBasis +
|
baseMainSize = childFlexBasis +
|
||||||
collectedFlexItemsValues.remainingFreeSpace /
|
collectedFlexItemsValues.remainingFreeSpace /
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor;
|
collectedFlexItemsValues.totalFlexGrowFactors * flexGrowFactor;
|
||||||
@@ -2346,8 +2338,8 @@ static void YGDistributeFreeSpaceFirstPass(
|
|||||||
availableInnerMainDim,
|
availableInnerMainDim,
|
||||||
availableInnerWidth);
|
availableInnerWidth);
|
||||||
|
|
||||||
if (!YGFloatIsUndefined(baseMainSize) &&
|
if (!yoga::isUndefined(baseMainSize) &&
|
||||||
!YGFloatIsUndefined(boundMainSize) &&
|
!yoga::isUndefined(boundMainSize) &&
|
||||||
baseMainSize != boundMainSize) {
|
baseMainSize != boundMainSize) {
|
||||||
// By excluding this item's size and flex factor from remaining, this
|
// By excluding this item's size and flex factor from remaining, this
|
||||||
// item's min/max constraints should also trigger in the second pass
|
// item's min/max constraints should also trigger in the second pass
|
||||||
@@ -2741,14 +2733,14 @@ static void YGNodelayoutImpl(
|
|||||||
const LayoutPassReason reason) {
|
const LayoutPassReason reason) {
|
||||||
YGAssertWithNode(
|
YGAssertWithNode(
|
||||||
node,
|
node,
|
||||||
YGFloatIsUndefined(availableWidth)
|
yoga::isUndefined(availableWidth)
|
||||||
? widthMeasureMode == YGMeasureModeUndefined
|
? widthMeasureMode == YGMeasureModeUndefined
|
||||||
: true,
|
: true,
|
||||||
"availableWidth is indefinite so widthMeasureMode must be "
|
"availableWidth is indefinite so widthMeasureMode must be "
|
||||||
"YGMeasureModeUndefined");
|
"YGMeasureModeUndefined");
|
||||||
YGAssertWithNode(
|
YGAssertWithNode(
|
||||||
node,
|
node,
|
||||||
YGFloatIsUndefined(availableHeight)
|
yoga::isUndefined(availableHeight)
|
||||||
? heightMeasureMode == YGMeasureModeUndefined
|
? heightMeasureMode == YGMeasureModeUndefined
|
||||||
: true,
|
: true,
|
||||||
"availableHeight is indefinite so heightMeasureMode must be "
|
"availableHeight is indefinite so heightMeasureMode must be "
|
||||||
@@ -3001,12 +2993,12 @@ static void YGNodelayoutImpl(
|
|||||||
const float maxInnerMainDim =
|
const float maxInnerMainDim =
|
||||||
isMainAxisRow ? maxInnerWidth : maxInnerHeight;
|
isMainAxisRow ? maxInnerWidth : maxInnerHeight;
|
||||||
|
|
||||||
if (!YGFloatIsUndefined(minInnerMainDim) &&
|
if (!yoga::isUndefined(minInnerMainDim) &&
|
||||||
collectedFlexItemsValues.sizeConsumedOnCurrentLine <
|
collectedFlexItemsValues.sizeConsumedOnCurrentLine <
|
||||||
minInnerMainDim) {
|
minInnerMainDim) {
|
||||||
availableInnerMainDim = minInnerMainDim;
|
availableInnerMainDim = minInnerMainDim;
|
||||||
} else if (
|
} else if (
|
||||||
!YGFloatIsUndefined(maxInnerMainDim) &&
|
!yoga::isUndefined(maxInnerMainDim) &&
|
||||||
collectedFlexItemsValues.sizeConsumedOnCurrentLine >
|
collectedFlexItemsValues.sizeConsumedOnCurrentLine >
|
||||||
maxInnerMainDim) {
|
maxInnerMainDim) {
|
||||||
availableInnerMainDim = maxInnerMainDim;
|
availableInnerMainDim = maxInnerMainDim;
|
||||||
@@ -3015,10 +3007,10 @@ static void YGNodelayoutImpl(
|
|||||||
node->hasErrata(YGErrataStretchFlexBasis);
|
node->hasErrata(YGErrataStretchFlexBasis);
|
||||||
|
|
||||||
if (!useLegacyStretchBehaviour &&
|
if (!useLegacyStretchBehaviour &&
|
||||||
((!YGFloatIsUndefined(
|
((!yoga::isUndefined(
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors) &&
|
collectedFlexItemsValues.totalFlexGrowFactors) &&
|
||||||
collectedFlexItemsValues.totalFlexGrowFactors == 0) ||
|
collectedFlexItemsValues.totalFlexGrowFactors == 0) ||
|
||||||
(!YGFloatIsUndefined(node->resolveFlexGrow()) &&
|
(!yoga::isUndefined(node->resolveFlexGrow()) &&
|
||||||
node->resolveFlexGrow() == 0))) {
|
node->resolveFlexGrow() == 0))) {
|
||||||
// If we don't have any children to flex or we can't flex the node
|
// If we don't have any children to flex or we can't flex the node
|
||||||
// itself, space we've used is all space we need. Root node also
|
// itself, space we've used is all space we need. Root node also
|
||||||
@@ -3031,7 +3023,7 @@ static void YGNodelayoutImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sizeBasedOnContent && !YGFloatIsUndefined(availableInnerMainDim)) {
|
if (!sizeBasedOnContent && !yoga::isUndefined(availableInnerMainDim)) {
|
||||||
collectedFlexItemsValues.remainingFreeSpace = availableInnerMainDim -
|
collectedFlexItemsValues.remainingFreeSpace = availableInnerMainDim -
|
||||||
collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
||||||
} else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) {
|
} else if (collectedFlexItemsValues.sizeConsumedOnCurrentLine < 0) {
|
||||||
@@ -3146,7 +3138,7 @@ static void YGNodelayoutImpl(
|
|||||||
// If leading position is not defined or calculations result in Nan,
|
// If leading position is not defined or calculations result in Nan,
|
||||||
// default to border + margin
|
// default to border + margin
|
||||||
if (!isChildLeadingPosDefined ||
|
if (!isChildLeadingPosDefined ||
|
||||||
YGFloatIsUndefined(child->getLayout().position[pos[crossAxis]])) {
|
yoga::isUndefined(child->getLayout().position[pos[crossAxis]])) {
|
||||||
child->setLayoutPosition(
|
child->setLayoutPosition(
|
||||||
node->getLeadingBorder(crossAxis) +
|
node->getLeadingBorder(crossAxis) +
|
||||||
child->getLeadingMargin(crossAxis, availableInnerWidth)
|
child->getLeadingMargin(crossAxis, availableInnerWidth)
|
||||||
@@ -3212,12 +3204,12 @@ static void YGNodelayoutImpl(
|
|||||||
auto crossAxisDoesNotGrow =
|
auto crossAxisDoesNotGrow =
|
||||||
alignContent != YGAlignStretch && isNodeFlexWrap;
|
alignContent != YGAlignStretch && isNodeFlexWrap;
|
||||||
const YGMeasureMode childWidthMeasureMode =
|
const YGMeasureMode childWidthMeasureMode =
|
||||||
YGFloatIsUndefined(childWidth) ||
|
yoga::isUndefined(childWidth) ||
|
||||||
(!isMainAxisRow && crossAxisDoesNotGrow)
|
(!isMainAxisRow && crossAxisDoesNotGrow)
|
||||||
? YGMeasureModeUndefined
|
? YGMeasureModeUndefined
|
||||||
: YGMeasureModeExactly;
|
: YGMeasureModeExactly;
|
||||||
const YGMeasureMode childHeightMeasureMode =
|
const YGMeasureMode childHeightMeasureMode =
|
||||||
YGFloatIsUndefined(childHeight) ||
|
yoga::isUndefined(childHeight) ||
|
||||||
(isMainAxisRow && crossAxisDoesNotGrow)
|
(isMainAxisRow && crossAxisDoesNotGrow)
|
||||||
? YGMeasureModeUndefined
|
? YGMeasureModeUndefined
|
||||||
: YGMeasureModeExactly;
|
: YGMeasureModeExactly;
|
||||||
@@ -3281,7 +3273,7 @@ static void YGNodelayoutImpl(
|
|||||||
if (performLayout && (isNodeFlexWrap || YGIsBaselineLayout(node))) {
|
if (performLayout && (isNodeFlexWrap || YGIsBaselineLayout(node))) {
|
||||||
float crossDimLead = 0;
|
float crossDimLead = 0;
|
||||||
float currentLead = leadingPaddingAndBorderCross;
|
float currentLead = leadingPaddingAndBorderCross;
|
||||||
if (!YGFloatIsUndefined(availableInnerCrossDim)) {
|
if (!yoga::isUndefined(availableInnerCrossDim)) {
|
||||||
const float remainingAlignContentDim =
|
const float remainingAlignContentDim =
|
||||||
availableInnerCrossDim - totalLineCrossDim;
|
availableInnerCrossDim - totalLineCrossDim;
|
||||||
switch (node->getStyle().alignContent()) {
|
switch (node->getStyle().alignContent()) {
|
||||||
@@ -3684,8 +3676,8 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
|
|||||||
float lastSize,
|
float lastSize,
|
||||||
float lastComputedSize) {
|
float lastComputedSize) {
|
||||||
return lastSizeMode == YGMeasureModeAtMost &&
|
return lastSizeMode == YGMeasureModeAtMost &&
|
||||||
sizeMode == YGMeasureModeAtMost && !YGFloatIsUndefined(lastSize) &&
|
sizeMode == YGMeasureModeAtMost && !yoga::isUndefined(lastSize) &&
|
||||||
!YGFloatIsUndefined(size) && !YGFloatIsUndefined(lastComputedSize) &&
|
!yoga::isUndefined(size) && !yoga::isUndefined(lastComputedSize) &&
|
||||||
lastSize > size &&
|
lastSize > size &&
|
||||||
(lastComputedSize <= size || yoga::inexactEquals(size, lastComputedSize));
|
(lastComputedSize <= size || yoga::inexactEquals(size, lastComputedSize));
|
||||||
}
|
}
|
||||||
@@ -3730,13 +3722,12 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(
|
|||||||
} else {
|
} else {
|
||||||
// Finally we just round the value
|
// Finally we just round the value
|
||||||
scaledValue = scaledValue - fractial +
|
scaledValue = scaledValue - fractial +
|
||||||
(!YGDoubleIsUndefined(fractial) &&
|
(!yoga::isUndefined(fractial) &&
|
||||||
(fractial > 0.5 || yoga::inexactEquals(fractial, 0.5))
|
(fractial > 0.5 || yoga::inexactEquals(fractial, 0.5))
|
||||||
? 1.0
|
? 1.0
|
||||||
: 0.0);
|
: 0.0);
|
||||||
}
|
}
|
||||||
return (YGDoubleIsUndefined(scaledValue) ||
|
return (yoga::isUndefined(scaledValue) || yoga::isUndefined(pointScaleFactor))
|
||||||
YGDoubleIsUndefined(pointScaleFactor))
|
|
||||||
? YGUndefined
|
? YGUndefined
|
||||||
: (float) (scaledValue / pointScaleFactor);
|
: (float) (scaledValue / pointScaleFactor);
|
||||||
}
|
}
|
||||||
@@ -3755,8 +3746,8 @@ YOGA_EXPORT bool YGNodeCanUseCachedMeasurement(
|
|||||||
const float marginRow,
|
const float marginRow,
|
||||||
const float marginColumn,
|
const float marginColumn,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config) {
|
||||||
if ((!YGFloatIsUndefined(lastComputedHeight) && lastComputedHeight < 0) ||
|
if ((!yoga::isUndefined(lastComputedHeight) && lastComputedHeight < 0) ||
|
||||||
(!YGFloatIsUndefined(lastComputedWidth) && lastComputedWidth < 0)) {
|
(!yoga::isUndefined(lastComputedWidth) && lastComputedWidth < 0)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool useRoundedComparison =
|
bool useRoundedComparison =
|
||||||
@@ -3858,7 +3849,7 @@ bool YGLayoutNodeInternal(
|
|||||||
layout->cachedLayout.computedHeight = -1;
|
layout->cachedLayout.computedHeight = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
YGCachedMeasurement* cachedResults = nullptr;
|
CachedMeasurement* cachedResults = nullptr;
|
||||||
|
|
||||||
// Determine whether the results are already cached. We maintain a separate
|
// Determine whether the results are already cached. We maintain a separate
|
||||||
// cache for layouts and measurements. A layout operation modifies the
|
// cache for layouts and measurements. A layout operation modifies the
|
||||||
@@ -4036,7 +4027,8 @@ bool YGLayoutNodeInternal(
|
|||||||
layoutMarkerData.maxMeasureCache =
|
layoutMarkerData.maxMeasureCache =
|
||||||
layout->nextCachedMeasurementsIndex + 1;
|
layout->nextCachedMeasurementsIndex + 1;
|
||||||
}
|
}
|
||||||
if (layout->nextCachedMeasurementsIndex == YG_MAX_CACHED_RESULT_COUNT) {
|
if (layout->nextCachedMeasurementsIndex ==
|
||||||
|
LayoutResults::MaxCachedMeasurements) {
|
||||||
if (gPrintChanges) {
|
if (gPrintChanges) {
|
||||||
yoga::log(
|
yoga::log(
|
||||||
node, YGLogLevelVerbose, nullptr, "Out of cache entries!\n");
|
node, YGLogLevelVerbose, nullptr, "Out of cache entries!\n");
|
||||||
@@ -4044,7 +4036,7 @@ bool YGLayoutNodeInternal(
|
|||||||
layout->nextCachedMeasurementsIndex = 0;
|
layout->nextCachedMeasurementsIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
YGCachedMeasurement* newCacheEntry;
|
CachedMeasurement* newCacheEntry;
|
||||||
if (performLayout) {
|
if (performLayout) {
|
||||||
// Use the single layout cache entry.
|
// Use the single layout cache entry.
|
||||||
newCacheEntry = &layout->cachedLayout;
|
newCacheEntry = &layout->cachedLayout;
|
||||||
@@ -4218,8 +4210,8 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
|
|||||||
widthMeasureMode = YGMeasureModeAtMost;
|
widthMeasureMode = YGMeasureModeAtMost;
|
||||||
} else {
|
} else {
|
||||||
width = ownerWidth;
|
width = ownerWidth;
|
||||||
widthMeasureMode = YGFloatIsUndefined(width) ? YGMeasureModeUndefined
|
widthMeasureMode = yoga::isUndefined(width) ? YGMeasureModeUndefined
|
||||||
: YGMeasureModeExactly;
|
: YGMeasureModeExactly;
|
||||||
}
|
}
|
||||||
|
|
||||||
float height = YGUndefined;
|
float height = YGUndefined;
|
||||||
@@ -4238,8 +4230,8 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
|
|||||||
heightMeasureMode = YGMeasureModeAtMost;
|
heightMeasureMode = YGMeasureModeAtMost;
|
||||||
} else {
|
} else {
|
||||||
height = ownerHeight;
|
height = ownerHeight;
|
||||||
heightMeasureMode = YGFloatIsUndefined(height) ? YGMeasureModeUndefined
|
heightMeasureMode = yoga::isUndefined(height) ? YGMeasureModeUndefined
|
||||||
: YGMeasureModeExactly;
|
: YGMeasureModeExactly;
|
||||||
}
|
}
|
||||||
if (YGLayoutNodeInternal(
|
if (YGLayoutNodeInternal(
|
||||||
node,
|
node,
|
||||||
|
@@ -43,4 +43,42 @@ inline YGFlexDirection resolveCrossDirection(
|
|||||||
: YGFlexDirectionColumn;
|
: YGFlexDirectionColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline YGEdge leadingEdge(const YGFlexDirection flexDirection) {
|
||||||
|
switch (flexDirection) {
|
||||||
|
case YGFlexDirectionColumn:
|
||||||
|
return YGEdgeTop;
|
||||||
|
case YGFlexDirectionColumnReverse:
|
||||||
|
return YGEdgeBottom;
|
||||||
|
case YGFlexDirectionRow:
|
||||||
|
return YGEdgeLeft;
|
||||||
|
case YGFlexDirectionRowReverse:
|
||||||
|
return YGEdgeRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
YGAssert(false, "Invalid YGFlexDirection");
|
||||||
|
|
||||||
|
// Avoid "not all control paths return a value" warning until next diff adds
|
||||||
|
// assert with [[noreturn]]
|
||||||
|
return YGEdgeTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGEdge trailingEdge(const YGFlexDirection flexDirection) {
|
||||||
|
switch (flexDirection) {
|
||||||
|
case YGFlexDirectionColumn:
|
||||||
|
return YGEdgeBottom;
|
||||||
|
case YGFlexDirectionColumnReverse:
|
||||||
|
return YGEdgeTop;
|
||||||
|
case YGFlexDirectionRow:
|
||||||
|
return YGEdgeRight;
|
||||||
|
case YGFlexDirectionRowReverse:
|
||||||
|
return YGEdgeLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
YGAssert(false, "Invalid YGFlexDirection");
|
||||||
|
|
||||||
|
// Avoid "not all control paths return a value" warning until next diff adds
|
||||||
|
// assert with [[noreturn]]
|
||||||
|
return YGEdgeTop;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace facebook::yoga
|
} // namespace facebook::yoga
|
||||||
|
@@ -8,7 +8,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
|
|
||||||
#include <yoga/numeric/FloatOptional.h>
|
#include <yoga/numeric/FloatOptional.h>
|
||||||
|
#include <yoga/style/CompactValue.h>
|
||||||
|
|
||||||
namespace facebook::yoga {
|
namespace facebook::yoga {
|
||||||
|
|
||||||
|
@@ -8,9 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
|
|
||||||
#include <yoga/bits/EnumBitset.h>
|
#include <yoga/bits/EnumBitset.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
|
||||||
|
|
||||||
// Tag struct used to form the opaque YGConfigRef for the public C API
|
// Tag struct used to form the opaque YGConfigRef for the public C API
|
||||||
struct YGConfig {};
|
struct YGConfig {};
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include <yoga/debug/NodeToString.h>
|
#include <yoga/debug/NodeToString.h>
|
||||||
#include <yoga/numeric/Comparison.h>
|
#include <yoga/numeric/Comparison.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
|
||||||
|
|
||||||
namespace facebook::yoga {
|
namespace facebook::yoga {
|
||||||
|
|
||||||
|
51
yoga/node/CachedMeasurement.h
Normal file
51
yoga/node/CachedMeasurement.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <yoga/Yoga.h>
|
||||||
|
#include <yoga/numeric/Comparison.h>
|
||||||
|
|
||||||
|
namespace facebook::yoga {
|
||||||
|
|
||||||
|
struct CachedMeasurement {
|
||||||
|
float availableWidth{-1};
|
||||||
|
float availableHeight{-1};
|
||||||
|
YGMeasureMode widthMeasureMode{YGMeasureModeUndefined};
|
||||||
|
YGMeasureMode heightMeasureMode{YGMeasureModeUndefined};
|
||||||
|
|
||||||
|
float computedWidth{-1};
|
||||||
|
float computedHeight{-1};
|
||||||
|
|
||||||
|
bool operator==(CachedMeasurement measurement) const {
|
||||||
|
bool isEqual = widthMeasureMode == measurement.widthMeasureMode &&
|
||||||
|
heightMeasureMode == measurement.heightMeasureMode;
|
||||||
|
|
||||||
|
if (!yoga::isUndefined(availableWidth) ||
|
||||||
|
!yoga::isUndefined(measurement.availableWidth)) {
|
||||||
|
isEqual = isEqual && availableWidth == measurement.availableWidth;
|
||||||
|
}
|
||||||
|
if (!yoga::isUndefined(availableHeight) ||
|
||||||
|
!yoga::isUndefined(measurement.availableHeight)) {
|
||||||
|
isEqual = isEqual && availableHeight == measurement.availableHeight;
|
||||||
|
}
|
||||||
|
if (!yoga::isUndefined(computedWidth) ||
|
||||||
|
!yoga::isUndefined(measurement.computedWidth)) {
|
||||||
|
isEqual = isEqual && computedWidth == measurement.computedWidth;
|
||||||
|
}
|
||||||
|
if (!yoga::isUndefined(computedHeight) ||
|
||||||
|
!yoga::isUndefined(measurement.computedHeight)) {
|
||||||
|
isEqual = isEqual && computedHeight == measurement.computedHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isEqual;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace facebook::yoga
|
@@ -5,6 +5,8 @@
|
|||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <yoga/node/LayoutResults.h>
|
#include <yoga/node/LayoutResults.h>
|
||||||
#include <yoga/numeric/Comparison.h>
|
#include <yoga/numeric/Comparison.h>
|
||||||
|
|
||||||
@@ -23,7 +25,8 @@ bool LayoutResults::operator==(LayoutResults layout) const {
|
|||||||
cachedLayout == layout.cachedLayout &&
|
cachedLayout == layout.cachedLayout &&
|
||||||
computedFlexBasis == layout.computedFlexBasis;
|
computedFlexBasis == layout.computedFlexBasis;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < YG_MAX_CACHED_RESULT_COUNT && isEqual; ++i) {
|
for (uint32_t i = 0; i < LayoutResults::MaxCachedMeasurements && isEqual;
|
||||||
|
++i) {
|
||||||
isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i];
|
isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,13 +7,19 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include <yoga/bits/NumericBitfield.h>
|
#include <yoga/bits/NumericBitfield.h>
|
||||||
#include <yoga/numeric/FloatOptional.h>
|
#include <yoga/numeric/FloatOptional.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
#include <yoga/node/CachedMeasurement.h>
|
||||||
|
|
||||||
namespace facebook::yoga {
|
namespace facebook::yoga {
|
||||||
|
|
||||||
struct LayoutResults {
|
struct LayoutResults {
|
||||||
|
// This value was chosen based on empirical data:
|
||||||
|
// 98% of analyzed layouts require less than 8 entries.
|
||||||
|
static constexpr int32_t MaxCachedMeasurements = 8;
|
||||||
|
|
||||||
std::array<float, 4> position = {};
|
std::array<float, 4> position = {};
|
||||||
std::array<float, 2> dimensions = {{YGUndefined, YGUndefined}};
|
std::array<float, 2> dimensions = {{YGUndefined, YGUndefined}};
|
||||||
std::array<float, 4> margin = {};
|
std::array<float, 4> margin = {};
|
||||||
@@ -36,11 +42,10 @@ public:
|
|||||||
YGDirection lastOwnerDirection = YGDirectionInherit;
|
YGDirection lastOwnerDirection = YGDirectionInherit;
|
||||||
|
|
||||||
uint32_t nextCachedMeasurementsIndex = 0;
|
uint32_t nextCachedMeasurementsIndex = 0;
|
||||||
std::array<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT>
|
std::array<CachedMeasurement, MaxCachedMeasurements> cachedMeasurements = {};
|
||||||
cachedMeasurements = {};
|
|
||||||
std::array<float, 2> measuredDimensions = {{YGUndefined, YGUndefined}};
|
std::array<float, 2> measuredDimensions = {{YGUndefined, YGUndefined}};
|
||||||
|
|
||||||
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
|
CachedMeasurement cachedLayout{};
|
||||||
|
|
||||||
YGDirection direction() const {
|
YGDirection direction() const {
|
||||||
return getEnumData<YGDirection>(flags, directionOffset);
|
return getEnumData<YGDirection>(flags, directionOffset);
|
||||||
|
@@ -117,10 +117,10 @@ FloatOptional Node::getLeadingPosition(
|
|||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.position(),
|
style_.position(),
|
||||||
YGEdgeStart,
|
YGEdgeStart,
|
||||||
leading[axis],
|
leadingEdge(axis),
|
||||||
CompactValue::ofZero())
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.position(), leading[axis], CompactValue::ofZero());
|
style_.position(), leadingEdge(axis), CompactValue::ofZero());
|
||||||
return yoga::resolveValue(leadingPosition, axisSize);
|
return yoga::resolveValue(leadingPosition, axisSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,10 +131,10 @@ FloatOptional Node::getTrailingPosition(
|
|||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.position(),
|
style_.position(),
|
||||||
YGEdgeEnd,
|
YGEdgeEnd,
|
||||||
trailing[axis],
|
trailingEdge(axis),
|
||||||
CompactValue::ofZero())
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.position(), trailing[axis], CompactValue::ofZero());
|
style_.position(), trailingEdge(axis), CompactValue::ofZero());
|
||||||
return yoga::resolveValue(trailingPosition, axisSize);
|
return yoga::resolveValue(trailingPosition, axisSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,10 +143,10 @@ bool Node::isLeadingPositionDefined(const YGFlexDirection axis) const {
|
|||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.position(),
|
style_.position(),
|
||||||
YGEdgeStart,
|
YGEdgeStart,
|
||||||
leading[axis],
|
leadingEdge(axis),
|
||||||
CompactValue::ofUndefined())
|
CompactValue::ofUndefined())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.position(), leading[axis], CompactValue::ofUndefined());
|
style_.position(), leadingEdge(axis), CompactValue::ofUndefined());
|
||||||
return !leadingPosition.isUndefined();
|
return !leadingPosition.isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,10 +155,10 @@ bool Node::isTrailingPosDefined(const YGFlexDirection axis) const {
|
|||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.position(),
|
style_.position(),
|
||||||
YGEdgeEnd,
|
YGEdgeEnd,
|
||||||
trailing[axis],
|
trailingEdge(axis),
|
||||||
CompactValue::ofUndefined())
|
CompactValue::ofUndefined())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.position(), trailing[axis], CompactValue::ofUndefined());
|
style_.position(), trailingEdge(axis), CompactValue::ofUndefined());
|
||||||
return !trailingPosition.isUndefined();
|
return !trailingPosition.isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,9 +167,12 @@ FloatOptional Node::getLeadingMargin(
|
|||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
auto leadingMargin = isRow(axis)
|
auto leadingMargin = isRow(axis)
|
||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero())
|
style_.margin(),
|
||||||
|
YGEdgeStart,
|
||||||
|
leadingEdge(axis),
|
||||||
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.margin(), leading[axis], CompactValue::ofZero());
|
style_.margin(), leadingEdge(axis), CompactValue::ofZero());
|
||||||
return leadingMargin.isAuto() ? FloatOptional{0}
|
return leadingMargin.isAuto() ? FloatOptional{0}
|
||||||
: yoga::resolveValue(leadingMargin, widthSize);
|
: yoga::resolveValue(leadingMargin, widthSize);
|
||||||
}
|
}
|
||||||
@@ -179,9 +182,12 @@ FloatOptional Node::getTrailingMargin(
|
|||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
auto trailingMargin = isRow(axis)
|
auto trailingMargin = isRow(axis)
|
||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
|
style_.margin(),
|
||||||
|
YGEdgeEnd,
|
||||||
|
trailingEdge(axis),
|
||||||
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.margin(), trailing[axis], CompactValue::ofZero());
|
style_.margin(), trailingEdge(axis), CompactValue::ofZero());
|
||||||
return trailingMargin.isAuto()
|
return trailingMargin.isAuto()
|
||||||
? FloatOptional{0}
|
? FloatOptional{0}
|
||||||
: yoga::resolveValue(trailingMargin, widthSize);
|
: yoga::resolveValue(trailingMargin, widthSize);
|
||||||
@@ -390,25 +396,25 @@ void Node::setPosition(
|
|||||||
|
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
(getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
||||||
leading[mainAxis]);
|
leadingEdge(mainAxis));
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
(getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
||||||
trailing[mainAxis]);
|
trailingEdge(mainAxis));
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
(getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
leading[crossAxis]);
|
leadingEdge(crossAxis));
|
||||||
setLayoutPosition(
|
setLayoutPosition(
|
||||||
(getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
(getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
trailing[crossAxis]);
|
trailingEdge(crossAxis));
|
||||||
}
|
}
|
||||||
|
|
||||||
YGValue Node::marginLeadingValue(const YGFlexDirection axis) const {
|
YGValue Node::marginLeadingValue(const YGFlexDirection axis) const {
|
||||||
if (isRow(axis) && !style_.margin()[YGEdgeStart].isUndefined()) {
|
if (isRow(axis) && !style_.margin()[YGEdgeStart].isUndefined()) {
|
||||||
return style_.margin()[YGEdgeStart];
|
return style_.margin()[YGEdgeStart];
|
||||||
} else {
|
} else {
|
||||||
return style_.margin()[leading[axis]];
|
return style_.margin()[leadingEdge(axis)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,7 +422,7 @@ YGValue Node::marginTrailingValue(const YGFlexDirection axis) const {
|
|||||||
if (isRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) {
|
if (isRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) {
|
||||||
return style_.margin()[YGEdgeEnd];
|
return style_.margin()[YGEdgeEnd];
|
||||||
} else {
|
} else {
|
||||||
return style_.margin()[trailing[axis]];
|
return style_.margin()[trailingEdge(axis)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,7 +499,7 @@ float Node::resolveFlexGrow() const {
|
|||||||
if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) {
|
if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) {
|
||||||
return style_.flex().unwrap();
|
return style_.flex().unwrap();
|
||||||
}
|
}
|
||||||
return kDefaultFlexGrow;
|
return Style::DefaultFlexGrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Node::resolveFlexShrink() const {
|
float Node::resolveFlexShrink() const {
|
||||||
@@ -507,7 +513,8 @@ float Node::resolveFlexShrink() const {
|
|||||||
style_.flex().unwrap() < 0.0f) {
|
style_.flex().unwrap() < 0.0f) {
|
||||||
return -style_.flex().unwrap();
|
return -style_.flex().unwrap();
|
||||||
}
|
}
|
||||||
return config_->useWebDefaults() ? kWebDefaultFlexShrink : kDefaultFlexShrink;
|
return config_->useWebDefaults() ? Style::WebDefaultFlexShrink
|
||||||
|
: Style::DefaultFlexShrink;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Node::isNodeFlexible() {
|
bool Node::isNodeFlexible() {
|
||||||
@@ -519,18 +526,24 @@ bool Node::isNodeFlexible() {
|
|||||||
float Node::getLeadingBorder(const YGFlexDirection axis) const {
|
float Node::getLeadingBorder(const YGFlexDirection axis) const {
|
||||||
YGValue leadingBorder = isRow(axis)
|
YGValue leadingBorder = isRow(axis)
|
||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero())
|
style_.border(),
|
||||||
|
YGEdgeStart,
|
||||||
|
leadingEdge(axis),
|
||||||
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.border(), leading[axis], CompactValue::ofZero());
|
style_.border(), leadingEdge(axis), CompactValue::ofZero());
|
||||||
return fmaxf(leadingBorder.value, 0.0f);
|
return fmaxf(leadingBorder.value, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Node::getTrailingBorder(const YGFlexDirection axis) const {
|
float Node::getTrailingBorder(const YGFlexDirection axis) const {
|
||||||
YGValue trailingBorder = isRow(axis)
|
YGValue trailingBorder = isRow(axis)
|
||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
|
style_.border(),
|
||||||
|
YGEdgeEnd,
|
||||||
|
trailingEdge(axis),
|
||||||
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.border(), trailing[axis], CompactValue::ofZero());
|
style_.border(), trailingEdge(axis), CompactValue::ofZero());
|
||||||
return fmaxf(trailingBorder.value, 0.0f);
|
return fmaxf(trailingBorder.value, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,10 +554,10 @@ FloatOptional Node::getLeadingPadding(
|
|||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.padding(),
|
style_.padding(),
|
||||||
YGEdgeStart,
|
YGEdgeStart,
|
||||||
leading[axis],
|
leadingEdge(axis),
|
||||||
CompactValue::ofZero())
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.padding(), leading[axis], CompactValue::ofZero());
|
style_.padding(), leadingEdge(axis), CompactValue::ofZero());
|
||||||
return yoga::maxOrDefined(
|
return yoga::maxOrDefined(
|
||||||
yoga::resolveValue(leadingPadding, widthSize), FloatOptional(0.0f));
|
yoga::resolveValue(leadingPadding, widthSize), FloatOptional(0.0f));
|
||||||
}
|
}
|
||||||
@@ -554,9 +567,12 @@ FloatOptional Node::getTrailingPadding(
|
|||||||
const float widthSize) const {
|
const float widthSize) const {
|
||||||
auto trailingPadding = isRow(axis)
|
auto trailingPadding = isRow(axis)
|
||||||
? computeEdgeValueForRow(
|
? computeEdgeValueForRow(
|
||||||
style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
|
style_.padding(),
|
||||||
|
YGEdgeEnd,
|
||||||
|
trailingEdge(axis),
|
||||||
|
CompactValue::ofZero())
|
||||||
: computeEdgeValueForColumn(
|
: computeEdgeValueForColumn(
|
||||||
style_.padding(), trailing[axis], CompactValue::ofZero());
|
style_.padding(), trailingEdge(axis), CompactValue::ofZero());
|
||||||
return yoga::maxOrDefined(
|
return yoga::maxOrDefined(
|
||||||
yoga::resolveValue(trailingPadding, widthSize), FloatOptional(0.0f));
|
yoga::resolveValue(trailingPadding, widthSize), FloatOptional(0.0f));
|
||||||
}
|
}
|
||||||
|
@@ -9,10 +9,10 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <yoga/config/Config.h>
|
#include <yoga/config/Config.h>
|
||||||
#include <yoga/node/LayoutResults.h>
|
#include <yoga/node/LayoutResults.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
|
||||||
|
|
||||||
#include <yoga/style/CompactValue.h>
|
#include <yoga/style/CompactValue.h>
|
||||||
#include <yoga/style/Style.h>
|
#include <yoga/style/Style.h>
|
||||||
|
|
||||||
|
@@ -15,19 +15,24 @@
|
|||||||
|
|
||||||
namespace facebook::yoga {
|
namespace facebook::yoga {
|
||||||
|
|
||||||
|
template <typename FloatT>
|
||||||
|
inline bool isUndefined(FloatT value) {
|
||||||
|
return std::isnan(value);
|
||||||
|
}
|
||||||
|
|
||||||
inline float maxOrDefined(const float a, const float b) {
|
inline float maxOrDefined(const float a, const float b) {
|
||||||
if (!std::isnan(a) && !std::isnan(b)) {
|
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
|
||||||
return fmaxf(a, b);
|
return fmaxf(a, b);
|
||||||
}
|
}
|
||||||
return std::isnan(a) ? b : a;
|
return yoga::isUndefined(a) ? b : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float minOrDefined(const float a, const float b) {
|
inline float minOrDefined(const float a, const float b) {
|
||||||
if (!std::isnan(a) && !std::isnan(b)) {
|
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
|
||||||
return fminf(a, b);
|
return fminf(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::isnan(a) ? b : a;
|
return yoga::isUndefined(a) ? b : a;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline FloatOptional maxOrDefined(FloatOptional op1, FloatOptional op2) {
|
inline FloatOptional maxOrDefined(FloatOptional op1, FloatOptional op2) {
|
||||||
@@ -43,17 +48,17 @@ inline FloatOptional maxOrDefined(FloatOptional op1, FloatOptional op2) {
|
|||||||
// Custom equality functions using a hardcoded epsilon of 0.0001f, or returning
|
// Custom equality functions using a hardcoded epsilon of 0.0001f, or returning
|
||||||
// true if both floats are NaN.
|
// true if both floats are NaN.
|
||||||
inline bool inexactEquals(const float a, const float b) {
|
inline bool inexactEquals(const float a, const float b) {
|
||||||
if (!std::isnan(a) && !std::isnan(b)) {
|
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
|
||||||
return fabs(a - b) < 0.0001f;
|
return fabs(a - b) < 0.0001f;
|
||||||
}
|
}
|
||||||
return std::isnan(a) && std::isnan(b);
|
return yoga::isUndefined(a) && yoga::isUndefined(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool inexactEquals(const double a, const double b) {
|
inline bool inexactEquals(const double a, const double b) {
|
||||||
if (!std::isnan(a) && !std::isnan(b)) {
|
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
|
||||||
return fabs(a - b) < 0.0001;
|
return fabs(a - b) < 0.0001;
|
||||||
}
|
}
|
||||||
return std::isnan(a) && std::isnan(b);
|
return yoga::isUndefined(a) && yoga::isUndefined(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool inexactEquals(const YGValue& a, const YGValue& b) {
|
inline bool inexactEquals(const YGValue& a, const YGValue& b) {
|
||||||
@@ -62,7 +67,7 @@ inline bool inexactEquals(const YGValue& a, const YGValue& b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (a.unit == YGUnitUndefined ||
|
if (a.unit == YGUnitUndefined ||
|
||||||
(std::isnan(a.value) && std::isnan(b.value))) {
|
(yoga::isUndefined(a.value) && yoga::isUndefined(b.value))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <yoga/Yoga-internal.h>
|
|
||||||
|
|
||||||
namespace facebook::yoga {
|
namespace facebook::yoga {
|
||||||
|
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <yoga/Yoga.h>
|
#include <yoga/Yoga.h>
|
||||||
#include <yoga/Yoga-internal.h>
|
|
||||||
|
|
||||||
#include <yoga/bits/NumericBitfield.h>
|
#include <yoga/bits/NumericBitfield.h>
|
||||||
#include <yoga/numeric/FloatOptional.h>
|
#include <yoga/numeric/FloatOptional.h>
|
||||||
@@ -23,13 +22,17 @@ namespace facebook::yoga {
|
|||||||
|
|
||||||
class YOGA_EXPORT Style {
|
class YOGA_EXPORT Style {
|
||||||
template <typename Enum>
|
template <typename Enum>
|
||||||
using Values = detail::Values<enums::count<Enum>()>;
|
using Values = std::array<CompactValue, enums::count<Enum>()>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Dimensions = Values<YGDimension>;
|
using Dimensions = Values<YGDimension>;
|
||||||
using Edges = Values<YGEdge>;
|
using Edges = Values<YGEdge>;
|
||||||
using Gutters = Values<YGGutter>;
|
using Gutters = Values<YGGutter>;
|
||||||
|
|
||||||
|
static constexpr float DefaultFlexGrow = 0.0f;
|
||||||
|
static constexpr float DefaultFlexShrink = 0.0f;
|
||||||
|
static constexpr float WebDefaultFlexShrink = 1.0f;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct BitfieldRef {
|
struct BitfieldRef {
|
||||||
Style& style;
|
Style& style;
|
||||||
@@ -112,7 +115,7 @@ private:
|
|||||||
Edges padding_ = {};
|
Edges padding_ = {};
|
||||||
Edges border_ = {};
|
Edges border_ = {};
|
||||||
Gutters gap_ = {};
|
Gutters gap_ = {};
|
||||||
Dimensions dimensions_{CompactValue::ofAuto()};
|
Dimensions dimensions_{CompactValue::ofAuto(), CompactValue::ofAuto()};
|
||||||
Dimensions minDimensions_ = {};
|
Dimensions minDimensions_ = {};
|
||||||
Dimensions maxDimensions_ = {};
|
Dimensions maxDimensions_ = {};
|
||||||
// Yoga specific properties, not compatible with flexbox specification
|
// Yoga specific properties, not compatible with flexbox specification
|
||||||
|
Reference in New Issue
Block a user