More niche box sizing tests #1712

Closed
joevilches wants to merge 4 commits from export-D63423302 into main
12 changed files with 3207 additions and 145 deletions

View File

@@ -1,36 +1,89 @@
<div data-disabled="true" id="box_sizing_content_box" <div id="box_sizing_content_box_simple"
style="width: 100px; height: 100px; padding: 5px; border-width: 10px; box-sizing: content-box"> style="width: 100px; height: 100px; padding: 5px; border-width: 10px; box-sizing: content-box">
</div> </div>
<div id="box_sizing_border_box" <div id="box_sizing_border_box_simple"
style="width: 100px; height: 100px; padding: 5px; border-width: 10px; box-sizing: border-box"> style="width: 100px; height: 100px; padding: 5px; border-width: 10px; box-sizing: border-box">
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_padding_only" <div id="box_sizing_content_box_percent" style="width: 100px; height: 100px;">
<div style="width: 50%; height: 25%; padding: 4px; border-width: 16px; box-sizing: content-box">
</div>
</div>
<div id="box_sizing_border_box_percent" style="width: 100px; height: 100px;">
<div style="width: 50%; height: 25%; padding: 4px; border-width: 16px; box-sizing: border-box">
</div>
</div>
<div id="box_sizing_content_box_absolute" style="width: 100px; height: 100px;">
<div style="width: 50; height: 25%; padding: 12px; border-width: 8px; box-sizing: content-box; position: absolute;">
</div>
</div>
<div id="box_sizing_border_box_absolute" style="width: 100px; height: 100px;">
<div style="width: 50; height: 25%; padding: 12px; border-width: 8px; box-sizing: border-box; position: absolute;">
</div>
</div>
<div id="box_sizing_content_box_comtaining_block"
style="width: 100px; height: 100px; padding: 12px; border-width: 8px; box-sizing: content-box; ">
<div style="width: 75; height: 75; position: static;">
<div style="width: 50px; height: 25%; position: absolute;">
</div>
</div>
</div>
<div id="box_sizing_border_box_comtaining_block"
style="width: 100px; height: 100px; padding: 12px; border-width: 8px; box-sizing: border-box; ">
<div style="width: 75; height: 75; position: static;">
<div style="width: 50px; height: 25%; position: absolute;">
</div>
</div>
</div>
<div id="box_sizing_content_box_padding_only"
style="width: 100px; height: 100px; padding: 5px; box-sizing: content-box"> style="width: 100px; height: 100px; padding: 5px; box-sizing: content-box">
</div> </div>
<div id="box_sizing_border_box_padding_only" <div id="box_sizing_content_box_padding_only_percent" style="width: 100px; height: 100px;">
style="width: 100px; height: 100px; padding: 5px; box-sizing: border-box"> <div style="width: 50%; height: 75; padding: 10%; box-sizing: content-box">
</div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_border_only" <div id="box_sizing_border_box_padding_only" style="width: 100px; height: 100px; padding: 5px; box-sizing: border-box">
</div>
<div id="box_sizing_border_box_padding_only_percent" style="width: 100px; height: 100px;">
<div style="width: 50%; height: 75; padding: 10%; box-sizing: border-box">
</div>
</div>
<div id="box_sizing_content_box_border_only"
style="width: 100px; height: 100px; border-width: 10px; box-sizing: content-box"> style="width: 100px; height: 100px; border-width: 10px; box-sizing: content-box">
</div> </div>
<div id="box_sizing_content_box_border_only_percent" style="width: 100px; height: 100px;">
<div style="width: 50%; height: 75; border-width: 10%; box-sizing: content-box">
</div>
</div>
<div id="box_sizing_border_box_border_only" <div id="box_sizing_border_box_border_only"
style="width: 100px; height: 100px; border-width: 10px; box-sizing: border-box"> style="width: 100px; height: 100px; border-width: 10px; box-sizing: border-box">
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_no_padding_no_border" <div id="box_sizing_border_box_border_only_percent" style="width: 100px; height: 100px;">
style="width: 100px; height: 100px; box-sizing: content-box"> <div style="width: 50%; height: 75; border-width: 10%; box-sizing: border-box">
</div>
</div> </div>
<div id="box_sizing_border_box_no_padding_no_border" <div id="box_sizing_content_box_no_padding_no_border" style="width: 100px; height: 100px; box-sizing: content-box">
style="width: 100px; height: 100px; box-sizing: border-box">
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_children" <div id="box_sizing_border_box_no_padding_no_border" style="width: 100px; height: 100px; box-sizing: border-box">
</div>
<div id="box_sizing_content_box_children"
style="width: 100px; height: 100px; padding: 5px; border-width: 10px; box-sizing: content-box"> style="width: 100px; height: 100px; padding: 5px; border-width: 10px; box-sizing: content-box">
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
@@ -46,7 +99,7 @@
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_siblings" style="width: 100px; height: 100px;"> <div id="box_sizing_content_box_siblings" style="width: 100px; height: 100px;">
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
<div style="width: 25px; height: 25px; box-sizing: content-box; padding: 10px; border-width: 10px"></div> <div style="width: 25px; height: 25px; box-sizing: content-box; padding: 10px; border-width: 10px"></div>
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
@@ -60,7 +113,7 @@
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_max_width" style="width: 100px; height: 100px;"> <div id="box_sizing_content_box_max_width" style="width: 100px; height: 100px;">
<div style="max-width: 50px; height: 25px; box-sizing: content-box; padding: 5px; border-width: 15px"></div> <div style="max-width: 50px; height: 25px; box-sizing: content-box; padding: 5px; border-width: 15px"></div>
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
@@ -70,7 +123,7 @@
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_max_height" style="width: 100px; height: 100px;"> <div id="box_sizing_content_box_max_height" style="width: 100px; height: 100px;">
<div style="width: 50px; max-height: 50px; box-sizing: content-box; padding: 5px; border-width: 15px"></div> <div style="width: 50px; max-height: 50px; box-sizing: content-box; padding: 5px; border-width: 15px"></div>
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
@@ -80,7 +133,7 @@
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_min_width" style="width: 100px; height: 100px;"> <div id="box_sizing_content_box_min_width" style="width: 100px; height: 100px;">
<div style="min-width: 50px; height: 25px; box-sizing: content-box; padding: 5px; border-width: 15px"></div> <div style="min-width: 50px; height: 25px; box-sizing: content-box; padding: 5px; border-width: 15px"></div>
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
@@ -90,7 +143,7 @@
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_min_height" style="width: 100px; height: 100px;"> <div id="box_sizing_content_box_min_height" style="width: 100px; height: 100px;">
<div style="width: 50px; min-height: 50px; box-sizing: content-box; padding: 5px; border-width: 15px"></div> <div style="width: 50px; min-height: 50px; box-sizing: content-box; padding: 5px; border-width: 15px"></div>
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
@@ -100,7 +153,7 @@
<div style="width: 25px; height: 25px"></div> <div style="width: 25px; height: 25px"></div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_no_height_no_width" style="width: 100px; height: 100px;"> <div id="box_sizing_content_box_no_height_no_width" style="width: 100px; height: 100px;">
<div style="box-sizing: content-box; padding: 2px; border-width: 7px"> <div style="box-sizing: content-box; padding: 2px; border-width: 7px">
</div> </div>
</div> </div>
@@ -110,7 +163,7 @@
</div> </div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_nested" <div id="box_sizing_content_box_nested"
style="width: 100px; height: 100px; box-sizing: content-box; padding: 15px; border-width: 3px;"> style="width: 100px; height: 100px; box-sizing: content-box; padding: 15px; border-width: 3px;">
<div style="width: 20px; height: 20px; box-sizing: content-box; padding: 2px; border-width: 7px"> <div style="width: 20px; height: 20px; box-sizing: content-box; padding: 2px; border-width: 7px">
<div style="width: 10px; height: 5px; box-sizing: content-box; padding: 1px; border-width: 2px"></div> <div style="width: 10px; height: 5px; box-sizing: content-box; padding: 1px; border-width: 2px"></div>
@@ -124,7 +177,7 @@
</div> </div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_nested_alternating" <div id="box_sizing_content_box_nested_alternating"
style="width: 100px; height: 100px; box-sizing: content-box; padding: 3px; border-width: 2px;"> style="width: 100px; height: 100px; box-sizing: content-box; padding: 3px; border-width: 2px;">
<div style="width: 40px; height: 40px; box-sizing: border-box; padding: 8px; border-width: 2px"> <div style="width: 40px; height: 40px; box-sizing: border-box; padding: 8px; border-width: 2px">
<div style="width: 20px; height: 25px; box-sizing: content-box; padding: 3px; border-width: 6px"> <div style="width: 20px; height: 25px; box-sizing: content-box; padding: 3px; border-width: 6px">
@@ -134,7 +187,7 @@
</div> </div>
</div> </div>
<div data-disabled="true" id="box_sizing_border_box_nested_alternating" <div id="box_sizing_border_box_nested_alternating"
style="width: 100px; height: 100px; box-sizing: border-box; padding: 3px; border-width: 2px;"> style="width: 100px; height: 100px; box-sizing: border-box; padding: 3px; border-width: 2px;">
<div style="width: 40px; height: 40px; box-sizing: content-box; padding: 8px; border-width: 2px"> <div style="width: 40px; height: 40px; box-sizing: content-box; padding: 8px; border-width: 2px">
<div style="width: 20px; height: 25px; box-sizing: border-box; padding: 3px; border-width: 6px"> <div style="width: 20px; height: 25px; box-sizing: border-box; padding: 3px; border-width: 6px">
@@ -143,3 +196,55 @@
</div> </div>
</div> </div>
</div> </div>
<div data-disabled="true" id="box_sizing_content_box_flex_basis_row" style="width: 100px; height: 100px; flex-direction: row;">
<div style="flex-basis: 50px; height: 25px; padding: 5px; border-width: 10px; box-sizing: content-box">
</div>
</div>
<div id="box_sizing_border_box_flex_basis_row" style="width: 100px; height: 100px; flex-direction: row;">
<div style="flex-basis: 50px; height: 25px; padding: 5px; border-width: 10px; box-sizing: border-box">
</div>
</div>
<div data-disabled="true" id="box_sizing_content_box_flex_basis_column" style="width: 100px; height: 100px; flex-direction: column;">
<div style="flex-basis: 50px; height: 25px; padding: 5px; border-width: 10px; box-sizing: content-box">
</div>
</div>
<div id="box_sizing_border_box_flex_basis_column" style="width: 100px; height: 100px; flex-direction: column;">
<div style="flex-basis: 50px; height: 25px; padding: 5px; border-width: 10px; box-sizing: border-box">
</div>
</div>
<div id="box_sizing_content_box_padding_start"
style="width: 100px; height: 100px; padding-start: 5px; box-sizing: content-box">
</div>
<div id="box_sizing_border_box_padding_start"
style="width: 100px; height: 100px; padding-start: 5px; box-sizing: border-box">
</div>
<div id="box_sizing_content_box_padding_end"
style="width: 100px; height: 100px; padding-end: 5px; box-sizing: content-box">
</div>
<div id="box_sizing_border_box_padding_end"
style="width: 100px; height: 100px; padding-end: 5px; box-sizing: border-box">
</div>
<div id="box_sizing_content_box_border_start"
style="width: 100px; height: 100px; border-start-width: 5px; box-sizing: content-box">
</div>
<div id="box_sizing_border_box_border_start"
style="width: 100px; height: 100px; border-start-width: 5px; box-sizing: border-box">
</div>
<div id="box_sizing_content_box_border_end"
style="width: 100px; height: 100px; border-end-width: 5px; box-sizing: content-box">
</div>
<div id="box_sizing_border_box_border_end"
style="width: 100px; height: 100px; border-end-width: 5px; box-sizing: border-box">
</div>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -899,3 +899,81 @@ TEST(YogaTest, percent_padding_and_percent_margin_with_measure_func) {
YGConfigFree(config); YGConfigFree(config);
} }
static YGSize _measure_half_width_height(
YGNodeConstRef node,
float width,
YGMeasureMode /*widthMode*/,
float height,
YGMeasureMode /*heightMode*/) {
int* measureCount = (int*)YGNodeGetContext(node);
if (measureCount != nullptr) {
(*measureCount)++;
}
return YGSize{0.5f * width, 0.5f * height};
}
TEST(YogaTest, measure_content_box) {
YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 200);
YGNodeStyleSetBoxSizing(root, YGBoxSizingContentBox);
YGNodeStyleSetPadding(root, YGEdgeAll, 5);
YGNodeStyleSetBorder(root, YGEdgeAll, 10);
int measureCount = 0;
YGNodeRef root_child0 = YGNodeNew();
YGNodeSetContext(root_child0, &measureCount);
YGNodeSetMeasureFunc(root_child0, _measure_half_width_height);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(1, measureCount);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_EQ(130, YGNodeLayoutGetWidth(root));
ASSERT_EQ(230, YGNodeLayoutGetHeight(root));
ASSERT_EQ(15, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(15, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(100, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}
TEST(YogaTest, measure_border_box) {
YGNodeRef root = YGNodeNew();
YGNodeStyleSetWidth(root, 100);
YGNodeStyleSetHeight(root, 200);
YGNodeStyleSetBoxSizing(root, YGBoxSizingBorderBox);
YGNodeStyleSetPadding(root, YGEdgeAll, 5);
YGNodeStyleSetBorder(root, YGEdgeAll, 10);
int measureCount = 0;
YGNodeRef root_child0 = YGNodeNew();
YGNodeSetContext(root_child0, &measureCount);
YGNodeSetMeasureFunc(root_child0, _measure_half_width_height);
YGNodeInsertChild(root, root_child0, 0);
YGNodeCalculateLayout(root, YGUndefined, YGUndefined, YGDirectionLTR);
ASSERT_EQ(1, measureCount);
ASSERT_EQ(0, YGNodeLayoutGetLeft(root));
ASSERT_EQ(0, YGNodeLayoutGetTop(root));
ASSERT_EQ(100, YGNodeLayoutGetWidth(root));
ASSERT_EQ(200, YGNodeLayoutGetHeight(root));
ASSERT_EQ(15, YGNodeLayoutGetLeft(root_child0));
ASSERT_EQ(15, YGNodeLayoutGetTop(root_child0));
ASSERT_EQ(70, YGNodeLayoutGetWidth(root_child0));
ASSERT_EQ(85, YGNodeLayoutGetHeight(root_child0));
YGNodeFreeRecursive(root);
}

File diff suppressed because it is too large Load Diff

View File

@@ -324,8 +324,9 @@ void layoutAbsoluteChild(
FlexDirection::Column, containingBlockWidth); FlexDirection::Column, containingBlockWidth);
if (child->hasDefiniteLength(Dimension::Width, containingBlockWidth)) { if (child->hasDefiniteLength(Dimension::Width, containingBlockWidth)) {
childWidth = child->getResolvedDimension(Dimension::Width) childWidth = child
.resolve(containingBlockWidth) ->getResolvedDimension(
direction, Dimension::Width, containingBlockWidth)
.unwrap() + .unwrap() +
marginRow; marginRow;
} else { } else {
@@ -359,8 +360,9 @@ void layoutAbsoluteChild(
} }
if (child->hasDefiniteLength(Dimension::Height, containingBlockHeight)) { if (child->hasDefiniteLength(Dimension::Height, containingBlockHeight)) {
childHeight = child->getResolvedDimension(Dimension::Height) childHeight = child
.resolve(containingBlockHeight) ->getResolvedDimension(
direction, Dimension::Height, containingBlockHeight)
.unwrap() + .unwrap() +
marginColumn; marginColumn;
} else { } else {

View File

@@ -29,6 +29,7 @@ inline float paddingAndBorderForAxis(
inline FloatOptional boundAxisWithinMinAndMax( inline FloatOptional boundAxisWithinMinAndMax(
const yoga::Node* const node, const yoga::Node* const node,
const Direction direction,
const FlexDirection axis, const FlexDirection axis,
const FloatOptional value, const FloatOptional value,
const float axisSize) { const float axisSize) {
@@ -36,11 +37,15 @@ inline FloatOptional boundAxisWithinMinAndMax(
FloatOptional max; FloatOptional max;
if (isColumn(axis)) { if (isColumn(axis)) {
min = node->style().minDimension(Dimension::Height).resolve(axisSize); min = node->style().resolvedMinDimension(
max = node->style().maxDimension(Dimension::Height).resolve(axisSize); direction, Dimension::Height, axisSize);
max = node->style().resolvedMaxDimension(
direction, Dimension::Height, axisSize);
} else if (isRow(axis)) { } else if (isRow(axis)) {
min = node->style().minDimension(Dimension::Width).resolve(axisSize); min = node->style().resolvedMinDimension(
max = node->style().maxDimension(Dimension::Width).resolve(axisSize); direction, Dimension::Width, axisSize);
max = node->style().resolvedMaxDimension(
direction, Dimension::Width, axisSize);
} }
if (max >= FloatOptional{0} && value > max) { if (max >= FloatOptional{0} && value > max) {
@@ -64,7 +69,8 @@ inline float boundAxis(
const float axisSize, const float axisSize,
const float widthSize) { const float widthSize) {
return yoga::maxOrDefined( return yoga::maxOrDefined(
boundAxisWithinMinAndMax(node, axis, FloatOptional{value}, axisSize) boundAxisWithinMinAndMax(
node, direction, axis, FloatOptional{value}, axisSize)
.unwrap(), .unwrap(),
paddingAndBorderForAxis(node, axis, direction, widthSize)); paddingAndBorderForAxis(node, axis, direction, widthSize));
} }

View File

@@ -38,13 +38,14 @@ std::atomic<uint32_t> gCurrentGenerationCount(0);
static void constrainMaxSizeForMode( static void constrainMaxSizeForMode(
const yoga::Node* node, const yoga::Node* node,
Direction direction,
FlexDirection axis, FlexDirection axis,
float ownerAxisSize, float ownerAxisSize,
float ownerWidth, float ownerWidth,
/*in_out*/ SizingMode* mode, /*in_out*/ SizingMode* mode,
/*in_out*/ float* size) { /*in_out*/ float* size) {
const FloatOptional maxSize = const FloatOptional maxSize = node->style().resolvedMaxDimension(
node->style().maxDimension(dimension(axis)).resolve(ownerAxisSize) + direction, dimension(axis), ownerAxisSize) +
FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth)); FloatOptional(node->style().computeMarginForAxis(axis, ownerWidth));
switch (*mode) { switch (*mode) {
case SizingMode::StretchFit: case SizingMode::StretchFit:
@@ -110,7 +111,7 @@ static void computeFlexBasisForChild(
child, FlexDirection::Row, direction, ownerWidth)); child, FlexDirection::Row, direction, ownerWidth));
child->setLayoutComputedFlexBasis(yoga::maxOrDefined( child->setLayoutComputedFlexBasis(yoga::maxOrDefined(
child->getResolvedDimension(Dimension::Width).resolve(ownerWidth), child->getResolvedDimension(direction, Dimension::Width, ownerWidth),
paddingAndBorder)); paddingAndBorder));
} else if (!isMainAxisRow && isColumnStyleDimDefined) { } else if (!isMainAxisRow && isColumnStyleDimDefined) {
// The height is definite, so use that as the flex basis. // The height is definite, so use that as the flex basis.
@@ -118,7 +119,7 @@ static void computeFlexBasisForChild(
FloatOptional(paddingAndBorderForAxis( FloatOptional(paddingAndBorderForAxis(
child, FlexDirection::Column, direction, ownerWidth)); child, FlexDirection::Column, direction, ownerWidth));
child->setLayoutComputedFlexBasis(yoga::maxOrDefined( child->setLayoutComputedFlexBasis(yoga::maxOrDefined(
child->getResolvedDimension(Dimension::Height).resolve(ownerHeight), child->getResolvedDimension(direction, Dimension::Height, ownerHeight),
paddingAndBorder)); paddingAndBorder));
} else { } else {
// Compute the flex basis and hypothetical main size (i.e. the clamped flex // Compute the flex basis and hypothetical main size (i.e. the clamped flex
@@ -132,15 +133,15 @@ static void computeFlexBasisForChild(
child->style().computeMarginForAxis(FlexDirection::Column, ownerWidth); child->style().computeMarginForAxis(FlexDirection::Column, ownerWidth);
if (isRowStyleDimDefined) { if (isRowStyleDimDefined) {
childWidth = child->getResolvedDimension(Dimension::Width) childWidth =
.resolve(ownerWidth) child->getResolvedDimension(direction, Dimension::Width, ownerWidth)
.unwrap() + .unwrap() +
marginRow; marginRow;
childWidthSizingMode = SizingMode::StretchFit; childWidthSizingMode = SizingMode::StretchFit;
} }
if (isColumnStyleDimDefined) { if (isColumnStyleDimDefined) {
childHeight = child->getResolvedDimension(Dimension::Height) childHeight =
.resolve(ownerHeight) child->getResolvedDimension(direction, Dimension::Height, ownerHeight)
.unwrap() + .unwrap() +
marginColumn; marginColumn;
childHeightSizingMode = SizingMode::StretchFit; childHeightSizingMode = SizingMode::StretchFit;
@@ -216,6 +217,7 @@ static void computeFlexBasisForChild(
constrainMaxSizeForMode( constrainMaxSizeForMode(
child, child,
direction,
FlexDirection::Row, FlexDirection::Row,
ownerWidth, ownerWidth,
ownerWidth, ownerWidth,
@@ -223,6 +225,7 @@ static void computeFlexBasisForChild(
&childWidth); &childWidth);
constrainMaxSizeForMode( constrainMaxSizeForMode(
child, child,
direction,
FlexDirection::Column, FlexDirection::Column,
ownerHeight, ownerHeight,
ownerWidth, ownerWidth,
@@ -469,6 +472,7 @@ static void zeroOutLayoutRecursively(yoga::Node* const node) {
static float calculateAvailableInnerDimension( static float calculateAvailableInnerDimension(
const yoga::Node* const node, const yoga::Node* const node,
const Direction direction,
const Dimension dimension, const Dimension dimension,
const float availableDim, const float availableDim,
const float paddingAndBorder, const float paddingAndBorder,
@@ -480,13 +484,13 @@ static float calculateAvailableInnerDimension(
// We want to make sure our available height does not violate min and max // We want to make sure our available height does not violate min and max
// constraints // constraints
const FloatOptional minDimensionOptional = const FloatOptional minDimensionOptional =
node->style().minDimension(dimension).resolve(ownerDim); node->style().resolvedMinDimension(direction, dimension, ownerDim);
const float minInnerDim = minDimensionOptional.isUndefined() const float minInnerDim = minDimensionOptional.isUndefined()
? 0.0f ? 0.0f
: minDimensionOptional.unwrap() - paddingAndBorder; : minDimensionOptional.unwrap() - paddingAndBorder;
const FloatOptional maxDimensionOptional = const FloatOptional maxDimensionOptional =
node->style().maxDimension(dimension).resolve(ownerDim); node->style().resolvedMaxDimension(direction, dimension, ownerDim);
const float maxInnerDim = maxDimensionOptional.isUndefined() const float maxInnerDim = maxDimensionOptional.isUndefined()
? FLT_MAX ? FLT_MAX
@@ -536,7 +540,7 @@ static float computeFlexBasisForChildren(
} }
for (auto child : children) { for (auto child : children) {
child->resolveDimension(); child->processDimensions();
if (child->style().display() == Display::None) { if (child->style().display() == Display::None) {
zeroOutLayoutRecursively(child); zeroOutLayoutRecursively(child);
child->setHasNewLayout(true); child->setHasNewLayout(true);
@@ -611,6 +615,7 @@ static float distributeFreeSpaceSecondPass(
for (auto currentLineChild : flexLine.itemsInFlow) { for (auto currentLineChild : flexLine.itemsInFlow) {
childFlexBasis = boundAxisWithinMinAndMax( childFlexBasis = boundAxisWithinMinAndMax(
currentLineChild, currentLineChild,
direction,
mainAxis, mainAxis,
currentLineChild->getLayout().computedFlexBasis, currentLineChild->getLayout().computedFlexBasis,
mainAxisownerSize) mainAxisownerSize)
@@ -709,13 +714,14 @@ static float distributeFreeSpaceSecondPass(
: SizingMode::FitContent; : SizingMode::FitContent;
} else { } else {
childCrossSize = childCrossSize =
currentLineChild->getResolvedDimension(dimension(crossAxis)) currentLineChild
.resolve(availableInnerCrossDim) ->getResolvedDimension(
direction, dimension(crossAxis), availableInnerCrossDim)
.unwrap() + .unwrap() +
marginCross; marginCross;
const bool isLoosePercentageMeasurement = const bool isLoosePercentageMeasurement =
currentLineChild->getResolvedDimension(dimension(crossAxis)).unit() == currentLineChild->getProcessedDimension(dimension(crossAxis))
Unit::Percent && .unit() == Unit::Percent &&
sizingModeCrossDim != SizingMode::StretchFit; sizingModeCrossDim != SizingMode::StretchFit;
childCrossSizingMode = childCrossSizingMode =
yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement yoga::isUndefined(childCrossSize) || isLoosePercentageMeasurement
@@ -725,6 +731,7 @@ static float distributeFreeSpaceSecondPass(
constrainMaxSizeForMode( constrainMaxSizeForMode(
currentLineChild, currentLineChild,
direction,
mainAxis, mainAxis,
availableInnerMainDim, availableInnerMainDim,
availableInnerWidth, availableInnerWidth,
@@ -732,6 +739,7 @@ static float distributeFreeSpaceSecondPass(
&childMainSize); &childMainSize);
constrainMaxSizeForMode( constrainMaxSizeForMode(
currentLineChild, currentLineChild,
direction,
crossAxis, crossAxis,
availableInnerCrossDim, availableInnerCrossDim,
availableInnerWidth, availableInnerWidth,
@@ -812,6 +820,7 @@ static void distributeFreeSpaceFirstPass(
for (auto currentLineChild : flexLine.itemsInFlow) { for (auto currentLineChild : flexLine.itemsInFlow) {
float childFlexBasis = boundAxisWithinMinAndMax( float childFlexBasis = boundAxisWithinMinAndMax(
currentLineChild, currentLineChild,
direction,
mainAxis, mainAxis,
currentLineChild->getLayout().computedFlexBasis, currentLineChild->getLayout().computedFlexBasis,
mainAxisownerSize) mainAxisownerSize)
@@ -982,8 +991,9 @@ static void justifyMainAxis(
if (sizingModeMainDim == SizingMode::FitContent && if (sizingModeMainDim == SizingMode::FitContent &&
flexLine.layout.remainingFreeSpace > 0) { flexLine.layout.remainingFreeSpace > 0) {
if (style.minDimension(dimension(mainAxis)).isDefined() && if (style.minDimension(dimension(mainAxis)).isDefined() &&
style.minDimension(dimension(mainAxis)) style
.resolve(mainAxisownerSize) .resolvedMinDimension(
direction, dimension(mainAxis), mainAxisownerSize)
.isDefined()) { .isDefined()) {
// This condition makes sure that if the size of main dimension(after // This condition makes sure that if the size of main dimension(after
// considering child nodes main dim, leading and trailing padding etc) // considering child nodes main dim, leading and trailing padding etc)
@@ -992,8 +1002,10 @@ static void justifyMainAxis(
// `minAvailableMainDim` denotes minimum available space in which child // `minAvailableMainDim` denotes minimum available space in which child
// can be laid out, it will exclude space consumed by padding and border. // can be laid out, it will exclude space consumed by padding and border.
const float minAvailableMainDim = style.minDimension(dimension(mainAxis)) const float minAvailableMainDim =
.resolve(mainAxisownerSize) style
.resolvedMinDimension(
direction, dimension(mainAxis), mainAxisownerSize)
.unwrap() - .unwrap() -
leadingPaddingAndBorderMain - trailingPaddingAndBorderMain; leadingPaddingAndBorderMain - trailingPaddingAndBorderMain;
const float occupiedSpaceByChildNodes = const float occupiedSpaceByChildNodes =
@@ -1387,12 +1399,14 @@ static void calculateLayoutImpl(
float availableInnerWidth = calculateAvailableInnerDimension( float availableInnerWidth = calculateAvailableInnerDimension(
node, node,
direction,
Dimension::Width, Dimension::Width,
availableWidth - marginAxisRow, availableWidth - marginAxisRow,
paddingAndBorderAxisRow, paddingAndBorderAxisRow,
ownerWidth); ownerWidth);
float availableInnerHeight = calculateAvailableInnerDimension( float availableInnerHeight = calculateAvailableInnerDimension(
node, node,
direction,
Dimension::Height, Dimension::Height,
availableHeight - marginAxisColumn, availableHeight - marginAxisColumn,
paddingAndBorderAxisColumn, paddingAndBorderAxisColumn,
@@ -1480,16 +1494,20 @@ static void calculateLayoutImpl(
if (sizingModeMainDim != SizingMode::StretchFit) { if (sizingModeMainDim != SizingMode::StretchFit) {
const auto& style = node->style(); const auto& style = node->style();
const float minInnerWidth = const float minInnerWidth =
style.minDimension(Dimension::Width).resolve(ownerWidth).unwrap() - style.resolvedMinDimension(direction, Dimension::Width, ownerWidth)
.unwrap() -
paddingAndBorderAxisRow; paddingAndBorderAxisRow;
const float maxInnerWidth = const float maxInnerWidth =
style.maxDimension(Dimension::Width).resolve(ownerWidth).unwrap() - style.resolvedMaxDimension(direction, Dimension::Width, ownerWidth)
.unwrap() -
paddingAndBorderAxisRow; paddingAndBorderAxisRow;
const float minInnerHeight = const float minInnerHeight =
style.minDimension(Dimension::Height).resolve(ownerHeight).unwrap() - style.resolvedMinDimension(direction, Dimension::Height, ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn; paddingAndBorderAxisColumn;
const float maxInnerHeight = const float maxInnerHeight =
style.maxDimension(Dimension::Height).resolve(ownerHeight).unwrap() - style.resolvedMaxDimension(direction, Dimension::Height, ownerHeight)
.unwrap() -
paddingAndBorderAxisColumn; paddingAndBorderAxisColumn;
const float minInnerMainDim = const float minInnerMainDim =
@@ -1688,6 +1706,7 @@ static void calculateLayoutImpl(
SizingMode childCrossSizingMode = SizingMode::StretchFit; SizingMode childCrossSizingMode = SizingMode::StretchFit;
constrainMaxSizeForMode( constrainMaxSizeForMode(
child, child,
direction,
mainAxis, mainAxis,
availableInnerMainDim, availableInnerMainDim,
availableInnerWidth, availableInnerWidth,
@@ -1695,6 +1714,7 @@ static void calculateLayoutImpl(
&childMainSize); &childMainSize);
constrainMaxSizeForMode( constrainMaxSizeForMode(
child, child,
direction,
crossAxis, crossAxis,
availableInnerCrossDim, availableInnerCrossDim,
availableInnerWidth, availableInnerWidth,
@@ -1781,8 +1801,8 @@ static void calculateLayoutImpl(
const float unclampedCrossDim = sizingModeCrossDim == SizingMode::StretchFit const float unclampedCrossDim = sizingModeCrossDim == SizingMode::StretchFit
? availableInnerCrossDim + paddingAndBorderAxisCross ? availableInnerCrossDim + paddingAndBorderAxisCross
: node->hasDefiniteLength(dimension(crossAxis), crossAxisownerSize) : node->hasDefiniteLength(dimension(crossAxis), crossAxisownerSize)
? node->getResolvedDimension(dimension(crossAxis)) ? node->getResolvedDimension(
.resolve(crossAxisownerSize) direction, dimension(crossAxis), crossAxisownerSize)
.unwrap() .unwrap()
: totalLineCrossDim + paddingAndBorderAxisCross; : totalLineCrossDim + paddingAndBorderAxisCross;
@@ -2035,6 +2055,7 @@ static void calculateLayoutImpl(
availableInnerMainDim + paddingAndBorderAxisMain, availableInnerMainDim + paddingAndBorderAxisMain,
boundAxisWithinMinAndMax( boundAxisWithinMinAndMax(
node, node,
direction,
mainAxis, mainAxis,
FloatOptional{maxLineMainDim}, FloatOptional{maxLineMainDim},
mainAxisownerSize) mainAxisownerSize)
@@ -2067,6 +2088,7 @@ static void calculateLayoutImpl(
availableInnerCrossDim + paddingAndBorderAxisCross, availableInnerCrossDim + paddingAndBorderAxisCross,
boundAxisWithinMinAndMax( boundAxisWithinMinAndMax(
node, node,
direction,
crossAxis, crossAxis,
FloatOptional{ FloatOptional{
totalLineCrossDim + paddingAndBorderAxisCross}, totalLineCrossDim + paddingAndBorderAxisCross},
@@ -2354,21 +2376,22 @@ void calculateLayout(
// visit all dirty nodes at least once. Subsequent visits will be skipped if // visit all dirty nodes at least once. Subsequent visits will be skipped if
// the input parameters don't change. // the input parameters don't change.
gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed); gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed);
node->resolveDimension(); node->processDimensions();
const Direction direction = node->resolveDirection(ownerDirection);
float width = YGUndefined; float width = YGUndefined;
SizingMode widthSizingMode = SizingMode::MaxContent; SizingMode widthSizingMode = SizingMode::MaxContent;
const auto& style = node->style(); const auto& style = node->style();
if (node->hasDefiniteLength(Dimension::Width, ownerWidth)) { if (node->hasDefiniteLength(Dimension::Width, ownerWidth)) {
width = width =
(node->getResolvedDimension(dimension(FlexDirection::Row)) (node->getResolvedDimension(
.resolve(ownerWidth) direction, dimension(FlexDirection::Row), ownerWidth)
.unwrap() + .unwrap() +
node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth)); node->style().computeMarginForAxis(FlexDirection::Row, ownerWidth));
widthSizingMode = SizingMode::StretchFit; widthSizingMode = SizingMode::StretchFit;
} else if (style.maxDimension(Dimension::Width) } else if (style.resolvedMaxDimension(direction, Dimension::Width, ownerWidth)
.resolve(ownerWidth)
.isDefined()) { .isDefined()) {
width = style.maxDimension(Dimension::Width).resolve(ownerWidth).unwrap(); width = style.resolvedMaxDimension(direction, Dimension::Width, ownerWidth)
.unwrap();
widthSizingMode = SizingMode::FitContent; widthSizingMode = SizingMode::FitContent;
} else { } else {
width = ownerWidth; width = ownerWidth;
@@ -2380,16 +2403,18 @@ void calculateLayout(
SizingMode heightSizingMode = SizingMode::MaxContent; SizingMode heightSizingMode = SizingMode::MaxContent;
if (node->hasDefiniteLength(Dimension::Height, ownerHeight)) { if (node->hasDefiniteLength(Dimension::Height, ownerHeight)) {
height = height =
(node->getResolvedDimension(dimension(FlexDirection::Column)) (node->getResolvedDimension(
.resolve(ownerHeight) direction, dimension(FlexDirection::Column), ownerHeight)
.unwrap() + .unwrap() +
node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth)); node->style().computeMarginForAxis(FlexDirection::Column, ownerWidth));
heightSizingMode = SizingMode::StretchFit; heightSizingMode = SizingMode::StretchFit;
} else if (style.maxDimension(Dimension::Height) } else if (style
.resolve(ownerHeight) .resolvedMaxDimension(
direction, Dimension::Height, ownerHeight)
.isDefined()) { .isDefined()) {
height = height =
style.maxDimension(Dimension::Height).resolve(ownerHeight).unwrap(); style.resolvedMaxDimension(direction, Dimension::Height, ownerHeight)
.unwrap();
heightSizingMode = SizingMode::FitContent; heightSizingMode = SizingMode::FitContent;
} else { } else {
height = ownerHeight; height = ownerHeight;

View File

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

View File

@@ -43,7 +43,7 @@ Node::Node(Node&& node) noexcept
owner_(node.owner_), owner_(node.owner_),
children_(std::move(node.children_)), children_(std::move(node.children_)),
config_(node.config_), config_(node.config_),
resolvedDimensions_(node.resolvedDimensions_) { processedDimensions_(node.processedDimensions_) {
for (auto c : children_) { for (auto c : children_) {
c->setOwner(this); c->setOwner(this);
} }
@@ -292,14 +292,14 @@ Style::Length Node::resolveFlexBasisPtr() const {
return value::ofAuto(); return value::ofAuto();
} }
void Node::resolveDimension() { void Node::processDimensions() {
for (auto dim : {Dimension::Width, Dimension::Height}) { for (auto dim : {Dimension::Width, Dimension::Height}) {
if (style_.maxDimension(dim).isDefined() && if (style_.maxDimension(dim).isDefined() &&
yoga::inexactEquals( yoga::inexactEquals(
style_.maxDimension(dim), style_.minDimension(dim))) { style_.maxDimension(dim), style_.minDimension(dim))) {
resolvedDimensions_[yoga::to_underlying(dim)] = style_.maxDimension(dim); processedDimensions_[yoga::to_underlying(dim)] = style_.maxDimension(dim);
} else { } else {
resolvedDimensions_[yoga::to_underlying(dim)] = style_.dimension(dim); processedDimensions_[yoga::to_underlying(dim)] = style_.dimension(dim);
} }
} }
} }

View File

@@ -86,7 +86,7 @@ class YG_EXPORT Node : public ::YGNode {
* https://www.w3.org/TR/css-sizing-3/#definite * https://www.w3.org/TR/css-sizing-3/#definite
*/ */
inline bool hasDefiniteLength(Dimension dimension, float ownerSize) { inline bool hasDefiniteLength(Dimension dimension, float ownerSize) {
auto usedValue = getResolvedDimension(dimension).resolve(ownerSize); auto usedValue = getProcessedDimension(dimension).resolve(ownerSize);
return usedValue.isDefined() && usedValue.unwrap() >= 0.0f; return usedValue.isDefined() && usedValue.unwrap() >= 0.0f;
} }
@@ -152,12 +152,27 @@ class YG_EXPORT Node : public ::YGNode {
return isDirty_; return isDirty_;
} }
std::array<Style::Length, 2> getResolvedDimensions() const { Style::Length getProcessedDimension(Dimension dimension) const {
return resolvedDimensions_; return processedDimensions_[static_cast<size_t>(dimension)];
} }
Style::Length getResolvedDimension(Dimension dimension) const { FloatOptional getResolvedDimension(
return resolvedDimensions_[static_cast<size_t>(dimension)]; Direction direction,
Dimension dimension,
float referenceLength) const {
FloatOptional value =
getProcessedDimension(dimension).resolve(referenceLength);
if (style_.boxSizing() == BoxSizing::BorderBox) {
return value;
}
FloatOptional dimensionPaddingAndBorder =
FloatOptional{style_.computePaddingAndBorderForDimension(
direction, dimension, referenceLength)};
return value +
(dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
: FloatOptional{0.0});
} }
// Setters // Setters
@@ -233,7 +248,7 @@ class YG_EXPORT Node : public ::YGNode {
// Other methods // Other methods
Style::Length resolveFlexBasisPtr() const; Style::Length resolveFlexBasisPtr() const;
void resolveDimension(); void processDimensions();
Direction resolveDirection(Direction ownerDirection); Direction resolveDirection(Direction ownerDirection);
void clearChildren(); void clearChildren();
/// Replaces the occurrences of oldChild with newChild /// Replaces the occurrences of oldChild with newChild
@@ -280,7 +295,7 @@ class YG_EXPORT Node : public ::YGNode {
Node* owner_ = nullptr; Node* owner_ = nullptr;
std::vector<Node*> children_; std::vector<Node*> children_;
const Config* config_; const Config* config_;
std::array<Style::Length, 2> resolvedDimensions_{ std::array<Style::Length, 2> processedDimensions_{
{value::undefined(), value::undefined()}}; {value::undefined(), value::undefined()}};
}; };

View File

@@ -189,6 +189,23 @@ class YG_EXPORT Style {
pool_.store(minDimensions_[yoga::to_underlying(axis)], value); pool_.store(minDimensions_[yoga::to_underlying(axis)], value);
} }
FloatOptional resolvedMinDimension(
Direction direction,
Dimension axis,
float referenceLength) const {
FloatOptional value = minDimension(axis).resolve(referenceLength);
if (boxSizing() == BoxSizing::BorderBox) {
return value;
}
FloatOptional dimensionPaddingAndBorder = FloatOptional{
computePaddingAndBorderForDimension(direction, axis, referenceLength)};
return value +
(dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
: FloatOptional{0.0});
}
Style::Length maxDimension(Dimension axis) const { Style::Length maxDimension(Dimension axis) const {
return pool_.getLength(maxDimensions_[yoga::to_underlying(axis)]); return pool_.getLength(maxDimensions_[yoga::to_underlying(axis)]);
} }
@@ -196,6 +213,23 @@ class YG_EXPORT Style {
pool_.store(maxDimensions_[yoga::to_underlying(axis)], value); pool_.store(maxDimensions_[yoga::to_underlying(axis)], value);
} }
FloatOptional resolvedMaxDimension(
Direction direction,
Dimension axis,
float referenceLength) const {
FloatOptional value = maxDimension(axis).resolve(referenceLength);
if (boxSizing() == BoxSizing::BorderBox) {
return value;
}
FloatOptional dimensionPaddingAndBorder = FloatOptional{
computePaddingAndBorderForDimension(direction, axis, referenceLength)};
return value +
(dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
: FloatOptional{0.0});
}
FloatOptional aspectRatio() const { FloatOptional aspectRatio() const {
return pool_.getNumber(aspectRatio_); return pool_.getNumber(aspectRatio_);
} }
@@ -446,6 +480,20 @@ class YG_EXPORT Style {
computeFlexEndBorder(axis, direction); computeFlexEndBorder(axis, direction);
} }
float computePaddingAndBorderForDimension(
Direction direction,
Dimension dimension,
float widthSize) const {
FlexDirection flexDirectionForDimension = dimension == Dimension::Width
? FlexDirection::Row
: FlexDirection::Column;
return computeFlexStartPaddingAndBorder(
flexDirectionForDimension, direction, widthSize) +
computeFlexEndPaddingAndBorder(
flexDirectionForDimension, direction, widthSize);
}
float computeBorderForAxis(FlexDirection axis) const { float computeBorderForAxis(FlexDirection axis) const {
return computeInlineStartBorder(axis, Direction::LTR) + return computeInlineStartBorder(axis, Direction::LTR) +
computeInlineEndBorder(axis, Direction::LTR); computeInlineEndBorder(axis, Direction::LTR);