Commit efdf268f authored by Christian Biesinger's avatar Christian Biesinger Committed by Commit Bot

[layoutng] More correct intrinsic sizing of orthogonal children

This allows us to get "correct" sizing of orthogonal children when
computing min/max content sizes. I have not verified if this behavior
is 100% correct per the spec, but it certainly gets us much closer and
allows us to pass a number of additional tests.

This is done by adding a writing_mode parameter to
NGLayoutInputNode::ComputeMinMaxSize, and the block node is then responsible
for producing right value for that writing mode. If orthogonal, it does
layout with the given constraint space, if any.

Bug: 591099

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: I5cf30a91b9548a3894c2bee483ec3245fec962e6
Reviewed-on: https://chromium-review.googlesource.com/1069848
Commit-Queue: Christian Biesinger <cbiesinger@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Reviewed-by: default avatarMorten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561664}
parent 8aca6d50
......@@ -43,6 +43,9 @@ crbug.com/591099 fast/css/getComputedStyle/getComputedStyle-resolved-values.html
# https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/layout/layout_block.cc?l=1372&rcl=0e081149ecd6a83f6289e3aee5797936008a1e10
crbug.com/591099 fast/block/marquee-width-shrinks-to-fit-in-fixed-size-container.html [ Failure ]
# For unknown reasons we render the reference incorrectly
crbug.com/591099 fast/multicol/vertical-rl/column-rules.html [ Failure ]
# New passes
crbug.com/591099 external/wpt/css/CSS2/floats-clear/no-clearance-adjoining-opposite-float.html [ Pass ]
crbug.com/591099 external/wpt/css/CSS2/floats-clear/no-clearance-due-to-large-margin-after-left-right.html [ Pass ]
......@@ -416,25 +419,8 @@ crbug.com/591099 external/wpt/css/css-writing-modes/float-vlr-013.xht [ Failure
crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-012.xht [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/line-box-direction-vrl-009.xht [ Pass ]
crbug.com/591099 external/wpt/css/css-writing-modes/margin-collapse-vrl-010.xht [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/nested-orthogonal-001.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-006.xht [ Pass ]
crbug.com/591099 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-014.xht [ Pass ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001a.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001b.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001c.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001d.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001e.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001f.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001g.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001h.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001i.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001j.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001k.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001l.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001m.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001n.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001o.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001p.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001q.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001r.html [ Failure ]
crbug.com/591099 external/wpt/css/css-writing-modes/orthogonal-parent-shrink-to-fit-001s.html [ Failure ]
......@@ -613,7 +599,6 @@ crbug.com/591099 fast/block/positioning/complex-positioned-movement-inline-ances
crbug.com/591099 fast/block/positioning/fixed-in-abs-height-change.html [ Crash ]
crbug.com/591099 fast/block/positioning/positioned-child-inside-relative-positioned-anonymous-block.html [ Failure ]
crbug.com/591099 fast/block/positioning/relative-overflow-replaced.html [ Failure ]
crbug.com/591099 fast/block/positioning/vertical-rl/002.html [ Failure ]
crbug.com/591099 fast/borders/bidi-002.html [ Failure ]
crbug.com/591099 fast/borders/bidi-012.html [ Failure ]
crbug.com/591099 fast/borders/border-image-border-radius.html [ Failure ]
......@@ -851,10 +836,6 @@ crbug.com/591099 fast/overflow/recompute-overflow-of-layout-root-container.html
crbug.com/591099 fast/pagination/modal-dialog.html [ Failure ]
crbug.com/824918 fast/pagination/paged-x-column-gap.html [ Failure ]
crbug.com/824918 fast/pagination/paged-y-to-paged-x.html [ Failure ]
crbug.com/824918 fast/pagination/viewport-x-vertical-rl-ltr.html [ Failure ]
crbug.com/824918 fast/pagination/viewport-x-vertical-rl-rtl.html [ Failure ]
crbug.com/824918 fast/pagination/viewport-y-vertical-rl-ltr.html [ Failure ]
crbug.com/824918 fast/pagination/viewport-y-vertical-rl-rtl.html [ Failure ]
crbug.com/591099 fast/parser/001.html [ Failure ]
crbug.com/591099 fast/parser/entities-in-html.html [ Failure ]
crbug.com/591099 fast/parser/entities-in-xhtml.xhtml [ Failure ]
......@@ -862,7 +843,6 @@ crbug.com/591099 fast/replaced/absolute-position-percentage-height.html [ Failur
crbug.com/591099 fast/replaced/border-radius-clip.html [ Failure ]
crbug.com/591099 fast/replaced/preferred-widths.html [ Failure ]
crbug.com/591099 fast/replaced/table-replaced-element.html [ Failure ]
crbug.com/591099 fast/replaced/vertical-rl/absolute-position-percentage-width.html [ Failure ]
crbug.com/591099 fast/ruby/add-text-to-block-ruby-with-after-pseudo-crash.html [ Crash ]
crbug.com/591099 fast/ruby/base-shorter-than-text.html [ Failure ]
crbug.com/591099 fast/ruby/float-overhang-from-ruby-text.html [ Failure ]
......@@ -924,7 +904,6 @@ crbug.com/591099 fast/table/large-shrink-wrapped-width.html [ Failure ]
crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure ]
crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure ]
crbug.com/591099 fast/table/percent-height-replaced-content-in-cell.html [ Failure ]
crbug.com/591099 fast/table/percent-widths-stretch-vertical.html [ Failure ]
crbug.com/591099 fast/table/table-display-types-vertical.html [ Failure ]
crbug.com/591099 fast/table/unbreakable-images-quirk.html [ Failure ]
crbug.com/591099 fast/table/vertical-align-baseline-readjust.html [ Failure ]
......@@ -1342,7 +1321,6 @@ crbug.com/591099 paint/invalidation/outline/focus-ring-on-inline-continuation-mo
crbug.com/591099 paint/invalidation/outline/inline-focus.html [ Failure ]
crbug.com/591099 paint/invalidation/outline/inline-outline-repaint-2.html [ Failure ]
crbug.com/591099 paint/invalidation/outline/outline-change-continuations.html [ Failure ]
crbug.com/591099 paint/invalidation/outline/outline-change-vertical-rl.html [ Failure ]
crbug.com/591099 paint/invalidation/outline/outline-containing-image-in-non-standard-mode.html [ Failure ]
crbug.com/591099 paint/invalidation/outline/outline-continuations.html [ Failure ]
crbug.com/591099 paint/invalidation/overflow/align-items-overflow-change.html [ Failure ]
......
......@@ -182,7 +182,8 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
// an anonymous box that contains all line boxes.
// |NextSibling| returns the next block sibling, or nullptr, skipping all
// following inline siblings and descendants.
child_sizes = child.ComputeMinMaxSize(child_input);
child_sizes =
child.ComputeMinMaxSize(Style().GetWritingMode(), child_input);
} else {
child_sizes = ComputeMinAndMaxContentContribution(
Style().GetWritingMode(), child, child_input);
......@@ -1639,7 +1640,7 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
// We only want to guess the child's size here, so preceding floats are of
// no interest.
MinMaxSizeInput zero_input;
sizes = child.ComputeMinMaxSize(zero_input);
sizes = child.ComputeMinMaxSize(child_style.GetWritingMode(), zero_input);
}
LayoutUnit child_inline_size =
......
......@@ -238,6 +238,7 @@ scoped_refptr<NGLayoutResult> NGBlockNode::Layout(
}
MinMaxSize NGBlockNode::ComputeMinMaxSize(
WritingMode container_writing_mode,
const MinMaxSizeInput& input,
const NGConstraintSpace* constraint_space) {
MinMaxSize sizes;
......@@ -259,12 +260,24 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
InitialContainingBlockSize())
.SetTextDirection(Style().Direction())
.SetIsIntermediateLayout(true)
.SetFloatsBfcOffset(NGBfcOffset())
.ToConstraintSpace(Style().GetWritingMode());
if (!constraint_space)
constraint_space = zero_constraint_space.get();
// TODO(cbiesinger): For orthogonal children, we need to always synthesize.
if (!IsParallelWritingMode(container_writing_mode,
Style().GetWritingMode())) {
scoped_refptr<NGLayoutResult> layout_result = Layout(*constraint_space);
DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
NGBoxFragment fragment(
container_writing_mode,
ToNGPhysicalBoxFragment(*layout_result->PhysicalFragment()));
sizes.min_size = sizes.max_size = fragment.Size().inline_size;
return sizes;
}
// TODO(layout-ng): We need to make sure to use the right algorithm
NGBlockLayoutAlgorithm minmax_algorithm(*this, *constraint_space);
base::Optional<MinMaxSize> maybe_sizes =
minmax_algorithm.ComputeMinMaxSize(input);
......@@ -274,7 +287,7 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
// Have to synthesize this value.
scoped_refptr<NGLayoutResult> layout_result = Layout(*zero_constraint_space);
NGBoxFragment min_fragment(
Style().GetWritingMode(),
container_writing_mode,
ToNGPhysicalBoxFragment(*layout_result->PhysicalFragment()));
sizes.min_size = min_fragment.Size().inline_size;
......@@ -290,7 +303,7 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
layout_result = Layout(*infinite_constraint_space);
NGBoxFragment max_fragment(
Style().GetWritingMode(),
container_writing_mode,
ToNGPhysicalBoxFragment(*layout_result->PhysicalFragment()));
sizes.max_size = max_fragment.Size().inline_size;
return sizes;
......
......@@ -47,7 +47,8 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
// min/max calculation (e.g. the node that will undergo shrink-to-fit). This
// constraint space will not be passed on to children. If no constraint space
// is specified, a zero-sized one will be used.
MinMaxSize ComputeMinMaxSize(const MinMaxSizeInput&,
MinMaxSize ComputeMinMaxSize(WritingMode container_writing_mode,
const MinMaxSizeInput&,
const NGConstraintSpace* = nullptr);
NGBoxStrut GetScrollbarSizes() const;
......
......@@ -159,7 +159,8 @@ TEST_F(NGBlockNodeForTest, MinAndMaxContent) {
const int kWidth = 30;
NGBlockNode box(ToLayoutBox(GetLayoutObjectByElementId("box")));
MinMaxSize sizes = box.ComputeMinMaxSize(MinMaxSizeInput());
MinMaxSize sizes =
box.ComputeMinMaxSize(WritingMode::kHorizontalTb, MinMaxSizeInput());
EXPECT_EQ(LayoutUnit(kWidth), sizes.min_size);
EXPECT_EQ(LayoutUnit(kWidth), sizes.max_size);
}
......
......@@ -36,11 +36,15 @@ scoped_refptr<NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
continue;
// Assume row flexbox with no orthogonal items, which lets us just use
// MinMaxSize for flex base size. An orthogonal item would need full layout.
// TODO(layout-ng): Now that ComputeMinMaxSize takes a writing mode, this
// should be easy to fix by just passing an appropriate constraint space to
// ComputeMinMaxSize.
DCHECK(IsParallelWritingMode(Node().Style().GetWritingMode(),
child.Style().GetWritingMode()))
<< "Orthogonal items aren't supported yet.";
MinMaxSizeInput zero_input;
MinMaxSize min_max_sizes = child.ComputeMinMaxSize(zero_input);
MinMaxSize min_max_sizes =
child.ComputeMinMaxSize(ConstraintSpace().GetWritingMode(), zero_input);
LayoutUnit flex_base_content_size;
if (child.Style().FlexBasis().IsAuto() && child.Style().Width().IsAuto()) {
......
......@@ -195,6 +195,7 @@ LayoutUnit ComputeInlineSizeForUnpositionedFloat(
// If we've already performed layout on the unpositioned float, just return
// the cached value.
if (unpositioned_float->layout_result) {
// TODO(layout-ng): Should this use IsParallelWritingMode()?
DCHECK(!is_same_writing_mode);
DCHECK(unpositioned_float->layout_result->PhysicalFragment());
return NGFragment(parent_space.GetWritingMode(),
......@@ -216,7 +217,8 @@ LayoutUnit ComputeInlineSizeForUnpositionedFloat(
base::Optional<MinMaxSize> min_max_size;
if (NeedMinMaxSize(*space.get(), style)) {
MinMaxSizeInput zero_input; // Floats do not intrude into floats.
min_max_size = unpositioned_float->node.ComputeMinMaxSize(zero_input);
min_max_size = unpositioned_float->node.ComputeMinMaxSize(
style.GetWritingMode(), zero_input);
}
return ComputeInlineSizeForFragment(*space.get(), style, min_max_size);
}
......
......@@ -132,10 +132,12 @@ scoped_refptr<NGLayoutResult> NGLayoutInputNode::Layout(
}
MinMaxSize NGLayoutInputNode::ComputeMinMaxSize(
WritingMode writing_mode,
const MinMaxSizeInput& input,
const NGConstraintSpace* space) {
return IsInline() ? ToNGInlineNode(*this).ComputeMinMaxSize(input)
: ToNGBlockNode(*this).ComputeMinMaxSize(input, space);
: ToNGBlockNode(*this).ComputeMinMaxSize(writing_mode,
input, space);
}
void NGLayoutInputNode::IntrinsicSize(
......
......@@ -8,6 +8,7 @@
#include "base/optional.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/layout_unit.h"
#include "third_party/blink/renderer/platform/text/writing_mode.h"
namespace blink {
......@@ -71,7 +72,8 @@ class CORE_EXPORT NGLayoutInputNode {
// Performs layout on this input node, will return the layout result.
scoped_refptr<NGLayoutResult> Layout(const NGConstraintSpace&, NGBreakToken*);
MinMaxSize ComputeMinMaxSize(const MinMaxSizeInput&,
MinMaxSize ComputeMinMaxSize(WritingMode,
const MinMaxSizeInput&,
const NGConstraintSpace* = nullptr);
// Returns intrinsic sizing information for replaced elements.
......
......@@ -339,8 +339,22 @@ MinMaxSize ComputeMinAndMaxContentContribution(
const NGConstraintSpace* constraint_space) {
base::Optional<MinMaxSize> minmax;
if (NeedMinMaxSizeForContentContribution(writing_mode, node.Style())) {
// TODO(layoutng): This is wrong for orthogonal writing modes.
minmax = node.ComputeMinMaxSize(input, constraint_space);
scoped_refptr<NGConstraintSpace> adjusted_constraint_space;
if (constraint_space) {
// TODO(layout-ng): Check if our constraint space produces spec-compliant
// outputs.
// It is important to set a floats bfc offset so that we don't get a
// partial layout. It is also important that we shrink to fit, by
// definition.
NGConstraintSpaceBuilder builder(*constraint_space);
builder.SetAvailableSize(constraint_space->AvailableSize())
.SetFloatsBfcOffset(NGBfcOffset())
.SetIsShrinkToFit(true);
adjusted_constraint_space =
builder.ToConstraintSpace(node.Style().GetWritingMode());
constraint_space = adjusted_constraint_space.get();
}
minmax = node.ComputeMinMaxSize(writing_mode, input, constraint_space);
}
return ComputeMinAndMaxContentContribution(writing_mode, node.Style(),
......
......@@ -94,6 +94,9 @@ ComputeMinAndMaxContentContribution(WritingMode writing_mode,
// writing_mode is the desired output writing mode (ie. often the writing mode
// of the parent); node is the node of which to compute the min/max content
// contribution.
// If a constraint space is provided, this function will convert it to the
// correct writing mode and otherwise make sure it is suitable for computing
// the desired value.
MinMaxSize ComputeMinAndMaxContentContribution(
WritingMode writing_mode,
NGLayoutInputNode node,
......
......@@ -312,8 +312,8 @@ scoped_refptr<NGLayoutResult> NGOutOfFlowLayoutPart::LayoutDescendant(
// This is a new formatting context, so whatever happened on the outside
// doesn't concern us.
MinMaxSizeInput zero_input;
min_max_size =
node.ComputeMinMaxSize(zero_input, descendant_constraint_space.get());
min_max_size = node.ComputeMinMaxSize(descendant_writing_mode, zero_input,
descendant_constraint_space.get());
}
base::Optional<NGLogicalSize> replaced_size;
......
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