Commit aff05a8e authored by Ian Kilpatrick's avatar Ian Kilpatrick Committed by Chromium LUCI CQ

[GridNG] A very basic implementation of ContributionSizeForGridItem

This is only truly correct for parallel min/max content contributions
which are inside indefinite track(s).

Things which are wrong:
 - parallel min/max content contributions need to use the correct
   percentage resolution sizes.
 - orthogonal min/max content contributions need to determine the
   available/percentages sizes based on base/used row/column tracks
   (if available).
 - minimum contributions are all wrong.

Bug: 1045599
Change-Id: I196efc81dbb44077217135aa59619567120da761
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2630626Reviewed-by: default avatarEthan Jimenez <ethavar@microsoft.com>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Reviewed-by: default avatarKurt Catti-Schmidt <kschmi@microsoft.com>
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845925}
parent c6324006
......@@ -359,21 +359,81 @@ LayoutUnit NGGridLayoutAlgorithm::ContributionSizeForGridItem(
const GridItemData& grid_item,
GridTrackSizingDirection track_direction,
GridItemContributionType contribution_type) const {
const ComputedStyle& grid_item_style = grid_item.node.Style();
GridTrackSizingDirection grid_item_track_direction = track_direction;
bool is_orthogonal_grid_item = Style().IsHorizontalWritingMode() ==
grid_item_style.IsHorizontalWritingMode();
if (is_orthogonal_grid_item) {
grid_item_track_direction =
(track_direction == kForColumns) ? kForRows : kForColumns;
const NGBlockNode& node = grid_item.node;
const ComputedStyle& item_style = node.Style();
bool is_parallel_with_track_direction =
(track_direction == kForColumns) ==
IsParallelWritingMode(Style().GetWritingMode(),
item_style.GetWritingMode());
auto MinMaxContentSizes = [&]() -> MinMaxSizes {
DCHECK(is_parallel_with_track_direction);
// TODO(ikilpatrick): kIndefiniteSize is incorrect for the %-block-size.
// We'll want to determine this using the base or used track-sizes instead.
// This should match the %-resolution sizes we use for layout during
// measuring.
MinMaxSizesInput input(kIndefiniteSize, MinMaxSizesType::kContent);
return ComputeMinAndMaxContentContribution(Style(), node, input).sizes;
};
// TODO(ikilpatrick): This function is just an initial approximation, and
// should be removed. Specifically it is incorrect for:
// - Replaced elements.
// - Items with non-visible overflow.
// - Incorrect %-resolution sizes, and available sizes.
auto MainSize = [&]() -> LayoutUnit {
// TODO(ikilpatrick): This constraint space is incorrect. Specifically the
// available, and percentages sizes should be determined from the base or
// used track-sizes instead.
NGConstraintSpaceBuilder builder(ConstraintSpace(),
item_style.GetWritingDirection(),
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), node, &builder);
builder.SetCacheSlot(NGCacheSlot::kMeasure);
builder.SetIsPaintedAtomically(true);
builder.SetAvailableSize(ChildAvailableSize());
builder.SetPercentageResolutionSize(child_percentage_size_);
const NGConstraintSpace space = builder.ToConstraintSpace();
if (is_parallel_with_track_direction) {
// TODO(ikilpatrick): ComputeInlineSizeForFragment is incorrect for
// replaced elements.
const NGBoxStrut border_padding =
ComputeBorders(space, node) + ComputePadding(space, item_style);
return ComputeInlineSizeForFragment(space, node, border_padding);
}
scoped_refptr<const NGLayoutResult> result = node.Layout(space);
return NGFragment(ConstraintSpace().GetWritingDirection(),
result->PhysicalFragment())
.BlockSize();
};
LayoutUnit contribution;
switch (contribution_type) {
case GridItemContributionType::kForContentBasedMinimums:
case GridItemContributionType::kForIntrinsicMaximums:
if (is_parallel_with_track_direction)
contribution = MinMaxContentSizes().min_size;
else
contribution = MainSize();
break;
case GridItemContributionType::kForIntrinsicMinimums:
contribution = MainSize();
break;
case GridItemContributionType::kForMaxContentMinimums:
case GridItemContributionType::kForMaxContentMaximums:
if (is_parallel_with_track_direction)
contribution = MinMaxContentSizes().max_size;
else
contribution = MainSize();
break;
}
Length length = (grid_item_track_direction == kForColumns)
? grid_item_style.LogicalWidth()
: grid_item_style.LogicalHeight();
return length.IsFixed() ? MinimumValueForLength(length, kIndefiniteSize)
: LayoutUnit();
return contribution + ((track_direction == kForColumns)
? grid_item.margins.InlineSum()
: grid_item.margins.BlockSum());
}
void NGGridLayoutAlgorithm::ConstructAndAppendGridItems(
......@@ -504,25 +564,7 @@ NGGridLayoutAlgorithm::GridItemData NGGridLayoutAlgorithm::MeasureGridItem(
// have all child inline and min/max sizes measured for content-based width
// resolution.
GridItemData grid_item(node);
const ComputedStyle& child_style = node.Style();
bool is_orthogonal_flow_root = !IsParallelWritingMode(
container_style.GetWritingMode(), child_style.GetWritingMode());
NGConstraintSpace constraint_space = BuildSpaceForGridItem(node);
// Children with orthogonal writing modes require a full layout pass to
// determine inline size.
if (is_orthogonal_flow_root) {
scoped_refptr<const NGLayoutResult> result = node.Layout(constraint_space);
grid_item.inline_size = NGFragment(ConstraintSpace().GetWritingDirection(),
result->PhysicalFragment())
.InlineSize();
} else {
NGBoxStrut border_padding_in_child_writing_mode =
ComputeBorders(constraint_space, node) +
ComputePadding(constraint_space, child_style);
grid_item.inline_size = ComputeInlineSizeForFragment(
constraint_space, node, border_padding_in_child_writing_mode);
}
const ComputedStyle& item_style = node.Style();
const ItemPosition normal_behaviour =
node.IsReplaced() ? ItemPosition::kStart : ItemPosition::kStretch;
......@@ -531,45 +573,28 @@ NGGridLayoutAlgorithm::GridItemData NGGridLayoutAlgorithm::MeasureGridItem(
// know if it stretches ahead of time to correctly determine any block-axis
// contribution).
grid_item.inline_axis_alignment = AxisEdgeFromItemPosition(
container_style, child_style,
child_style.ResolvedJustifySelf(normal_behaviour, &container_style)
container_style, item_style,
item_style.ResolvedJustifySelf(normal_behaviour, &container_style)
.GetPosition(),
/* is_inline_axis */ true, &grid_item.is_inline_axis_stretched);
grid_item.block_axis_alignment = AxisEdgeFromItemPosition(
container_style, child_style,
child_style.ResolvedAlignSelf(normal_behaviour, &container_style)
container_style, item_style,
item_style.ResolvedAlignSelf(normal_behaviour, &container_style)
.GetPosition(),
/* is_inline_axis */ false, &grid_item.is_block_axis_stretched);
// TODO(ikilpatrick): This is likely incorrect for margins in the
// ComputeMinMaxSizes phase.
grid_item.margins =
ComputeMarginsFor(constraint_space, child_style, ConstraintSpace());
grid_item.min_max_sizes =
node.ComputeMinMaxSizes(
container_style.GetWritingMode(),
MinMaxSizesInput(child_percentage_size_.block_size,
MinMaxSizesType::kContent),
&constraint_space)
.sizes;
ComputePhysicalMargins(item_style, ChildAvailableSize().inline_size)
.ConvertToLogical(ConstraintSpace().GetWritingDirection());
grid_item.item_type = node.IsOutOfFlowPositioned() ? ItemType::kOutOfFlow
: ItemType::kInGridFlow;
return grid_item;
}
NGConstraintSpace NGGridLayoutAlgorithm::BuildSpaceForGridItem(
const NGBlockNode node) const {
const auto& style = node.Style();
NGConstraintSpaceBuilder builder(ConstraintSpace(),
style.GetWritingDirection(),
/* is_new_fc */ true);
SetOrthogonalFallbackInlineSizeIfNeeded(Style(), node, &builder);
builder.SetCacheSlot(NGCacheSlot::kMeasure);
builder.SetIsPaintedAtomically(true);
builder.SetAvailableSize(ChildAvailableSize());
builder.SetPercentageResolutionSize(child_percentage_size_);
return builder.ToConstraintSpace();
}
void NGGridLayoutAlgorithm::BuildBlockTrackCollections(
Vector<GridItemData>* grid_items,
NGGridBlockTrackCollection* column_track_collection,
......
......@@ -75,8 +75,6 @@ class CORE_EXPORT NGGridLayoutAlgorithm
GridArea resolved_position;
NGBoxStrut margins;
LayoutUnit inline_size;
MinMaxSizes min_max_sizes;
AxisEdge inline_axis_alignment;
AxisEdge block_axis_alignment;
......@@ -157,7 +155,6 @@ class CORE_EXPORT NGGridLayoutAlgorithm
Vector<GridItemData>* grid_items,
Vector<GridItemData>* out_of_flow_items = nullptr) const;
GridItemData MeasureGridItem(const NGBlockNode node) const;
NGConstraintSpace BuildSpaceForGridItem(const NGBlockNode node) const;
void BuildBlockTrackCollections(
Vector<GridItemData>* grid_items,
......
......@@ -86,15 +86,6 @@ class NGGridLayoutAlgorithmTest
return grid_items_.size();
}
Vector<LayoutUnit> GridItemInlineSizes(
const NGGridLayoutAlgorithm& algorithm) {
Vector<LayoutUnit> results;
for (const auto& item : grid_items_) {
results.push_back(item.inline_size);
}
return results;
}
Vector<LayoutUnit> GridItemInlineMarginSum(
const NGGridLayoutAlgorithm& algorithm) {
Vector<LayoutUnit> results;
......@@ -104,15 +95,6 @@ class NGGridLayoutAlgorithmTest
return results;
}
Vector<MinMaxSizes> GridItemMinMaxSizes(
const NGGridLayoutAlgorithm& algorithm) {
Vector<MinMaxSizes> results;
for (const auto& item : grid_items_) {
results.push_back(item.min_max_sizes);
}
return results;
}
Vector<GridArea> GridItemGridAreas(const NGGridLayoutAlgorithm& algorithm) {
Vector<GridArea> results;
for (const auto& item : grid_items_) {
......@@ -342,14 +324,6 @@ TEST_F(NGGridLayoutAlgorithmTest, NGGridLayoutAlgorithmMeasuring) {
BuildGridItemsAndTrackCollections(algorithm);
EXPECT_EQ(GridItemCount(algorithm), 9U);
Vector<LayoutUnit> actual_inline_sizes = GridItemInlineSizes(algorithm);
EXPECT_EQ(GridItemCount(algorithm), actual_inline_sizes.size());
LayoutUnit expected_inline_sizes[] = {
LayoutUnit(50), LayoutUnit(116), LayoutUnit(100),
LayoutUnit(100), LayoutUnit(300), LayoutUnit(100),
LayoutUnit(400), LayoutUnit(100), LayoutUnit(10)};
Vector<LayoutUnit> actual_inline_margin_sums =
GridItemInlineMarginSum(algorithm);
EXPECT_EQ(GridItemCount(algorithm), actual_inline_margin_sums.size());
......@@ -359,27 +333,9 @@ TEST_F(NGGridLayoutAlgorithmTest, NGGridLayoutAlgorithmMeasuring) {
LayoutUnit(0), LayoutUnit(0), LayoutUnit(0),
LayoutUnit(10), LayoutUnit(100), LayoutUnit(0)};
Vector<MinMaxSizes> actual_min_max_sizes = GridItemMinMaxSizes(algorithm);
EXPECT_EQ(GridItemCount(algorithm), actual_min_max_sizes.size());
MinMaxSizes expected_min_max_sizes[] = {
{LayoutUnit(40), LayoutUnit(60)}, {LayoutUnit(116), LayoutUnit(116)},
{LayoutUnit(40), LayoutUnit(60)}, {LayoutUnit(100), LayoutUnit(100)},
{LayoutUnit(300), LayoutUnit(300)}, {LayoutUnit(300), LayoutUnit(300)},
{LayoutUnit(300), LayoutUnit(300)}, {LayoutUnit(100), LayoutUnit(100)},
{LayoutUnit(40), LayoutUnit(40)}};
for (size_t i = 0; i < GridItemCount(algorithm); ++i) {
EXPECT_EQ(actual_inline_sizes[i], expected_inline_sizes[i])
<< " index: " << i;
EXPECT_EQ(actual_inline_margin_sums[i], expected_inline_margin_sums[i])
<< " index: " << i;
EXPECT_EQ(actual_min_max_sizes[i].min_size,
expected_min_max_sizes[i].min_size)
<< " index: " << i;
EXPECT_EQ(actual_min_max_sizes[i].max_size,
expected_min_max_sizes[i].max_size)
<< " index: " << i;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment