Commit 4049f639 authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

[LayoutNG] Orthogonal flows need available inline size for min/max calculation.

Provide a suitable constraint space when calculating min/max inline
sizes for an orthogonal flow root. ComputeMinMaxSize() in NGBlockNode
typically ended up creating its zero-sized constraint space, which would
typically result in large block sizes (since there'd e.g. only be space
for one word per line).

Set percentage resolution size too, instead of leaving it at 0x0.
Percentages are often unresolvable (i.e. indefinite), in which case we
should of course refrain from resolving them, rather than resolving the
percentage against zero (which we used to do).

Add a DCHECK that we're always provided with a constraint space when
calculating min/max for orthogonal flows, as using the zero-size one
will not produce the correct result.

Bug: 848225
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: Ic0aac380b2b733d3a55b25396c89584e4468899d
Reviewed-on: https://chromium-review.googlesource.com/1090845
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565446}
parent cb55d023
...@@ -46,6 +46,8 @@ crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-vlr-in-ht ...@@ -46,6 +46,8 @@ crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-vlr-in-ht
crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-vrl-in-htb-002.xht [ Pass ] crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-prct-vrl-in-htb-002.xht [ Pass ]
crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-vlr-in-htb-001.xht [ Pass ] crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-vlr-in-htb-001.xht [ Pass ]
crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-vlr-in-htb-004.xht [ Pass ] crbug.com/626703 external/wpt/css/css-writing-modes/sizing-orthog-vlr-in-htb-004.xht [ Pass ]
crbug.com/591099 external/wpt/css/css-writing-modes/two-levels-of-orthogonal-flows-percentage.html [ Pass ]
crbug.com/591099 fast/dom/inner-text-first-letter.html [ Pass ] crbug.com/591099 fast/dom/inner-text-first-letter.html [ Pass ]
# New failures are appended below by the script. # New failures are appended below by the script.
......
...@@ -2200,6 +2200,7 @@ crbug.com/492664 external/wpt/css/css-writing-modes/line-box-height-vlr-021.xht ...@@ -2200,6 +2200,7 @@ crbug.com/492664 external/wpt/css/css-writing-modes/line-box-height-vlr-021.xht
crbug.com/492664 external/wpt/css/css-writing-modes/line-box-height-vlr-023.xht [ Failure ] crbug.com/492664 external/wpt/css/css-writing-modes/line-box-height-vlr-023.xht [ Failure ]
crbug.com/492664 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-006.xht [ Failure ] crbug.com/492664 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-006.xht [ Failure ]
crbug.com/492664 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-014.xht [ Failure ] crbug.com/492664 external/wpt/css/css-writing-modes/ortho-htb-alongside-vrl-floats-014.xht [ Failure ]
crbug.com/492664 external/wpt/css/css-writing-modes/two-levels-of-orthogonal-flows-percentage.html [ Failure ]
crbug.com/637055 fast/css/outline-offset-large.html [ Skip ] crbug.com/637055 fast/css/outline-offset-large.html [ Skip ]
......
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<p>The yellow box should be in the top right corner of the hotpink box.</p>
<div style="width:30em; height:30em; background:hotpink;">
<div style="float:right; writing-mode:vertical-rl; background:yellow;">
<div style="visibility:hidden;">
Roses are red,<br>
violets are blue.<br>
All my base<br>
are belong to you.<br>
</div>
</div>
</div>
</div>
<!DOCTYPE html>
<title>Two levels of writing mode roots with text inside, fixed available inline size for inner on outer</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<div style="width:10em; border:solid; background:yellow;">
<div style="padding:3px;">
This text should be inside a box with a yellow background and a black border. There should be no red.
</div>
</div>
<!DOCTYPE html>
<title>Two levels of writing mode roots with text inside, percentage inline size on inner</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<p>There should be three lines below. The middle line should have a yellow
background that takes up about 50% of the viewport width (but otherwise be
exactly like the two others, i.e. no extra height or anything like that).</p>
A B C D E F G
<div style="width:50vw; background:yellow;">
A B C D E F G
</div>
A B C D E F G
<!DOCTYPE html>
<title>Two levels of writing mode roots with text inside, no constraints</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#intrinsic" title="4. Intrinsic Size Determination">
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto" title="7.3.1. Available Space in Orthogonal Flows">
<p>There should be three lines below. The middle line should have a
yellow background (but otherwise be exactly like the two others,
i.e. no extra height or anything like that)</p>
A B C D E F G
<div style="width:fit-content; background:yellow;">
A B C D E F G
</div>
A B C D E F G
<!DOCTYPE html>
<title>Three levels of writing mode roots with text inside, no constraints</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#intrinsic" title="4. Intrinsic Size Determination">
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto" title="7.3.1. Available Space in Orthogonal Flows">
<link rel="match" href="reference/three-levels-of-orthogonal-flows.html">
<p>The yellow box should be in the top right corner of the hotpink box.</p>
<div style="writing-mode:vertical-rl; width:30em; height:30em; background:hotpink;">
<div style="writing-mode:horizontal-tb;">
<div style="writing-mode:vertical-rl; background:yellow;">
<div style="visibility:hidden;">
Roses are red,<br>
violets are blue.<br>
All my base<br>
are belong to you.<br>
</div>
</div>
</div>
</div>
<!DOCTYPE html>
<title>Two levels of writing mode roots with text inside, fixed available inline size for inner on outer</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#intrinsic" title="4. Intrinsic Size Determination">
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto" title="7.3.1. Available Space in Orthogonal Flows">
<link rel="match" href="reference/two-levels-of-orthogonal-flows-fixed.html">
<div style="writing-mode:vertical-rl; width:10em; border:solid; background:red;">
<div style="writing-mode:horizontal-tb; padding:3px; background:yellow;">
This text should be inside a box with a yellow background and a black border. There should be no red.
</div>
</div>
<!DOCTYPE html>
<title>Two levels of writing mode roots with text inside, percentage inline size on inner</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#intrinsic" title="4. Intrinsic Size Determination">
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto" title="7.3.1. Available Space in Orthogonal Flows">
<link rel="match" href="reference/two-levels-of-orthogonal-flows-percentage.html">
<p>There should be three lines below. The middle line should have a yellow
background that takes up about 50% of the viewport width (but otherwise be
exactly like the two others, i.e. no extra height or anything like that).</p>
A B C D E F G
<div style="writing-mode:vertical-rl; background:yellow;">
<div style="writing-mode:horizontal-tb; width:50%;">
A B C D E F G
</div>
</div>
A B C D E F G
<!DOCTYPE html>
<title>Two levels of writing mode roots with text inside, no constraints</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#intrinsic" title="4. Intrinsic Size Determination">
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto" title="7.3.1. Available Space in Orthogonal Flows">
<link rel="match" href="reference/two-levels-of-orthogonal-flows.html">
<p>There should be three lines below. The middle line should have a
yellow background (but otherwise be exactly like the two others,
i.e. no extra height or anything like that)</p>
A B C D E F G
<div style="writing-mode:vertical-rl; background:yellow;">
<div style="writing-mode:horizontal-tb;">
A B C D E F G
</div>
</div>
A B C D E F G
...@@ -118,6 +118,42 @@ NGLogicalOffset LogicalFromBfcOffsets(const NGFragment& fragment, ...@@ -118,6 +118,42 @@ NGLogicalOffset LogicalFromBfcOffsets(const NGFragment& fragment,
child_bfc_offset.block_offset - parent_bfc_offset.block_offset}; child_bfc_offset.block_offset - parent_bfc_offset.block_offset};
} }
// Create a child constraint space with only extrinsic block sizing data. This
// will and can not be used for final layout, but is needed in an intermediate
// measure pass that calculates the min/max size contribution from a child that
// establishes an orthogonal flow root.
//
// Note that it's the child's *block* size that will be propagated as min/max
// inline size to the container. Therefore it's crucial to provide the child
// with an available inline size (which can be derived from the block size of
// the container if definite). We'll provide any extrinsic available block size
// that we have. This includes fixed and resolvable percentage sizes, for
// instance, while auto will not resolve. If no extrinsic size can be
// determined, we will resort to using a fallback later on, such as the initial
// containing block size. Spec:
// https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto
scoped_refptr<NGConstraintSpace> CreateExtrinsicConstraintSpace(
const NGConstraintSpace& container_space,
NGBlockNode container,
NGBlockNode child) {
LayoutUnit extrinsic_block_size = ComputeBlockSizeForFragment(
container_space, container.Style(), NGSizeIndefinite);
if (extrinsic_block_size != NGSizeIndefinite) {
extrinsic_block_size -=
CalculateBorderScrollbarPadding(container_space, container).BlockSum();
extrinsic_block_size = std::max(extrinsic_block_size, LayoutUnit());
}
NGLogicalSize extrinsic_size(NGSizeIndefinite, extrinsic_block_size);
return NGConstraintSpaceBuilder(container_space)
.SetAvailableSize(extrinsic_size)
.SetPercentageResolutionSize(extrinsic_size)
.SetIsIntermediateLayout(true)
.SetIsNewFormattingContext(child.CreatesNewFormattingContext())
.SetFloatsBfcOffset(NGBfcOffset())
.ToConstraintSpace(child.Style().GetWritingMode());
}
} // namespace } // namespace
NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode node, NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode node,
...@@ -186,8 +222,19 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize( ...@@ -186,8 +222,19 @@ base::Optional<MinMaxSize> NGBlockLayoutAlgorithm::ComputeMinMaxSize(
child_sizes = child_sizes =
child.ComputeMinMaxSize(Style().GetWritingMode(), child_input); child.ComputeMinMaxSize(Style().GetWritingMode(), child_input);
} else { } else {
// We'll need extrinsic sizing data when computing min/max for orthogonal
// flow roots.
scoped_refptr<NGConstraintSpace> extrinsic_constraint_space;
const NGConstraintSpace* optional_constraint_space = nullptr;
if (!IsParallelWritingMode(Style().GetWritingMode(),
child.Style().GetWritingMode())) {
extrinsic_constraint_space = CreateExtrinsicConstraintSpace(
ConstraintSpace(), Node(), ToNGBlockNode(child));
optional_constraint_space = extrinsic_constraint_space.get();
}
child_sizes = ComputeMinAndMaxContentContribution( child_sizes = ComputeMinAndMaxContentContribution(
Style().GetWritingMode(), child, child_input); Style().GetWritingMode(), child, child_input,
optional_constraint_space);
} }
// Determine the max inline contribution of the child. // Determine the max inline contribution of the child.
......
...@@ -269,11 +269,18 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize( ...@@ -269,11 +269,18 @@ MinMaxSize NGBlockNode::ComputeMinMaxSize(
CreateConstraintSpaceBuilderForMinMax(*this).ToConstraintSpace( CreateConstraintSpaceBuilderForMinMax(*this).ToConstraintSpace(
Style().GetWritingMode()); Style().GetWritingMode());
if (!constraint_space) bool is_orthogonal_flow_root =
!IsParallelWritingMode(container_writing_mode, Style().GetWritingMode());
if (!constraint_space) {
// Using the zero-sized constraint space when measuring for an orthogonal
// flow root isn't going to give the right result.
DCHECK(!is_orthogonal_flow_root);
constraint_space = zero_constraint_space.get(); constraint_space = zero_constraint_space.get();
}
if (!IsParallelWritingMode(container_writing_mode, if (is_orthogonal_flow_root) {
Style().GetWritingMode())) {
scoped_refptr<NGLayoutResult> layout_result = Layout(*constraint_space); scoped_refptr<NGLayoutResult> layout_result = Layout(*constraint_space);
DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess); DCHECK_EQ(layout_result->Status(), NGLayoutResult::kSuccess);
NGBoxFragment fragment( NGBoxFragment fragment(
......
...@@ -44,9 +44,11 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode { ...@@ -44,9 +44,11 @@ class CORE_EXPORT NGBlockNode final : public NGLayoutInputNode {
// An optional constraint space may be supplied, which will be used to resolve // An optional constraint space may be supplied, which will be used to resolve
// percentage padding on this node, to set up the right min/max size // percentage padding on this node, to set up the right min/max size
// contribution. This is typically desirable for the subtree root of the // contribution. This is typically desirable for the subtree root of the
// min/max calculation (e.g. the node that will undergo shrink-to-fit). This // min/max calculation (e.g. the node that will undergo shrink-to-fit). It is
// constraint space will not be passed on to children. If no constraint space // also used to provide provide a sensible available inline size when
// is specified, a zero-sized one will be used. // calculating min/max for orthogonal flows. 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(WritingMode container_writing_mode, MinMaxSize ComputeMinMaxSize(WritingMode container_writing_mode,
const MinMaxSizeInput&, const MinMaxSizeInput&,
const NGConstraintSpace* = nullptr); const NGConstraintSpace* = nullptr);
......
...@@ -348,6 +348,8 @@ MinMaxSize ComputeMinAndMaxContentContribution( ...@@ -348,6 +348,8 @@ MinMaxSize ComputeMinAndMaxContentContribution(
// definition. // definition.
NGConstraintSpaceBuilder builder(*constraint_space); NGConstraintSpaceBuilder builder(*constraint_space);
builder.SetAvailableSize(constraint_space->AvailableSize()) builder.SetAvailableSize(constraint_space->AvailableSize())
.SetPercentageResolutionSize(
constraint_space->PercentageResolutionSize())
.SetFloatsBfcOffset(NGBfcOffset()) .SetFloatsBfcOffset(NGBfcOffset())
.SetIsNewFormattingContext(node.CreatesNewFormattingContext()) .SetIsNewFormattingContext(node.CreatesNewFormattingContext())
.SetIsShrinkToFit(true); .SetIsShrinkToFit(true);
......
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