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/DoricViewNode.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
|
||||
|
||||
@ -93,4 +105,22 @@ HEADERS += \
|
||||
utils/DoricCountDownLatch.h \
|
||||
utils/DoricObjectFactory.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