| 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_block_child_iterator.h" | 9 #include "core/layout/ng/ng_block_child_iterator.h" |
| 10 #include "core/layout/ng/ng_box_fragment.h" | 10 #include "core/layout/ng/ng_box_fragment.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_floats_utils.h" | 13 #include "core/layout/ng/ng_floats_utils.h" |
| 14 #include "core/layout/ng/ng_fragment.h" | 14 #include "core/layout/ng/ng_fragment.h" |
| 15 #include "core/layout/ng/ng_fragment_builder.h" | 15 #include "core/layout/ng/ng_fragment_builder.h" |
| 16 #include "core/layout/ng/ng_inline_node.h" | 16 #include "core/layout/ng/ng_inline_node.h" |
| 17 #include "core/layout/ng/ng_layout_opportunity_iterator.h" | 17 #include "core/layout/ng/ng_layout_opportunity_iterator.h" |
| 18 #include "core/layout/ng/ng_length_utils.h" | 18 #include "core/layout/ng/ng_length_utils.h" |
| 19 #include "core/layout/ng/ng_line_builder.h" | 19 #include "core/layout/ng/ng_line_builder.h" |
| 20 #include "core/layout/ng/ng_out_of_flow_layout_part.h" | 20 #include "core/layout/ng/ng_out_of_flow_layout_part.h" |
| 21 #include "core/layout/ng/ng_space_utils.h" |
| 21 #include "core/style/ComputedStyle.h" | 22 #include "core/style/ComputedStyle.h" |
| 22 #include "platform/LengthFunctions.h" | 23 #include "platform/LengthFunctions.h" |
| 23 #include "wtf/Optional.h" | 24 #include "wtf/Optional.h" |
| 24 | 25 |
| 25 namespace blink { | 26 namespace blink { |
| 26 namespace { | 27 namespace { |
| 27 | 28 |
| 28 // Whether child's constraint space should shrink to its intrinsic width. | 29 // Whether child's constraint space should shrink to its intrinsic width. |
| 29 // This is needed for buttons, select, input, floats and orthogonal children. | 30 // This is needed for buttons, select, input, floats and orthogonal children. |
| 30 // See LayoutBox::sizesLogicalWidthToFitContent for the rationale behind this. | 31 // See LayoutBox::sizesLogicalWidthToFitContent for the rationale behind this. |
| 31 bool ShouldShrinkToFit(const NGConstraintSpace& parent_space, | 32 bool ShouldShrinkToFit(const NGConstraintSpace& parent_space, |
| 32 const ComputedStyle& child_style) { | 33 const ComputedStyle& child_style) { |
| 33 NGWritingMode child_writing_mode = | 34 NGWritingMode child_writing_mode = |
| 34 FromPlatformWritingMode(child_style.getWritingMode()); | 35 FromPlatformWritingMode(child_style.getWritingMode()); |
| 35 // Whether the child and the containing block are parallel to each other. | 36 // Whether the child and the containing block are parallel to each other. |
| 36 // Example: vertical-rl and vertical-lr | 37 // Example: vertical-rl and vertical-lr |
| 37 bool is_in_parallel_flow = | 38 bool is_in_parallel_flow = |
| 38 IsParallelWritingMode(parent_space.WritingMode(), child_writing_mode); | 39 IsParallelWritingMode(parent_space.WritingMode(), child_writing_mode); |
| 39 | 40 |
| 40 return child_style.display() == EDisplay::kInlineBlock || | 41 return child_style.display() == EDisplay::kInlineBlock || |
| 41 child_style.isFloating() || !is_in_parallel_flow; | 42 child_style.isFloating() || !is_in_parallel_flow; |
| 42 } | 43 } |
| 43 | 44 |
| 44 // Returns max of 2 {@code WTF::Optional} values. | |
| 45 template <typename T> | |
| 46 WTF::Optional<T> OptionalMax(const WTF::Optional<T>& value1, | |
| 47 const WTF::Optional<T>& value2) { | |
| 48 if (value1 && value2) { | |
| 49 return std::max(value1.value(), value2.value()); | |
| 50 } else if (value1) { | |
| 51 return value1; | |
| 52 } | |
| 53 return value2; | |
| 54 } | |
| 55 | |
| 56 WTF::Optional<LayoutUnit> GetClearanceOffset( | |
| 57 const std::shared_ptr<NGExclusions>& exclusions, | |
| 58 const ComputedStyle& style) { | |
| 59 const NGExclusion* right_exclusion = exclusions->last_right_float; | |
| 60 const NGExclusion* left_exclusion = exclusions->last_left_float; | |
| 61 | |
| 62 WTF::Optional<LayoutUnit> left_offset; | |
| 63 if (left_exclusion) { | |
| 64 left_offset = left_exclusion->rect.BlockEndOffset(); | |
| 65 } | |
| 66 WTF::Optional<LayoutUnit> right_offset; | |
| 67 if (right_exclusion) { | |
| 68 right_offset = right_exclusion->rect.BlockEndOffset(); | |
| 69 } | |
| 70 | |
| 71 switch (style.clear()) { | |
| 72 case EClear::kNone: | |
| 73 return WTF::nullopt; // nothing to do here. | |
| 74 case EClear::kLeft: | |
| 75 return left_offset; | |
| 76 case EClear::kRight: | |
| 77 return right_offset; | |
| 78 case EClear::kBoth: | |
| 79 return OptionalMax<LayoutUnit>(left_offset, right_offset); | |
| 80 default: | |
| 81 ASSERT_NOT_REACHED(); | |
| 82 } | |
| 83 return WTF::nullopt; | |
| 84 } | |
| 85 | |
| 86 // Positions pending floats stored on the fragment builder starting from | 45 // Positions pending floats stored on the fragment builder starting from |
| 87 // {@code origin_point_block_offset}. | 46 // {@code origin_point_block_offset}. |
| 88 void PositionPendingFloats(const LayoutUnit origin_point_block_offset, | 47 void PositionPendingFloats(const LayoutUnit origin_point_block_offset, |
| 89 NGConstraintSpace* new_parent_space, | 48 NGConstraintSpace* new_parent_space, |
| 90 NGFragmentBuilder* builder) { | 49 NGFragmentBuilder* builder) { |
| 91 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here"; | 50 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here"; |
| 92 LayoutUnit bfc_block_offset = builder->BfcOffset().value().block_offset; | 51 LayoutUnit bfc_block_offset = builder->BfcOffset().value().block_offset; |
| 93 | 52 |
| 94 for (auto& floating_object : builder->UnpositionedFloats()) { | 53 for (auto& floating_object : builder->UnpositionedFloats()) { |
| 95 const auto* float_space = floating_object->space.get(); | 54 const auto* float_space = floating_object->space.get(); |
| 96 const NGConstraintSpace* original_parent_space = | 55 const NGConstraintSpace* original_parent_space = |
| 97 floating_object->original_parent_space.get(); | 56 floating_object->original_parent_space.get(); |
| 98 | 57 |
| 99 NGLogicalOffset origin_point = {float_space->BfcOffset().inline_offset, | 58 NGLogicalOffset origin_point = {float_space->BfcOffset().inline_offset, |
| 100 origin_point_block_offset}; | 59 origin_point_block_offset}; |
| 101 NGLogicalOffset from_offset = { | 60 NGLogicalOffset from_offset = { |
| 102 original_parent_space->BfcOffset().inline_offset, bfc_block_offset}; | 61 original_parent_space->BfcOffset().inline_offset, bfc_block_offset}; |
| 103 | 62 |
| 104 NGLogicalOffset float_fragment_offset = PositionFloat( | 63 NGLogicalOffset float_fragment_offset = PositionFloat( |
| 105 origin_point, from_offset, floating_object.get(), new_parent_space); | 64 origin_point, from_offset, floating_object.get(), new_parent_space); |
| 106 builder->AddFloatingObject(floating_object, float_fragment_offset); | 65 builder->AddFloatingObject(floating_object, float_fragment_offset); |
| 107 } | 66 } |
| 108 builder->MutableUnpositionedFloats().clear(); | 67 builder->MutableUnpositionedFloats().clear(); |
| 109 } | 68 } |
| 110 | 69 |
| 111 // Whether an in-flow block-level child creates a new formatting context. | |
| 112 // | |
| 113 // This will *NOT* check the following cases: | |
| 114 // - The child is out-of-flow, e.g. floating or abs-pos. | |
| 115 // - The child is a inline-level, e.g. "display: inline-block". | |
| 116 // - The child establishes a new formatting context, but should be a child of | |
| 117 // another layout algorithm, e.g. "display: table-caption" or flex-item. | |
| 118 bool IsNewFormattingContextForInFlowBlockLevelChild( | |
| 119 const NGConstraintSpace& space, | |
| 120 const ComputedStyle& style) { | |
| 121 // TODO(layout-dev): This doesn't capture a few cases which can't be computed | |
| 122 // directly from style yet: | |
| 123 // - The child is a <fieldset>. | |
| 124 // - "column-span: all" is set on the child (requires knowledge that we are | |
| 125 // in a multi-col formatting context). | |
| 126 // (https://drafts.csswg.org/css-multicol-1/#valdef-column-span-all) | |
| 127 | |
| 128 if (style.specifiesColumns() || style.containsPaint() || | |
| 129 style.containsLayout()) | |
| 130 return true; | |
| 131 | |
| 132 if (!style.isOverflowVisible()) | |
| 133 return true; | |
| 134 | |
| 135 EDisplay display = style.display(); | |
| 136 if (display == EDisplay::kGrid || display == EDisplay::kFlex || | |
| 137 display == EDisplay::kWebkitBox) | |
| 138 return true; | |
| 139 | |
| 140 if (space.WritingMode() != FromPlatformWritingMode(style.getWritingMode())) | |
| 141 return true; | |
| 142 | |
| 143 return false; | |
| 144 } | |
| 145 | |
| 146 // Whether we've run out of space in this flow. If so, there will be no work | 70 // Whether we've run out of space in this flow. If so, there will be no work |
| 147 // left to do for this block in this fragmentainer. | 71 // left to do for this block in this fragmentainer. |
| 148 bool IsOutOfSpace(const NGConstraintSpace& space, LayoutUnit content_size) { | 72 bool IsOutOfSpace(const NGConstraintSpace& space, LayoutUnit content_size) { |
| 149 return space.HasBlockFragmentation() && | 73 return space.HasBlockFragmentation() && |
| 150 content_size >= space.FragmentainerSpaceAvailable(); | 74 content_size >= space.FragmentainerSpaceAvailable(); |
| 151 } | 75 } |
| 152 | 76 |
| 153 } // namespace | 77 } // namespace |
| 154 | 78 |
| 155 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( | 79 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( |
| (...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 DCHECK(builder_.BfcOffset()); | 527 DCHECK(builder_.BfcOffset()); |
| 604 space_available -= curr_bfc_offset_.block_offset; | 528 space_available -= curr_bfc_offset_.block_offset; |
| 605 } | 529 } |
| 606 } | 530 } |
| 607 space_builder_.SetFragmentainerSpaceAvailable(space_available); | 531 space_builder_.SetFragmentainerSpaceAvailable(space_available); |
| 608 | 532 |
| 609 return space_builder_.ToConstraintSpace( | 533 return space_builder_.ToConstraintSpace( |
| 610 FromPlatformWritingMode(child_style.getWritingMode())); | 534 FromPlatformWritingMode(child_style.getWritingMode())); |
| 611 } | 535 } |
| 612 } // namespace blink | 536 } // namespace blink |
| OLD | NEW |