Skip to content

Commit

Permalink
[GridNG] Allow stretching in block-axis.
Browse files Browse the repository at this point in the history
This block-stretching logic as:
https://chromium-review.googlesource.com/c/chromium/src/+/2513771
... did for the inline-axis.

Previously we didn't have the concept of "stretching" the block-axis
instead relying on the parent layout algorithm to set a fixed
block-size.

This allow stretching (similar to the inline-dimension).

The failing tests (which I'll update in the test expectations) are due
to this specification issue:
w3c/csswg-drafts#5713

The changes in layout_replaced.cc are needed to transfer the stretched
size through the aspect-ratio.

Bug: 1045599
Change-Id: Ifdd8653d81a1ead84a0afbf5ebd31ba0b75dc8ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2523743
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: Kurt Catti-Schmidt <kschmi@microsoft.com>
Reviewed-by: David Grogan <dgrogan@chromium.org>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/master@{#827854}
GitOrigin-RevId: eaff997ccac677831d0a3c72e638ddf6528276d7
  • Loading branch information
bfgeek authored and copybara-github committed Nov 16, 2020
1 parent 88f0676 commit 30b1983
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 64 deletions.
4 changes: 4 additions & 0 deletions blink/renderer/core/layout/box_layout_extra_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ struct BoxLayoutExtraInput {
// purposes of percent block-size resolution.
bool is_override_block_size_definite = true;

// If an 'auto' inline/block-size should stretch to the available size.
bool stretch_inline_size_if_auto = false;
bool stretch_block_size_if_auto = false;

// Available inline size. https://drafts.csswg.org/css-sizing/#available
LayoutUnit available_inline_size;

Expand Down
20 changes: 18 additions & 2 deletions blink/renderer/core/layout/layout_box.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2042,6 +2042,16 @@ bool LayoutBox::IsOverrideLogicalHeightDefinite() const {
return extra_input_ && extra_input_->is_override_block_size_definite;
}

bool LayoutBox::StretchInlineSizeIfAuto() const {
NOT_DESTROYED();
return extra_input_ && extra_input_->stretch_inline_size_if_auto;
}

bool LayoutBox::StretchBlockSizeIfAuto() const {
NOT_DESTROYED();
return extra_input_ && extra_input_->stretch_block_size_if_auto;
}

bool LayoutBox::HasOverrideLogicalHeight() const {
NOT_DESTROYED();
if (extra_input_ && extra_input_->override_block_size)
Expand Down Expand Up @@ -5048,12 +5058,15 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalWidthRespectingMinMaxWidth(

LayoutUnit LayoutBox::ComputeReplacedLogicalWidthUsing(
SizeType size_type,
const Length& logical_width) const {
Length logical_width) const {
NOT_DESTROYED();
DCHECK(size_type == kMinSize || size_type == kMainOrPreferredSize ||
!logical_width.IsAuto());
if (size_type == kMinSize && logical_width.IsAuto())
return AdjustContentBoxLogicalWidthForBoxSizing(LayoutUnit());
if (size_type == kMainOrPreferredSize && logical_width.IsAuto() &&
StretchInlineSizeIfAuto())
logical_width = Length::FillAvailable();

switch (logical_width.GetType()) {
case Length::kFixed:
Expand Down Expand Up @@ -5176,12 +5189,15 @@ LayoutUnit LayoutBox::ComputeReplacedLogicalHeightRespectingMinMaxHeight(

LayoutUnit LayoutBox::ComputeReplacedLogicalHeightUsing(
SizeType size_type,
const Length& logical_height) const {
Length logical_height) const {
NOT_DESTROYED();
DCHECK(size_type == kMinSize || size_type == kMainOrPreferredSize ||
!logical_height.IsAuto());
if (size_type == kMinSize && logical_height.IsAuto())
return AdjustContentBoxLogicalHeightForBoxSizing(LayoutUnit());
if (size_type == kMainOrPreferredSize && logical_height.IsAuto() &&
StretchBlockSizeIfAuto())
logical_height = Length::FillAvailable();

switch (logical_height.GetType()) {
case Length::kFixed:
Expand Down
8 changes: 4 additions & 4 deletions blink/renderer/core/layout/layout_box.h
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,8 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
LayoutUnit OverrideLogicalHeight() const;
LayoutUnit OverrideLogicalWidth() const;
bool IsOverrideLogicalHeightDefinite() const;
bool StretchInlineSizeIfAuto() const;
bool StretchBlockSizeIfAuto() const;
bool HasOverrideLogicalHeight() const;
bool HasOverrideLogicalWidth() const;
void SetOverrideLogicalHeight(LayoutUnit);
Expand Down Expand Up @@ -1400,13 +1402,11 @@ class CORE_EXPORT LayoutBox : public LayoutBoxModelObject {
SizeType,
const Length& height,
LayoutUnit intrinsic_content_height) const;
LayoutUnit ComputeReplacedLogicalWidthUsing(SizeType,
const Length& width) const;
LayoutUnit ComputeReplacedLogicalWidthUsing(SizeType, Length width) const;
LayoutUnit ComputeReplacedLogicalWidthRespectingMinMaxWidth(
LayoutUnit logical_width,
ShouldComputePreferred = kComputeActual) const;
LayoutUnit ComputeReplacedLogicalHeightUsing(SizeType,
const Length& height) const;
LayoutUnit ComputeReplacedLogicalHeightUsing(SizeType, Length height) const;
LayoutUnit ComputeReplacedLogicalHeightRespectingMinMaxHeight(
LayoutUnit logical_height) const;

Expand Down
7 changes: 4 additions & 3 deletions blink/renderer/core/layout/layout_replaced.cc
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ void LayoutReplaced::Paint(const PaintInfo& paint_info) const {
bool LayoutReplaced::HasReplacedLogicalHeight() const {
NOT_DESTROYED();
if (StyleRef().LogicalHeight().IsAuto())
return false;
return StretchBlockSizeIfAuto();

if (StyleRef().LogicalHeight().IsSpecified()) {
if (HasAutoHeightOrContainingBlockWithAutoHeight())
Expand Down Expand Up @@ -762,7 +762,7 @@ LayoutUnit LayoutReplaced::ComputeConstrainedLogicalWidth(
LayoutUnit LayoutReplaced::ComputeReplacedLogicalWidth(
ShouldComputePreferred should_compute_preferred) const {
NOT_DESTROYED();
if (!StyleRef().LogicalWidth().IsAuto()) {
if (!StyleRef().LogicalWidth().IsAuto() || StretchInlineSizeIfAuto()) {
return ComputeReplacedLogicalWidthRespectingMinMaxWidth(
ComputeReplacedLogicalWidthUsing(kMainOrPreferredSize,
StyleRef().LogicalWidth()),
Expand All @@ -778,7 +778,8 @@ LayoutUnit LayoutReplaced::ComputeReplacedLogicalWidth(
ConstrainIntrinsicSizeToMinMax(intrinsic_sizing_info);

if (StyleRef().LogicalWidth().IsAuto()) {
bool computed_height_is_auto = StyleRef().LogicalHeight().IsAuto();
bool computed_height_is_auto =
StyleRef().LogicalHeight().IsAuto() && !StretchBlockSizeIfAuto();

// If 'height' and 'width' both have computed values of 'auto' and the
// element also has an intrinsic width, then that intrinsic width is the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1201,14 +1201,8 @@ void NGGridLayoutAlgorithm::PlaceGridItem(const GridItemData& grid_item,
builder.SetAvailableSize(size);
builder.SetPercentageResolutionSize(size);

// TODO(ikilpatrick): We need a slightly different constraint space API now.
// Instead of a "shrink-to-fit" bit, we should have a "is-stretched" bit to
// indicate if 'auto' should stretch to fill the available space. This should
// apply to both the inline, and block axis. E.g.
// IsInlineSizeStretched / IsBlockSizeStretched or similar.
builder.SetIsFixedBlockSize(item_style.LogicalHeight().IsAuto() &&
grid_item.is_block_axis_stretched);
builder.SetStretchInlineSizeIfAuto(grid_item.is_inline_axis_stretched);
builder.SetStretchBlockSizeIfAuto(grid_item.is_block_axis_stretched);

scoped_refptr<const NGLayoutResult> result =
grid_item.node.Layout(builder.ToConstraintSpace());
Expand Down
3 changes: 2 additions & 1 deletion blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2522,7 +2522,8 @@ NGConstraintSpace NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(

if (IsParallelWritingMode(ConstraintSpace().GetWritingMode(),
child_writing_direction.GetWritingMode())) {
if (!child.GetLayoutBox()->AutoWidthShouldFitContent())
if (!child.GetLayoutBox()->AutoWidthShouldFitContent() &&
!child.IsReplaced())
builder.SetStretchInlineSizeIfAuto(true);
}

Expand Down
4 changes: 4 additions & 0 deletions blink/renderer/core/layout/ng/ng_block_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ void SetupBoxLayoutExtraInput(const NGConstraintSpace& space,
input->is_override_block_size_definite =
!space.IsFixedBlockSizeIndefinite();
}
input->stretch_inline_size_if_auto = space.StretchInlineSizeIfAuto();
input->stretch_block_size_if_auto =
space.StretchBlockSizeIfAuto() &&
space.AvailableSize().block_size != kIndefiniteSize;
}

bool CanUseCachedIntrinsicInlineSizes(const MinMaxSizesInput& input,
Expand Down
9 changes: 6 additions & 3 deletions blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -999,9 +999,12 @@ LayoutUnit NGColumnLayoutAlgorithm::ConstrainColumnBlockSize(
LayoutUnit max = ResolveMaxBlockLength(
ConstraintSpace(), style, BorderPadding(), style.LogicalMaxHeight(),
LengthResolvePhase::kLayout);
LayoutUnit extent = ResolveMainBlockLength(
ConstraintSpace(), style, BorderPadding(), style.LogicalHeight(),
kIndefiniteSize, LengthResolvePhase::kLayout);
LayoutUnit extent = kIndefiniteSize;
if (!style.LogicalHeight().IsAuto()) {
extent = ResolveMainBlockLength(ConstraintSpace(), style, BorderPadding(),
style.LogicalHeight(), kIndefiniteSize,
LengthResolvePhase::kLayout);
}
if (extent != kIndefiniteSize) {
// A specified height/width will just constrain the maximum length.
max = std::min(max, extent);
Expand Down
8 changes: 7 additions & 1 deletion blink/renderer/core/layout/ng/ng_constraint_space.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,11 +440,14 @@ class CORE_EXPORT NGConstraintSpace final {
return bitfields_.is_fixed_block_size_indefinite;
}

// Return true if the inline-size property when 'auto' should stretch to
// Return true if the respective size property when 'auto' should stretch to
// consume the available space. If false, it behaves as "shrink-to-fit".
bool StretchInlineSizeIfAuto() const {
return bitfields_.stretch_inline_size_if_auto;
}
bool StretchBlockSizeIfAuto() const {
return bitfields_.stretch_block_size_if_auto;
}

bool IsPaintedAtomically() const { return bitfields_.is_painted_atomically; }

Expand Down Expand Up @@ -1282,6 +1285,7 @@ class CORE_EXPORT NGConstraintSpace final {
static_cast<unsigned>(NGBaselineAlgorithmType::kFirstLine)),
cache_slot(static_cast<unsigned>(NGCacheSlot::kLayout)),
stretch_inline_size_if_auto(false),
stretch_block_size_if_auto(false),
is_fixed_inline_size(false),
is_fixed_block_size(false),
is_fixed_block_size_indefinite(false),
Expand Down Expand Up @@ -1311,6 +1315,7 @@ class CORE_EXPORT NGConstraintSpace final {

bool AreSizeConstraintsEqual(const Bitfields& other) const {
return stretch_inline_size_if_auto == other.stretch_inline_size_if_auto &&
stretch_block_size_if_auto == other.stretch_block_size_if_auto &&
is_fixed_inline_size == other.is_fixed_inline_size &&
is_fixed_block_size == other.is_fixed_block_size &&
is_fixed_block_size_indefinite ==
Expand Down Expand Up @@ -1341,6 +1346,7 @@ class CORE_EXPORT NGConstraintSpace final {

// Size constraints.
unsigned stretch_inline_size_if_auto : 1;
unsigned stretch_block_size_if_auto : 1;
unsigned is_fixed_inline_size : 1;
unsigned is_fixed_block_size : 1;
unsigned is_fixed_block_size_indefinite : 1;
Expand Down
12 changes: 11 additions & 1 deletion blink/renderer/core/layout/ng/ng_constraint_space_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,17 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
}

void SetStretchInlineSizeIfAuto(bool b) {
space_.bitfields_.stretch_inline_size_if_auto = b;
if (LIKELY(is_in_parallel_flow_))
space_.bitfields_.stretch_inline_size_if_auto = b;
else
space_.bitfields_.stretch_block_size_if_auto = b;
}

void SetStretchBlockSizeIfAuto(bool b) {
if (LIKELY(is_in_parallel_flow_))
space_.bitfields_.stretch_block_size_if_auto = b;
else
space_.bitfields_.stretch_inline_size_if_auto = b;
}

void SetIsPaintedAtomically(bool b) {
Expand Down
7 changes: 6 additions & 1 deletion blink/renderer/core/layout/ng/ng_layout_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ inline bool InlineLengthMayChange(const ComputedStyle& style,
inline bool BlockLengthMayChange(const Length& length,
const NGConstraintSpace& new_space,
const NGConstraintSpace& old_space) {
if (length.IsFillAvailable()) {
DCHECK_EQ(new_space.StretchBlockSizeIfAuto(),
old_space.StretchBlockSizeIfAuto());
if (length.IsFillAvailable() ||
(length.IsAuto() && new_space.StretchBlockSizeIfAuto())) {
if (new_space.AvailableSize().block_size !=
old_space.AvailableSize().block_size)
return true;
Expand All @@ -85,6 +88,8 @@ bool SizeMayChange(const NGBlockNode& node,
old_space.IsFixedBlockSizeIndefinite());
DCHECK_EQ(new_space.StretchInlineSizeIfAuto(),
old_space.StretchInlineSizeIfAuto());
DCHECK_EQ(new_space.StretchBlockSizeIfAuto(),
old_space.StretchBlockSizeIfAuto());
DCHECK_EQ(new_space.TableCellChildLayoutMode(),
old_space.TableCellChildLayoutMode());

Expand Down
31 changes: 18 additions & 13 deletions blink/renderer/core/layout/ng/ng_length_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ LayoutUnit ResolveBlockLengthInternal(
}
return value;
}
case Length::kAuto:
case Length::kMinContent:
case Length::kMaxContent:
case Length::kMinIntrinsic:
Expand All @@ -212,7 +211,7 @@ LayoutUnit ResolveBlockLengthInternal(
// border and padding. We cannot check for this if we are
// block-fragmented, though, because then the block-start border/padding
// may be in a different fragmentainer than the block-end border/padding.
if (intrinsic_size != LayoutUnit(-1) &&
if (intrinsic_size != kIndefiniteSize &&
!constraint_space.HasBlockFragmentation())
DCHECK_GE(intrinsic_size, border_padding.BlockSum());
#endif // DCHECK_IS_ON()
Expand All @@ -222,6 +221,7 @@ LayoutUnit ResolveBlockLengthInternal(
case Length::kExtendToZoom:
NOTREACHED() << "These should only be used for viewport definitions";
FALLTHROUGH;
case Length::kAuto:
case Length::kNone:
default:
NOTREACHED();
Expand Down Expand Up @@ -557,17 +557,17 @@ namespace {

// Computes the block-size for a fragment, ignoring the fixed block-size if set.
LayoutUnit ComputeBlockSizeForFragmentInternal(
const NGConstraintSpace& constraint_space,
const NGConstraintSpace& space,
const ComputedStyle& style,
const NGBoxStrut& border_padding,
LayoutUnit intrinsic_size,
base::Optional<LayoutUnit> inline_size,
const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
nullptr) {
MinMaxSizes min_max = ComputeMinMaxBlockSize(
constraint_space, style, border_padding, intrinsic_size,
opt_percentage_resolution_block_size_for_min_max);
const Length& logical_height = style.LogicalHeight();
MinMaxSizes min_max =
ComputeMinMaxBlockSize(space, style, border_padding, intrinsic_size,
opt_percentage_resolution_block_size_for_min_max);
Length logical_height = style.LogicalHeight();
// Scrollable percentage-sized children of table cells, in the table
// "measure" phase contribute nothing to the row height measurement.
// See: https://drafts.csswg.org/css-tables-3/#row-layout
Expand All @@ -580,19 +580,24 @@ LayoutUnit ComputeBlockSizeForFragmentInternal(
// things to consider, would be checking the row and row-group, and also other
// properties, such as {min,max}-block-size.
if (logical_height.IsPercentOrCalc() &&
constraint_space.TableCellChildLayoutMode() ==
space.TableCellChildLayoutMode() ==
NGTableCellChildLayoutMode::kMeasureRestricted &&
(style.OverflowBlockDirection() == EOverflow::kAuto ||
style.OverflowBlockDirection() == EOverflow::kScroll))
return min_max.min_size;

const bool is_logical_height_auto = logical_height.IsAuto();
if (is_logical_height_auto) {
logical_height = space.StretchBlockSizeIfAuto() ? Length::FillAvailable()
: Length::FitContent();
}
// TODO(cbiesinger): Audit callers of ResolveMainBlockLength to see whether
// they need to respect aspect ratio.
LayoutUnit extent = ResolveMainBlockLength(
constraint_space, style, border_padding, logical_height, intrinsic_size,
LengthResolvePhase::kLayout,
opt_percentage_resolution_block_size_for_min_max);
if (UNLIKELY((extent == kIndefiniteSize || logical_height.IsAuto()) &&
LayoutUnit extent =
ResolveMainBlockLength(space, style, border_padding, logical_height,
intrinsic_size, LengthResolvePhase::kLayout,
opt_percentage_resolution_block_size_for_min_max);
if (UNLIKELY((extent == kIndefiniteSize || is_logical_height_auto) &&
!style.AspectRatio().IsAuto() && inline_size)) {
extent =
BlockSizeFromAspectRatio(border_padding, style.LogicalAspectRatio(),
Expand Down
4 changes: 3 additions & 1 deletion blink/renderer/core/layout/ng/ng_length_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ inline LayoutUnit ResolveMainBlockLength(
LengthResolvePhase phase,
const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
nullptr) {
DCHECK(!length.IsAuto());
if (UNLIKELY((length.IsPercentOrCalc() || length.IsFillAvailable()) &&
BlockLengthUnresolvable(
constraint_space, length, phase,
Expand All @@ -265,14 +266,15 @@ inline LayoutUnit ResolveMainBlockLength(
LengthResolvePhase phase,
const LayoutUnit* opt_percentage_resolution_block_size_for_min_max =
nullptr) {
DCHECK(!length.IsAuto());
if (UNLIKELY((length.IsPercentOrCalc() || length.IsFillAvailable()) &&
BlockLengthUnresolvable(
constraint_space, length, phase,
opt_percentage_resolution_block_size_for_min_max)))
return intrinsic_block_size_func();

LayoutUnit intrinsic_block_size = kIndefiniteSize;
if (length.IsAutoOrContentOrIntrinsic())
if (length.IsContentOrIntrinsic())
intrinsic_block_size = intrinsic_block_size_func();

return ResolveBlockLengthInternal(
Expand Down
3 changes: 0 additions & 3 deletions blink/renderer/core/layout/ng/ng_length_utils_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,6 @@ TEST_F(NGLengthUtilsTest, testResolveInlineLength) {
TEST_F(NGLengthUtilsTest, testResolveBlockLength) {
EXPECT_EQ(LayoutUnit(90), ResolveMainBlockLength(Length::Percent(30)));
EXPECT_EQ(LayoutUnit(150), ResolveMainBlockLength(Length::Fixed(150)));
EXPECT_EQ(LayoutUnit(0), ResolveMainBlockLength(Length::Auto()));
EXPECT_EQ(LayoutUnit(300), ResolveMainBlockLength(Length::FillAvailable()));

EXPECT_EQ(LayoutUnit(300), ResolveMainBlockLength(Length::FillAvailable()));
}

Expand Down
Loading

0 comments on commit 30b1983

Please sign in to comment.