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_box.h" | 5 #include "core/layout/ng/ng_box.h" |
6 | 6 |
7 #include "core/layout/LayoutBlockFlow.h" | 7 #include "core/layout/LayoutBlockFlow.h" |
8 #include "core/layout/ng/layout_ng_block_flow.h" | 8 #include "core/layout/ng/layout_ng_block_flow.h" |
9 #include "core/layout/ng/ng_block_layout_algorithm.h" | 9 #include "core/layout/ng/ng_block_layout_algorithm.h" |
| 10 #include "core/layout/ng/ng_constraint_space_builder.h" |
10 #include "core/layout/ng/ng_constraint_space.h" | 11 #include "core/layout/ng/ng_constraint_space.h" |
11 #include "core/layout/ng/ng_direction.h" | 12 #include "core/layout/ng/ng_direction.h" |
12 #include "core/layout/ng/ng_fragment.h" | 13 #include "core/layout/ng/ng_fragment.h" |
13 #include "core/layout/ng/ng_fragment_builder.h" | 14 #include "core/layout/ng/ng_fragment_builder.h" |
14 #include "core/layout/ng/ng_length_utils.h" | 15 #include "core/layout/ng/ng_length_utils.h" |
15 #include "core/layout/ng/ng_writing_mode.h" | 16 #include "core/layout/ng/ng_writing_mode.h" |
16 | 17 |
17 namespace blink { | 18 namespace blink { |
18 | 19 |
19 NGBox::NGBox(LayoutObject* layout_object) | 20 NGBox::NGBox(LayoutObject* layout_object) |
20 : layout_box_(toLayoutBox(layout_object)) { | 21 : layout_box_(toLayoutBox(layout_object)) { |
21 DCHECK(layout_box_); | 22 DCHECK(layout_box_); |
22 } | 23 } |
23 | 24 |
24 NGBox::NGBox(ComputedStyle* style) : layout_box_(nullptr), style_(style) { | 25 NGBox::NGBox(ComputedStyle* style) : layout_box_(nullptr), style_(style) { |
25 DCHECK(style_); | 26 DCHECK(style_); |
26 } | 27 } |
27 | 28 |
28 bool NGBox::Layout(const NGConstraintSpace* constraint_space, | 29 bool NGBox::Layout(const NGConstraintSpace* constraint_space, |
29 NGFragment** out) { | 30 NGFragment** out) { |
| 31 DCHECK(!minmax_algorithm_) |
| 32 << "Can't interleave Layout and ComputeMinAndMaxContentSizes"; |
30 if (layout_box_ && layout_box_->isOutOfFlowPositioned()) | 33 if (layout_box_ && layout_box_->isOutOfFlowPositioned()) |
31 layout_box_->containingBlock()->insertPositionedObject(layout_box_); | 34 layout_box_->containingBlock()->insertPositionedObject(layout_box_); |
32 // We can either use the new layout code to do the layout and then copy the | 35 // We can either use the new layout code to do the layout and then copy the |
33 // resulting size to the LayoutObject, or use the old layout code and | 36 // resulting size to the LayoutObject, or use the old layout code and |
34 // synthesize a fragment. | 37 // synthesize a fragment. |
35 if (CanUseNewLayout()) { | 38 if (CanUseNewLayout()) { |
36 // Change the coordinate system of the constraint space. | 39 // Change the coordinate system of the constraint space. |
37 NGConstraintSpace* child_constraint_space = new NGConstraintSpace( | 40 NGConstraintSpace* child_constraint_space = new NGConstraintSpace( |
38 FromPlatformWritingMode(Style()->getWritingMode()), | 41 FromPlatformWritingMode(Style()->getWritingMode()), |
39 FromPlatformDirection(Style()->direction()), | 42 FromPlatformDirection(Style()->direction()), |
40 constraint_space->MutablePhysicalSpace()); | 43 constraint_space->MutablePhysicalSpace()); |
41 | 44 |
42 if (!algorithm_) | 45 if (!layout_algorithm_) |
43 algorithm_ = new NGBlockLayoutAlgorithm(Style(), FirstChild(), | 46 layout_algorithm_ = new NGBlockLayoutAlgorithm(Style(), FirstChild(), |
44 child_constraint_space); | 47 child_constraint_space); |
45 | 48 |
46 NGPhysicalFragment* fragment = nullptr; | 49 NGPhysicalFragment* fragment = nullptr; |
47 if (!algorithm_->Layout(&fragment)) | 50 if (!layout_algorithm_->Layout(&fragment)) |
48 return false; | 51 return false; |
49 fragment_ = fragment; | 52 fragment_ = fragment; |
50 | 53 |
51 if (layout_box_) { | 54 if (layout_box_) { |
52 CopyFragmentDataToLayoutBox(*constraint_space); | 55 CopyFragmentDataToLayoutBox(*constraint_space); |
53 } | 56 } |
54 } else { | 57 } else { |
55 DCHECK(layout_box_); | 58 DCHECK(layout_box_); |
56 fragment_ = RunOldLayout(*constraint_space); | 59 fragment_ = RunOldLayout(*constraint_space); |
57 } | 60 } |
58 *out = new NGFragment(constraint_space->WritingMode(), | 61 *out = new NGFragment(constraint_space->WritingMode(), |
59 FromPlatformDirection(Style()->direction()), | 62 FromPlatformDirection(Style()->direction()), |
60 fragment_.get()); | 63 fragment_.get()); |
61 // Reset algorithm for future use | 64 // Reset algorithm for future use |
62 algorithm_ = nullptr; | 65 layout_algorithm_ = nullptr; |
63 return true; | 66 return true; |
64 } | 67 } |
65 | 68 |
| 69 bool NGBox::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { |
| 70 DCHECK(!layout_algorithm_) |
| 71 << "Can't interleave Layout and ComputeMinAndMaxContentSizes"; |
| 72 if (!minmax_algorithm_) { |
| 73 NGConstraintSpaceBuilder builder( |
| 74 FromPlatformWritingMode(Style()->getWritingMode())); |
| 75 |
| 76 builder.SetContainerSize(NGLogicalSize(LayoutUnit(), LayoutUnit())); |
| 77 // TODO(layoutng): Use builder.ToConstraintSpace.ToLogicalConstraintSpace |
| 78 // once |
| 79 // that's available. |
| 80 NGConstraintSpace* constraint_space = new NGConstraintSpace( |
| 81 FromPlatformWritingMode(Style()->getWritingMode()), |
| 82 FromPlatformDirection(Style()->direction()), |
| 83 builder.ToConstraintSpace()); |
| 84 |
| 85 minmax_algorithm_ = |
| 86 new NGBlockLayoutAlgorithm(Style(), FirstChild(), constraint_space); |
| 87 } |
| 88 // TODO(cbiesinger): For orthogonal children, we need to always synthesize. |
| 89 NGLayoutAlgorithm::MinAndMaxState state = |
| 90 minmax_algorithm_->ComputeMinAndMaxContentSizes(sizes); |
| 91 if (state == NGLayoutAlgorithm::Success) |
| 92 return true; |
| 93 if (state == NGLayoutAlgorithm::Pending) |
| 94 return false; |
| 95 DCHECK_EQ(state, NGLayoutAlgorithm::NotImplemented); |
| 96 |
| 97 // TODO(cbiesinger): Replace the loops below with a state machine like in |
| 98 // Layout. |
| 99 |
| 100 // Have to synthesize this value. |
| 101 NGPhysicalFragment* physical_fragment; |
| 102 while (!minmax_algorithm_->Layout(&physical_fragment)) |
| 103 continue; |
| 104 NGFragment* fragment = new NGFragment( |
| 105 FromPlatformWritingMode(Style()->getWritingMode()), |
| 106 FromPlatformDirection(Style()->direction()), physical_fragment); |
| 107 |
| 108 sizes->min_content = fragment->InlineOverflow(); |
| 109 |
| 110 // Now, redo with infinite space for max_content |
| 111 NGConstraintSpaceBuilder builder( |
| 112 FromPlatformWritingMode(Style()->getWritingMode())); |
| 113 builder.SetContainerSize(NGLogicalSize(LayoutUnit::max(), LayoutUnit())); |
| 114 NGConstraintSpace* constraint_space = new NGConstraintSpace( |
| 115 FromPlatformWritingMode(Style()->getWritingMode()), |
| 116 FromPlatformDirection(Style()->direction()), builder.ToConstraintSpace()); |
| 117 |
| 118 minmax_algorithm_ = |
| 119 new NGBlockLayoutAlgorithm(Style(), FirstChild(), constraint_space); |
| 120 while (!minmax_algorithm_->Layout(&physical_fragment)) |
| 121 continue; |
| 122 |
| 123 fragment = new NGFragment(FromPlatformWritingMode(Style()->getWritingMode()), |
| 124 FromPlatformDirection(Style()->direction()), |
| 125 physical_fragment); |
| 126 sizes->max_content = fragment->InlineOverflow(); |
| 127 minmax_algorithm_ = nullptr; |
| 128 return true; |
| 129 } |
| 130 |
66 const ComputedStyle* NGBox::Style() const { | 131 const ComputedStyle* NGBox::Style() const { |
67 if (style_) | 132 if (style_) |
68 return style_.get(); | 133 return style_.get(); |
69 DCHECK(layout_box_); | 134 DCHECK(layout_box_); |
70 return layout_box_->style(); | 135 return layout_box_->style(); |
71 } | 136 } |
72 | 137 |
73 NGBox* NGBox::NextSibling() { | 138 NGBox* NGBox::NextSibling() { |
74 if (!next_sibling_) { | 139 if (!next_sibling_) { |
75 LayoutObject* next_sibling = | 140 LayoutObject* next_sibling = |
(...skipping 14 matching lines...) Expand all Loading... |
90 } | 155 } |
91 | 156 |
92 void NGBox::SetNextSibling(NGBox* sibling) { | 157 void NGBox::SetNextSibling(NGBox* sibling) { |
93 next_sibling_ = sibling; | 158 next_sibling_ = sibling; |
94 } | 159 } |
95 | 160 |
96 void NGBox::SetFirstChild(NGBox* child) { | 161 void NGBox::SetFirstChild(NGBox* child) { |
97 first_child_ = child; | 162 first_child_ = child; |
98 } | 163 } |
99 | 164 |
| 165 DEFINE_TRACE(NGBox) { |
| 166 visitor->trace(layout_algorithm_); |
| 167 visitor->trace(minmax_algorithm_); |
| 168 visitor->trace(fragment_); |
| 169 visitor->trace(next_sibling_); |
| 170 visitor->trace(first_child_); |
| 171 } |
| 172 |
100 void NGBox::PositionUpdated() { | 173 void NGBox::PositionUpdated() { |
101 if (!layout_box_) | 174 if (!layout_box_) |
102 return; | 175 return; |
103 DCHECK(layout_box_->parent()) << "Should be called on children only."; | 176 DCHECK(layout_box_->parent()) << "Should be called on children only."; |
104 | 177 |
105 layout_box_->setX(fragment_->LeftOffset()); | 178 layout_box_->setX(fragment_->LeftOffset()); |
106 layout_box_->setY(fragment_->TopOffset()); | 179 layout_box_->setY(fragment_->TopOffset()); |
107 | 180 |
108 if (layout_box_->isFloating() && layout_box_->parent()->isLayoutBlockFlow()) { | 181 if (layout_box_->isFloating() && layout_box_->parent()->isLayoutBlockFlow()) { |
109 FloatingObject* floating_object = toLayoutBlockFlow(layout_box_->parent()) | 182 FloatingObject* floating_object = toLayoutBlockFlow(layout_box_->parent()) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 .SetBlockSize(layout_box_->logicalHeight()) | 252 .SetBlockSize(layout_box_->logicalHeight()) |
180 .SetDirection(FromPlatformDirection(layout_box_->styleRef().direction())) | 253 .SetDirection(FromPlatformDirection(layout_box_->styleRef().direction())) |
181 .SetWritingMode( | 254 .SetWritingMode( |
182 FromPlatformWritingMode(layout_box_->styleRef().getWritingMode())) | 255 FromPlatformWritingMode(layout_box_->styleRef().getWritingMode())) |
183 .SetInlineOverflow(overflow.width()) | 256 .SetInlineOverflow(overflow.width()) |
184 .SetBlockOverflow(overflow.height()); | 257 .SetBlockOverflow(overflow.height()); |
185 return builder.ToFragment(); | 258 return builder.ToFragment(); |
186 } | 259 } |
187 | 260 |
188 } // namespace blink | 261 } // namespace blink |
OLD | NEW |