OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/layout/ng/ng_block_layout_algorithm.h" | 5 #include "core/layout/ng/ng_block_layout_algorithm.h" |
6 | 6 |
7 #include "core/layout/ng/inline/ng_inline_node.h" | 7 #include "core/layout/ng/inline/ng_inline_node.h" |
8 #include "core/layout/ng/ng_absolute_utils.h" | 8 #include "core/layout/ng/ng_absolute_utils.h" |
9 #include "core/layout/ng/ng_block_child_iterator.h" | 9 #include "core/layout/ng/ng_block_child_iterator.h" |
10 #include "core/layout/ng/ng_constraint_space.h" | 10 #include "core/layout/ng/ng_constraint_space.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 const auto& floating_objects = container_builder->UnpositionedFloats(); | 95 const auto& floating_objects = container_builder->UnpositionedFloats(); |
96 container_builder->MutablePositionedFloats().AppendVector(PositionFloats( | 96 container_builder->MutablePositionedFloats().AppendVector(PositionFloats( |
97 origin_block_offset, container_builder->BfcOffset().value().block_offset, | 97 origin_block_offset, container_builder->BfcOffset().value().block_offset, |
98 floating_objects, space)); | 98 floating_objects, space)); |
99 container_builder->MutableUnpositionedFloats().clear(); | 99 container_builder->MutableUnpositionedFloats().clear(); |
100 } | 100 } |
101 | 101 |
102 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode* node, | 102 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode* node, |
103 NGConstraintSpace* space, | 103 NGConstraintSpace* space, |
104 NGBlockBreakToken* break_token) | 104 NGBlockBreakToken* break_token) |
105 : NGLayoutAlgorithm(node, space, break_token), | 105 : NGLayoutAlgorithm(node, space, break_token) {} |
106 space_builder_(constraint_space_) {} | |
107 | 106 |
108 Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize() | 107 Optional<MinMaxContentSize> NGBlockLayoutAlgorithm::ComputeMinMaxContentSize() |
109 const { | 108 const { |
110 MinMaxContentSize sizes; | 109 MinMaxContentSize sizes; |
111 | 110 |
112 // Size-contained elements don't consider their contents for intrinsic sizing. | 111 // Size-contained elements don't consider their contents for intrinsic sizing. |
113 if (Style().ContainsSize()) | 112 if (Style().ContainsSize()) |
114 return sizes; | 113 return sizes; |
115 | 114 |
116 // TODO: handle floats & orthogonal children. | 115 // TODO: handle floats & orthogonal children. |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 | 167 |
169 // Our calculated block-axis size may be indefinite at this point. | 168 // Our calculated block-axis size may be indefinite at this point. |
170 // If so, just leave the size as NGSizeIndefinite instead of subtracting | 169 // If so, just leave the size as NGSizeIndefinite instead of subtracting |
171 // borders and padding. | 170 // borders and padding. |
172 NGLogicalSize adjusted_size(size); | 171 NGLogicalSize adjusted_size(size); |
173 if (size.block_size == NGSizeIndefinite) | 172 if (size.block_size == NGSizeIndefinite) |
174 adjusted_size.inline_size -= border_and_padding_.InlineSum(); | 173 adjusted_size.inline_size -= border_and_padding_.InlineSum(); |
175 else | 174 else |
176 adjusted_size -= border_and_padding_; | 175 adjusted_size -= border_and_padding_; |
177 | 176 |
178 space_builder_.SetAvailableSize(adjusted_size) | 177 child_available_size_ = adjusted_size; |
179 .SetPercentageResolutionSize(adjusted_size); | 178 child_percentage_size_ = adjusted_size; |
180 | 179 |
181 container_builder_.SetDirection(constraint_space_->Direction()); | 180 container_builder_.SetDirection(constraint_space_->Direction()); |
182 container_builder_.SetWritingMode(constraint_space_->WritingMode()); | 181 container_builder_.SetWritingMode(constraint_space_->WritingMode()); |
183 container_builder_.SetSize(size); | 182 container_builder_.SetSize(size); |
184 container_builder_.MutableUnpositionedFloats() = | 183 container_builder_.MutableUnpositionedFloats() = |
185 constraint_space_->UnpositionedFloats(); | 184 constraint_space_->UnpositionedFloats(); |
186 | 185 |
187 NGBlockChildIterator child_iterator(Node()->FirstChild(), BreakToken()); | 186 NGBlockChildIterator child_iterator(Node()->FirstChild(), BreakToken()); |
188 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); | 187 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); |
189 NGLayoutInputNode* child = entry.node; | 188 NGLayoutInputNode* child = entry.node; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 offset); | 233 offset); |
235 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); | 234 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); |
236 child = entry.node; | 235 child = entry.node; |
237 child_break_token = entry.token; | 236 child_break_token = entry.token; |
238 continue; | 237 continue; |
239 } | 238 } |
240 } | 239 } |
241 | 240 |
242 NGLogicalOffset child_bfc_offset = PrepareChildLayout(child); | 241 NGLogicalOffset child_bfc_offset = PrepareChildLayout(child); |
243 RefPtr<NGConstraintSpace> child_space = | 242 RefPtr<NGConstraintSpace> child_space = |
244 CreateConstraintSpaceForChild(child_bfc_offset, child); | 243 CreateConstraintSpaceForChild(child_bfc_offset, *child); |
245 RefPtr<NGLayoutResult> layout_result = | 244 RefPtr<NGLayoutResult> layout_result = |
246 child->Layout(child_space.Get(), child_break_token); | 245 child->Layout(child_space.Get(), child_break_token); |
247 | 246 |
248 if (child->IsFloating()) | 247 if (child->IsFloating()) |
249 FinishFloatChildLayout(child->Style(), *child_space, layout_result.Get()); | 248 FinishFloatChildLayout(child->Style(), *child_space, layout_result.Get()); |
250 else | 249 else |
251 FinishChildLayout(*child_space, child, layout_result.Get()); | 250 FinishChildLayout(*child_space, child, layout_result.Get()); |
252 | 251 |
253 entry = child_iterator.NextChild(); | 252 entry = child_iterator.NextChild(); |
254 child = entry.node; | 253 child = entry.node; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout( | 306 NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout( |
308 NGLayoutInputNode* child) { | 307 NGLayoutInputNode* child) { |
309 DCHECK(child); | 308 DCHECK(child); |
310 | 309 |
311 curr_bfc_offset_ = container_builder_.BfcOffset() | 310 curr_bfc_offset_ = container_builder_.BfcOffset() |
312 ? container_builder_.BfcOffset().value() | 311 ? container_builder_.BfcOffset().value() |
313 : ConstraintSpace().BfcOffset(); | 312 : ConstraintSpace().BfcOffset(); |
314 curr_bfc_offset_.block_offset += content_size_; | 313 curr_bfc_offset_.block_offset += content_size_; |
315 | 314 |
316 // Calculate margins in parent's writing mode. | 315 // Calculate margins in parent's writing mode. |
317 curr_child_margins_ = CalculateMargins( | 316 curr_child_margins_ = CalculateMargins(child); |
318 child, *space_builder_.ToConstraintSpace( | |
319 FromPlatformWritingMode(Style().GetWritingMode()))); | |
320 | 317 |
321 bool should_position_pending_floats = | 318 bool should_position_pending_floats = |
322 !child->IsFloating() && | 319 !child->IsFloating() && |
323 !IsNewFormattingContextForBlockLevelChild(Style(), *child) && | 320 !IsNewFormattingContextForBlockLevelChild(Style(), *child) && |
324 ClearanceMayAffectLayout(ConstraintSpace(), | 321 ClearanceMayAffectLayout(ConstraintSpace(), |
325 container_builder_.UnpositionedFloats(), | 322 container_builder_.UnpositionedFloats(), |
326 child->Style()); | 323 child->Style()); |
327 | 324 |
328 // Children which may clear a float need to force all the pending floats to | 325 // Children which may clear a float need to force all the pending floats to |
329 // be positioned before layout. This also resolves the fragment's bfc offset. | 326 // be positioned before layout. This also resolves the fragment's bfc offset. |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 container_builder_.SetBlockSize(space_left); | 550 container_builder_.SetBlockSize(space_left); |
554 container_builder_.SetBlockOverflow(space_left); | 551 container_builder_.SetBlockOverflow(space_left); |
555 return; | 552 return; |
556 } | 553 } |
557 | 554 |
558 // The end of the block fits in the current fragmentainer. | 555 // The end of the block fits in the current fragmentainer. |
559 container_builder_.SetBlockSize(block_size); | 556 container_builder_.SetBlockSize(block_size); |
560 container_builder_.SetBlockOverflow(content_size_); | 557 container_builder_.SetBlockOverflow(content_size_); |
561 } | 558 } |
562 | 559 |
563 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins( | 560 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(NGLayoutInputNode* child) { |
564 NGLayoutInputNode* child, | |
565 const NGConstraintSpace& space) { | |
566 DCHECK(child); | 561 DCHECK(child); |
567 if (child->IsInline()) | 562 if (child->IsInline()) |
568 return {}; | 563 return {}; |
569 const ComputedStyle& child_style = child->Style(); | 564 const ComputedStyle& child_style = child->Style(); |
570 | 565 |
571 WTF::Optional<MinMaxContentSize> sizes; | 566 RefPtr<NGConstraintSpace> space = |
572 if (NeedMinMaxContentSize(space, child_style)) | 567 NGConstraintSpaceBuilder(MutableConstraintSpace()) |
573 sizes = child->ComputeMinMaxContentSize(); | 568 .SetAvailableSize(child_available_size_) |
| 569 .SetPercentageResolutionSize(child_percentage_size_) |
| 570 .ToConstraintSpace(ConstraintSpace().WritingMode()); |
574 | 571 |
575 LayoutUnit child_inline_size = | 572 NGBoxStrut margins = ComputeMargins(*space, child_style, space->WritingMode(), |
576 ComputeInlineSizeForFragment(space, child_style, sizes); | 573 space->Direction()); |
577 NGBoxStrut margins = ComputeMargins(space, child_style, space.WritingMode(), | 574 |
578 space.Direction()); | 575 // TODO(ikilpatrick): Move the auto margins calculation for different writing |
| 576 // modes to post-layout. |
579 if (!child->IsFloating()) { | 577 if (!child->IsFloating()) { |
580 ApplyAutoMargins(space, child_style, child_inline_size, &margins); | 578 WTF::Optional<MinMaxContentSize> sizes; |
| 579 if (NeedMinMaxContentSize(*space, child_style)) |
| 580 sizes = child->ComputeMinMaxContentSize(); |
| 581 |
| 582 LayoutUnit child_inline_size = |
| 583 ComputeInlineSizeForFragment(*space, child_style, sizes); |
| 584 ApplyAutoMargins(*space, child_style, child_inline_size, &margins); |
581 } | 585 } |
582 return margins; | 586 return margins; |
583 } | 587 } |
584 | 588 |
585 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( | 589 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( |
586 const NGLogicalOffset& child_bfc_offset, | 590 const NGLogicalOffset& child_bfc_offset, |
587 NGLayoutInputNode* child) { | 591 const NGLayoutInputNode& child) { |
588 DCHECK(child); | 592 NGConstraintSpaceBuilder space_builder(MutableConstraintSpace()); |
| 593 space_builder.SetAvailableSize(child_available_size_) |
| 594 .SetPercentageResolutionSize(child_percentage_size_); |
589 | 595 |
590 const ComputedStyle& child_style = child->Style(); | 596 const ComputedStyle& child_style = child.Style(); |
591 bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), *child); | 597 bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child); |
592 space_builder_.SetIsNewFormattingContext(is_new_bfc) | 598 space_builder.SetIsNewFormattingContext(is_new_bfc) |
593 .SetBfcOffset(child_bfc_offset); | 599 .SetBfcOffset(child_bfc_offset); |
594 | 600 |
595 // Float's margins are not included in child's space because: | 601 // Float's margins are not included in child's space because: |
596 // 1) Floats do not participate in margins collapsing. | 602 // 1) Floats do not participate in margins collapsing. |
597 // 2) Floats margins are used separately to calculate floating exclusions. | 603 // 2) Floats margins are used separately to calculate floating exclusions. |
598 space_builder_.SetMarginStrut(child->IsFloating() ? NGMarginStrut() | 604 space_builder.SetMarginStrut(child.IsFloating() ? NGMarginStrut() |
599 : curr_margin_strut_); | 605 : curr_margin_strut_); |
600 | 606 |
601 if (!is_new_bfc) { | 607 if (!is_new_bfc) { |
602 space_builder_.SetUnpositionedFloats( | 608 space_builder.SetUnpositionedFloats( |
603 container_builder_.MutableUnpositionedFloats()); | 609 container_builder_.MutableUnpositionedFloats()); |
604 } | 610 } |
605 | 611 |
606 if (child->IsInline()) { | 612 if (child.IsInline()) { |
607 // TODO(kojii): Setup space_builder_ appropriately for inline child. | 613 // TODO(kojii): Setup space_builder appropriately for inline child. |
608 space_builder_.SetClearanceOffset(ConstraintSpace().ClearanceOffset()); | 614 space_builder.SetClearanceOffset(ConstraintSpace().ClearanceOffset()); |
609 return space_builder_.ToConstraintSpace( | 615 return space_builder.ToConstraintSpace( |
610 FromPlatformWritingMode(Style().GetWritingMode())); | 616 FromPlatformWritingMode(Style().GetWritingMode())); |
611 } | 617 } |
612 | 618 |
613 space_builder_ | 619 space_builder |
614 .SetClearanceOffset( | 620 .SetClearanceOffset( |
615 GetClearanceOffset(constraint_space_->Exclusions(), child_style)) | 621 GetClearanceOffset(constraint_space_->Exclusions(), child_style)) |
616 .SetIsShrinkToFit(ShouldShrinkToFit(Style(), child_style)) | 622 .SetIsShrinkToFit(ShouldShrinkToFit(Style(), child_style)) |
617 .SetTextDirection(child_style.Direction()); | 623 .SetTextDirection(child_style.Direction()); |
618 | 624 |
619 LayoutUnit space_available; | 625 LayoutUnit space_available; |
620 if (constraint_space_->HasBlockFragmentation()) { | 626 if (constraint_space_->HasBlockFragmentation()) { |
621 space_available = ConstraintSpace().FragmentainerSpaceAvailable(); | 627 space_available = ConstraintSpace().FragmentainerSpaceAvailable(); |
622 // If a block establishes a new formatting context we must know our | 628 // If a block establishes a new formatting context we must know our |
623 // position in the formatting context, and are able to adjust the | 629 // position in the formatting context, and are able to adjust the |
624 // fragmentation line. | 630 // fragmentation line. |
625 if (is_new_bfc) { | 631 if (is_new_bfc) { |
626 space_available -= child_bfc_offset.block_offset; | 632 space_available -= child_bfc_offset.block_offset; |
627 } | 633 } |
628 } | 634 } |
629 space_builder_.SetFragmentainerSpaceAvailable(space_available); | 635 space_builder.SetFragmentainerSpaceAvailable(space_available); |
630 | 636 |
631 return space_builder_.ToConstraintSpace( | 637 return space_builder.ToConstraintSpace( |
632 FromPlatformWritingMode(child_style.GetWritingMode())); | 638 FromPlatformWritingMode(child_style.GetWritingMode())); |
633 } | 639 } |
634 } // namespace blink | 640 } // namespace blink |
OLD | NEW |