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/ng_absolute_utils.h" | 7 #include "core/layout/ng/ng_absolute_utils.h" |
8 #include "core/layout/ng/ng_block_break_token.h" | 8 #include "core/layout/ng/ng_block_break_token.h" |
9 #include "core/layout/ng/ng_box_fragment.h" | 9 #include "core/layout/ng/ng_box_fragment.h" |
10 #include "core/layout/ng/ng_column_mapper.h" | 10 #include "core/layout/ng/ng_column_mapper.h" |
11 #include "core/layout/ng/ng_constraint_space.h" | 11 #include "core/layout/ng/ng_constraint_space.h" |
12 #include "core/layout/ng/ng_constraint_space_builder.h" | 12 #include "core/layout/ng/ng_constraint_space_builder.h" |
13 #include "core/layout/ng/ng_fragment.h" | 13 #include "core/layout/ng/ng_fragment.h" |
14 #include "core/layout/ng/ng_fragment_builder.h" | 14 #include "core/layout/ng/ng_fragment_builder.h" |
15 #include "core/layout/ng/ng_inline_node.h" | 15 #include "core/layout/ng/ng_inline_node.h" |
16 #include "core/layout/ng/ng_layout_opportunity_iterator.h" | 16 #include "core/layout/ng/ng_layout_opportunity_iterator.h" |
17 #include "core/layout/ng/ng_length_utils.h" | 17 #include "core/layout/ng/ng_length_utils.h" |
18 #include "core/layout/ng/ng_line_builder.h" | 18 #include "core/layout/ng/ng_line_builder.h" |
19 #include "core/layout/ng/ng_out_of_flow_layout_part.h" | 19 #include "core/layout/ng/ng_out_of_flow_layout_part.h" |
20 #include "core/layout/ng/ng_units.h" | 20 #include "core/layout/ng/ng_units.h" |
21 #include "core/style/ComputedStyle.h" | 21 #include "core/style/ComputedStyle.h" |
22 #include "platform/LengthFunctions.h" | 22 #include "platform/LengthFunctions.h" |
23 #include "wtf/Optional.h" | 23 #include "wtf/Optional.h" |
24 | 24 |
25 namespace blink { | 25 namespace blink { |
26 namespace { | 26 namespace { |
27 | 27 |
| 28 // Whether child's constraint space should shrink to its intrinsic width. |
| 29 // This is needed for buttons, select, input, floats and orthogonal children. |
| 30 // See LayoutBox::sizesLogicalWidthToFitContent for the rationale behind this. |
| 31 bool ShouldShrinkToFit(const NGConstraintSpace& parent_space, |
| 32 const ComputedStyle& child_style) { |
| 33 NGWritingMode child_writing_mode = |
| 34 FromPlatformWritingMode(child_style.getWritingMode()); |
| 35 // Whether the child and the containing block are parallel to each other. |
| 36 // Example: vertical-rl and vertical-lr |
| 37 bool is_in_parallel_flow = |
| 38 (parent_space.WritingMode() == kHorizontalTopBottom) == |
| 39 (child_writing_mode == kHorizontalTopBottom); |
| 40 |
| 41 return child_style.display() == EDisplay::InlineBlock || |
| 42 child_style.isFloating() || !is_in_parallel_flow; |
| 43 } |
| 44 |
28 // Updates the fragment's BFC offset if it's not already set. | 45 // Updates the fragment's BFC offset if it's not already set. |
29 void UpdateFragmentBfcOffset(const NGLogicalOffset& offset, | 46 void UpdateFragmentBfcOffset(const NGLogicalOffset& offset, |
30 const NGConstraintSpace& space, | 47 const NGConstraintSpace& space, |
31 NGFragmentBuilder* builder) { | 48 NGFragmentBuilder* builder) { |
32 NGLogicalOffset fragment_offset = | 49 NGLogicalOffset fragment_offset = |
33 space.IsNewFormattingContext() ? NGLogicalOffset() : offset; | 50 space.IsNewFormattingContext() ? space.BfcOffset() : offset; |
34 if (!builder->BfcOffset()) | 51 if (!builder->BfcOffset()) |
35 builder->SetBfcOffset(fragment_offset); | 52 builder->SetBfcOffset(fragment_offset); |
36 } | 53 } |
37 | 54 |
38 // Adjusts content_size to respect the CSS "clear" property. | 55 // Adjusts content_size to respect the CSS "clear" property. |
39 // Picks up the maximum between left/right exclusions and content_size depending | 56 // Picks up the maximum between left/right exclusions and content_size depending |
40 // on the value of style.clear() property. | 57 // on the value of style.clear() property. |
41 void AdjustToClearance(const std::shared_ptr<NGExclusions>& exclusions, | 58 void AdjustToClearance(const std::shared_ptr<NGExclusions>& exclusions, |
42 const ComputedStyle& style, | 59 const ComputedStyle& style, |
43 const NGLogicalOffset& from_offset, | 60 const NGLogicalOffset& from_offset, |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 content_size_ = border_and_padding_.block_start; | 389 content_size_ = border_and_padding_.block_start; |
373 current_child_ = first_child_; | 390 current_child_ = first_child_; |
374 } | 391 } |
375 | 392 |
376 curr_margin_strut_ = ConstraintSpace().MarginStrut(); | 393 curr_margin_strut_ = ConstraintSpace().MarginStrut(); |
377 curr_bfc_offset_ = ConstraintSpace().BfcOffset(); | 394 curr_bfc_offset_ = ConstraintSpace().BfcOffset(); |
378 | 395 |
379 // Margins collapsing: | 396 // Margins collapsing: |
380 // Do not collapse margins between parent and its child if there is | 397 // Do not collapse margins between parent and its child if there is |
381 // border/padding between them. | 398 // border/padding between them. |
382 if (border_and_padding_.block_start) { | 399 if (border_and_padding_.block_start || |
| 400 ConstraintSpace().IsNewFormattingContext()) { |
383 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); | 401 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); |
384 builder_->SetBfcOffset(curr_bfc_offset_); | 402 builder_->SetBfcOffset(curr_bfc_offset_); |
385 curr_margin_strut_ = NGMarginStrut(); | 403 curr_margin_strut_ = NGMarginStrut(); |
386 } | 404 } |
387 curr_bfc_offset_.block_offset += content_size_; | 405 curr_bfc_offset_.block_offset += content_size_; |
388 | 406 |
389 while (current_child_) { | 407 while (current_child_) { |
390 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock) { | 408 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock) { |
391 NGBlockNode* current_block_child = toNGBlockNode(current_child_); | 409 NGBlockNode* current_block_child = toNGBlockNode(current_child_); |
392 EPosition position = current_block_child->Style().position(); | 410 EPosition position = current_block_child->Style().position(); |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 NGBoxStrut margins = | 713 NGBoxStrut margins = |
696 ComputeMargins(space, style, space.WritingMode(), space.Direction()); | 714 ComputeMargins(space, style, space.WritingMode(), space.Direction()); |
697 if (!style.isFloating()) { | 715 if (!style.isFloating()) { |
698 ApplyAutoMargins(space, style, child_inline_size, &margins); | 716 ApplyAutoMargins(space, style, child_inline_size, &margins); |
699 } | 717 } |
700 return margins; | 718 return margins; |
701 } | 719 } |
702 | 720 |
703 NGConstraintSpace* | 721 NGConstraintSpace* |
704 NGBlockLayoutAlgorithm::CreateConstraintSpaceForCurrentChild() { | 722 NGBlockLayoutAlgorithm::CreateConstraintSpaceForCurrentChild() { |
705 // TODO(layout-ng): Orthogonal children should also shrink to fit (in *their* | |
706 // inline axis) | |
707 DCHECK(current_child_); | 723 DCHECK(current_child_); |
708 if (current_child_->Type() == NGLayoutInputNode::kLegacyInline) { | 724 if (current_child_->Type() == NGLayoutInputNode::kLegacyInline) { |
709 // TODO(kojii): Setup space_builder_ appropriately for inline child. | 725 // TODO(kojii): Setup space_builder_ appropriately for inline child. |
710 return space_builder_->ToConstraintSpace(); | 726 return space_builder_->ToConstraintSpace(); |
| 727 // Calculate margins in parent's writing mode. |
711 } | 728 } |
| 729 curr_child_margins_ = CalculateMargins(*space_builder_->ToConstraintSpace(), |
| 730 CurrentChildStyle()); |
712 | 731 |
713 const ComputedStyle& current_child_style = CurrentChildStyle(); | 732 const ComputedStyle& current_child_style = CurrentChildStyle(); |
714 bool shrink_to_fit = current_child_style.display() == EDisplay::InlineBlock || | |
715 current_child_style.isFloating(); | |
716 bool is_new_bfc = IsNewFormattingContextForInFlowBlockLevelChild( | 733 bool is_new_bfc = IsNewFormattingContextForInFlowBlockLevelChild( |
717 ConstraintSpace(), current_child_style); | 734 ConstraintSpace(), current_child_style); |
718 space_builder_->SetIsNewFormattingContext(is_new_bfc) | 735 space_builder_->SetIsNewFormattingContext(is_new_bfc) |
719 .SetIsShrinkToFit(shrink_to_fit) | 736 .SetIsShrinkToFit( |
| 737 ShouldShrinkToFit(ConstraintSpace(), CurrentChildStyle())) |
720 .SetWritingMode( | 738 .SetWritingMode( |
721 FromPlatformWritingMode(current_child_style.getWritingMode())) | 739 FromPlatformWritingMode(current_child_style.getWritingMode())) |
722 .SetTextDirection(current_child_style.direction()); | 740 .SetTextDirection(current_child_style.direction()); |
723 LayoutUnit space_available = SpaceAvailableForCurrentChild(); | 741 LayoutUnit space_available = SpaceAvailableForCurrentChild(); |
724 space_builder_->SetFragmentainerSpaceAvailable(space_available); | 742 space_builder_->SetFragmentainerSpaceAvailable(space_available); |
725 | 743 |
726 curr_child_margins_ = CalculateMargins(*space_builder_->ToConstraintSpace(), | |
727 current_child_style); | |
728 | |
729 // Clearance : | 744 // Clearance : |
730 // - Collapse margins | 745 // - Collapse margins |
731 // - Update curr_bfc_offset and parent BFC offset if needed. | 746 // - Update curr_bfc_offset and parent BFC offset if needed. |
732 // - Position all pending floats as position is known now. | 747 // - Position all pending floats as position is known now. |
733 // TODO(glebl): Fix the use case with clear: left and an intruding right. | 748 // TODO(glebl): Fix the use case with clear: left and an intruding right. |
734 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847 | 749 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847 |
735 if (current_child_style.clear() != EClear::kNone) { | 750 if (current_child_style.clear() != EClear::kNone) { |
736 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); | 751 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); |
737 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), | 752 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), |
738 builder_.get()); | 753 builder_.get()); |
(...skipping 20 matching lines...) Expand all Loading... |
759 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; | 774 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; |
760 if (ConstraintSpace().IsNewFormattingContext()) { | 775 if (ConstraintSpace().IsNewFormattingContext()) { |
761 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; | 776 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; |
762 } | 777 } |
763 space_builder_->SetBfcOffset(curr_bfc_offset_); | 778 space_builder_->SetBfcOffset(curr_bfc_offset_); |
764 | 779 |
765 return space_builder_->ToConstraintSpace(); | 780 return space_builder_->ToConstraintSpace(); |
766 } | 781 } |
767 | 782 |
768 } // namespace blink | 783 } // namespace blink |
OLD | NEW |