added yoga src

This commit is contained in:
Atul R 2019-05-23 21:46:20 +02:00
parent f031259f35
commit 90f11ef352
31 changed files with 7889 additions and 1 deletions

View File

@ -1,6 +1,7 @@
{
"includes": [
"./config/application.gypi"
"./config/application.gypi",
'./config/yoga.gypi'
],
"targets": []
}

20
config/yoga.gypi Normal file
View File

@ -0,0 +1,20 @@
{
"includes": [],
"target_defaults": {
"sources": [
"../deps/yoga/Yoga.cpp",
"../deps/yoga/YGValue.cpp",
"../deps/yoga/YGStyle.cpp",
"../deps/yoga/YGNodePrint.cpp",
"../deps/yoga/YGNode.cpp",
"../deps/yoga/YGMarker.cpp",
"../deps/yoga/YGLayout.cpp",
"../deps/yoga/YGEnums.cpp",
"../deps/yoga/YGConfig.cpp",
"../deps/yoga/Utils.cpp",
"../deps/yoga/log.cpp",
"../deps/yoga/event/event.cpp",
],
}
}

183
deps/yoga/CompactValue.h vendored Normal file
View File

@ -0,0 +1,183 @@
/**
* 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 <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 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

66
deps/yoga/Utils.cpp vendored Normal file
View File

@ -0,0 +1,66 @@
/**
* 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;
}

142
deps/yoga/Utils.h vendored Normal file
View File

@ -0,0 +1,142 @@
/**
* 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 inculding 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 comparision function compares the array of float with
// YGFloatsEqual, as the default float comparision 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);
}

43
deps/yoga/YGConfig.cpp vendored Normal file
View File

@ -0,0 +1,43 @@
/**
* 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;
}

77
deps/yoga/YGConfig.h vendored Normal file
View File

@ -0,0 +1,77 @@
/**
* 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 "YGMarker.h"
#include "Yoga-internal.h"
#include "Yoga.h"
struct 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;
YGMarkerCallbacks markerCallbacks = {nullptr, 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});
}
};

225
deps/yoga/YGEnums.cpp vendored Normal file
View 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.
*/
#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";
}

150
deps/yoga/YGEnums.h vendored Normal file
View File

@ -0,0 +1,150 @@
/**
* 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

69
deps/yoga/YGFloatOptional.h vendored Normal file
View 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 <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;
}

40
deps/yoga/YGLayout.cpp vendored Normal file
View File

@ -0,0 +1,40 @@
/**
* 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;
}

48
deps/yoga/YGLayout.h vendored Normal file
View File

@ -0,0 +1,48 @@
/**
* 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 "YGFloatOptional.h"
#include "Yoga-internal.h"
constexpr std::array<float, 2> kYGDefaultDimensionValues = {
{YGUndefined, YGUndefined}};
struct YGLayout {
std::array<float, 4> position = {};
std::array<float, 2> dimensions = kYGDefaultDimensionValues;
std::array<float, 4> margin = {};
std::array<float, 4> border = {};
std::array<float, 4> padding = {};
YGDirection direction : 2;
bool didUseLegacyFlag : 1;
bool doesLegacyStretchFlagAffectsLayout : 1;
bool hadOverflow : 1;
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 = kYGDefaultDimensionValues;
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
YGLayout()
: direction(YGDirectionInherit),
didUseLegacyFlag(false),
doesLegacyStretchFlagAffectsLayout(false),
hadOverflow(false) {}
bool operator==(YGLayout layout) const;
bool operator!=(YGLayout layout) const { return !(*this == layout); }
};

32
deps/yoga/YGMacros.h vendored Normal file
View 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
#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
#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

14
deps/yoga/YGMarker.cpp vendored Normal file
View File

@ -0,0 +1,14 @@
/**
* 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 "YGMarker.h"
#include "YGConfig.h"
void YGConfigSetMarkerCallbacks(
YGConfigRef config,
YGMarkerCallbacks markerCallbacks) {
config->markerCallbacks = markerCallbacks;
}

90
deps/yoga/YGMarker.h vendored Normal file
View File

@ -0,0 +1,90 @@
/**
* 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"
YG_EXTERN_C_BEGIN
typedef struct YGNode* YGNodeRef;
typedef struct YGConfig* YGConfigRef;
typedef YG_ENUM_BEGIN(YGMarker){
YGMarkerLayout,
YGMarkerMeasure,
YGMarkerBaselineFn,
} YG_ENUM_END(YGMarker);
typedef struct {
int layouts;
int measures;
int maxMeasureCache;
int cachedLayouts;
int cachedMeasures;
} YGMarkerLayoutData;
typedef struct {
bool _unused;
} YGMarkerNoData;
typedef union {
YGMarkerLayoutData* layout;
YGMarkerNoData* noData;
} YGMarkerData;
typedef struct {
// accepts marker type, a node ref, and marker data (depends on marker type)
// can return a handle or id that Yoga will pass to endMarker
void* (*startMarker)(YGMarker, YGNodeRef, YGMarkerData);
// accepts marker type, a node ref, marker data, and marker id as returned by
// startMarker
void (*endMarker)(YGMarker, YGNodeRef, YGMarkerData, void* id);
} YGMarkerCallbacks;
void YGConfigSetMarkerCallbacks(YGConfigRef, YGMarkerCallbacks);
YG_EXTERN_C_END
#ifdef __cplusplus
namespace facebook {
namespace yoga {
namespace marker {
namespace detail {
template <YGMarker M>
struct MarkerData;
template <>
struct MarkerData<YGMarkerLayout> {
using type = YGMarkerLayoutData;
static type*& get(YGMarkerData& d) { return d.layout; }
};
struct NoMarkerData {
using type = YGMarkerNoData;
static type*& get(YGMarkerData& d) { return d.noData; }
};
template <>
struct MarkerData<YGMarkerMeasure> : NoMarkerData {};
template <>
struct MarkerData<YGMarkerBaselineFn> : NoMarkerData {};
} // namespace detail
template <YGMarker M>
typename detail::MarkerData<M>::type* data(YGMarkerData d) {
return detail::MarkerData<M>::get(d);
}
} // namespace marker
} // namespace yoga
} // namespace facebook
#endif // __cplusplus

590
deps/yoga/YGNode.cpp vendored Normal file
View File

@ -0,0 +1,590 @@
/**
* 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_;
hasNewLayout_ = node.hasNewLayout_;
isReferenceBaseline_ = node.isReferenceBaseline_;
isDirty_ = node.isDirty_;
nodeType_ = node.nodeType_;
measureUsesContext_ = node.measureUsesContext_;
baselineUsesContext_ = node.baselineUsesContext_;
printUsesContext_ = node.printUsesContext_;
useWebDefaults_ = node.useWebDefaults_;
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 (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 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 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
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) {
measureUsesContext_ = false;
decltype(YGNode::measure_) m;
m.noContext = measureFunc;
setMeasureFunc(m);
}
void YGNode::setMeasureFunc(MeasureWithContextFn measureFunc) {
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 == isDirty_) {
return;
}
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 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();
}
}
void YGNode::clearChildren() {
children_.clear();
children_.shrink_to_fit();
}
// Other Methods
void YGNode::cloneChildrenIfNeeded(void* cloneContext) {
iterChildrenAfterCloningIfNeeded([](YGNodeRef, void*) {}, cloneContext);
}
void YGNode::markDirtyAndPropogate() {
if (!isDirty_) {
setDirty(true);
setLayoutComputedFlexBasis(YGFloatOptional());
if (owner_) {
owner_->markDirtyAndPropogate();
}
}
}
void YGNode::markDirtyAndPropogateDownwards() {
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 (!useWebDefaults_ && !style_.flex().isUndefined() &&
style_.flex().unwrap() < 0.0f) {
return -style_.flex().unwrap();
}
return 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 = useWebDefaults_;
*this = YGNode{getConfig()};
if (webDefaults) {
useWebDefaults();
}
}

322
deps/yoga/YGNode.h vendored Normal file
View File

@ -0,0 +1,322 @@
/**
* 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 "CompactValue.h"
#include "YGConfig.h"
#include "YGLayout.h"
#include "YGStyle.h"
#include "Yoga-internal.h"
YGConfigRef YGConfigGetDefault();
struct YGNode {
using MeasureWithContextFn =
YGSize (*)(YGNode*, float, YGMeasureMode, float, YGMeasureMode, void*);
using BaselineWithContextFn = float (*)(YGNode*, float, float, void*);
using PrintWithContextFn = void (*)(YGNode*, void*);
private:
void* context_ = nullptr;
bool hasNewLayout_ : 1;
bool isReferenceBaseline_ : 1;
bool isDirty_ : 1;
YGNodeType nodeType_ : 1;
bool measureUsesContext_ : 1;
bool baselineUsesContext_ : 1;
bool printUsesContext_ : 1;
bool useWebDefaults_ : 1;
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() {
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)
: hasNewLayout_{true},
isReferenceBaseline_{false},
isDirty_{false},
nodeType_{YGNodeTypeDefault},
measureUsesContext_{false},
baselineUsesContext_{false},
printUsesContext_{false},
useWebDefaults_{config->useWebDefaults},
config_{config} {
if (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 hasNewLayout_; }
YGNodeType getNodeType() const { return 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 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 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;
printUsesContext_ = false;
}
void setPrintFunc(PrintWithContextFn printFunc) {
print_.withContext = printFunc;
printUsesContext_ = true;
}
void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); }
void setHasNewLayout(bool hasNewLayout) { hasNewLayout_ = hasNewLayout; }
void setNodeType(YGNodeType nodeType) { nodeType_ = nodeType; }
void setMeasureFunc(YGMeasureFunc measureFunc);
void setMeasureFunc(MeasureWithContextFn);
void setMeasureFunc(std::nullptr_t) {
return setMeasureFunc(YGMeasureFunc{nullptr});
}
void setBaselineFunc(YGBaselineFunc baseLineFunc) {
baselineUsesContext_ = false;
baseline_.noContext = baseLineFunc;
}
void setBaselineFunc(BaselineWithContextFn baseLineFunc) {
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) {
isReferenceBaseline_ = isReferenceBaseline;
}
void setOwner(YGNodeRef owner) { owner_ = owner; }
void setChildren(const YGVector& children) { children_ = children; }
// TODO: rvalue override for setChildren
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();
};

224
deps/yoga/YGNodePrint.cpp vendored Normal file
View File

@ -0,0 +1,224 @@
/**
* 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

24
deps/yoga/YGNodePrint.h vendored Normal file
View File

@ -0,0 +1,24 @@
/**
* 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

55
deps/yoga/YGStyle.cpp vendored Normal file
View File

@ -0,0 +1,55 @@
/**
* 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;
}

291
deps/yoga/YGStyle.h vendored Normal file
View File

@ -0,0 +1,291 @@
/**
* 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 <bitset>
#include <cstdint>
#include <type_traits>
#include "CompactValue.h"
#include "YGEnums.h"
#include "YGFloatOptional.h"
#include "Yoga-internal.h"
#include "Yoga.h"
#if !defined(ENUM_BITFIELDS_NOT_SUPPORTED)
#define BITFIELD_ENUM_SIZED(num) : num
#else
#define BITFIELD_ENUM_SIZED(num)
#endif
#define BITFIELD_ACCESSORS(FIELD) \
decltype(FIELD##_) get_##FIELD() const { return FIELD##_; } \
void set_##FIELD(decltype(FIELD##_) x) { FIELD##_ = x; }
#define BITFIELD_REF(FIELD) \
BitfieldRef< \
decltype(FIELD##_), \
&YGStyle::get_##FIELD, \
&YGStyle::set_##FIELD, \
FIELD##Bit>
class YGStyle {
template <typename Enum>
using Values =
facebook::yoga::detail::Values<facebook::yoga::enums::count<Enum>()>;
using CompactValue = facebook::yoga::detail::CompactValue;
static constexpr uint64_t allBits(int fromBit, int toBit) {
return fromBit < toBit
? (uint64_t{1} << fromBit) | allBits(fromBit + 1, toBit)
: 0;
}
public:
using Dimensions = Values<YGDimension>;
using Edges = Values<YGEdge>;
template <typename T, T YGStyle::*Prop, int PropBit>
struct Ref {
YGStyle& style;
operator T() const { return style.*Prop; }
Ref<T, Prop, PropBit>& operator=(T value) {
style.*Prop = value;
style.assignedProps_.set(PropBit);
return *this;
}
};
template <typename Idx, Values<Idx> YGStyle::*Prop, int PropBit>
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;
style.assignedProps_.set(PropBit + idx);
return *this;
}
};
YGStyle& style;
IdxRef<Idx, Prop, PropBit>& operator=(const Values<Idx>& values) {
style.*Prop = values;
style.assignedProps_ |=
allBits(PropBit, PropBit + facebook::yoga::enums::count<Idx>());
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]; }
};
template <
typename T,
T (YGStyle::*Get)() const,
void (YGStyle::*Set)(T),
int PropBit>
struct BitfieldRef {
YGStyle& style;
operator T() const { return (style.*Get)(); }
BitfieldRef<T, Get, Set, PropBit>& operator=(T x) {
(style.*Set)(x);
style.assignedProps_.set(PropBit);
return *this;
}
};
YGStyle()
: direction_(YGDirectionInherit),
flexDirection_(YGFlexDirectionColumn),
justifyContent_(YGJustifyFlexStart),
alignContent_(YGAlignFlexStart),
alignItems_(YGAlignStretch),
alignSelf_(YGAlignAuto),
positionType_(YGPositionTypeRelative),
flexWrap_(YGWrapNoWrap),
overflow_(YGOverflowVisible),
display_(YGDisplayFlex) {}
~YGStyle() = default;
static constexpr int directionBit = 0;
static constexpr int flexDirectionBit = directionBit + 1;
static constexpr int justifyContentBit = flexDirectionBit + 1;
static constexpr int alignContentBit = justifyContentBit + 1;
static constexpr int alignItemsBit = alignContentBit + 1;
static constexpr int alignSelfBit = alignItemsBit + 1;
static constexpr int positionTypeBit = alignSelfBit + 1;
static constexpr int flexWrapBit = positionTypeBit + 1;
static constexpr int overflowBit = flexWrapBit + 1;
static constexpr int displayBit = overflowBit + 1;
static constexpr int flexBit = displayBit + 1;
static constexpr int flexGrowBit = flexBit + 1;
static constexpr int flexShrinkBit = flexGrowBit + 1;
static constexpr int flexBasisBit = flexShrinkBit + 1;
static constexpr int marginBit = flexBasisBit + 1;
static constexpr int positionBit =
marginBit + facebook::yoga::enums::count<YGEdge>();
static constexpr int paddingBit =
positionBit + facebook::yoga::enums::count<YGEdge>();
static constexpr int borderBit =
paddingBit + facebook::yoga::enums::count<YGEdge>();
static constexpr int dimensionsBit =
borderBit + facebook::yoga::enums::count<YGEdge>();
static constexpr int maxDimensionsBit =
dimensionsBit + facebook::yoga::enums::count<YGDimension>();
static constexpr int minDimensionsBit =
maxDimensionsBit + facebook::yoga::enums::count<YGDimension>();
static constexpr int aspectRatioBit =
minDimensionsBit + facebook::yoga::enums::count<YGDimension>();
static constexpr int numStyles = aspectRatioBit + 1;
private:
std::bitset<aspectRatioBit + 1> assignedProps_;
/* Some platforms don't support enum bitfields,
so please use BITFIELD_ENUM_SIZED(BITS_COUNT) */
YGDirection direction_ BITFIELD_ENUM_SIZED(2);
YGFlexDirection flexDirection_ BITFIELD_ENUM_SIZED(2);
YGJustify justifyContent_ BITFIELD_ENUM_SIZED(3);
YGAlign alignContent_ BITFIELD_ENUM_SIZED(3);
YGAlign alignItems_ BITFIELD_ENUM_SIZED(3);
YGAlign alignSelf_ BITFIELD_ENUM_SIZED(3);
YGPositionType positionType_ BITFIELD_ENUM_SIZED(1);
YGWrap flexWrap_ BITFIELD_ENUM_SIZED(2);
YGOverflow overflow_ BITFIELD_ENUM_SIZED(2);
YGDisplay display_ BITFIELD_ENUM_SIZED(1);
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_ = {};
BITFIELD_ACCESSORS(direction)
BITFIELD_ACCESSORS(flexDirection)
BITFIELD_ACCESSORS(justifyContent)
BITFIELD_ACCESSORS(alignContent);
BITFIELD_ACCESSORS(alignItems);
BITFIELD_ACCESSORS(alignSelf);
BITFIELD_ACCESSORS(positionType);
BITFIELD_ACCESSORS(flexWrap);
BITFIELD_ACCESSORS(overflow);
BITFIELD_ACCESSORS(display);
public:
const decltype(assignedProps_)& assignedProps() const {
return assignedProps_;
}
// for library users needing a type
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
YGDirection direction() const { return direction_; }
BITFIELD_REF(direction) direction() { return {*this}; }
YGFlexDirection flexDirection() const { return flexDirection_; }
BITFIELD_REF(flexDirection) flexDirection() { return {*this}; }
YGJustify justifyContent() const { return justifyContent_; }
BITFIELD_REF(justifyContent) justifyContent() { return {*this}; }
YGAlign alignContent() const { return alignContent_; }
BITFIELD_REF(alignContent) alignContent() { return {*this}; }
YGAlign alignItems() const { return alignItems_; }
BITFIELD_REF(alignItems) alignItems() { return {*this}; }
YGAlign alignSelf() const { return alignSelf_; }
BITFIELD_REF(alignSelf) alignSelf() { return {*this}; }
YGPositionType positionType() const { return positionType_; }
BITFIELD_REF(positionType) positionType() { return {*this}; }
YGWrap flexWrap() const { return flexWrap_; }
BITFIELD_REF(flexWrap) flexWrap() { return {*this}; }
YGOverflow overflow() const { return overflow_; }
BITFIELD_REF(overflow) overflow() { return {*this}; }
YGDisplay display() const { return display_; }
BITFIELD_REF(display) display() { return {*this}; }
YGFloatOptional flex() const { return flex_; }
Ref<YGFloatOptional, &YGStyle::flex_, flexBit> flex() { return {*this}; }
YGFloatOptional flexGrow() const { return flexGrow_; }
Ref<YGFloatOptional, &YGStyle::flexGrow_, flexGrowBit> flexGrow() {
return {*this};
}
YGFloatOptional flexShrink() const { return flexShrink_; }
Ref<YGFloatOptional, &YGStyle::flexShrink_, flexShrinkBit> flexShrink() {
return {*this};
}
CompactValue flexBasis() const { return flexBasis_; }
Ref<CompactValue, &YGStyle::flexBasis_, flexBasisBit> flexBasis() {
return {*this};
}
const Edges& margin() const { return margin_; }
IdxRef<YGEdge, &YGStyle::margin_, marginBit> margin() { return {*this}; }
const Edges& position() const { return position_; }
IdxRef<YGEdge, &YGStyle::position_, positionBit> position() {
return {*this};
}
const Edges& padding() const { return padding_; }
IdxRef<YGEdge, &YGStyle::padding_, paddingBit> padding() { return {*this}; }
const Edges& border() const { return border_; }
IdxRef<YGEdge, &YGStyle::border_, borderBit> border() { return {*this}; }
const Dimensions& dimensions() const { return dimensions_; }
IdxRef<YGDimension, &YGStyle::dimensions_, dimensionsBit> dimensions() {
return {*this};
}
const Dimensions& minDimensions() const { return minDimensions_; }
IdxRef<YGDimension, &YGStyle::minDimensions_, minDimensionsBit>
minDimensions() {
return {*this};
}
const Dimensions& maxDimensions() const { return maxDimensions_; }
IdxRef<YGDimension, &YGStyle::maxDimensions_, maxDimensionsBit>
maxDimensions() {
return {*this};
}
// Yoga specific properties, not compatible with flexbox specification
YGFloatOptional aspectRatio() const { return aspectRatio_; }
Ref<YGFloatOptional, &YGStyle::aspectRatio_, aspectRatioBit> aspectRatio() {
return {*this};
}
};
bool operator==(const YGStyle& lhs, const YGStyle& rhs);
inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) {
return !(lhs == rhs);
}
#undef BITFIELD_ENUM_SIZED
#undef BITFIELD_ACCESSORS
#undef BITFIELD_REF

11
deps/yoga/YGValue.cpp vendored Normal file
View File

@ -0,0 +1,11 @@
/**
* 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};

83
deps/yoga/YGValue.h vendored Normal file
View File

@ -0,0 +1,83 @@
/**
* 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;
extern const YGValue YGValueAuto;
extern const YGValue YGValueUndefined;
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

156
deps/yoga/Yoga-internal.h vendored Normal file
View File

@ -0,0 +1,156 @@
/**
* 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
WIN_EXPORT float YGRoundValueToPixelGrid(
const float value,
const float pointScaleFactor,
const bool forceCeil,
const bool forceFloor);
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);

4265
deps/yoga/Yoga.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

368
deps/yoga/Yoga.h vendored Normal file
View File

@ -0,0 +1,368 @@
/**
* 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 prefered 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

57
deps/yoga/event/event.cpp vendored Normal file
View File

@ -0,0 +1,57 @@
/**
* 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 <memory>
#include <stdexcept>
#include <mutex>
#include <iostream>
namespace facebook {
namespace yoga {
namespace {
std::mutex& eventSubscribersMutex() {
static std::mutex subscribersMutex;
return subscribersMutex;
}
std::shared_ptr<Event::Subscribers>& eventSubscribers() {
static auto subscribers = std::make_shared<Event::Subscribers>();
return subscribers;
}
} // namespace
void Event::reset() {
eventSubscribers() = std::make_shared<Event::Subscribers>();
}
void Event::subscribe(std::function<Subscriber>&& subscriber) {
std::lock_guard<std::mutex> guard(eventSubscribersMutex());
eventSubscribers() =
std::make_shared<Event::Subscribers>(*eventSubscribers());
eventSubscribers()->push_back(subscriber);
}
void Event::publish(const YGNode& node, Type eventType, const Data& eventData) {
std::shared_ptr<Event::Subscribers> subscribers;
{
std::lock_guard<std::mutex> guard(eventSubscribersMutex());
subscribers = eventSubscribers();
}
for (auto& subscriber : *subscribers) {
if (subscriber) {
subscriber(node, eventType, eventData);
}
}
}
} // namespace yoga
} // namespace facebook

75
deps/yoga/event/event.h vendored Normal file
View File

@ -0,0 +1,75 @@
/**
* 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>
struct YGConfig;
struct YGNode;
namespace facebook {
namespace yoga {
struct Event {
enum Type {
NodeAllocation,
NodeDeallocation,
NodeLayout,
LayoutPassStart,
LayoutPassEnd
};
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 = {}) {
publish(node, E, Data{eventData});
}
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;
};
} // namespace yoga
} // namespace facebook

63
deps/yoga/instrumentation.h vendored Normal file
View File

@ -0,0 +1,63 @@
/**
* 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"
#include "YGMarker.h"
#include "YGNode.h"
namespace facebook {
namespace yoga {
namespace marker {
template <YGMarker MarkerType>
class MarkerSection {
private:
using Data = detail::MarkerData<MarkerType>;
public:
MarkerSection(YGNodeRef node) : MarkerSection{node, node->getConfig()} {}
~MarkerSection() {
if (endMarker_) {
endMarker_(MarkerType, node_, markerData(&data), userData_);
}
}
typename Data::type data = {};
template <typename Ret, typename... Args>
static Ret wrap(
YGNodeRef node,
Ret (YGNode::*method)(Args...),
Args... args) {
MarkerSection<MarkerType> section{node};
return (node->*method)(std::forward<Args>(args)...);
}
private:
decltype(YGMarkerCallbacks{}.endMarker) endMarker_;
YGNodeRef node_;
void* userData_;
MarkerSection(YGNodeRef node, YGConfigRef config)
: MarkerSection{node, config ? &config->markerCallbacks : nullptr} {}
MarkerSection(YGNodeRef node, YGMarkerCallbacks* callbacks)
: endMarker_{callbacks ? callbacks->endMarker : nullptr},
node_{node},
userData_{
callbacks && callbacks->startMarker
? callbacks->startMarker(MarkerType, node, markerData(&data))
: nullptr} {}
static YGMarkerData markerData(typename Data::type* d) {
YGMarkerData markerData = {};
Data::get(markerData) = d;
return markerData;
}
};
} // namespace marker
} // namespace yoga
} // namespace facebook

67
deps/yoga/log.cpp vendored Normal file
View File

@ -0,0 +1,67 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the LICENSE
* file in the root directory of this source tree.
*/
#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
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

37
deps/yoga/log.h vendored Normal file
View File

@ -0,0 +1,37 @@
/**
* 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