Skip to content

Commit

Permalink
Impl of content box
Browse files Browse the repository at this point in the history
Summary:
X-link: facebook/yoga#1711

box sizing is really just a reinterpretation of what length properties (like `width`, `height`, `max-width`, etc) mean. So to implement this I just add the border and padding if we are in content box when we ask for any of these properties. All the math that gets done by the algorithm is still in border box land, and the layout we return is to be interpreted as the border box (this is actually the expected behavior per https://drafts.csswg.org/css-sizing/#box-sizing). This makes this implementation pretty simple actually.

Chnagelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D63416833
  • Loading branch information
joevilches authored and facebook-github-bot committed Sep 30, 2024
1 parent b852187 commit db9a35d
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,9 @@ void layoutAbsoluteChild(
FlexDirection::Column, containingBlockWidth);

if (child->hasDefiniteLength(Dimension::Width, containingBlockWidth)) {
childWidth = child->getProcessedDimension(Dimension::Width)
.resolve(containingBlockWidth)
childWidth = child
->getResolvedDimension(
direction, Dimension::Width, containingBlockWidth)
.unwrap() +
marginRow;
} else {
Expand Down Expand Up @@ -359,8 +360,9 @@ void layoutAbsoluteChild(
}

if (child->hasDefiniteLength(Dimension::Height, containingBlockHeight)) {
childHeight = child->getProcessedDimension(Dimension::Height)
.resolve(containingBlockHeight)
childHeight = child
->getResolvedDimension(
direction, Dimension::Height, containingBlockHeight)
.unwrap() +
marginColumn;
} else {
Expand Down
16 changes: 11 additions & 5 deletions packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,23 @@ inline float paddingAndBorderForAxis(

inline FloatOptional boundAxisWithinMinAndMax(
const yoga::Node* const node,
const Direction direction,
const FlexDirection axis,
const FloatOptional value,
const float axisSize) {
FloatOptional min;
FloatOptional max;

if (isColumn(axis)) {
min = node->style().minDimension(Dimension::Height).resolve(axisSize);
max = node->style().maxDimension(Dimension::Height).resolve(axisSize);
min = node->style().resolvedMinDimension(
direction, Dimension::Height, axisSize);
max = node->style().resolvedMaxDimension(
direction, Dimension::Height, axisSize);
} else if (isRow(axis)) {
min = node->style().minDimension(Dimension::Width).resolve(axisSize);
max = node->style().maxDimension(Dimension::Width).resolve(axisSize);
min = node->style().resolvedMinDimension(
direction, Dimension::Width, axisSize);
max = node->style().resolvedMaxDimension(
direction, Dimension::Width, axisSize);
}

if (max >= FloatOptional{0} && value > max) {
Expand All @@ -64,7 +69,8 @@ inline float boundAxis(
const float axisSize,
const float widthSize) {
return yoga::maxOrDefined(
boundAxisWithinMinAndMax(node, axis, FloatOptional{value}, axisSize)
boundAxisWithinMinAndMax(
node, direction, axis, FloatOptional{value}, axisSize)
.unwrap(),
paddingAndBorderForAxis(node, axis, direction, widthSize));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ std::atomic<uint32_t> gCurrentGenerationCount(0);

static void constrainMaxSizeForMode(
const yoga::Node* node,
Direction direction,
FlexDirection axis,
float ownerAxisSize,
float ownerWidth,
/*in_out*/ SizingMode* mode,
/*in_out*/ float* size) {
const FloatOptional maxSize =
node->style().maxDimension(dimension(axis)).resolve(ownerAxisSize) +
const FloatOptional maxSize = node->style().resolvedMaxDimension(
direction, dimension(axis), ownerAxisSize) +
FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth));
switch (*mode) {
case SizingMode::StretchFit:
Expand Down Expand Up @@ -110,15 +111,15 @@ static void computeFlexBasisForChild(
child, FlexDirection::Row, direction, ownerWidth));

child->setLayoutComputedFlexBasis(yoga::maxOrDefined(
child->getProcessedDimension(Dimension::Width).resolve(ownerWidth),
child->getResolvedDimension(direction, Dimension::Width, ownerWidth),
paddingAndBorder));
} else if (!isMainAxisRow && isColumnStyleDimDefined) {
// The height is definite, so use that as the flex basis.
const FloatOptional paddingAndBorder =
FloatOptional(paddingAndBorderForAxis(
child, FlexDirection::Column, direction, ownerWidth));
child->setLayoutComputedFlexBasis(yoga::maxOrDefined(
child->getProcessedDimension(Dimension::Height).resolve(ownerHeight),
child->getResolvedDimension(direction, Dimension::Height, ownerHeight),
paddingAndBorder));
} else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex
Expand All @@ -132,16 +133,16 @@ static void computeFlexBasisForChild(
child->style().computeMarginForAxis(FlexDirection::Column, ownerWidth);

if (isRowStyleDimDefined) {
childWidth = child->getProcessedDimension(Dimension::Width)
.resolve(ownerWidth)
.unwrap() +
childWidth =
child->getResolvedDimension(direction, Dimension::Width, ownerWidth)
.unwrap() +
marginRow;
childWidthSizingMode = SizingMode::StretchFit;
}
if (isColumnStyleDimDefined) {
childHeight = child->getProcessedDimension(Dimension::Height)
.resolve(ownerHeight)
.unwrap() +
childHeight =
child->getResolvedDimension(direction, Dimension::Height, ownerHeight)
.unwrap() +
marginColumn;
childHeightSizingMode = SizingMode::StretchFit;
}
Expand Down Expand Up @@ -216,13 +217,15 @@ static void computeFlexBasisForChild(

constrainMaxSizeForMode(
child,
direction,
FlexDirection::Row,
ownerWidth,
ownerWidth,
&childWidthSizingMode,
&childWidth);
constrainMaxSizeForMode(
child,
direction,
FlexDirection::Column,
ownerHeight,
ownerWidth,
Expand Down Expand Up @@ -469,6 +472,7 @@ static void zeroOutLayoutRecursively(yoga::Node* const node) {

static float calculateAvailableInnerDimension(
const yoga::Node* const node,
const Direction direction,
const Dimension dimension,
const float availableDim,
const float paddingAndBorder,
Expand All @@ -480,13 +484,13 @@ static float calculateAvailableInnerDimension(
// We want to make sure our available height does not violate min and max
// constraints
const FloatOptional minDimensionOptional =
node->style().minDimension(dimension).resolve(ownerDim);
node->style().resolvedMinDimension(direction, dimension, ownerDim);
const float minInnerDim = minDimensionOptional.isUndefined()
? 0.0f
: minDimensionOptional.unwrap() - paddingAndBorder;

const FloatOptional maxDimensionOptional =
node->style().maxDimension(dimension).resolve(ownerDim);
node->style().resolvedMaxDimension(direction, dimension, ownerDim);

const float maxInnerDim = maxDimensionOptional.isUndefined()
? FLT_MAX
Expand Down Expand Up @@ -611,6 +615,7 @@ static float distributeFreeSpaceSecondPass(
for (auto currentLineChild : flexLine.itemsInFlow) {
childFlexBasis = boundAxisWithinMinAndMax(
currentLineChild,
direction,
mainAxis,
currentLineChild->getLayout().computedFlexBasis,
mainAxisownerSize)
Expand Down Expand Up @@ -709,8 +714,9 @@ static float distributeFreeSpaceSecondPass(
: SizingMode::FitContent;
} else {
childCrossSize =
currentLineChild->getProcessedDimension(dimension(crossAxis))
.resolve(availableInnerCrossDim)
currentLineChild
->getResolvedDimension(
direction, dimension(crossAxis), availableInnerCrossDim)
.unwrap() +
marginCross;
const bool isLoosePercentageMeasurement =
Expand All @@ -725,13 +731,15 @@ static float distributeFreeSpaceSecondPass(

constrainMaxSizeForMode(
currentLineChild,
direction,
mainAxis,
availableInnerMainDim,
availableInnerWidth,
&childMainSizingMode,
&childMainSize);
constrainMaxSizeForMode(
currentLineChild,
direction,
crossAxis,
availableInnerCrossDim,
availableInnerWidth,
Expand Down Expand Up @@ -812,6 +820,7 @@ static void distributeFreeSpaceFirstPass(
for (auto currentLineChild : flexLine.itemsInFlow) {
float childFlexBasis = boundAxisWithinMinAndMax(
currentLineChild,
direction,
mainAxis,
currentLineChild->getLayout().computedFlexBasis,
mainAxisownerSize)
Expand Down Expand Up @@ -982,8 +991,9 @@ static void justifyMainAxis(
if (sizingModeMainDim == SizingMode::FitContent &&
flexLine.layout.remainingFreeSpace > 0) {
if (style.minDimension(dimension(mainAxis)).isDefined() &&
style.minDimension(dimension(mainAxis))
.resolve(mainAxisownerSize)
style
.resolvedMinDimension(
direction, dimension(mainAxis), mainAxisownerSize)
.isDefined()) {
// This condition makes sure that if the size of main dimension(after
// considering child nodes main dim, leading and trailing padding etc)
Expand All @@ -992,9 +1002,11 @@ static void justifyMainAxis(

// `minAvailableMainDim` denotes minimum available space in which child
// can be laid out, it will exclude space consumed by padding and border.
const float minAvailableMainDim = style.minDimension(dimension(mainAxis))
.resolve(mainAxisownerSize)
.unwrap() -
const float minAvailableMainDim =
style
.resolvedMinDimension(
direction, dimension(mainAxis), mainAxisownerSize)
.unwrap() -
leadingPaddingAndBorderMain - trailingPaddingAndBorderMain;
const float occupiedSpaceByChildNodes =
availableInnerMainDim - flexLine.layout.remainingFreeSpace;
Expand Down Expand Up @@ -1387,12 +1399,14 @@ static void calculateLayoutImpl(

float availableInnerWidth = calculateAvailableInnerDimension(
node,
direction,
Dimension::Width,
availableWidth - marginAxisRow,
paddingAndBorderAxisRow,
ownerWidth);
float availableInnerHeight = calculateAvailableInnerDimension(
node,
direction,
Dimension::Height,
availableHeight - marginAxisColumn,
paddingAndBorderAxisColumn,
Expand Down Expand Up @@ -1480,16 +1494,20 @@ static void calculateLayoutImpl(
if (sizingModeMainDim != SizingMode::StretchFit) {
const auto& style = node->style();
const float minInnerWidth =
style.minDimension(Dimension::Width).resolve(ownerWidth).unwrap() -
style.resolvedMinDimension(direction, Dimension::Width, ownerWidth)
.unwrap() -
paddingAndBorderAxisRow;
const float maxInnerWidth =
style.maxDimension(Dimension::Width).resolve(ownerWidth).unwrap() -
style.resolvedMaxDimension(direction, Dimension::Width, ownerWidth)
.unwrap() -
paddingAndBorderAxisRow;
const float minInnerHeight =
style.minDimension(Dimension::Height).resolve(ownerHeight).unwrap() -
style.resolvedMinDimension(direction, Dimension::Height, ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn;
const float maxInnerHeight =
style.maxDimension(Dimension::Height).resolve(ownerHeight).unwrap() -
style.resolvedMaxDimension(direction, Dimension::Height, ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn;

const float minInnerMainDim =
Expand Down Expand Up @@ -1688,13 +1706,15 @@ static void calculateLayoutImpl(
SizingMode childCrossSizingMode = SizingMode::StretchFit;
constrainMaxSizeForMode(
child,
direction,
mainAxis,
availableInnerMainDim,
availableInnerWidth,
&childMainSizingMode,
&childMainSize);
constrainMaxSizeForMode(
child,
direction,
crossAxis,
availableInnerCrossDim,
availableInnerWidth,
Expand Down Expand Up @@ -1781,8 +1801,8 @@ static void calculateLayoutImpl(
const float unclampedCrossDim = sizingModeCrossDim == SizingMode::StretchFit
? availableInnerCrossDim + paddingAndBorderAxisCross
: node->hasDefiniteLength(dimension(crossAxis), crossAxisownerSize)
? node->getProcessedDimension(dimension(crossAxis))
.resolve(crossAxisownerSize)
? node->getResolvedDimension(
direction, dimension(crossAxis), crossAxisownerSize)
.unwrap()
: totalLineCrossDim + paddingAndBorderAxisCross;

Expand Down Expand Up @@ -2035,6 +2055,7 @@ static void calculateLayoutImpl(
availableInnerMainDim + paddingAndBorderAxisMain,
boundAxisWithinMinAndMax(
node,
direction,
mainAxis,
FloatOptional{maxLineMainDim},
mainAxisownerSize)
Expand Down Expand Up @@ -2067,6 +2088,7 @@ static void calculateLayoutImpl(
availableInnerCrossDim + paddingAndBorderAxisCross,
boundAxisWithinMinAndMax(
node,
direction,
crossAxis,
FloatOptional{
totalLineCrossDim + paddingAndBorderAxisCross},
Expand Down Expand Up @@ -2355,20 +2377,21 @@ void calculateLayout(
// the input parameters don't change.
gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed);
node->processDimensions();
const Direction direction = node->resolveDirection(ownerDirection);
float width = YGUndefined;
SizingMode widthSizingMode = SizingMode::MaxContent;
const auto& style = node->style();
if (node->hasDefiniteLength(Dimension::Width, ownerWidth)) {
width =
(node->getProcessedDimension(Dimension::Width)
.resolve(ownerWidth)
(node->getResolvedDimension(
direction, dimension(FlexDirection::Row), ownerWidth)
.unwrap() +
node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth));
widthSizingMode = SizingMode::StretchFit;
} else if (style.maxDimension(Dimension::Width)
.resolve(ownerWidth)
} else if (style.resolvedMaxDimension(direction, Dimension::Width, ownerWidth)
.isDefined()) {
width = style.maxDimension(Dimension::Width).resolve(ownerWidth).unwrap();
width = style.resolvedMaxDimension(direction, Dimension::Width, ownerWidth)
.unwrap();
widthSizingMode = SizingMode::FitContent;
} else {
width = ownerWidth;
Expand All @@ -2380,16 +2403,18 @@ void calculateLayout(
SizingMode heightSizingMode = SizingMode::MaxContent;
if (node->hasDefiniteLength(Dimension::Height, ownerHeight)) {
height =
(node->getProcessedDimension(Dimension::Height)
.resolve(ownerHeight)
(node->getResolvedDimension(
direction, dimension(FlexDirection::Column), ownerHeight)
.unwrap() +
node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth));
heightSizingMode = SizingMode::StretchFit;
} else if (style.maxDimension(Dimension::Height)
.resolve(ownerHeight)
} else if (style
.resolvedMaxDimension(
direction, Dimension::Height, ownerHeight)
.isDefined()) {
height =
style.maxDimension(Dimension::Height).resolve(ownerHeight).unwrap();
style.resolvedMaxDimension(direction, Dimension::Height, ownerHeight)
.unwrap();
heightSizingMode = SizingMode::FitContent;
} else {
height = ownerHeight;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ FlexLine calculateFlexLine(
size_t firstElementInLineIndex = startOfLineIndex;

float sizeConsumedIncludingMinConstraint = 0;
const FlexDirection mainAxis = resolveDirection(
node->style().flexDirection(), node->resolveDirection(ownerDirection));
const Direction direction = node->resolveDirection(ownerDirection);
const FlexDirection mainAxis =
resolveDirection(node->style().flexDirection(), direction);
const bool isNodeFlexWrap = node->style().flexWrap() != Wrap::NoWrap;
const float gap =
node->style().computeGapForAxis(mainAxis, availableInnerMainDim);
Expand Down Expand Up @@ -67,6 +68,7 @@ FlexLine calculateFlexLine(
const float flexBasisWithMinAndMaxConstraints =
boundAxisWithinMinAndMax(
child,
direction,
mainAxis,
child->getLayout().computedFlexBasis,
mainAxisownerSize)
Expand Down
Loading

0 comments on commit db9a35d

Please sign in to comment.