add third party: yoga 1.18.0
This commit is contained in:
parent
fc0df69ed4
commit
1b83298102
@ -41,7 +41,19 @@ SOURCES += \
|
|||||||
shader/DoricVLayoutNode.cpp \
|
shader/DoricVLayoutNode.cpp \
|
||||||
shader/DoricViewNode.cpp \
|
shader/DoricViewNode.cpp \
|
||||||
utils/DoricConstant.cpp \
|
utils/DoricConstant.cpp \
|
||||||
utils/DoricContextHolder.cpp
|
utils/DoricContextHolder.cpp \
|
||||||
|
yoga/Utils.cpp \
|
||||||
|
yoga/YGConfig.cpp \
|
||||||
|
yoga/YGEnums.cpp \
|
||||||
|
yoga/YGLayout.cpp \
|
||||||
|
yoga/YGNode.cpp \
|
||||||
|
yoga/YGNodePrint.cpp \
|
||||||
|
yoga/YGStyle.cpp \
|
||||||
|
yoga/YGValue.cpp \
|
||||||
|
yoga/Yoga.cpp \
|
||||||
|
yoga/event/event.cpp \
|
||||||
|
yoga/internal/experiments.cpp \
|
||||||
|
yoga/log.cpp
|
||||||
|
|
||||||
RESOURCES += qml.qrc
|
RESOURCES += qml.qrc
|
||||||
|
|
||||||
@ -93,4 +105,22 @@ HEADERS += \
|
|||||||
utils/DoricCountDownLatch.h \
|
utils/DoricCountDownLatch.h \
|
||||||
utils/DoricObjectFactory.h \
|
utils/DoricObjectFactory.h \
|
||||||
utils/DoricThreadMode.h \
|
utils/DoricThreadMode.h \
|
||||||
utils/DoricUtils.h
|
utils/DoricUtils.h \
|
||||||
|
yoga/Bitfield.h \
|
||||||
|
yoga/CompactValue.h \
|
||||||
|
yoga/Utils.h \
|
||||||
|
yoga/YGConfig.h \
|
||||||
|
yoga/YGEnums.h \
|
||||||
|
yoga/YGFloatOptional.h \
|
||||||
|
yoga/YGLayout.h \
|
||||||
|
yoga/YGMacros.h \
|
||||||
|
yoga/YGNode.h \
|
||||||
|
yoga/YGNodePrint.h \
|
||||||
|
yoga/YGStyle.h \
|
||||||
|
yoga/YGValue.h \
|
||||||
|
yoga/Yoga-internal.h \
|
||||||
|
yoga/Yoga.h \
|
||||||
|
yoga/event/event.h \
|
||||||
|
yoga/internal/experiments-inl.h \
|
||||||
|
yoga/internal/experiments.h \
|
||||||
|
yoga/log.h
|
||||||
|
145
doric-Qt/doric/yoga/Bitfield.h
Normal file
145
doric-Qt/doric/yoga/Bitfield.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
184
doric-Qt/doric/yoga/CompactValue.h
Normal file
184
doric-Qt/doric/yoga/CompactValue.h
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* 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 "YGValue.h"
|
||||||
|
#include "YGMacros.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::numeric_limits<float>::is_iec559,
|
||||||
|
"facebook::yoga::detail::CompactValue only works with IEEE754 floats");
|
||||||
|
|
||||||
|
#ifdef YOGA_COMPACT_VALUE_TEST
|
||||||
|
#define VISIBLE_FOR_TESTING public:
|
||||||
|
#else
|
||||||
|
#define VISIBLE_FOR_TESTING private:
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// This class stores YGValue in 32 bits.
|
||||||
|
// - The value does not matter for Undefined and Auto. NaNs are used for their
|
||||||
|
// representation.
|
||||||
|
// - To differentiate between Point and Percent, one exponent bit is used.
|
||||||
|
// Supported the range [0x40, 0xbf] (0xbf is inclusive for point, but
|
||||||
|
// exclusive for percent).
|
||||||
|
// - Value ranges:
|
||||||
|
// points: 1.08420217e-19f to 36893485948395847680
|
||||||
|
// 0x00000000 0x3fffffff
|
||||||
|
// percent: 1.08420217e-19f to 18446742974197923840
|
||||||
|
// 0x40000000 0x7f7fffff
|
||||||
|
// - Zero is supported, negative zero is not
|
||||||
|
// - values outside of the representable range are clamped
|
||||||
|
class YOGA_EXPORT CompactValue {
|
||||||
|
friend constexpr bool operator==(CompactValue, CompactValue) noexcept;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr auto LOWER_BOUND = 1.08420217e-19f;
|
||||||
|
static constexpr auto UPPER_BOUND_POINT = 36893485948395847680.0f;
|
||||||
|
static constexpr auto UPPER_BOUND_PERCENT = 18446742974197923840.0f;
|
||||||
|
|
||||||
|
template <YGUnit Unit>
|
||||||
|
static CompactValue of(float value) noexcept {
|
||||||
|
if (value == 0.0f || (value < LOWER_BOUND && value > -LOWER_BOUND)) {
|
||||||
|
constexpr auto zero =
|
||||||
|
Unit == YGUnitPercent ? ZERO_BITS_PERCENT : ZERO_BITS_POINT;
|
||||||
|
return {Payload{zero}};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto upperBound =
|
||||||
|
Unit == YGUnitPercent ? UPPER_BOUND_PERCENT : UPPER_BOUND_POINT;
|
||||||
|
if (value > upperBound || value < -upperBound) {
|
||||||
|
value = copysignf(upperBound, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t unitBit = Unit == YGUnitPercent ? PERCENT_BIT : 0;
|
||||||
|
auto data = Payload{value};
|
||||||
|
data.repr -= BIAS;
|
||||||
|
data.repr |= unitBit;
|
||||||
|
return {data};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <YGUnit Unit>
|
||||||
|
static CompactValue ofMaybe(float value) noexcept {
|
||||||
|
return std::isnan(value) || std::isinf(value) ? ofUndefined()
|
||||||
|
: of<Unit>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr CompactValue ofZero() noexcept {
|
||||||
|
return CompactValue{Payload{ZERO_BITS_POINT}};
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr CompactValue ofUndefined() noexcept {
|
||||||
|
return CompactValue{};
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr CompactValue ofAuto() noexcept {
|
||||||
|
return CompactValue{Payload{AUTO_BITS}};
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr CompactValue() noexcept
|
||||||
|
: payload_(std::numeric_limits<float>::quiet_NaN()) {}
|
||||||
|
|
||||||
|
CompactValue(const YGValue& x) noexcept : payload_(uint32_t{0}) {
|
||||||
|
switch (x.unit) {
|
||||||
|
case YGUnitUndefined:
|
||||||
|
*this = ofUndefined();
|
||||||
|
break;
|
||||||
|
case YGUnitAuto:
|
||||||
|
*this = ofAuto();
|
||||||
|
break;
|
||||||
|
case YGUnitPoint:
|
||||||
|
*this = of<YGUnitPoint>(x.value);
|
||||||
|
break;
|
||||||
|
case YGUnitPercent:
|
||||||
|
*this = of<YGUnitPercent>(x.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator YGValue() const noexcept {
|
||||||
|
switch (payload_.repr) {
|
||||||
|
case AUTO_BITS:
|
||||||
|
return YGValueAuto;
|
||||||
|
case ZERO_BITS_POINT:
|
||||||
|
return YGValue{0.0f, YGUnitPoint};
|
||||||
|
case ZERO_BITS_PERCENT:
|
||||||
|
return YGValue{0.0f, YGUnitPercent};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std::isnan(payload_.value)) {
|
||||||
|
return YGValueUndefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto data = payload_;
|
||||||
|
data.repr &= ~PERCENT_BIT;
|
||||||
|
data.repr += BIAS;
|
||||||
|
|
||||||
|
return YGValue{data.value,
|
||||||
|
payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUndefined() const noexcept {
|
||||||
|
return (
|
||||||
|
payload_.repr != AUTO_BITS && payload_.repr != ZERO_BITS_POINT &&
|
||||||
|
payload_.repr != ZERO_BITS_PERCENT && std::isnan(payload_.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAuto() const noexcept { return payload_.repr == AUTO_BITS; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
union Payload {
|
||||||
|
float value;
|
||||||
|
uint32_t repr;
|
||||||
|
Payload() = delete;
|
||||||
|
constexpr Payload(uint32_t r) : repr(r) {}
|
||||||
|
constexpr Payload(float v) : value(v) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr uint32_t BIAS = 0x20000000;
|
||||||
|
static constexpr uint32_t PERCENT_BIT = 0x40000000;
|
||||||
|
|
||||||
|
// these are signaling NaNs with specific bit pattern as payload they will be
|
||||||
|
// silenced whenever going through an FPU operation on ARM + x86
|
||||||
|
static constexpr uint32_t AUTO_BITS = 0x7faaaaaa;
|
||||||
|
static constexpr uint32_t ZERO_BITS_POINT = 0x7f8f0f0f;
|
||||||
|
static constexpr uint32_t ZERO_BITS_PERCENT = 0x7f80f0f0;
|
||||||
|
|
||||||
|
constexpr CompactValue(Payload data) noexcept : payload_(data) {}
|
||||||
|
|
||||||
|
Payload payload_;
|
||||||
|
|
||||||
|
VISIBLE_FOR_TESTING uint32_t repr() { return payload_.repr; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
CompactValue CompactValue::of<YGUnitUndefined>(float) noexcept = delete;
|
||||||
|
template <>
|
||||||
|
CompactValue CompactValue::of<YGUnitAuto>(float) noexcept = delete;
|
||||||
|
template <>
|
||||||
|
CompactValue CompactValue::ofMaybe<YGUnitUndefined>(float) noexcept = delete;
|
||||||
|
template <>
|
||||||
|
CompactValue CompactValue::ofMaybe<YGUnitAuto>(float) noexcept = delete;
|
||||||
|
|
||||||
|
constexpr bool operator==(CompactValue a, CompactValue b) noexcept {
|
||||||
|
return a.payload_.repr == b.payload_.repr;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool operator!=(CompactValue a, CompactValue b) noexcept {
|
||||||
|
return !(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
67
doric-Qt/doric/yoga/Utils.cpp
Normal file
67
doric-Qt/doric/yoga/Utils.cpp
Normal 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
using namespace facebook;
|
||||||
|
|
||||||
|
YGFlexDirection YGFlexDirectionCross(
|
||||||
|
const YGFlexDirection flexDirection,
|
||||||
|
const YGDirection direction) {
|
||||||
|
return YGFlexDirectionIsColumn(flexDirection)
|
||||||
|
? YGResolveFlexDirection(YGFlexDirectionRow, direction)
|
||||||
|
: YGFlexDirectionColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
float YGFloatMax(const float a, const float b) {
|
||||||
|
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
|
||||||
|
return fmaxf(a, b);
|
||||||
|
}
|
||||||
|
return yoga::isUndefined(a) ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
float YGFloatMin(const float a, const float b) {
|
||||||
|
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
|
||||||
|
return fminf(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return yoga::isUndefined(a) ? b : a;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGValueEqual(const YGValue& a, const YGValue& b) {
|
||||||
|
if (a.unit != b.unit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.unit == YGUnitUndefined ||
|
||||||
|
(yoga::isUndefined(a.value) && yoga::isUndefined(b.value))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fabs(a.value - b.value) < 0.0001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGFloatsEqual(const float a, const float b) {
|
||||||
|
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
|
||||||
|
return fabs(a - b) < 0.0001f;
|
||||||
|
}
|
||||||
|
return yoga::isUndefined(a) && yoga::isUndefined(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
float YGFloatSanitize(const float val) {
|
||||||
|
return yoga::isUndefined(val) ? 0 : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) {
|
||||||
|
if (op1 >= op2) {
|
||||||
|
return op1;
|
||||||
|
}
|
||||||
|
if (op2 > op1) {
|
||||||
|
return op2;
|
||||||
|
}
|
||||||
|
return op1.isUndefined() ? op2 : op1;
|
||||||
|
}
|
143
doric-Qt/doric/yoga/Utils.h
Normal file
143
doric-Qt/doric/yoga/Utils.h
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* 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 "YGNode.h"
|
||||||
|
#include "Yoga-internal.h"
|
||||||
|
#include "CompactValue.h"
|
||||||
|
|
||||||
|
// This struct is an helper model to hold the data for step 4 of flexbox algo,
|
||||||
|
// which is collecting the flex items in a line.
|
||||||
|
//
|
||||||
|
// - itemsOnLine: Number of items which can fit in a line considering the
|
||||||
|
// available Inner dimension, the flex items computed flexbasis and their
|
||||||
|
// margin. It may be different than the difference between start and end
|
||||||
|
// indicates because we skip over absolute-positioned items.
|
||||||
|
//
|
||||||
|
// - sizeConsumedOnCurrentLine: It is accumulation of the dimensions and margin
|
||||||
|
// of all the children on the current line. This will be used in order to
|
||||||
|
// either set the dimensions of the node if none already exist or to compute
|
||||||
|
// the remaining space left for the flexible children.
|
||||||
|
//
|
||||||
|
// - totalFlexGrowFactors: total flex grow factors of flex items which are to be
|
||||||
|
// layed in the current line
|
||||||
|
//
|
||||||
|
// - totalFlexShrinkFactors: total flex shrink factors of flex items which are
|
||||||
|
// to be layed in the current line
|
||||||
|
//
|
||||||
|
// - endOfLineIndex: Its the end index of the last flex item which was examined
|
||||||
|
// and it may or may not be part of the current line(as it may be absolutely
|
||||||
|
// positioned or including it may have caused to overshoot availableInnerDim)
|
||||||
|
//
|
||||||
|
// - relativeChildren: Maintain a vector of the child nodes that can shrink
|
||||||
|
// and/or grow.
|
||||||
|
|
||||||
|
struct YGCollectFlexItemsRowValues {
|
||||||
|
uint32_t itemsOnLine;
|
||||||
|
float sizeConsumedOnCurrentLine;
|
||||||
|
float totalFlexGrowFactors;
|
||||||
|
float totalFlexShrinkScaledFactors;
|
||||||
|
uint32_t endOfLineIndex;
|
||||||
|
std::vector<YGNodeRef> relativeChildren;
|
||||||
|
float remainingFreeSpace;
|
||||||
|
// The size of the mainDim for the row after considering size, padding, margin
|
||||||
|
// and border of flex items. This is used to calculate maxLineDim after going
|
||||||
|
// through all the rows to decide on the main axis size of owner.
|
||||||
|
float mainDim;
|
||||||
|
// The size of the crossDim for the row after considering size, padding,
|
||||||
|
// margin and border of flex items. Used for calculating containers crossSize.
|
||||||
|
float crossDim;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool YGValueEqual(const YGValue& a, const YGValue& b);
|
||||||
|
inline bool YGValueEqual(
|
||||||
|
facebook::yoga::detail::CompactValue a,
|
||||||
|
facebook::yoga::detail::CompactValue b) {
|
||||||
|
return YGValueEqual((YGValue) a, (YGValue) b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This custom float equality function returns true if either absolute
|
||||||
|
// difference between two floats is less than 0.0001f or both are undefined.
|
||||||
|
bool YGFloatsEqual(const float a, const float b);
|
||||||
|
|
||||||
|
float YGFloatMax(const float a, const float b);
|
||||||
|
|
||||||
|
YGFloatOptional YGFloatOptionalMax(
|
||||||
|
const YGFloatOptional op1,
|
||||||
|
const YGFloatOptional op2);
|
||||||
|
|
||||||
|
float YGFloatMin(const float a, const float b);
|
||||||
|
|
||||||
|
// This custom float comparison function compares the array of float with
|
||||||
|
// YGFloatsEqual, as the default float comparison operator will not work(Look
|
||||||
|
// at the comments of YGFloatsEqual function).
|
||||||
|
template <std::size_t size>
|
||||||
|
bool YGFloatArrayEqual(
|
||||||
|
const std::array<float, size>& val1,
|
||||||
|
const std::array<float, size>& val2) {
|
||||||
|
bool areEqual = true;
|
||||||
|
for (std::size_t i = 0; i < size && areEqual; ++i) {
|
||||||
|
areEqual = YGFloatsEqual(val1[i], val2[i]);
|
||||||
|
}
|
||||||
|
return areEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function returns 0 if YGFloatIsUndefined(val) is true and val otherwise
|
||||||
|
float YGFloatSanitize(const float val);
|
||||||
|
|
||||||
|
YGFlexDirection YGFlexDirectionCross(
|
||||||
|
const YGFlexDirection flexDirection,
|
||||||
|
const YGDirection direction);
|
||||||
|
|
||||||
|
inline bool YGFlexDirectionIsRow(const YGFlexDirection flexDirection) {
|
||||||
|
return flexDirection == YGFlexDirectionRow ||
|
||||||
|
flexDirection == YGFlexDirectionRowReverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGFloatOptional YGResolveValue(
|
||||||
|
const YGValue value,
|
||||||
|
const float ownerSize) {
|
||||||
|
switch (value.unit) {
|
||||||
|
case YGUnitPoint:
|
||||||
|
return YGFloatOptional{value.value};
|
||||||
|
case YGUnitPercent:
|
||||||
|
return YGFloatOptional{value.value * ownerSize * 0.01f};
|
||||||
|
default:
|
||||||
|
return YGFloatOptional{};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGFloatOptional YGResolveValue(
|
||||||
|
yoga::detail::CompactValue value,
|
||||||
|
float ownerSize) {
|
||||||
|
return YGResolveValue((YGValue) value, ownerSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool YGFlexDirectionIsColumn(const YGFlexDirection flexDirection) {
|
||||||
|
return flexDirection == YGFlexDirectionColumn ||
|
||||||
|
flexDirection == YGFlexDirectionColumnReverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGFlexDirection YGResolveFlexDirection(
|
||||||
|
const YGFlexDirection flexDirection,
|
||||||
|
const YGDirection direction) {
|
||||||
|
if (direction == YGDirectionRTL) {
|
||||||
|
if (flexDirection == YGFlexDirectionRow) {
|
||||||
|
return YGFlexDirectionRowReverse;
|
||||||
|
} else if (flexDirection == YGFlexDirectionRowReverse) {
|
||||||
|
return YGFlexDirectionRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flexDirection;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGFloatOptional YGResolveValueMargin(
|
||||||
|
yoga::detail::CompactValue value,
|
||||||
|
const float ownerSize) {
|
||||||
|
return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize);
|
||||||
|
}
|
44
doric-Qt/doric/yoga/YGConfig.cpp
Normal file
44
doric-Qt/doric/yoga/YGConfig.cpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YGConfig.h"
|
||||||
|
|
||||||
|
YGConfig::YGConfig(YGLogger logger) : cloneNodeCallback_{nullptr} {
|
||||||
|
logger_.noContext = logger;
|
||||||
|
loggerUsesContext_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGConfig::log(
|
||||||
|
YGConfig* config,
|
||||||
|
YGNode* node,
|
||||||
|
YGLogLevel logLevel,
|
||||||
|
void* logContext,
|
||||||
|
const char* format,
|
||||||
|
va_list args) {
|
||||||
|
if (loggerUsesContext_) {
|
||||||
|
logger_.withContext(config, node, logLevel, logContext, format, args);
|
||||||
|
} else {
|
||||||
|
logger_.noContext(config, node, logLevel, format, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YGNodeRef YGConfig::cloneNode(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGNodeRef owner,
|
||||||
|
int childIndex,
|
||||||
|
void* cloneContext) {
|
||||||
|
YGNodeRef clone = nullptr;
|
||||||
|
if (cloneNodeCallback_.noContext != nullptr) {
|
||||||
|
clone = cloneNodeUsesContext_
|
||||||
|
? cloneNodeCallback_.withContext(node, owner, childIndex, cloneContext)
|
||||||
|
: cloneNodeCallback_.noContext(node, owner, childIndex);
|
||||||
|
}
|
||||||
|
if (clone == nullptr) {
|
||||||
|
clone = YGNodeClone(node);
|
||||||
|
}
|
||||||
|
return clone;
|
||||||
|
}
|
76
doric-Qt/doric/yoga/YGConfig.h
Normal file
76
doric-Qt/doric/yoga/YGConfig.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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 "Yoga-internal.h"
|
||||||
|
#include "Yoga.h"
|
||||||
|
|
||||||
|
struct YOGA_EXPORT YGConfig {
|
||||||
|
using LogWithContextFn = int (*)(
|
||||||
|
YGConfigRef config,
|
||||||
|
YGNodeRef node,
|
||||||
|
YGLogLevel level,
|
||||||
|
void* context,
|
||||||
|
const char* format,
|
||||||
|
va_list args);
|
||||||
|
using CloneWithContextFn = YGNodeRef (*)(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGNodeRef owner,
|
||||||
|
int childIndex,
|
||||||
|
void* cloneContext);
|
||||||
|
|
||||||
|
private:
|
||||||
|
union {
|
||||||
|
CloneWithContextFn withContext;
|
||||||
|
YGCloneNodeFunc noContext;
|
||||||
|
} cloneNodeCallback_;
|
||||||
|
union {
|
||||||
|
LogWithContextFn withContext;
|
||||||
|
YGLogger noContext;
|
||||||
|
} logger_;
|
||||||
|
bool cloneNodeUsesContext_;
|
||||||
|
bool loggerUsesContext_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool useWebDefaults = false;
|
||||||
|
bool useLegacyStretchBehaviour = false;
|
||||||
|
bool shouldDiffLayoutWithoutLegacyStretchBehaviour = false;
|
||||||
|
bool printTree = false;
|
||||||
|
float pointScaleFactor = 1.0f;
|
||||||
|
std::array<bool, facebook::yoga::enums::count<YGExperimentalFeature>()>
|
||||||
|
experimentalFeatures = {};
|
||||||
|
void* context = nullptr;
|
||||||
|
|
||||||
|
YGConfig(YGLogger logger);
|
||||||
|
void log(YGConfig*, YGNode*, YGLogLevel, void*, const char*, va_list);
|
||||||
|
void setLogger(YGLogger logger) {
|
||||||
|
logger_.noContext = logger;
|
||||||
|
loggerUsesContext_ = false;
|
||||||
|
}
|
||||||
|
void setLogger(LogWithContextFn logger) {
|
||||||
|
logger_.withContext = logger;
|
||||||
|
loggerUsesContext_ = true;
|
||||||
|
}
|
||||||
|
void setLogger(std::nullptr_t) { setLogger(YGLogger{nullptr}); }
|
||||||
|
|
||||||
|
YGNodeRef cloneNode(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGNodeRef owner,
|
||||||
|
int childIndex,
|
||||||
|
void* cloneContext);
|
||||||
|
void setCloneNodeCallback(YGCloneNodeFunc cloneNode) {
|
||||||
|
cloneNodeCallback_.noContext = cloneNode;
|
||||||
|
cloneNodeUsesContext_ = false;
|
||||||
|
}
|
||||||
|
void setCloneNodeCallback(CloneWithContextFn cloneNode) {
|
||||||
|
cloneNodeCallback_.withContext = cloneNode;
|
||||||
|
cloneNodeUsesContext_ = true;
|
||||||
|
}
|
||||||
|
void setCloneNodeCallback(std::nullptr_t) {
|
||||||
|
setCloneNodeCallback(YGCloneNodeFunc{nullptr});
|
||||||
|
}
|
||||||
|
};
|
226
doric-Qt/doric/yoga/YGEnums.cpp
Normal file
226
doric-Qt/doric/yoga/YGEnums.cpp
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YGEnums.h"
|
||||||
|
|
||||||
|
const char* YGAlignToString(const YGAlign value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGAlignAuto:
|
||||||
|
return "auto";
|
||||||
|
case YGAlignFlexStart:
|
||||||
|
return "flex-start";
|
||||||
|
case YGAlignCenter:
|
||||||
|
return "center";
|
||||||
|
case YGAlignFlexEnd:
|
||||||
|
return "flex-end";
|
||||||
|
case YGAlignStretch:
|
||||||
|
return "stretch";
|
||||||
|
case YGAlignBaseline:
|
||||||
|
return "baseline";
|
||||||
|
case YGAlignSpaceBetween:
|
||||||
|
return "space-between";
|
||||||
|
case YGAlignSpaceAround:
|
||||||
|
return "space-around";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGDimensionToString(const YGDimension value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGDimensionWidth:
|
||||||
|
return "width";
|
||||||
|
case YGDimensionHeight:
|
||||||
|
return "height";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGDirectionToString(const YGDirection value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGDirectionInherit:
|
||||||
|
return "inherit";
|
||||||
|
case YGDirectionLTR:
|
||||||
|
return "ltr";
|
||||||
|
case YGDirectionRTL:
|
||||||
|
return "rtl";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGDisplayToString(const YGDisplay value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGDisplayFlex:
|
||||||
|
return "flex";
|
||||||
|
case YGDisplayNone:
|
||||||
|
return "none";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGEdgeToString(const YGEdge value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGEdgeLeft:
|
||||||
|
return "left";
|
||||||
|
case YGEdgeTop:
|
||||||
|
return "top";
|
||||||
|
case YGEdgeRight:
|
||||||
|
return "right";
|
||||||
|
case YGEdgeBottom:
|
||||||
|
return "bottom";
|
||||||
|
case YGEdgeStart:
|
||||||
|
return "start";
|
||||||
|
case YGEdgeEnd:
|
||||||
|
return "end";
|
||||||
|
case YGEdgeHorizontal:
|
||||||
|
return "horizontal";
|
||||||
|
case YGEdgeVertical:
|
||||||
|
return "vertical";
|
||||||
|
case YGEdgeAll:
|
||||||
|
return "all";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGExperimentalFeatureToString(const YGExperimentalFeature value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGExperimentalFeatureWebFlexBasis:
|
||||||
|
return "web-flex-basis";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGFlexDirectionToString(const YGFlexDirection value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGFlexDirectionColumn:
|
||||||
|
return "column";
|
||||||
|
case YGFlexDirectionColumnReverse:
|
||||||
|
return "column-reverse";
|
||||||
|
case YGFlexDirectionRow:
|
||||||
|
return "row";
|
||||||
|
case YGFlexDirectionRowReverse:
|
||||||
|
return "row-reverse";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGJustifyToString(const YGJustify value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGJustifyFlexStart:
|
||||||
|
return "flex-start";
|
||||||
|
case YGJustifyCenter:
|
||||||
|
return "center";
|
||||||
|
case YGJustifyFlexEnd:
|
||||||
|
return "flex-end";
|
||||||
|
case YGJustifySpaceBetween:
|
||||||
|
return "space-between";
|
||||||
|
case YGJustifySpaceAround:
|
||||||
|
return "space-around";
|
||||||
|
case YGJustifySpaceEvenly:
|
||||||
|
return "space-evenly";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGLogLevelToString(const YGLogLevel value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGLogLevelError:
|
||||||
|
return "error";
|
||||||
|
case YGLogLevelWarn:
|
||||||
|
return "warn";
|
||||||
|
case YGLogLevelInfo:
|
||||||
|
return "info";
|
||||||
|
case YGLogLevelDebug:
|
||||||
|
return "debug";
|
||||||
|
case YGLogLevelVerbose:
|
||||||
|
return "verbose";
|
||||||
|
case YGLogLevelFatal:
|
||||||
|
return "fatal";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGMeasureModeToString(const YGMeasureMode value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGMeasureModeUndefined:
|
||||||
|
return "undefined";
|
||||||
|
case YGMeasureModeExactly:
|
||||||
|
return "exactly";
|
||||||
|
case YGMeasureModeAtMost:
|
||||||
|
return "at-most";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGNodeTypeToString(const YGNodeType value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGNodeTypeDefault:
|
||||||
|
return "default";
|
||||||
|
case YGNodeTypeText:
|
||||||
|
return "text";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGOverflowToString(const YGOverflow value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGOverflowVisible:
|
||||||
|
return "visible";
|
||||||
|
case YGOverflowHidden:
|
||||||
|
return "hidden";
|
||||||
|
case YGOverflowScroll:
|
||||||
|
return "scroll";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGPositionTypeToString(const YGPositionType value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGPositionTypeRelative:
|
||||||
|
return "relative";
|
||||||
|
case YGPositionTypeAbsolute:
|
||||||
|
return "absolute";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGPrintOptionsToString(const YGPrintOptions value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGPrintOptionsLayout:
|
||||||
|
return "layout";
|
||||||
|
case YGPrintOptionsStyle:
|
||||||
|
return "style";
|
||||||
|
case YGPrintOptionsChildren:
|
||||||
|
return "children";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGUnitToString(const YGUnit value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGUnitUndefined:
|
||||||
|
return "undefined";
|
||||||
|
case YGUnitPoint:
|
||||||
|
return "point";
|
||||||
|
case YGUnitPercent:
|
||||||
|
return "percent";
|
||||||
|
case YGUnitAuto:
|
||||||
|
return "auto";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* YGWrapToString(const YGWrap value) {
|
||||||
|
switch (value) {
|
||||||
|
case YGWrapNoWrap:
|
||||||
|
return "no-wrap";
|
||||||
|
case YGWrapWrap:
|
||||||
|
return "wrap";
|
||||||
|
case YGWrapWrapReverse:
|
||||||
|
return "wrap-reverse";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
151
doric-Qt/doric/yoga/YGEnums.h
Normal file
151
doric-Qt/doric/yoga/YGEnums.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* 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 "YGMacros.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
namespace enums {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr int count(); // can't use `= delete` due to a defect in clang < 3.9
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <int... xs>
|
||||||
|
constexpr int n() {
|
||||||
|
return sizeof...(xs);
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
} // namespace enums
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define YG_ENUM_DECL(NAME, ...) \
|
||||||
|
typedef YG_ENUM_BEGIN(NAME){__VA_ARGS__} YG_ENUM_END(NAME); \
|
||||||
|
WIN_EXPORT const char* NAME##ToString(NAME);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define YG_ENUM_SEQ_DECL(NAME, ...) \
|
||||||
|
YG_ENUM_DECL(NAME, __VA_ARGS__) \
|
||||||
|
YG_EXTERN_C_END \
|
||||||
|
namespace facebook { \
|
||||||
|
namespace yoga { \
|
||||||
|
namespace enums { \
|
||||||
|
template <> \
|
||||||
|
constexpr int count<NAME>() { \
|
||||||
|
return detail::n<__VA_ARGS__>(); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
YG_EXTERN_C_BEGIN
|
||||||
|
#else
|
||||||
|
#define YG_ENUM_SEQ_DECL YG_ENUM_DECL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
YG_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGAlign,
|
||||||
|
YGAlignAuto,
|
||||||
|
YGAlignFlexStart,
|
||||||
|
YGAlignCenter,
|
||||||
|
YGAlignFlexEnd,
|
||||||
|
YGAlignStretch,
|
||||||
|
YGAlignBaseline,
|
||||||
|
YGAlignSpaceBetween,
|
||||||
|
YGAlignSpaceAround);
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(YGDimension, YGDimensionWidth, YGDimensionHeight)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGDirection,
|
||||||
|
YGDirectionInherit,
|
||||||
|
YGDirectionLTR,
|
||||||
|
YGDirectionRTL)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(YGDisplay, YGDisplayFlex, YGDisplayNone)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGEdge,
|
||||||
|
YGEdgeLeft,
|
||||||
|
YGEdgeTop,
|
||||||
|
YGEdgeRight,
|
||||||
|
YGEdgeBottom,
|
||||||
|
YGEdgeStart,
|
||||||
|
YGEdgeEnd,
|
||||||
|
YGEdgeHorizontal,
|
||||||
|
YGEdgeVertical,
|
||||||
|
YGEdgeAll)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGFlexDirection,
|
||||||
|
YGFlexDirectionColumn,
|
||||||
|
YGFlexDirectionColumnReverse,
|
||||||
|
YGFlexDirectionRow,
|
||||||
|
YGFlexDirectionRowReverse)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGJustify,
|
||||||
|
YGJustifyFlexStart,
|
||||||
|
YGJustifyCenter,
|
||||||
|
YGJustifyFlexEnd,
|
||||||
|
YGJustifySpaceBetween,
|
||||||
|
YGJustifySpaceAround,
|
||||||
|
YGJustifySpaceEvenly)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGLogLevel,
|
||||||
|
YGLogLevelError,
|
||||||
|
YGLogLevelWarn,
|
||||||
|
YGLogLevelInfo,
|
||||||
|
YGLogLevelDebug,
|
||||||
|
YGLogLevelVerbose,
|
||||||
|
YGLogLevelFatal)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGMeasureMode,
|
||||||
|
YGMeasureModeUndefined,
|
||||||
|
YGMeasureModeExactly,
|
||||||
|
YGMeasureModeAtMost)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(YGNodeType, YGNodeTypeDefault, YGNodeTypeText)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGOverflow,
|
||||||
|
YGOverflowVisible,
|
||||||
|
YGOverflowHidden,
|
||||||
|
YGOverflowScroll)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute)
|
||||||
|
|
||||||
|
YG_ENUM_DECL(
|
||||||
|
YGPrintOptions,
|
||||||
|
YGPrintOptionsLayout = 1,
|
||||||
|
YGPrintOptionsStyle = 2,
|
||||||
|
YGPrintOptionsChildren = 4)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(
|
||||||
|
YGUnit,
|
||||||
|
YGUnitUndefined,
|
||||||
|
YGUnitPoint,
|
||||||
|
YGUnitPercent,
|
||||||
|
YGUnitAuto)
|
||||||
|
|
||||||
|
YG_ENUM_SEQ_DECL(YGWrap, YGWrapNoWrap, YGWrapWrap, YGWrapWrapReverse)
|
||||||
|
|
||||||
|
YG_EXTERN_C_END
|
||||||
|
|
||||||
|
#undef YG_ENUM_DECL
|
||||||
|
#undef YG_ENUM_SEQ_DECL
|
70
doric-Qt/doric/yoga/YGFloatOptional.h
Normal file
70
doric-Qt/doric/yoga/YGFloatOptional.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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 <cmath>
|
||||||
|
#include <limits>
|
||||||
|
#include "Yoga-internal.h"
|
||||||
|
|
||||||
|
struct YGFloatOptional {
|
||||||
|
private:
|
||||||
|
float value_ = std::numeric_limits<float>::quiet_NaN();
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit constexpr YGFloatOptional(float value) : value_(value) {}
|
||||||
|
constexpr YGFloatOptional() = default;
|
||||||
|
|
||||||
|
// returns the wrapped value, or a value x with YGIsUndefined(x) == true
|
||||||
|
constexpr float unwrap() const { return value_; }
|
||||||
|
|
||||||
|
bool isUndefined() const { return std::isnan(value_); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// operators take YGFloatOptional by value, as it is a 32bit value
|
||||||
|
|
||||||
|
inline bool operator==(YGFloatOptional lhs, YGFloatOptional rhs) {
|
||||||
|
return lhs.unwrap() == rhs.unwrap() ||
|
||||||
|
(lhs.isUndefined() && rhs.isUndefined());
|
||||||
|
}
|
||||||
|
inline bool operator!=(YGFloatOptional lhs, YGFloatOptional rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(YGFloatOptional lhs, float rhs) {
|
||||||
|
return lhs == YGFloatOptional{rhs};
|
||||||
|
}
|
||||||
|
inline bool operator!=(YGFloatOptional lhs, float rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(float lhs, YGFloatOptional rhs) {
|
||||||
|
return rhs == lhs;
|
||||||
|
}
|
||||||
|
inline bool operator!=(float lhs, YGFloatOptional rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGFloatOptional operator+(YGFloatOptional lhs, YGFloatOptional rhs) {
|
||||||
|
return YGFloatOptional{lhs.unwrap() + rhs.unwrap()};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>(YGFloatOptional lhs, YGFloatOptional rhs) {
|
||||||
|
return lhs.unwrap() > rhs.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(YGFloatOptional lhs, YGFloatOptional rhs) {
|
||||||
|
return lhs.unwrap() < rhs.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>=(YGFloatOptional lhs, YGFloatOptional rhs) {
|
||||||
|
return lhs > rhs || lhs == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<=(YGFloatOptional lhs, YGFloatOptional rhs) {
|
||||||
|
return lhs < rhs || lhs == rhs;
|
||||||
|
}
|
42
doric-Qt/doric/yoga/YGLayout.cpp
Normal file
42
doric-Qt/doric/yoga/YGLayout.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YGLayout.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
using namespace facebook;
|
||||||
|
|
||||||
|
bool YGLayout::operator==(YGLayout layout) const {
|
||||||
|
bool isEqual = YGFloatArrayEqual(position, layout.position) &&
|
||||||
|
YGFloatArrayEqual(dimensions, layout.dimensions) &&
|
||||||
|
YGFloatArrayEqual(margin, layout.margin) &&
|
||||||
|
YGFloatArrayEqual(border, layout.border) &&
|
||||||
|
YGFloatArrayEqual(padding, layout.padding) &&
|
||||||
|
direction() == layout.direction() &&
|
||||||
|
hadOverflow() == layout.hadOverflow() &&
|
||||||
|
lastOwnerDirection == layout.lastOwnerDirection &&
|
||||||
|
nextCachedMeasurementsIndex == layout.nextCachedMeasurementsIndex &&
|
||||||
|
cachedLayout == layout.cachedLayout &&
|
||||||
|
computedFlexBasis == layout.computedFlexBasis;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < YG_MAX_CACHED_RESULT_COUNT && isEqual; ++i) {
|
||||||
|
isEqual = isEqual && cachedMeasurements[i] == layout.cachedMeasurements[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!yoga::isUndefined(measuredDimensions[0]) ||
|
||||||
|
!yoga::isUndefined(layout.measuredDimensions[0])) {
|
||||||
|
isEqual =
|
||||||
|
isEqual && (measuredDimensions[0] == layout.measuredDimensions[0]);
|
||||||
|
}
|
||||||
|
if (!yoga::isUndefined(measuredDimensions[1]) ||
|
||||||
|
!yoga::isUndefined(layout.measuredDimensions[1])) {
|
||||||
|
isEqual =
|
||||||
|
isEqual && (measuredDimensions[1] == layout.measuredDimensions[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isEqual;
|
||||||
|
}
|
69
doric-Qt/doric/yoga/YGLayout.h
Normal file
69
doric-Qt/doric/yoga/YGLayout.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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 "Bitfield.h"
|
||||||
|
#include "YGFloatOptional.h"
|
||||||
|
#include "Yoga-internal.h"
|
||||||
|
|
||||||
|
struct YGLayout {
|
||||||
|
std::array<float, 4> position = {};
|
||||||
|
std::array<float, 2> dimensions = {{YGUndefined, YGUndefined}};
|
||||||
|
std::array<float, 4> margin = {};
|
||||||
|
std::array<float, 4> border = {};
|
||||||
|
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};
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint32_t computedFlexBasisGeneration = 0;
|
||||||
|
YGFloatOptional computedFlexBasis = {};
|
||||||
|
|
||||||
|
// Instead of recomputing the entire layout every single time, we cache some
|
||||||
|
// information to break early when nothing changed
|
||||||
|
uint32_t generationCount = 0;
|
||||||
|
YGDirection lastOwnerDirection = (YGDirection) -1;
|
||||||
|
|
||||||
|
uint32_t nextCachedMeasurementsIndex = 0;
|
||||||
|
std::array<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT>
|
||||||
|
cachedMeasurements = {};
|
||||||
|
std::array<float, 2> measuredDimensions = {{YGUndefined, YGUndefined}};
|
||||||
|
|
||||||
|
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
|
||||||
|
|
||||||
|
YGDirection direction() const { return flags_.at<directionIdx>(); }
|
||||||
|
decltype(flags_)::Ref<directionIdx> direction() {
|
||||||
|
return flags_.at<directionIdx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool didUseLegacyFlag() const { return flags_.at<didUseLegacyFlagIdx>(); }
|
||||||
|
decltype(flags_)::Ref<didUseLegacyFlagIdx> didUseLegacyFlag() {
|
||||||
|
return flags_.at<didUseLegacyFlagIdx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool doesLegacyStretchFlagAffectsLayout() const {
|
||||||
|
return flags_.at<doesLegacyStretchFlagAffectsLayoutIdx>();
|
||||||
|
}
|
||||||
|
decltype(flags_)::Ref<doesLegacyStretchFlagAffectsLayoutIdx>
|
||||||
|
doesLegacyStretchFlagAffectsLayout() {
|
||||||
|
return flags_.at<doesLegacyStretchFlagAffectsLayoutIdx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hadOverflow() const { return flags_.at<hadOverflowIdx>(); }
|
||||||
|
decltype(flags_)::Ref<hadOverflowIdx> hadOverflow() {
|
||||||
|
return flags_.at<hadOverflowIdx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(YGLayout layout) const;
|
||||||
|
bool operator!=(YGLayout layout) const { return !(*this == layout); }
|
||||||
|
};
|
53
doric-Qt/doric/yoga/YGMacros.h
Normal file
53
doric-Qt/doric/yoga/YGMacros.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define YG_EXTERN_C_BEGIN extern "C" {
|
||||||
|
#define YG_EXTERN_C_END }
|
||||||
|
#else
|
||||||
|
#define YG_EXTERN_C_BEGIN
|
||||||
|
#define YG_EXTERN_C_END
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WINDLL
|
||||||
|
#define WIN_EXPORT __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define WIN_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef YOGA_EXPORT
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define YOGA_EXPORT
|
||||||
|
#else
|
||||||
|
#define YOGA_EXPORT __attribute__((visibility("default")))
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NS_ENUM
|
||||||
|
// Cannot use NSInteger as NSInteger has a different size than int (which is the
|
||||||
|
// default type of a enum). Therefor when linking the Yoga C library into obj-c
|
||||||
|
// the header is a missmatch for the Yoga ABI.
|
||||||
|
#define YG_ENUM_BEGIN(name) NS_ENUM(int, name)
|
||||||
|
#define YG_ENUM_END(name)
|
||||||
|
#else
|
||||||
|
#define YG_ENUM_BEGIN(name) enum name
|
||||||
|
#define YG_ENUM_END(name) name
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define YG_DEPRECATED __attribute__((deprecated))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define YG_DEPRECATED __declspec(deprecated)
|
||||||
|
#elif __cplusplus >= 201402L
|
||||||
|
#if defined(__has_cpp_attribute)
|
||||||
|
#if __has_cpp_attribute(deprecated)
|
||||||
|
#define YG_DEPRECATED [[deprecated]]
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
585
doric-Qt/doric/yoga/YGNode.cpp
Normal file
585
doric-Qt/doric/yoga/YGNode.cpp
Normal file
@ -0,0 +1,585 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YGNode.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include "CompactValue.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
using namespace facebook;
|
||||||
|
using facebook::yoga::detail::CompactValue;
|
||||||
|
|
||||||
|
YGNode::YGNode(YGNode&& node) {
|
||||||
|
context_ = node.context_;
|
||||||
|
flags_ = node.flags_;
|
||||||
|
measure_ = node.measure_;
|
||||||
|
baseline_ = node.baseline_;
|
||||||
|
print_ = node.print_;
|
||||||
|
dirtied_ = node.dirtied_;
|
||||||
|
style_ = node.style_;
|
||||||
|
layout_ = node.layout_;
|
||||||
|
lineIndex_ = node.lineIndex_;
|
||||||
|
owner_ = node.owner_;
|
||||||
|
children_ = std::move(node.children_);
|
||||||
|
config_ = node.config_;
|
||||||
|
resolvedDimensions_ = node.resolvedDimensions_;
|
||||||
|
for (auto c : children_) {
|
||||||
|
c->setOwner(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YGNode::YGNode(const YGNode& node, YGConfigRef config) : YGNode{node} {
|
||||||
|
config_ = config;
|
||||||
|
if (config->useWebDefaults) {
|
||||||
|
useWebDefaults();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::print(void* printContext) {
|
||||||
|
if (print_.noContext != nullptr) {
|
||||||
|
if (flags_.at<printUsesContext_>()) {
|
||||||
|
print_.withContext(this, printContext);
|
||||||
|
} else {
|
||||||
|
print_.noContext(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YGFloatOptional YGNode::getLeadingPosition(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float axisSize) const {
|
||||||
|
if (YGFlexDirectionIsRow(axis)) {
|
||||||
|
auto leadingPosition = YGComputedEdgeValue(
|
||||||
|
style_.position(), YGEdgeStart, CompactValue::ofUndefined());
|
||||||
|
if (!leadingPosition.isUndefined()) {
|
||||||
|
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()) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
YGFloatOptional YGNode::getMarginForAxis(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const {
|
||||||
|
return getLeadingMargin(axis, widthSize) + getTrailingMargin(axis, widthSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
YGSize YGNode::measure(
|
||||||
|
float width,
|
||||||
|
YGMeasureMode widthMode,
|
||||||
|
float height,
|
||||||
|
YGMeasureMode heightMode,
|
||||||
|
void* layoutContext) {
|
||||||
|
|
||||||
|
return flags_.at<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_>()
|
||||||
|
? baseline_.withContext(this, width, height, layoutContext)
|
||||||
|
: baseline_.noContext(this, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
|
||||||
|
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;
|
||||||
|
} else {
|
||||||
|
YGAssertWithNode(
|
||||||
|
this,
|
||||||
|
children_.size() == 0,
|
||||||
|
"Cannot set measure function: Nodes with measure functions cannot have "
|
||||||
|
"children.");
|
||||||
|
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
|
||||||
|
// places in Litho
|
||||||
|
setNodeType(YGNodeTypeText);
|
||||||
|
}
|
||||||
|
|
||||||
|
measure_ = measureFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) {
|
||||||
|
flags_.at<measureUsesContext_>() = false;
|
||||||
|
decltype(YGNode::measure_) m;
|
||||||
|
m.noContext = measureFunc;
|
||||||
|
setMeasureFunc(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
YOGA_EXPORT void YGNode::setMeasureFunc(MeasureWithContextFn measureFunc) {
|
||||||
|
flags_.at<measureUsesContext_>() = true;
|
||||||
|
decltype(YGNode::measure_) m;
|
||||||
|
m.withContext = measureFunc;
|
||||||
|
setMeasureFunc(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::replaceChild(YGNodeRef child, uint32_t index) {
|
||||||
|
children_[index] = child;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::replaceChild(YGNodeRef oldChild, YGNodeRef newChild) {
|
||||||
|
std::replace(children_.begin(), children_.end(), oldChild, newChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::insertChild(YGNodeRef child, uint32_t index) {
|
||||||
|
children_.insert(children_.begin() + index, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setDirty(bool isDirty) {
|
||||||
|
if (isDirty == flags_.at<isDirty_>()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flags_.at<isDirty_>() = isDirty;
|
||||||
|
if (isDirty && dirtied_) {
|
||||||
|
dirtied_(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGNode::removeChild(YGNodeRef child) {
|
||||||
|
std::vector<YGNodeRef>::iterator p =
|
||||||
|
std::find(children_.begin(), children_.end(), child);
|
||||||
|
if (p != children_.end()) {
|
||||||
|
children_.erase(p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::removeChild(uint32_t index) {
|
||||||
|
children_.erase(children_.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutDirection(YGDirection direction) {
|
||||||
|
layout_.direction() = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutMargin(float margin, int index) {
|
||||||
|
layout_.margin[index] = margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutBorder(float border, int index) {
|
||||||
|
layout_.border[index] = border;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutPadding(float padding, int index) {
|
||||||
|
layout_.padding[index] = padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutLastOwnerDirection(YGDirection direction) {
|
||||||
|
layout_.lastOwnerDirection = direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutComputedFlexBasis(
|
||||||
|
const YGFloatOptional computedFlexBasis) {
|
||||||
|
layout_.computedFlexBasis = computedFlexBasis;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutPosition(float position, int index) {
|
||||||
|
layout_.position[index] = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutComputedFlexBasisGeneration(
|
||||||
|
uint32_t computedFlexBasisGeneration) {
|
||||||
|
layout_.computedFlexBasisGeneration = computedFlexBasisGeneration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) {
|
||||||
|
layout_.measuredDimensions[index] = measuredDimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutHadOverflow(bool hadOverflow) {
|
||||||
|
layout_.hadOverflow() = hadOverflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutDimension(float dimension, int index) {
|
||||||
|
layout_.dimensions[index] = dimension;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If both left and right are defined, then use left. Otherwise return +left or
|
||||||
|
// -right depending on which is defined.
|
||||||
|
YGFloatOptional YGNode::relativePosition(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float axisSize) const {
|
||||||
|
if (isLeadingPositionDefined(axis)) {
|
||||||
|
return getLeadingPosition(axis, axisSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
YGFloatOptional trailingPosition = getTrailingPosition(axis, axisSize);
|
||||||
|
if (!trailingPosition.isUndefined()) {
|
||||||
|
trailingPosition = YGFloatOptional{-1 * trailingPosition.unwrap()};
|
||||||
|
}
|
||||||
|
return trailingPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setPosition(
|
||||||
|
const YGDirection direction,
|
||||||
|
const float mainSize,
|
||||||
|
const float crossSize,
|
||||||
|
const float ownerWidth) {
|
||||||
|
/* Root nodes should be always layouted as LTR, so we don't return negative
|
||||||
|
* values. */
|
||||||
|
const YGDirection directionRespectingRoot =
|
||||||
|
owner_ != nullptr ? direction : YGDirectionLTR;
|
||||||
|
const YGFlexDirection mainAxis =
|
||||||
|
YGResolveFlexDirection(style_.flexDirection(), directionRespectingRoot);
|
||||||
|
const YGFlexDirection crossAxis =
|
||||||
|
YGFlexDirectionCross(mainAxis, directionRespectingRoot);
|
||||||
|
|
||||||
|
const YGFloatOptional relativePositionMain =
|
||||||
|
relativePosition(mainAxis, mainSize);
|
||||||
|
const YGFloatOptional relativePositionCross =
|
||||||
|
relativePosition(crossAxis, crossSize);
|
||||||
|
|
||||||
|
setLayoutPosition(
|
||||||
|
(getLeadingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
||||||
|
leading[mainAxis]);
|
||||||
|
setLayoutPosition(
|
||||||
|
(getTrailingMargin(mainAxis, ownerWidth) + relativePositionMain).unwrap(),
|
||||||
|
trailing[mainAxis]);
|
||||||
|
setLayoutPosition(
|
||||||
|
(getLeadingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
||||||
|
.unwrap(),
|
||||||
|
leading[crossAxis]);
|
||||||
|
setLayoutPosition(
|
||||||
|
(getTrailingMargin(crossAxis, ownerWidth) + relativePositionCross)
|
||||||
|
.unwrap(),
|
||||||
|
trailing[crossAxis]);
|
||||||
|
}
|
||||||
|
|
||||||
|
YGValue YGNode::marginLeadingValue(const YGFlexDirection axis) const {
|
||||||
|
if (YGFlexDirectionIsRow(axis) &&
|
||||||
|
!style_.margin()[YGEdgeStart].isUndefined()) {
|
||||||
|
return style_.margin()[YGEdgeStart];
|
||||||
|
} else {
|
||||||
|
return style_.margin()[leading[axis]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YGValue YGNode::marginTrailingValue(const YGFlexDirection axis) const {
|
||||||
|
if (YGFlexDirectionIsRow(axis) && !style_.margin()[YGEdgeEnd].isUndefined()) {
|
||||||
|
return style_.margin()[YGEdgeEnd];
|
||||||
|
} else {
|
||||||
|
return style_.margin()[trailing[axis]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YGValue YGNode::resolveFlexBasisPtr() const {
|
||||||
|
YGValue flexBasis = style_.flexBasis();
|
||||||
|
if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) {
|
||||||
|
return flexBasis;
|
||||||
|
}
|
||||||
|
if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) {
|
||||||
|
return flags_.at<useWebDefaults_>() ? YGValueAuto : YGValueZero;
|
||||||
|
}
|
||||||
|
return YGValueAuto;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::resolveDimension() {
|
||||||
|
using namespace yoga;
|
||||||
|
const YGStyle& style = getStyle();
|
||||||
|
for (auto dim : {YGDimensionWidth, YGDimensionHeight}) {
|
||||||
|
if (!style.maxDimensions()[dim].isUndefined() &&
|
||||||
|
YGValueEqual(style.maxDimensions()[dim], style.minDimensions()[dim])) {
|
||||||
|
resolvedDimensions_[dim] = style.maxDimensions()[dim];
|
||||||
|
} else {
|
||||||
|
resolvedDimensions_[dim] = style.dimensions()[dim];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YGDirection YGNode::resolveDirection(const YGDirection ownerDirection) {
|
||||||
|
if (style_.direction() == YGDirectionInherit) {
|
||||||
|
return ownerDirection > YGDirectionInherit ? ownerDirection
|
||||||
|
: YGDirectionLTR;
|
||||||
|
} else {
|
||||||
|
return style_.direction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YOGA_EXPORT void YGNode::clearChildren() {
|
||||||
|
children_.clear();
|
||||||
|
children_.shrink_to_fit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other Methods
|
||||||
|
|
||||||
|
void YGNode::cloneChildrenIfNeeded(void* cloneContext) {
|
||||||
|
iterChildrenAfterCloningIfNeeded([](YGNodeRef, void*) {}, cloneContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::markDirtyAndPropogate() {
|
||||||
|
if (!flags_.at<isDirty_>()) {
|
||||||
|
setDirty(true);
|
||||||
|
setLayoutComputedFlexBasis(YGFloatOptional());
|
||||||
|
if (owner_) {
|
||||||
|
owner_->markDirtyAndPropogate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::markDirtyAndPropogateDownwards() {
|
||||||
|
flags_.at<isDirty_>() = true;
|
||||||
|
for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) {
|
||||||
|
childNode->markDirtyAndPropogateDownwards();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
float YGNode::resolveFlexGrow() const {
|
||||||
|
// Root nodes flexGrow should always be 0
|
||||||
|
if (owner_ == nullptr) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (!style_.flexGrow().isUndefined()) {
|
||||||
|
return style_.flexGrow().unwrap();
|
||||||
|
}
|
||||||
|
if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) {
|
||||||
|
return style_.flex().unwrap();
|
||||||
|
}
|
||||||
|
return kDefaultFlexGrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
float YGNode::resolveFlexShrink() const {
|
||||||
|
if (owner_ == nullptr) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (!style_.flexShrink().isUndefined()) {
|
||||||
|
return style_.flexShrink().unwrap();
|
||||||
|
}
|
||||||
|
if (!flags_.at<useWebDefaults_>() && !style_.flex().isUndefined() &&
|
||||||
|
style_.flex().unwrap() < 0.0f) {
|
||||||
|
return -style_.flex().unwrap();
|
||||||
|
}
|
||||||
|
return flags_.at<useWebDefaults_>() ? kWebDefaultFlexShrink
|
||||||
|
: kDefaultFlexShrink;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGNode::isNodeFlexible() {
|
||||||
|
return (
|
||||||
|
(style_.positionType() == YGPositionTypeRelative) &&
|
||||||
|
(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(
|
||||||
|
style_.border(), leading[axis], CompactValue::ofZero());
|
||||||
|
return YGFloatMax(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
YGFloatOptional YGNode::getLeadingPaddingAndBorder(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const {
|
||||||
|
return getLeadingPadding(axis, widthSize) +
|
||||||
|
YGFloatOptional(getLeadingBorder(axis));
|
||||||
|
}
|
||||||
|
|
||||||
|
YGFloatOptional YGNode::getTrailingPaddingAndBorder(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const {
|
||||||
|
return getTrailingPadding(axis, widthSize) +
|
||||||
|
YGFloatOptional(getTrailingBorder(axis));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGNode::didUseLegacyFlag() {
|
||||||
|
bool didUseLegacyFlag = layout_.didUseLegacyFlag();
|
||||||
|
if (didUseLegacyFlag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (const auto& child : children_) {
|
||||||
|
if (child->layout_.didUseLegacyFlag()) {
|
||||||
|
didUseLegacyFlag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return didUseLegacyFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutDoesLegacyFlagAffectsLayout(
|
||||||
|
bool doesLegacyFlagAffectsLayout) {
|
||||||
|
layout_.doesLegacyStretchFlagAffectsLayout() = doesLegacyFlagAffectsLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) {
|
||||||
|
layout_.didUseLegacyFlag() = didUseLegacyFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const {
|
||||||
|
if (children_.size() != node.children_.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (layout_ != node.layout_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (children_.size() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLayoutTreeEqual = true;
|
||||||
|
YGNodeRef otherNodeChildren = nullptr;
|
||||||
|
for (std::vector<YGNodeRef>::size_type i = 0; i < children_.size(); ++i) {
|
||||||
|
otherNodeChildren = node.children_[i];
|
||||||
|
isLayoutTreeEqual =
|
||||||
|
children_[i]->isLayoutTreeEqualToNode(*otherNodeChildren);
|
||||||
|
if (!isLayoutTreeEqual) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isLayoutTreeEqual;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNode::reset() {
|
||||||
|
YGAssertWithNode(
|
||||||
|
this,
|
||||||
|
children_.size() == 0,
|
||||||
|
"Cannot reset a node which still has children attached");
|
||||||
|
YGAssertWithNode(
|
||||||
|
this, owner_ == nullptr, "Cannot reset a node still attached to a owner");
|
||||||
|
|
||||||
|
clearChildren();
|
||||||
|
|
||||||
|
auto webDefaults = flags_.at<useWebDefaults_>();
|
||||||
|
*this = YGNode{getConfig()};
|
||||||
|
if (webDefaults) {
|
||||||
|
useWebDefaults();
|
||||||
|
}
|
||||||
|
}
|
323
doric-Qt/doric/yoga/YGNode.h
Normal file
323
doric-Qt/doric/yoga/YGNode.h
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
* 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 <cstdint>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "Bitfield.h"
|
||||||
|
#include "CompactValue.h"
|
||||||
|
#include "YGConfig.h"
|
||||||
|
#include "YGLayout.h"
|
||||||
|
#include "YGStyle.h"
|
||||||
|
#include "YGMacros.h"
|
||||||
|
#include "Yoga-internal.h"
|
||||||
|
|
||||||
|
YGConfigRef YGConfigGetDefault();
|
||||||
|
|
||||||
|
struct YOGA_EXPORT YGNode {
|
||||||
|
using MeasureWithContextFn =
|
||||||
|
YGSize (*)(YGNode*, float, YGMeasureMode, float, YGMeasureMode, void*);
|
||||||
|
using BaselineWithContextFn = float (*)(YGNode*, float, float, void*);
|
||||||
|
using PrintWithContextFn = void (*)(YGNode*, void*);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr size_t hasNewLayout_ = 0;
|
||||||
|
static constexpr size_t isReferenceBaseline_ = 1;
|
||||||
|
static constexpr size_t isDirty_ = 2;
|
||||||
|
static constexpr size_t nodeType_ = 3;
|
||||||
|
static constexpr size_t measureUsesContext_ = 4;
|
||||||
|
static constexpr size_t baselineUsesContext_ = 5;
|
||||||
|
static constexpr size_t printUsesContext_ = 6;
|
||||||
|
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 reserved_ = 0;
|
||||||
|
union {
|
||||||
|
YGMeasureFunc noContext;
|
||||||
|
MeasureWithContextFn withContext;
|
||||||
|
} measure_ = {nullptr};
|
||||||
|
union {
|
||||||
|
YGBaselineFunc noContext;
|
||||||
|
BaselineWithContextFn withContext;
|
||||||
|
} baseline_ = {nullptr};
|
||||||
|
union {
|
||||||
|
YGPrintFunc noContext;
|
||||||
|
PrintWithContextFn withContext;
|
||||||
|
} print_ = {nullptr};
|
||||||
|
YGDirtiedFunc dirtied_ = nullptr;
|
||||||
|
YGStyle style_ = {};
|
||||||
|
YGLayout layout_ = {};
|
||||||
|
uint32_t lineIndex_ = 0;
|
||||||
|
YGNodeRef owner_ = nullptr;
|
||||||
|
YGVector children_ = {};
|
||||||
|
YGConfigRef config_;
|
||||||
|
std::array<YGValue, 2> resolvedDimensions_ = {
|
||||||
|
{YGValueUndefined, YGValueUndefined}};
|
||||||
|
|
||||||
|
YGFloatOptional relativePosition(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float axisSize) const;
|
||||||
|
|
||||||
|
void setMeasureFunc(decltype(measure_));
|
||||||
|
void setBaselineFunc(decltype(baseline_));
|
||||||
|
|
||||||
|
void useWebDefaults() {
|
||||||
|
flags_.at<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
|
||||||
|
// 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!
|
||||||
|
YGNode& operator=(YGNode&&) = default;
|
||||||
|
|
||||||
|
using CompactValue = facebook::yoga::detail::CompactValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
YGNode() : YGNode{YGConfigGetDefault()} {}
|
||||||
|
explicit YGNode(const YGConfigRef config) : config_{config} {
|
||||||
|
if (config->useWebDefaults) {
|
||||||
|
useWebDefaults();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
~YGNode() = default; // cleanup of owner/children relationships in YGNodeFree
|
||||||
|
|
||||||
|
YGNode(YGNode&&);
|
||||||
|
|
||||||
|
// Does not expose true value semantics, as children are not cloned eagerly.
|
||||||
|
// Should we remove this?
|
||||||
|
YGNode(const YGNode& node) = default;
|
||||||
|
|
||||||
|
// for RB fabric
|
||||||
|
YGNode(const YGNode& node, YGConfigRef config);
|
||||||
|
|
||||||
|
// assignment means potential leaks of existing children, or alternatively
|
||||||
|
// freeing unowned memory, double free, or freeing stack memory.
|
||||||
|
YGNode& operator=(const YGNode&) = delete;
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
void* getContext() const { return context_; }
|
||||||
|
|
||||||
|
uint8_t& reserved() { return reserved_; }
|
||||||
|
uint8_t reserved() const { return reserved_; }
|
||||||
|
|
||||||
|
void print(void*);
|
||||||
|
|
||||||
|
bool getHasNewLayout() const { return flags_.at<hasNewLayout_>(); }
|
||||||
|
|
||||||
|
YGNodeType getNodeType() const { return flags_.at<nodeType_>(); }
|
||||||
|
|
||||||
|
bool hasMeasureFunc() const noexcept { return measure_.noContext != nullptr; }
|
||||||
|
|
||||||
|
YGSize measure(float, YGMeasureMode, float, YGMeasureMode, void*);
|
||||||
|
|
||||||
|
bool hasBaselineFunc() const noexcept {
|
||||||
|
return baseline_.noContext != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
float baseline(float width, float height, void* layoutContext);
|
||||||
|
|
||||||
|
YGDirtiedFunc getDirtied() const { return dirtied_; }
|
||||||
|
|
||||||
|
// For Performance reasons passing as reference.
|
||||||
|
YGStyle& getStyle() { return style_; }
|
||||||
|
|
||||||
|
const YGStyle& getStyle() const { return style_; }
|
||||||
|
|
||||||
|
// For Performance reasons passing as reference.
|
||||||
|
YGLayout& getLayout() { return layout_; }
|
||||||
|
|
||||||
|
const YGLayout& getLayout() const { return layout_; }
|
||||||
|
|
||||||
|
uint32_t getLineIndex() const { return lineIndex_; }
|
||||||
|
|
||||||
|
bool isReferenceBaseline() { return flags_.at<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
|
||||||
|
// of the YGNode when a YGNode only belongs to one YogaTree or nullptr when
|
||||||
|
// the YGNode is shared between two or more YogaTrees.
|
||||||
|
YGNodeRef getOwner() const { return owner_; }
|
||||||
|
|
||||||
|
// Deprecated, use getOwner() instead.
|
||||||
|
YGNodeRef getParent() const { return getOwner(); }
|
||||||
|
|
||||||
|
const YGVector& getChildren() const { return children_; }
|
||||||
|
|
||||||
|
// Applies a callback to all children, after cloning them if they are not
|
||||||
|
// owned.
|
||||||
|
template <typename T>
|
||||||
|
void iterChildrenAfterCloningIfNeeded(T callback, void* cloneContext) {
|
||||||
|
int i = 0;
|
||||||
|
for (YGNodeRef& child : children_) {
|
||||||
|
if (child->getOwner() != this) {
|
||||||
|
child = config_->cloneNode(child, this, i, cloneContext);
|
||||||
|
child->setOwner(this);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
|
||||||
|
callback(child, cloneContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
YGNodeRef getChild(uint32_t index) const { return children_.at(index); }
|
||||||
|
|
||||||
|
YGConfigRef getConfig() const { return config_; }
|
||||||
|
|
||||||
|
bool isDirty() const { return flags_.at<isDirty_>(); }
|
||||||
|
|
||||||
|
std::array<YGValue, 2> getResolvedDimensions() const {
|
||||||
|
return resolvedDimensions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
YGValue getResolvedDimension(int index) const {
|
||||||
|
return resolvedDimensions_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods related to positions, margin, padding and border
|
||||||
|
YGFloatOptional getLeadingPosition(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float axisSize) const;
|
||||||
|
bool isLeadingPositionDefined(const YGFlexDirection axis) const;
|
||||||
|
bool isTrailingPosDefined(const YGFlexDirection axis) const;
|
||||||
|
YGFloatOptional getTrailingPosition(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float axisSize) const;
|
||||||
|
YGFloatOptional getLeadingMargin(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const;
|
||||||
|
YGFloatOptional getTrailingMargin(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const;
|
||||||
|
float getLeadingBorder(const YGFlexDirection flexDirection) const;
|
||||||
|
float getTrailingBorder(const YGFlexDirection flexDirection) const;
|
||||||
|
YGFloatOptional getLeadingPadding(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const;
|
||||||
|
YGFloatOptional getTrailingPadding(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const;
|
||||||
|
YGFloatOptional getLeadingPaddingAndBorder(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const;
|
||||||
|
YGFloatOptional getTrailingPaddingAndBorder(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const;
|
||||||
|
YGFloatOptional getMarginForAxis(
|
||||||
|
const YGFlexDirection axis,
|
||||||
|
const float widthSize) const;
|
||||||
|
// Setters
|
||||||
|
|
||||||
|
void setContext(void* context) { context_ = context; }
|
||||||
|
|
||||||
|
void setPrintFunc(YGPrintFunc printFunc) {
|
||||||
|
print_.noContext = printFunc;
|
||||||
|
flags_.at<printUsesContext_>() = false;
|
||||||
|
}
|
||||||
|
void setPrintFunc(PrintWithContextFn printFunc) {
|
||||||
|
print_.withContext = printFunc;
|
||||||
|
flags_.at<printUsesContext_>() = true;
|
||||||
|
}
|
||||||
|
void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); }
|
||||||
|
|
||||||
|
void setHasNewLayout(bool hasNewLayout) {
|
||||||
|
flags_.at<hasNewLayout_>() = hasNewLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNodeType(YGNodeType nodeType) { flags_.at<nodeType_>() = nodeType; }
|
||||||
|
|
||||||
|
void setMeasureFunc(YGMeasureFunc measureFunc);
|
||||||
|
void setMeasureFunc(MeasureWithContextFn);
|
||||||
|
void setMeasureFunc(std::nullptr_t) {
|
||||||
|
return setMeasureFunc(YGMeasureFunc{nullptr});
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBaselineFunc(YGBaselineFunc baseLineFunc) {
|
||||||
|
flags_.at<baselineUsesContext_>() = false;
|
||||||
|
baseline_.noContext = baseLineFunc;
|
||||||
|
}
|
||||||
|
void setBaselineFunc(BaselineWithContextFn baseLineFunc) {
|
||||||
|
flags_.at<baselineUsesContext_>() = true;
|
||||||
|
baseline_.withContext = baseLineFunc;
|
||||||
|
}
|
||||||
|
void setBaselineFunc(std::nullptr_t) {
|
||||||
|
return setBaselineFunc(YGBaselineFunc{nullptr});
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDirtiedFunc(YGDirtiedFunc dirtiedFunc) { dirtied_ = dirtiedFunc; }
|
||||||
|
|
||||||
|
void setStyle(const YGStyle& style) { style_ = style; }
|
||||||
|
|
||||||
|
void setLayout(const YGLayout& layout) { layout_ = layout; }
|
||||||
|
|
||||||
|
void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; }
|
||||||
|
|
||||||
|
void setIsReferenceBaseline(bool isReferenceBaseline) {
|
||||||
|
flags_.at<isReferenceBaseline_>() = isReferenceBaseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOwner(YGNodeRef owner) { owner_ = owner; }
|
||||||
|
|
||||||
|
void setChildren(const YGVector& children) { children_ = children; }
|
||||||
|
|
||||||
|
// TODO: rvalue override for setChildren
|
||||||
|
|
||||||
|
YG_DEPRECATED void setConfig(YGConfigRef config) { config_ = config; }
|
||||||
|
|
||||||
|
void setDirty(bool isDirty);
|
||||||
|
void setLayoutLastOwnerDirection(YGDirection direction);
|
||||||
|
void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis);
|
||||||
|
void setLayoutComputedFlexBasisGeneration(
|
||||||
|
uint32_t computedFlexBasisGeneration);
|
||||||
|
void setLayoutMeasuredDimension(float measuredDimension, int index);
|
||||||
|
void setLayoutHadOverflow(bool hadOverflow);
|
||||||
|
void setLayoutDimension(float dimension, int index);
|
||||||
|
void setLayoutDirection(YGDirection direction);
|
||||||
|
void setLayoutMargin(float margin, int index);
|
||||||
|
void setLayoutBorder(float border, int index);
|
||||||
|
void setLayoutPadding(float padding, int index);
|
||||||
|
void setLayoutPosition(float position, int index);
|
||||||
|
void setPosition(
|
||||||
|
const YGDirection direction,
|
||||||
|
const float mainSize,
|
||||||
|
const float crossSize,
|
||||||
|
const float ownerWidth);
|
||||||
|
void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout);
|
||||||
|
void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag);
|
||||||
|
void markDirtyAndPropogateDownwards();
|
||||||
|
|
||||||
|
// Other methods
|
||||||
|
YGValue marginLeadingValue(const YGFlexDirection axis) const;
|
||||||
|
YGValue marginTrailingValue(const YGFlexDirection axis) const;
|
||||||
|
YGValue resolveFlexBasisPtr() const;
|
||||||
|
void resolveDimension();
|
||||||
|
YGDirection resolveDirection(const YGDirection ownerDirection);
|
||||||
|
void clearChildren();
|
||||||
|
/// Replaces the occurrences of oldChild with newChild
|
||||||
|
void replaceChild(YGNodeRef oldChild, YGNodeRef newChild);
|
||||||
|
void replaceChild(YGNodeRef child, uint32_t index);
|
||||||
|
void insertChild(YGNodeRef child, uint32_t index);
|
||||||
|
/// Removes the first occurrence of child
|
||||||
|
bool removeChild(YGNodeRef child);
|
||||||
|
void removeChild(uint32_t index);
|
||||||
|
|
||||||
|
void cloneChildrenIfNeeded(void*);
|
||||||
|
void markDirtyAndPropogate();
|
||||||
|
float resolveFlexGrow() const;
|
||||||
|
float resolveFlexShrink() const;
|
||||||
|
bool isNodeFlexible();
|
||||||
|
bool didUseLegacyFlag();
|
||||||
|
bool isLayoutTreeEqualToNode(const YGNode& node) const;
|
||||||
|
void reset();
|
||||||
|
};
|
225
doric-Qt/doric/yoga/YGNodePrint.cpp
Normal file
225
doric-Qt/doric/yoga/YGNodePrint.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#include "YGNodePrint.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "YGEnums.h"
|
||||||
|
#include "YGNode.h"
|
||||||
|
#include "Yoga-internal.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
typedef std::string string;
|
||||||
|
|
||||||
|
static void indent(string& base, uint32_t level) {
|
||||||
|
for (uint32_t i = 0; i < level; ++i) {
|
||||||
|
base.append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool areFourValuesEqual(const YGStyle::Edges& four) {
|
||||||
|
return YGValueEqual(four[0], four[1]) && YGValueEqual(four[0], four[2]) &&
|
||||||
|
YGValueEqual(four[0], four[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendFormatedString(string& str, const char* fmt, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
va_list argsCopy;
|
||||||
|
va_copy(argsCopy, args);
|
||||||
|
std::vector<char> buf(1 + vsnprintf(NULL, 0, fmt, args));
|
||||||
|
va_end(args);
|
||||||
|
vsnprintf(buf.data(), buf.size(), fmt, argsCopy);
|
||||||
|
va_end(argsCopy);
|
||||||
|
string result = string(buf.begin(), buf.end() - 1);
|
||||||
|
str.append(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendFloatOptionalIfDefined(
|
||||||
|
string& base,
|
||||||
|
const string key,
|
||||||
|
const YGFloatOptional num) {
|
||||||
|
if (!num.isUndefined()) {
|
||||||
|
appendFormatedString(base, "%s: %g; ", key.c_str(), num.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendNumberIfNotUndefined(
|
||||||
|
string& base,
|
||||||
|
const string key,
|
||||||
|
const YGValue number) {
|
||||||
|
if (number.unit != YGUnitUndefined) {
|
||||||
|
if (number.unit == YGUnitAuto) {
|
||||||
|
base.append(key + ": auto; ");
|
||||||
|
} else {
|
||||||
|
string unit = number.unit == YGUnitPoint ? "px" : "%%";
|
||||||
|
appendFormatedString(
|
||||||
|
base, "%s: %g%s; ", key.c_str(), number.value, unit.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendNumberIfNotAuto(
|
||||||
|
string& base,
|
||||||
|
const string& key,
|
||||||
|
const YGValue number) {
|
||||||
|
if (number.unit != YGUnitAuto) {
|
||||||
|
appendNumberIfNotUndefined(base, key, number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendNumberIfNotZero(
|
||||||
|
string& base,
|
||||||
|
const string& str,
|
||||||
|
const YGValue number) {
|
||||||
|
if (number.unit == YGUnitAuto) {
|
||||||
|
base.append(str + ": auto; ");
|
||||||
|
} else if (!YGFloatsEqual(number.value, 0)) {
|
||||||
|
appendNumberIfNotUndefined(base, str, number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendEdges(
|
||||||
|
string& base,
|
||||||
|
const string& key,
|
||||||
|
const YGStyle::Edges& edges) {
|
||||||
|
if (areFourValuesEqual(edges)) {
|
||||||
|
appendNumberIfNotZero(base, key, edges[YGEdgeLeft]);
|
||||||
|
} else {
|
||||||
|
for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) {
|
||||||
|
string str = key + "-" + YGEdgeToString(static_cast<YGEdge>(edge));
|
||||||
|
appendNumberIfNotZero(base, str, edges[edge]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void appendEdgeIfNotUndefined(
|
||||||
|
string& base,
|
||||||
|
const string& str,
|
||||||
|
const YGStyle::Edges& edges,
|
||||||
|
const YGEdge edge) {
|
||||||
|
appendNumberIfNotUndefined(
|
||||||
|
base,
|
||||||
|
str,
|
||||||
|
YGComputedEdgeValue(edges, edge, detail::CompactValue::ofUndefined()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void YGNodeToString(
|
||||||
|
std::string& str,
|
||||||
|
YGNodeRef node,
|
||||||
|
YGPrintOptions options,
|
||||||
|
uint32_t level) {
|
||||||
|
indent(str, level);
|
||||||
|
appendFormatedString(str, "<div ");
|
||||||
|
|
||||||
|
if (options & YGPrintOptionsLayout) {
|
||||||
|
appendFormatedString(str, "layout=\"");
|
||||||
|
appendFormatedString(
|
||||||
|
str, "width: %g; ", node->getLayout().dimensions[YGDimensionWidth]);
|
||||||
|
appendFormatedString(
|
||||||
|
str, "height: %g; ", node->getLayout().dimensions[YGDimensionHeight]);
|
||||||
|
appendFormatedString(
|
||||||
|
str, "top: %g; ", node->getLayout().position[YGEdgeTop]);
|
||||||
|
appendFormatedString(
|
||||||
|
str, "left: %g;", node->getLayout().position[YGEdgeLeft]);
|
||||||
|
appendFormatedString(str, "\" ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options & YGPrintOptionsStyle) {
|
||||||
|
appendFormatedString(str, "style=\"");
|
||||||
|
const auto& style = node->getStyle();
|
||||||
|
if (style.flexDirection() != YGNode().getStyle().flexDirection()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str,
|
||||||
|
"flex-direction: %s; ",
|
||||||
|
YGFlexDirectionToString(style.flexDirection()));
|
||||||
|
}
|
||||||
|
if (style.justifyContent() != YGNode().getStyle().justifyContent()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str,
|
||||||
|
"justify-content: %s; ",
|
||||||
|
YGJustifyToString(style.justifyContent()));
|
||||||
|
}
|
||||||
|
if (style.alignItems() != YGNode().getStyle().alignItems()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str, "align-items: %s; ", YGAlignToString(style.alignItems()));
|
||||||
|
}
|
||||||
|
if (style.alignContent() != YGNode().getStyle().alignContent()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str, "align-content: %s; ", YGAlignToString(style.alignContent()));
|
||||||
|
}
|
||||||
|
if (style.alignSelf() != YGNode().getStyle().alignSelf()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str, "align-self: %s; ", YGAlignToString(style.alignSelf()));
|
||||||
|
}
|
||||||
|
appendFloatOptionalIfDefined(str, "flex-grow", style.flexGrow());
|
||||||
|
appendFloatOptionalIfDefined(str, "flex-shrink", style.flexShrink());
|
||||||
|
appendNumberIfNotAuto(str, "flex-basis", style.flexBasis());
|
||||||
|
appendFloatOptionalIfDefined(str, "flex", style.flex());
|
||||||
|
|
||||||
|
if (style.flexWrap() != YGNode().getStyle().flexWrap()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str, "flex-wrap: %s; ", YGWrapToString(style.flexWrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style.overflow() != YGNode().getStyle().overflow()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str, "overflow: %s; ", YGOverflowToString(style.overflow()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style.display() != YGNode().getStyle().display()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str, "display: %s; ", YGDisplayToString(style.display()));
|
||||||
|
}
|
||||||
|
appendEdges(str, "margin", style.margin());
|
||||||
|
appendEdges(str, "padding", style.padding());
|
||||||
|
appendEdges(str, "border", style.border());
|
||||||
|
|
||||||
|
appendNumberIfNotAuto(str, "width", style.dimensions()[YGDimensionWidth]);
|
||||||
|
appendNumberIfNotAuto(str, "height", style.dimensions()[YGDimensionHeight]);
|
||||||
|
appendNumberIfNotAuto(
|
||||||
|
str, "max-width", style.maxDimensions()[YGDimensionWidth]);
|
||||||
|
appendNumberIfNotAuto(
|
||||||
|
str, "max-height", style.maxDimensions()[YGDimensionHeight]);
|
||||||
|
appendNumberIfNotAuto(
|
||||||
|
str, "min-width", style.minDimensions()[YGDimensionWidth]);
|
||||||
|
appendNumberIfNotAuto(
|
||||||
|
str, "min-height", style.minDimensions()[YGDimensionHeight]);
|
||||||
|
|
||||||
|
if (style.positionType() != YGNode().getStyle().positionType()) {
|
||||||
|
appendFormatedString(
|
||||||
|
str, "position: %s; ", YGPositionTypeToString(style.positionType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
appendEdgeIfNotUndefined(str, "left", style.position(), YGEdgeLeft);
|
||||||
|
appendEdgeIfNotUndefined(str, "right", style.position(), YGEdgeRight);
|
||||||
|
appendEdgeIfNotUndefined(str, "top", style.position(), YGEdgeTop);
|
||||||
|
appendEdgeIfNotUndefined(str, "bottom", style.position(), YGEdgeBottom);
|
||||||
|
appendFormatedString(str, "\" ");
|
||||||
|
|
||||||
|
if (node->hasMeasureFunc()) {
|
||||||
|
appendFormatedString(str, "has-custom-measure=\"true\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendFormatedString(str, ">");
|
||||||
|
|
||||||
|
const uint32_t childCount = static_cast<uint32_t>(node->getChildren().size());
|
||||||
|
if (options & YGPrintOptionsChildren && childCount > 0) {
|
||||||
|
for (uint32_t i = 0; i < childCount; i++) {
|
||||||
|
appendFormatedString(str, "\n");
|
||||||
|
YGNodeToString(str, YGNodeGetChild(node, i), options, level + 1);
|
||||||
|
}
|
||||||
|
appendFormatedString(str, "\n");
|
||||||
|
indent(str, level);
|
||||||
|
}
|
||||||
|
appendFormatedString(str, "</div>");
|
||||||
|
}
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
||||||
|
#endif
|
25
doric-Qt/doric/yoga/YGNodePrint.h
Normal file
25
doric-Qt/doric/yoga/YGNodePrint.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Yoga.h"
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
|
||||||
|
void YGNodeToString(
|
||||||
|
std::string& str,
|
||||||
|
YGNodeRef node,
|
||||||
|
YGPrintOptions options,
|
||||||
|
uint32_t level);
|
||||||
|
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
||||||
|
#endif
|
56
doric-Qt/doric/yoga/YGStyle.cpp
Normal file
56
doric-Qt/doric/yoga/YGStyle.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YGStyle.h"
|
||||||
|
#include "Utils.h"
|
||||||
|
|
||||||
|
// Yoga specific properties, not compatible with flexbox specification
|
||||||
|
bool operator==(const YGStyle& lhs, const YGStyle& rhs) {
|
||||||
|
bool areNonFloatValuesEqual = lhs.direction() == rhs.direction() &&
|
||||||
|
lhs.flexDirection() == rhs.flexDirection() &&
|
||||||
|
lhs.justifyContent() == rhs.justifyContent() &&
|
||||||
|
lhs.alignContent() == rhs.alignContent() &&
|
||||||
|
lhs.alignItems() == rhs.alignItems() &&
|
||||||
|
lhs.alignSelf() == rhs.alignSelf() &&
|
||||||
|
lhs.positionType() == rhs.positionType() &&
|
||||||
|
lhs.flexWrap() == rhs.flexWrap() && lhs.overflow() == rhs.overflow() &&
|
||||||
|
lhs.display() == rhs.display() &&
|
||||||
|
YGValueEqual(lhs.flexBasis(), rhs.flexBasis()) &&
|
||||||
|
lhs.margin() == rhs.margin() && lhs.position() == rhs.position() &&
|
||||||
|
lhs.padding() == rhs.padding() && lhs.border() == rhs.border() &&
|
||||||
|
lhs.dimensions() == rhs.dimensions() &&
|
||||||
|
lhs.minDimensions() == rhs.minDimensions() &&
|
||||||
|
lhs.maxDimensions() == rhs.maxDimensions();
|
||||||
|
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
lhs.flex().isUndefined() == rhs.flex().isUndefined();
|
||||||
|
if (areNonFloatValuesEqual && !lhs.flex().isUndefined() &&
|
||||||
|
!rhs.flex().isUndefined()) {
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual && lhs.flex() == rhs.flex();
|
||||||
|
}
|
||||||
|
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
lhs.flexGrow().isUndefined() == rhs.flexGrow().isUndefined();
|
||||||
|
if (areNonFloatValuesEqual && !lhs.flexGrow().isUndefined()) {
|
||||||
|
areNonFloatValuesEqual =
|
||||||
|
areNonFloatValuesEqual && lhs.flexGrow() == rhs.flexGrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
areNonFloatValuesEqual = areNonFloatValuesEqual &&
|
||||||
|
lhs.flexShrink().isUndefined() == rhs.flexShrink().isUndefined();
|
||||||
|
if (areNonFloatValuesEqual && !rhs.flexShrink().isUndefined()) {
|
||||||
|
areNonFloatValuesEqual =
|
||||||
|
areNonFloatValuesEqual && lhs.flexShrink() == rhs.flexShrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(lhs.aspectRatio().isUndefined() && rhs.aspectRatio().isUndefined())) {
|
||||||
|
areNonFloatValuesEqual =
|
||||||
|
areNonFloatValuesEqual && lhs.aspectRatio() == rhs.aspectRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
return areNonFloatValuesEqual;
|
||||||
|
}
|
203
doric-Qt/doric/yoga/YGStyle.h
Normal file
203
doric-Qt/doric/yoga/YGStyle.h
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* 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 <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"
|
||||||
|
|
||||||
|
class YOGA_EXPORT YGStyle {
|
||||||
|
template <typename Enum>
|
||||||
|
using Values =
|
||||||
|
facebook::yoga::detail::Values<facebook::yoga::enums::count<Enum>()>;
|
||||||
|
using CompactValue = facebook::yoga::detail::CompactValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Dimensions = Values<YGDimension>;
|
||||||
|
using Edges = Values<YGEdge>;
|
||||||
|
|
||||||
|
template <typename T, T YGStyle::*Prop>
|
||||||
|
struct Ref {
|
||||||
|
YGStyle& style;
|
||||||
|
operator T() const { return style.*Prop; }
|
||||||
|
Ref<T, Prop>& operator=(T value) {
|
||||||
|
style.*Prop = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Idx, Values<Idx> YGStyle::*Prop>
|
||||||
|
struct IdxRef {
|
||||||
|
struct Ref {
|
||||||
|
YGStyle& style;
|
||||||
|
Idx idx;
|
||||||
|
operator CompactValue() const { return (style.*Prop)[idx]; }
|
||||||
|
operator YGValue() const { return (style.*Prop)[idx]; }
|
||||||
|
Ref& operator=(CompactValue value) {
|
||||||
|
(style.*Prop)[idx] = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
YGStyle& style;
|
||||||
|
IdxRef<Idx, Prop>& operator=(const Values<Idx>& values) {
|
||||||
|
style.*Prop = values;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
operator const Values<Idx>&() const { return style.*Prop; }
|
||||||
|
Ref operator[](Idx idx) { return {style, idx}; }
|
||||||
|
CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
YGStyle() = default;
|
||||||
|
~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>;
|
||||||
|
|
||||||
|
Flags flags_ = {YGDirectionInherit,
|
||||||
|
YGFlexDirectionColumn,
|
||||||
|
YGJustifyFlexStart,
|
||||||
|
YGAlignFlexStart,
|
||||||
|
YGAlignStretch,
|
||||||
|
YGAlignAuto,
|
||||||
|
YGPositionTypeRelative,
|
||||||
|
YGWrapNoWrap,
|
||||||
|
YGOverflowVisible,
|
||||||
|
YGDisplayFlex};
|
||||||
|
YGFloatOptional flex_ = {};
|
||||||
|
YGFloatOptional flexGrow_ = {};
|
||||||
|
YGFloatOptional flexShrink_ = {};
|
||||||
|
CompactValue flexBasis_ = CompactValue::ofAuto();
|
||||||
|
Edges margin_ = {};
|
||||||
|
Edges position_ = {};
|
||||||
|
Edges padding_ = {};
|
||||||
|
Edges border_ = {};
|
||||||
|
Dimensions dimensions_{CompactValue::ofAuto()};
|
||||||
|
Dimensions minDimensions_ = {};
|
||||||
|
Dimensions maxDimensions_ = {};
|
||||||
|
// Yoga specific properties, not compatible with flexbox specification
|
||||||
|
YGFloatOptional aspectRatio_ = {};
|
||||||
|
|
||||||
|
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>(); }
|
||||||
|
|
||||||
|
YGFlexDirection flexDirection() const {
|
||||||
|
return flags_.at<flexDirectionIdx>();
|
||||||
|
}
|
||||||
|
Flags::Ref<flexDirectionIdx> flexDirection() {
|
||||||
|
return flags_.at<flexDirectionIdx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
YGJustify justifyContent() const { return flags_.at<justifyContentIdx>(); }
|
||||||
|
Flags::Ref<justifyContentIdx> justifyContent() {
|
||||||
|
return flags_.at<justifyContentIdx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
YGAlign alignContent() const { return flags_.at<alignContentIdx>(); }
|
||||||
|
Flags::Ref<alignContentIdx> alignContent() {
|
||||||
|
return flags_.at<alignContentIdx>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 flags_.at<flexWrapIdx>(); }
|
||||||
|
Flags::Ref<flexWrapIdx> flexWrap() { return flags_.at<flexWrapIdx>(); }
|
||||||
|
|
||||||
|
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>(); }
|
||||||
|
|
||||||
|
YGFloatOptional flex() const { return flex_; }
|
||||||
|
Ref<YGFloatOptional, &YGStyle::flex_> flex() { return {*this}; }
|
||||||
|
|
||||||
|
YGFloatOptional flexGrow() const { return flexGrow_; }
|
||||||
|
Ref<YGFloatOptional, &YGStyle::flexGrow_> flexGrow() { return {*this}; }
|
||||||
|
|
||||||
|
YGFloatOptional flexShrink() const { return flexShrink_; }
|
||||||
|
Ref<YGFloatOptional, &YGStyle::flexShrink_> flexShrink() { return {*this}; }
|
||||||
|
|
||||||
|
CompactValue flexBasis() const { return flexBasis_; }
|
||||||
|
Ref<CompactValue, &YGStyle::flexBasis_> flexBasis() { return {*this}; }
|
||||||
|
|
||||||
|
const Edges& margin() const { return margin_; }
|
||||||
|
IdxRef<YGEdge, &YGStyle::margin_> margin() { return {*this}; }
|
||||||
|
|
||||||
|
const Edges& position() const { return position_; }
|
||||||
|
IdxRef<YGEdge, &YGStyle::position_> position() { return {*this}; }
|
||||||
|
|
||||||
|
const Edges& padding() const { return padding_; }
|
||||||
|
IdxRef<YGEdge, &YGStyle::padding_> padding() { return {*this}; }
|
||||||
|
|
||||||
|
const Edges& border() const { return border_; }
|
||||||
|
IdxRef<YGEdge, &YGStyle::border_> border() { return {*this}; }
|
||||||
|
|
||||||
|
const Dimensions& dimensions() const { return dimensions_; }
|
||||||
|
IdxRef<YGDimension, &YGStyle::dimensions_> dimensions() { return {*this}; }
|
||||||
|
|
||||||
|
const Dimensions& minDimensions() const { return minDimensions_; }
|
||||||
|
IdxRef<YGDimension, &YGStyle::minDimensions_> minDimensions() {
|
||||||
|
return {*this};
|
||||||
|
}
|
||||||
|
|
||||||
|
const Dimensions& maxDimensions() const { return maxDimensions_; }
|
||||||
|
IdxRef<YGDimension, &YGStyle::maxDimensions_> maxDimensions() {
|
||||||
|
return {*this};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yoga specific properties, not compatible with flexbox specification
|
||||||
|
YGFloatOptional aspectRatio() const { return aspectRatio_; }
|
||||||
|
Ref<YGFloatOptional, &YGStyle::aspectRatio_> aspectRatio() { return {*this}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
YOGA_EXPORT bool operator==(const YGStyle& lhs, const YGStyle& rhs);
|
||||||
|
YOGA_EXPORT inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
12
doric-Qt/doric/yoga/YGValue.cpp
Normal file
12
doric-Qt/doric/yoga/YGValue.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "YGValue.h"
|
||||||
|
|
||||||
|
const YGValue YGValueZero = {0, YGUnitPoint};
|
||||||
|
const YGValue YGValueUndefined = {YGUndefined, YGUnitUndefined};
|
||||||
|
const YGValue YGValueAuto = {YGUndefined, YGUnitAuto};
|
84
doric-Qt/doric/yoga/YGValue.h
Normal file
84
doric-Qt/doric/yoga/YGValue.h
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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 <math.h>
|
||||||
|
#include "YGEnums.h"
|
||||||
|
#include "YGMacros.h"
|
||||||
|
|
||||||
|
YG_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
// Not defined in MSVC++
|
||||||
|
#ifndef NAN
|
||||||
|
static const uint32_t __nan = 0x7fc00000;
|
||||||
|
#define NAN (*(const float*) __nan)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define YGUndefined NAN
|
||||||
|
|
||||||
|
typedef struct YGValue {
|
||||||
|
float value;
|
||||||
|
YGUnit unit;
|
||||||
|
} YGValue;
|
||||||
|
|
||||||
|
YOGA_EXPORT extern const YGValue YGValueAuto;
|
||||||
|
YOGA_EXPORT extern const YGValue YGValueUndefined;
|
||||||
|
YOGA_EXPORT extern const YGValue YGValueZero;
|
||||||
|
|
||||||
|
YG_EXTERN_C_END
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
inline bool operator==(const YGValue& lhs, const YGValue& rhs) {
|
||||||
|
if (lhs.unit != rhs.unit) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (lhs.unit) {
|
||||||
|
case YGUnitUndefined:
|
||||||
|
case YGUnitAuto:
|
||||||
|
return true;
|
||||||
|
case YGUnitPoint:
|
||||||
|
case YGUnitPercent:
|
||||||
|
return lhs.value == rhs.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const YGValue& lhs, const YGValue& rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGValue operator-(const YGValue& value) {
|
||||||
|
return {-value.value, value.unit};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
namespace literals {
|
||||||
|
|
||||||
|
inline YGValue operator"" _pt(long double value) {
|
||||||
|
return YGValue{static_cast<float>(value), YGUnitPoint};
|
||||||
|
}
|
||||||
|
inline YGValue operator"" _pt(unsigned long long value) {
|
||||||
|
return operator"" _pt(static_cast<long double>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline YGValue operator"" _percent(long double value) {
|
||||||
|
return YGValue{static_cast<float>(value), YGUnitPercent};
|
||||||
|
}
|
||||||
|
inline YGValue operator"" _percent(unsigned long long value) {
|
||||||
|
return operator"" _percent(static_cast<long double>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace literals
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
||||||
|
|
||||||
|
#endif
|
151
doric-Qt/doric/yoga/Yoga-internal.h
Normal file
151
doric-Qt/doric/yoga/Yoga-internal.h
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* 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 <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
#include "CompactValue.h"
|
||||||
|
#include "Yoga.h"
|
||||||
|
|
||||||
|
using YGVector = std::vector<YGNodeRef>;
|
||||||
|
|
||||||
|
YG_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
void YGNodeCalculateLayoutWithContext(
|
||||||
|
YGNodeRef node,
|
||||||
|
float availableWidth,
|
||||||
|
float availableHeight,
|
||||||
|
YGDirection ownerDirection,
|
||||||
|
void* layoutContext);
|
||||||
|
|
||||||
|
YG_EXTERN_C_END
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
|
||||||
|
inline bool isUndefined(float value) {
|
||||||
|
return std::isnan(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
||||||
|
|
||||||
|
using namespace facebook;
|
||||||
|
|
||||||
|
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(0),
|
||||||
|
availableHeight(0),
|
||||||
|
widthMeasureMode((YGMeasureMode) -1),
|
||||||
|
heightMeasureMode((YGMeasureMode) -1),
|
||||||
|
computedWidth(-1),
|
||||||
|
computedHeight(-1) {}
|
||||||
|
|
||||||
|
bool operator==(YGCachedMeasurement 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
namespace yoga {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <size_t Size>
|
||||||
|
class Values {
|
||||||
|
private:
|
||||||
|
std::array<CompactValue, Size> values_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Values() = 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 detail
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
||||||
|
|
||||||
|
static const float kDefaultFlexGrow = 0.0f;
|
||||||
|
static const float kDefaultFlexShrink = 0.0f;
|
||||||
|
static const float kWebDefaultFlexShrink = 1.0f;
|
||||||
|
|
||||||
|
extern bool YGFloatsEqual(const float a, const float b);
|
||||||
|
extern facebook::yoga::detail::CompactValue YGComputedEdgeValue(
|
||||||
|
const facebook::yoga::detail::Values<
|
||||||
|
facebook::yoga::enums::count<YGEdge>()>& edges,
|
||||||
|
YGEdge edge,
|
||||||
|
facebook::yoga::detail::CompactValue defaultValue);
|
4405
doric-Qt/doric/yoga/Yoga.cpp
Normal file
4405
doric-Qt/doric/yoga/Yoga.cpp
Normal file
File diff suppressed because it is too large
Load Diff
369
doric-Qt/doric/yoga/Yoga.h
Normal file
369
doric-Qt/doric/yoga/Yoga.h
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
/*
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "YGEnums.h"
|
||||||
|
#include "YGMacros.h"
|
||||||
|
#include "YGValue.h"
|
||||||
|
|
||||||
|
YG_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
typedef struct YGSize {
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
} YGSize;
|
||||||
|
|
||||||
|
typedef struct YGConfig* YGConfigRef;
|
||||||
|
|
||||||
|
typedef struct YGNode* YGNodeRef;
|
||||||
|
typedef const struct YGNode* YGNodeConstRef;
|
||||||
|
|
||||||
|
typedef YGSize (*YGMeasureFunc)(
|
||||||
|
YGNodeRef node,
|
||||||
|
float width,
|
||||||
|
YGMeasureMode widthMode,
|
||||||
|
float height,
|
||||||
|
YGMeasureMode heightMode);
|
||||||
|
typedef float (*YGBaselineFunc)(YGNodeRef node, float width, float height);
|
||||||
|
typedef void (*YGDirtiedFunc)(YGNodeRef node);
|
||||||
|
typedef void (*YGPrintFunc)(YGNodeRef node);
|
||||||
|
typedef void (*YGNodeCleanupFunc)(YGNodeRef node);
|
||||||
|
typedef int (*YGLogger)(
|
||||||
|
YGConfigRef config,
|
||||||
|
YGNodeRef node,
|
||||||
|
YGLogLevel level,
|
||||||
|
const char* format,
|
||||||
|
va_list args);
|
||||||
|
typedef YGNodeRef (
|
||||||
|
*YGCloneNodeFunc)(YGNodeRef oldNode, YGNodeRef owner, int childIndex);
|
||||||
|
|
||||||
|
// YGNode
|
||||||
|
WIN_EXPORT YGNodeRef YGNodeNew(void);
|
||||||
|
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(YGConfigRef config);
|
||||||
|
WIN_EXPORT YGNodeRef YGNodeClone(YGNodeRef node);
|
||||||
|
WIN_EXPORT void YGNodeFree(YGNodeRef node);
|
||||||
|
WIN_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGNodeCleanupFunc cleanup);
|
||||||
|
WIN_EXPORT void YGNodeFreeRecursive(YGNodeRef node);
|
||||||
|
WIN_EXPORT void YGNodeReset(YGNodeRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeInsertChild(
|
||||||
|
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);
|
||||||
|
WIN_EXPORT YGNodeRef YGNodeGetOwner(YGNodeRef node);
|
||||||
|
WIN_EXPORT YGNodeRef YGNodeGetParent(YGNodeRef node);
|
||||||
|
WIN_EXPORT uint32_t YGNodeGetChildCount(YGNodeRef node);
|
||||||
|
WIN_EXPORT void YGNodeSetChildren(
|
||||||
|
YGNodeRef owner,
|
||||||
|
const YGNodeRef children[],
|
||||||
|
uint32_t count);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeSetIsReferenceBaseline(
|
||||||
|
YGNodeRef node,
|
||||||
|
bool isReferenceBaseline);
|
||||||
|
|
||||||
|
WIN_EXPORT bool YGNodeIsReferenceBaseline(YGNodeRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeCalculateLayout(
|
||||||
|
YGNodeRef node,
|
||||||
|
float availableWidth,
|
||||||
|
float availableHeight,
|
||||||
|
YGDirection ownerDirection);
|
||||||
|
|
||||||
|
// Mark a node as dirty. Only valid for nodes with a custom measure function
|
||||||
|
// set.
|
||||||
|
//
|
||||||
|
// Yoga knows when to mark all other nodes as dirty but because nodes with
|
||||||
|
// measure functions depend on information not known to Yoga they must perform
|
||||||
|
// this dirty marking manually.
|
||||||
|
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
|
||||||
|
// `YGCalculateLayout` will cause the recalculation of each and every node.
|
||||||
|
WIN_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(YGNodeRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodePrint(YGNodeRef node, YGPrintOptions options);
|
||||||
|
|
||||||
|
WIN_EXPORT bool YGFloatIsUndefined(float value);
|
||||||
|
|
||||||
|
WIN_EXPORT bool YGNodeCanUseCachedMeasurement(
|
||||||
|
YGMeasureMode widthMode,
|
||||||
|
float width,
|
||||||
|
YGMeasureMode heightMode,
|
||||||
|
float height,
|
||||||
|
YGMeasureMode lastWidthMode,
|
||||||
|
float lastWidth,
|
||||||
|
YGMeasureMode lastHeightMode,
|
||||||
|
float lastHeight,
|
||||||
|
float lastComputedWidth,
|
||||||
|
float lastComputedHeight,
|
||||||
|
float marginRow,
|
||||||
|
float marginColumn,
|
||||||
|
YGConfigRef config);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeRef srcNode);
|
||||||
|
|
||||||
|
WIN_EXPORT void* YGNodeGetContext(YGNodeRef node);
|
||||||
|
WIN_EXPORT void YGNodeSetContext(YGNodeRef node, void* context);
|
||||||
|
void YGConfigSetPrintTreeFlag(YGConfigRef config, bool enabled);
|
||||||
|
bool YGNodeHasMeasureFunc(YGNodeRef node);
|
||||||
|
WIN_EXPORT void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc);
|
||||||
|
bool YGNodeHasBaselineFunc(YGNodeRef node);
|
||||||
|
void YGNodeSetBaselineFunc(YGNodeRef node, YGBaselineFunc baselineFunc);
|
||||||
|
YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeRef node);
|
||||||
|
void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc);
|
||||||
|
void YGNodeSetPrintFunc(YGNodeRef node, YGPrintFunc printFunc);
|
||||||
|
WIN_EXPORT bool YGNodeGetHasNewLayout(YGNodeRef node);
|
||||||
|
WIN_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout);
|
||||||
|
YGNodeType YGNodeGetNodeType(YGNodeRef node);
|
||||||
|
void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType);
|
||||||
|
WIN_EXPORT bool YGNodeIsDirty(YGNodeRef node);
|
||||||
|
bool YGNodeLayoutGetDidUseLegacyFlag(YGNodeRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction);
|
||||||
|
WIN_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlexDirection(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGFlexDirection flexDirection);
|
||||||
|
WIN_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetJustifyContent(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGJustify justifyContent);
|
||||||
|
WIN_EXPORT YGJustify YGNodeStyleGetJustifyContent(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetAlignContent(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGAlign alignContent);
|
||||||
|
WIN_EXPORT YGAlign YGNodeStyleGetAlignContent(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetAlignItems(YGNodeRef node, YGAlign alignItems);
|
||||||
|
WIN_EXPORT YGAlign YGNodeStyleGetAlignItems(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetAlignSelf(YGNodeRef node, YGAlign alignSelf);
|
||||||
|
WIN_EXPORT YGAlign YGNodeStyleGetAlignSelf(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetPositionType(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGPositionType positionType);
|
||||||
|
WIN_EXPORT YGPositionType YGNodeStyleGetPositionType(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlexWrap(YGNodeRef node, YGWrap flexWrap);
|
||||||
|
WIN_EXPORT YGWrap YGNodeStyleGetFlexWrap(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetOverflow(YGNodeRef node, YGOverflow overflow);
|
||||||
|
WIN_EXPORT YGOverflow YGNodeStyleGetOverflow(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetDisplay(YGNodeRef node, YGDisplay display);
|
||||||
|
WIN_EXPORT YGDisplay YGNodeStyleGetDisplay(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlex(YGNodeRef node, float flex);
|
||||||
|
WIN_EXPORT float YGNodeStyleGetFlex(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlexGrow(YGNodeRef node, float flexGrow);
|
||||||
|
WIN_EXPORT float YGNodeStyleGetFlexGrow(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlexShrink(YGNodeRef node, float flexShrink);
|
||||||
|
WIN_EXPORT float YGNodeStyleGetFlexShrink(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlexBasis(YGNodeRef node, float flexBasis);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlexBasisPercent(YGNodeRef node, float flexBasis);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetPosition(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGEdge edge,
|
||||||
|
float position);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetPositionPercent(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGEdge edge,
|
||||||
|
float position);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float margin);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMarginPercent(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGEdge edge,
|
||||||
|
float margin);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetPadding(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGEdge edge,
|
||||||
|
float padding);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetPaddingPercent(
|
||||||
|
YGNodeRef node,
|
||||||
|
YGEdge edge,
|
||||||
|
float padding);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, float border);
|
||||||
|
WIN_EXPORT float YGNodeStyleGetBorder(YGNodeConstRef node, YGEdge edge);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, float width);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, float width);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, float height);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, float height);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMinWidth(YGNodeRef node, float minWidth);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMinWidthPercent(YGNodeRef node, float minWidth);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetMinWidth(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMinHeight(YGNodeRef node, float minHeight);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMinHeightPercent(YGNodeRef node, float minHeight);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetMinHeight(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMaxWidth(YGNodeRef node, float maxWidth);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMaxWidthPercent(YGNodeRef node, float maxWidth);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetMaxWidth(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMaxHeight(YGNodeRef node, float maxHeight);
|
||||||
|
WIN_EXPORT void YGNodeStyleSetMaxHeightPercent(YGNodeRef node, float maxHeight);
|
||||||
|
WIN_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node);
|
||||||
|
|
||||||
|
// Yoga specific properties, not compatible with flexbox specification Aspect
|
||||||
|
// ratio control the size of the undefined dimension of a node. Aspect ratio is
|
||||||
|
// encoded as a floating point value width/height. e.g. A value of 2 leads to a
|
||||||
|
// node with a width twice the size of its height while a value of 0.5 gives the
|
||||||
|
// opposite effect.
|
||||||
|
//
|
||||||
|
// - On a node with a set width/height aspect ratio control the size of the
|
||||||
|
// unset dimension
|
||||||
|
// - On a node with a set flex basis aspect ratio controls the size of the node
|
||||||
|
// in the cross axis if unset
|
||||||
|
// - On a node with a measure function aspect ratio works as though the measure
|
||||||
|
// function measures the flex basis
|
||||||
|
// - On a node with flex grow/shrink aspect ratio controls the size of the node
|
||||||
|
// in the cross axis if unset
|
||||||
|
// - Aspect ratio takes min/max dimensions into account
|
||||||
|
WIN_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, float aspectRatio);
|
||||||
|
WIN_EXPORT float YGNodeStyleGetAspectRatio(YGNodeConstRef node);
|
||||||
|
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetLeft(YGNodeRef node);
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetTop(YGNodeRef node);
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetRight(YGNodeRef node);
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetBottom(YGNodeRef node);
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetWidth(YGNodeRef node);
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetHeight(YGNodeRef node);
|
||||||
|
WIN_EXPORT YGDirection YGNodeLayoutGetDirection(YGNodeRef node);
|
||||||
|
WIN_EXPORT bool YGNodeLayoutGetHadOverflow(YGNodeRef node);
|
||||||
|
bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(YGNodeRef node);
|
||||||
|
|
||||||
|
// Get the computed values for these nodes after performing layout. If they were
|
||||||
|
// set using point values then the returned value will be the same as
|
||||||
|
// YGNodeStyleGetXXX. However if they were set using a percentage value then the
|
||||||
|
// returned value is the computed value used during layout.
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetMargin(YGNodeRef node, YGEdge edge);
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetBorder(YGNodeRef node, YGEdge edge);
|
||||||
|
WIN_EXPORT float YGNodeLayoutGetPadding(YGNodeRef node, YGEdge edge);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger);
|
||||||
|
WIN_EXPORT void YGAssert(bool condition, const char* message);
|
||||||
|
WIN_EXPORT void YGAssertWithNode(
|
||||||
|
YGNodeRef node,
|
||||||
|
bool condition,
|
||||||
|
const char* message);
|
||||||
|
WIN_EXPORT void YGAssertWithConfig(
|
||||||
|
YGConfigRef config,
|
||||||
|
bool condition,
|
||||||
|
const char* message);
|
||||||
|
// Set this to number of pixels in 1 point to round calculation results If you
|
||||||
|
// want to avoid rounding - set PointScaleFactor to 0
|
||||||
|
WIN_EXPORT void YGConfigSetPointScaleFactor(
|
||||||
|
YGConfigRef config,
|
||||||
|
float pixelsInPoint);
|
||||||
|
void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||||
|
YGConfigRef config,
|
||||||
|
bool shouldDiffLayout);
|
||||||
|
|
||||||
|
// Yoga previously had an error where containers would take the maximum space
|
||||||
|
// possible instead of the minimum like they are supposed to. In practice this
|
||||||
|
// resulted in implicit behaviour similar to align-self: stretch; Because this
|
||||||
|
// was such a long-standing bug we must allow legacy users to switch back to
|
||||||
|
// this behaviour.
|
||||||
|
WIN_EXPORT void YGConfigSetUseLegacyStretchBehaviour(
|
||||||
|
YGConfigRef config,
|
||||||
|
bool useLegacyStretchBehaviour);
|
||||||
|
|
||||||
|
// YGConfig
|
||||||
|
WIN_EXPORT YGConfigRef YGConfigNew(void);
|
||||||
|
WIN_EXPORT void YGConfigFree(YGConfigRef config);
|
||||||
|
WIN_EXPORT void YGConfigCopy(YGConfigRef dest, YGConfigRef src);
|
||||||
|
WIN_EXPORT int32_t YGConfigGetInstanceCount(void);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGConfigSetExperimentalFeatureEnabled(
|
||||||
|
YGConfigRef config,
|
||||||
|
YGExperimentalFeature feature,
|
||||||
|
bool enabled);
|
||||||
|
WIN_EXPORT bool YGConfigIsExperimentalFeatureEnabled(
|
||||||
|
YGConfigRef config,
|
||||||
|
YGExperimentalFeature feature);
|
||||||
|
|
||||||
|
// Using the web defaults is the preferred configuration for new projects. Usage
|
||||||
|
// of non web defaults should be considered as legacy.
|
||||||
|
WIN_EXPORT void YGConfigSetUseWebDefaults(YGConfigRef config, bool enabled);
|
||||||
|
WIN_EXPORT bool YGConfigGetUseWebDefaults(YGConfigRef config);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGConfigSetCloneNodeFunc(
|
||||||
|
YGConfigRef config,
|
||||||
|
YGCloneNodeFunc callback);
|
||||||
|
|
||||||
|
// Export only for C#
|
||||||
|
WIN_EXPORT YGConfigRef YGConfigGetDefault(void);
|
||||||
|
|
||||||
|
WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context);
|
||||||
|
WIN_EXPORT void* YGConfigGetContext(YGConfigRef config);
|
||||||
|
|
||||||
|
WIN_EXPORT float YGRoundValueToPixelGrid(
|
||||||
|
float value,
|
||||||
|
float pointScaleFactor,
|
||||||
|
bool forceCeil,
|
||||||
|
bool forceFloor);
|
||||||
|
|
||||||
|
YG_EXTERN_C_END
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Calls f on each node in the tree including the given node argument.
|
||||||
|
void YGTraversePreOrder(
|
||||||
|
YGNodeRef node,
|
||||||
|
std::function<void(YGNodeRef node)>&& f);
|
||||||
|
|
||||||
|
void YGNodeSetChildren(YGNodeRef owner, const std::vector<YGNodeRef>& children);
|
||||||
|
|
||||||
|
#endif
|
87
doric-Qt/doric/yoga/event/event.cpp
Normal file
87
doric-Qt/doric/yoga/event/event.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "event.h"
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
|
||||||
|
const char* LayoutPassReasonToString(const LayoutPassReason value) {
|
||||||
|
switch (value) {
|
||||||
|
case LayoutPassReason::kInitial:
|
||||||
|
return "initial";
|
||||||
|
case LayoutPassReason::kAbsLayout:
|
||||||
|
return "abs_layout";
|
||||||
|
case LayoutPassReason::kStretch:
|
||||||
|
return "stretch";
|
||||||
|
case LayoutPassReason::kMultilineStretch:
|
||||||
|
return "multiline_stretch";
|
||||||
|
case LayoutPassReason::kFlexLayout:
|
||||||
|
return "flex_layout";
|
||||||
|
case LayoutPassReason::kMeasureChild:
|
||||||
|
return "measure";
|
||||||
|
case LayoutPassReason::kAbsMeasureChild:
|
||||||
|
return "abs_measure";
|
||||||
|
case LayoutPassReason::kFlexMeasure:
|
||||||
|
return "flex_measure";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
std::function<Event::Subscriber> subscriber = nullptr;
|
||||||
|
Node* next = nullptr;
|
||||||
|
|
||||||
|
Node(std::function<Event::Subscriber>&& subscriber)
|
||||||
|
: subscriber{std::move(subscriber)} {}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::atomic<Node*> subscribers{nullptr};
|
||||||
|
|
||||||
|
Node* push(Node* newHead) {
|
||||||
|
Node* oldHead;
|
||||||
|
do {
|
||||||
|
oldHead = subscribers.load(std::memory_order_relaxed);
|
||||||
|
if (newHead != nullptr) {
|
||||||
|
newHead->next = oldHead;
|
||||||
|
}
|
||||||
|
} while (!subscribers.compare_exchange_weak(
|
||||||
|
oldHead, newHead, std::memory_order_release, std::memory_order_relaxed));
|
||||||
|
return oldHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void Event::reset() {
|
||||||
|
auto head = push(nullptr);
|
||||||
|
while (head != nullptr) {
|
||||||
|
auto current = head;
|
||||||
|
head = head->next;
|
||||||
|
delete current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::subscribe(std::function<Subscriber>&& subscriber) {
|
||||||
|
push(new Node{std::move(subscriber)});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::publish(const YGNode& node, Type eventType, const Data& eventData) {
|
||||||
|
for (auto subscriber = subscribers.load(std::memory_order_relaxed);
|
||||||
|
subscriber != nullptr;
|
||||||
|
subscriber = subscriber->next) {
|
||||||
|
subscriber->subscriber(node, eventType, eventData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
145
doric-Qt/doric/yoga/event/event.h
Normal file
145
doric-Qt/doric/yoga/event/event.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* 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 <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
#include <yoga/YGEnums.h>
|
||||||
|
|
||||||
|
struct YGConfig;
|
||||||
|
struct YGNode;
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
|
||||||
|
enum struct LayoutType : int {
|
||||||
|
kLayout = 0,
|
||||||
|
kMeasure = 1,
|
||||||
|
kCachedLayout = 2,
|
||||||
|
kCachedMeasure = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum struct LayoutPassReason : int {
|
||||||
|
kInitial = 0,
|
||||||
|
kAbsLayout = 1,
|
||||||
|
kStretch = 2,
|
||||||
|
kMultilineStretch = 3,
|
||||||
|
kFlexLayout = 4,
|
||||||
|
kMeasureChild = 5,
|
||||||
|
kAbsMeasureChild = 6,
|
||||||
|
kFlexMeasure = 7,
|
||||||
|
COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LayoutData {
|
||||||
|
int layouts;
|
||||||
|
int measures;
|
||||||
|
int maxMeasureCache;
|
||||||
|
int cachedLayouts;
|
||||||
|
int cachedMeasures;
|
||||||
|
int measureCallbacks;
|
||||||
|
std::array<int, static_cast<uint8_t>(LayoutPassReason::COUNT)>
|
||||||
|
measureCallbackReasonsCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* LayoutPassReasonToString(const LayoutPassReason value);
|
||||||
|
|
||||||
|
struct YOGA_EXPORT Event {
|
||||||
|
enum Type {
|
||||||
|
NodeAllocation,
|
||||||
|
NodeDeallocation,
|
||||||
|
NodeLayout,
|
||||||
|
LayoutPassStart,
|
||||||
|
LayoutPassEnd,
|
||||||
|
MeasureCallbackStart,
|
||||||
|
MeasureCallbackEnd,
|
||||||
|
NodeBaselineStart,
|
||||||
|
NodeBaselineEnd,
|
||||||
|
};
|
||||||
|
class Data;
|
||||||
|
using Subscriber = void(const YGNode&, Type, Data);
|
||||||
|
using Subscribers = std::vector<std::function<Subscriber>>;
|
||||||
|
|
||||||
|
template <Type E>
|
||||||
|
struct TypedData {};
|
||||||
|
|
||||||
|
class Data {
|
||||||
|
const void* data_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <Type E>
|
||||||
|
Data(const TypedData<E>& data) : data_{&data} {}
|
||||||
|
|
||||||
|
template <Type E>
|
||||||
|
const TypedData<E>& get() const {
|
||||||
|
return *static_cast<const TypedData<E>*>(data_);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static void reset();
|
||||||
|
|
||||||
|
static void subscribe(std::function<Subscriber>&& subscriber);
|
||||||
|
|
||||||
|
template <Type E>
|
||||||
|
static void publish(const YGNode& node, const TypedData<E>& eventData = {}) {
|
||||||
|
#ifdef YG_ENABLE_EVENTS
|
||||||
|
publish(node, E, Data{eventData});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Type E>
|
||||||
|
static void publish(const YGNode* node, const TypedData<E>& eventData = {}) {
|
||||||
|
publish<E>(*node, eventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void publish(const YGNode&, Type, const Data&);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Event::TypedData<Event::NodeAllocation> {
|
||||||
|
YGConfig* config;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Event::TypedData<Event::NodeDeallocation> {
|
||||||
|
YGConfig* config;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Event::TypedData<Event::LayoutPassStart> {
|
||||||
|
void* layoutContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Event::TypedData<Event::LayoutPassEnd> {
|
||||||
|
void* layoutContext;
|
||||||
|
LayoutData* layoutData;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Event::TypedData<Event::MeasureCallbackEnd> {
|
||||||
|
void* layoutContext;
|
||||||
|
float width;
|
||||||
|
YGMeasureMode widthMeasureMode;
|
||||||
|
float height;
|
||||||
|
YGMeasureMode heightMeasureMode;
|
||||||
|
float measuredWidth;
|
||||||
|
float measuredHeight;
|
||||||
|
const LayoutPassReason reason;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Event::TypedData<Event::NodeLayout> {
|
||||||
|
LayoutType layoutType;
|
||||||
|
void* layoutContext;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
32
doric-Qt/doric/yoga/internal/experiments-inl.h
Normal file
32
doric-Qt/doric/yoga/internal/experiments-inl.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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 "experiments.h"
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
extern std::bitset<sizeof(int)> enabledExperiments;
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
inline bool isEnabled(Experiment experiment) {
|
||||||
|
return detail::enabledExperiments.test(static_cast<size_t>(experiment));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void disableAllExperiments() {
|
||||||
|
detail::enabledExperiments = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
38
doric-Qt/doric/yoga/internal/experiments.cpp
Normal file
38
doric-Qt/doric/yoga/internal/experiments.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "experiments.h"
|
||||||
|
#include "experiments-inl.h"
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
std::bitset<sizeof(int)> enabledExperiments = 0;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
void enable(Experiment experiment) {
|
||||||
|
detail::enabledExperiments.set(static_cast<size_t>(experiment));
|
||||||
|
}
|
||||||
|
|
||||||
|
void disable(Experiment experiment) {
|
||||||
|
detail::enabledExperiments.reset(static_cast<size_t>(experiment));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool toggle(Experiment experiment) {
|
||||||
|
auto bit = static_cast<size_t>(experiment);
|
||||||
|
auto previousState = detail::enabledExperiments.test(bit);
|
||||||
|
detail::enabledExperiments.flip(bit);
|
||||||
|
return previousState;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
26
doric-Qt/doric/yoga/internal/experiments.h
Normal file
26
doric-Qt/doric/yoga/internal/experiments.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
enum struct Experiment : size_t {
|
||||||
|
kDoubleMeasureCallbacks,
|
||||||
|
};
|
||||||
|
|
||||||
|
void enable(Experiment);
|
||||||
|
void disable(Experiment);
|
||||||
|
bool toggle(Experiment);
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
68
doric-Qt/doric/yoga/log.cpp
Normal file
68
doric-Qt/doric/yoga/log.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#include "Yoga.h"
|
||||||
|
#include "YGConfig.h"
|
||||||
|
#include "YGNode.h"
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void vlog(
|
||||||
|
YGConfig* config,
|
||||||
|
YGNode* node,
|
||||||
|
YGLogLevel level,
|
||||||
|
void* context,
|
||||||
|
const char* format,
|
||||||
|
va_list args) {
|
||||||
|
YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault();
|
||||||
|
logConfig->log(logConfig, node, level, context, format, args);
|
||||||
|
|
||||||
|
if (level == YGLogLevelFatal) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
YOGA_EXPORT void Log::log(
|
||||||
|
YGNode* node,
|
||||||
|
YGLogLevel level,
|
||||||
|
void* context,
|
||||||
|
const char* format,
|
||||||
|
...) noexcept {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vlog(
|
||||||
|
node == nullptr ? nullptr : node->getConfig(),
|
||||||
|
node,
|
||||||
|
level,
|
||||||
|
context,
|
||||||
|
format,
|
||||||
|
args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Log::log(
|
||||||
|
YGConfig* config,
|
||||||
|
YGLogLevel level,
|
||||||
|
void* context,
|
||||||
|
const char* format,
|
||||||
|
...) noexcept {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
vlog(config, nullptr, level, context, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
38
doric-Qt/doric/yoga/log.h
Normal file
38
doric-Qt/doric/yoga/log.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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 "YGEnums.h"
|
||||||
|
|
||||||
|
struct YGNode;
|
||||||
|
struct YGConfig;
|
||||||
|
|
||||||
|
namespace facebook {
|
||||||
|
namespace yoga {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
struct Log {
|
||||||
|
static void log(
|
||||||
|
YGNode* node,
|
||||||
|
YGLogLevel level,
|
||||||
|
void*,
|
||||||
|
const char* message,
|
||||||
|
...) noexcept;
|
||||||
|
|
||||||
|
static void log(
|
||||||
|
YGConfig* config,
|
||||||
|
YGLogLevel level,
|
||||||
|
void*,
|
||||||
|
const char* format,
|
||||||
|
...) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace yoga
|
||||||
|
} // namespace facebook
|
Reference in New Issue
Block a user