update yoga to cbf6495d66a7a8066d1354daa14d3bb1af19f6ef

This commit is contained in:
王劲鹏 2021-04-20 10:18:06 +08:00 committed by osborn
parent 5ba5f5ce6c
commit 8d04d41b19
20 changed files with 609 additions and 588 deletions

View File

@ -123,7 +123,7 @@ HEADERS += \
widget/flex/FlexLayout.h \
widget/flex/FlexLayoutConfig.h \
widget/flex/FlexLayoutService.h \
yoga/Bitfield.h \
yoga/BitUtils.h \
yoga/CompactValue.h \
yoga/Utils.h \
yoga/YGConfig.h \

View File

@ -0,0 +1,67 @@
/*
* 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 <cstdio>
#include <cstdint>
#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 <typename Enum>
constexpr size_t bitWidthFn() {
static_assert(
enums::count<Enum>() > 0, "Enums must have at least one entries");
return log2ceilFn(enums::count<Enum>() - 1);
}
template <typename Enum>
constexpr Enum getEnumData(int flags, size_t index) {
return static_cast<Enum>((flags & mask(bitWidthFn<Enum>(), index)) >> index);
}
template <typename Enum>
void setEnumData(uint32_t& flags, size_t index, int newValue) {
flags = (flags & ~mask(bitWidthFn<Enum>(), index)) |
((newValue << index) & (mask(bitWidthFn<Enum>(), index)));
}
template <typename Enum>
void setEnumData(uint8_t& flags, size_t index, int newValue) {
flags = (flags & ~static_cast<uint8_t>(mask(bitWidthFn<Enum>(), index))) |
((newValue << index) &
(static_cast<uint8_t>(mask(bitWidthFn<Enum>(), 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

View File

@ -1,145 +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 <cstddef>
#include <limits>
#include <type_traits>
#include <yoga/YGEnums.h>
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 <typename Enum>
constexpr size_t bitWidth() {
static_assert(
enums::count<Enum>() > 0, "Enums must have at least one entries");
return log2ceil(enums::count<Enum>() - 1);
}
// Number of bits needed for a boolean
template <>
constexpr size_t bitWidth<bool>() {
return 1;
}
template <typename U, typename... Ts>
struct BitTraits {};
template <typename U>
struct BitTraits<U> {
// Base cases
static constexpr size_t width(size_t) { return 0; }
static constexpr size_t shift(size_t) { return 0; }
};
template <typename U, typename T, typename... Ts>
struct BitTraits<U, T, Ts...> {
using Rest = BitTraits<U, Ts...>;
static constexpr size_t width(size_t idx) {
return idx == 0 ? bitWidth<T>() : 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 <size_t Idx, typename T, typename... Ts>
struct IndexedType {
using Type = typename IndexedType<Idx - 1, Ts...>::Type;
};
template <typename T, typename... Ts>
struct IndexedType<0, T, Ts...> {
using Type = T;
};
} // namespace detail
template <typename Storage, typename... Fields>
class Bitfield {
static_assert(
std::is_integral<Storage>::value,
"Bitfield needs an integral storage type");
static_assert(
std::is_unsigned<Storage>::value,
"Bitfield needs an unsigned storage type");
static_assert(sizeof...(Fields) > 0, "Bitfield needs at least one member");
using BitTraits = detail::BitTraits<Storage, Fields...>;
#if !defined(_MSC_VER) || _MSC_VER > 1914
static_assert(
BitTraits::shift(0) + BitTraits::width(0) <=
std::numeric_limits<Storage>::digits,
"Specified storage type is too narrow to hold all types");
#endif
template <size_t Idx>
using TypeAt = typename detail::IndexedType<Idx, Fields...>::Type;
template <size_t Idx, typename Value, typename... Values>
static constexpr Storage initStorage(Value value, Values... values) {
return ((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx)) |
initStorage<Idx + 1, Values...>(values...);
}
template <size_t Idx>
static constexpr Storage initStorage() {
return Storage{0};
}
Storage storage_ = 0;
public:
template <size_t Idx>
class Ref {
Bitfield& bitfield_;
public:
Ref(Bitfield& bitfield) : bitfield_(bitfield) {}
Ref& operator=(TypeAt<Idx> value) {
bitfield_.storage_ = (bitfield_.storage_ & ~BitTraits::mask(Idx)) |
((value << BitTraits::shift(Idx)) & BitTraits::mask(Idx));
return *this;
}
operator TypeAt<Idx>() const {
return const_cast<const Bitfield&>(bitfield_).at<Idx>();
}
};
constexpr Bitfield() = default;
constexpr Bitfield(Fields... values) : storage_{initStorage<0>(values...)} {}
template <size_t Idx>
constexpr TypeAt<Idx> at() const {
return static_cast<TypeAt<Idx>>(
(storage_ & BitTraits::mask(Idx)) >> BitTraits::shift(Idx));
}
template <size_t Idx>
Ref<Idx> at() {
return {*this};
}
};
} // namespace yoga
} // namespace facebook

View File

@ -125,8 +125,8 @@ public:
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 {

View File

@ -6,6 +6,7 @@
*/
#include "Utils.h"
#include <stdexcept>
using namespace facebook;
@ -52,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.0001;
}
return yoga::isUndefined(a) && yoga::isUndefined(b);
}
float YGFloatSanitize(const float val) {
return yoga::isUndefined(val) ? 0 : val;
}
@ -65,3 +73,7 @@ YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) {
}
return op1.isUndefined() ? op2 : op1;
}
void throwLogicalErrorWithMessage(const char* message) {
throw std::logic_error(message);
}

View File

@ -64,6 +64,8 @@ inline bool YGValueEqual(
// 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(
@ -141,3 +143,5 @@ inline YGFloatOptional YGResolveValueMargin(
const float ownerSize) {
return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize);
}
void throwLogicalErrorWithMessage(const char* message);

View File

@ -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:

View File

@ -128,7 +128,11 @@ YG_ENUM_SEQ_DECL(
YGOverflowHidden,
YGOverflowScroll)
YG_ENUM_SEQ_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute)
YG_ENUM_SEQ_DECL(
YGPositionType,
YGPositionTypeStatic,
YGPositionTypeRelative,
YGPositionTypeAbsolute)
YG_ENUM_DECL(
YGPrintOptions,

View File

@ -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<float, 4> position = {};
std::array<float, 2> dimensions = {{YGUndefined, YGUndefined}};
@ -18,12 +20,14 @@ struct YGLayout {
std::array<float, 4> 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<uint8_t, YGDirection, bool, bool, bool> flags_ =
{YGDirectionInherit, false, false, false};
static constexpr size_t directionOffset = 0;
static constexpr size_t didUseLegacyFlagOffset =
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
static constexpr size_t doesLegacyStretchFlagAffectsLayoutOffset =
didUseLegacyFlagOffset + 1;
static constexpr size_t hadOverflowOffset =
doesLegacyStretchFlagAffectsLayoutOffset + 1;
uint8_t flags = 0;
public:
uint32_t computedFlexBasisGeneration = 0;
@ -32,7 +36,7 @@ public:
// 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<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT>
@ -41,27 +45,41 @@ public:
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
YGDirection direction() const { return flags_.at<directionIdx>(); }
decltype(flags_)::Ref<directionIdx> direction() {
return flags_.at<directionIdx>();
YGDirection direction() const {
return facebook::yoga::detail::getEnumData<YGDirection>(
flags, directionOffset);
}
bool didUseLegacyFlag() const { return flags_.at<didUseLegacyFlagIdx>(); }
decltype(flags_)::Ref<didUseLegacyFlagIdx> didUseLegacyFlag() {
return flags_.at<didUseLegacyFlagIdx>();
void setDirection(YGDirection direction) {
facebook::yoga::detail::setEnumData<YGDirection>(
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<doesLegacyStretchFlagAffectsLayoutIdx>();
}
decltype(flags_)::Ref<doesLegacyStretchFlagAffectsLayoutIdx>
doesLegacyStretchFlagAffectsLayout() {
return flags_.at<doesLegacyStretchFlagAffectsLayoutIdx>();
return facebook::yoga::detail::getBooleanData(
flags, doesLegacyStretchFlagAffectsLayoutOffset);
}
bool hadOverflow() const { return flags_.at<hadOverflowIdx>(); }
decltype(flags_)::Ref<hadOverflowIdx> hadOverflow() {
return flags_.at<hadOverflowIdx>();
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;

View File

@ -16,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_;
@ -29,7 +29,7 @@ YGNode::YGNode(YGNode&& node) {
config_ = node.config_;
resolvedDimensions_ = node.resolvedDimensions_;
for (auto c : children_) {
c->setOwner(c);
c->setOwner(this);
}
}
@ -42,7 +42,7 @@ YGNode::YGNode(const YGNode& node, YGConfigRef config) : YGNode{node} {
void YGNode::print(void* printContext) {
if (print_.noContext != nullptr) {
if (flags_.at<printUsesContext_>()) {
if (facebook::yoga::detail::getBooleanData(flags, printUsesContext_)) {
print_.withContext(this, printContext);
} else {
print_.noContext(this);
@ -50,89 +50,111 @@ void YGNode::print(void* printContext) {
}
}
CompactValue YGNode::computeEdgeValueForRow(
const YGStyle::Edges& edges,
YGEdge rowEdge,
YGEdge edge,
CompactValue defaultValue) {
if (!edges[rowEdge].isUndefined()) {
return edges[rowEdge];
} else if (!edges[edge].isUndefined()) {
return edges[edge];
} else if (!edges[YGEdgeHorizontal].isUndefined()) {
return edges[YGEdgeHorizontal];
} else if (!edges[YGEdgeAll].isUndefined()) {
return edges[YGEdgeAll];
} else {
return defaultValue;
}
}
CompactValue YGNode::computeEdgeValueForColumn(
const YGStyle::Edges& edges,
YGEdge edge,
CompactValue defaultValue) {
if (!edges[edge].isUndefined()) {
return edges[edge];
} else if (!edges[YGEdgeVertical].isUndefined()) {
return edges[YGEdgeVertical];
} else if (!edges[YGEdgeAll].isUndefined()) {
return edges[YGEdgeAll];
} else {
return defaultValue;
}
}
YGFloatOptional YGNode::getLeadingPosition(
const YGFlexDirection axis,
const float axisSize) const {
if (YGFlexDirectionIsRow(axis)) {
auto leadingPosition = YGComputedEdgeValue(
style_.position(), YGEdgeStart, CompactValue::ofUndefined());
if (!leadingPosition.isUndefined()) {
auto leadingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.position(),
YGEdgeStart,
leading[axis],
CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.position(), leading[axis], CompactValue::ofZero());
return YGResolveValue(leadingPosition, axisSize);
}
}
auto leadingPosition = YGComputedEdgeValue(
style_.position(), leading[axis], CompactValue::ofUndefined());
return leadingPosition.isUndefined()
? YGFloatOptional{0}
: YGResolveValue(leadingPosition, axisSize);
}
YGFloatOptional YGNode::getTrailingPosition(
const YGFlexDirection axis,
const float axisSize) const {
if (YGFlexDirectionIsRow(axis)) {
auto trailingPosition = YGComputedEdgeValue(
style_.position(), YGEdgeEnd, CompactValue::ofUndefined());
if (!trailingPosition.isUndefined()) {
auto trailingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.position(),
YGEdgeEnd,
trailing[axis],
CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.position(), trailing[axis], CompactValue::ofZero());
return YGResolveValue(trailingPosition, axisSize);
}
}
auto trailingPosition = YGComputedEdgeValue(
style_.position(), trailing[axis], CompactValue::ofUndefined());
return trailingPosition.isUndefined()
? YGFloatOptional{0}
: YGResolveValue(trailingPosition, axisSize);
}
bool YGNode::isLeadingPositionDefined(const YGFlexDirection axis) const {
return (YGFlexDirectionIsRow(axis) &&
!YGComputedEdgeValue(
style_.position(), YGEdgeStart, CompactValue::ofUndefined())
.isUndefined()) ||
!YGComputedEdgeValue(
style_.position(), leading[axis], CompactValue::ofUndefined())
.isUndefined();
auto leadingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.position(),
YGEdgeStart,
leading[axis],
CompactValue::ofUndefined())
: computeEdgeValueForColumn(
style_.position(), leading[axis], CompactValue::ofUndefined());
return !leadingPosition.isUndefined();
}
bool YGNode::isTrailingPosDefined(const YGFlexDirection axis) const {
return (YGFlexDirectionIsRow(axis) &&
!YGComputedEdgeValue(
style_.position(), YGEdgeEnd, CompactValue::ofUndefined())
.isUndefined()) ||
!YGComputedEdgeValue(
style_.position(), trailing[axis], CompactValue::ofUndefined())
.isUndefined();
auto trailingPosition = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.position(),
YGEdgeEnd,
trailing[axis],
CompactValue::ofUndefined())
: computeEdgeValueForColumn(
style_.position(), trailing[axis], CompactValue::ofUndefined());
return !trailingPosition.isUndefined();
}
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()),
widthSize);
auto leadingMargin = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.margin(), YGEdgeStart, leading[axis], CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.margin(), leading[axis], CompactValue::ofZero());
return YGResolveValueMargin(leadingMargin, widthSize);
}
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()),
widthSize);
auto trailingMargin = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.margin(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.margin(), trailing[axis], CompactValue::ofZero());
return YGResolveValueMargin(trailingMargin, widthSize);
}
YGFloatOptional YGNode::getMarginForAxis(
@ -147,15 +169,14 @@ YGSize YGNode::measure(
float height,
YGMeasureMode heightMode,
void* layoutContext) {
return flags_.at<measureUsesContext_>()
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<baselineUsesContext_>()
return facebook::yoga::detail::getBooleanData(flags, baselineUsesContext_)
? baseline_.withContext(this, width, height, layoutContext)
: baseline_.noContext(this, width, height);
}
@ -166,7 +187,7 @@ 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<nodeType_>() = YGNodeTypeDefault;
setNodeType(YGNodeTypeDefault);
} else {
YGAssertWithNode(
this,
@ -182,14 +203,14 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) {
}
void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) {
flags_.at<measureUsesContext_>() = 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<measureUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, true);
decltype(YGNode::measure_) m;
m.withContext = measureFunc;
setMeasureFunc(m);
@ -208,10 +229,10 @@ void YGNode::insertChild(YGNodeRef child, uint32_t index) {
}
void YGNode::setDirty(bool isDirty) {
if (isDirty == flags_.at<isDirty_>()) {
if (isDirty == facebook::yoga::detail::getBooleanData(flags, isDirty_)) {
return;
}
flags_.at<isDirty_>() = isDirty;
facebook::yoga::detail::setBooleanData(flags, isDirty_, isDirty);
if (isDirty && dirtied_) {
dirtied_(this);
}
@ -232,7 +253,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) {
@ -270,7 +291,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) {
@ -307,6 +328,9 @@ void YGNode::setPosition(
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 =
@ -351,7 +375,9 @@ YGValue YGNode::resolveFlexBasisPtr() const {
return flexBasis;
}
if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) {
return flags_.at<useWebDefaults_>() ? YGValueAuto : YGValueZero;
return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_)
? YGValueAuto
: YGValueZero;
}
return YGValueAuto;
}
@ -390,7 +416,7 @@ void YGNode::cloneChildrenIfNeeded(void* cloneContext) {
}
void YGNode::markDirtyAndPropogate() {
if (!flags_.at<isDirty_>()) {
if (!facebook::yoga::detail::getBooleanData(flags, isDirty_)) {
setDirty(true);
setLayoutComputedFlexBasis(YGFloatOptional());
if (owner_) {
@ -400,7 +426,7 @@ void YGNode::markDirtyAndPropogate() {
}
void YGNode::markDirtyAndPropogateDownwards() {
flags_.at<isDirty_>() = true;
facebook::yoga::detail::setBooleanData(flags, isDirty_, true);
for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) {
childNode->markDirtyAndPropogateDownwards();
});
@ -427,83 +453,64 @@ float YGNode::resolveFlexShrink() const {
if (!style_.flexShrink().isUndefined()) {
return style_.flexShrink().unwrap();
}
if (!flags_.at<useWebDefaults_>() && !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<useWebDefaults_>() ? kWebDefaultFlexShrink
return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_)
? kWebDefaultFlexShrink
: kDefaultFlexShrink;
}
bool YGNode::isNodeFlexible() {
return (
(style_.positionType() == YGPositionTypeRelative) &&
(style_.positionType() != YGPositionTypeAbsolute) &&
(resolveFlexGrow() != 0 || resolveFlexShrink() != 0));
}
float YGNode::getLeadingBorder(const YGFlexDirection axis) const {
YGValue leadingBorder;
if (YGFlexDirectionIsRow(axis) &&
!style_.border()[YGEdgeStart].isUndefined()) {
leadingBorder = style_.border()[YGEdgeStart];
if (leadingBorder.value >= 0) {
return leadingBorder.value;
}
}
leadingBorder = YGComputedEdgeValue(
YGValue leadingBorder = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.border(), YGEdgeStart, leading[axis], CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.border(), leading[axis], CompactValue::ofZero());
return YGFloatMax(leadingBorder.value, 0.0f);
return fmaxf(leadingBorder.value, 0.0f);
}
float YGNode::getTrailingBorder(const YGFlexDirection flexDirection) const {
YGValue trailingBorder;
if (YGFlexDirectionIsRow(flexDirection) &&
!style_.border()[YGEdgeEnd].isUndefined()) {
trailingBorder = style_.border()[YGEdgeEnd];
if (trailingBorder.value >= 0.0f) {
return trailingBorder.value;
}
}
trailingBorder = YGComputedEdgeValue(
style_.border(), trailing[flexDirection], CompactValue::ofZero());
return YGFloatMax(trailingBorder.value, 0.0f);
float YGNode::getTrailingBorder(const YGFlexDirection axis) const {
YGValue trailingBorder = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.border(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.border(), trailing[axis], CompactValue::ofZero());
return fmaxf(trailingBorder.value, 0.0f);
}
YGFloatOptional YGNode::getLeadingPadding(
const YGFlexDirection axis,
const float widthSize) const {
const YGFloatOptional paddingEdgeStart =
YGResolveValue(style_.padding()[YGEdgeStart], widthSize);
if (YGFlexDirectionIsRow(axis) &&
!style_.padding()[YGEdgeStart].isUndefined() &&
!paddingEdgeStart.isUndefined() && paddingEdgeStart.unwrap() >= 0.0f) {
return paddingEdgeStart;
}
YGFloatOptional resolvedValue = YGResolveValue(
YGComputedEdgeValue(
style_.padding(), leading[axis], CompactValue::ofZero()),
widthSize);
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
auto leadingPadding = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.padding(),
YGEdgeStart,
leading[axis],
CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.padding(), leading[axis], CompactValue::ofZero());
return YGFloatOptionalMax(
YGResolveValue(leadingPadding, widthSize), YGFloatOptional(0.0f));
}
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);
return YGFloatOptionalMax(resolvedValue, YGFloatOptional(0.0f));
auto trailingPadding = YGFlexDirectionIsRow(axis)
? computeEdgeValueForRow(
style_.padding(), YGEdgeEnd, trailing[axis], CompactValue::ofZero())
: computeEdgeValueForColumn(
style_.padding(), trailing[axis], CompactValue::ofZero());
return YGFloatOptionalMax(
YGResolveValue(trailingPadding, widthSize), YGFloatOptional(0.0f));
}
YGFloatOptional YGNode::getLeadingPaddingAndBorder(
@ -536,11 +543,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 {
@ -577,7 +584,8 @@ void YGNode::reset() {
clearChildren();
auto webDefaults = flags_.at<useWebDefaults_>();
auto webDefaults =
facebook::yoga::detail::getBooleanData(flags, useWebDefaults_);
*this = YGNode{getConfig()};
if (webDefaults) {
useWebDefaults();

View File

@ -6,9 +6,12 @@
*/
#pragma once
#ifdef __cplusplus
#include <cstdint>
#include <stdio.h>
#include "Bitfield.h"
#include "BitUtils.h"
#include "CompactValue.h"
#include "YGConfig.h"
#include "YGLayout.h"
@ -35,10 +38,7 @@ private:
static constexpr size_t useWebDefaults_ = 7;
void* context_ = nullptr;
using Flags = facebook::yoga::
Bitfield<uint8_t, bool, bool, bool, YGNodeType, bool, bool, bool, bool>;
Flags flags_ =
{true, false, false, YGNodeTypeDefault, false, false, false, false};
uint8_t flags = 1;
uint8_t reserved_ = 0;
union {
YGMeasureFunc noContext;
@ -70,13 +70,13 @@ private:
void setBaselineFunc(decltype(baseline_));
void useWebDefaults() {
flags_.at<useWebDefaults_>() = 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!
@ -114,9 +114,13 @@ public:
void print(void*);
bool getHasNewLayout() const { return flags_.at<hasNewLayout_>(); }
bool getHasNewLayout() const {
return facebook::yoga::detail::getBooleanData(flags, hasNewLayout_);
}
YGNodeType getNodeType() const { return flags_.at<nodeType_>(); }
YGNodeType getNodeType() const {
return facebook::yoga::detail::getEnumData<YGNodeType>(flags, nodeType_);
}
bool hasMeasureFunc() const noexcept { return measure_.noContext != nullptr; }
@ -142,7 +146,9 @@ public:
uint32_t getLineIndex() const { return lineIndex_; }
bool isReferenceBaseline() { return flags_.at<isReferenceBaseline_>(); }
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
@ -175,7 +181,9 @@ public:
YGConfigRef getConfig() const { return config_; }
bool isDirty() const { return flags_.at<isDirty_>(); }
bool isDirty() const {
return facebook::yoga::detail::getBooleanData(flags, isDirty_);
}
std::array<YGValue, 2> getResolvedDimensions() const {
return resolvedDimensions_;
@ -185,6 +193,17 @@ public:
return resolvedDimensions_[index];
}
static CompactValue computeEdgeValueForColumn(
const YGStyle::Edges& edges,
YGEdge edge,
CompactValue defaultValue);
static CompactValue computeEdgeValueForRow(
const YGStyle::Edges& edges,
YGEdge rowEdge,
YGEdge edge,
CompactValue defaultValue);
// Methods related to positions, margin, padding and border
YGFloatOptional getLeadingPosition(
const YGFlexDirection axis,
@ -223,19 +242,22 @@ public:
void setPrintFunc(YGPrintFunc printFunc) {
print_.noContext = printFunc;
flags_.at<printUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, printUsesContext_, false);
}
void setPrintFunc(PrintWithContextFn printFunc) {
print_.withContext = printFunc;
flags_.at<printUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, printUsesContext_, true);
}
void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); }
void setHasNewLayout(bool hasNewLayout) {
flags_.at<hasNewLayout_>() = hasNewLayout;
facebook::yoga::detail::setBooleanData(flags, hasNewLayout_, hasNewLayout);
}
void setNodeType(YGNodeType nodeType) { flags_.at<nodeType_>() = nodeType; }
void setNodeType(YGNodeType nodeType) {
return facebook::yoga::detail::setEnumData<YGNodeType>(
flags, nodeType_, nodeType);
}
void setMeasureFunc(YGMeasureFunc measureFunc);
void setMeasureFunc(MeasureWithContextFn);
@ -244,11 +266,11 @@ public:
}
void setBaselineFunc(YGBaselineFunc baseLineFunc) {
flags_.at<baselineUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, false);
baseline_.noContext = baseLineFunc;
}
void setBaselineFunc(BaselineWithContextFn baseLineFunc) {
flags_.at<baselineUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, true);
baseline_.withContext = baseLineFunc;
}
void setBaselineFunc(std::nullptr_t) {
@ -264,7 +286,8 @@ public:
void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; }
void setIsReferenceBaseline(bool isReferenceBaseline) {
flags_.at<isReferenceBaseline_>() = isReferenceBaseline;
facebook::yoga::detail::setBooleanData(
flags, isReferenceBaseline_, isReferenceBaseline);
}
void setOwner(YGNodeRef owner) { owner_ = owner; }
@ -321,3 +344,5 @@ public:
bool isLayoutTreeEqualToNode(const YGNode& node) const;
void reset();
};
#endif

View File

@ -104,10 +104,13 @@ static void appendEdgeIfNotUndefined(
const string& str,
const YGStyle::Edges& edges,
const YGEdge edge) {
appendNumberIfNotUndefined(
base,
str,
YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined()));
// TODO: this doesn't take RTL / YGEdgeStart / YGEdgeEnd into account
auto value = (edge == YGEdgeLeft || edge == YGEdgeRight)
? YGNode::computeEdgeValueForRow(
edges, edge, edge, detail::CompactValue::ofUndefined())
: YGNode::computeEdgeValueForColumn(
edges, edge, detail::CompactValue::ofUndefined());
appendNumberIfNotUndefined(base, str, value);
}
void YGNodeToString(

View File

@ -6,16 +6,19 @@
*/
#pragma once
#ifdef __cplusplus
#include <algorithm>
#include <array>
#include <cstdint>
#include <type_traits>
#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 <typename Enum>
@ -27,6 +30,19 @@ public:
using Dimensions = Values<YGDimension>;
using Edges = Values<YGEdge>;
template <typename T>
struct BitfieldRef {
YGStyle& style;
size_t offset;
operator T() const {
return facebook::yoga::detail::getEnumData<T>(style.flags, offset);
}
BitfieldRef<T>& operator=(T x) {
facebook::yoga::detail::setEnumData<T>(style.flags, offset, x);
return *this;
}
};
template <typename T, T YGStyle::*Prop>
struct Ref {
YGStyle& style;
@ -60,43 +76,35 @@ public:
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<
uint32_t,
YGDirection,
YGFlexDirection,
YGJustify,
YGAlign,
YGAlign,
YGAlign,
YGPositionType,
YGWrap,
YGOverflow,
YGDisplay>;
static constexpr size_t directionOffset = 0;
static constexpr size_t flexdirectionOffset =
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
static constexpr size_t justifyContentOffset = flexdirectionOffset +
facebook::yoga::detail::bitWidthFn<YGFlexDirection>();
static constexpr size_t alignContentOffset =
justifyContentOffset + facebook::yoga::detail::bitWidthFn<YGJustify>();
static constexpr size_t alignItemsOffset =
alignContentOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t alignSelfOffset =
alignItemsOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t positionTypeOffset =
alignSelfOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t flexWrapOffset =
positionTypeOffset + facebook::yoga::detail::bitWidthFn<YGPositionType>();
static constexpr size_t overflowOffset =
flexWrapOffset + facebook::yoga::detail::bitWidthFn<YGWrap>();
static constexpr size_t displayOffset =
overflowOffset + facebook::yoga::detail::bitWidthFn<YGOverflow>();
uint32_t flags = 0;
Flags flags_ = {YGDirectionInherit,
YGFlexDirectionColumn,
YGJustifyFlexStart,
YGAlignFlexStart,
YGAlignStretch,
YGAlignAuto,
YGPositionTypeRelative,
YGWrapNoWrap,
YGOverflowVisible,
YGDisplayFlex};
YGFloatOptional flex_ = {};
YGFloatOptional flexGrow_ = {};
YGFloatOptional flexShrink_ = {};
@ -115,45 +123,68 @@ public:
// for library users needing a type
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
YGDirection direction() const { return flags_.at<directionIdx>(); }
Flags::Ref<directionIdx> direction() { return flags_.at<directionIdx>(); }
YGDirection direction() const {
return facebook::yoga::detail::getEnumData<YGDirection>(
flags, directionOffset);
}
BitfieldRef<YGDirection> direction() { return {*this, directionOffset}; }
YGFlexDirection flexDirection() const {
return flags_.at<flexDirectionIdx>();
return facebook::yoga::detail::getEnumData<YGFlexDirection>(
flags, flexdirectionOffset);
}
Flags::Ref<flexDirectionIdx> flexDirection() {
return flags_.at<flexDirectionIdx>();
BitfieldRef<YGFlexDirection> flexDirection() {
return {*this, flexdirectionOffset};
}
YGJustify justifyContent() const { return flags_.at<justifyContentIdx>(); }
Flags::Ref<justifyContentIdx> justifyContent() {
return flags_.at<justifyContentIdx>();
YGJustify justifyContent() const {
return facebook::yoga::detail::getEnumData<YGJustify>(
flags, justifyContentOffset);
}
BitfieldRef<YGJustify> justifyContent() {
return {*this, justifyContentOffset};
}
YGAlign alignContent() const { return flags_.at<alignContentIdx>(); }
Flags::Ref<alignContentIdx> alignContent() {
return flags_.at<alignContentIdx>();
YGAlign alignContent() const {
return facebook::yoga::detail::getEnumData<YGAlign>(
flags, alignContentOffset);
}
BitfieldRef<YGAlign> alignContent() { return {*this, alignContentOffset}; }
YGAlign alignItems() const {
return facebook::yoga::detail::getEnumData<YGAlign>(
flags, alignItemsOffset);
}
BitfieldRef<YGAlign> alignItems() { return {*this, alignItemsOffset}; }
YGAlign alignSelf() const {
return facebook::yoga::detail::getEnumData<YGAlign>(flags, alignSelfOffset);
}
BitfieldRef<YGAlign> alignSelf() { return {*this, alignSelfOffset}; }
YGPositionType positionType() const {
return facebook::yoga::detail::getEnumData<YGPositionType>(
flags, positionTypeOffset);
}
BitfieldRef<YGPositionType> positionType() {
return {*this, positionTypeOffset};
}
YGAlign alignItems() const { return flags_.at<alignItemsIdx>(); }
Flags::Ref<alignItemsIdx> alignItems() { return flags_.at<alignItemsIdx>(); }
YGAlign alignSelf() const { return flags_.at<alignSelfIdx>(); }
Flags::Ref<alignSelfIdx> alignSelf() { return flags_.at<alignSelfIdx>(); }
YGPositionType positionType() const { return flags_.at<positionTypeIdx>(); }
Flags::Ref<positionTypeIdx> positionType() {
return flags_.at<positionTypeIdx>();
YGWrap flexWrap() const {
return facebook::yoga::detail::getEnumData<YGWrap>(flags, flexWrapOffset);
}
BitfieldRef<YGWrap> flexWrap() { return {*this, flexWrapOffset}; }
YGWrap flexWrap() const { return flags_.at<flexWrapIdx>(); }
Flags::Ref<flexWrapIdx> flexWrap() { return flags_.at<flexWrapIdx>(); }
YGOverflow overflow() const {
return facebook::yoga::detail::getEnumData<YGOverflow>(
flags, overflowOffset);
}
BitfieldRef<YGOverflow> overflow() { return {*this, overflowOffset}; }
YGOverflow overflow() const { return flags_.at<overflowIdx>(); }
Flags::Ref<overflowIdx> overflow() { return flags_.at<overflowIdx>(); }
YGDisplay display() const { return flags_.at<displayIdx>(); }
Flags::Ref<displayIdx> display() { return flags_.at<displayIdx>(); }
YGDisplay display() const {
return facebook::yoga::detail::getEnumData<YGDisplay>(flags, displayOffset);
}
BitfieldRef<YGDisplay> display() { return {*this, displayOffset}; }
YGFloatOptional flex() const { return flex_; }
Ref<YGFloatOptional, &YGStyle::flex_> flex() { return {*this}; }
@ -201,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

View File

@ -11,6 +11,13 @@
#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 <limits>
constexpr float YGUndefined = std::numeric_limits<float>::quiet_NaN();
#else
YG_EXTERN_C_BEGIN
// Not defined in MSVC++
@ -20,6 +27,7 @@ static const uint32_t __nan = 0x7fc00000;
#endif
#define YGUndefined NAN
#endif
typedef struct YGValue {
float value;
@ -30,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

View File

@ -33,6 +33,10 @@ inline bool isUndefined(float value) {
return std::isnan(value);
}
inline bool isUndefined(double value) {
return std::isnan(value);
}
} // namespace yoga
} // namespace facebook
@ -54,10 +58,10 @@ 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) {}
@ -144,8 +148,3 @@ static const float kDefaultFlexShrink = 0.0f;
static const float kWebDefaultFlexShrink = 1.0f;
extern bool YGFloatsEqual(const float a, const float b);
extern facebook::yoga::detail::CompactValue YGComputedEdgeValue(
const facebook::yoga::detail::Values<
facebook::yoga::enums::count<YGEdge>()>& edges,
YGEdge edge,
facebook::yoga::detail::CompactValue defaultValue);

View File

@ -106,38 +106,12 @@ static int YGDefaultLog(
#undef YG_UNUSED
#endif
YOGA_EXPORT bool YGFloatIsUndefined(const float value) {
static inline bool YGDoubleIsUndefined(const double value) {
return facebook::yoga::isUndefined(value);
}
detail::CompactValue YGComputedEdgeValue(
const YGStyle::Edges& edges,
YGEdge edge,
detail::CompactValue defaultValue) {
if (!edges[edge].isUndefined()) {
return edges[edge];
}
if ((edge == YGEdgeTop || edge == YGEdgeBottom) &&
!edges[YGEdgeVertical].isUndefined()) {
return edges[YGEdgeVertical];
}
if ((edge == YGEdgeLeft || edge == YGEdgeRight || edge == YGEdgeStart ||
edge == YGEdgeEnd) &&
!edges[YGEdgeHorizontal].isUndefined()) {
return edges[YGEdgeHorizontal];
}
if (!edges[YGEdgeAll].isUndefined()) {
return edges[YGEdgeAll];
}
if (edge == YGEdgeStart || edge == YGEdgeEnd) {
return detail::CompactValue::ofUndefined();
}
return defaultValue;
YOGA_EXPORT bool YGFloatIsUndefined(const float value) {
return facebook::yoga::isUndefined(value);
}
YOGA_EXPORT void* YGNodeGetContext(YGNodeRef node) {
@ -249,9 +223,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;
}
@ -386,6 +357,14 @@ YOGA_EXPORT void YGNodeInsertChild(
owner->markDirtyAndPropogate();
}
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) {
@ -1126,7 +1105,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;
}
@ -1655,8 +1634,8 @@ static void YGNodeAbsoluteLayoutChild(
static void YGNodeWithMeasureFuncSetMeasuredDimensions(
const YGNodeRef node,
const float availableWidth,
const float availableHeight,
float availableWidth,
float availableHeight,
const YGMeasureMode widthMeasureMode,
const YGMeasureMode heightMeasureMode,
const float ownerWidth,
@ -1669,40 +1648,40 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(
node->hasMeasureFunc(),
"Expected node to have custom measure function");
const float paddingAndBorderAxisRow =
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth);
const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis(
node, YGFlexDirectionColumn, availableWidth);
const float marginAxisRow =
node->getMarginForAxis(YGFlexDirectionRow, availableWidth).unwrap();
const float marginAxisColumn =
node->getMarginForAxis(YGFlexDirectionColumn, availableWidth).unwrap();
if (widthMeasureMode == YGMeasureModeUndefined) {
availableWidth = YGUndefined;
}
if (heightMeasureMode == YGMeasureModeUndefined) {
availableHeight = YGUndefined;
}
const auto& padding = node->getLayout().padding;
const auto& border = node->getLayout().border;
const float paddingAndBorderAxisRow = padding[YGEdgeLeft] +
padding[YGEdgeRight] + border[YGEdgeLeft] + border[YGEdgeRight];
const float paddingAndBorderAxisColumn = padding[YGEdgeTop] +
padding[YGEdgeBottom] + border[YGEdgeTop] + border[YGEdgeBottom];
// We want to make sure we don't call measure with negative size
const float innerWidth = YGFloatIsUndefined(availableWidth)
? availableWidth
: YGFloatMax(0, availableWidth - marginAxisRow - paddingAndBorderAxisRow);
: YGFloatMax(0, availableWidth - paddingAndBorderAxisRow);
const float innerHeight = YGFloatIsUndefined(availableHeight)
? availableHeight
: YGFloatMax(
0, availableHeight - marginAxisColumn - paddingAndBorderAxisColumn);
: YGFloatMax(0, availableHeight - 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),
node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth),
YGDimensionWidth);
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node,
YGFlexDirectionColumn,
availableHeight - marginAxisColumn,
availableHeight,
ownerHeight,
ownerWidth),
YGDimensionHeight);
@ -1739,7 +1718,7 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(
(widthMeasureMode == YGMeasureModeUndefined ||
widthMeasureMode == YGMeasureModeAtMost)
? measuredSize.width + paddingAndBorderAxisRow
: availableWidth - marginAxisRow,
: availableWidth,
ownerWidth,
ownerWidth),
YGDimensionWidth);
@ -1751,7 +1730,7 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(
(heightMeasureMode == YGMeasureModeUndefined ||
heightMeasureMode == YGMeasureModeAtMost)
? measuredSize.height + paddingAndBorderAxisColumn
: availableHeight - marginAxisColumn,
: availableHeight,
ownerHeight,
ownerWidth),
YGDimensionHeight);
@ -1768,37 +1747,28 @@ static void YGNodeEmptyContainerSetMeasuredDimensions(
const YGMeasureMode heightMeasureMode,
const float ownerWidth,
const float ownerHeight) {
const float paddingAndBorderAxisRow =
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth);
const float paddingAndBorderAxisColumn =
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth);
const float marginAxisRow =
node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap();
const float marginAxisColumn =
node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap();
const auto& padding = node->getLayout().padding;
const auto& border = node->getLayout().border;
float width = availableWidth;
if (widthMeasureMode == YGMeasureModeUndefined ||
widthMeasureMode == YGMeasureModeAtMost) {
width = padding[YGEdgeLeft] + padding[YGEdgeRight] + border[YGEdgeLeft] +
border[YGEdgeRight];
}
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node,
YGFlexDirectionRow,
(widthMeasureMode == YGMeasureModeUndefined ||
widthMeasureMode == YGMeasureModeAtMost)
? paddingAndBorderAxisRow
: availableWidth - marginAxisRow,
ownerWidth,
ownerWidth),
YGNodeBoundAxis(node, YGFlexDirectionRow, width, ownerWidth, ownerWidth),
YGDimensionWidth);
float height = availableHeight;
if (heightMeasureMode == YGMeasureModeUndefined ||
heightMeasureMode == YGMeasureModeAtMost) {
height = padding[YGEdgeTop] + padding[YGEdgeBottom] + border[YGEdgeTop] +
border[YGEdgeBottom];
}
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node,
YGFlexDirectionColumn,
(heightMeasureMode == YGMeasureModeUndefined ||
heightMeasureMode == YGMeasureModeAtMost)
? paddingAndBorderAxisColumn
: availableHeight - marginAxisColumn,
ownerHeight,
ownerWidth),
node, YGFlexDirectionColumn, height, ownerHeight, ownerWidth),
YGDimensionHeight);
}
@ -1816,11 +1786,6 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(
heightMeasureMode == YGMeasureModeAtMost && availableHeight <= 0.0f) ||
(widthMeasureMode == YGMeasureModeExactly &&
heightMeasureMode == YGMeasureModeExactly)) {
auto marginAxisColumn =
node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap();
auto marginAxisRow =
node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap();
node->setLayoutMeasuredDimension(
YGNodeBoundAxis(
node,
@ -1829,7 +1794,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(
(widthMeasureMode == YGMeasureModeAtMost &&
availableWidth < 0.0f)
? 0.0f
: availableWidth - marginAxisRow,
: availableWidth,
ownerWidth,
ownerWidth),
YGDimensionWidth);
@ -1842,7 +1807,7 @@ static bool YGNodeFixedSizeSetMeasuredDimensions(
(heightMeasureMode == YGMeasureModeAtMost &&
availableHeight < 0.0f)
? 0.0f
: availableHeight - marginAxisColumn,
: availableHeight,
ownerHeight,
ownerWidth),
YGDimensionHeight);
@ -1866,19 +1831,11 @@ static void YGZeroOutLayoutRecursivly(
static float YGNodeCalculateAvailableInnerDim(
const YGNodeConstRef node,
YGFlexDirection axis,
float availableDim,
float ownerDim) {
YGFlexDirection direction =
YGFlexDirectionIsRow(axis) ? YGFlexDirectionRow : YGFlexDirectionColumn;
YGDimension dimension =
YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight;
const float margin = node->getMarginForAxis(direction, ownerDim).unwrap();
const float paddingAndBorder =
YGNodePaddingAndBorderForAxis(node, direction, ownerDim);
float availableInnerDim = availableDim - margin - paddingAndBorder;
const YGDimension dimension,
const float availableDim,
const float paddingAndBorder,
const float ownerDim) {
float availableInnerDim = availableDim - paddingAndBorder;
// Max dimension overrides predefined dimension value; Min dimension in turn
// overrides both of the above
if (!YGFloatIsUndefined(availableInnerDim)) {
@ -2328,7 +2285,8 @@ static void YGDistributeFreeSpaceFirstPass(
// first and second passes.
deltaFreeSpace += boundMainSize - childFlexBasis;
collectedFlexItemsValues.totalFlexShrinkScaledFactors -=
flexShrinkScaledFactor;
(-currentRelativeChild->resolveFlexShrink() *
currentRelativeChild->getLayout().computedFlexBasis.unwrap());
}
}
} else if (
@ -2490,7 +2448,7 @@ static void YGJustifyMainAxis(
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++;
}
@ -2574,7 +2532,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 /
@ -2764,16 +2722,22 @@ static void YGNodelayoutImpl(
const YGEdge startEdge =
direction == YGDirectionLTR ? YGEdgeLeft : YGEdgeRight;
const YGEdge endEdge = direction == YGDirectionLTR ? YGEdgeRight : YGEdgeLeft;
node->setLayoutMargin(
node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap(), startEdge);
node->setLayoutMargin(
node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap(), endEdge);
node->setLayoutMargin(
node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap(),
YGEdgeTop);
node->setLayoutMargin(
node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap(),
YGEdgeBottom);
const float marginRowLeading =
node->getLeadingMargin(flexRowDirection, ownerWidth).unwrap();
node->setLayoutMargin(marginRowLeading, startEdge);
const float marginRowTrailing =
node->getTrailingMargin(flexRowDirection, ownerWidth).unwrap();
node->setLayoutMargin(marginRowTrailing, endEdge);
const float marginColumnLeading =
node->getLeadingMargin(flexColumnDirection, ownerWidth).unwrap();
node->setLayoutMargin(marginColumnLeading, YGEdgeTop);
const float marginColumnTrailing =
node->getTrailingMargin(flexColumnDirection, ownerWidth).unwrap();
node->setLayoutMargin(marginColumnTrailing, YGEdgeBottom);
const float marginAxisRow = marginRowLeading + marginRowTrailing;
const float marginAxisColumn = marginColumnLeading + marginColumnTrailing;
node->setLayoutBorder(node->getLeadingBorder(flexRowDirection), startEdge);
node->setLayoutBorder(node->getTrailingBorder(flexRowDirection), endEdge);
@ -2796,8 +2760,8 @@ static void YGNodelayoutImpl(
if (node->hasMeasureFunc()) {
YGNodeWithMeasureFuncSetMeasuredDimensions(
node,
availableWidth,
availableHeight,
availableWidth - marginAxisRow,
availableHeight - marginAxisColumn,
widthMeasureMode,
heightMeasureMode,
ownerWidth,
@ -2812,8 +2776,8 @@ static void YGNodelayoutImpl(
if (childCount == 0) {
YGNodeEmptyContainerSetMeasuredDimensions(
node,
availableWidth,
availableHeight,
availableWidth - marginAxisRow,
availableHeight - marginAxisColumn,
widthMeasureMode,
heightMeasureMode,
ownerWidth,
@ -2826,8 +2790,8 @@ static void YGNodelayoutImpl(
if (!performLayout &&
YGNodeFixedSizeSetMeasuredDimensions(
node,
availableWidth,
availableHeight,
availableWidth - marginAxisRow,
availableHeight - marginAxisColumn,
widthMeasureMode,
heightMeasureMode,
ownerWidth,
@ -2851,12 +2815,14 @@ static void YGNodelayoutImpl(
const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight;
const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth;
const float leadingPaddingAndBorderCross =
node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap();
const float paddingAndBorderAxisMain =
YGNodePaddingAndBorderForAxis(node, mainAxis, ownerWidth);
const float leadingPaddingAndBorderCross =
node->getLeadingPaddingAndBorder(crossAxis, ownerWidth).unwrap();
const float trailingPaddingAndBorderCross =
node->getTrailingPaddingAndBorder(crossAxis, ownerWidth).unwrap();
const float paddingAndBorderAxisCross =
YGNodePaddingAndBorderForAxis(node, crossAxis, ownerWidth);
leadingPaddingAndBorderCross + trailingPaddingAndBorderCross;
YGMeasureMode measureModeMainDim =
isMainAxisRow ? widthMeasureMode : heightMeasureMode;
@ -2868,35 +2834,20 @@ static void YGNodelayoutImpl(
const float paddingAndBorderAxisColumn =
isMainAxisRow ? paddingAndBorderAxisCross : paddingAndBorderAxisMain;
const float marginAxisRow =
node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap();
const float marginAxisColumn =
node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap();
const auto& minDimensions = node->getStyle().minDimensions();
const auto& maxDimensions = node->getStyle().maxDimensions();
const float minInnerWidth =
YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() -
paddingAndBorderAxisRow;
const float maxInnerWidth =
YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() -
paddingAndBorderAxisRow;
const float minInnerHeight =
YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight).unwrap() -
paddingAndBorderAxisColumn;
const float maxInnerHeight =
YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight).unwrap() -
paddingAndBorderAxisColumn;
const float minInnerMainDim = isMainAxisRow ? minInnerWidth : minInnerHeight;
const float maxInnerMainDim = isMainAxisRow ? maxInnerWidth : maxInnerHeight;
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
float availableInnerWidth = YGNodeCalculateAvailableInnerDim(
node, YGFlexDirectionRow, availableWidth, ownerWidth);
node,
YGDimensionWidth,
availableWidth - marginAxisRow,
paddingAndBorderAxisRow,
ownerWidth);
float availableInnerHeight = YGNodeCalculateAvailableInnerDim(
node, YGFlexDirectionColumn, availableHeight, ownerHeight);
node,
YGDimensionHeight,
availableHeight - marginAxisColumn,
paddingAndBorderAxisColumn,
ownerHeight);
float availableInnerMainDim =
isMainAxisRow ? availableInnerWidth : availableInnerHeight;
@ -2968,6 +2919,28 @@ static void YGNodelayoutImpl(
// If we don't measure with exact main dimension we want to ensure we don't
// violate min and max
if (measureModeMainDim != YGMeasureModeExactly) {
const auto& minDimensions = node->getStyle().minDimensions();
const auto& maxDimensions = node->getStyle().maxDimensions();
const float minInnerWidth =
YGResolveValue(minDimensions[YGDimensionWidth], ownerWidth).unwrap() -
paddingAndBorderAxisRow;
const float maxInnerWidth =
YGResolveValue(maxDimensions[YGDimensionWidth], ownerWidth).unwrap() -
paddingAndBorderAxisRow;
const float minInnerHeight =
YGResolveValue(minDimensions[YGDimensionHeight], ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn;
const float maxInnerHeight =
YGResolveValue(maxDimensions[YGDimensionHeight], ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn;
const float minInnerMainDim =
isMainAxisRow ? minInnerWidth : minInnerHeight;
const float maxInnerMainDim =
isMainAxisRow ? maxInnerWidth : maxInnerHeight;
if (!YGFloatIsUndefined(minInnerMainDim) &&
collectedFlexItemsValues.sizeConsumedOnCurrentLine <
minInnerMainDim) {
@ -3296,7 +3269,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;
}
@ -3338,7 +3311,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(
@ -3516,8 +3489,8 @@ static void YGNodelayoutImpl(
YGNodeBoundAxisWithinMinAndMax(
node,
crossAxis,
YGFloatOptional{totalLineCrossDim +
paddingAndBorderAxisCross},
YGFloatOptional{
totalLineCrossDim + paddingAndBorderAxisCross},
crossAxisownerSize)
.unwrap()),
paddingAndBorderAxisCross),
@ -3529,7 +3502,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]] -
@ -3542,7 +3515,8 @@ static void YGNodelayoutImpl(
if (performLayout) {
// STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN
for (auto child : node->getChildren()) {
if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
if (child->getStyle().display() == YGDisplayNone ||
child->getStyle().positionType() != YGPositionTypeAbsolute) {
continue;
}
YGNodeAbsoluteLayoutChild(
@ -3646,14 +3620,14 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
}
YOGA_EXPORT float YGRoundValueToPixelGrid(
const float value,
const float pointScaleFactor,
const double value,
const double pointScaleFactor,
const bool forceCeil,
const bool forceFloor) {
double scaledValue = ((double) value) * pointScaleFactor;
double scaledValue = value * pointScaleFactor;
// We want to calculate `fractial` such that `floor(scaledValue) = scaledValue
// - fractial`.
float fractial = fmodf(scaledValue, 1.0f);
double fractial = fmod(scaledValue, 1.0);
if (fractial < 0) {
// This branch is for handling negative numbers for `value`.
//
@ -3672,28 +3646,28 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(
// - 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)) {
scaledValue = scaledValue - fractial + 1.0f;
} else if (YGDoubleEqual(fractial, 1.0)) {
scaledValue = scaledValue - fractial + 1.0;
} else if (forceCeil) {
// Next we check if we need to use forced rounding
scaledValue = scaledValue - fractial + 1.0f;
scaledValue = scaledValue - fractial + 1.0;
} else if (forceFloor) {
scaledValue = scaledValue - fractial;
} else {
// Finally we just round the value
scaledValue = scaledValue - fractial +
(!YGFloatIsUndefined(fractial) &&
(fractial > 0.5f || YGFloatsEqual(fractial, 0.5f))
? 1.0f
: 0.0f);
(!YGDoubleIsUndefined(fractial) &&
(fractial > 0.5 || YGDoubleEqual(fractial, 0.5))
? 1.0
: 0.0);
}
return (YGFloatIsUndefined(scaledValue) ||
YGFloatIsUndefined(pointScaleFactor))
return (YGDoubleIsUndefined(scaledValue) ||
YGDoubleIsUndefined(pointScaleFactor))
? YGUndefined
: scaledValue / pointScaleFactor;
: (float) (scaledValue / pointScaleFactor);
}
YOGA_EXPORT bool YGNodeCanUseCachedMeasurement(
@ -3803,8 +3777,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;
}
@ -4061,24 +4037,24 @@ YOGA_EXPORT void YGConfigSetPointScaleFactor(
static void YGRoundToPixelGrid(
const YGNodeRef node,
const float pointScaleFactor,
const float absoluteLeft,
const float absoluteTop) {
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.
@ -4096,11 +4072,11 @@ static void YGRoundToPixelGrid(
// whole number, we don't have any fraction To verify if the result is close
// to whole number we want to check both floor and ceil numbers
const bool hasFractionalWidth =
!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(
@ -4321,6 +4297,7 @@ YOGA_EXPORT void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
void YGAssert(const bool condition, const char* message) {
if (!condition) {
Log::log(YGNodeRef{nullptr}, YGLogLevelFatal, nullptr, "%s\n", message);
throwLogicalErrorWithMessage(message);
}
}
@ -4330,6 +4307,7 @@ void YGAssertWithNode(
const char* message) {
if (!condition) {
Log::log(node, YGLogLevelFatal, nullptr, "%s\n", message);
throwLogicalErrorWithMessage(message);
}
}
@ -4339,6 +4317,7 @@ void YGAssertWithConfig(
const char* message) {
if (!condition) {
Log::log(config, YGLogLevelFatal, nullptr, "%s\n", message);
throwLogicalErrorWithMessage(message);
}
}

View File

@ -69,6 +69,11 @@ WIN_EXPORT void YGNodeInsertChild(
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);
WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index);
@ -102,7 +107,7 @@ WIN_EXPORT void YGNodeMarkDirty(YGNodeRef node);
// Marks the current node and all its descendants as dirty.
//
// Intended to be used for Uoga benchmarks. Don't use in production, as calling
// Intended to be used for Yoga benchmarks. Don't use in production, as calling
// `YGCalculateLayout` will cause the recalculation of each and every node.
WIN_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(YGNodeRef node);
@ -347,8 +352,8 @@ WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context);
WIN_EXPORT void* YGConfigGetContext(YGConfigRef config);
WIN_EXPORT float YGRoundValueToPixelGrid(
float value,
float pointScaleFactor,
double value,
double pointScaleFactor,
bool forceCeil,
bool forceFloor);

View File

@ -8,7 +8,6 @@
#include "event.h"
#include <atomic>
#include <memory>
#include <stdexcept>
namespace facebook {
namespace yoga {

View File

@ -11,6 +11,7 @@
#include <vector>
#include <array>
#include <yoga/YGEnums.h>
#include <stdint.h>
struct YGConfig;
struct YGNode;

View File

@ -26,10 +26,6 @@ void vlog(
va_list args) {
YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault();
logConfig->log(logConfig, node, level, context, format, args);
if (level == YGLogLevelFatal) {
abort();
}
}
} // namespace