YGStyle: wrap all fields into accessors

Summary:
@public

In order to encapsulate property access on `YGStyle`, as a first measure we wrap all fields with accessors.

This will e.g. enable dynamic property storage and instrumentation in the future.

All accessors have a `const` version that allows direct access via `const&`. For mutation, bit fields are wrapped with a custom reference object.

This style allows for the least amount of changes in client code. Property access simply needs appended parens, eg `style.direction` becomes `style.direction`.

Reviewed By: shergin

Differential Revision: D14999096

fbshipit-source-id: fbf29f7ddab520513d4618f5e70094c4f6330b30
This commit is contained in:
David Aurelio
2019-04-23 08:08:51 -07:00
committed by Facebook Github Bot
parent e167642672
commit dee93017f7
7 changed files with 720 additions and 350 deletions

View File

@@ -224,8 +224,8 @@ WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
gNodeInstanceCount++;
if (config->useWebDefaults) {
node->setStyleFlexDirection(YGFlexDirectionRow);
node->setStyleAlignContent(YGAlignStretch);
node->getStyle().flexDirection() = YGFlexDirectionRow;
node->getStyle().alignContent() = YGAlignStretch;
}
node->setConfig(config);
return node;
@@ -522,61 +522,69 @@ void YGNodeCopyStyle(const YGNodeRef dstNode, const YGNodeRef srcNode) {
}
}
float YGNodeStyleGetFlexGrow(const YGNodeRef node) {
return node->getStyle().flexGrow.isUndefined()
float YGNodeStyleGetFlexGrow(const YGNodeRef n) {
const YGNode* node = n;
return node->getStyle().flexGrow().isUndefined()
? kDefaultFlexGrow
: node->getStyle().flexGrow.unwrap();
: node->getStyle().flexGrow().unwrap();
}
float YGNodeStyleGetFlexShrink(const YGNodeRef node) {
return node->getStyle().flexShrink.isUndefined()
float YGNodeStyleGetFlexShrink(const YGNodeRef n) {
const YGNode* node = n;
return node->getStyle().flexShrink().isUndefined()
? (node->getConfig()->useWebDefaults ? kWebDefaultFlexShrink
: kDefaultFlexShrink)
: node->getStyle().flexShrink.unwrap();
: node->getStyle().flexShrink().unwrap();
}
namespace {
template <typename T, typename NeedsUpdate, typename Update>
void updateNodeProp(
void updateStyle(
YGNode* node,
T value,
NeedsUpdate&& needsUpdate,
Update&& update) {
if (needsUpdate(node, value)) {
update(node, value);
if (needsUpdate(node->getStyle(), value)) {
update(node->getStyle(), value);
node->markDirtyAndPropogate();
}
}
template <typename T, T YGStyle::*Prop>
void updateStyleProp(YGNode* node, T value) {
updateNodeProp(
template <typename T, YGStyle::BitfieldRef<T> (YGStyle::*Prop)()>
void updateStyle(YGNode* node, T value) {
updateStyle(
node,
value,
[](YGNode* n, T x) { return (n->getStyle().*Prop) != x; },
[](YGNode* n, T x) { (n->getStyle().*Prop) = x; });
[](YGStyle& s, T x) { return (s.*Prop)() != x; },
[](YGStyle& s, T x) { (s.*Prop)() = x; });
}
template <typename Idx, detail::Values<enums::count<Idx>()> YGStyle::*Prop>
template <typename T, T& (YGStyle::*Prop)()>
void updateStyle(YGNode* node, T value) {
updateStyle(
node,
value,
[](YGStyle& s, T x) { return (s.*Prop)() != x; },
[](YGStyle& s, T x) { (s.*Prop)() = x; });
}
template <typename Idx, detail::Values<enums::count<Idx>()>& (YGStyle::*Prop)()>
void updateIndexedStyleProp(YGNode* node, Idx idx, detail::CompactValue value) {
updateNodeProp(
using detail::CompactValue;
updateStyle(
node,
value,
[idx](YGNode* n, detail::CompactValue x) {
return (n->getStyle().*Prop)[idx] != x;
},
[idx](YGNode* n, detail::CompactValue x) {
(n->getStyle().*Prop)[idx] = x;
});
[idx](YGStyle& s, CompactValue x) { return (s.*Prop)()[idx] != x; },
[idx](YGStyle& s, CompactValue x) { (s.*Prop)()[idx] = x; });
}
template <detail::Values<enums::count<YGEdge>()> YGStyle::*Prop>
template <YGStyle::Edges& (YGStyle::*Prop)()>
void updateEdgeProp(YGNode* node, YGEdge edge, detail::CompactValue value) {
updateIndexedStyleProp<YGEdge, Prop>(node, edge, value);
}
template <detail::Values<enums::count<YGDimension>()> YGStyle::*Prop>
template <YGStyle::Dimensions& (YGStyle::*Prop)()>
void updateDimensionProp(
YGNode* node,
YGDimension dimension,
@@ -584,141 +592,127 @@ void updateDimensionProp(
updateIndexedStyleProp<YGDimension, Prop>(node, dimension, value);
}
#define YG_UPDATE_STYLE_PROP_BITFIELD(PROP_NAME, node, value) \
updateNodeProp( \
node, \
value, \
[](YGNode* n, decltype(value) x) { \
return n->getStyle().PROP_NAME != x; \
}, \
[](YGNode* n, decltype(value) x) { n->getStyle().PROP_NAME = x; })
} // namespace
void YGNodeStyleSetDirection(const YGNodeRef node, const YGDirection value) {
YG_UPDATE_STYLE_PROP_BITFIELD(direction, node, value);
updateStyle<YGDirection, &YGStyle::direction>(node, value);
}
YGDirection YGNodeStyleGetDirection(const YGNodeRef node) {
return node->getStyle().direction;
return node->getStyle().direction();
}
void YGNodeStyleSetFlexDirection(
const YGNodeRef node,
const YGFlexDirection flexDirection) {
YG_UPDATE_STYLE_PROP_BITFIELD(flexDirection, node, flexDirection);
updateStyle<YGFlexDirection, &YGStyle::flexDirection>(node, flexDirection);
}
YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeRef node) {
return node->getStyle().flexDirection;
return node->getStyle().flexDirection();
}
void YGNodeStyleSetJustifyContent(
const YGNodeRef node,
const YGJustify justifyContent) {
YG_UPDATE_STYLE_PROP_BITFIELD(justifyContent, node, justifyContent);
updateStyle<YGJustify, &YGStyle::justifyContent>(node, justifyContent);
}
YGJustify YGNodeStyleGetJustifyContent(const YGNodeRef node) {
return node->getStyle().justifyContent;
return node->getStyle().justifyContent();
}
void YGNodeStyleSetAlignContent(
const YGNodeRef node,
const YGAlign alignContent) {
YG_UPDATE_STYLE_PROP_BITFIELD(alignContent, node, alignContent);
updateStyle<YGAlign, &YGStyle::alignContent>(node, alignContent);
}
YGAlign YGNodeStyleGetAlignContent(const YGNodeRef node) {
return node->getStyle().alignContent;
return node->getStyle().alignContent();
}
void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) {
YG_UPDATE_STYLE_PROP_BITFIELD(alignItems, node, alignItems);
updateStyle<YGAlign, &YGStyle::alignItems>(node, alignItems);
}
YGAlign YGNodeStyleGetAlignItems(const YGNodeRef node) {
return node->getStyle().alignItems;
return node->getStyle().alignItems();
}
void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) {
YG_UPDATE_STYLE_PROP_BITFIELD(alignSelf, node, alignSelf);
updateStyle<YGAlign, &YGStyle::alignSelf>(node, alignSelf);
}
YGAlign YGNodeStyleGetAlignSelf(const YGNodeRef node) {
return node->getStyle().alignSelf;
return node->getStyle().alignSelf();
}
void YGNodeStyleSetPositionType(
const YGNodeRef node,
const YGPositionType positionType) {
YG_UPDATE_STYLE_PROP_BITFIELD(positionType, node, positionType);
updateStyle<YGPositionType, &YGStyle::positionType>(node, positionType);
}
YGPositionType YGNodeStyleGetPositionType(const YGNodeRef node) {
return node->getStyle().positionType;
return node->getStyle().positionType();
}
void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) {
YG_UPDATE_STYLE_PROP_BITFIELD(flexWrap, node, flexWrap);
updateStyle<YGWrap, &YGStyle::flexWrap>(node, flexWrap);
}
YGWrap YGNodeStyleGetFlexWrap(const YGNodeRef node) {
return node->getStyle().flexWrap;
return node->getStyle().flexWrap();
}
void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) {
YG_UPDATE_STYLE_PROP_BITFIELD(overflow, node, overflow);
updateStyle<YGOverflow, &YGStyle::overflow>(node, overflow);
}
YGOverflow YGNodeStyleGetOverflow(const YGNodeRef node) {
return node->getStyle().overflow;
return node->getStyle().overflow();
}
void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) {
YG_UPDATE_STYLE_PROP_BITFIELD(display, node, display);
updateStyle<YGDisplay, &YGStyle::display>(node, display);
}
YGDisplay YGNodeStyleGetDisplay(const YGNodeRef node) {
return node->getStyle().display;
return node->getStyle().display();
}
// TODO(T26792433): Change the API to accept YGFloatOptional.
void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) {
updateStyleProp<YGFloatOptional, &YGStyle::flex>(node, YGFloatOptional{flex});
updateStyle<YGFloatOptional, &YGStyle::flex>(node, YGFloatOptional{flex});
}
// TODO(T26792433): Change the API to accept YGFloatOptional.
float YGNodeStyleGetFlex(const YGNodeRef node) {
return node->getStyle().flex.isUndefined() ? YGUndefined
: node->getStyle().flex.unwrap();
const auto& style = node->getStyle();
return style.flex().isUndefined() ? YGUndefined : style.flex().unwrap();
}
// TODO(T26792433): Change the API to accept YGFloatOptional.
void YGNodeStyleSetFlexGrow(const YGNodeRef node, const float flexGrow) {
updateStyleProp<YGFloatOptional, &YGStyle::flexGrow>(
updateStyle<YGFloatOptional, &YGStyle::flexGrow>(
node, YGFloatOptional{flexGrow});
}
// TODO(T26792433): Change the API to accept YGFloatOptional.
void YGNodeStyleSetFlexShrink(const YGNodeRef node, const float flexShrink) {
updateStyleProp<YGFloatOptional, &YGStyle::flexShrink>(
updateStyle<YGFloatOptional, &YGStyle::flexShrink>(
node, YGFloatOptional{flexShrink});
}
YGValue YGNodeStyleGetFlexBasis(const YGNodeRef node) {
YGValue flexBasis = node->getStyle().flexBasis;
if (flexBasis.unit == YGUnitUndefined || flexBasis.unit == YGUnitAuto) {
// TODO(T26792433): Get rid off the use of YGUndefined at client side
flexBasis.value = YGUndefined;
}
return flexBasis;
return static_cast<const YGNode*>(node)->getStyle().flexBasis();
}
void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) {
auto value = detail::CompactValue::ofMaybe<YGUnitPoint>(flexBasis);
updateStyleProp<detail::CompactValue, &YGStyle::flexBasis>(node, value);
updateStyle<detail::CompactValue, &YGStyle::flexBasis>(node, value);
}
void YGNodeStyleSetFlexBasisPercent(
const YGNodeRef node,
const float flexBasisPercent) {
auto value = detail::CompactValue::ofMaybe<YGUnitPercent>(flexBasisPercent);
updateStyleProp<detail::CompactValue, &YGStyle::flexBasis>(node, value);
updateStyle<detail::CompactValue, &YGStyle::flexBasis>(node, value);
}
void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) {
updateStyleProp<detail::CompactValue, &YGStyle::flexBasis>(
updateStyle<detail::CompactValue, &YGStyle::flexBasis>(
node, detail::CompactValue::ofAuto());
}
@@ -731,7 +725,7 @@ void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float percent) {
updateEdgeProp<&YGStyle::position>(node, edge, value);
}
YGValue YGNodeStyleGetPosition(YGNodeRef node, YGEdge edge) {
return node->getStyle().position[edge];
return static_cast<const YGNode*>(node)->getStyle().position()[edge];
}
void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) {
@@ -746,7 +740,7 @@ void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) {
updateEdgeProp<&YGStyle::margin>(node, edge, detail::CompactValue::ofAuto());
}
YGValue YGNodeStyleGetMargin(YGNodeRef node, YGEdge edge) {
return node->getStyle().margin[edge];
return static_cast<const YGNode*>(node)->getStyle().margin()[edge];
}
void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) {
@@ -758,7 +752,7 @@ void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) {
updateEdgeProp<&YGStyle::padding>(node, edge, value);
}
YGValue YGNodeStyleGetPadding(YGNodeRef node, YGEdge edge) {
return node->getStyle().padding[edge];
return static_cast<const YGNode*>(node)->getStyle().padding()[edge];
}
// TODO(T26792433): Change the API to accept YGFloatOptional.
@@ -771,14 +765,14 @@ void YGNodeStyleSetBorder(
}
float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) {
if (node->getStyle().border[edge].isUndefined() ||
node->getStyle().border[edge].isAuto()) {
const auto& style = node->getStyle();
if (style.border()[edge].isUndefined() || style.border()[edge].isAuto()) {
// TODO(T26792433): Rather than returning YGUndefined, change the api to
// return YGFloatOptional.
return YGUndefined;
}
auto border = (YGValue) node->getStyle().border[edge];
auto border = (YGValue) style.border()[edge];
return border.value;
}
@@ -786,13 +780,13 @@ float YGNodeStyleGetBorder(const YGNodeRef node, const YGEdge edge) {
// TODO(T26792433): Change the API to accept YGFloatOptional.
float YGNodeStyleGetAspectRatio(const YGNodeRef node) {
const YGFloatOptional op = node->getStyle().aspectRatio;
const YGFloatOptional op = node->getStyle().aspectRatio();
return op.isUndefined() ? YGUndefined : op.unwrap();
}
// TODO(T26792433): Change the API to accept YGFloatOptional.
void YGNodeStyleSetAspectRatio(const YGNodeRef node, const float aspectRatio) {
updateStyleProp<YGFloatOptional, &YGStyle::aspectRatio>(
updateStyle<YGFloatOptional, &YGStyle::aspectRatio>(
node, YGFloatOptional{aspectRatio});
}
@@ -809,7 +803,9 @@ void YGNodeStyleSetWidthAuto(YGNodeRef node) {
node, YGDimensionWidth, detail::CompactValue::ofAuto());
}
YGValue YGNodeStyleGetWidth(YGNodeRef node) {
return node->getStyle().dimensions[YGDimensionWidth];
return static_cast<const YGNode*>(node)
->getStyle()
.dimensions()[YGDimensionWidth];
}
void YGNodeStyleSetHeight(YGNodeRef node, float points) {
@@ -825,7 +821,9 @@ void YGNodeStyleSetHeightAuto(YGNodeRef node) {
node, YGDimensionHeight, detail::CompactValue::ofAuto());
}
YGValue YGNodeStyleGetHeight(YGNodeRef node) {
return node->getStyle().dimensions[YGDimensionHeight];
return static_cast<const YGNode*>(node)
->getStyle()
.dimensions()[YGDimensionHeight];
}
void YGNodeStyleSetMinWidth(const YGNodeRef node, const float minWidth) {
@@ -837,7 +835,9 @@ void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) {
updateDimensionProp<&YGStyle::minDimensions>(node, YGDimensionWidth, value);
}
YGValue YGNodeStyleGetMinWidth(const YGNodeRef node) {
return node->getStyle().minDimensions[YGDimensionWidth];
return static_cast<const YGNode*>(node)
->getStyle()
.minDimensions()[YGDimensionWidth];
};
void YGNodeStyleSetMinHeight(const YGNodeRef node, const float minHeight) {
@@ -851,7 +851,9 @@ void YGNodeStyleSetMinHeightPercent(
updateDimensionProp<&YGStyle::minDimensions>(node, YGDimensionHeight, value);
}
YGValue YGNodeStyleGetMinHeight(const YGNodeRef node) {
return node->getStyle().minDimensions[YGDimensionHeight];
return static_cast<const YGNode*>(node)
->getStyle()
.minDimensions()[YGDimensionHeight];
};
void YGNodeStyleSetMaxWidth(const YGNodeRef node, const float maxWidth) {
@@ -863,7 +865,9 @@ void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) {
updateDimensionProp<&YGStyle::maxDimensions>(node, YGDimensionWidth, value);
}
YGValue YGNodeStyleGetMaxWidth(const YGNodeRef node) {
return node->getStyle().maxDimensions[YGDimensionWidth];
return static_cast<const YGNode*>(node)
->getStyle()
.maxDimensions()[YGDimensionWidth];
};
void YGNodeStyleSetMaxHeight(const YGNodeRef node, const float maxHeight) {
@@ -877,7 +881,9 @@ void YGNodeStyleSetMaxHeightPercent(
updateDimensionProp<&YGStyle::maxDimensions>(node, YGDimensionHeight, value);
}
YGValue YGNodeStyleGetMaxHeight(const YGNodeRef node) {
return node->getStyle().maxDimensions[YGDimensionHeight];
return static_cast<const YGNode*>(node)
->getStyle()
.maxDimensions()[YGDimensionHeight];
};
#define YG_NODE_LAYOUT_PROPERTY_IMPL(type, name, instanceName) \
@@ -983,14 +989,12 @@ static inline float YGNodePaddingAndBorderForAxis(
.unwrap();
}
static inline YGAlign YGNodeAlignItem(
const YGNodeRef node,
const YGNodeRef child) {
const YGAlign align = child->getStyle().alignSelf == YGAlignAuto
? node->getStyle().alignItems
: child->getStyle().alignSelf;
static inline YGAlign YGNodeAlignItem(const YGNode* node, const YGNode* child) {
const YGAlign align = child->getStyle().alignSelf() == YGAlignAuto
? node->getStyle().alignItems()
: child->getStyle().alignSelf();
if (align == YGAlignBaseline &&
YGFlexDirectionIsColumn(node->getStyle().flexDirection)) {
YGFlexDirectionIsColumn(node->getStyle().flexDirection())) {
return YGAlignFlexStart;
}
return align;
@@ -1018,7 +1022,7 @@ static float YGBaseline(const YGNodeRef node, void* layoutContext) {
if (child->getLineIndex() > 0) {
break;
}
if (child->getStyle().positionType == YGPositionTypeAbsolute) {
if (child->getStyle().positionType() == YGPositionTypeAbsolute) {
continue;
}
if (YGNodeAlignItem(node, child) == YGAlignBaseline ||
@@ -1041,17 +1045,17 @@ static float YGBaseline(const YGNodeRef node, void* layoutContext) {
}
static bool YGIsBaselineLayout(const YGNodeRef node) {
if (YGFlexDirectionIsColumn(node->getStyle().flexDirection)) {
if (YGFlexDirectionIsColumn(node->getStyle().flexDirection())) {
return false;
}
if (node->getStyle().alignItems == YGAlignBaseline) {
if (node->getStyle().alignItems() == YGAlignBaseline) {
return true;
}
const uint32_t childCount = YGNodeGetChildCount(node);
for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = YGNodeGetChild(node, i);
if (child->getStyle().positionType == YGPositionTypeRelative &&
child->getStyle().alignSelf == YGAlignBaseline) {
if (child->getStyle().positionType() == YGPositionTypeRelative &&
child->getStyle().alignSelf() == YGAlignBaseline) {
return true;
}
}
@@ -1103,14 +1107,14 @@ static YGFloatOptional YGNodeBoundAxisWithinMinAndMax(
if (YGFlexDirectionIsColumn(axis)) {
min = YGResolveValue(
node->getStyle().minDimensions[YGDimensionHeight], axisSize);
node->getStyle().minDimensions()[YGDimensionHeight], axisSize);
max = YGResolveValue(
node->getStyle().maxDimensions[YGDimensionHeight], axisSize);
node->getStyle().maxDimensions()[YGDimensionHeight], axisSize);
} else if (YGFlexDirectionIsRow(axis)) {
min = YGResolveValue(
node->getStyle().minDimensions[YGDimensionWidth], axisSize);
node->getStyle().minDimensions()[YGDimensionWidth], axisSize);
max = YGResolveValue(
node->getStyle().maxDimensions[YGDimensionWidth], axisSize);
node->getStyle().maxDimensions()[YGDimensionWidth], axisSize);
}
if (max >= YGFloatOptional{0} && value > max) {
@@ -1158,7 +1162,8 @@ static void YGConstrainMaxSizeForMode(
YGMeasureMode* mode,
float* size) {
const YGFloatOptional maxSize =
YGResolveValue(node->getStyle().maxDimensions[dim[axis]], ownerAxisSize) +
YGResolveValue(
node->getStyle().maxDimensions()[dim[axis]], ownerAxisSize) +
YGFloatOptional(node->getMarginForAxis(axis, ownerWidth));
switch (*mode) {
case YGMeasureModeExactly:
@@ -1190,7 +1195,7 @@ static void YGNodeComputeFlexBasisForChild(
YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) {
const YGFlexDirection mainAxis =
YGResolveFlexDirection(node->getStyle().flexDirection, direction);
YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
const float mainAxisSize = isMainAxisRow ? width : height;
const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight;
@@ -1225,7 +1230,7 @@ static void YGNodeComputeFlexBasisForChild(
child->setLayoutComputedFlexBasis(YGFloatOptionalMax(
YGResolveValue(
child->getResolvedDimension(YGDimensionWidth), ownerWidth),
child->getResolvedDimensions()[YGDimensionWidth], ownerWidth),
paddingAndBorder));
} else if (!isMainAxisRow && isColumnStyleDimDefined) {
// The height is definite, so use that as the flex basis.
@@ -1234,7 +1239,7 @@ static void YGNodeComputeFlexBasisForChild(
child, YGFlexDirectionColumn, ownerWidth));
child->setLayoutComputedFlexBasis(YGFloatOptionalMax(
YGResolveValue(
child->getResolvedDimension(YGDimensionHeight), ownerHeight),
child->getResolvedDimensions()[YGDimensionHeight], ownerHeight),
paddingAndBorder));
} else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex
@@ -1252,7 +1257,7 @@ static void YGNodeComputeFlexBasisForChild(
if (isRowStyleDimDefined) {
childWidth =
YGResolveValue(
child->getResolvedDimension(YGDimensionWidth), ownerWidth)
child->getResolvedDimensions()[YGDimensionWidth], ownerWidth)
.unwrap() +
marginRow;
childWidthMeasureMode = YGMeasureModeExactly;
@@ -1260,7 +1265,7 @@ static void YGNodeComputeFlexBasisForChild(
if (isColumnStyleDimDefined) {
childHeight =
YGResolveValue(
child->getResolvedDimension(YGDimensionHeight), ownerHeight)
child->getResolvedDimensions()[YGDimensionHeight], ownerHeight)
.unwrap() +
marginColumn;
childHeightMeasureMode = YGMeasureModeExactly;
@@ -1268,32 +1273,32 @@ static void YGNodeComputeFlexBasisForChild(
// The W3C spec doesn't say anything about the 'overflow' property, but all
// major browsers appear to implement the following logic.
if ((!isMainAxisRow && node->getStyle().overflow == YGOverflowScroll) ||
node->getStyle().overflow != YGOverflowScroll) {
if ((!isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
node->getStyle().overflow() != YGOverflowScroll) {
if (YGFloatIsUndefined(childWidth) && !YGFloatIsUndefined(width)) {
childWidth = width;
childWidthMeasureMode = YGMeasureModeAtMost;
}
}
if ((isMainAxisRow && node->getStyle().overflow == YGOverflowScroll) ||
node->getStyle().overflow != YGOverflowScroll) {
if ((isMainAxisRow && node->getStyle().overflow() == YGOverflowScroll) ||
node->getStyle().overflow() != YGOverflowScroll) {
if (YGFloatIsUndefined(childHeight) && !YGFloatIsUndefined(height)) {
childHeight = height;
childHeightMeasureMode = YGMeasureModeAtMost;
}
}
if (!child->getStyle().aspectRatio.isUndefined()) {
const auto& childStyle = child->getStyle();
if (!childStyle.aspectRatio().isUndefined()) {
if (!isMainAxisRow && childWidthMeasureMode == YGMeasureModeExactly) {
childHeight = marginColumn +
(childWidth - marginRow) / child->getStyle().aspectRatio.unwrap();
(childWidth - marginRow) / childStyle.aspectRatio().unwrap();
childHeightMeasureMode = YGMeasureModeExactly;
} else if (
isMainAxisRow && childHeightMeasureMode == YGMeasureModeExactly) {
childWidth = marginRow +
(childHeight - marginColumn) *
child->getStyle().aspectRatio.unwrap();
(childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
childWidthMeasureMode = YGMeasureModeExactly;
}
}
@@ -1310,9 +1315,9 @@ static void YGNodeComputeFlexBasisForChild(
childWidthStretch) {
childWidth = width;
childWidthMeasureMode = YGMeasureModeExactly;
if (!child->getStyle().aspectRatio.isUndefined()) {
if (!childStyle.aspectRatio().isUndefined()) {
childHeight =
(childWidth - marginRow) / child->getStyle().aspectRatio.unwrap();
(childWidth - marginRow) / childStyle.aspectRatio().unwrap();
childHeightMeasureMode = YGMeasureModeExactly;
}
}
@@ -1327,9 +1332,9 @@ static void YGNodeComputeFlexBasisForChild(
childHeight = height;
childHeightMeasureMode = YGMeasureModeExactly;
if (!child->getStyle().aspectRatio.isUndefined()) {
childWidth = (childHeight - marginColumn) *
child->getStyle().aspectRatio.unwrap();
if (!childStyle.aspectRatio().isUndefined()) {
childWidth =
(childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
childWidthMeasureMode = YGMeasureModeExactly;
}
}
@@ -1383,7 +1388,7 @@ static void YGNodeAbsoluteLayoutChild(
YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) {
const YGFlexDirection mainAxis =
YGResolveFlexDirection(node->getStyle().flexDirection, direction);
YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
@@ -1398,7 +1403,7 @@ static void YGNodeAbsoluteLayoutChild(
if (YGNodeIsStyleDimDefined(child, YGFlexDirectionRow, width)) {
childWidth =
YGResolveValue(child->getResolvedDimension(YGDimensionWidth), width)
YGResolveValue(child->getResolvedDimensions()[YGDimensionWidth], width)
.unwrap() +
marginRow;
} else {
@@ -1418,9 +1423,9 @@ static void YGNodeAbsoluteLayoutChild(
}
if (YGNodeIsStyleDimDefined(child, YGFlexDirectionColumn, height)) {
childHeight =
YGResolveValue(child->getResolvedDimension(YGDimensionHeight), height)
.unwrap() +
childHeight = YGResolveValue(
child->getResolvedDimensions()[YGDimensionHeight], height)
.unwrap() +
marginColumn;
} else {
// If the child doesn't have a specified height, compute the height based on
@@ -1441,15 +1446,15 @@ static void YGNodeAbsoluteLayoutChild(
// Exactly one dimension needs to be defined for us to be able to do aspect
// ratio calculation. One dimension being the anchor and the other being
// flexible.
const auto& childStyle = child->getStyle();
if (YGFloatIsUndefined(childWidth) ^ YGFloatIsUndefined(childHeight)) {
if (!child->getStyle().aspectRatio.isUndefined()) {
if (!childStyle.aspectRatio().isUndefined()) {
if (YGFloatIsUndefined(childWidth)) {
childWidth = marginRow +
(childHeight - marginColumn) *
child->getStyle().aspectRatio.unwrap();
(childHeight - marginColumn) * childStyle.aspectRatio().unwrap();
} else if (YGFloatIsUndefined(childHeight)) {
childHeight = marginColumn +
(childWidth - marginRow) / child->getStyle().aspectRatio.unwrap();
(childWidth - marginRow) / childStyle.aspectRatio().unwrap();
}
}
}
@@ -1521,7 +1526,7 @@ static void YGNodeAbsoluteLayoutChild(
leading[mainAxis]);
} else if (
!child->isLeadingPositionDefined(mainAxis) &&
node->getStyle().justifyContent == YGJustifyCenter) {
node->getStyle().justifyContent() == YGJustifyCenter) {
child->setLayoutPosition(
(node->getLayout().measuredDimensions[dim[mainAxis]] -
child->getLayout().measuredDimensions[dim[mainAxis]]) /
@@ -1529,7 +1534,7 @@ static void YGNodeAbsoluteLayoutChild(
leading[mainAxis]);
} else if (
!child->isLeadingPositionDefined(mainAxis) &&
node->getStyle().justifyContent == YGJustifyFlexEnd) {
node->getStyle().justifyContent() == YGJustifyFlexEnd) {
child->setLayoutPosition(
(node->getLayout().measuredDimensions[dim[mainAxis]] -
child->getLayout().measuredDimensions[dim[mainAxis]]),
@@ -1559,7 +1564,7 @@ static void YGNodeAbsoluteLayoutChild(
} else if (
!child->isLeadingPositionDefined(crossAxis) &&
((YGNodeAlignItem(node, child) == YGAlignFlexEnd) ^
(node->getStyle().flexWrap == YGWrapWrapReverse))) {
(node->getStyle().flexWrap() == YGWrapWrapReverse))) {
child->setLayoutPosition(
(node->getLayout().measuredDimensions[dim[crossAxis]] -
child->getLayout().measuredDimensions[dim[crossAxis]]),
@@ -1782,13 +1787,13 @@ static float YGNodeCalculateAvailableInnerDim(
// We want to make sure our available height does not violate min and max
// constraints
const YGFloatOptional minDimensionOptional =
YGResolveValue(node->getStyle().minDimensions[dimension], ownerDim);
YGResolveValue(node->getStyle().minDimensions()[dimension], ownerDim);
const float minInnerDim = minDimensionOptional.isUndefined()
? 0.0f
: minDimensionOptional.unwrap() - paddingAndBorder;
const YGFloatOptional maxDimensionOptional =
YGResolveValue(node->getStyle().maxDimensions[dimension], ownerDim);
YGResolveValue(node->getStyle().maxDimensions()[dimension], ownerDim);
const float maxInnerDim = maxDimensionOptional.isUndefined()
? FLT_MAX
@@ -1839,7 +1844,7 @@ static float YGNodeComputeFlexBasisForChildren(
for (auto child : children) {
child->resolveDimension();
if (child->getStyle().display == YGDisplayNone) {
if (child->getStyle().display() == YGDisplayNone) {
YGZeroOutLayoutRecursivly(child, layoutContext);
child->setHasNewLayout(true);
child->setDirty(false);
@@ -1858,7 +1863,7 @@ static float YGNodeComputeFlexBasisForChildren(
childDirection, mainDim, crossDim, availableInnerWidth);
}
if (child->getStyle().positionType == YGPositionTypeAbsolute) {
if (child->getStyle().positionType() == YGPositionTypeAbsolute) {
continue;
}
if (child == singleFlexChild) {
@@ -1906,15 +1911,15 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
float sizeConsumedOnCurrentLineIncludingMinConstraint = 0;
const YGFlexDirection mainAxis = YGResolveFlexDirection(
node->getStyle().flexDirection, node->resolveDirection(ownerDirection));
const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap;
node->getStyle().flexDirection(), node->resolveDirection(ownerDirection));
const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
// Add items to the current line until it's full or we run out of items.
uint32_t endOfLineIndex = startOfLineIndex;
for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) {
const YGNodeRef child = node->getChild(endOfLineIndex);
if (child->getStyle().display == YGDisplayNone ||
child->getStyle().positionType == YGPositionTypeAbsolute) {
if (child->getStyle().display() == YGDisplayNone ||
child->getStyle().positionType() == YGPositionTypeAbsolute) {
continue;
}
child->setLineIndex(lineCount);
@@ -1997,7 +2002,7 @@ static float YGDistributeFreeSpaceSecondPass(
float flexGrowFactor = 0;
float deltaFreeSpace = 0;
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap;
const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
for (auto currentRelativeChild : collectedFlexItemsValues.relativeChildren) {
childFlexBasis = YGNodeBoundAxisWithinMinAndMax(
@@ -2067,11 +2072,11 @@ static float YGDistributeFreeSpaceSecondPass(
YGMeasureMode childCrossMeasureMode;
YGMeasureMode childMainMeasureMode = YGMeasureModeExactly;
if (!currentRelativeChild->getStyle().aspectRatio.isUndefined()) {
childCrossSize = isMainAxisRow ? (childMainSize - marginMain) /
currentRelativeChild->getStyle().aspectRatio.unwrap()
: (childMainSize - marginMain) *
currentRelativeChild->getStyle().aspectRatio.unwrap();
const auto& childStyle = currentRelativeChild->getStyle();
if (!childStyle.aspectRatio().isUndefined()) {
childCrossSize = isMainAxisRow
? (childMainSize - marginMain) / childStyle.aspectRatio().unwrap()
: (childMainSize - marginMain) * childStyle.aspectRatio().unwrap();
childCrossMeasureMode = YGMeasureModeExactly;
childCrossSize += marginCross;
@@ -2335,7 +2340,7 @@ static void YGJustifyMainAxis(
const float availableInnerWidth,
const bool performLayout,
void* const layoutContext) {
const YGStyle& style = node->getStyle();
const auto& style = node->getStyle();
const float leadingPaddingAndBorderMain =
node->getLeadingPaddingAndBorder(mainAxis, ownerWidth).unwrap();
const float trailingPaddingAndBorderMain =
@@ -2344,8 +2349,8 @@ static void YGJustifyMainAxis(
// remainingFreeSpace is 0 when min main dimension is not given
if (measureModeMainDim == YGMeasureModeAtMost &&
collectedFlexItemsValues.remainingFreeSpace > 0) {
if (!style.minDimensions[dim[mainAxis]].isUndefined() &&
!YGResolveValue(style.minDimensions[dim[mainAxis]], mainAxisownerSize)
if (!style.minDimensions()[dim[mainAxis]].isUndefined() &&
!YGResolveValue(style.minDimensions()[dim[mainAxis]], mainAxisownerSize)
.isUndefined()) {
// This condition makes sure that if the size of main dimension(after
// considering child nodes main dim, leading and trailing padding etc)
@@ -2355,7 +2360,8 @@ static void YGJustifyMainAxis(
// `minAvailableMainDim` denotes minimum available space in which child
// can be laid out, it will exclude space consumed by padding and border.
const float minAvailableMainDim =
YGResolveValue(style.minDimensions[dim[mainAxis]], mainAxisownerSize)
YGResolveValue(
style.minDimensions()[dim[mainAxis]], mainAxisownerSize)
.unwrap() -
leadingPaddingAndBorderMain - trailingPaddingAndBorderMain;
const float occupiedSpaceByChildNodes =
@@ -2372,7 +2378,7 @@ static void YGJustifyMainAxis(
i < collectedFlexItemsValues.endOfLineIndex;
i++) {
const YGNodeRef child = node->getChild(i);
if (child->getStyle().positionType == YGPositionTypeRelative) {
if (child->getStyle().positionType() == YGPositionTypeRelative) {
if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
numberOfAutoMarginsOnCurrentLine++;
}
@@ -2387,7 +2393,7 @@ static void YGJustifyMainAxis(
// each two elements.
float leadingMainDim = 0;
float betweenMainDim = 0;
const YGJustify justifyContent = node->getStyle().justifyContent;
const YGJustify justifyContent = node->getStyle().justifyContent();
if (numberOfAutoMarginsOnCurrentLine == 0) {
switch (justifyContent) {
@@ -2436,10 +2442,10 @@ static void YGJustifyMainAxis(
const YGNodeRef child = node->getChild(i);
const YGStyle& childStyle = child->getStyle();
const YGLayout childLayout = child->getLayout();
if (childStyle.display == YGDisplayNone) {
if (childStyle.display() == YGDisplayNone) {
continue;
}
if (childStyle.positionType == YGPositionTypeAbsolute &&
if (childStyle.positionType() == YGPositionTypeAbsolute &&
child->isLeadingPositionDefined(mainAxis)) {
if (performLayout) {
// In case the child is position absolute and has left/top being
@@ -2456,7 +2462,7 @@ static void YGJustifyMainAxis(
// Now that we placed the element, we need to update the variables.
// We need to do that only for relative elements. Absolute elements do not
// take part in that phase.
if (childStyle.positionType == YGPositionTypeRelative) {
if (childStyle.positionType() == YGPositionTypeRelative) {
if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
collectedFlexItemsValues.mainDim +=
collectedFlexItemsValues.remainingFreeSpace /
@@ -2720,10 +2726,10 @@ static void YGNodelayoutImpl(
// STEP 1: CALCULATE VALUES FOR REMAINDER OF ALGORITHM
const YGFlexDirection mainAxis =
YGResolveFlexDirection(node->getStyle().flexDirection, direction);
YGResolveFlexDirection(node->getStyle().flexDirection(), direction);
const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
const bool isNodeFlexWrap = node->getStyle().flexWrap != YGWrapNoWrap;
const bool isNodeFlexWrap = node->getStyle().flexWrap() != YGWrapNoWrap;
const float mainAxisownerSize = isMainAxisRow ? ownerWidth : ownerHeight;
const float crossAxisownerSize = isMainAxisRow ? ownerHeight : ownerWidth;
@@ -2752,22 +2758,22 @@ static void YGNodelayoutImpl(
const float minInnerWidth =
YGResolveValue(
node->getStyle().minDimensions[YGDimensionWidth], ownerWidth)
node->getStyle().minDimensions()[YGDimensionWidth], ownerWidth)
.unwrap() -
paddingAndBorderAxisRow;
const float maxInnerWidth =
YGResolveValue(
node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)
node->getStyle().maxDimensions()[YGDimensionWidth], ownerWidth)
.unwrap() -
paddingAndBorderAxisRow;
const float minInnerHeight =
YGResolveValue(
node->getStyle().minDimensions[YGDimensionHeight], ownerHeight)
node->getStyle().minDimensions()[YGDimensionHeight], ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn;
const float maxInnerHeight =
YGResolveValue(
node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)
node->getStyle().maxDimensions()[YGDimensionHeight], ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn;
@@ -2971,10 +2977,10 @@ static void YGNodelayoutImpl(
if (performLayout) {
for (uint32_t i = startOfLineIndex; i < endOfLineIndex; i++) {
const YGNodeRef child = node->getChild(i);
if (child->getStyle().display == YGDisplayNone) {
if (child->getStyle().display() == YGDisplayNone) {
continue;
}
if (child->getStyle().positionType == YGPositionTypeAbsolute) {
if (child->getStyle().positionType() == YGPositionTypeAbsolute) {
// If the child is absolutely positioned and has a
// top/left/bottom/right set, override all the previously computed
// positions to set it correctly.
@@ -3019,14 +3025,13 @@ static void YGNodelayoutImpl(
child, crossAxis, availableInnerCrossDim)) {
float childMainSize =
child->getLayout().measuredDimensions[dim[mainAxis]];
float childCrossSize =
!child->getStyle().aspectRatio.isUndefined()
const auto& childStyle = child->getStyle();
float childCrossSize = !childStyle.aspectRatio().isUndefined()
? child->getMarginForAxis(crossAxis, availableInnerWidth)
.unwrap() +
(isMainAxisRow ? childMainSize /
child->getStyle().aspectRatio.unwrap()
: childMainSize *
child->getStyle().aspectRatio.unwrap())
(isMainAxisRow
? childMainSize / childStyle.aspectRatio().unwrap()
: childMainSize * childStyle.aspectRatio().unwrap())
: collectedFlexItemsValues.crossDim;
childMainSize +=
@@ -3055,7 +3060,7 @@ static void YGNodelayoutImpl(
const float childHeight =
!isMainAxisRow ? childMainSize : childCrossSize;
auto alignContent = node->getStyle().alignContent;
auto alignContent = node->getStyle().alignContent();
auto crossAxisDoesNotGrow =
alignContent != YGAlignStretch && isNodeFlexWrap;
const YGMeasureMode childWidthMeasureMode =
@@ -3127,7 +3132,7 @@ static void YGNodelayoutImpl(
if (!YGFloatIsUndefined(availableInnerCrossDim)) {
const float remainingAlignContentDim =
availableInnerCrossDim - totalLineCrossDim;
switch (node->getStyle().alignContent) {
switch (node->getStyle().alignContent()) {
case YGAlignFlexEnd:
currentLead += remainingAlignContentDim;
break;
@@ -3171,10 +3176,10 @@ static void YGNodelayoutImpl(
float maxDescentForCurrentLine = 0;
for (ii = startIndex; ii < childCount; ii++) {
const YGNodeRef child = node->getChild(ii);
if (child->getStyle().display == YGDisplayNone) {
if (child->getStyle().display() == YGDisplayNone) {
continue;
}
if (child->getStyle().positionType == YGPositionTypeRelative) {
if (child->getStyle().positionType() == YGPositionTypeRelative) {
if (child->getLineIndex() != i) {
break;
}
@@ -3213,10 +3218,10 @@ static void YGNodelayoutImpl(
if (performLayout) {
for (ii = startIndex; ii < endIndex; ii++) {
const YGNodeRef child = node->getChild(ii);
if (child->getStyle().display == YGDisplayNone) {
if (child->getStyle().display() == YGDisplayNone) {
continue;
}
if (child->getStyle().positionType == YGPositionTypeRelative) {
if (child->getStyle().positionType() == YGPositionTypeRelative) {
switch (YGNodeAlignItem(node, child)) {
case YGAlignFlexStart: {
child->setLayoutPosition(
@@ -3342,7 +3347,7 @@ static void YGNodelayoutImpl(
// If the user didn't specify a width or height for the node, set the
// dimensions based on the children.
if (measureModeMainDim == YGMeasureModeUndefined ||
(node->getStyle().overflow != YGOverflowScroll &&
(node->getStyle().overflow() != YGOverflowScroll &&
measureModeMainDim == YGMeasureModeAtMost)) {
// Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount.
@@ -3353,7 +3358,7 @@ static void YGNodelayoutImpl(
} else if (
measureModeMainDim == YGMeasureModeAtMost &&
node->getStyle().overflow == YGOverflowScroll) {
node->getStyle().overflow() == YGOverflowScroll) {
node->setLayoutMeasuredDimension(
YGFloatMax(
YGFloatMin(
@@ -3369,7 +3374,7 @@ static void YGNodelayoutImpl(
}
if (measureModeCrossDim == YGMeasureModeUndefined ||
(node->getStyle().overflow != YGOverflowScroll &&
(node->getStyle().overflow() != YGOverflowScroll &&
measureModeCrossDim == YGMeasureModeAtMost)) {
// Clamp the size to the min/max size, if specified, and make sure it
// doesn't go below the padding and border amount.
@@ -3384,7 +3389,7 @@ static void YGNodelayoutImpl(
} else if (
measureModeCrossDim == YGMeasureModeAtMost &&
node->getStyle().overflow == YGOverflowScroll) {
node->getStyle().overflow() == YGOverflowScroll) {
node->setLayoutMeasuredDimension(
YGFloatMax(
YGFloatMin(
@@ -3402,10 +3407,10 @@ static void YGNodelayoutImpl(
// As we only wrapped in normal direction yet, we need to reverse the
// positions on wrap-reverse.
if (performLayout && node->getStyle().flexWrap == YGWrapWrapReverse) {
if (performLayout && node->getStyle().flexWrap() == YGWrapWrapReverse) {
for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = YGNodeGetChild(node, i);
if (child->getStyle().positionType == YGPositionTypeRelative) {
if (child->getStyle().positionType() == YGPositionTypeRelative) {
child->setLayoutPosition(
node->getLayout().measuredDimensions[dim[crossAxis]] -
child->getLayout().position[pos[crossAxis]] -
@@ -3418,7 +3423,7 @@ static void YGNodelayoutImpl(
if (performLayout) {
// STEP 10: SIZING AND POSITIONING ABSOLUTE CHILDREN
for (auto child : node->getChildren()) {
if (child->getStyle().positionType != YGPositionTypeAbsolute) {
if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
continue;
}
YGNodeAbsoluteLayoutChild(
@@ -3443,7 +3448,7 @@ static void YGNodelayoutImpl(
if (needsMainTrailingPos || needsCrossTrailingPos) {
for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = node->getChild(i);
if (child->getStyle().display == YGDisplayNone) {
if (child->getStyle().display() == YGDisplayNone) {
continue;
}
if (needsMainTrailingPos) {
@@ -4014,10 +4019,11 @@ void YGNodeCalculateLayoutWithContext(
.unwrap();
widthMeasureMode = YGMeasureModeExactly;
} else if (!YGResolveValue(
node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)
node->getStyle().maxDimensions()[YGDimensionWidth],
ownerWidth)
.isUndefined()) {
width = YGResolveValue(
node->getStyle().maxDimensions[YGDimensionWidth], ownerWidth)
node->getStyle().maxDimensions()[YGDimensionWidth], ownerWidth)
.unwrap();
widthMeasureMode = YGMeasureModeAtMost;
} else {
@@ -4036,12 +4042,13 @@ void YGNodeCalculateLayoutWithContext(
.unwrap();
heightMeasureMode = YGMeasureModeExactly;
} else if (!YGResolveValue(
node->getStyle().maxDimensions[YGDimensionHeight],
node->getStyle().maxDimensions()[YGDimensionHeight],
ownerHeight)
.isUndefined()) {
height = YGResolveValue(
node->getStyle().maxDimensions[YGDimensionHeight], ownerHeight)
.unwrap();
height =
YGResolveValue(
node->getStyle().maxDimensions()[YGDimensionHeight], ownerHeight)
.unwrap();
heightMeasureMode = YGMeasureModeAtMost;
} else {
height = ownerHeight;