Fix issue where position insets were not working with row reverse (#1431)

Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1431

X-link: https://github.com/facebook/react-native/pull/41041

The last of the row-reverse issues hurray!

The position insets were broken with row-reverse since we were using the main-start/main-end edges to inset from and NOT the inline-start/inline-end edges as we should. This made it so that inset in left and right were swapped and same with top and bottom (with column-reverse). The solution here is the same as the previous ones were we are migrating to using inline-start/end as the leading/trailing edge now.

Reviewed By: NickGerleman

Differential Revision: D50390543

fbshipit-source-id: b714deab8489fbe11f7f6db21e4aad3b3aa314b3
This commit is contained in:
Joe Vilches
2023-10-18 17:30:18 -07:00
committed by Facebook GitHub Bot
parent 2668e8e70c
commit b6f85a1c76
3 changed files with 89 additions and 54 deletions

View File

@@ -343,13 +343,13 @@ static void layoutAbsoluteChild(
} else { } else {
// If the child doesn't have a specified width, compute the width based on // If the child doesn't have a specified width, compute the width based on
// the left/right offsets if they're defined. // the left/right offsets if they're defined.
if (child->isFlexStartPositionDefined(FlexDirection::Row) && if (child->isInlineStartPositionDefined(FlexDirection::Row, direction) &&
child->isFlexEndPositionDefined(FlexDirection::Row)) { child->isInlineEndPositionDefined(FlexDirection::Row, direction)) {
childWidth = node->getLayout().measuredDimension(Dimension::Width) - childWidth = node->getLayout().measuredDimension(Dimension::Width) -
(node->getInlineStartBorder(FlexDirection::Row, direction) + (node->getInlineStartBorder(FlexDirection::Row, direction) +
node->getInlineEndBorder(FlexDirection::Row, direction)) - node->getInlineEndBorder(FlexDirection::Row, direction)) -
(child->getFlexStartPosition(FlexDirection::Row, width) + (child->getInlineStartPosition(FlexDirection::Row, direction, width) +
child->getFlexEndPosition(FlexDirection::Row, width)); child->getInlineEndPosition(FlexDirection::Row, direction, width));
childWidth = childWidth =
boundAxis(child, FlexDirection::Row, childWidth, width, width); boundAxis(child, FlexDirection::Row, childWidth, width, width);
} }
@@ -363,13 +363,15 @@ static void layoutAbsoluteChild(
} else { } else {
// If the child doesn't have a specified height, compute the height based on // If the child doesn't have a specified height, compute the height based on
// the top/bottom offsets if they're defined. // the top/bottom offsets if they're defined.
if (child->isFlexStartPositionDefined(FlexDirection::Column) && if (child->isInlineStartPositionDefined(FlexDirection::Column, direction) &&
child->isFlexEndPositionDefined(FlexDirection::Column)) { child->isInlineEndPositionDefined(FlexDirection::Column, direction)) {
childHeight = node->getLayout().measuredDimension(Dimension::Height) - childHeight = node->getLayout().measuredDimension(Dimension::Height) -
(node->getInlineStartBorder(FlexDirection::Column, direction) + (node->getInlineStartBorder(FlexDirection::Column, direction) +
node->getInlineEndBorder(FlexDirection::Column, direction)) - node->getInlineEndBorder(FlexDirection::Column, direction)) -
(child->getFlexStartPosition(FlexDirection::Column, height) + (child->getInlineStartPosition(
child->getFlexEndPosition(FlexDirection::Column, height)); FlexDirection::Column, direction, height) +
child->getInlineEndPosition(
FlexDirection::Column, direction, height));
childHeight = childHeight =
boundAxis(child, FlexDirection::Column, childHeight, height, width); boundAxis(child, FlexDirection::Column, childHeight, height, width);
} }
@@ -446,18 +448,19 @@ static void layoutAbsoluteChild(
depth, depth,
generationCount); generationCount);
if (child->isFlexEndPositionDefined(mainAxis) && if (child->isInlineEndPositionDefined(mainAxis, direction) &&
!child->isFlexStartPositionDefined(mainAxis)) { !child->isInlineStartPositionDefined(mainAxis, direction)) {
child->setLayoutPosition( child->setLayoutPosition(
node->getLayout().measuredDimension(dimension(mainAxis)) - node->getLayout().measuredDimension(dimension(mainAxis)) -
child->getLayout().measuredDimension(dimension(mainAxis)) - child->getLayout().measuredDimension(dimension(mainAxis)) -
node->getInlineEndBorder(mainAxis, direction) - node->getInlineEndBorder(mainAxis, direction) -
child->getInlineEndMargin( child->getInlineEndMargin(
mainAxis, direction, isMainAxisRow ? width : height) - mainAxis, direction, isMainAxisRow ? width : height) -
child->getFlexEndPosition(mainAxis, isMainAxisRow ? width : height), child->getInlineEndPosition(
mainAxis, direction, isMainAxisRow ? width : height),
flexStartEdge(mainAxis)); flexStartEdge(mainAxis));
} else if ( } else if (
!child->isFlexStartPositionDefined(mainAxis) && !child->isInlineStartPositionDefined(mainAxis, direction) &&
node->getStyle().justifyContent() == Justify::Center) { node->getStyle().justifyContent() == Justify::Center) {
child->setLayoutPosition( child->setLayoutPosition(
(node->getLayout().measuredDimension(dimension(mainAxis)) - (node->getLayout().measuredDimension(dimension(mainAxis)) -
@@ -465,7 +468,7 @@ static void layoutAbsoluteChild(
2.0f, 2.0f,
flexStartEdge(mainAxis)); flexStartEdge(mainAxis));
} else if ( } else if (
!child->isFlexStartPositionDefined(mainAxis) && !child->isInlineStartPositionDefined(mainAxis, direction) &&
node->getStyle().justifyContent() == Justify::FlexEnd) { node->getStyle().justifyContent() == Justify::FlexEnd) {
child->setLayoutPosition( child->setLayoutPosition(
(node->getLayout().measuredDimension(dimension(mainAxis)) - (node->getLayout().measuredDimension(dimension(mainAxis)) -
@@ -474,10 +477,11 @@ static void layoutAbsoluteChild(
} else if ( } else if (
node->getConfig()->isExperimentalFeatureEnabled( node->getConfig()->isExperimentalFeatureEnabled(
ExperimentalFeature::AbsolutePercentageAgainstPaddingEdge) && ExperimentalFeature::AbsolutePercentageAgainstPaddingEdge) &&
child->isFlexStartPositionDefined(mainAxis)) { child->isInlineStartPositionDefined(mainAxis, direction)) {
child->setLayoutPosition( child->setLayoutPosition(
child->getFlexStartPosition( child->getInlineStartPosition(
mainAxis, mainAxis,
direction,
node->getLayout().measuredDimension(dimension(mainAxis))) + node->getLayout().measuredDimension(dimension(mainAxis))) +
node->getInlineStartBorder(mainAxis, direction) + node->getInlineStartBorder(mainAxis, direction) +
child->getInlineStartMargin( child->getInlineStartMargin(
@@ -487,20 +491,20 @@ static void layoutAbsoluteChild(
flexStartEdge(mainAxis)); flexStartEdge(mainAxis));
} }
if (child->isFlexEndPositionDefined(crossAxis) && if (child->isInlineEndPositionDefined(crossAxis, direction) &&
!child->isFlexStartPositionDefined(crossAxis)) { !child->isInlineStartPositionDefined(crossAxis, direction)) {
child->setLayoutPosition( child->setLayoutPosition(
node->getLayout().measuredDimension(dimension(crossAxis)) - node->getLayout().measuredDimension(dimension(crossAxis)) -
child->getLayout().measuredDimension(dimension(crossAxis)) - child->getLayout().measuredDimension(dimension(crossAxis)) -
node->getInlineEndBorder(crossAxis, direction) - node->getInlineEndBorder(crossAxis, direction) -
child->getInlineEndMargin( child->getInlineEndMargin(
crossAxis, direction, isMainAxisRow ? height : width) - crossAxis, direction, isMainAxisRow ? height : width) -
child->getFlexEndPosition( child->getInlineEndPosition(
crossAxis, isMainAxisRow ? height : width), crossAxis, direction, isMainAxisRow ? height : width),
flexStartEdge(crossAxis)); flexStartEdge(crossAxis));
} else if ( } else if (
!child->isFlexStartPositionDefined(crossAxis) && !child->isInlineStartPositionDefined(crossAxis, direction) &&
resolveChildAlignment(node, child) == Align::Center) { resolveChildAlignment(node, child) == Align::Center) {
child->setLayoutPosition( child->setLayoutPosition(
(node->getLayout().measuredDimension(dimension(crossAxis)) - (node->getLayout().measuredDimension(dimension(crossAxis)) -
@@ -508,7 +512,7 @@ static void layoutAbsoluteChild(
2.0f, 2.0f,
flexStartEdge(crossAxis)); flexStartEdge(crossAxis));
} else if ( } else if (
!child->isFlexStartPositionDefined(crossAxis) && !child->isInlineStartPositionDefined(crossAxis, direction) &&
((resolveChildAlignment(node, child) == Align::FlexEnd) ^ ((resolveChildAlignment(node, child) == Align::FlexEnd) ^
(node->getStyle().flexWrap() == Wrap::WrapReverse))) { (node->getStyle().flexWrap() == Wrap::WrapReverse))) {
child->setLayoutPosition( child->setLayoutPosition(
@@ -518,10 +522,11 @@ static void layoutAbsoluteChild(
} else if ( } else if (
node->getConfig()->isExperimentalFeatureEnabled( node->getConfig()->isExperimentalFeatureEnabled(
ExperimentalFeature::AbsolutePercentageAgainstPaddingEdge) && ExperimentalFeature::AbsolutePercentageAgainstPaddingEdge) &&
child->isFlexStartPositionDefined(crossAxis)) { child->isInlineStartPositionDefined(crossAxis, direction)) {
child->setLayoutPosition( child->setLayoutPosition(
child->getFlexStartPosition( child->getInlineStartPosition(
crossAxis, crossAxis,
direction,
node->getLayout().measuredDimension(dimension(crossAxis))) + node->getLayout().measuredDimension(dimension(crossAxis))) +
node->getInlineStartBorder(crossAxis, direction) + node->getInlineStartBorder(crossAxis, direction) +
child->getInlineStartMargin( child->getInlineStartMargin(
@@ -1305,13 +1310,14 @@ static void justifyMainAxis(
continue; continue;
} }
if (childStyle.positionType() == PositionType::Absolute && if (childStyle.positionType() == PositionType::Absolute &&
child->isFlexStartPositionDefined(mainAxis)) { child->isInlineStartPositionDefined(mainAxis, direction)) {
if (performLayout) { if (performLayout) {
// In case the child is position absolute and has left/top being // In case the child is position absolute and has left/top being
// defined, we override the position to whatever the user said (and // defined, we override the position to whatever the user said (and
// margin/border). // margin/border).
child->setLayoutPosition( child->setLayoutPosition(
child->getFlexStartPosition(mainAxis, availableInnerMainDim) + child->getInlineStartPosition(
mainAxis, direction, availableInnerMainDim) +
node->getInlineStartBorder(mainAxis, direction) + node->getInlineStartBorder(mainAxis, direction) +
child->getInlineStartMargin( child->getInlineStartMargin(
mainAxis, direction, availableInnerWidth), mainAxis, direction, availableInnerWidth),
@@ -1864,10 +1870,11 @@ static void calculateLayoutImpl(
// top/left/bottom/right set, override all the previously computed // top/left/bottom/right set, override all the previously computed
// positions to set it correctly. // positions to set it correctly.
const bool isChildLeadingPosDefined = const bool isChildLeadingPosDefined =
child->isFlexStartPositionDefined(crossAxis); child->isInlineStartPositionDefined(crossAxis, direction);
if (isChildLeadingPosDefined) { if (isChildLeadingPosDefined) {
child->setLayoutPosition( child->setLayoutPosition(
child->getFlexStartPosition(crossAxis, availableInnerCrossDim) + child->getInlineStartPosition(
crossAxis, direction, availableInnerCrossDim) +
node->getInlineStartBorder(crossAxis, direction) + node->getInlineStartBorder(crossAxis, direction) +
child->getInlineStartMargin( child->getInlineStartMargin(
crossAxis, direction, availableInnerWidth), crossAxis, direction, availableInnerWidth),
@@ -2195,8 +2202,10 @@ static void calculateLayoutImpl(
child->setLayoutPosition( child->setLayoutPosition(
currentLead + maxAscentForCurrentLine - currentLead + maxAscentForCurrentLine -
calculateBaseline(child) + calculateBaseline(child) +
child->getFlexStartPosition( child->getInlineStartPosition(
FlexDirection::Column, availableInnerCrossDim), FlexDirection::Column,
direction,
availableInnerCrossDim),
YGEdgeTop); YGEdgeTop);
break; break;

View File

@@ -99,36 +99,46 @@ YGEdge Node::getInlineEndEdgeUsingErrata(
: inlineEndEdge(flexDirection, direction); : inlineEndEdge(flexDirection, direction);
} }
bool Node::isFlexStartPositionDefined(FlexDirection axis) const { bool Node::isInlineStartPositionDefined(FlexDirection axis, Direction direction)
const {
const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction);
auto leadingPosition = isRow(axis) auto leadingPosition = isRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge)
style_.position(), YGEdgeStart, flexStartEdge(axis)) : computeEdgeValueForColumn(style_.position(), startEdge);
: computeEdgeValueForColumn(style_.position(), flexStartEdge(axis));
return !leadingPosition.isUndefined(); return !leadingPosition.isUndefined();
} }
bool Node::isFlexEndPositionDefined(FlexDirection axis) const { bool Node::isInlineEndPositionDefined(FlexDirection axis, Direction direction)
const {
const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction);
auto trailingPosition = isRow(axis) auto trailingPosition = isRow(axis)
? computeEdgeValueForRow(style_.position(), YGEdgeEnd, flexEndEdge(axis)) ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.position(), flexEndEdge(axis)); : computeEdgeValueForColumn(style_.position(), endEdge);
return !trailingPosition.isUndefined(); return !trailingPosition.isUndefined();
} }
float Node::getFlexStartPosition(FlexDirection axis, float axisSize) const { float Node::getInlineStartPosition(
FlexDirection axis,
Direction direction,
float axisSize) const {
const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction);
auto leadingPosition = isRow(axis) auto leadingPosition = isRow(axis)
? computeEdgeValueForRow( ? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge)
style_.position(), YGEdgeStart, flexStartEdge(axis)) : computeEdgeValueForColumn(style_.position(), startEdge);
: computeEdgeValueForColumn(style_.position(), flexStartEdge(axis));
return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f); return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f);
} }
float Node::getFlexEndPosition(FlexDirection axis, float axisSize) const { float Node::getInlineEndPosition(
FlexDirection axis,
Direction direction,
float axisSize) const {
const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction);
auto trailingPosition = isRow(axis) auto trailingPosition = isRow(axis)
? computeEdgeValueForRow(style_.position(), YGEdgeEnd, flexEndEdge(axis)) ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge)
: computeEdgeValueForColumn(style_.position(), flexEndEdge(axis)); : computeEdgeValueForColumn(style_.position(), endEdge);
return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f); return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f);
} }
@@ -440,12 +450,15 @@ void Node::setLayoutDimension(float dimensionValue, Dimension dimension) {
// If both left and right are defined, then use left. Otherwise return +left or // If both left and right are defined, then use left. Otherwise return +left or
// -right depending on which is defined. // -right depending on which is defined.
float Node::relativePosition(FlexDirection axis, float axisSize) const { float Node::relativePosition(
if (isFlexStartPositionDefined(axis)) { FlexDirection axis,
return getFlexStartPosition(axis, axisSize); Direction direction,
float axisSize) const {
if (isInlineStartPositionDefined(axis, direction)) {
return getInlineStartPosition(axis, direction, axisSize);
} }
return -1 * getFlexEndPosition(axis, axisSize); return -1 * getInlineEndPosition(axis, direction, axisSize);
} }
void Node::setPosition( void Node::setPosition(
@@ -465,8 +478,10 @@ void Node::setPosition(
// Here we should check for `PositionType::Static` and in this case zero inset // Here we should check for `PositionType::Static` and in this case zero inset
// properties (left, right, top, bottom, begin, end). // properties (left, right, top, bottom, begin, end).
// https://www.w3.org/TR/css-position-3/#valdef-position-static // https://www.w3.org/TR/css-position-3/#valdef-position-static
const float relativePositionMain = relativePosition(mainAxis, mainSize); const float relativePositionMain =
const float relativePositionCross = relativePosition(crossAxis, crossSize); relativePosition(mainAxis, directionRespectingRoot, mainSize);
const float relativePositionCross =
relativePosition(crossAxis, directionRespectingRoot, crossSize);
const YGEdge mainAxisLeadingEdge = const YGEdge mainAxisLeadingEdge =
getInlineStartEdgeUsingErrata(mainAxis, direction); getInlineStartEdgeUsingErrata(mainAxis, direction);

View File

@@ -48,7 +48,10 @@ class YG_EXPORT Node : public ::YGNode {
std::array<YGValue, 2> resolvedDimensions_ = { std::array<YGValue, 2> resolvedDimensions_ = {
{YGValueUndefined, YGValueUndefined}}; {YGValueUndefined, YGValueUndefined}};
float relativePosition(FlexDirection axis, const float axisSize) const; float relativePosition(
FlexDirection axis,
Direction direction,
const float axisSize) const;
YGEdge getInlineStartEdgeUsingErrata( YGEdge getInlineStartEdgeUsingErrata(
FlexDirection flexDirection, FlexDirection flexDirection,
@@ -196,10 +199,18 @@ class YG_EXPORT Node : public ::YGNode {
YGEdge edge); YGEdge edge);
// Methods related to positions, margin, padding and border // Methods related to positions, margin, padding and border
bool isFlexStartPositionDefined(FlexDirection axis) const; bool isInlineStartPositionDefined(FlexDirection axis, Direction direction)
bool isFlexEndPositionDefined(FlexDirection axis) const; const;
float getFlexStartPosition(FlexDirection axis, float axisSize) const; bool isInlineEndPositionDefined(FlexDirection axis, Direction direction)
float getFlexEndPosition(FlexDirection axis, float axisSize) const; const;
float getInlineStartPosition(
FlexDirection axis,
Direction direction,
float axisSize) const;
float getInlineEndPosition(
FlexDirection axis,
Direction direction,
float axisSize) const;
float getInlineStartMargin( float getInlineStartMargin(
FlexDirection axis, FlexDirection axis,
Direction direction, Direction direction,