Revert D50998164: Allow lazy resolution of edge dimension values

Differential Revision:
D50998164

Original commit changeset: 248396f9587e

Original Phabricator Diff: D50998164

fbshipit-source-id: 4f592158324d758bb9e3731ced36b8e3587c459c
This commit is contained in:
Nick Gerleman
2023-11-15 18:34:47 -08:00
committed by Facebook GitHub Bot
parent 88233cf549
commit 5d55c8eeb5
21 changed files with 612 additions and 827 deletions
@@ -134,8 +134,8 @@ using namespace facebook::react;
props.accessible = true;
auto &yogaStyle = props.yogaStyle;
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(0));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(0));
yogaStyle.position()[YGEdgeLeft] = YGValue{0, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{0, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(200));
return sharedProps;
@@ -214,8 +214,8 @@ using namespace facebook::react;
props.accessible = true;
auto &yogaStyle = props.yogaStyle;
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(0));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(30));
yogaStyle.position()[YGEdgeLeft] = YGValue{0, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{30, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(50));
return sharedProps;
@@ -258,8 +258,8 @@ using namespace facebook::react;
props.accessible = true;
auto &yogaStyle = props.yogaStyle;
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(0));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(90));
yogaStyle.position()[YGEdgeLeft] = YGValue{0, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{90, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(50));
return sharedProps;
@@ -432,8 +432,8 @@ static ParagraphShadowNode::ConcreteState::Shared stateWithShadowNode(
props.accessibilityTraits = AccessibilityTraits::Link;
auto &yogaStyle = props.yogaStyle;
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(0));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(0));
yogaStyle.position()[YGEdgeLeft] = YGValue{0, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{0, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(200));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(20));
return sharedProps;
@@ -20,12 +20,12 @@ class SafeAreaViewComponentDescriptor final
: public ConcreteComponentDescriptor<SafeAreaViewShadowNode> {
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
void adopt(ShadowNode& shadowNode) const override {
auto& yogaLayoutableShadowNode =
auto& layoutableShadowNode =
static_cast<YogaLayoutableShadowNode&>(shadowNode);
auto& stateData = static_cast<const SafeAreaViewShadowNode::ConcreteState&>(
*shadowNode.getState())
.getData();
yogaLayoutableShadowNode.setPadding(stateData.padding);
layoutableShadowNode.setPadding(stateData.padding);
ConcreteComponentDescriptor::adopt(shadowNode);
}
@@ -40,7 +40,7 @@ class AndroidTextInputComponentDescriptor final
const ShadowNodeFamily::Shared& family) const override {
int surfaceId = family->getSurfaceId();
ThemePadding theme;
yoga::Style::Edges theme;
// TODO: figure out RTL/start/end/left/right stuff here
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
surfaceIdToThemePaddingMap_.end()) {
@@ -59,16 +59,11 @@ class AndroidTextInputComponentDescriptor final
fabricUIManager, surfaceId, defaultTextInputPaddingArray)) {
jfloat* defaultTextInputPadding =
env->GetFloatArrayElements(defaultTextInputPaddingArray, 0);
theme.start =
yoga::CompactValue::of<YGUnitPoint>(defaultTextInputPadding[0]);
theme.end =
yoga::CompactValue::of<YGUnitPoint>(defaultTextInputPadding[1]);
theme.top =
yoga::CompactValue::of<YGUnitPoint>(defaultTextInputPadding[2]);
theme.bottom =
yoga::CompactValue::of<YGUnitPoint>(defaultTextInputPadding[3]);
theme[YGEdgeStart] = (YGValue){defaultTextInputPadding[0], YGUnitPoint};
theme[YGEdgeEnd] = (YGValue){defaultTextInputPadding[1], YGUnitPoint};
theme[YGEdgeTop] = (YGValue){defaultTextInputPadding[2], YGUnitPoint};
theme[YGEdgeBottom] =
(YGValue){defaultTextInputPadding[3], YGUnitPoint};
surfaceIdToThemePaddingMap_.emplace(std::make_pair(surfaceId, theme));
env->ReleaseFloatArrayElements(
defaultTextInputPaddingArray, defaultTextInputPadding, JNI_ABORT);
@@ -82,10 +77,10 @@ class AndroidTextInputComponentDescriptor final
{},
{},
{},
((YGValue)theme.start).value,
((YGValue)theme.end).value,
((YGValue)theme.top).value,
((YGValue)theme.bottom).value)),
((YGValue)theme[YGEdgeStart]).value,
((YGValue)theme[YGEdgeEnd]).value,
((YGValue)theme[YGEdgeTop]).value,
((YGValue)theme[YGEdgeBottom]).value)),
family);
}
@@ -104,7 +99,7 @@ class AndroidTextInputComponentDescriptor final
int surfaceId = textInputShadowNode.getSurfaceId();
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
surfaceIdToThemePaddingMap_.end()) {
ThemePadding theme = surfaceIdToThemePaddingMap_[surfaceId];
yoga::Style::Edges theme = surfaceIdToThemePaddingMap_[surfaceId];
auto& textInputProps = textInputShadowNode.getConcreteProps();
@@ -113,34 +108,29 @@ class AndroidTextInputComponentDescriptor final
// TODO: T62959168 account for RTL and paddingLeft when setting default
// paddingStart, and vice-versa with paddingRight/paddingEnd.
// For now this assumes no RTL.
ThemePadding result{
.start = textInputProps.yogaStyle.padding(YGEdgeStart),
.end = textInputProps.yogaStyle.padding(YGEdgeEnd),
.top = textInputProps.yogaStyle.padding(YGEdgeTop),
.bottom = textInputProps.yogaStyle.padding(YGEdgeBottom)};
yoga::Style::Edges result = textInputProps.yogaStyle.padding();
bool changedPadding = false;
if (!textInputProps.hasPadding && !textInputProps.hasPaddingStart &&
!textInputProps.hasPaddingLeft &&
!textInputProps.hasPaddingHorizontal) {
changedPadding = true;
result.start = theme.start;
result[YGEdgeStart] = theme[YGEdgeStart];
}
if (!textInputProps.hasPadding && !textInputProps.hasPaddingEnd &&
!textInputProps.hasPaddingRight &&
!textInputProps.hasPaddingHorizontal) {
changedPadding = true;
result.end = theme.end;
result[YGEdgeEnd] = theme[YGEdgeEnd];
}
if (!textInputProps.hasPadding && !textInputProps.hasPaddingTop &&
!textInputProps.hasPaddingVertical) {
changedPadding = true;
result.top = theme.top;
result[YGEdgeTop] = theme[YGEdgeTop];
}
if (!textInputProps.hasPadding && !textInputProps.hasPaddingBottom &&
!textInputProps.hasPaddingVertical) {
changedPadding = true;
result.bottom = theme.bottom;
result[YGEdgeBottom] = theme[YGEdgeBottom];
}
// If the TextInput initially does not have paddingLeft or paddingStart, a
@@ -151,12 +141,12 @@ class AndroidTextInputComponentDescriptor final
if ((textInputProps.hasPadding || textInputProps.hasPaddingLeft ||
textInputProps.hasPaddingHorizontal) &&
!textInputProps.hasPaddingStart) {
result.start = yoga::CompactValue::ofUndefined();
result[YGEdgeStart] = YGValueUndefined;
}
if ((textInputProps.hasPadding || textInputProps.hasPaddingRight ||
textInputProps.hasPaddingHorizontal) &&
!textInputProps.hasPaddingEnd) {
result.end = yoga::CompactValue::ofUndefined();
result[YGEdgeEnd] = YGValueUndefined;
}
// Note that this is expensive: on every adopt, we need to set the Yoga
@@ -164,13 +154,8 @@ class AndroidTextInputComponentDescriptor final
// commit, state update, etc, will incur this cost.
if (changedPadding) {
// Set new props on node
yoga::Style& style =
const_cast<AndroidTextInputProps&>(textInputProps).yogaStyle;
style.setPadding(YGEdgeStart, result.start);
style.setPadding(YGEdgeEnd, result.end);
style.setPadding(YGEdgeTop, result.top);
style.setPadding(YGEdgeBottom, result.bottom);
const_cast<AndroidTextInputProps&>(textInputProps).yogaStyle.padding() =
result;
// Communicate new props to Yoga part of the node
textInputShadowNode.updateYogaProps();
}
@@ -183,19 +168,13 @@ class AndroidTextInputComponentDescriptor final
}
private:
struct ThemePadding {
yoga::CompactValue start;
yoga::CompactValue end;
yoga::CompactValue top;
yoga::CompactValue bottom;
};
// TODO T68526882: Unify with Binding::UIManagerJavaDescriptor
constexpr static auto UIManagerJavaDescriptor =
"com/facebook/react/fabric/FabricUIManager";
SharedTextLayoutManager textLayoutManager_;
mutable std::unordered_map<int, ThemePadding> surfaceIdToThemePaddingMap_;
mutable std::unordered_map<int, yoga::Style::Edges>
surfaceIdToThemePaddingMap_;
};
} // namespace facebook::react
@@ -358,20 +358,20 @@ BorderMetrics BaseViewProps::resolveBorderMetrics(
bool{layoutMetrics.layoutDirection == LayoutDirection::RightToLeft};
auto borderWidths = CascadedBorderWidths{
/* .left = */ optionalFloatFromYogaValue(yogaStyle.border(YGEdgeLeft)),
/* .top = */ optionalFloatFromYogaValue(yogaStyle.border(YGEdgeTop)),
/* .left = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeLeft]),
/* .top = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeTop]),
/* .right = */
optionalFloatFromYogaValue(yogaStyle.border(YGEdgeRight)),
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeRight]),
/* .bottom = */
optionalFloatFromYogaValue(yogaStyle.border(YGEdgeBottom)),
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeBottom]),
/* .start = */
optionalFloatFromYogaValue(yogaStyle.border(YGEdgeStart)),
/* .end = */ optionalFloatFromYogaValue(yogaStyle.border(YGEdgeEnd)),
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeStart]),
/* .end = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeEnd]),
/* .horizontal = */
optionalFloatFromYogaValue(yogaStyle.border(YGEdgeHorizontal)),
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeHorizontal]),
/* .vertical = */
optionalFloatFromYogaValue(yogaStyle.border(YGEdgeVertical)),
/* .all = */ optionalFloatFromYogaValue(yogaStyle.border(YGEdgeAll)),
optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeVertical]),
/* .all = */ optionalFloatFromYogaValue(yogaStyle.border()[YGEdgeAll]),
};
return {
@@ -54,17 +54,9 @@ void ViewShadowNode::initialize() noexcept {
viewProps.removeClippedSubviews ||
HostPlatformViewTraitsInitializer::formsStackingContext(viewProps);
bool hasBorder = [&]() {
for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) {
if (viewProps.yogaStyle.border(static_cast<YGEdge>(edge)).isDefined()) {
return true;
}
}
return false;
}();
bool formsView = formsStackingContext ||
isColorMeaningful(viewProps.backgroundColor) || hasBorder ||
isColorMeaningful(viewProps.backgroundColor) ||
!(viewProps.yogaStyle.border() == yoga::Style::Edges{}) ||
!viewProps.testId.empty() ||
HostPlatformViewTraitsInitializer::formsView(viewProps);
@@ -391,55 +391,64 @@ void YogaLayoutableShadowNode::updateYogaProps() {
yoga::Style result{baseStyle};
// Aliases with precedence
if (props.insetInlineEnd.isDefined()) {
result.setPosition(YGEdgeEnd, props.insetInlineEnd);
if (!props.inset.isUndefined()) {
result.position()[YGEdgeAll] = props.inset;
}
if (props.insetInlineStart.isDefined()) {
result.setPosition(YGEdgeStart, props.insetInlineStart);
if (!props.insetBlock.isUndefined()) {
result.position()[YGEdgeVertical] = props.insetBlock;
}
if (props.marginInline.isDefined()) {
result.setMargin(YGEdgeHorizontal, props.marginInline);
if (!props.insetInline.isUndefined()) {
result.position()[YGEdgeHorizontal] = props.insetInline;
}
if (props.marginInlineStart.isDefined()) {
result.setMargin(YGEdgeStart, props.marginInlineStart);
if (!props.insetInlineEnd.isUndefined()) {
result.position()[YGEdgeEnd] = props.insetInlineEnd;
}
if (props.marginInlineEnd.isDefined()) {
result.setMargin(YGEdgeEnd, props.marginInlineEnd);
if (!props.insetInlineStart.isUndefined()) {
result.position()[YGEdgeStart] = props.insetInlineStart;
}
if (props.marginBlock.isDefined()) {
result.setMargin(YGEdgeVertical, props.marginBlock);
if (!props.marginInline.isUndefined()) {
result.margin()[YGEdgeHorizontal] = props.marginInline;
}
if (props.paddingInline.isDefined()) {
result.setPadding(YGEdgeHorizontal, props.paddingInline);
if (!props.marginInlineStart.isUndefined()) {
result.margin()[YGEdgeStart] = props.marginInlineStart;
}
if (props.paddingInlineStart.isDefined()) {
result.setPadding(YGEdgeStart, props.paddingInlineStart);
if (!props.marginInlineEnd.isUndefined()) {
result.margin()[YGEdgeEnd] = props.marginInlineEnd;
}
if (props.paddingInlineEnd.isDefined()) {
result.setPadding(YGEdgeEnd, props.paddingInlineEnd);
if (!props.marginBlock.isUndefined()) {
result.margin()[YGEdgeVertical] = props.marginBlock;
}
if (props.paddingBlock.isDefined()) {
result.setPadding(YGEdgeVertical, props.paddingBlock);
if (!props.paddingInline.isUndefined()) {
result.padding()[YGEdgeHorizontal] = props.paddingInline;
}
if (!props.paddingInlineStart.isUndefined()) {
result.padding()[YGEdgeStart] = props.paddingInlineStart;
}
if (!props.paddingInlineEnd.isUndefined()) {
result.padding()[YGEdgeEnd] = props.paddingInlineEnd;
}
if (!props.paddingBlock.isUndefined()) {
result.padding()[YGEdgeVertical] = props.paddingBlock;
}
// Aliases without precedence
if (result.position(YGEdgeBottom).isUndefined()) {
result.setPosition(YGEdgeBottom, props.insetBlockEnd);
if (CompactValue(result.position()[YGEdgeBottom]).isUndefined()) {
result.position()[YGEdgeBottom] = props.insetBlockEnd;
}
if (result.position(YGEdgeTop).isUndefined()) {
result.setPosition(YGEdgeTop, props.insetBlockStart);
if (CompactValue(result.position()[YGEdgeTop]).isUndefined()) {
result.position()[YGEdgeTop] = props.insetBlockStart;
}
if (result.margin(YGEdgeTop).isUndefined()) {
result.setMargin(YGEdgeTop, props.marginBlockStart);
if (CompactValue(result.margin()[YGEdgeTop]).isUndefined()) {
result.margin()[YGEdgeTop] = props.marginBlockStart;
}
if (result.margin(YGEdgeBottom).isUndefined()) {
result.setMargin(YGEdgeBottom, props.marginBlockEnd);
if (CompactValue(result.margin()[YGEdgeBottom]).isUndefined()) {
result.margin()[YGEdgeBottom] = props.marginBlockEnd;
}
if (result.padding(YGEdgeTop).isUndefined()) {
result.setPadding(YGEdgeTop, props.paddingBlockStart);
if (CompactValue(result.padding()[YGEdgeTop]).isUndefined()) {
result.padding()[YGEdgeTop] = props.paddingBlockStart;
}
if (result.padding(YGEdgeBottom).isUndefined()) {
result.setPadding(YGEdgeBottom, props.paddingBlockEnd);
if (CompactValue(result.padding()[YGEdgeBottom]).isUndefined()) {
result.padding()[YGEdgeBottom] = props.paddingBlockEnd;
}
return result;
@@ -549,18 +558,18 @@ void YogaLayoutableShadowNode::setPadding(RectangleEdges<Float> padding) const {
auto rightPadding = yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.right);
auto bottomPadding = yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.bottom);
if (leftPadding != style.padding(YGEdgeLeft) ||
topPadding != style.padding(YGEdgeTop) ||
rightPadding != style.padding(YGEdgeRight) ||
bottomPadding != style.padding(YGEdgeBottom)) {
style.setPadding(
YGEdgeTop, yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.top));
style.setPadding(
YGEdgeLeft, yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.left));
style.setPadding(
YGEdgeRight, yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.right));
style.setPadding(
YGEdgeBottom, yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.bottom));
if (leftPadding != style.padding()[YGEdgeLeft] ||
topPadding != style.padding()[YGEdgeTop] ||
rightPadding != style.padding()[YGEdgeRight] ||
bottomPadding != style.padding()[YGEdgeBottom]) {
style.padding()[YGEdgeTop] =
yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.top);
style.padding()[YGEdgeLeft] =
yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.left);
style.padding()[YGEdgeRight] =
yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.right);
style.padding()[YGEdgeBottom] =
yoga::CompactValue::ofMaybe<YGUnitPoint>(padding.bottom);
yogaNode_.setStyle(style);
yogaNode_.setDirty(true);
}
@@ -883,36 +892,40 @@ void YogaLayoutableShadowNode::swapLeftAndRightInYogaStyleProps(
const YogaLayoutableShadowNode& shadowNode) {
auto yogaStyle = shadowNode.yogaNode_.getStyle();
const yoga::Style::Edges& position = yogaStyle.position();
const yoga::Style::Edges& padding = yogaStyle.padding();
const yoga::Style::Edges& margin = yogaStyle.margin();
// Swap Yoga node values, position, padding and margin.
if (yogaStyle.position(YGEdgeLeft).isDefined()) {
yogaStyle.setPosition(YGEdgeStart, yogaStyle.position(YGEdgeLeft));
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::ofUndefined());
if (yogaStyle.position()[YGEdgeLeft] != YGValueUndefined) {
yogaStyle.position()[YGEdgeStart] = position[YGEdgeLeft];
yogaStyle.position()[YGEdgeLeft] = YGValueUndefined;
}
if (yogaStyle.position(YGEdgeRight).isDefined()) {
yogaStyle.setPosition(YGEdgeEnd, yogaStyle.position(YGEdgeRight));
yogaStyle.setPosition(YGEdgeRight, yoga::CompactValue::ofUndefined());
if (yogaStyle.position()[YGEdgeRight] != YGValueUndefined) {
yogaStyle.position()[YGEdgeEnd] = position[YGEdgeRight];
yogaStyle.position()[YGEdgeRight] = YGValueUndefined;
}
if (yogaStyle.padding(YGEdgeLeft).isDefined()) {
yogaStyle.setPadding(YGEdgeStart, yogaStyle.padding(YGEdgeLeft));
yogaStyle.setPadding(YGEdgeLeft, yoga::CompactValue::ofUndefined());
if (yogaStyle.padding()[YGEdgeLeft] != YGValueUndefined) {
yogaStyle.padding()[YGEdgeStart] = padding[YGEdgeLeft];
yogaStyle.padding()[YGEdgeLeft] = YGValueUndefined;
}
if (yogaStyle.padding(YGEdgeRight).isDefined()) {
yogaStyle.setPadding(YGEdgeEnd, yogaStyle.padding(YGEdgeRight));
yogaStyle.setPadding(YGEdgeRight, yoga::CompactValue::ofUndefined());
if (yogaStyle.padding()[YGEdgeRight] != YGValueUndefined) {
yogaStyle.padding()[YGEdgeEnd] = padding[YGEdgeRight];
yogaStyle.padding()[YGEdgeRight] = YGValueUndefined;
}
if (yogaStyle.margin(YGEdgeLeft).isDefined()) {
yogaStyle.setMargin(YGEdgeStart, yogaStyle.margin(YGEdgeLeft));
yogaStyle.setMargin(YGEdgeLeft, yoga::CompactValue::ofUndefined());
if (yogaStyle.margin()[YGEdgeLeft] != YGValueUndefined) {
yogaStyle.margin()[YGEdgeStart] = margin[YGEdgeLeft];
yogaStyle.margin()[YGEdgeLeft] = YGValueUndefined;
}
if (yogaStyle.margin(YGEdgeRight).isDefined()) {
yogaStyle.setMargin(YGEdgeEnd, yogaStyle.margin(YGEdgeRight));
yogaStyle.setMargin(YGEdgeRight, yoga::CompactValue::ofUndefined());
if (yogaStyle.margin()[YGEdgeRight] != YGValueUndefined) {
yogaStyle.margin()[YGEdgeEnd] = margin[YGEdgeRight];
yogaStyle.margin()[YGEdgeRight] = YGValueUndefined;
}
shadowNode.yogaNode_.setStyle(yogaStyle);
@@ -965,14 +978,16 @@ void YogaLayoutableShadowNode::swapLeftAndRightInViewProps(
props.borderStyles.right.reset();
}
if (props.yogaStyle.border(YGEdgeLeft).isDefined()) {
props.yogaStyle.setBorder(YGEdgeStart, props.yogaStyle.border(YGEdgeLeft));
props.yogaStyle.setBorder(YGEdgeLeft, yoga::CompactValue::ofUndefined());
const yoga::Style::Edges& border = props.yogaStyle.border();
if (props.yogaStyle.border()[YGEdgeLeft] != YGValueUndefined) {
props.yogaStyle.border()[YGEdgeStart] = border[YGEdgeLeft];
props.yogaStyle.border()[YGEdgeLeft] = YGValueUndefined;
}
if (props.yogaStyle.border(YGEdgeRight).isDefined()) {
props.yogaStyle.setBorder(YGEdgeEnd, props.yogaStyle.border(YGEdgeRight));
props.yogaStyle.setBorder(YGEdgeRight, yoga::CompactValue::ofUndefined());
if (props.yogaStyle.border()[YGEdgeRight] != YGValueUndefined) {
props.yogaStyle.border()[YGEdgeEnd] = border[YGEdgeRight];
props.yogaStyle.border()[YGEdgeRight] = YGValueUndefined;
}
}
@@ -174,67 +174,60 @@ static inline T const getFieldValue(
#define REBUILD_FIELD_SWITCH_CASE_YSP(field) \
REBUILD_FIELD_SWITCH_CASE2(field, #field)
#define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, setter, index, fieldName) \
case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \
yogaStyle.setter( \
index, getFieldValue(context, value, ygDefaults.field(index))); \
return; \
#define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, index, fieldName) \
case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \
yogaStyle.field()[index] = \
getFieldValue(context, value, ygDefaults.field()[index]); \
return; \
}
#define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \
field, setter, index, fieldName) \
case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \
yogaStyle.setter( \
index, getFieldValue(context, value, ygDefaults.field(index))); \
return; \
}
#define REBUILD_FIELD_YG_DIMENSION(field, setter, widthStr, heightStr) \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \
field, setter, yoga::Dimension::Width, widthStr); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \
field, setter, yoga::Dimension::Height, heightStr);
#define REBUILD_FIELD_YG_GUTTER( \
field, setter, rowGapStr, columnGapStr, gapStr) \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \
field, setter, yoga::Gutter::Row, rowGapStr); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \
field, setter, yoga::Gutter::Column, columnGapStr); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \
field, setter, yoga::Gutter::All, gapStr);
#define REBUILD_FIELD_YG_EDGES(field, setter, prefix, suffix) \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeLeft, prefix "Left" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeTop, prefix "Top" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeRight, prefix "Right" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeBottom, prefix "Bottom" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeStart, prefix "Start" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeEnd, prefix "End" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeHorizontal, prefix "Horizontal" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeVertical, prefix "Vertical" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, setter, YGEdgeAll, prefix "" suffix);
#define REBUILD_FIELD_YG_EDGES(field, prefix, suffix) \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, YGEdgeLeft, prefix "Left" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, YGEdgeTop, prefix "Top" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, YGEdgeRight, prefix "Right" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, YGEdgeBottom, prefix "Bottom" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, YGEdgeStart, prefix "Start" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, YGEdgeEnd, prefix "End" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, YGEdgeHorizontal, prefix "Horizontal" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
field, YGEdgeVertical, prefix "Vertical" suffix); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, YGEdgeAll, prefix "" suffix);
#define REBUILD_FIELD_YG_EDGES_POSITION() \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeLeft, "left"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeTop, "top"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeRight, "right"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeBottom, "bottom"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeStart, "start"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeEnd, "end"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeHorizontal, "insetInline"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeVertical, "insetBlock"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \
position, setPosition, YGEdgeAll, "inset");
#define REBUILD_FIELD_YG_EDGES_POSITION() \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeLeft, "left"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeTop, "top"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeRight, "right"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeBottom, "bottom"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeStart, "start"); \
REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeEnd, "end");
void YogaStylableProps::setProp(
const PropsParserContext& context,
@@ -269,15 +262,18 @@ void YogaStylableProps::setProp(
REBUILD_FIELD_YG_DIMENSION(
maxDimension, setMaxDimension, "maxWidth", "maxHeight");
REBUILD_FIELD_YG_EDGES_POSITION();
REBUILD_FIELD_YG_EDGES(margin, setMargin, "margin", "");
REBUILD_FIELD_YG_EDGES(padding, setPadding, "padding", "");
REBUILD_FIELD_YG_EDGES(border, setBorder, "border", "Width");
REBUILD_FIELD_YG_EDGES(margin, "margin", "");
REBUILD_FIELD_YG_EDGES(padding, "padding", "");
REBUILD_FIELD_YG_EDGES(border, "border", "Width");
// Aliases
RAW_SET_PROP_SWITCH_CASE(inset, "inset");
RAW_SET_PROP_SWITCH_CASE(insetBlock, "insetBlock");
RAW_SET_PROP_SWITCH_CASE(insetBlockEnd, "insetBlockEnd");
RAW_SET_PROP_SWITCH_CASE(insetBlockStart, "insetBlockStart");
RAW_SET_PROP_SWITCH_CASE(insetInlineStart, "insetInlineStart");
RAW_SET_PROP_SWITCH_CASE(insetInline, "insetInline");
RAW_SET_PROP_SWITCH_CASE(insetInlineEnd, "insetInlineEnd");
RAW_SET_PROP_SWITCH_CASE(insetInlineStart, "insetInlineStart");
RAW_SET_PROP_SWITCH_CASE(marginInline, "marginInline");
RAW_SET_PROP_SWITCH_CASE(marginInlineStart, "marginInlineStart");
RAW_SET_PROP_SWITCH_CASE(marginInlineEnd, "marginInlineEnd");
@@ -347,155 +343,14 @@ SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const {
"flexShrink", yogaStyle.flexShrink(), defaultYogaStyle.flexShrink()),
debugStringConvertibleItem(
"flexBasis", yogaStyle.flexBasis(), defaultYogaStyle.flexBasis()),
debugStringConvertibleItem(
"marginLeft",
yogaStyle.margin(YGEdgeLeft),
defaultYogaStyle.margin(YGEdgeLeft)),
"margin", yogaStyle.margin(), defaultYogaStyle.margin()),
debugStringConvertibleItem(
"marginTop",
yogaStyle.margin(YGEdgeTop),
defaultYogaStyle.margin(YGEdgeTop)),
"position", yogaStyle.position(), defaultYogaStyle.position()),
debugStringConvertibleItem(
"marginRight",
yogaStyle.margin(YGEdgeRight),
defaultYogaStyle.margin(YGEdgeRight)),
"padding", yogaStyle.padding(), defaultYogaStyle.padding()),
debugStringConvertibleItem(
"marginBottom",
yogaStyle.margin(YGEdgeBottom),
defaultYogaStyle.margin(YGEdgeBottom)),
debugStringConvertibleItem(
"marginStart",
yogaStyle.margin(YGEdgeStart),
defaultYogaStyle.margin(YGEdgeStart)),
debugStringConvertibleItem(
"marginEnd",
yogaStyle.margin(YGEdgeEnd),
defaultYogaStyle.margin(YGEdgeEnd)),
debugStringConvertibleItem(
"marginHorizontal",
yogaStyle.margin(YGEdgeHorizontal),
defaultYogaStyle.margin(YGEdgeHorizontal)),
debugStringConvertibleItem(
"marginVertical",
yogaStyle.margin(YGEdgeVertical),
defaultYogaStyle.margin(YGEdgeVertical)),
debugStringConvertibleItem(
"margin",
yogaStyle.margin(YGEdgeAll),
defaultYogaStyle.margin(YGEdgeAll)),
debugStringConvertibleItem(
"left",
yogaStyle.position(YGEdgeLeft),
defaultYogaStyle.position(YGEdgeLeft)),
debugStringConvertibleItem(
"top",
yogaStyle.position(YGEdgeTop),
defaultYogaStyle.position(YGEdgeTop)),
debugStringConvertibleItem(
"right",
yogaStyle.position(YGEdgeRight),
defaultYogaStyle.position(YGEdgeRight)),
debugStringConvertibleItem(
"bottom",
yogaStyle.position(YGEdgeBottom),
defaultYogaStyle.position(YGEdgeBottom)),
debugStringConvertibleItem(
"start",
yogaStyle.position(YGEdgeStart),
defaultYogaStyle.position(YGEdgeStart)),
debugStringConvertibleItem(
"end",
yogaStyle.position(YGEdgeEnd),
defaultYogaStyle.position(YGEdgeEnd)),
debugStringConvertibleItem(
"inseInline",
yogaStyle.position(YGEdgeHorizontal),
defaultYogaStyle.position(YGEdgeHorizontal)),
debugStringConvertibleItem(
"insetBlock",
yogaStyle.position(YGEdgeVertical),
defaultYogaStyle.position(YGEdgeVertical)),
debugStringConvertibleItem(
"inset",
yogaStyle.position(YGEdgeAll),
defaultYogaStyle.position(YGEdgeAll)),
debugStringConvertibleItem(
"paddingLeft",
yogaStyle.padding(YGEdgeLeft),
defaultYogaStyle.padding(YGEdgeLeft)),
debugStringConvertibleItem(
"paddingTop",
yogaStyle.padding(YGEdgeTop),
defaultYogaStyle.padding(YGEdgeTop)),
debugStringConvertibleItem(
"paddingRight",
yogaStyle.padding(YGEdgeRight),
defaultYogaStyle.padding(YGEdgeRight)),
debugStringConvertibleItem(
"paddingBottom",
yogaStyle.padding(YGEdgeBottom),
defaultYogaStyle.padding(YGEdgeBottom)),
debugStringConvertibleItem(
"paddingStart",
yogaStyle.padding(YGEdgeStart),
defaultYogaStyle.padding(YGEdgeStart)),
debugStringConvertibleItem(
"paddingEnd",
yogaStyle.padding(YGEdgeEnd),
defaultYogaStyle.padding(YGEdgeEnd)),
debugStringConvertibleItem(
"paddingHorizontal",
yogaStyle.padding(YGEdgeHorizontal),
defaultYogaStyle.padding(YGEdgeHorizontal)),
debugStringConvertibleItem(
"paddingVertical",
yogaStyle.padding(YGEdgeVertical),
defaultYogaStyle.padding(YGEdgeVertical)),
debugStringConvertibleItem(
"padding",
yogaStyle.padding(YGEdgeAll),
defaultYogaStyle.padding(YGEdgeAll)),
debugStringConvertibleItem(
"borderLeft",
yogaStyle.border(YGEdgeLeft),
defaultYogaStyle.border(YGEdgeLeft)),
debugStringConvertibleItem(
"borderTop",
yogaStyle.border(YGEdgeTop),
defaultYogaStyle.border(YGEdgeTop)),
debugStringConvertibleItem(
"borderRight",
yogaStyle.border(YGEdgeRight),
defaultYogaStyle.border(YGEdgeRight)),
debugStringConvertibleItem(
"borderBottom",
yogaStyle.border(YGEdgeBottom),
defaultYogaStyle.border(YGEdgeBottom)),
debugStringConvertibleItem(
"borderStart",
yogaStyle.border(YGEdgeStart),
defaultYogaStyle.border(YGEdgeStart)),
debugStringConvertibleItem(
"borderEnd",
yogaStyle.border(YGEdgeEnd),
defaultYogaStyle.border(YGEdgeEnd)),
debugStringConvertibleItem(
"borderHorizontal",
yogaStyle.border(YGEdgeHorizontal),
defaultYogaStyle.border(YGEdgeHorizontal)),
debugStringConvertibleItem(
"borderVertical",
yogaStyle.border(YGEdgeVertical),
defaultYogaStyle.border(YGEdgeVertical)),
debugStringConvertibleItem(
"border",
yogaStyle.border(YGEdgeAll),
defaultYogaStyle.border(YGEdgeAll)),
"border", yogaStyle.border(), defaultYogaStyle.border()),
debugStringConvertibleItem(
"width",
yogaStyle.dimension(yoga::Dimension::Width),
@@ -532,6 +387,18 @@ void YogaStylableProps::convertRawPropAliases(
const PropsParserContext& context,
const YogaStylableProps& sourceProps,
const RawProps& rawProps) {
inset = convertRawProp(
context,
rawProps,
"inset",
sourceProps.inset,
CompactValue::ofUndefined());
insetBlock = convertRawProp(
context,
rawProps,
"insetBlock",
sourceProps.insetBlock,
CompactValue::ofUndefined());
insetBlockEnd = convertRawProp(
context,
rawProps,
@@ -544,18 +411,24 @@ void YogaStylableProps::convertRawPropAliases(
"insetBlockStart",
sourceProps.insetBlockStart,
CompactValue::ofUndefined());
insetInlineStart = convertRawProp(
insetInline = convertRawProp(
context,
rawProps,
"start",
sourceProps.insetInlineStart,
"insetInline",
sourceProps.insetInline,
CompactValue::ofUndefined());
insetInlineEnd = convertRawProp(
context,
rawProps,
"end",
"insetInlineEnd",
sourceProps.insetInlineEnd,
CompactValue::ofUndefined());
insetInlineStart = convertRawProp(
context,
rawProps,
"insetInlineStart",
sourceProps.insetInlineStart,
CompactValue::ofUndefined());
marginInline = convertRawProp(
context,
rawProps,
@@ -41,6 +41,8 @@ class YogaStylableProps : public Props {
// Duplicates of existing properties with different names, taking
// precedence. E.g. "marginBlock" instead of "marginVertical"
CompactValue inset;
CompactValue insetInline;
CompactValue insetInlineEnd;
CompactValue insetInlineStart;
@@ -57,6 +59,7 @@ class YogaStylableProps : public Props {
// BlockEnd/BlockStart map to top/bottom (no writing mode), but we preserve
// Yoga's precedence and prefer specific edges (e.g. top) to ones which are
// flow relative (e.g. blockStart).
CompactValue insetBlock;
CompactValue insetBlockEnd;
CompactValue insetBlockStart;
@@ -395,7 +395,7 @@ inline void fromRawValue(
inline void fromRawValue(
const PropsParserContext& context,
const RawValue& value,
yoga::CompactValue& result) {
yoga::Style::ValueRepr& result) {
if (value.hasType<Float>()) {
result = yoga::CompactValue::ofMaybe<YGUnitPoint>((float)value);
return;
@@ -428,7 +428,7 @@ inline void fromRawValue(
const PropsParserContext& context,
const RawValue& value,
YGValue& result) {
yoga::CompactValue ygValue{};
yoga::Style::ValueRepr ygValue{};
fromRawValue(context, value, ygValue);
result = ygValue;
}
@@ -778,6 +778,40 @@ inline std::string toString(const yoga::FloatOptional& value) {
return folly::to<std::string>(floatFromYogaFloat(value.unwrap()));
}
inline std::string toString(const yoga::Style::Dimensions& value) {
return "{" + toString(value[0]) + ", " + toString(value[1]) + "}";
}
inline std::string toString(const yoga::Style::Edges& value) {
static std::array<std::string, 9> names = {
{"left",
"top",
"right",
"bottom",
"start",
"end",
"horizontal",
"vertical",
"all"}};
auto result = std::string{};
auto separator = std::string{", "};
for (size_t i = 0; i < names.size(); i++) {
YGValue v = value[i];
if (v.unit == YGUnitUndefined) {
continue;
}
result += names[i] + ": " + toString(v) + separator;
}
if (!result.empty()) {
result.erase(result.length() - separator.length());
}
return "{" + result + "}";
}
inline std::string toString(const LayoutConformance& value) {
switch (value) {
case LayoutConformance::Undefined:
@@ -13,28 +13,22 @@
namespace facebook::react {
MapBuffer convertBorderWidths(const yoga::Style& style) {
MapBuffer convertBorderWidths(const yoga::Style::Edges& border) {
MapBufferBuilder builder(7);
putOptionalFloat(
builder, EDGE_TOP, optionalFloatFromYogaValue(style.border(YGEdgeTop)));
builder, EDGE_TOP, optionalFloatFromYogaValue(border[YGEdgeTop]));
putOptionalFloat(
builder,
EDGE_RIGHT,
optionalFloatFromYogaValue(style.border(YGEdgeRight)));
builder, EDGE_RIGHT, optionalFloatFromYogaValue(border[YGEdgeRight]));
putOptionalFloat(
builder,
EDGE_BOTTOM,
optionalFloatFromYogaValue(style.border(YGEdgeBottom)));
builder, EDGE_BOTTOM, optionalFloatFromYogaValue(border[YGEdgeBottom]));
putOptionalFloat(
builder, EDGE_LEFT, optionalFloatFromYogaValue(style.border(YGEdgeLeft)));
builder, EDGE_LEFT, optionalFloatFromYogaValue(border[YGEdgeLeft]));
putOptionalFloat(
builder,
EDGE_START,
optionalFloatFromYogaValue(style.border(YGEdgeStart)));
builder, EDGE_START, optionalFloatFromYogaValue(border[YGEdgeStart]));
putOptionalFloat(
builder, EDGE_END, optionalFloatFromYogaValue(style.border(YGEdgeEnd)));
builder, EDGE_END, optionalFloatFromYogaValue(border[YGEdgeEnd]));
putOptionalFloat(
builder, EDGE_ALL, optionalFloatFromYogaValue(style.border(YGEdgeAll)));
builder, EDGE_ALL, optionalFloatFromYogaValue(border[YGEdgeAll]));
return builder.build();
}
@@ -60,18 +54,9 @@ void YogaStylableProps::propsDiffMapBuffer(
const auto& oldStyle = oldProps.yogaStyle;
const auto& newStyle = newProps.yogaStyle;
bool areBordersEqual = [&]() {
for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) {
if (oldStyle.border(static_cast<YGEdge>(edge)) !=
newStyle.border(static_cast<YGEdge>(edge))) {
return false;
}
}
return true;
}();
if (!areBordersEqual) {
builder.putMapBuffer(YG_BORDER_WIDTH, convertBorderWidths(newStyle));
if (!(oldStyle.border() == newStyle.border())) {
builder.putMapBuffer(
YG_BORDER_WIDTH, convertBorderWidths(newStyle.border()));
}
if (oldStyle.overflow() != newStyle.overflow()) {
@@ -18,6 +18,134 @@ namespace facebook::react {
// Nearly this entire file can be deleted when iterator-style Prop parsing
// ships fully for View
static inline yoga::Style::Edges convertRawProp(
const PropsParserContext& context,
const RawProps& rawProps,
const char* prefix,
const char* suffix,
const yoga::Style::Edges& sourceValue,
const yoga::Style::Edges& defaultValue) {
auto result = defaultValue;
result[YGEdgeLeft] = convertRawProp(
context,
rawProps,
"Left",
sourceValue[YGEdgeLeft],
defaultValue[YGEdgeLeft],
prefix,
suffix);
result[YGEdgeTop] = convertRawProp(
context,
rawProps,
"Top",
sourceValue[YGEdgeTop],
defaultValue[YGEdgeTop],
prefix,
suffix);
result[YGEdgeRight] = convertRawProp(
context,
rawProps,
"Right",
sourceValue[YGEdgeRight],
defaultValue[YGEdgeRight],
prefix,
suffix);
result[YGEdgeBottom] = convertRawProp(
context,
rawProps,
"Bottom",
sourceValue[YGEdgeBottom],
defaultValue[YGEdgeBottom],
prefix,
suffix);
result[YGEdgeStart] = convertRawProp(
context,
rawProps,
"Start",
sourceValue[YGEdgeStart],
defaultValue[YGEdgeStart],
prefix,
suffix);
result[YGEdgeEnd] = convertRawProp(
context,
rawProps,
"End",
sourceValue[YGEdgeEnd],
defaultValue[YGEdgeEnd],
prefix,
suffix);
result[YGEdgeHorizontal] = convertRawProp(
context,
rawProps,
"Horizontal",
sourceValue[YGEdgeHorizontal],
defaultValue[YGEdgeHorizontal],
prefix,
suffix);
result[YGEdgeVertical] = convertRawProp(
context,
rawProps,
"Vertical",
sourceValue[YGEdgeVertical],
defaultValue[YGEdgeVertical],
prefix,
suffix);
result[YGEdgeAll] = convertRawProp(
context,
rawProps,
"",
sourceValue[YGEdgeAll],
defaultValue[YGEdgeAll],
prefix,
suffix);
return result;
}
static inline yoga::Style::Edges convertRawProp(
const PropsParserContext& context,
const RawProps& rawProps,
const yoga::Style::Edges& sourceValue,
const yoga::Style::Edges& defaultValue) {
auto result = defaultValue;
result[YGEdgeLeft] = convertRawProp(
context,
rawProps,
"left",
sourceValue[YGEdgeLeft],
defaultValue[YGEdgeLeft]);
result[YGEdgeTop] = convertRawProp(
context,
rawProps,
"top",
sourceValue[YGEdgeTop],
defaultValue[YGEdgeTop]);
result[YGEdgeRight] = convertRawProp(
context,
rawProps,
"right",
sourceValue[YGEdgeRight],
defaultValue[YGEdgeRight]);
result[YGEdgeBottom] = convertRawProp(
context,
rawProps,
"bottom",
sourceValue[YGEdgeBottom],
defaultValue[YGEdgeBottom]);
result[YGEdgeStart] = convertRawProp(
context,
rawProps,
"start",
sourceValue[YGEdgeStart],
defaultValue[YGEdgeStart]);
result[YGEdgeEnd] = convertRawProp(
context,
rawProps,
"end",
sourceValue[YGEdgeEnd],
defaultValue[YGEdgeEnd]);
return result;
}
static inline yoga::Style convertRawProp(
const PropsParserContext& context,
const RawProps& rawProps,
@@ -99,249 +227,22 @@ static inline yoga::Style convertRawProp(
"flexBasis",
sourceValue.flexBasis(),
yogaStyle.flexBasis());
yogaStyle.setMargin(
YGEdgeLeft,
convertRawProp(
context,
rawProps,
"marginLeft",
sourceValue.margin(YGEdgeLeft),
yogaStyle.margin(YGEdgeLeft)));
yogaStyle.setMargin(
YGEdgeTop,
convertRawProp(
context,
rawProps,
"marginTop",
sourceValue.margin(YGEdgeTop),
yogaStyle.margin(YGEdgeTop)));
yogaStyle.setMargin(
YGEdgeRight,
convertRawProp(
context,
rawProps,
"marginRight",
sourceValue.margin(YGEdgeRight),
yogaStyle.margin(YGEdgeRight)));
yogaStyle.setMargin(
YGEdgeBottom,
convertRawProp(
context,
rawProps,
"marginBottom",
sourceValue.margin(YGEdgeBottom),
yogaStyle.margin(YGEdgeBottom)));
yogaStyle.setMargin(
YGEdgeStart,
convertRawProp(
context,
rawProps,
"marginStart",
sourceValue.margin(YGEdgeStart),
yogaStyle.margin(YGEdgeStart)));
yogaStyle.setMargin(
YGEdgeEnd,
convertRawProp(
context,
rawProps,
"marginEnd",
sourceValue.margin(YGEdgeEnd),
yogaStyle.margin(YGEdgeEnd)));
yogaStyle.setMargin(
YGEdgeHorizontal,
convertRawProp(
context,
rawProps,
"marginHorizontal",
sourceValue.margin(YGEdgeHorizontal),
yogaStyle.margin(YGEdgeHorizontal)));
yogaStyle.setMargin(
YGEdgeVertical,
convertRawProp(
context,
rawProps,
"marginVertical",
sourceValue.margin(YGEdgeVertical),
yogaStyle.margin(YGEdgeVertical)));
yogaStyle.setMargin(
YGEdgeAll,
convertRawProp(
context,
rawProps,
"margin",
sourceValue.margin(YGEdgeAll),
yogaStyle.margin(YGEdgeAll)));
yogaStyle.setPosition(
YGEdgeLeft,
convertRawProp(
context,
rawProps,
"left",
sourceValue.position(YGEdgeLeft),
yogaStyle.position(YGEdgeLeft)));
yogaStyle.setPosition(
YGEdgeTop,
convertRawProp(
context,
rawProps,
"top",
sourceValue.position(YGEdgeTop),
yogaStyle.position(YGEdgeTop)));
yogaStyle.setPosition(
YGEdgeRight,
convertRawProp(
context,
rawProps,
"right",
sourceValue.position(YGEdgeRight),
yogaStyle.position(YGEdgeRight)));
yogaStyle.setPosition(
YGEdgeBottom,
convertRawProp(
context,
rawProps,
"bottom",
sourceValue.position(YGEdgeBottom),
yogaStyle.position(YGEdgeBottom)));
yogaStyle.setPosition(
YGEdgeStart,
convertRawProp(
context,
rawProps,
"start",
sourceValue.position(YGEdgeStart),
yogaStyle.position(YGEdgeStart)));
yogaStyle.setPosition(
YGEdgeEnd,
convertRawProp(
context,
rawProps,
"end",
sourceValue.position(YGEdgeEnd),
yogaStyle.position(YGEdgeEnd)));
yogaStyle.setPosition(
YGEdgeHorizontal,
convertRawProp(
context,
rawProps,
"insetInline",
sourceValue.position(YGEdgeHorizontal),
yogaStyle.position(YGEdgeHorizontal)));
yogaStyle.setPosition(
YGEdgeVertical,
convertRawProp(
context,
rawProps,
"insetBlock",
sourceValue.position(YGEdgeVertical),
yogaStyle.position(YGEdgeVertical)));
yogaStyle.setPosition(
YGEdgeAll,
convertRawProp(
context,
rawProps,
"inset",
sourceValue.position(YGEdgeAll),
yogaStyle.position(YGEdgeAll)));
yogaStyle.setPadding(
YGEdgeLeft,
convertRawProp(
context,
rawProps,
"paddingLeft",
sourceValue.padding(YGEdgeLeft),
yogaStyle.padding(YGEdgeLeft)));
yogaStyle.setPadding(
YGEdgeTop,
convertRawProp(
context,
rawProps,
"paddingTop",
sourceValue.padding(YGEdgeTop),
yogaStyle.padding(YGEdgeTop)));
yogaStyle.setPadding(
YGEdgeRight,
convertRawProp(
context,
rawProps,
"paddingRight",
sourceValue.padding(YGEdgeRight),
yogaStyle.padding(YGEdgeRight)));
yogaStyle.setPadding(
YGEdgeBottom,
convertRawProp(
context,
rawProps,
"paddingBottom",
sourceValue.padding(YGEdgeBottom),
yogaStyle.padding(YGEdgeBottom)));
yogaStyle.setPadding(
YGEdgeStart,
convertRawProp(
context,
rawProps,
"paddingStart",
sourceValue.padding(YGEdgeStart),
yogaStyle.padding(YGEdgeStart)));
yogaStyle.setPadding(
YGEdgeEnd,
convertRawProp(
context,
rawProps,
"paddingEnd",
sourceValue.padding(YGEdgeEnd),
yogaStyle.padding(YGEdgeEnd)));
yogaStyle.setPadding(
YGEdgeHorizontal,
convertRawProp(
context,
rawProps,
"paddingHorizontal",
sourceValue.padding(YGEdgeHorizontal),
yogaStyle.padding(YGEdgeHorizontal)));
yogaStyle.setPadding(
YGEdgeVertical,
convertRawProp(
context,
rawProps,
"paddingVertical",
sourceValue.padding(YGEdgeVertical),
yogaStyle.padding(YGEdgeVertical)));
yogaStyle.setPadding(
YGEdgeAll,
convertRawProp(
context,
rawProps,
"padding",
sourceValue.padding(YGEdgeAll),
yogaStyle.padding(YGEdgeAll)));
yogaStyle.margin() = convertRawProp(
context,
rawProps,
"margin",
"",
sourceValue.margin(),
yogaStyle.margin());
yogaStyle.position() = convertRawProp(
context, rawProps, sourceValue.position(), yogaStyle.position());
yogaStyle.padding() = convertRawProp(
context,
rawProps,
"padding",
"",
sourceValue.padding(),
yogaStyle.padding());
yogaStyle.setGap(
yoga::Gutter::Row,
@@ -370,86 +271,13 @@ static inline yoga::Style convertRawProp(
sourceValue.gap(yoga::Gutter::All),
yogaStyle.gap(yoga::Gutter::All)));
yogaStyle.setBorder(
YGEdgeLeft,
convertRawProp(
context,
rawProps,
"borderLeftWidth",
sourceValue.border(YGEdgeLeft),
yogaStyle.border(YGEdgeLeft)));
yogaStyle.setBorder(
YGEdgeTop,
convertRawProp(
context,
rawProps,
"borderTopWidth",
sourceValue.border(YGEdgeTop),
yogaStyle.border(YGEdgeTop)));
yogaStyle.setBorder(
YGEdgeRight,
convertRawProp(
context,
rawProps,
"borderRightWidth",
sourceValue.border(YGEdgeRight),
yogaStyle.border(YGEdgeRight)));
yogaStyle.setBorder(
YGEdgeBottom,
convertRawProp(
context,
rawProps,
"borderBottomWidth",
sourceValue.border(YGEdgeBottom),
yogaStyle.border(YGEdgeBottom)));
yogaStyle.setBorder(
YGEdgeStart,
convertRawProp(
context,
rawProps,
"borderStartWidth",
sourceValue.border(YGEdgeStart),
yogaStyle.border(YGEdgeStart)));
yogaStyle.setBorder(
YGEdgeEnd,
convertRawProp(
context,
rawProps,
"borderEndWidth",
sourceValue.border(YGEdgeEnd),
yogaStyle.border(YGEdgeEnd)));
yogaStyle.setBorder(
YGEdgeHorizontal,
convertRawProp(
context,
rawProps,
"borderHorizontalWidth",
sourceValue.border(YGEdgeHorizontal),
yogaStyle.border(YGEdgeHorizontal)));
yogaStyle.setBorder(
YGEdgeVertical,
convertRawProp(
context,
rawProps,
"borderVerticalWidth",
sourceValue.border(YGEdgeVertical),
yogaStyle.border(YGEdgeVertical)));
yogaStyle.setBorder(
YGEdgeAll,
convertRawProp(
context,
rawProps,
"borderWidth",
sourceValue.border(YGEdgeAll),
yogaStyle.border(YGEdgeAll)));
yogaStyle.border() = convertRawProp(
context,
rawProps,
"border",
"Width",
sourceValue.border(),
yogaStyle.border());
yogaStyle.setDimension(
yoga::Dimension::Width,
@@ -103,8 +103,8 @@ class LayoutTest : public ::testing::Test {
auto &props = *sharedProps;
auto &yogaStyle = props.yogaStyle;
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(10));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(10));
yogaStyle.position()[YGEdgeLeft] = YGValue{10, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{10, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(30));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(90));
@@ -136,8 +136,8 @@ class LayoutTest : public ::testing::Test {
}
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(10));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(10));
yogaStyle.position()[YGEdgeLeft] = YGValue{10, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{10, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(110));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(20));
return sharedProps;
@@ -151,8 +151,8 @@ class LayoutTest : public ::testing::Test {
auto &props = *sharedProps;
auto &yogaStyle = props.yogaStyle;
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(70));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(-50));
yogaStyle.position()[YGEdgeLeft] = YGValue{70, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{-50, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(30));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(60));
return sharedProps;
@@ -166,8 +166,8 @@ class LayoutTest : public ::testing::Test {
auto &props = *sharedProps;
auto &yogaStyle = props.yogaStyle;
yogaStyle.positionType() = yoga::PositionType::Absolute;
yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::of<YGUnitPoint>(-60));
yogaStyle.setPosition(YGEdgeTop, yoga::CompactValue::of<YGUnitPoint>(50));
yogaStyle.position()[YGEdgeLeft] = YGValue{-60, YGUnitPoint};
yogaStyle.position()[YGEdgeTop] = YGValue{50, YGUnitPoint};
yogaStyle.setDimension(yoga::Dimension::Width, yoga::CompactValue::of<YGUnitPoint>(70));
yogaStyle.setDimension(yoga::Dimension::Height, yoga::CompactValue::of<YGUnitPoint>(20));
return sharedProps;
@@ -251,8 +251,8 @@ TEST_F(StackingContextTest, mostPropsDoNotForceViewsToMaterialize) {
mutateViewShadowNodeProps_(nodeAA_, [](ViewProps& props) {
auto& yogaStyle = props.yogaStyle;
yogaStyle.setPadding(YGEdgeAll, yoga::CompactValue::of<YGUnitPoint>(42));
yogaStyle.setMargin(YGEdgeAll, yoga::CompactValue::of<YGUnitPoint>(42));
yogaStyle.padding()[YGEdgeAll] = YGValue{42, YGUnitPoint};
yogaStyle.margin()[YGEdgeAll] = YGValue{42, YGUnitPoint};
yogaStyle.positionType() = yoga::PositionType::Absolute;
props.shadowRadius = 42;
props.shadowOffset = Size{42, 42};
@@ -262,7 +262,7 @@ TEST_F(StackingContextTest, mostPropsDoNotForceViewsToMaterialize) {
mutateViewShadowNodeProps_(nodeBA_, [](ViewProps& props) {
auto& yogaStyle = props.yogaStyle;
props.zIndex = 42;
yogaStyle.setMargin(YGEdgeAll, yoga::CompactValue::of<YGUnitPoint>(42));
yogaStyle.margin()[YGEdgeAll] = YGValue{42, YGUnitPoint};
props.shadowColor = clearColor();
props.shadowOpacity = 0.42;
});
@@ -35,6 +35,19 @@ void updateStyle(YGNodeRef node, Ref (Style::*prop)(), T value) {
[prop](Style& s, T x) { (s.*prop)() = x; });
}
template <typename Ref, typename Idx>
void updateIndexedStyleProp(
YGNodeRef node,
Ref (Style::*prop)(),
Idx idx,
CompactValue value) {
updateStyle(
resolveRef(node),
value,
[idx, prop](Style& s, CompactValue x) { return (s.*prop)()[idx] != x; },
[idx, prop](Style& s, CompactValue x) { (s.*prop)()[idx] = x; });
}
template <auto GetterT, auto SetterT, typename IdxT>
void updateIndexedStyleProp(YGNodeRef node, IdxT idx, CompactValue value) {
updateStyle(
@@ -224,53 +237,53 @@ YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) {
void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float points) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
updateIndexedStyleProp<&Style::position, &Style::setPosition>(
node, edge, value);
updateIndexedStyleProp<MSVC_HINT(position)>(
node, &Style::position, edge, value);
}
void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float percent) {
auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
updateIndexedStyleProp<&Style::position, &Style::setPosition>(
node, edge, value);
updateIndexedStyleProp<MSVC_HINT(position)>(
node, &Style::position, edge, value);
}
YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) {
return resolveRef(node)->getStyle().position(edge);
return resolveRef(node)->getStyle().position()[edge];
}
void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value);
updateIndexedStyleProp<MSVC_HINT(margin)>(node, &Style::margin, edge, value);
}
void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, float percent) {
auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value);
updateIndexedStyleProp<MSVC_HINT(margin)>(node, &Style::margin, edge, value);
}
void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) {
updateIndexedStyleProp<&Style::margin, &Style::setMargin>(
node, edge, CompactValue::ofAuto());
updateIndexedStyleProp<MSVC_HINT(margin)>(
node, &Style::margin, edge, CompactValue::ofAuto());
}
YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) {
return resolveRef(node)->getStyle().margin(edge);
return resolveRef(node)->getStyle().margin()[edge];
}
void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(points);
updateIndexedStyleProp<&Style::padding, &Style::setPadding>(
node, edge, value);
updateIndexedStyleProp<MSVC_HINT(padding)>(
node, &Style::padding, edge, value);
}
void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) {
auto value = CompactValue::ofMaybe<YGUnitPercent>(percent);
updateIndexedStyleProp<&Style::padding, &Style::setPadding>(
node, edge, value);
updateIndexedStyleProp<MSVC_HINT(padding)>(
node, &Style::padding, edge, value);
}
YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) {
return resolveRef(node)->getStyle().padding(edge);
return resolveRef(node)->getStyle().padding()[edge];
}
void YGNodeStyleSetBorder(
@@ -278,11 +291,11 @@ void YGNodeStyleSetBorder(
const YGEdge edge,
const float border) {
auto value = CompactValue::ofMaybe<YGUnitPoint>(border);
updateIndexedStyleProp<&Style::border, &Style::setBorder>(node, edge, value);
updateIndexedStyleProp<MSVC_HINT(border)>(node, &Style::border, edge, value);
}
float YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) {
auto border = resolveRef(node)->getStyle().border(edge);
auto border = resolveRef(node)->getStyle().border()[edge];
if (border.isUndefined() || border.isAuto()) {
return YGUndefined;
}
@@ -11,7 +11,6 @@
#include <yoga/debug/AssertFatal.h>
#include <yoga/enums/Dimension.h>
#include <yoga/enums/Direction.h>
#include <yoga/enums/FlexDirection.h>
namespace facebook::yoga {
@@ -7,10 +7,8 @@
#include <stdexcept>
#include <yoga/config/Config.h>
#include <yoga/debug/AssertFatal.h>
#include <yoga/debug/Log.h>
#include <yoga/node/Node.h>
namespace facebook::yoga {
@@ -8,12 +8,11 @@
#pragma once
#include <yoga/Yoga.h>
#include <yoga/config/Config.h>
#include <yoga/node/Node.h>
namespace facebook::yoga {
class Node;
class Config;
[[noreturn]] void fatalWithMessage(const char* message);
void assertFatal(bool condition, const char* message);
@@ -23,6 +23,12 @@ static void indent(std::string& base, uint32_t level) {
}
}
static bool areFourValuesEqual(const Style::Edges& four) {
return yoga::inexactEquals(four[0], four[1]) &&
yoga::inexactEquals(four[0], four[2]) &&
yoga::inexactEquals(four[0], four[3]);
}
static void appendFormattedString(std::string& str, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
@@ -80,15 +86,33 @@ static void appendNumberIfNotZero(
}
}
template <auto Field>
static void
appendEdges(std::string& base, const std::string& key, const Style& style) {
for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) {
std::string str = key + "-" + YGEdgeToString(static_cast<YGEdge>(edge));
appendNumberIfNotZero(base, str, (style.*Field)(static_cast<YGEdge>(edge)));
static void appendEdges(
std::string& base,
const std::string& key,
const Style::Edges& edges) {
if (areFourValuesEqual(edges)) {
auto edgeValue = yoga::Node::computeEdgeValueForColumn(edges, YGEdgeLeft);
appendNumberIfNotUndefined(base, key, edgeValue);
} else {
for (int edge = YGEdgeLeft; edge != YGEdgeAll; ++edge) {
std::string str = key + "-" + YGEdgeToString(static_cast<YGEdge>(edge));
appendNumberIfNotZero(base, str, edges[static_cast<size_t>(edge)]);
}
}
}
static void appendEdgeIfNotUndefined(
std::string& base,
const std::string& str,
const Style::Edges& edges,
const YGEdge edge) {
// TODO: this doesn't take RTL / YGEdgeStart / YGEdgeEnd into account
auto value = (edge == YGEdgeLeft || edge == YGEdgeRight)
? yoga::Node::computeEdgeValueForRow(edges, edge, edge)
: yoga::Node::computeEdgeValueForColumn(edges, edge);
appendNumberIfNotUndefined(base, str, value);
}
void nodeToString(
std::string& str,
const yoga::Node* node,
@@ -149,9 +173,9 @@ void nodeToString(
if (style.display() != yoga::Node{}.getStyle().display()) {
appendFormattedString(str, "display: %s; ", toString(style.display()));
}
appendEdges<&Style::margin>(str, "margin", style);
appendEdges<&Style::padding>(str, "padding", style);
appendEdges<&Style::border>(str, "border", style);
appendEdges(str, "margin", style.margin());
appendEdges(str, "padding", style.padding());
appendEdges(str, "border", style.border());
if (style.gap(Gutter::All).isDefined()) {
appendNumberIfNotUndefined(str, "gap", style.gap(Gutter::All));
@@ -176,7 +200,10 @@ void nodeToString(
str, "position: %s; ", toString(style.positionType()));
}
appendEdges<&Style::position>(str, "position", style);
appendEdgeIfNotUndefined(str, "left", style.position(), YGEdgeLeft);
appendEdgeIfNotUndefined(str, "right", style.position(), YGEdgeRight);
appendEdgeIfNotUndefined(str, "top", style.position(), YGEdgeTop);
appendEdgeIfNotUndefined(str, "bottom", style.position(), YGEdgeBottom);
appendFormattedString(str, "\" ");
if (node->hasMeasureFunc()) {
@@ -56,29 +56,30 @@ void Node::print() {
}
}
// TODO: Edge value resolution should be moved to `yoga::Style`
template <auto Field>
CompactValue Node::computeEdgeValueForRow(YGEdge rowEdge, YGEdge edge) const {
if ((style_.*Field)(rowEdge).isDefined()) {
return (style_.*Field)(rowEdge);
} else if ((style_.*Field)(edge).isDefined()) {
return (style_.*Field)(edge);
} else if ((style_.*Field)(YGEdgeHorizontal).isDefined()) {
return (style_.*Field)(YGEdgeHorizontal);
CompactValue Node::computeEdgeValueForRow(
const Style::Edges& edges,
YGEdge rowEdge,
YGEdge edge) {
if (edges[rowEdge].isDefined()) {
return edges[rowEdge];
} else if (edges[edge].isDefined()) {
return edges[edge];
} else if (edges[YGEdgeHorizontal].isDefined()) {
return edges[YGEdgeHorizontal];
} else {
return (style_.*Field)(YGEdgeAll);
return edges[YGEdgeAll];
}
}
// TODO: Edge value resolution should be moved to `yoga::Style`
template <auto Field>
CompactValue Node::computeEdgeValueForColumn(YGEdge edge) const {
if ((style_.*Field)(edge).isDefined()) {
return (style_.*Field)(edge);
} else if ((style_.*Field)(YGEdgeVertical).isDefined()) {
return (style_.*Field)(YGEdgeVertical);
CompactValue Node::computeEdgeValueForColumn(
const Style::Edges& edges,
YGEdge edge) {
if (edges[edge].isDefined()) {
return edges[edge];
} else if (edges[YGEdgeVertical].isDefined()) {
return edges[YGEdgeVertical];
} else {
return (style_.*Field)(YGEdgeAll);
return edges[YGEdgeAll];
}
}
@@ -101,8 +102,8 @@ YGEdge Node::getInlineEndEdgeUsingErrata(
bool Node::isFlexStartPositionDefined(FlexDirection axis) const {
const YGEdge startEdge = flexStartEdge(axis);
auto leadingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::position>(startEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.position(), startEdge);
return leadingPosition.isDefined();
}
@@ -111,8 +112,8 @@ bool Node::isInlineStartPositionDefined(FlexDirection axis, Direction direction)
const {
const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction);
auto leadingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::position>(startEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.position(), startEdge);
return leadingPosition.isDefined();
}
@@ -120,8 +121,8 @@ bool Node::isInlineStartPositionDefined(FlexDirection axis, Direction direction)
bool Node::isFlexEndPositionDefined(FlexDirection axis) const {
const YGEdge endEdge = flexEndEdge(axis);
auto trailingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::position>(endEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.position(), endEdge);
return !trailingPosition.isUndefined();
}
@@ -130,8 +131,8 @@ bool Node::isInlineEndPositionDefined(FlexDirection axis, Direction direction)
const {
const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction);
auto trailingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::position>(endEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.position(), endEdge);
return trailingPosition.isDefined();
}
@@ -139,8 +140,8 @@ bool Node::isInlineEndPositionDefined(FlexDirection axis, Direction direction)
float Node::getFlexStartPosition(FlexDirection axis, float axisSize) const {
const YGEdge startEdge = flexStartEdge(axis);
auto leadingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::position>(startEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.position(), startEdge);
return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f);
}
@@ -151,8 +152,8 @@ float Node::getInlineStartPosition(
float axisSize) const {
const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction);
auto leadingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::position>(startEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.position(), startEdge);
return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f);
}
@@ -160,8 +161,8 @@ float Node::getInlineStartPosition(
float Node::getFlexEndPosition(FlexDirection axis, float axisSize) const {
const YGEdge endEdge = flexEndEdge(axis);
auto trailingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::position>(endEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.position(), endEdge);
return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f);
}
@@ -172,8 +173,8 @@ float Node::getInlineEndPosition(
float axisSize) const {
const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction);
auto trailingPosition = isRow(axis)
? computeEdgeValueForRow<&Style::position>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::position>(endEdge);
? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.position(), endEdge);
return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f);
}
@@ -181,8 +182,8 @@ float Node::getInlineEndPosition(
float Node::getFlexStartMargin(FlexDirection axis, float widthSize) const {
const YGEdge startEdge = flexStartEdge(axis);
auto leadingMargin = isRow(axis)
? computeEdgeValueForRow<&Style::margin>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::margin>(startEdge);
? computeEdgeValueForRow(style_.margin(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.margin(), startEdge);
return resolveValue(leadingMargin, widthSize).unwrapOrDefault(0.0f);
}
@@ -193,8 +194,8 @@ float Node::getInlineStartMargin(
float widthSize) const {
const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction);
auto leadingMargin = isRow(axis)
? computeEdgeValueForRow<&Style::margin>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::margin>(startEdge);
? computeEdgeValueForRow(style_.margin(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.margin(), startEdge);
return resolveValue(leadingMargin, widthSize).unwrapOrDefault(0.0f);
}
@@ -202,8 +203,8 @@ float Node::getInlineStartMargin(
float Node::getFlexEndMargin(FlexDirection axis, float widthSize) const {
const YGEdge endEdge = flexEndEdge(axis);
auto trailingMargin = isRow(axis)
? computeEdgeValueForRow<&Style::margin>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::margin>(endEdge);
? computeEdgeValueForRow(style_.margin(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.margin(), endEdge);
return resolveValue(trailingMargin, widthSize).unwrapOrDefault(0.0f);
}
@@ -214,8 +215,8 @@ float Node::getInlineEndMargin(
float widthSize) const {
const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction);
auto trailingMargin = isRow(axis)
? computeEdgeValueForRow<&Style::margin>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::margin>(endEdge);
? computeEdgeValueForRow(style_.margin(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.margin(), endEdge);
return resolveValue(trailingMargin, widthSize).unwrapOrDefault(0.0f);
}
@@ -224,8 +225,8 @@ float Node::getInlineStartBorder(FlexDirection axis, Direction direction)
const {
const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction);
YGValue leadingBorder = isRow(axis)
? computeEdgeValueForRow<&Style::border>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::border>(startEdge);
? computeEdgeValueForRow(style_.border(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.border(), startEdge);
return maxOrDefined(leadingBorder.value, 0.0f);
}
@@ -234,9 +235,9 @@ float Node::getFlexStartBorder(FlexDirection axis, Direction direction) const {
const YGEdge leadRelativeFlexItemEdge =
flexStartRelativeEdge(axis, direction);
YGValue leadingBorder = isRow(axis)
? computeEdgeValueForRow<&Style::border>(
leadRelativeFlexItemEdge, flexStartEdge(axis))
: computeEdgeValueForColumn<&Style::border>(flexStartEdge(axis));
? computeEdgeValueForRow(
style_.border(), leadRelativeFlexItemEdge, flexStartEdge(axis))
: computeEdgeValueForColumn(style_.border(), flexStartEdge(axis));
return maxOrDefined(leadingBorder.value, 0.0f);
}
@@ -244,8 +245,8 @@ float Node::getFlexStartBorder(FlexDirection axis, Direction direction) const {
float Node::getInlineEndBorder(FlexDirection axis, Direction direction) const {
const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction);
YGValue trailingBorder = isRow(axis)
? computeEdgeValueForRow<&Style::border>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::border>(endEdge);
? computeEdgeValueForRow(style_.border(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.border(), endEdge);
return maxOrDefined(trailingBorder.value, 0.0f);
}
@@ -253,9 +254,9 @@ float Node::getInlineEndBorder(FlexDirection axis, Direction direction) const {
float Node::getFlexEndBorder(FlexDirection axis, Direction direction) const {
const YGEdge trailRelativeFlexItemEdge = flexEndRelativeEdge(axis, direction);
YGValue trailingBorder = isRow(axis)
? computeEdgeValueForRow<&Style::border>(
trailRelativeFlexItemEdge, flexEndEdge(axis))
: computeEdgeValueForColumn<&Style::border>(flexEndEdge(axis));
? computeEdgeValueForRow(
style_.border(), trailRelativeFlexItemEdge, flexEndEdge(axis))
: computeEdgeValueForColumn(style_.border(), flexEndEdge(axis));
return maxOrDefined(trailingBorder.value, 0.0f);
}
@@ -266,8 +267,8 @@ float Node::getInlineStartPadding(
float widthSize) const {
const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction);
auto leadingPadding = isRow(axis)
? computeEdgeValueForRow<&Style::padding>(YGEdgeStart, startEdge)
: computeEdgeValueForColumn<&Style::padding>(startEdge);
? computeEdgeValueForRow(style_.padding(), YGEdgeStart, startEdge)
: computeEdgeValueForColumn(style_.padding(), startEdge);
return maxOrDefined(resolveValue(leadingPadding, widthSize).unwrap(), 0.0f);
}
@@ -279,9 +280,9 @@ float Node::getFlexStartPadding(
const YGEdge leadRelativeFlexItemEdge =
flexStartRelativeEdge(axis, direction);
auto leadingPadding = isRow(axis)
? computeEdgeValueForRow<&Style::padding>(
leadRelativeFlexItemEdge, flexStartEdge(axis))
: computeEdgeValueForColumn<&Style::padding>(flexStartEdge(axis));
? computeEdgeValueForRow(
style_.padding(), leadRelativeFlexItemEdge, flexStartEdge(axis))
: computeEdgeValueForColumn(style_.padding(), flexStartEdge(axis));
return maxOrDefined(resolveValue(leadingPadding, widthSize).unwrap(), 0.0f);
}
@@ -292,8 +293,8 @@ float Node::getInlineEndPadding(
float widthSize) const {
const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction);
auto trailingPadding = isRow(axis)
? computeEdgeValueForRow<&Style::padding>(YGEdgeEnd, endEdge)
: computeEdgeValueForColumn<&Style::padding>(endEdge);
? computeEdgeValueForRow(style_.padding(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.padding(), endEdge);
return maxOrDefined(resolveValue(trailingPadding, widthSize).unwrap(), 0.0f);
}
@@ -304,9 +305,9 @@ float Node::getFlexEndPadding(
float widthSize) const {
const YGEdge trailRelativeFlexItemEdge = flexEndRelativeEdge(axis, direction);
auto trailingPadding = isRow(axis)
? computeEdgeValueForRow<&Style::padding>(
trailRelativeFlexItemEdge, flexEndEdge(axis))
: computeEdgeValueForColumn<&Style::padding>(flexEndEdge(axis));
? computeEdgeValueForRow(
style_.padding(), trailRelativeFlexItemEdge, flexEndEdge(axis))
: computeEdgeValueForColumn(style_.padding(), flexEndEdge(axis));
return maxOrDefined(resolveValue(trailingPadding, widthSize).unwrap(), 0.0f);
}
@@ -564,18 +565,18 @@ void Node::setPosition(
}
YGValue Node::getFlexStartMarginValue(FlexDirection axis) const {
if (isRow(axis) && style_.margin(YGEdgeStart).isDefined()) {
return style_.margin(YGEdgeStart);
if (isRow(axis) && style_.margin()[YGEdgeStart].isDefined()) {
return style_.margin()[YGEdgeStart];
} else {
return style_.margin(flexStartEdge(axis));
return style_.margin()[flexStartEdge(axis)];
}
}
YGValue Node::marginTrailingValue(FlexDirection axis) const {
if (isRow(axis) && style_.margin(YGEdgeEnd).isDefined()) {
return style_.margin(YGEdgeEnd);
if (isRow(axis) && style_.margin()[YGEdgeEnd].isDefined()) {
return style_.margin()[YGEdgeEnd];
} else {
return style_.margin(flexEndEdge(axis));
return style_.margin()[flexEndEdge(axis)];
}
}
@@ -65,12 +65,6 @@ class YG_EXPORT Node : public ::YGNode {
style_.alignContent() = Align::Stretch;
}
template <auto Field>
CompactValue computeEdgeValueForColumn(YGEdge edge) const;
template <auto Field>
CompactValue computeEdgeValueForRow(YGEdge rowEdge, YGEdge edge) const;
// DANGER DANGER DANGER!
// If the node assigned to has children, we'd either have to deallocate
// them (potentially incorrect) or ignore them (danger of leaks). Only ever
@@ -195,6 +189,15 @@ class YG_EXPORT Node : public ::YGNode {
return resolvedDimensions_[static_cast<size_t>(dimension)];
}
static CompactValue computeEdgeValueForColumn(
const Style::Edges& edges,
YGEdge edge);
static CompactValue computeEdgeValueForRow(
const Style::Edges& edges,
YGEdge rowEdge,
YGEdge edge);
// Methods related to positions, margin, padding and border
bool isFlexStartPositionDefined(FlexDirection axis) const;
bool isInlineStartPositionDefined(FlexDirection axis, Direction direction)
@@ -34,11 +34,11 @@ class YG_EXPORT Style {
template <typename Enum>
using Values = std::array<CompactValue, ordinalCount<Enum>()>;
public:
using Dimensions = Values<Dimension>;
using Edges = Values<YGEdge>;
using Gutters = Values<Gutter>;
public:
static constexpr float DefaultFlexGrow = 0.0f;
static constexpr float DefaultFlexShrink = 0.0f;
static constexpr float WebDefaultFlexShrink = 1.0f;
@@ -68,6 +68,39 @@ class YG_EXPORT Style {
}
};
template <typename Idx, Values<Idx> Style::*Prop>
struct IdxRef {
struct Ref {
Style& style;
Idx idx;
operator CompactValue() const {
return (style.*Prop)[idx];
}
operator YGValue() const {
return (style.*Prop)[idx];
}
Ref& operator=(CompactValue value) {
(style.*Prop)[idx] = value;
return *this;
}
};
Style& style;
IdxRef<Idx, Prop>& operator=(const Values<Idx>& values) {
style.*Prop = values;
return *this;
}
operator const Values<Idx>&() const {
return style.*Prop;
}
Ref operator[](Idx idx) {
return {style, idx};
}
CompactValue operator[](Idx idx) const {
return (style.*Prop)[idx];
}
};
Style() {
alignContent() = Align::FlexStart;
alignItems() = Align::Stretch;
@@ -113,6 +146,9 @@ class YG_EXPORT Style {
FloatOptional aspectRatio_ = {};
public:
// for library users needing a type
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
Direction direction() const {
return getEnumData<Direction>(flags, directionOffset);
}
@@ -211,32 +247,32 @@ class YG_EXPORT Style {
return {*this};
}
CompactValue margin(YGEdge edge) const {
return margin_[edge];
const Edges& margin() const {
return margin_;
}
void setMargin(YGEdge edge, CompactValue value) {
margin_[edge] = value;
IdxRef<YGEdge, &Style::margin_> margin() {
return {*this};
}
CompactValue position(YGEdge edge) const {
return position_[edge];
const Edges& position() const {
return position_;
}
void setPosition(YGEdge edge, CompactValue value) {
position_[edge] = value;
IdxRef<YGEdge, &Style::position_> position() {
return {*this};
}
CompactValue padding(YGEdge edge) const {
return padding_[edge];
const Edges& padding() const {
return padding_;
}
void setPadding(YGEdge edge, CompactValue value) {
padding_[edge] = value;
IdxRef<YGEdge, &Style::padding_> padding() {
return {*this};
}
CompactValue border(YGEdge edge) const {
return border_[edge];
const Edges& border() const {
return border_;
}
void setBorder(YGEdge edge, CompactValue value) {
border_[edge] = value;
IdxRef<YGEdge, &Style::border_> border() {
return {*this};
}
CompactValue gap(Gutter gutter) const {