Simplify Edge Resolution (#1550)
Summary: X-link: https://github.com/facebook/react-native/pull/42254 Pull Request resolved: https://github.com/facebook/yoga/pull/1550 This change aims to simplify how we resolve edges. This operation happens many, many times, and has gotten complex and slow when paired with StyleValuePool. This starts reshaping so that `yoga::Style` can resolve a style prop for a given edge. This is closer to the ideal computed style API to avoid recalcing this so many times, but doesn't address that. This relies on removing the errata related to row-reverse, and cleans up the removal started in the last change. This has no measurable perf effect under CompactValue, but has a >10% uplift in perf when using StyleValueHandle, where we can trivially check if a handle points to a defined value without resolving it, but only within `yoga::Style` since we don't expose the handle outside of it. More quantifiably, we go from 2.35 million StyleValuePool reads to 993k. The rest are checks on the handle. Reviewed By: joevilches Differential Revision: D52605596 fbshipit-source-id: 0b366963a899e376f99ce3d75cd5f14a25d60cec
This commit is contained in:
committed by
Facebook GitHub Bot
parent
35b9b5223e
commit
8744792f41
@@ -25,39 +25,39 @@ float getResolvedLayoutProperty(const YGNodeConstRef nodeRef, const Edge edge) {
|
||||
|
||||
if (edge == Edge::Start) {
|
||||
if (node->getLayout().direction() == Direction::RTL) {
|
||||
return (node->getLayout().*LayoutMember)(Edge::Right);
|
||||
return (node->getLayout().*LayoutMember)(PhysicalEdge::Right);
|
||||
} else {
|
||||
return (node->getLayout().*LayoutMember)(Edge::Left);
|
||||
return (node->getLayout().*LayoutMember)(PhysicalEdge::Left);
|
||||
}
|
||||
}
|
||||
|
||||
if (edge == Edge::End) {
|
||||
if (node->getLayout().direction() == Direction::RTL) {
|
||||
return (node->getLayout().*LayoutMember)(Edge::Left);
|
||||
return (node->getLayout().*LayoutMember)(PhysicalEdge::Left);
|
||||
} else {
|
||||
return (node->getLayout().*LayoutMember)(Edge::Right);
|
||||
return (node->getLayout().*LayoutMember)(PhysicalEdge::Right);
|
||||
}
|
||||
}
|
||||
|
||||
return (node->getLayout().*LayoutMember)(edge);
|
||||
return (node->getLayout().*LayoutMember)(static_cast<PhysicalEdge>(edge));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
float YGNodeLayoutGetLeft(const YGNodeConstRef node) {
|
||||
return resolveRef(node)->getLayout().position(Edge::Left);
|
||||
return resolveRef(node)->getLayout().position(PhysicalEdge::Left);
|
||||
}
|
||||
|
||||
float YGNodeLayoutGetTop(const YGNodeConstRef node) {
|
||||
return resolveRef(node)->getLayout().position(Edge::Top);
|
||||
return resolveRef(node)->getLayout().position(PhysicalEdge::Top);
|
||||
}
|
||||
|
||||
float YGNodeLayoutGetRight(const YGNodeConstRef node) {
|
||||
return resolveRef(node)->getLayout().position(Edge::Right);
|
||||
return resolveRef(node)->getLayout().position(PhysicalEdge::Right);
|
||||
}
|
||||
|
||||
float YGNodeLayoutGetBottom(const YGNodeConstRef node) {
|
||||
return resolveRef(node)->getLayout().position(Edge::Bottom);
|
||||
return resolveRef(node)->getLayout().position(PhysicalEdge::Bottom);
|
||||
}
|
||||
|
||||
float YGNodeLayoutGetWidth(const YGNodeConstRef node) {
|
||||
|
@@ -20,7 +20,8 @@ static inline void setFlexStartLayoutPosition(
|
||||
const FlexDirection axis,
|
||||
const float containingBlockWidth) {
|
||||
child->setLayoutPosition(
|
||||
child->getFlexStartMargin(axis, direction, containingBlockWidth) +
|
||||
child->style().computeFlexStartMargin(
|
||||
axis, direction, containingBlockWidth) +
|
||||
parent->getLayout().border(flexStartEdge(axis)) +
|
||||
parent->getLayout().padding(flexStartEdge(axis)),
|
||||
flexStartEdge(axis));
|
||||
@@ -36,7 +37,8 @@ static inline void setFlexEndLayoutPosition(
|
||||
getPositionOfOppositeEdge(
|
||||
parent->getLayout().border(flexEndEdge(axis)) +
|
||||
parent->getLayout().padding(flexEndEdge(axis)) +
|
||||
child->getFlexEndMargin(axis, direction, containingBlockWidth),
|
||||
child->style().computeFlexEndMargin(
|
||||
axis, direction, containingBlockWidth),
|
||||
axis,
|
||||
parent,
|
||||
child),
|
||||
@@ -57,12 +59,13 @@ static inline void setCenterLayoutPosition(
|
||||
parent->getLayout().padding(flexEndEdge(axis));
|
||||
const float childOuterSize =
|
||||
child->getLayout().measuredDimension(dimension(axis)) +
|
||||
child->getMarginForAxis(axis, containingBlockWidth);
|
||||
child->style().computeMarginForAxis(axis, containingBlockWidth);
|
||||
child->setLayoutPosition(
|
||||
(parentContentBoxSize - childOuterSize) / 2.0f +
|
||||
parent->getLayout().border(flexStartEdge(axis)) +
|
||||
parent->getLayout().padding(flexStartEdge(axis)) +
|
||||
child->getFlexStartMargin(axis, direction, containingBlockWidth),
|
||||
child->style().computeFlexStartMargin(
|
||||
axis, direction, containingBlockWidth),
|
||||
flexStartEdge(axis));
|
||||
}
|
||||
|
||||
@@ -150,30 +153,32 @@ static void positionAbsoluteChildLegacy(
|
||||
: ((resolveChildAlignment(parent, child) == Align::FlexEnd) ^
|
||||
(parent->style().flexWrap() == Wrap::WrapReverse));
|
||||
|
||||
if (child->isFlexEndPositionDefined(axis, direction) &&
|
||||
!child->isFlexStartPositionDefined(axis, direction)) {
|
||||
if (child->style().isFlexEndPositionDefined(axis, direction) &&
|
||||
!child->style().isFlexStartPositionDefined(axis, direction)) {
|
||||
child->setLayoutPosition(
|
||||
containingNode->getLayout().measuredDimension(dimension(axis)) -
|
||||
child->getLayout().measuredDimension(dimension(axis)) -
|
||||
containingNode->getFlexEndBorder(axis, direction) -
|
||||
child->getFlexEndMargin(
|
||||
containingNode->style().computeFlexEndBorder(axis, direction) -
|
||||
child->style().computeFlexEndMargin(
|
||||
axis,
|
||||
direction,
|
||||
isAxisRow ? containingBlockWidth : containingBlockHeight) -
|
||||
child->getFlexEndPosition(
|
||||
child->style().computeFlexEndPosition(
|
||||
axis,
|
||||
direction,
|
||||
isAxisRow ? containingBlockWidth : containingBlockHeight),
|
||||
flexStartEdge(axis));
|
||||
} else if (
|
||||
!child->isFlexStartPositionDefined(axis, direction) && shouldCenter) {
|
||||
!child->style().isFlexStartPositionDefined(axis, direction) &&
|
||||
shouldCenter) {
|
||||
child->setLayoutPosition(
|
||||
(parent->getLayout().measuredDimension(dimension(axis)) -
|
||||
child->getLayout().measuredDimension(dimension(axis))) /
|
||||
2.0f,
|
||||
flexStartEdge(axis));
|
||||
} else if (
|
||||
!child->isFlexStartPositionDefined(axis, direction) && shouldFlexEnd) {
|
||||
!child->style().isFlexStartPositionDefined(axis, direction) &&
|
||||
shouldFlexEnd) {
|
||||
child->setLayoutPosition(
|
||||
(parent->getLayout().measuredDimension(dimension(axis)) -
|
||||
child->getLayout().measuredDimension(dimension(axis))),
|
||||
@@ -218,11 +223,13 @@ static void positionAbsoluteChildImpl(
|
||||
// to the flex-start edge because this algorithm works by positioning on the
|
||||
// flex-start edge and then filling in the flex-end direction at the end if
|
||||
// necessary.
|
||||
if (child->isInlineStartPositionDefined(axis, direction)) {
|
||||
if (child->style().isInlineStartPositionDefined(axis, direction)) {
|
||||
const float positionRelativeToInlineStart =
|
||||
child->getInlineStartPosition(axis, direction, containingBlockSize) +
|
||||
containingNode->getInlineStartBorder(axis, direction) +
|
||||
child->getInlineStartMargin(axis, direction, containingBlockSize);
|
||||
child->style().computeInlineStartPosition(
|
||||
axis, direction, containingBlockSize) +
|
||||
containingNode->style().computeInlineStartBorder(axis, direction) +
|
||||
child->style().computeInlineStartMargin(
|
||||
axis, direction, containingBlockSize);
|
||||
const float positionRelativeToFlexStart =
|
||||
inlineStartEdge(axis, direction) != flexStartEdge(axis)
|
||||
? getPositionOfOppositeEdge(
|
||||
@@ -230,13 +237,15 @@ static void positionAbsoluteChildImpl(
|
||||
: positionRelativeToInlineStart;
|
||||
|
||||
child->setLayoutPosition(positionRelativeToFlexStart, flexStartEdge(axis));
|
||||
} else if (child->isInlineEndPositionDefined(axis, direction)) {
|
||||
} else if (child->style().isInlineEndPositionDefined(axis, direction)) {
|
||||
const float positionRelativeToInlineStart =
|
||||
containingNode->getLayout().measuredDimension(dimension(axis)) -
|
||||
child->getLayout().measuredDimension(dimension(axis)) -
|
||||
containingNode->getInlineEndBorder(axis, direction) -
|
||||
child->getInlineEndMargin(axis, direction, containingBlockSize) -
|
||||
child->getInlineEndPosition(axis, direction, containingBlockSize);
|
||||
containingNode->style().computeInlineEndBorder(axis, direction) -
|
||||
child->style().computeInlineEndMargin(
|
||||
axis, direction, containingBlockSize) -
|
||||
child->style().computeInlineEndPosition(
|
||||
axis, direction, containingBlockSize);
|
||||
const float positionRelativeToFlexStart =
|
||||
inlineStartEdge(axis, direction) != flexStartEdge(axis)
|
||||
? getPositionOfOppositeEdge(
|
||||
@@ -303,10 +312,10 @@ void layoutAbsoluteChild(
|
||||
SizingMode childWidthSizingMode = SizingMode::MaxContent;
|
||||
SizingMode childHeightSizingMode = SizingMode::MaxContent;
|
||||
|
||||
auto marginRow =
|
||||
child->getMarginForAxis(FlexDirection::Row, containingBlockWidth);
|
||||
auto marginColumn =
|
||||
child->getMarginForAxis(FlexDirection::Column, containingBlockWidth);
|
||||
auto marginRow = child->style().computeMarginForAxis(
|
||||
FlexDirection::Row, containingBlockWidth);
|
||||
auto marginColumn = child->style().computeMarginForAxis(
|
||||
FlexDirection::Column, containingBlockWidth);
|
||||
|
||||
if (child->hasDefiniteLength(Dimension::Width, containingBlockWidth)) {
|
||||
childWidth = child->getResolvedDimension(Dimension::Width)
|
||||
@@ -316,15 +325,19 @@ void layoutAbsoluteChild(
|
||||
} else {
|
||||
// If the child doesn't have a specified width, compute the width based on
|
||||
// the left/right offsets if they're defined.
|
||||
if (child->isFlexStartPositionDefined(FlexDirection::Row, direction) &&
|
||||
child->isFlexEndPositionDefined(FlexDirection::Row, direction)) {
|
||||
if (child->style().isFlexStartPositionDefined(
|
||||
FlexDirection::Row, direction) &&
|
||||
child->style().isFlexEndPositionDefined(
|
||||
FlexDirection::Row, direction)) {
|
||||
childWidth =
|
||||
containingNode->getLayout().measuredDimension(Dimension::Width) -
|
||||
(containingNode->getFlexStartBorder(FlexDirection::Row, direction) +
|
||||
containingNode->getFlexEndBorder(FlexDirection::Row, direction)) -
|
||||
(child->getFlexStartPosition(
|
||||
(containingNode->style().computeFlexStartBorder(
|
||||
FlexDirection::Row, direction) +
|
||||
containingNode->style().computeFlexEndBorder(
|
||||
FlexDirection::Row, direction)) -
|
||||
(child->style().computeFlexStartPosition(
|
||||
FlexDirection::Row, direction, containingBlockWidth) +
|
||||
child->getFlexEndPosition(
|
||||
child->style().computeFlexEndPosition(
|
||||
FlexDirection::Row, direction, containingBlockWidth));
|
||||
childWidth = boundAxis(
|
||||
child,
|
||||
@@ -343,16 +356,19 @@ void layoutAbsoluteChild(
|
||||
} else {
|
||||
// If the child doesn't have a specified height, compute the height based
|
||||
// on the top/bottom offsets if they're defined.
|
||||
if (child->isFlexStartPositionDefined(FlexDirection::Column, direction) &&
|
||||
child->isFlexEndPositionDefined(FlexDirection::Column, direction)) {
|
||||
if (child->style().isFlexStartPositionDefined(
|
||||
FlexDirection::Column, direction) &&
|
||||
child->style().isFlexEndPositionDefined(
|
||||
FlexDirection::Column, direction)) {
|
||||
childHeight =
|
||||
containingNode->getLayout().measuredDimension(Dimension::Height) -
|
||||
(containingNode->getFlexStartBorder(
|
||||
(containingNode->style().computeFlexStartBorder(
|
||||
FlexDirection::Column, direction) +
|
||||
containingNode->getFlexEndBorder(FlexDirection::Column, direction)) -
|
||||
(child->getFlexStartPosition(
|
||||
containingNode->style().computeFlexEndBorder(
|
||||
FlexDirection::Column, direction)) -
|
||||
(child->style().computeFlexStartPosition(
|
||||
FlexDirection::Column, direction, containingBlockHeight) +
|
||||
child->getFlexEndPosition(
|
||||
child->style().computeFlexEndPosition(
|
||||
FlexDirection::Column, direction, containingBlockHeight));
|
||||
childHeight = boundAxis(
|
||||
child,
|
||||
@@ -414,9 +430,11 @@ void layoutAbsoluteChild(
|
||||
depth,
|
||||
generationCount);
|
||||
childWidth = child->getLayout().measuredDimension(Dimension::Width) +
|
||||
child->getMarginForAxis(FlexDirection::Row, containingBlockWidth);
|
||||
child->style().computeMarginForAxis(
|
||||
FlexDirection::Row, containingBlockWidth);
|
||||
childHeight = child->getLayout().measuredDimension(Dimension::Height) +
|
||||
child->getMarginForAxis(FlexDirection::Column, containingBlockWidth);
|
||||
child->style().computeMarginForAxis(
|
||||
FlexDirection::Column, containingBlockWidth);
|
||||
}
|
||||
|
||||
calculateLayoutInternal(
|
||||
@@ -479,11 +497,12 @@ void layoutAbsoluteDescendants(
|
||||
const float containingBlockWidth = absoluteErrata
|
||||
? containingNodeAvailableInnerWidth
|
||||
: containingNode->getLayout().measuredDimension(Dimension::Width) -
|
||||
containingNode->getBorderForAxis(FlexDirection::Row);
|
||||
containingNode->style().computeBorderForAxis(FlexDirection::Row);
|
||||
const float containingBlockHeight = absoluteErrata
|
||||
? containingNodeAvailableInnerHeight
|
||||
: containingNode->getLayout().measuredDimension(Dimension::Height) -
|
||||
containingNode->getBorderForAxis(FlexDirection::Column);
|
||||
containingNode->style().computeBorderForAxis(
|
||||
FlexDirection::Column);
|
||||
|
||||
layoutAbsoluteChild(
|
||||
containingNode,
|
||||
|
@@ -57,7 +57,7 @@ float calculateBaseline(const yoga::Node* node) {
|
||||
}
|
||||
|
||||
const float baseline = calculateBaseline(baselineChild);
|
||||
return baseline + baselineChild->getLayout().position(Edge::Top);
|
||||
return baseline + baselineChild->getLayout().position(PhysicalEdge::Top);
|
||||
}
|
||||
|
||||
bool isBaselineLayout(const yoga::Node* node) {
|
||||
|
@@ -22,8 +22,10 @@ inline float paddingAndBorderForAxis(
|
||||
const float widthSize) {
|
||||
// The total padding/border for a given axis does not depend on the direction
|
||||
// so hardcoding LTR here to avoid piping direction to this function
|
||||
return node->getInlineStartPaddingAndBorder(axis, Direction::LTR, widthSize) +
|
||||
node->getInlineEndPaddingAndBorder(axis, Direction::LTR, widthSize);
|
||||
return node->style().computeInlineStartPaddingAndBorder(
|
||||
axis, Direction::LTR, widthSize) +
|
||||
node->style().computeInlineEndPaddingAndBorder(
|
||||
axis, Direction::LTR, widthSize);
|
||||
}
|
||||
|
||||
inline FloatOptional boundAxisWithinMinAndMax(
|
||||
|
@@ -45,7 +45,7 @@ static void constrainMaxSizeForMode(
|
||||
/*in_out*/ float* size) {
|
||||
const FloatOptional maxSize =
|
||||
node->style().maxDimension(dimension(axis)).resolve(ownerAxisSize) +
|
||||
FloatOptional(node->getMarginForAxis(axis, ownerWidth));
|
||||
FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth));
|
||||
switch (*mode) {
|
||||
case SizingMode::StretchFit:
|
||||
case SizingMode::FitContent:
|
||||
@@ -126,9 +126,10 @@ static void computeFlexBasisForChild(
|
||||
childWidthSizingMode = SizingMode::MaxContent;
|
||||
childHeightSizingMode = SizingMode::MaxContent;
|
||||
|
||||
auto marginRow = child->getMarginForAxis(FlexDirection::Row, ownerWidth);
|
||||
auto marginRow =
|
||||
child->style().computeMarginForAxis(FlexDirection::Row, ownerWidth);
|
||||
auto marginColumn =
|
||||
child->getMarginForAxis(FlexDirection::Column, ownerWidth);
|
||||
child->style().computeMarginForAxis(FlexDirection::Column, ownerWidth);
|
||||
|
||||
if (isRowStyleDimDefined) {
|
||||
childWidth = child->getResolvedDimension(Dimension::Width)
|
||||
@@ -274,12 +275,12 @@ static void measureNodeWithMeasureFunc(
|
||||
}
|
||||
|
||||
const auto& layout = node->getLayout();
|
||||
const float paddingAndBorderAxisRow = layout.padding(Edge::Left) +
|
||||
layout.padding(Edge::Right) + layout.border(Edge::Left) +
|
||||
layout.border(Edge::Right);
|
||||
const float paddingAndBorderAxisColumn = layout.padding(Edge::Top) +
|
||||
layout.padding(Edge::Bottom) + layout.border(Edge::Top) +
|
||||
layout.border(Edge::Bottom);
|
||||
const float paddingAndBorderAxisRow = layout.padding(PhysicalEdge::Left) +
|
||||
layout.padding(PhysicalEdge::Right) + layout.border(PhysicalEdge::Left) +
|
||||
layout.border(PhysicalEdge::Right);
|
||||
const float paddingAndBorderAxisColumn = layout.padding(PhysicalEdge::Top) +
|
||||
layout.padding(PhysicalEdge::Bottom) + layout.border(PhysicalEdge::Top) +
|
||||
layout.border(PhysicalEdge::Bottom);
|
||||
|
||||
// We want to make sure we don't call measure with negative size
|
||||
const float innerWidth = yoga::isUndefined(availableWidth)
|
||||
@@ -369,8 +370,9 @@ static void measureNodeWithoutChildren(
|
||||
float width = availableWidth;
|
||||
if (widthSizingMode == SizingMode::MaxContent ||
|
||||
widthSizingMode == SizingMode::FitContent) {
|
||||
width = layout.padding(Edge::Left) + layout.padding(Edge::Right) +
|
||||
layout.border(Edge::Left) + layout.border(Edge::Right);
|
||||
width = layout.padding(PhysicalEdge::Left) +
|
||||
layout.padding(PhysicalEdge::Right) +
|
||||
layout.border(PhysicalEdge::Left) + layout.border(PhysicalEdge::Right);
|
||||
}
|
||||
node->setLayoutMeasuredDimension(
|
||||
boundAxis(node, FlexDirection::Row, width, ownerWidth, ownerWidth),
|
||||
@@ -379,8 +381,9 @@ static void measureNodeWithoutChildren(
|
||||
float height = availableHeight;
|
||||
if (heightSizingMode == SizingMode::MaxContent ||
|
||||
heightSizingMode == SizingMode::FitContent) {
|
||||
height = layout.padding(Edge::Top) + layout.padding(Edge::Bottom) +
|
||||
layout.border(Edge::Top) + layout.border(Edge::Bottom);
|
||||
height = layout.padding(PhysicalEdge::Top) +
|
||||
layout.padding(PhysicalEdge::Bottom) +
|
||||
layout.border(PhysicalEdge::Top) + layout.border(PhysicalEdge::Bottom);
|
||||
}
|
||||
node->setLayoutMeasuredDimension(
|
||||
boundAxis(node, FlexDirection::Column, height, ownerHeight, ownerWidth),
|
||||
@@ -555,7 +558,7 @@ static float computeFlexBasisForChildren(
|
||||
|
||||
totalOuterFlexBasis +=
|
||||
(child->getLayout().computedFlexBasis.unwrap() +
|
||||
child->getMarginForAxis(mainAxis, availableInnerWidth));
|
||||
child->style().computeMarginForAxis(mainAxis, availableInnerWidth));
|
||||
}
|
||||
|
||||
return totalOuterFlexBasis;
|
||||
@@ -570,6 +573,7 @@ static float distributeFreeSpaceSecondPass(
|
||||
yoga::Node* const node,
|
||||
const FlexDirection mainAxis,
|
||||
const FlexDirection crossAxis,
|
||||
const Direction direction,
|
||||
const float mainAxisownerSize,
|
||||
const float availableInnerMainDim,
|
||||
const float availableInnerCrossDim,
|
||||
@@ -642,10 +646,10 @@ static float distributeFreeSpaceSecondPass(
|
||||
|
||||
deltaFreeSpace += updatedMainSize - childFlexBasis;
|
||||
|
||||
const float marginMain =
|
||||
currentLineChild->getMarginForAxis(mainAxis, availableInnerWidth);
|
||||
const float marginCross =
|
||||
currentLineChild->getMarginForAxis(crossAxis, availableInnerWidth);
|
||||
const float marginMain = currentLineChild->style().computeMarginForAxis(
|
||||
mainAxis, availableInnerWidth);
|
||||
const float marginCross = currentLineChild->style().computeMarginForAxis(
|
||||
crossAxis, availableInnerWidth);
|
||||
|
||||
float childCrossSize;
|
||||
float childMainSize = updatedMainSize + marginMain;
|
||||
@@ -667,9 +671,9 @@ static float distributeFreeSpaceSecondPass(
|
||||
sizingModeCrossDim == SizingMode::StretchFit &&
|
||||
!(isNodeFlexWrap && mainAxisOverflows) &&
|
||||
resolveChildAlignment(node, currentLineChild) == Align::Stretch &&
|
||||
currentLineChild->getFlexStartMarginValue(crossAxis).unit() !=
|
||||
Unit::Auto &&
|
||||
currentLineChild->marginTrailingValue(crossAxis).unit() != Unit::Auto) {
|
||||
!currentLineChild->style().flexStartMarginIsAuto(
|
||||
crossAxis, direction) &&
|
||||
!currentLineChild->style().flexEndMarginIsAuto(crossAxis, direction)) {
|
||||
childCrossSize = availableInnerCrossDim;
|
||||
childCrossSizingMode = SizingMode::StretchFit;
|
||||
} else if (!currentLineChild->hasDefiniteLength(
|
||||
@@ -713,9 +717,9 @@ static float distributeFreeSpaceSecondPass(
|
||||
!currentLineChild->hasDefiniteLength(
|
||||
dimension(crossAxis), availableInnerCrossDim) &&
|
||||
resolveChildAlignment(node, currentLineChild) == Align::Stretch &&
|
||||
currentLineChild->getFlexStartMarginValue(crossAxis).unit() !=
|
||||
Unit::Auto &&
|
||||
currentLineChild->marginTrailingValue(crossAxis).unit() != Unit::Auto;
|
||||
!currentLineChild->style().flexStartMarginIsAuto(
|
||||
crossAxis, direction) &&
|
||||
!currentLineChild->style().flexEndMarginIsAuto(crossAxis, direction);
|
||||
|
||||
const float childWidth = isMainAxisRow ? childMainSize : childCrossSize;
|
||||
const float childHeight = !isMainAxisRow ? childMainSize : childCrossSize;
|
||||
@@ -861,6 +865,7 @@ static void resolveFlexibleLength(
|
||||
FlexLine& flexLine,
|
||||
const FlexDirection mainAxis,
|
||||
const FlexDirection crossAxis,
|
||||
const Direction direction,
|
||||
const float mainAxisownerSize,
|
||||
const float availableInnerMainDim,
|
||||
const float availableInnerCrossDim,
|
||||
@@ -887,6 +892,7 @@ static void resolveFlexibleLength(
|
||||
node,
|
||||
mainAxis,
|
||||
crossAxis,
|
||||
direction,
|
||||
mainAxisownerSize,
|
||||
availableInnerMainDim,
|
||||
availableInnerCrossDim,
|
||||
@@ -920,11 +926,13 @@ static void justifyMainAxis(
|
||||
const auto& style = node->style();
|
||||
|
||||
const float leadingPaddingAndBorderMain =
|
||||
node->getFlexStartPaddingAndBorder(mainAxis, direction, ownerWidth);
|
||||
node->style().computeFlexStartPaddingAndBorder(
|
||||
mainAxis, direction, ownerWidth);
|
||||
const float trailingPaddingAndBorderMain =
|
||||
node->getFlexEndPaddingAndBorder(mainAxis, direction, ownerWidth);
|
||||
node->style().computeFlexEndPaddingAndBorder(
|
||||
mainAxis, direction, ownerWidth);
|
||||
|
||||
const float gap = node->getGapForAxis(mainAxis);
|
||||
const float gap = node->style().computeGapForAxis(mainAxis);
|
||||
// If we are using "at most" rules in the main axis, make sure that
|
||||
// remainingFreeSpace is 0 when min main dimension is not given
|
||||
if (sizingModeMainDim == SizingMode::FitContent &&
|
||||
@@ -957,10 +965,10 @@ static void justifyMainAxis(
|
||||
for (size_t i = startOfLineIndex; i < flexLine.endOfLineIndex; i++) {
|
||||
auto child = node->getChild(i);
|
||||
if (child->style().positionType() != PositionType::Absolute) {
|
||||
if (child->getFlexStartMarginValue(mainAxis).unit() == Unit::Auto) {
|
||||
if (child->style().flexStartMarginIsAuto(mainAxis, direction)) {
|
||||
numberOfAutoMarginsOnCurrentLine++;
|
||||
}
|
||||
if (child->marginTrailingValue(mainAxis).unit() == Unit::Auto) {
|
||||
if (child->style().flexEndMarginIsAuto(mainAxis, direction)) {
|
||||
numberOfAutoMarginsOnCurrentLine++;
|
||||
}
|
||||
}
|
||||
@@ -1019,17 +1027,18 @@ static void justifyMainAxis(
|
||||
continue;
|
||||
}
|
||||
if (childStyle.positionType() == PositionType::Absolute &&
|
||||
child->isInlineStartPositionDefined(mainAxis, direction)) {
|
||||
child->style().isInlineStartPositionDefined(mainAxis, direction)) {
|
||||
if (performLayout) {
|
||||
// In case the child is position absolute and has left/top being
|
||||
// defined, we override the position to whatever the user said (and
|
||||
// margin/border).
|
||||
child->setLayoutPosition(
|
||||
child->getInlineStartPosition(
|
||||
child->style().computeInlineStartPosition(
|
||||
mainAxis, direction, availableInnerMainDim) +
|
||||
node->getInlineStartBorder(mainAxis, direction) +
|
||||
child->getInlineStartMargin(
|
||||
node->style().computeInlineStartBorder(mainAxis, direction) +
|
||||
child->style().computeInlineStartMargin(
|
||||
mainAxis, direction, availableInnerWidth),
|
||||
// FIXME T175195745: Mismatched edge
|
||||
flexStartEdge(mainAxis));
|
||||
}
|
||||
} else {
|
||||
@@ -1037,7 +1046,7 @@ static void justifyMainAxis(
|
||||
// We need to do that only for relative elements. Absolute elements do not
|
||||
// take part in that phase.
|
||||
if (childStyle.positionType() != PositionType::Absolute) {
|
||||
if (child->getFlexStartMarginValue(mainAxis).unit() == Unit::Auto) {
|
||||
if (child->style().flexStartMarginIsAuto(mainAxis, direction)) {
|
||||
flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace /
|
||||
static_cast<float>(numberOfAutoMarginsOnCurrentLine);
|
||||
}
|
||||
@@ -1053,7 +1062,7 @@ static void justifyMainAxis(
|
||||
flexLine.layout.mainDim += betweenMainDim;
|
||||
}
|
||||
|
||||
if (child->marginTrailingValue(mainAxis).unit() == Unit::Auto) {
|
||||
if (child->style().flexEndMarginIsAuto(mainAxis, direction)) {
|
||||
flexLine.layout.mainDim += flexLine.layout.remainingFreeSpace /
|
||||
static_cast<float>(numberOfAutoMarginsOnCurrentLine);
|
||||
}
|
||||
@@ -1063,8 +1072,8 @@ static void justifyMainAxis(
|
||||
// If we skipped the flex step, then we can't rely on the measuredDims
|
||||
// because they weren't computed. This means we can't call
|
||||
// dimensionWithMargin.
|
||||
flexLine.layout.mainDim +=
|
||||
child->getMarginForAxis(mainAxis, availableInnerWidth) +
|
||||
flexLine.layout.mainDim += child->style().computeMarginForAxis(
|
||||
mainAxis, availableInnerWidth) +
|
||||
childLayout.computedFlexBasis.unwrap();
|
||||
flexLine.layout.crossDim = availableInnerCrossDim;
|
||||
} else {
|
||||
@@ -1077,11 +1086,11 @@ static void justifyMainAxis(
|
||||
// If the child is baseline aligned then the cross dimension is
|
||||
// calculated by adding maxAscent and maxDescent from the baseline.
|
||||
const float ascent = calculateBaseline(child) +
|
||||
child->getInlineStartMargin(
|
||||
child->style().computeInlineStartMargin(
|
||||
FlexDirection::Column, direction, availableInnerWidth);
|
||||
const float descent =
|
||||
child->getLayout().measuredDimension(Dimension::Height) +
|
||||
child->getMarginForAxis(
|
||||
child->style().computeMarginForAxis(
|
||||
FlexDirection::Column, availableInnerWidth) -
|
||||
ascent;
|
||||
|
||||
@@ -1101,7 +1110,7 @@ static void justifyMainAxis(
|
||||
} else if (performLayout) {
|
||||
child->setLayoutPosition(
|
||||
childLayout.position(flexStartEdge(mainAxis)) +
|
||||
node->getInlineStartBorder(mainAxis, direction) +
|
||||
node->style().computeFlexStartBorder(mainAxis, direction) +
|
||||
leadingMainDim,
|
||||
flexStartEdge(mainAxis));
|
||||
}
|
||||
@@ -1211,46 +1220,56 @@ static void calculateLayoutImpl(
|
||||
const FlexDirection flexColumnDirection =
|
||||
resolveDirection(FlexDirection::Column, direction);
|
||||
|
||||
const Edge startEdge = direction == Direction::LTR ? Edge::Left : Edge::Right;
|
||||
const Edge endEdge = direction == Direction::LTR ? Edge::Right : Edge::Left;
|
||||
const auto startEdge =
|
||||
direction == Direction::LTR ? PhysicalEdge::Left : PhysicalEdge::Right;
|
||||
const auto endEdge =
|
||||
direction == Direction::LTR ? PhysicalEdge::Right : PhysicalEdge::Left;
|
||||
|
||||
const float marginRowLeading =
|
||||
node->getInlineStartMargin(flexRowDirection, direction, ownerWidth);
|
||||
const float marginRowLeading = node->style().computeInlineStartMargin(
|
||||
flexRowDirection, direction, ownerWidth);
|
||||
node->setLayoutMargin(marginRowLeading, startEdge);
|
||||
const float marginRowTrailing =
|
||||
node->getInlineEndMargin(flexRowDirection, direction, ownerWidth);
|
||||
const float marginRowTrailing = node->style().computeInlineEndMargin(
|
||||
flexRowDirection, direction, ownerWidth);
|
||||
node->setLayoutMargin(marginRowTrailing, endEdge);
|
||||
const float marginColumnLeading =
|
||||
node->getInlineStartMargin(flexColumnDirection, direction, ownerWidth);
|
||||
node->setLayoutMargin(marginColumnLeading, Edge::Top);
|
||||
const float marginColumnTrailing =
|
||||
node->getInlineEndMargin(flexColumnDirection, direction, ownerWidth);
|
||||
node->setLayoutMargin(marginColumnTrailing, Edge::Bottom);
|
||||
const float marginColumnLeading = node->style().computeInlineStartMargin(
|
||||
flexColumnDirection, direction, ownerWidth);
|
||||
node->setLayoutMargin(marginColumnLeading, PhysicalEdge::Top);
|
||||
const float marginColumnTrailing = node->style().computeInlineEndMargin(
|
||||
flexColumnDirection, direction, ownerWidth);
|
||||
node->setLayoutMargin(marginColumnTrailing, PhysicalEdge::Bottom);
|
||||
|
||||
const float marginAxisRow = marginRowLeading + marginRowTrailing;
|
||||
const float marginAxisColumn = marginColumnLeading + marginColumnTrailing;
|
||||
|
||||
node->setLayoutBorder(
|
||||
node->getInlineStartBorder(flexRowDirection, direction), startEdge);
|
||||
node->style().computeInlineStartBorder(flexRowDirection, direction),
|
||||
startEdge);
|
||||
node->setLayoutBorder(
|
||||
node->getInlineEndBorder(flexRowDirection, direction), endEdge);
|
||||
node->style().computeInlineEndBorder(flexRowDirection, direction),
|
||||
endEdge);
|
||||
node->setLayoutBorder(
|
||||
node->getInlineStartBorder(flexColumnDirection, direction), Edge::Top);
|
||||
node->style().computeInlineStartBorder(flexColumnDirection, direction),
|
||||
PhysicalEdge::Top);
|
||||
node->setLayoutBorder(
|
||||
node->getInlineEndBorder(flexColumnDirection, direction), Edge::Bottom);
|
||||
node->style().computeInlineEndBorder(flexColumnDirection, direction),
|
||||
PhysicalEdge::Bottom);
|
||||
|
||||
node->setLayoutPadding(
|
||||
node->getInlineStartPadding(flexRowDirection, direction, ownerWidth),
|
||||
node->style().computeInlineStartPadding(
|
||||
flexRowDirection, direction, ownerWidth),
|
||||
startEdge);
|
||||
node->setLayoutPadding(
|
||||
node->getInlineEndPadding(flexRowDirection, direction, ownerWidth),
|
||||
node->style().computeInlineEndPadding(
|
||||
flexRowDirection, direction, ownerWidth),
|
||||
endEdge);
|
||||
node->setLayoutPadding(
|
||||
node->getInlineStartPadding(flexColumnDirection, direction, ownerWidth),
|
||||
Edge::Top);
|
||||
node->style().computeInlineStartPadding(
|
||||
flexColumnDirection, direction, ownerWidth),
|
||||
PhysicalEdge::Top);
|
||||
node->setLayoutPadding(
|
||||
node->getInlineEndPadding(flexColumnDirection, direction, ownerWidth),
|
||||
Edge::Bottom);
|
||||
node->style().computeInlineEndPadding(
|
||||
flexColumnDirection, direction, ownerWidth),
|
||||
PhysicalEdge::Bottom);
|
||||
|
||||
if (node->hasMeasureFunc()) {
|
||||
measureNodeWithMeasureFunc(
|
||||
@@ -1314,7 +1333,8 @@ static void calculateLayoutImpl(
|
||||
const float paddingAndBorderAxisCross =
|
||||
paddingAndBorderForAxis(node, crossAxis, ownerWidth);
|
||||
const float leadingPaddingAndBorderCross =
|
||||
node->getInlineStartPaddingAndBorder(crossAxis, direction, ownerWidth);
|
||||
node->style().computeInlineStartPaddingAndBorder(
|
||||
crossAxis, direction, ownerWidth);
|
||||
|
||||
SizingMode sizingModeMainDim =
|
||||
isMainAxisRow ? widthSizingMode : heightSizingMode;
|
||||
@@ -1364,8 +1384,8 @@ static void calculateLayoutImpl(
|
||||
generationCount);
|
||||
|
||||
if (childCount > 1) {
|
||||
totalMainDim +=
|
||||
node->getGapForAxis(mainAxis) * static_cast<float>(childCount - 1);
|
||||
totalMainDim += node->style().computeGapForAxis(mainAxis) *
|
||||
static_cast<float>(childCount - 1);
|
||||
}
|
||||
|
||||
const bool mainAxisOverflows =
|
||||
@@ -1388,7 +1408,7 @@ static void calculateLayoutImpl(
|
||||
// Accumulated cross dimensions of all lines so far.
|
||||
float totalLineCrossDim = 0;
|
||||
|
||||
const float crossAxisGap = node->getGapForAxis(crossAxis);
|
||||
const float crossAxisGap = node->style().computeGapForAxis(crossAxis);
|
||||
|
||||
// Max main dimension of all the lines.
|
||||
float maxLineMainDim = 0;
|
||||
@@ -1481,6 +1501,7 @@ static void calculateLayoutImpl(
|
||||
flexLine,
|
||||
mainAxis,
|
||||
crossAxis,
|
||||
direction,
|
||||
mainAxisownerSize,
|
||||
availableInnerMainDim,
|
||||
availableInnerCrossDim,
|
||||
@@ -1568,14 +1589,16 @@ static void calculateLayoutImpl(
|
||||
// top/left/bottom/right set, override all the previously computed
|
||||
// positions to set it correctly.
|
||||
const bool isChildLeadingPosDefined =
|
||||
child->isInlineStartPositionDefined(crossAxis, direction);
|
||||
child->style().isInlineStartPositionDefined(crossAxis, direction);
|
||||
if (isChildLeadingPosDefined) {
|
||||
child->setLayoutPosition(
|
||||
child->getInlineStartPosition(
|
||||
child->style().computeInlineStartPosition(
|
||||
crossAxis, direction, availableInnerCrossDim) +
|
||||
node->getInlineStartBorder(crossAxis, direction) +
|
||||
child->getInlineStartMargin(
|
||||
node->style().computeInlineStartBorder(
|
||||
crossAxis, direction) +
|
||||
child->style().computeInlineStartMargin(
|
||||
crossAxis, direction, availableInnerWidth),
|
||||
// FIXME T175195745: Mismatched edge
|
||||
flexStartEdge(crossAxis));
|
||||
}
|
||||
// If leading position is not defined or calculations result in Nan,
|
||||
@@ -1584,9 +1607,10 @@ static void calculateLayoutImpl(
|
||||
yoga::isUndefined(
|
||||
child->getLayout().position(flexStartEdge(crossAxis)))) {
|
||||
child->setLayoutPosition(
|
||||
node->getInlineStartBorder(crossAxis, direction) +
|
||||
child->getInlineStartMargin(
|
||||
node->style().computeInlineStartBorder(crossAxis, direction) +
|
||||
child->style().computeInlineStartMargin(
|
||||
crossAxis, direction, availableInnerWidth),
|
||||
// FIXME T175195745: Mismatched edge
|
||||
flexStartEdge(crossAxis));
|
||||
}
|
||||
} else {
|
||||
@@ -1601,8 +1625,8 @@ static void calculateLayoutImpl(
|
||||
// time, this time forcing the cross-axis size to be the computed
|
||||
// cross size for the current line.
|
||||
if (alignItem == Align::Stretch &&
|
||||
child->getFlexStartMarginValue(crossAxis).unit() != Unit::Auto &&
|
||||
child->marginTrailingValue(crossAxis).unit() != Unit::Auto) {
|
||||
!child->style().flexStartMarginIsAuto(crossAxis, direction) &&
|
||||
!child->style().flexEndMarginIsAuto(crossAxis, direction)) {
|
||||
// If the child defines a definite size for its cross axis, there's
|
||||
// no need to stretch.
|
||||
if (!child->hasDefiniteLength(
|
||||
@@ -1611,14 +1635,15 @@ static void calculateLayoutImpl(
|
||||
child->getLayout().measuredDimension(dimension(mainAxis));
|
||||
const auto& childStyle = child->style();
|
||||
float childCrossSize = childStyle.aspectRatio().isDefined()
|
||||
? child->getMarginForAxis(crossAxis, availableInnerWidth) +
|
||||
? child->style().computeMarginForAxis(
|
||||
crossAxis, availableInnerWidth) +
|
||||
(isMainAxisRow
|
||||
? childMainSize / childStyle.aspectRatio().unwrap()
|
||||
: childMainSize * childStyle.aspectRatio().unwrap())
|
||||
: flexLine.layout.crossDim;
|
||||
|
||||
childMainSize +=
|
||||
child->getMarginForAxis(mainAxis, availableInnerWidth);
|
||||
childMainSize += child->style().computeMarginForAxis(
|
||||
mainAxis, availableInnerWidth);
|
||||
|
||||
SizingMode childMainSizingMode = SizingMode::StretchFit;
|
||||
SizingMode childCrossSizingMode = SizingMode::StretchFit;
|
||||
@@ -1675,17 +1700,15 @@ static void calculateLayoutImpl(
|
||||
const float remainingCrossDim = containerCrossAxis -
|
||||
child->dimensionWithMargin(crossAxis, availableInnerWidth);
|
||||
|
||||
if (child->getFlexStartMarginValue(crossAxis).unit() ==
|
||||
Unit::Auto &&
|
||||
child->marginTrailingValue(crossAxis).unit() == Unit::Auto) {
|
||||
if (child->style().flexStartMarginIsAuto(crossAxis, direction) &&
|
||||
child->style().flexEndMarginIsAuto(crossAxis, direction)) {
|
||||
leadingCrossDim +=
|
||||
yoga::maxOrDefined(0.0f, remainingCrossDim / 2);
|
||||
} else if (
|
||||
child->marginTrailingValue(crossAxis).unit() == Unit::Auto) {
|
||||
} else if (child->style().flexEndMarginIsAuto(
|
||||
crossAxis, direction)) {
|
||||
// No-Op
|
||||
} else if (
|
||||
child->getFlexStartMarginValue(crossAxis).unit() ==
|
||||
Unit::Auto) {
|
||||
} else if (child->style().flexStartMarginIsAuto(
|
||||
crossAxis, direction)) {
|
||||
leadingCrossDim += yoga::maxOrDefined(0.0f, remainingCrossDim);
|
||||
} else if (alignItem == Align::FlexStart) {
|
||||
// No-Op
|
||||
@@ -1795,15 +1818,16 @@ static void calculateLayoutImpl(
|
||||
lineHeight = yoga::maxOrDefined(
|
||||
lineHeight,
|
||||
child->getLayout().measuredDimension(dimension(crossAxis)) +
|
||||
child->getMarginForAxis(crossAxis, availableInnerWidth));
|
||||
child->style().computeMarginForAxis(
|
||||
crossAxis, availableInnerWidth));
|
||||
}
|
||||
if (resolveChildAlignment(node, child) == Align::Baseline) {
|
||||
const float ascent = calculateBaseline(child) +
|
||||
child->getInlineStartMargin(
|
||||
child->style().computeInlineStartMargin(
|
||||
FlexDirection::Column, direction, availableInnerWidth);
|
||||
const float descent =
|
||||
child->getLayout().measuredDimension(Dimension::Height) +
|
||||
child->getMarginForAxis(
|
||||
child->style().computeMarginForAxis(
|
||||
FlexDirection::Column, availableInnerWidth) -
|
||||
ascent;
|
||||
maxAscentForCurrentLine =
|
||||
@@ -1829,18 +1853,20 @@ static void calculateLayoutImpl(
|
||||
case Align::FlexStart: {
|
||||
child->setLayoutPosition(
|
||||
currentLead +
|
||||
child->getInlineStartMargin(
|
||||
child->style().computeInlineStartMargin(
|
||||
crossAxis, direction, availableInnerWidth),
|
||||
// FIXME T175195745: Mismatched edge
|
||||
flexStartEdge(crossAxis));
|
||||
break;
|
||||
}
|
||||
case Align::FlexEnd: {
|
||||
child->setLayoutPosition(
|
||||
currentLead + lineHeight -
|
||||
child->getInlineEndMargin(
|
||||
child->style().computeInlineEndMargin(
|
||||
crossAxis, direction, availableInnerWidth) -
|
||||
child->getLayout().measuredDimension(
|
||||
dimension(crossAxis)),
|
||||
// FIXME T175195745: Mismatched edge
|
||||
flexStartEdge(crossAxis));
|
||||
break;
|
||||
}
|
||||
@@ -1856,8 +1882,9 @@ static void calculateLayoutImpl(
|
||||
case Align::Stretch: {
|
||||
child->setLayoutPosition(
|
||||
currentLead +
|
||||
child->getInlineStartMargin(
|
||||
child->style().computeInlineStartMargin(
|
||||
crossAxis, direction, availableInnerWidth),
|
||||
// FIXME T175195745: Mismatched edge
|
||||
flexStartEdge(crossAxis));
|
||||
|
||||
// Remeasure child with the line height as it as been only
|
||||
@@ -1867,13 +1894,14 @@ static void calculateLayoutImpl(
|
||||
const float childWidth = isMainAxisRow
|
||||
? (child->getLayout().measuredDimension(
|
||||
Dimension::Width) +
|
||||
child->getMarginForAxis(mainAxis, availableInnerWidth))
|
||||
child->style().computeMarginForAxis(
|
||||
mainAxis, availableInnerWidth))
|
||||
: leadPerLine + lineHeight;
|
||||
|
||||
const float childHeight = !isMainAxisRow
|
||||
? (child->getLayout().measuredDimension(
|
||||
Dimension::Height) +
|
||||
child->getMarginForAxis(
|
||||
child->style().computeMarginForAxis(
|
||||
crossAxis, availableInnerWidth))
|
||||
: leadPerLine + lineHeight;
|
||||
|
||||
@@ -1907,11 +1935,11 @@ static void calculateLayoutImpl(
|
||||
child->setLayoutPosition(
|
||||
currentLead + maxAscentForCurrentLine -
|
||||
calculateBaseline(child) +
|
||||
child->getInlineStartPosition(
|
||||
child->style().computeInlineStartPosition(
|
||||
FlexDirection::Column,
|
||||
direction,
|
||||
availableInnerCrossDim),
|
||||
Edge::Top);
|
||||
PhysicalEdge::Top);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -2123,9 +2151,9 @@ bool calculateLayoutInternal(
|
||||
// measurements if at all possible.
|
||||
if (node->hasMeasureFunc()) {
|
||||
const float marginAxisRow =
|
||||
node->getMarginForAxis(FlexDirection::Row, ownerWidth);
|
||||
node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth);
|
||||
const float marginAxisColumn =
|
||||
node->getMarginForAxis(FlexDirection::Column, ownerWidth);
|
||||
node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth);
|
||||
|
||||
// First, try to use the layout cache.
|
||||
if (canUseCachedMeasurement(
|
||||
@@ -2295,7 +2323,7 @@ void calculateLayout(
|
||||
(node->getResolvedDimension(dimension(FlexDirection::Row))
|
||||
.resolve(ownerWidth)
|
||||
.unwrap() +
|
||||
node->getMarginForAxis(FlexDirection::Row, ownerWidth));
|
||||
node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth));
|
||||
widthSizingMode = SizingMode::StretchFit;
|
||||
} else if (style.maxDimension(Dimension::Width)
|
||||
.resolve(ownerWidth)
|
||||
@@ -2315,7 +2343,7 @@ void calculateLayout(
|
||||
(node->getResolvedDimension(dimension(FlexDirection::Column))
|
||||
.resolve(ownerHeight)
|
||||
.unwrap() +
|
||||
node->getMarginForAxis(FlexDirection::Column, ownerWidth));
|
||||
node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth));
|
||||
heightSizingMode = SizingMode::StretchFit;
|
||||
} else if (style.maxDimension(Dimension::Height)
|
||||
.resolve(ownerHeight)
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include <yoga/enums/Direction.h>
|
||||
#include <yoga/enums/Edge.h>
|
||||
#include <yoga/enums/FlexDirection.h>
|
||||
#include <yoga/enums/PhysicalEdge.h>
|
||||
|
||||
namespace facebook::yoga {
|
||||
|
||||
@@ -49,83 +50,59 @@ inline FlexDirection resolveCrossDirection(
|
||||
: FlexDirection::Column;
|
||||
}
|
||||
|
||||
inline Edge flexStartEdge(const FlexDirection flexDirection) {
|
||||
inline PhysicalEdge flexStartEdge(FlexDirection flexDirection) {
|
||||
switch (flexDirection) {
|
||||
case FlexDirection::Column:
|
||||
return Edge::Top;
|
||||
return PhysicalEdge::Top;
|
||||
case FlexDirection::ColumnReverse:
|
||||
return Edge::Bottom;
|
||||
return PhysicalEdge::Bottom;
|
||||
case FlexDirection::Row:
|
||||
return Edge::Left;
|
||||
return PhysicalEdge::Left;
|
||||
case FlexDirection::RowReverse:
|
||||
return Edge::Right;
|
||||
return PhysicalEdge::Right;
|
||||
}
|
||||
|
||||
fatalWithMessage("Invalid FlexDirection");
|
||||
}
|
||||
|
||||
inline Edge flexEndEdge(const FlexDirection flexDirection) {
|
||||
inline PhysicalEdge flexEndEdge(FlexDirection flexDirection) {
|
||||
switch (flexDirection) {
|
||||
case FlexDirection::Column:
|
||||
return Edge::Bottom;
|
||||
return PhysicalEdge::Bottom;
|
||||
case FlexDirection::ColumnReverse:
|
||||
return Edge::Top;
|
||||
return PhysicalEdge::Top;
|
||||
case FlexDirection::Row:
|
||||
return Edge::Right;
|
||||
return PhysicalEdge::Right;
|
||||
case FlexDirection::RowReverse:
|
||||
return Edge::Left;
|
||||
return PhysicalEdge::Left;
|
||||
}
|
||||
|
||||
fatalWithMessage("Invalid FlexDirection");
|
||||
}
|
||||
|
||||
inline Edge inlineStartEdge(
|
||||
const FlexDirection flexDirection,
|
||||
const Direction direction) {
|
||||
if (isRow(flexDirection)) {
|
||||
return direction == Direction::RTL ? Edge::Right : Edge::Left;
|
||||
}
|
||||
|
||||
return Edge::Top;
|
||||
}
|
||||
|
||||
inline Edge inlineEndEdge(
|
||||
const FlexDirection flexDirection,
|
||||
const Direction direction) {
|
||||
if (isRow(flexDirection)) {
|
||||
return direction == Direction::RTL ? Edge::Left : Edge::Right;
|
||||
}
|
||||
|
||||
return Edge::Bottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* The physical edges that Edge::Start and Edge::End correspond to (e.g.
|
||||
* left/right) are soley dependent on the direction. However, there are cases
|
||||
* where we want the flex start/end edge (i.e. which edge is the start/end
|
||||
* for laying out flex items), which can be distinct from the corresponding
|
||||
* inline edge. In these cases we need to know which "relative edge"
|
||||
* (Edge::Start/Edge::End) corresponds to the said flex start/end edge as these
|
||||
* relative edges can be used instead of physical ones when defining certain
|
||||
* attributes like border or padding.
|
||||
*/
|
||||
inline Edge flexStartRelativeEdge(
|
||||
inline PhysicalEdge inlineStartEdge(
|
||||
FlexDirection flexDirection,
|
||||
Direction direction) {
|
||||
const Edge leadLayoutEdge = inlineStartEdge(flexDirection, direction);
|
||||
const Edge leadFlexItemEdge = flexStartEdge(flexDirection);
|
||||
return leadLayoutEdge == leadFlexItemEdge ? Edge::Start : Edge::End;
|
||||
if (isRow(flexDirection)) {
|
||||
return direction == Direction::RTL ? PhysicalEdge::Right
|
||||
: PhysicalEdge::Left;
|
||||
}
|
||||
|
||||
return PhysicalEdge::Top;
|
||||
}
|
||||
|
||||
inline Edge flexEndRelativeEdge(
|
||||
inline PhysicalEdge inlineEndEdge(
|
||||
FlexDirection flexDirection,
|
||||
Direction direction) {
|
||||
const Edge trailLayoutEdge = inlineEndEdge(flexDirection, direction);
|
||||
const Edge trailFlexItemEdge = flexEndEdge(flexDirection);
|
||||
return trailLayoutEdge == trailFlexItemEdge ? Edge::End : Edge::Start;
|
||||
if (isRow(flexDirection)) {
|
||||
return direction == Direction::RTL ? PhysicalEdge::Left
|
||||
: PhysicalEdge::Right;
|
||||
}
|
||||
|
||||
return PhysicalEdge::Bottom;
|
||||
}
|
||||
|
||||
inline Dimension dimension(const FlexDirection flexDirection) {
|
||||
inline Dimension dimension(FlexDirection flexDirection) {
|
||||
switch (flexDirection) {
|
||||
case FlexDirection::Column:
|
||||
return Dimension::Height;
|
||||
|
@@ -34,7 +34,7 @@ FlexLine calculateFlexLine(
|
||||
const FlexDirection mainAxis = resolveDirection(
|
||||
node->style().flexDirection(), node->resolveDirection(ownerDirection));
|
||||
const bool isNodeFlexWrap = node->style().flexWrap() != Wrap::NoWrap;
|
||||
const float gap = node->getGapForAxis(mainAxis);
|
||||
const float gap = node->style().computeGapForAxis(mainAxis);
|
||||
|
||||
// Add items to the current line until it's full or we run out of items.
|
||||
for (; endOfLineIndex < node->getChildren().size(); endOfLineIndex++) {
|
||||
@@ -53,7 +53,7 @@ FlexLine calculateFlexLine(
|
||||
|
||||
child->setLineIndex(lineCount);
|
||||
const float childMarginMainAxis =
|
||||
child->getMarginForAxis(mainAxis, availableInnerWidth);
|
||||
child->style().computeMarginForAxis(mainAxis, availableInnerWidth);
|
||||
const float childLeadingGapMainAxis = isFirstElementInLine ? 0.0f : gap;
|
||||
const float flexBasisWithMinAndMaxConstraints =
|
||||
boundAxisWithinMinAndMax(
|
||||
|
@@ -68,8 +68,8 @@ void roundLayoutResultsToPixelGrid(
|
||||
const double absoluteTop) {
|
||||
const auto pointScaleFactor = node->getConfig()->getPointScaleFactor();
|
||||
|
||||
const double nodeLeft = node->getLayout().position(Edge::Left);
|
||||
const double nodeTop = node->getLayout().position(Edge::Top);
|
||||
const double nodeLeft = node->getLayout().position(PhysicalEdge::Left);
|
||||
const double nodeTop = node->getLayout().position(PhysicalEdge::Top);
|
||||
|
||||
const double nodeWidth = node->getLayout().dimension(Dimension::Width);
|
||||
const double nodeHeight = node->getLayout().dimension(Dimension::Height);
|
||||
@@ -87,11 +87,11 @@ void roundLayoutResultsToPixelGrid(
|
||||
|
||||
node->setLayoutPosition(
|
||||
roundValueToPixelGrid(nodeLeft, pointScaleFactor, false, textRounding),
|
||||
Edge::Left);
|
||||
PhysicalEdge::Left);
|
||||
|
||||
node->setLayoutPosition(
|
||||
roundValueToPixelGrid(nodeTop, pointScaleFactor, false, textRounding),
|
||||
Edge::Top);
|
||||
PhysicalEdge::Top);
|
||||
|
||||
// We multiply dimension by scale factor and if the result is close to the
|
||||
// whole number, we don't have any fraction To verify if the result is close
|
||||
|
@@ -106,9 +106,9 @@ void nodeToString(
|
||||
appendFormattedString(
|
||||
str, "height: %g; ", node->getLayout().dimension(Dimension::Height));
|
||||
appendFormattedString(
|
||||
str, "top: %g; ", node->getLayout().position(Edge::Top));
|
||||
str, "top: %g; ", node->getLayout().position(PhysicalEdge::Top));
|
||||
appendFormattedString(
|
||||
str, "left: %g;", node->getLayout().position(Edge::Left));
|
||||
str, "left: %g;", node->getLayout().position(PhysicalEdge::Left));
|
||||
appendFormattedString(str, "\" ");
|
||||
}
|
||||
|
||||
|
21
yoga/enums/PhysicalEdge.h
Normal file
21
yoga/enums/PhysicalEdge.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <yoga/enums/Edge.h>
|
||||
|
||||
namespace facebook::yoga {
|
||||
|
||||
enum class PhysicalEdge : uint32_t {
|
||||
Left = yoga::to_underlying(Edge::Left),
|
||||
Top = yoga::to_underlying(Edge::Top),
|
||||
Right = yoga::to_underlying(Edge::Right),
|
||||
Bottom = yoga::to_underlying(Edge::Bottom),
|
||||
};
|
||||
|
||||
} // namespace facebook::yoga
|
@@ -13,6 +13,7 @@
|
||||
#include <yoga/enums/Dimension.h>
|
||||
#include <yoga/enums/Direction.h>
|
||||
#include <yoga/enums/Edge.h>
|
||||
#include <yoga/enums/PhysicalEdge.h>
|
||||
#include <yoga/node/CachedMeasurement.h>
|
||||
#include <yoga/numeric/FloatOptional.h>
|
||||
|
||||
@@ -68,44 +69,36 @@ struct LayoutResults {
|
||||
measuredDimensions_[yoga::to_underlying(axis)] = dimension;
|
||||
}
|
||||
|
||||
float position(Edge cardinalEdge) const {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
return position_[yoga::to_underlying(cardinalEdge)];
|
||||
float position(PhysicalEdge physicalEdge) const {
|
||||
return position_[yoga::to_underlying(physicalEdge)];
|
||||
}
|
||||
|
||||
void setPosition(Edge cardinalEdge, float dimension) {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
position_[yoga::to_underlying(cardinalEdge)] = dimension;
|
||||
void setPosition(PhysicalEdge physicalEdge, float dimension) {
|
||||
position_[yoga::to_underlying(physicalEdge)] = dimension;
|
||||
}
|
||||
|
||||
float margin(Edge cardinalEdge) const {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
return margin_[yoga::to_underlying(cardinalEdge)];
|
||||
float margin(PhysicalEdge physicalEdge) const {
|
||||
return margin_[yoga::to_underlying(physicalEdge)];
|
||||
}
|
||||
|
||||
void setMargin(Edge cardinalEdge, float dimension) {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
margin_[yoga::to_underlying(cardinalEdge)] = dimension;
|
||||
void setMargin(PhysicalEdge physicalEdge, float dimension) {
|
||||
margin_[yoga::to_underlying(physicalEdge)] = dimension;
|
||||
}
|
||||
|
||||
float border(Edge cardinalEdge) const {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
return border_[yoga::to_underlying(cardinalEdge)];
|
||||
float border(PhysicalEdge physicalEdge) const {
|
||||
return border_[yoga::to_underlying(physicalEdge)];
|
||||
}
|
||||
|
||||
void setBorder(Edge cardinalEdge, float dimension) {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
border_[yoga::to_underlying(cardinalEdge)] = dimension;
|
||||
void setBorder(PhysicalEdge physicalEdge, float dimension) {
|
||||
border_[yoga::to_underlying(physicalEdge)] = dimension;
|
||||
}
|
||||
|
||||
float padding(Edge cardinalEdge) const {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
return padding_[yoga::to_underlying(cardinalEdge)];
|
||||
float padding(PhysicalEdge physicalEdge) const {
|
||||
return padding_[yoga::to_underlying(physicalEdge)];
|
||||
}
|
||||
|
||||
void setPadding(Edge cardinalEdge, float dimension) {
|
||||
assertCardinalEdge(cardinalEdge);
|
||||
padding_[yoga::to_underlying(cardinalEdge)] = dimension;
|
||||
void setPadding(PhysicalEdge physicalEdge, float dimension) {
|
||||
padding_[yoga::to_underlying(physicalEdge)] = dimension;
|
||||
}
|
||||
|
||||
bool operator==(LayoutResults layout) const;
|
||||
@@ -114,11 +107,6 @@ struct LayoutResults {
|
||||
}
|
||||
|
||||
private:
|
||||
static inline void assertCardinalEdge(Edge edge) {
|
||||
assertFatal(
|
||||
static_cast<int>(edge) <= 3, "Edge must be top/left/bottom/right");
|
||||
}
|
||||
|
||||
Direction direction_ : bitCount<Direction>() = Direction::Inherit;
|
||||
bool hadOverflow_ : 1 = false;
|
||||
|
||||
|
@@ -9,7 +9,6 @@
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
|
||||
#include <yoga/algorithm/FlexDirection.h>
|
||||
#include <yoga/debug/AssertFatal.h>
|
||||
#include <yoga/node/Node.h>
|
||||
#include <yoga/numeric/Comparison.h>
|
||||
@@ -49,326 +48,6 @@ Node::Node(Node&& node) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Edge value resolution should be moved to `yoga::Style`
|
||||
template <auto Field>
|
||||
Style::Length Node::computeEdgeValueForRow(Edge rowEdge, Edge 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)(Edge::Horizontal).isDefined()) {
|
||||
return (style_.*Field)(Edge::Horizontal);
|
||||
} else {
|
||||
return (style_.*Field)(Edge::All);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Edge value resolution should be moved to `yoga::Style`
|
||||
template <auto Field>
|
||||
Style::Length Node::computeEdgeValueForColumn(Edge edge) const {
|
||||
if ((style_.*Field)(edge).isDefined()) {
|
||||
return (style_.*Field)(edge);
|
||||
} else if ((style_.*Field)(Edge::Vertical).isDefined()) {
|
||||
return (style_.*Field)(Edge::Vertical);
|
||||
} else {
|
||||
return (style_.*Field)(Edge::All);
|
||||
}
|
||||
}
|
||||
|
||||
Edge Node::getInlineStartEdge(FlexDirection flexDirection, Direction direction)
|
||||
const {
|
||||
return inlineStartEdge(flexDirection, direction);
|
||||
}
|
||||
|
||||
Edge Node::getInlineEndEdge(FlexDirection flexDirection, Direction direction)
|
||||
const {
|
||||
return inlineEndEdge(flexDirection, direction);
|
||||
}
|
||||
|
||||
Edge Node::getFlexStartRelativeEdge(
|
||||
FlexDirection flexDirection,
|
||||
Direction direction) const {
|
||||
return flexStartRelativeEdge(flexDirection, direction);
|
||||
}
|
||||
|
||||
Edge Node::getFlexEndRelativeEdge(
|
||||
FlexDirection flexDirection,
|
||||
Direction direction) const {
|
||||
return flexEndRelativeEdge(flexDirection, direction);
|
||||
}
|
||||
|
||||
bool Node::isFlexStartPositionDefined(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
auto leadingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(
|
||||
getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::position>(flexStartEdge(axis));
|
||||
|
||||
return leadingPosition.isDefined();
|
||||
}
|
||||
|
||||
bool Node::isInlineStartPositionDefined(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
Edge startEdge = getInlineStartEdge(axis, direction);
|
||||
Style::Length leadingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(Edge::Start, startEdge)
|
||||
: computeEdgeValueForColumn<&Style::position>(startEdge);
|
||||
|
||||
return leadingPosition.isDefined();
|
||||
}
|
||||
|
||||
bool Node::isFlexEndPositionDefined(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
auto trailingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(
|
||||
getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::position>(flexEndEdge(axis));
|
||||
|
||||
return !trailingPosition.isUndefined();
|
||||
}
|
||||
|
||||
bool Node::isInlineEndPositionDefined(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
Edge endEdge = getInlineEndEdge(axis, direction);
|
||||
Style::Length trailingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(Edge::End, endEdge)
|
||||
: computeEdgeValueForColumn<&Style::position>(endEdge);
|
||||
|
||||
return trailingPosition.isDefined();
|
||||
}
|
||||
|
||||
float Node::getFlexStartPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
auto leadingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(
|
||||
getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::position>(flexStartEdge(axis));
|
||||
|
||||
return leadingPosition.resolve(axisSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineStartPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
Edge startEdge = getInlineStartEdge(axis, direction);
|
||||
Style::Length leadingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(Edge::Start, startEdge)
|
||||
: computeEdgeValueForColumn<&Style::position>(startEdge);
|
||||
|
||||
return leadingPosition.resolve(axisSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getFlexEndPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
auto trailingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(
|
||||
getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::position>(flexEndEdge(axis));
|
||||
|
||||
return trailingPosition.resolve(axisSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineEndPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
Edge endEdge = getInlineEndEdge(axis, direction);
|
||||
Style::Length trailingPosition = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::position>(Edge::End, endEdge)
|
||||
: computeEdgeValueForColumn<&Style::position>(endEdge);
|
||||
|
||||
return trailingPosition.resolve(axisSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getFlexStartMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
auto leadingMargin = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::margin>(
|
||||
getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::margin>(flexStartEdge(axis));
|
||||
|
||||
return leadingMargin.resolve(widthSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineStartMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
Edge startEdge = getInlineStartEdge(axis, direction);
|
||||
Style::Length leadingMargin = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::margin>(Edge::Start, startEdge)
|
||||
: computeEdgeValueForColumn<&Style::margin>(startEdge);
|
||||
|
||||
return leadingMargin.resolve(widthSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getFlexEndMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
auto trailingMargin = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::margin>(
|
||||
getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::margin>(flexEndEdge(axis));
|
||||
|
||||
return trailingMargin.resolve(widthSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineEndMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
Edge endEdge = getInlineEndEdge(axis, direction);
|
||||
Style::Length trailingMargin = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::margin>(Edge::End, endEdge)
|
||||
: computeEdgeValueForColumn<&Style::margin>(endEdge);
|
||||
|
||||
return trailingMargin.resolve(widthSize).unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineStartBorder(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
Edge startEdge = getInlineStartEdge(axis, direction);
|
||||
Style::Length leadingBorder = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::border>(Edge::Start, startEdge)
|
||||
: computeEdgeValueForColumn<&Style::border>(startEdge);
|
||||
|
||||
return maxOrDefined(leadingBorder.value().unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getFlexStartBorder(FlexDirection axis, Direction direction) const {
|
||||
Style::Length leadingBorder = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::border>(
|
||||
getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::border>(flexStartEdge(axis));
|
||||
|
||||
return maxOrDefined(leadingBorder.value().unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineEndBorder(FlexDirection axis, Direction direction) const {
|
||||
Edge endEdge = getInlineEndEdge(axis, direction);
|
||||
Style::Length trailingBorder = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::border>(Edge::End, endEdge)
|
||||
: computeEdgeValueForColumn<&Style::border>(endEdge);
|
||||
|
||||
return maxOrDefined(trailingBorder.value().unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getFlexEndBorder(FlexDirection axis, Direction direction) const {
|
||||
Style::Length trailingBorder = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::border>(
|
||||
getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::border>(flexEndEdge(axis));
|
||||
|
||||
return maxOrDefined(trailingBorder.value().unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineStartPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
Edge startEdge = getInlineStartEdge(axis, direction);
|
||||
Style::Length leadingPadding = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::padding>(Edge::Start, startEdge)
|
||||
: computeEdgeValueForColumn<&Style::padding>(startEdge);
|
||||
|
||||
return maxOrDefined(leadingPadding.resolve(widthSize).unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getFlexStartPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
auto leadingPadding = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::padding>(
|
||||
getFlexStartRelativeEdge(axis, direction), flexStartEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::padding>(flexStartEdge(axis));
|
||||
|
||||
return maxOrDefined(leadingPadding.resolve(widthSize).unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineEndPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
Edge endEdge = getInlineEndEdge(axis, direction);
|
||||
Style::Length trailingPadding = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::padding>(Edge::End, endEdge)
|
||||
: computeEdgeValueForColumn<&Style::padding>(endEdge);
|
||||
|
||||
return maxOrDefined(trailingPadding.resolve(widthSize).unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getFlexEndPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
auto trailingPadding = isRow(axis)
|
||||
? computeEdgeValueForRow<&Style::padding>(
|
||||
getFlexEndRelativeEdge(axis, direction), flexEndEdge(axis))
|
||||
: computeEdgeValueForColumn<&Style::padding>(flexEndEdge(axis));
|
||||
|
||||
return maxOrDefined(trailingPadding.resolve(widthSize).unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
float Node::getInlineStartPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return getInlineStartPadding(axis, direction, widthSize) +
|
||||
getInlineStartBorder(axis, direction);
|
||||
}
|
||||
|
||||
float Node::getFlexStartPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return getFlexStartPadding(axis, direction, widthSize) +
|
||||
getFlexStartBorder(axis, direction);
|
||||
}
|
||||
|
||||
float Node::getInlineEndPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return getInlineEndPadding(axis, direction, widthSize) +
|
||||
getInlineEndBorder(axis, direction);
|
||||
}
|
||||
|
||||
float Node::getFlexEndPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return getFlexEndPadding(axis, direction, widthSize) +
|
||||
getFlexEndBorder(axis, direction);
|
||||
}
|
||||
|
||||
float Node::getBorderForAxis(FlexDirection axis) const {
|
||||
return getInlineStartBorder(axis, Direction::LTR) +
|
||||
getInlineEndBorder(axis, Direction::LTR);
|
||||
}
|
||||
|
||||
float Node::getMarginForAxis(FlexDirection axis, float widthSize) const {
|
||||
// The total margin for a given axis does not depend on the direction
|
||||
// so hardcoding LTR here to avoid piping direction to this function
|
||||
return getInlineStartMargin(axis, Direction::LTR, widthSize) +
|
||||
getInlineEndMargin(axis, Direction::LTR, widthSize);
|
||||
}
|
||||
|
||||
float Node::getGapForAxis(FlexDirection axis) const {
|
||||
auto gap = isRow(axis) ? style_.resolveColumnGap() : style_.resolveRowGap();
|
||||
// TODO: Validate percentage gap, and expose ability to set percentage to
|
||||
// public API
|
||||
return maxOrDefined(gap.resolve(0.0f /*ownerSize*/).unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
YGSize Node::measure(
|
||||
float width,
|
||||
MeasureMode widthMode,
|
||||
@@ -386,7 +65,7 @@ float Node::dimensionWithMargin(
|
||||
const FlexDirection axis,
|
||||
const float widthSize) {
|
||||
return getLayout().measuredDimension(dimension(axis)) +
|
||||
getMarginForAxis(axis, widthSize);
|
||||
style_.computeMarginForAxis(axis, widthSize);
|
||||
}
|
||||
|
||||
bool Node::isLayoutDimensionDefined(const FlexDirection axis) {
|
||||
@@ -470,15 +149,15 @@ void Node::setLayoutDirection(Direction direction) {
|
||||
layout_.setDirection(direction);
|
||||
}
|
||||
|
||||
void Node::setLayoutMargin(float margin, Edge edge) {
|
||||
void Node::setLayoutMargin(float margin, PhysicalEdge edge) {
|
||||
layout_.setMargin(edge, margin);
|
||||
}
|
||||
|
||||
void Node::setLayoutBorder(float border, Edge edge) {
|
||||
void Node::setLayoutBorder(float border, PhysicalEdge edge) {
|
||||
layout_.setBorder(edge, border);
|
||||
}
|
||||
|
||||
void Node::setLayoutPadding(float padding, Edge edge) {
|
||||
void Node::setLayoutPadding(float padding, PhysicalEdge edge) {
|
||||
layout_.setPadding(edge, padding);
|
||||
}
|
||||
|
||||
@@ -490,7 +169,7 @@ void Node::setLayoutComputedFlexBasis(const FloatOptional computedFlexBasis) {
|
||||
layout_.computedFlexBasis = computedFlexBasis;
|
||||
}
|
||||
|
||||
void Node::setLayoutPosition(float position, Edge edge) {
|
||||
void Node::setLayoutPosition(float position, PhysicalEdge edge) {
|
||||
layout_.setPosition(edge, position);
|
||||
}
|
||||
|
||||
@@ -523,11 +202,11 @@ float Node::relativePosition(
|
||||
if (style_.positionType() == PositionType::Static) {
|
||||
return 0;
|
||||
}
|
||||
if (isInlineStartPositionDefined(axis, direction)) {
|
||||
return getInlineStartPosition(axis, direction, axisSize);
|
||||
if (style_.isInlineStartPositionDefined(axis, direction)) {
|
||||
return style_.computeInlineStartPosition(axis, direction, axisSize);
|
||||
}
|
||||
|
||||
return -1 * getInlineEndPosition(axis, direction, axisSize);
|
||||
return -1 * style_.computeInlineEndPosition(axis, direction, axisSize);
|
||||
}
|
||||
|
||||
void Node::setPosition(
|
||||
@@ -551,45 +230,29 @@ void Node::setPosition(
|
||||
const float relativePositionCross =
|
||||
relativePosition(crossAxis, directionRespectingRoot, crossSize);
|
||||
|
||||
const Edge mainAxisLeadingEdge = getInlineStartEdge(mainAxis, direction);
|
||||
const Edge mainAxisTrailingEdge = getInlineEndEdge(mainAxis, direction);
|
||||
const Edge crossAxisLeadingEdge = getInlineStartEdge(crossAxis, direction);
|
||||
const Edge crossAxisTrailingEdge = getInlineEndEdge(crossAxis, direction);
|
||||
const auto mainAxisLeadingEdge = inlineStartEdge(mainAxis, direction);
|
||||
const auto mainAxisTrailingEdge = inlineEndEdge(mainAxis, direction);
|
||||
const auto crossAxisLeadingEdge = inlineStartEdge(crossAxis, direction);
|
||||
const auto crossAxisTrailingEdge = inlineEndEdge(crossAxis, direction);
|
||||
|
||||
setLayoutPosition(
|
||||
(getInlineStartMargin(mainAxis, direction, ownerWidth) +
|
||||
(style_.computeInlineStartMargin(mainAxis, direction, ownerWidth) +
|
||||
relativePositionMain),
|
||||
mainAxisLeadingEdge);
|
||||
setLayoutPosition(
|
||||
(getInlineEndMargin(mainAxis, direction, ownerWidth) +
|
||||
(style_.computeInlineEndMargin(mainAxis, direction, ownerWidth) +
|
||||
relativePositionMain),
|
||||
mainAxisTrailingEdge);
|
||||
setLayoutPosition(
|
||||
(getInlineStartMargin(crossAxis, direction, ownerWidth) +
|
||||
(style_.computeInlineStartMargin(crossAxis, direction, ownerWidth) +
|
||||
relativePositionCross),
|
||||
crossAxisLeadingEdge);
|
||||
setLayoutPosition(
|
||||
(getInlineEndMargin(crossAxis, direction, ownerWidth) +
|
||||
(style_.computeInlineEndMargin(crossAxis, direction, ownerWidth) +
|
||||
relativePositionCross),
|
||||
crossAxisTrailingEdge);
|
||||
}
|
||||
|
||||
Style::Length Node::getFlexStartMarginValue(FlexDirection axis) const {
|
||||
if (isRow(axis) && style_.margin(Edge::Start).isDefined()) {
|
||||
return style_.margin(Edge::Start);
|
||||
} else {
|
||||
return style_.margin(flexStartEdge(axis));
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length Node::marginTrailingValue(FlexDirection axis) const {
|
||||
if (isRow(axis) && style_.margin(Edge::End).isDefined()) {
|
||||
return style_.margin(Edge::End);
|
||||
} else {
|
||||
return style_.margin(flexEndEdge(axis));
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length Node::resolveFlexBasisPtr() const {
|
||||
Style::Length flexBasis = style_.flexBasis();
|
||||
if (flexBasis.unit() != Unit::Auto && flexBasis.unit() != Unit::Undefined) {
|
||||
|
109
yoga/node/Node.h
109
yoga/node/Node.h
@@ -20,6 +20,7 @@
|
||||
#include <yoga/enums/Errata.h>
|
||||
#include <yoga/enums/MeasureMode.h>
|
||||
#include <yoga/enums/NodeType.h>
|
||||
#include <yoga/enums/PhysicalEdge.h>
|
||||
#include <yoga/node/LayoutResults.h>
|
||||
#include <yoga/style/Style.h>
|
||||
|
||||
@@ -155,89 +156,6 @@ class YG_EXPORT Node : public ::YGNode {
|
||||
return resolvedDimensions_[static_cast<size_t>(dimension)];
|
||||
}
|
||||
|
||||
// Methods related to positions, margin, padding and border
|
||||
bool isFlexStartPositionDefined(FlexDirection axis, Direction direction)
|
||||
const;
|
||||
bool isInlineStartPositionDefined(FlexDirection axis, Direction direction)
|
||||
const;
|
||||
bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const;
|
||||
bool isInlineEndPositionDefined(FlexDirection axis, Direction direction)
|
||||
const;
|
||||
float getFlexStartPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const;
|
||||
float getInlineStartPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const;
|
||||
float getFlexEndPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const;
|
||||
float getInlineEndPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const;
|
||||
float getFlexStartMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getInlineStartMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getFlexEndMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getInlineEndMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getFlexStartBorder(FlexDirection flexDirection, Direction direction)
|
||||
const;
|
||||
float getInlineStartBorder(FlexDirection flexDirection, Direction direction)
|
||||
const;
|
||||
float getFlexEndBorder(FlexDirection flexDirection, Direction direction)
|
||||
const;
|
||||
float getInlineEndBorder(FlexDirection flexDirection, Direction direction)
|
||||
const;
|
||||
float getFlexStartPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getInlineStartPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getFlexEndPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getInlineEndPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getFlexStartPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getInlineStartPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getFlexEndPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getInlineEndPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const;
|
||||
float getBorderForAxis(FlexDirection axis) const;
|
||||
float getMarginForAxis(FlexDirection axis, float widthSize) const;
|
||||
float getGapForAxis(FlexDirection axis) const;
|
||||
// Setters
|
||||
|
||||
void setContext(void* context) {
|
||||
@@ -303,10 +221,10 @@ class YG_EXPORT Node : public ::YGNode {
|
||||
void setLayoutHadOverflow(bool hadOverflow);
|
||||
void setLayoutDimension(float LengthValue, Dimension dimension);
|
||||
void setLayoutDirection(Direction direction);
|
||||
void setLayoutMargin(float margin, Edge edge);
|
||||
void setLayoutBorder(float border, Edge edge);
|
||||
void setLayoutPadding(float padding, Edge edge);
|
||||
void setLayoutPosition(float position, Edge edge);
|
||||
void setLayoutMargin(float margin, PhysicalEdge edge);
|
||||
void setLayoutBorder(float border, PhysicalEdge edge);
|
||||
void setLayoutPadding(float padding, PhysicalEdge edge);
|
||||
void setLayoutPosition(float position, PhysicalEdge edge);
|
||||
void setPosition(
|
||||
const Direction direction,
|
||||
const float mainSize,
|
||||
@@ -314,8 +232,6 @@ class YG_EXPORT Node : public ::YGNode {
|
||||
const float ownerWidth);
|
||||
|
||||
// Other methods
|
||||
Style::Length getFlexStartMarginValue(FlexDirection axis) const;
|
||||
Style::Length marginTrailingValue(FlexDirection axis) const;
|
||||
Style::Length resolveFlexBasisPtr() const;
|
||||
void resolveDimension();
|
||||
Direction resolveDirection(const Direction ownerDirection);
|
||||
@@ -344,26 +260,11 @@ class YG_EXPORT Node : public ::YGNode {
|
||||
Direction direction,
|
||||
const float axisSize) const;
|
||||
|
||||
Edge getInlineStartEdge(FlexDirection flexDirection, Direction direction)
|
||||
const;
|
||||
Edge getInlineEndEdge(FlexDirection flexDirection, Direction direction) const;
|
||||
Edge getFlexStartRelativeEdge(
|
||||
FlexDirection flexDirection,
|
||||
Direction direction) const;
|
||||
Edge getFlexEndRelativeEdge(FlexDirection flexDirection, Direction direction)
|
||||
const;
|
||||
|
||||
void useWebDefaults() {
|
||||
style_.setFlexDirection(FlexDirection::Row);
|
||||
style_.setAlignContent(Align::Stretch);
|
||||
}
|
||||
|
||||
template <auto Field>
|
||||
Style::Length computeEdgeValueForColumn(Edge edge) const;
|
||||
|
||||
template <auto Field>
|
||||
Style::Length computeEdgeValueForRow(Edge rowEdge, Edge edge) const;
|
||||
|
||||
bool hasNewLayout_ : 1 = true;
|
||||
bool isReferenceBaseline_ : 1 = false;
|
||||
bool isDirty_ : 1 = false;
|
||||
|
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
#include <yoga/algorithm/FlexDirection.h>
|
||||
#include <yoga/enums/Align.h>
|
||||
#include <yoga/enums/Dimension.h>
|
||||
#include <yoga/enums/Direction.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <yoga/enums/Gutter.h>
|
||||
#include <yoga/enums/Justify.h>
|
||||
#include <yoga/enums/Overflow.h>
|
||||
#include <yoga/enums/PhysicalEdge.h>
|
||||
#include <yoga/enums/PositionType.h>
|
||||
#include <yoga/enums/Unit.h>
|
||||
#include <yoga/enums/Wrap.h>
|
||||
@@ -201,36 +203,241 @@ class YG_EXPORT Style {
|
||||
aspectRatio_ = value;
|
||||
}
|
||||
|
||||
Style::Length resolveColumnGap() const {
|
||||
if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::Column)];
|
||||
} else {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::All)];
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length resolveRowGap() const {
|
||||
if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::Row)];
|
||||
} else {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::All)];
|
||||
}
|
||||
}
|
||||
|
||||
bool horizontalInsetsDefined() const {
|
||||
return position_[YGEdge::YGEdgeLeft].isDefined() ||
|
||||
position_[YGEdge::YGEdgeRight].isDefined() ||
|
||||
position_[YGEdge::YGEdgeAll].isDefined() ||
|
||||
position_[YGEdge::YGEdgeHorizontal].isDefined() ||
|
||||
position_[YGEdge::YGEdgeStart].isDefined() ||
|
||||
position_[YGEdge::YGEdgeEnd].isDefined();
|
||||
return position_[yoga::to_underlying(Edge::Left)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::Right)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::All)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::Horizontal)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::Start)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::End)].isDefined();
|
||||
}
|
||||
|
||||
bool verticalInsetsDefined() const {
|
||||
return position_[YGEdge::YGEdgeTop].isDefined() ||
|
||||
position_[YGEdge::YGEdgeBottom].isDefined() ||
|
||||
position_[YGEdge::YGEdgeAll].isDefined() ||
|
||||
position_[YGEdge::YGEdgeVertical].isDefined();
|
||||
return position_[yoga::to_underlying(Edge::Top)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::Bottom)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::All)].isDefined() ||
|
||||
position_[yoga::to_underlying(Edge::Vertical)].isDefined();
|
||||
}
|
||||
|
||||
bool isFlexStartPositionDefined(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
return computePosition(flexStartEdge(axis), direction).isDefined();
|
||||
}
|
||||
|
||||
bool isInlineStartPositionDefined(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
return computePosition(inlineStartEdge(axis, direction), direction)
|
||||
.isDefined();
|
||||
}
|
||||
|
||||
bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const {
|
||||
return computePosition(flexEndEdge(axis), direction).isDefined();
|
||||
}
|
||||
|
||||
bool isInlineEndPositionDefined(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
return computePosition(inlineEndEdge(axis, direction), direction)
|
||||
.isDefined();
|
||||
}
|
||||
|
||||
float computeFlexStartPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
return computePosition(flexStartEdge(axis), direction)
|
||||
.resolve(axisSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeInlineStartPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
return computePosition(inlineStartEdge(axis, direction), direction)
|
||||
.resolve(axisSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeFlexEndPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
return computePosition(flexEndEdge(axis), direction)
|
||||
.resolve(axisSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeInlineEndPosition(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float axisSize) const {
|
||||
return computePosition(inlineEndEdge(axis, direction), direction)
|
||||
.resolve(axisSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeFlexStartMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeMargin(flexStartEdge(axis), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeInlineStartMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeMargin(inlineStartEdge(axis, direction), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeFlexEndMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeMargin(flexEndEdge(axis), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeInlineEndMargin(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeMargin(inlineEndEdge(axis, direction), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeFlexStartBorder(FlexDirection axis, Direction direction) const {
|
||||
return computeBorder(flexStartEdge(axis), direction)
|
||||
.resolve(0.0f)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeInlineStartBorder(FlexDirection axis, Direction direction)
|
||||
const {
|
||||
return computeBorder(inlineStartEdge(axis, direction), direction)
|
||||
.resolve(0.0f)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeFlexEndBorder(FlexDirection axis, Direction direction) const {
|
||||
return computeBorder(flexEndEdge(axis), direction)
|
||||
.resolve(0.0f)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeInlineEndBorder(FlexDirection axis, Direction direction) const {
|
||||
return computeBorder(inlineEndEdge(axis, direction), direction)
|
||||
.resolve(0.0f)
|
||||
.unwrapOrDefault(0.0f);
|
||||
}
|
||||
|
||||
float computeFlexStartPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return maxOrDefined(
|
||||
computePadding(flexStartEdge(axis), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrap(),
|
||||
0.0f);
|
||||
}
|
||||
|
||||
float computeInlineStartPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return maxOrDefined(
|
||||
computePadding(inlineStartEdge(axis, direction), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrap(),
|
||||
0.0f);
|
||||
}
|
||||
|
||||
float computeFlexEndPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return maxOrDefined(
|
||||
computePadding(flexEndEdge(axis), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrap(),
|
||||
0.0f);
|
||||
}
|
||||
|
||||
float computeInlineEndPadding(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return maxOrDefined(
|
||||
computePadding(inlineEndEdge(axis, direction), direction)
|
||||
.resolve(widthSize)
|
||||
.unwrap(),
|
||||
0.0f);
|
||||
}
|
||||
|
||||
float computeInlineStartPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeInlineStartPadding(axis, direction, widthSize) +
|
||||
computeInlineStartBorder(axis, direction);
|
||||
}
|
||||
|
||||
float computeFlexStartPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeFlexStartPadding(axis, direction, widthSize) +
|
||||
computeFlexStartBorder(axis, direction);
|
||||
}
|
||||
|
||||
float computeInlineEndPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeInlineEndPadding(axis, direction, widthSize) +
|
||||
computeInlineEndBorder(axis, direction);
|
||||
}
|
||||
|
||||
float computeFlexEndPaddingAndBorder(
|
||||
FlexDirection axis,
|
||||
Direction direction,
|
||||
float widthSize) const {
|
||||
return computeFlexEndPadding(axis, direction, widthSize) +
|
||||
computeFlexEndBorder(axis, direction);
|
||||
}
|
||||
|
||||
float computeBorderForAxis(FlexDirection axis) const {
|
||||
return computeInlineStartBorder(axis, Direction::LTR) +
|
||||
computeInlineEndBorder(axis, Direction::LTR);
|
||||
}
|
||||
|
||||
float computeMarginForAxis(FlexDirection axis, float widthSize) const {
|
||||
// The total margin for a given axis does not depend on the direction
|
||||
// so hardcoding LTR here to avoid piping direction to this function
|
||||
return computeInlineStartMargin(axis, Direction::LTR, widthSize) +
|
||||
computeInlineEndMargin(axis, Direction::LTR, widthSize);
|
||||
}
|
||||
|
||||
float computeGapForAxis(FlexDirection axis) const {
|
||||
auto gap = isRow(axis) ? computeColumnGap() : computeRowGap();
|
||||
// TODO: Validate percentage gap, and expose ability to set percentage to
|
||||
// public API
|
||||
return maxOrDefined(gap.resolve(0.0f /*ownerSize*/).unwrap(), 0.0f);
|
||||
}
|
||||
|
||||
bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const {
|
||||
return computeMargin(flexStartEdge(axis), direction).isAuto();
|
||||
}
|
||||
|
||||
bool flexEndMarginIsAuto(FlexDirection axis, Direction direction) const {
|
||||
return computeMargin(flexEndEdge(axis), direction).isAuto();
|
||||
}
|
||||
|
||||
bool operator==(const Style& other) const {
|
||||
@@ -265,6 +472,138 @@ class YG_EXPORT Style {
|
||||
using Edges = std::array<CompactValue, ordinalCount<Edge>()>;
|
||||
using Gutters = std::array<CompactValue, ordinalCount<Gutter>()>;
|
||||
|
||||
Style::Length computeColumnGap() const {
|
||||
if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::Column)];
|
||||
} else {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::All)];
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length computeRowGap() const {
|
||||
if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::Row)];
|
||||
} else {
|
||||
return (Style::Length)gap_[yoga::to_underlying(Gutter::All)];
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length computeLeftEdge(const Edges& edges, Direction layoutDirection)
|
||||
const {
|
||||
if (layoutDirection == Direction::LTR &&
|
||||
edges[yoga::to_underlying(Edge::Start)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Start)];
|
||||
} else if (
|
||||
layoutDirection == Direction::RTL &&
|
||||
edges[yoga::to_underlying(Edge::End)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::End)];
|
||||
} else if (edges[yoga::to_underlying(Edge::Left)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Left)];
|
||||
} else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Horizontal)];
|
||||
} else {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::All)];
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length computeTopEdge(const Edges& edges) const {
|
||||
if (edges[yoga::to_underlying(Edge::Top)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Top)];
|
||||
} else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Vertical)];
|
||||
} else {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::All)];
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length computeRightEdge(const Edges& edges, Direction layoutDirection)
|
||||
const {
|
||||
if (layoutDirection == Direction::LTR &&
|
||||
edges[yoga::to_underlying(Edge::End)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::End)];
|
||||
} else if (
|
||||
layoutDirection == Direction::RTL &&
|
||||
edges[yoga::to_underlying(Edge::Start)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Start)];
|
||||
} else if (edges[yoga::to_underlying(Edge::Right)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Right)];
|
||||
} else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Horizontal)];
|
||||
} else {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::All)];
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length computeBottomEdge(const Edges& edges) const {
|
||||
if (edges[yoga::to_underlying(Edge::Bottom)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Bottom)];
|
||||
} else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::Vertical)];
|
||||
} else {
|
||||
return (Style::Length)edges[yoga::to_underlying(Edge::All)];
|
||||
}
|
||||
}
|
||||
|
||||
Style::Length computePosition(PhysicalEdge edge, Direction direction) const {
|
||||
switch (edge) {
|
||||
case PhysicalEdge::Left:
|
||||
return computeLeftEdge(position_, direction);
|
||||
case PhysicalEdge::Top:
|
||||
return computeTopEdge(position_);
|
||||
case PhysicalEdge::Right:
|
||||
return computeRightEdge(position_, direction);
|
||||
case PhysicalEdge::Bottom:
|
||||
return computeBottomEdge(position_);
|
||||
}
|
||||
|
||||
fatalWithMessage("Invalid physical edge");
|
||||
}
|
||||
|
||||
Style::Length computeMargin(PhysicalEdge edge, Direction direction) const {
|
||||
switch (edge) {
|
||||
case PhysicalEdge::Left:
|
||||
return computeLeftEdge(margin_, direction);
|
||||
case PhysicalEdge::Top:
|
||||
return computeTopEdge(margin_);
|
||||
case PhysicalEdge::Right:
|
||||
return computeRightEdge(margin_, direction);
|
||||
case PhysicalEdge::Bottom:
|
||||
return computeBottomEdge(margin_);
|
||||
}
|
||||
|
||||
fatalWithMessage("Invalid physical edge");
|
||||
}
|
||||
|
||||
Style::Length computePadding(PhysicalEdge edge, Direction direction) const {
|
||||
switch (edge) {
|
||||
case PhysicalEdge::Left:
|
||||
return computeLeftEdge(padding_, direction);
|
||||
case PhysicalEdge::Top:
|
||||
return computeTopEdge(padding_);
|
||||
case PhysicalEdge::Right:
|
||||
return computeRightEdge(padding_, direction);
|
||||
case PhysicalEdge::Bottom:
|
||||
return computeBottomEdge(padding_);
|
||||
}
|
||||
|
||||
fatalWithMessage("Invalid physical edge");
|
||||
}
|
||||
|
||||
Style::Length computeBorder(PhysicalEdge edge, Direction direction) const {
|
||||
switch (edge) {
|
||||
case PhysicalEdge::Left:
|
||||
return computeLeftEdge(border_, direction);
|
||||
case PhysicalEdge::Top:
|
||||
return computeTopEdge(border_);
|
||||
case PhysicalEdge::Right:
|
||||
return computeRightEdge(border_, direction);
|
||||
case PhysicalEdge::Bottom:
|
||||
return computeBottomEdge(border_);
|
||||
}
|
||||
|
||||
fatalWithMessage("Invalid physical edge");
|
||||
}
|
||||
|
||||
Direction direction_ : bitCount<Direction>() = Direction::Inherit;
|
||||
FlexDirection flexDirection_
|
||||
: bitCount<FlexDirection>() = FlexDirection::Column;
|
||||
|
Reference in New Issue
Block a user