Commit 639c840b authored by ikilpatrick's avatar ikilpatrick Committed by Commit Bot

[LayoutNG] Removes per-child state from NGBlockLayoutAlgorithm.

Removes curr_bfc_offset_, curr_child_margins_, curr_margin_strut_ in
favour of stack variables.

This clears up the information flow between children, and makes it clear
*which* margin strut, etc is being used for a particular child's
positioning. (E.g. the OOFPositioned child's positioning was difficult
to determine before).

This introduces one regression which I'll investigate separately (static
position is weird with abs-pos legacy children now) - so I've removed the
LayoutNG CQ bot.

BUG=635619

Review-Url: https://codereview.chromium.org/2899413002
Cr-Commit-Position: refs/heads/master@{#476354}
parent ba20af04
...@@ -502,7 +502,6 @@ crbug.com/719646 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-in ...@@ -502,7 +502,6 @@ crbug.com/719646 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-in
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-percents-001.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-percents-001.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-height-005.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-height-005.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-width-007.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-non-replaced-width-007.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-width-002.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-width-006.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-replaced-width-006.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-013.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-013.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-017.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/blocks-017.xht [ Failure ]
...@@ -553,13 +552,7 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-bloc ...@@ -553,13 +552,7 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-bloc
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-non-replaced-height-002.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-non-replaced-height-002.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-008.xht [ Skip ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-replaced-height-008.xht [ Skip ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-valign-002.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-block-valign-002.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-non-replaced-height-002.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-non-replaced-height-003.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-008.xht [ Skip ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-height-008.xht [ Skip ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-001.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-002.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-003.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-006.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-012.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-012.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-013.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-013.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-015.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-015.xht [ Failure ]
...@@ -596,6 +589,7 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height- ...@@ -596,6 +589,7 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-081.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-081.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-082.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-082.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-090.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-090.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/inline-replaced-width-006.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-092.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-092.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-093.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-093.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-101.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/max-height-101.xht [ Failure ]
...@@ -737,8 +731,6 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning ...@@ -737,8 +731,6 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning-float-002.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/positioning-float-002.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/relpos-calcs-004.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/relpos-calcs-004.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/relpos-calcs-005.xht [ Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/relpos-calcs-005.xht [ Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-007.xht [ Crash ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-008.xht [ Crash ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-019.xht [ Crash Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-019.xht [ Crash Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-020.xht [ Crash Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-020.xht [ Crash Failure ]
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-031.xht [ Crash Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-031.xht [ Crash Failure ]
...@@ -758,7 +750,7 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-104.xht ...@@ -758,7 +750,7 @@ crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-104.xht
crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-113.xht [ Crash Failure ] crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/positioning/top-113.xht [ Crash Failure ]
### virtual/layout_ng/fast/block/basic ### virtual/layout_ng/fast/block/basic
crbug.com/635619 virtual/layout_ng/fast/block/basic/003.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/basic/001.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/basic/006.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/basic/006.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/basic/011.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/basic/011.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/basic/013.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/basic/013.html [ Failure ]
...@@ -825,7 +817,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/br-with-clear.html [ Failure ...@@ -825,7 +817,6 @@ crbug.com/635619 virtual/layout_ng/fast/block/float/br-with-clear.html [ Failure
crbug.com/635619 virtual/layout_ng/fast/block/float/canvas-with-floats-marked-for-layout.html [ Crash ] crbug.com/635619 virtual/layout_ng/fast/block/float/canvas-with-floats-marked-for-layout.html [ Crash ]
crbug.com/635619 virtual/layout_ng/fast/block/float/centered-float-avoidance-complexity.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/centered-float-avoidance-complexity.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/checkbox-and-radio-avoid-floats.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/checkbox-and-radio-avoid-floats.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/clamped-right-float.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/clear-element-too-wide-for-containing-block.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/clear-element-too-wide-for-containing-block.html [ Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/clear-intruding-floats-when-moving-to-inline-parent-3.html [ Crash Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/clear-intruding-floats-when-moving-to-inline-parent-3.html [ Crash Failure ]
crbug.com/635619 virtual/layout_ng/fast/block/float/clear-to-fit.html [ Failure ] crbug.com/635619 virtual/layout_ng/fast/block/float/clear-to-fit.html [ Failure ]
......
...@@ -55,11 +55,11 @@ NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm( ...@@ -55,11 +55,11 @@ NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm(
// Only resolve our BFC offset if we know that we are non-empty as we may // Only resolve our BFC offset if we know that we are non-empty as we may
// need to pass through our margin strut. // need to pass through our margin strut.
if (!inline_node->Items().IsEmpty()) { if (!inline_node->Items().IsEmpty()) {
NGLogicalOffset bfc_offset = ConstraintSpace().BfcOffset(); LayoutUnit bfc_block_offset = ConstraintSpace().BfcOffset().block_offset;
bfc_offset.block_offset += ConstraintSpace().MarginStrut().Sum(); bfc_block_offset += ConstraintSpace().MarginStrut().Sum();
MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_offset, MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_block_offset,
&container_builder_); &container_builder_);
PositionPendingFloats(bfc_offset.block_offset, &container_builder_, PositionPendingFloats(bfc_block_offset, &container_builder_,
MutableConstraintSpace()); MutableConstraintSpace());
} }
......
...@@ -67,14 +67,31 @@ bool IsOutOfSpace(const NGConstraintSpace& space, LayoutUnit content_size) { ...@@ -67,14 +67,31 @@ bool IsOutOfSpace(const NGConstraintSpace& space, LayoutUnit content_size) {
} // namespace } // namespace
// This struct is used for communicating to a child the position of the
// previous inflow child.
struct NGPreviousInflowPosition {
LayoutUnit bfc_block_offset;
LayoutUnit logical_block_offset;
NGMarginStrut margin_strut;
};
// This strut holds information for the current inflow child. The data is not
// useful outside of handling this single inflow child.
struct NGInflowChildData {
NGLogicalOffset bfc_offset_estimate;
NGMarginStrut margin_strut;
NGBoxStrut margins;
};
void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace& space, void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace& space,
const NGLogicalOffset& offset, LayoutUnit bfc_block_offset,
NGFragmentBuilder* builder) { NGFragmentBuilder* builder) {
DCHECK(builder); DCHECK(builder);
if (!builder->BfcOffset()) { if (!builder->BfcOffset()) {
NGLogicalOffset mutable_offset(offset); NGLogicalOffset bfc_offset = {space.BfcOffset().inline_offset,
AdjustToClearance(space.ClearanceOffset(), &mutable_offset); bfc_block_offset};
builder->SetBfcOffset(mutable_offset); AdjustToClearance(space.ClearanceOffset(), &bfc_offset);
builder->SetBfcOffset(bfc_offset);
} }
} }
...@@ -150,11 +167,13 @@ Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize() ...@@ -150,11 +167,13 @@ Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize()
} }
NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset( NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
const NGBoxStrut& child_margins,
const WTF::Optional<NGLogicalOffset>& known_fragment_offset) { const WTF::Optional<NGLogicalOffset>& known_fragment_offset) {
if (known_fragment_offset) if (known_fragment_offset)
return known_fragment_offset.value() - ContainerBfcOffset(); return known_fragment_offset.value() - ContainerBfcOffset();
LayoutUnit inline_offset = LayoutUnit inline_offset =
border_and_padding_.inline_start + curr_child_margins_.inline_start; border_and_padding_.inline_start + child_margins.inline_start;
// TODO(ikilpatrick): Using the content_size_ here looks suspicious - check.
return {inline_offset, content_size_}; return {inline_offset, content_size_};
} }
...@@ -199,17 +218,20 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -199,17 +218,20 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// within a previous fragment. // within a previous fragment.
content_size_ = BreakToken() ? LayoutUnit() : border_and_padding_.block_start; content_size_ = BreakToken() ? LayoutUnit() : border_and_padding_.block_start;
curr_margin_strut_ = ConstraintSpace().MarginStrut(); NGMarginStrut input_margin_strut = ConstraintSpace().MarginStrut();
curr_bfc_offset_ = ConstraintSpace().BfcOffset(); LayoutUnit input_bfc_block_offset =
ConstraintSpace().BfcOffset().block_offset;
// Margins collapsing: // Margins collapsing:
// Do not collapse margins between parent and its child if there is // Do not collapse margins between parent and its child if there is
// border/padding between them. // border/padding between them.
if (border_and_padding_.block_start) { if (border_and_padding_.block_start) {
curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); input_bfc_block_offset += input_margin_strut.Sum();
MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, MaybeUpdateFragmentBfcOffset(ConstraintSpace(), input_bfc_block_offset,
&container_builder_); &container_builder_);
curr_margin_strut_ = NGMarginStrut(); // We reset the block offset here as it may have been effected by clearance.
input_bfc_block_offset = ContainerBfcOffset().block_offset;
input_margin_strut = NGMarginStrut();
} }
// If a new formatting context hits the margin collapsing if-branch above // If a new formatting context hits the margin collapsing if-branch above
...@@ -218,29 +240,34 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -218,29 +240,34 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// If we are resuming layout from a break token the same rule applies. Margin // If we are resuming layout from a break token the same rule applies. Margin
// struts cannot pass through break tokens. // struts cannot pass through break tokens.
if (ConstraintSpace().IsNewFormattingContext() || BreakToken()) { if (ConstraintSpace().IsNewFormattingContext() || BreakToken()) {
MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, MaybeUpdateFragmentBfcOffset(ConstraintSpace(), input_bfc_block_offset,
&container_builder_); &container_builder_);
DCHECK_EQ(curr_margin_strut_, NGMarginStrut()); DCHECK_EQ(input_margin_strut, NGMarginStrut());
DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset()); DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset());
curr_bfc_offset_ = {};
} }
curr_bfc_offset_.block_offset += content_size_; input_bfc_block_offset += content_size_;
NGPreviousInflowPosition previous_inflow_position = {
input_bfc_block_offset, content_size_, input_margin_strut};
while (child) { while (child) {
if (child->IsOutOfFlowPositioned()) { if (child->IsOutOfFlowPositioned()) {
DCHECK(!child_break_token); DCHECK(!child_break_token);
HandleOutOfFlowPositioned(ToNGBlockNode(child)); HandleOutOfFlowPositioned(previous_inflow_position, ToNGBlockNode(child));
} else if (child->IsFloating()) { } else if (child->IsFloating()) {
HandleFloating(ToNGBlockNode(child), HandleFloating(previous_inflow_position, ToNGBlockNode(child),
ToNGBlockBreakToken(child_break_token)); ToNGBlockBreakToken(child_break_token));
} else { } else {
NGLogicalOffset child_bfc_offset = PrepareChildLayout(child); NGInflowChildData child_data =
PrepareChildLayout(previous_inflow_position, child);
RefPtr<NGConstraintSpace> child_space = RefPtr<NGConstraintSpace> child_space =
CreateConstraintSpaceForChild(child_bfc_offset, *child); CreateConstraintSpaceForChild(*child, child_data);
RefPtr<NGLayoutResult> layout_result = RefPtr<NGLayoutResult> layout_result =
child->Layout(child_space.Get(), child_break_token); child->Layout(child_space.Get(), child_break_token);
FinishChildLayout(*child_space, child, layout_result.Get()); previous_inflow_position =
FinishChildLayout(*child_space, previous_inflow_position, child_data,
child, layout_result.Get());
} }
entry = child_iterator.NextChild(); entry = child_iterator.NextChild();
...@@ -251,6 +278,9 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -251,6 +278,9 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
break; break;
} }
NGMarginStrut end_margin_strut = previous_inflow_position.margin_strut;
LayoutUnit end_bfc_block_offset = previous_inflow_position.bfc_block_offset;
// Margins collapsing: // Margins collapsing:
// Bottom margins of an in-flow block box doesn't collapse with its last // Bottom margins of an in-flow block box doesn't collapse with its last
// in-flow block-level child's bottom margin if the box has bottom // in-flow block-level child's bottom margin if the box has bottom
...@@ -258,8 +288,8 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -258,8 +288,8 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
content_size_ += border_and_padding_.block_end; content_size_ += border_and_padding_.block_end;
if (border_and_padding_.block_end || if (border_and_padding_.block_end ||
ConstraintSpace().IsNewFormattingContext()) { ConstraintSpace().IsNewFormattingContext()) {
content_size_ += curr_margin_strut_.Sum(); content_size_ += end_margin_strut.Sum();
curr_margin_strut_ = NGMarginStrut(); end_margin_strut = NGMarginStrut();
} }
// Recompute the block-axis size now that we know our content size. // Recompute the block-axis size now that we know our content size.
...@@ -273,10 +303,10 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -273,10 +303,10 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// Non-empty blocks always know their position in space. // Non-empty blocks always know their position in space.
// TODO(ikilpatrick): This check for a break token seems error prone. // TODO(ikilpatrick): This check for a break token seems error prone.
if (size.block_size || BreakToken()) { if (size.block_size || BreakToken()) {
curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); end_bfc_block_offset += end_margin_strut.Sum();
MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, MaybeUpdateFragmentBfcOffset(ConstraintSpace(), end_bfc_block_offset,
&container_builder_); &container_builder_);
PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, PositionPendingFloats(end_bfc_block_offset, &container_builder_,
MutableConstraintSpace()); MutableConstraintSpace());
} }
...@@ -285,9 +315,9 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -285,9 +315,9 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
// of its parent if the parent has height != auto() // of its parent if the parent has height != auto()
if (!Style().LogicalHeight().IsAuto()) { if (!Style().LogicalHeight().IsAuto()) {
// TODO(glebl): handle minLogicalHeight, maxLogicalHeight. // TODO(glebl): handle minLogicalHeight, maxLogicalHeight.
curr_margin_strut_ = NGMarginStrut(); end_margin_strut = NGMarginStrut();
} }
container_builder_.SetEndMarginStrut(curr_margin_strut_); container_builder_.SetEndMarginStrut(end_margin_strut);
container_builder_.SetOverflowSize( container_builder_.SetOverflowSize(
NGLogicalSize(max_inline_size_, content_size_)); NGLogicalSize(max_inline_size_, content_size_));
...@@ -302,33 +332,32 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { ...@@ -302,33 +332,32 @@ RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
return container_builder_.ToBoxFragment(); return container_builder_.ToBoxFragment();
} }
void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode* child) { void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(
NGLogicalOffset offset = {border_and_padding_.inline_start, content_size_}; const NGPreviousInflowPosition& previous_inflow_position,
NGBlockNode* child) {
NGLogicalOffset offset = {border_and_padding_.inline_start,
previous_inflow_position.logical_block_offset};
// We only include the margin strut in the OOF static-position if we know we // We only include the margin strut in the OOF static-position if we know we
// aren't going to be a zero-block-size fragment. // aren't going to be a zero-block-size fragment.
if (container_builder_.BfcOffset()) if (container_builder_.BfcOffset())
offset.block_offset += curr_margin_strut_.Sum(); offset.block_offset += previous_inflow_position.margin_strut.Sum();
container_builder_.AddOutOfFlowChildCandidate(child, offset); container_builder_.AddOutOfFlowChildCandidate(child, offset);
} }
void NGBlockLayoutAlgorithm::HandleFloating(NGBlockNode* child, void NGBlockLayoutAlgorithm::HandleFloating(
const NGPreviousInflowPosition& previous_inflow_position,
NGBlockNode* child,
NGBlockBreakToken* token) { NGBlockBreakToken* token) {
// TODO(ikilpatrick): Pass in BFC offset from previous in-flow child.
curr_bfc_offset_ = container_builder_.BfcOffset()
? container_builder_.BfcOffset().value()
: ConstraintSpace().BfcOffset();
curr_bfc_offset_.block_offset += content_size_;
// Calculate margins in the BFC's writing mode. // Calculate margins in the BFC's writing mode.
curr_child_margins_ = CalculateMargins(child); NGBoxStrut margins = CalculateMargins(child);
NGLogicalOffset origin_offset = constraint_space_->BfcOffset(); NGLogicalOffset origin_offset = constraint_space_->BfcOffset();
origin_offset.inline_offset += border_and_padding_.inline_start; origin_offset.inline_offset += border_and_padding_.inline_start;
RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create( RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create(
child_available_size_, child_percentage_size_, origin_offset, child_available_size_, child_percentage_size_, origin_offset,
constraint_space_->BfcOffset(), curr_child_margins_, child, token); constraint_space_->BfcOffset(), margins, child, token);
container_builder_.AddUnpositionedFloat(unpositioned_float); container_builder_.AddUnpositionedFloat(unpositioned_float);
// If there is a break token for a float we must be resuming layout, we must // If there is a break token for a float we must be resuming layout, we must
...@@ -337,29 +366,28 @@ void NGBlockLayoutAlgorithm::HandleFloating(NGBlockNode* child, ...@@ -337,29 +366,28 @@ void NGBlockLayoutAlgorithm::HandleFloating(NGBlockNode* child,
// No need to postpone the positioning if we know the correct offset. // No need to postpone the positioning if we know the correct offset.
if (container_builder_.BfcOffset()) { if (container_builder_.BfcOffset()) {
NGLogicalOffset origin_point = curr_bfc_offset_;
// Adjust origin point to the margins of the last child. // Adjust origin point to the margins of the last child.
// Example: <div style="margin-bottom: 20px"><float></div> // Example: <div style="margin-bottom: 20px"><float></div>
// <div style="margin-bottom: 30px"></div> // <div style="margin-bottom: 30px"></div>
origin_point.block_offset += curr_margin_strut_.Sum(); LayoutUnit origin_block_offset =
PositionPendingFloats(origin_point.block_offset, &container_builder_, previous_inflow_position.bfc_block_offset +
previous_inflow_position.margin_strut.Sum();
PositionPendingFloats(origin_block_offset, &container_builder_,
MutableConstraintSpace()); MutableConstraintSpace());
} }
} }
NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout( NGInflowChildData NGBlockLayoutAlgorithm::PrepareChildLayout(
const NGPreviousInflowPosition& previous_inflow_position,
NGLayoutInputNode* child) { NGLayoutInputNode* child) {
DCHECK(child); DCHECK(child);
DCHECK(!child->IsFloating()); DCHECK(!child->IsFloating());
// TODO(ikilpatrick): Pass in BFC offset from previous in-flow child. LayoutUnit bfc_block_offset = previous_inflow_position.bfc_block_offset;
curr_bfc_offset_ = container_builder_.BfcOffset()
? container_builder_.BfcOffset().value()
: ConstraintSpace().BfcOffset();
curr_bfc_offset_.block_offset += content_size_;
// Calculate margins in parent's writing mode. // Calculate margins in parent's writing mode.
curr_child_margins_ = CalculateMargins(child); NGBoxStrut margins = CalculateMargins(child);
NGMarginStrut margin_strut = previous_inflow_position.margin_strut;
bool should_position_pending_floats = bool should_position_pending_floats =
!IsNewFormattingContextForBlockLevelChild(Style(), *child) && !IsNewFormattingContextForBlockLevelChild(Style(), *child) &&
...@@ -371,45 +399,50 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout( ...@@ -371,45 +399,50 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout(
// be positioned before layout. This also resolves the fragment's bfc offset. // be positioned before layout. This also resolves the fragment's bfc offset.
if (should_position_pending_floats) { if (should_position_pending_floats) {
LayoutUnit origin_point_block_offset = LayoutUnit origin_point_block_offset =
curr_bfc_offset_.block_offset + curr_margin_strut_.Sum(); bfc_block_offset + margin_strut.Sum();
MaybeUpdateFragmentBfcOffset( MaybeUpdateFragmentBfcOffset(ConstraintSpace(), origin_point_block_offset,
ConstraintSpace(),
{curr_bfc_offset_.inline_offset, origin_point_block_offset},
&container_builder_); &container_builder_);
// TODO(ikilpatrick): Check if origin_point_block_offset is correct -
// MaybeUpdateFragmentBfcOffset might have changed it due to clearance.
PositionPendingFloats(origin_point_block_offset, &container_builder_, PositionPendingFloats(origin_point_block_offset, &container_builder_,
MutableConstraintSpace()); MutableConstraintSpace());
} }
NGLogicalOffset child_bfc_offset = curr_bfc_offset_; NGLogicalOffset child_bfc_offset = {
child_bfc_offset.inline_offset += ConstraintSpace().BfcOffset().inline_offset +
{border_and_padding_.inline_start + curr_child_margins_.inline_start}; border_and_padding_.inline_start + margins.inline_start,
bfc_block_offset};
bool is_new_fc = IsNewFormattingContextForBlockLevelChild(Style(), *child);
// Append the current margin strut with child's block start margin. // Append the current margin strut with child's block start margin.
// Non empty border/padding, and new FC use cases are handled inside of the // Non empty border/padding, and new FC use cases are handled inside of the
// child's layout. // child's layout.
if (!IsNewFormattingContextForBlockLevelChild(Style(), *child)) if (!is_new_fc)
curr_margin_strut_.Append(curr_child_margins_.block_start); margin_strut.Append(margins.block_start);
// TODO(crbug.com/716930): We should also collapse margins below once we // TODO(crbug.com/716930): We should also collapse margins below once we
// remove LayoutInline splitting. // remove LayoutInline splitting.
// Should collapse margins if our child is a legacy block. // Should collapse margins if our child is a legacy block.
if (IsLegacyBlock(*child)) { // TODO(ikilpatrick): I think this can be removed.
curr_bfc_offset_ += if (IsLegacyBlock(*child) && !is_new_fc) {
{border_and_padding_.inline_start + curr_child_margins_.inline_start, child_bfc_offset.block_offset += margin_strut.Sum();
curr_margin_strut_.Sum()}; MaybeUpdateFragmentBfcOffset(
MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, ConstraintSpace(), child_bfc_offset.block_offset, &container_builder_);
&container_builder_); // TODO(ikilpatrick): Check if child_bfc_offset.block_offset is correct -
PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, // MaybeUpdateFragmentBfcOffset might have changed it due to clearance.
PositionPendingFloats(child_bfc_offset.block_offset, &container_builder_,
MutableConstraintSpace()); MutableConstraintSpace());
curr_margin_strut_ = {}; margin_strut = {};
} }
child_bfc_offset.block_offset = curr_bfc_offset_.block_offset; return {child_bfc_offset, margin_strut, margins};
return child_bfc_offset;
} }
void NGBlockLayoutAlgorithm::FinishChildLayout( NGPreviousInflowPosition NGBlockLayoutAlgorithm::FinishChildLayout(
const NGConstraintSpace& child_space, const NGConstraintSpace& child_space,
const NGPreviousInflowPosition& previous_inflow_position,
const NGInflowChildData& child_data,
const NGLayoutInputNode* child, const NGLayoutInputNode* child,
NGLayoutResult* layout_result) { NGLayoutResult* layout_result) {
// Pull out unpositioned floats to the current fragment. This may needed if // Pull out unpositioned floats to the current fragment. This may needed if
...@@ -425,97 +458,134 @@ void NGBlockLayoutAlgorithm::FinishChildLayout( ...@@ -425,97 +458,134 @@ void NGBlockLayoutAlgorithm::FinishChildLayout(
// Determine the fragment's position in the parent space. // Determine the fragment's position in the parent space.
WTF::Optional<NGLogicalOffset> child_bfc_offset; WTF::Optional<NGLogicalOffset> child_bfc_offset;
if (child_space.IsNewFormattingContext()) if (child_space.IsNewFormattingContext())
child_bfc_offset = PositionNewFc(fragment, child_space); child_bfc_offset = PositionNewFc(*child, previous_inflow_position, fragment,
child_data, child_space);
else if (fragment.BfcOffset()) else if (fragment.BfcOffset())
child_bfc_offset = PositionWithBfcOffset(fragment); child_bfc_offset = PositionWithBfcOffset(fragment);
else if (IsLegacyBlock(*child)) else if (IsLegacyBlock(*child))
child_bfc_offset = PositionLegacy(child_space); child_bfc_offset = PositionLegacy(child_space, child_data);
else if (container_builder_.BfcOffset()) else if (container_builder_.BfcOffset())
child_bfc_offset = PositionWithParentBfc(child_space, fragment); child_bfc_offset = PositionWithParentBfc(child_space, child_data, fragment);
NGLogicalOffset logical_offset = CalculateLogicalOffset(child_bfc_offset); NGLogicalOffset logical_offset =
CalculateLogicalOffset(child_data.margins, child_bfc_offset);
// Update margin strut. NGMarginStrut margin_strut = fragment.EndMarginStrut();
curr_margin_strut_ = fragment.EndMarginStrut(); margin_strut.Append(child_data.margins.block_end);
curr_margin_strut_.Append(curr_child_margins_.block_end);
// Only modify content_size if BlockSize is not empty. It's needed to prevent // Only modify content_size_ if the fragment's BlockSize is not empty. This is
// the situation when logical_offset is included in content_size for empty // needed to prevent the situation when logical_offset is included in
// blocks. Example: // content_size_ for empty blocks. Example:
// <div style="overflow:hidden"> // <div style="overflow:hidden">
// <div style="margin-top: 8px"></div> // <div style="margin-top: 8px"></div>
// <div style="margin-top: 10px"></div> // <div style="margin-top: 10px"></div>
// </div> // </div>
if (fragment.BlockSize()) if (fragment.BlockSize())
content_size_ = fragment.BlockSize() + logical_offset.block_offset; content_size_ = std::max(
max_inline_size_ = content_size_, logical_offset.block_offset + fragment.BlockSize());
std::max(max_inline_size_, fragment.InlineSize() + max_inline_size_ = std::max(
curr_child_margins_.InlineSum() + max_inline_size_, fragment.InlineSize() + child_data.margins.InlineSum() +
border_and_padding_.InlineSum()); border_and_padding_.InlineSum());
container_builder_.AddChild(layout_result, logical_offset); container_builder_.AddChild(layout_result, logical_offset);
// Determine the child's end BFC block offset for the next child to use.
LayoutUnit child_end_bfc_block_offset;
if (child_bfc_offset) {
// TODO(crbug.com/716930): I think the fragment.BfcOffset() condition here
// can be removed once we've removed inline splitting.
if (fragment.BlockSize() || fragment.BfcOffset()) {
child_end_bfc_block_offset =
child_bfc_offset.value().block_offset + fragment.BlockSize();
} else {
DCHECK_EQ(LayoutUnit(), fragment.BlockSize());
child_end_bfc_block_offset = previous_inflow_position.bfc_block_offset;
}
} else {
child_end_bfc_block_offset = ConstraintSpace().BfcOffset().block_offset;
}
return {child_end_bfc_block_offset,
logical_offset.block_offset + fragment.BlockSize(), margin_strut};
} }
NGLogicalOffset NGBlockLayoutAlgorithm::PositionNewFc( NGLogicalOffset NGBlockLayoutAlgorithm::PositionNewFc(
const NGLayoutInputNode& child,
const NGPreviousInflowPosition& previous_inflow_position,
const NGBoxFragment& fragment, const NGBoxFragment& fragment,
const NGInflowChildData& child_data,
const NGConstraintSpace& child_space) { const NGConstraintSpace& child_space) {
const ComputedStyle& child_style = child.Style();
LayoutUnit child_bfc_offset_estimate =
child_data.bfc_offset_estimate.block_offset;
// 1. Position all pending floats to a temporary space. // 1. Position all pending floats to a temporary space.
RefPtr<NGConstraintSpace> tmp_space = RefPtr<NGConstraintSpace> tmp_space =
NGConstraintSpaceBuilder(&child_space) NGConstraintSpaceBuilder(&child_space)
.SetIsNewFormattingContext(false) .SetIsNewFormattingContext(false)
.ToConstraintSpace(child_space.WritingMode()); .ToConstraintSpace(child_space.WritingMode());
PositionFloats(curr_bfc_offset_.block_offset, curr_bfc_offset_.block_offset, PositionFloats(child_bfc_offset_estimate, child_bfc_offset_estimate,
curr_bfc_offset_.block_offset, child_bfc_offset_estimate,
container_builder_.UnpositionedFloats(), tmp_space.Get()); container_builder_.UnpositionedFloats(), tmp_space.Get());
NGLogicalOffset origin_offset = curr_bfc_offset_; NGLogicalOffset origin_offset = {ConstraintSpace().BfcOffset().inline_offset +
origin_offset.inline_offset += border_and_padding_.inline_start; border_and_padding_.inline_start,
child_bfc_offset_estimate};
AdjustToClearance(
GetClearanceOffset(ConstraintSpace().Exclusions(), child_style.Clear()),
&origin_offset);
// 2. Find an estimated layout opportunity for our fragment. // 2. Find an estimated layout opportunity for our fragment.
NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
tmp_space->Exclusions().get(), child_space.AvailableSize(), origin_offset, tmp_space->Exclusions().get(), child_space.AvailableSize(), origin_offset,
curr_child_margins_, fragment.Size()); child_data.margins, fragment.Size());
NGMarginStrut margin_strut = previous_inflow_position.margin_strut;
// 3. If the found opportunity lies on the same line with our estimated // 3. If the found opportunity lies on the same line with our estimated
// child's BFC offset then merge fragment's margins with the current // child's BFC offset then merge fragment's margins with the current
// MarginStrut. // MarginStrut.
if (opportunity.offset.block_offset == curr_bfc_offset_.block_offset) if (opportunity.offset.block_offset == child_bfc_offset_estimate)
curr_margin_strut_.Append(curr_child_margins_.block_start); margin_strut.Append(child_data.margins.block_start);
curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); child_bfc_offset_estimate += margin_strut.Sum();
curr_margin_strut_ = {};
// 4. The child's BFC block offset is known here. // 4. The child's BFC block offset is known here.
MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, MaybeUpdateFragmentBfcOffset(ConstraintSpace(), child_bfc_offset_estimate,
&container_builder_); &container_builder_);
PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, PositionPendingFloats(child_bfc_offset_estimate, &container_builder_,
MutableConstraintSpace()); MutableConstraintSpace());
origin_offset = curr_bfc_offset_; origin_offset = {ConstraintSpace().BfcOffset().inline_offset +
origin_offset.inline_offset += border_and_padding_.inline_start; border_and_padding_.inline_start,
child_bfc_offset_estimate};
AdjustToClearance(
GetClearanceOffset(ConstraintSpace().Exclusions(), child_style.Clear()),
&origin_offset);
// 5. Find the final layout opportunity for the fragment after all pending // 5. Find the final layout opportunity for the fragment after all pending
// floats are positioned at the correct BFC block's offset. // floats are positioned at the correct BFC block's offset.
opportunity = FindLayoutOpportunityForFragment( opportunity = FindLayoutOpportunityForFragment(
MutableConstraintSpace()->Exclusions().get(), child_space.AvailableSize(), MutableConstraintSpace()->Exclusions().get(), child_space.AvailableSize(),
origin_offset, curr_child_margins_, fragment.Size()); origin_offset, child_data.margins, fragment.Size());
curr_bfc_offset_ = opportunity.offset; return opportunity.offset;
return curr_bfc_offset_;
} }
NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithBfcOffset( NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithBfcOffset(
const NGBoxFragment& fragment) { const NGBoxFragment& fragment) {
DCHECK(fragment.BfcOffset()); DCHECK(fragment.BfcOffset());
curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; LayoutUnit bfc_block_offset = fragment.BfcOffset().value().block_offset;
MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_block_offset,
&container_builder_); &container_builder_);
PositionPendingFloats(curr_bfc_offset_.block_offset, &container_builder_, PositionPendingFloats(bfc_block_offset, &container_builder_,
MutableConstraintSpace()); MutableConstraintSpace());
return fragment.BfcOffset().value(); return fragment.BfcOffset().value();
} }
NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc( NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc(
const NGConstraintSpace& space, const NGConstraintSpace& space,
const NGInflowChildData& child_data,
const NGBoxFragment& fragment) { const NGBoxFragment& fragment) {
// The child must be an in-flow zero-block-size fragment, use its end margin // The child must be an in-flow zero-block-size fragment, use its end margin
// strut for positioning. // strut for positioning.
...@@ -523,22 +593,28 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc( ...@@ -523,22 +593,28 @@ NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc(
DCHECK_EQ(fragment.BlockSize(), LayoutUnit()); DCHECK_EQ(fragment.BlockSize(), LayoutUnit());
NGMarginStrut margin_strut = fragment.EndMarginStrut(); NGMarginStrut margin_strut = fragment.EndMarginStrut();
margin_strut.Append(curr_child_margins_.block_end); margin_strut.Append(child_data.margins.block_end);
curr_bfc_offset_ += NGLogicalOffset bfc_offset = {
{border_and_padding_.inline_start + curr_child_margins_.inline_start, ConstraintSpace().BfcOffset().inline_offset +
margin_strut.Sum()}; border_and_padding_.inline_start + child_data.margins.inline_start,
AdjustToClearance(space.ClearanceOffset(), &curr_bfc_offset_); child_data.bfc_offset_estimate.block_offset + margin_strut.Sum()};
PositionPendingFloatsFromOffset( AdjustToClearance(space.ClearanceOffset(), &bfc_offset);
curr_bfc_offset_.block_offset, curr_bfc_offset_.block_offset, PositionPendingFloatsFromOffset(bfc_offset.block_offset,
&container_builder_, MutableConstraintSpace()); bfc_offset.block_offset, &container_builder_,
return curr_bfc_offset_; MutableConstraintSpace());
return bfc_offset;
} }
NGLogicalOffset NGBlockLayoutAlgorithm::PositionLegacy( NGLogicalOffset NGBlockLayoutAlgorithm::PositionLegacy(
const NGConstraintSpace& child_space) { const NGConstraintSpace& child_space,
AdjustToClearance(child_space.ClearanceOffset(), &curr_bfc_offset_); const NGInflowChildData& child_data) {
return curr_bfc_offset_; NGLogicalOffset bfc_offset = {ConstraintSpace().BfcOffset().inline_offset +
border_and_padding_.inline_start +
child_data.margins.inline_start,
child_data.bfc_offset_estimate.block_offset};
AdjustToClearance(child_space.ClearanceOffset(), &bfc_offset);
return bfc_offset;
} }
void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
...@@ -609,8 +685,8 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(NGLayoutInputNode* child) { ...@@ -609,8 +685,8 @@ NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(NGLayoutInputNode* child) {
} }
RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
const NGLogicalOffset& child_bfc_offset, const NGLayoutInputNode& child,
const NGLayoutInputNode& child) { const NGInflowChildData& child_data) {
NGConstraintSpaceBuilder space_builder(MutableConstraintSpace()); NGConstraintSpaceBuilder space_builder(MutableConstraintSpace());
space_builder.SetAvailableSize(child_available_size_) space_builder.SetAvailableSize(child_available_size_)
.SetPercentageResolutionSize(child_percentage_size_); .SetPercentageResolutionSize(child_percentage_size_);
...@@ -618,8 +694,8 @@ RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( ...@@ -618,8 +694,8 @@ RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
const ComputedStyle& child_style = child.Style(); const ComputedStyle& child_style = child.Style();
bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child); bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child);
space_builder.SetIsNewFormattingContext(is_new_bfc) space_builder.SetIsNewFormattingContext(is_new_bfc)
.SetBfcOffset(child_bfc_offset) .SetBfcOffset(child_data.bfc_offset_estimate)
.SetMarginStrut(curr_margin_strut_); .SetMarginStrut(child_data.margin_strut);
if (!is_new_bfc) { if (!is_new_bfc) {
space_builder.SetUnpositionedFloats( space_builder.SetUnpositionedFloats(
...@@ -646,7 +722,7 @@ RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( ...@@ -646,7 +722,7 @@ RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
// position in the formatting context, and are able to adjust the // position in the formatting context, and are able to adjust the
// fragmentation line. // fragmentation line.
if (is_new_bfc) { if (is_new_bfc) {
space_available -= child_bfc_offset.block_offset; space_available -= child_data.bfc_offset_estimate.block_offset;
} }
} }
space_builder.SetFragmentainerSpaceAvailable(space_available); space_builder.SetFragmentainerSpaceAvailable(space_available);
......
...@@ -18,10 +18,12 @@ namespace blink { ...@@ -18,10 +18,12 @@ namespace blink {
class NGConstraintSpace; class NGConstraintSpace;
class NGLayoutResult; class NGLayoutResult;
struct NGInflowChildData;
struct NGPreviousInflowPosition;
// Updates the fragment's BFC offset if it's not already set. // Updates the fragment's BFC offset if it's not already set.
void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace&, void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace&,
const NGLogicalOffset&, LayoutUnit bfc_block_offset,
NGFragmentBuilder* builder); NGFragmentBuilder* builder);
// Positions pending floats starting from {@origin_block_offset} and relative // Positions pending floats starting from {@origin_block_offset} and relative
...@@ -52,13 +54,17 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -52,13 +54,17 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// Creates a new constraint space for the current child. // Creates a new constraint space for the current child.
RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild( RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild(
const NGLogicalOffset& child_bfc_offset, const NGLayoutInputNode& child,
const NGLayoutInputNode&); const NGInflowChildData& child_data);
// @return Estimated BFC offset for the "to be layout" child. // @return Estimated BFC offset for the "to be layout" child.
NGLogicalOffset PrepareChildLayout(NGLayoutInputNode*); NGInflowChildData PrepareChildLayout(const NGPreviousInflowPosition&,
NGLayoutInputNode*);
void FinishChildLayout(const NGConstraintSpace&, NGPreviousInflowPosition FinishChildLayout(
const NGConstraintSpace&,
const NGPreviousInflowPosition& prev_data,
const NGInflowChildData& child_data,
const NGLayoutInputNode* child, const NGLayoutInputNode* child,
NGLayoutResult*); NGLayoutResult*);
...@@ -81,7 +87,10 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -81,7 +87,10 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// then it will be placed there and we collapse its margin. // then it will be placed there and we collapse its margin.
// 2) If #new-fc is too big then we need to clear its position and place it // 2) If #new-fc is too big then we need to clear its position and place it
// below #float ignoring its vertical margin. // below #float ignoring its vertical margin.
NGLogicalOffset PositionNewFc(const NGBoxFragment&, NGLogicalOffset PositionNewFc(const NGLayoutInputNode& child,
const NGPreviousInflowPosition&,
const NGBoxFragment&,
const NGInflowChildData& child_data,
const NGConstraintSpace& child_space); const NGConstraintSpace& child_space);
// Positions the fragment that knows its BFC offset. // Positions the fragment that knows its BFC offset.
...@@ -95,12 +104,16 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -95,12 +104,16 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// <div style="padding: 1px"> // <div style="padding: 1px">
// <div id="empty-div" style="margins: 1px"></div> // <div id="empty-div" style="margins: 1px"></div>
NGLogicalOffset PositionWithParentBfc(const NGConstraintSpace&, NGLogicalOffset PositionWithParentBfc(const NGConstraintSpace&,
const NGInflowChildData& child_data,
const NGBoxFragment&); const NGBoxFragment&);
NGLogicalOffset PositionLegacy(const NGConstraintSpace& child_space); NGLogicalOffset PositionLegacy(const NGConstraintSpace& child_space,
const NGInflowChildData& child_data);
void HandleOutOfFlowPositioned(NGBlockNode*); void HandleOutOfFlowPositioned(const NGPreviousInflowPosition&, NGBlockNode*);
void HandleFloating(NGBlockNode*, NGBlockBreakToken*); void HandleFloating(const NGPreviousInflowPosition&,
NGBlockNode*,
NGBlockBreakToken*);
// Final adjustments before fragment creation. We need to prevent the // Final adjustments before fragment creation. We need to prevent the
// fragment from crossing fragmentainer boundaries, and rather create a break // fragment from crossing fragmentainer boundaries, and rather create a break
...@@ -112,6 +125,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -112,6 +125,7 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
// or {@code known_fragment_offset} if the fragment knows it's offset // or {@code known_fragment_offset} if the fragment knows it's offset
// @return Fragment's offset relative to the fragment's parent. // @return Fragment's offset relative to the fragment's parent.
NGLogicalOffset CalculateLogicalOffset( NGLogicalOffset CalculateLogicalOffset(
const NGBoxStrut& child_margins,
const WTF::Optional<NGLogicalOffset>& known_fragment_offset); const WTF::Optional<NGLogicalOffset>& known_fragment_offset);
NGLogicalSize child_available_size_; NGLogicalSize child_available_size_;
...@@ -120,10 +134,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm ...@@ -120,10 +134,6 @@ class CORE_EXPORT NGBlockLayoutAlgorithm
NGBoxStrut border_and_padding_; NGBoxStrut border_and_padding_;
LayoutUnit content_size_; LayoutUnit content_size_;
LayoutUnit max_inline_size_; LayoutUnit max_inline_size_;
// MarginStrut for the previous child.
NGMarginStrut curr_margin_strut_;
NGLogicalOffset curr_bfc_offset_;
NGBoxStrut curr_child_margins_;
}; };
} // namespace blink } // namespace blink
......
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