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_node.h" | 5 #include "core/layout/ng/ng_block_node.h" |
6 | 6 |
7 #include "core/layout/LayoutBlockFlow.h" | 7 #include "core/layout/LayoutBlockFlow.h" |
8 #include "core/layout/api/LineLayoutAPIShim.h" | 8 #include "core/layout/api/LineLayoutAPIShim.h" |
9 #include "core/layout/line/InlineIterator.h" | 9 #include "core/layout/line/InlineIterator.h" |
10 #include "core/layout/ng/layout_ng_block_flow.h" | 10 #include "core/layout/ng/layout_ng_block_flow.h" |
11 #include "core/layout/ng/ng_block_layout_algorithm.h" | 11 #include "core/layout/ng/ng_block_layout_algorithm.h" |
12 #include "core/layout/ng/ng_box_fragment.h" | 12 #include "core/layout/ng/ng_box_fragment.h" |
13 #include "core/layout/ng/ng_constraint_space.h" | 13 #include "core/layout/ng/ng_constraint_space.h" |
14 #include "core/layout/ng/ng_constraint_space_builder.h" | 14 #include "core/layout/ng/ng_constraint_space_builder.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_coordinator.h" | |
18 #include "core/layout/ng/ng_length_utils.h" | 17 #include "core/layout/ng/ng_length_utils.h" |
19 #include "core/layout/ng/ng_writing_mode.h" | 18 #include "core/layout/ng/ng_writing_mode.h" |
20 #include "core/paint/PaintLayer.h" | 19 #include "core/paint/PaintLayer.h" |
21 #include "platform/RuntimeEnabledFeatures.h" | 20 #include "platform/RuntimeEnabledFeatures.h" |
22 | 21 |
23 namespace blink { | 22 namespace blink { |
24 | 23 |
25 NGBlockNode::NGBlockNode(LayoutObject* layout_object) | 24 NGBlockNode::NGBlockNode(LayoutObject* layout_object) |
26 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), | 25 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), |
27 layout_box_(toLayoutBox(layout_object)) { | 26 layout_box_(toLayoutBox(layout_object)) { |
28 DCHECK(layout_box_); | 27 DCHECK(layout_box_); |
29 } | 28 } |
30 | 29 |
31 NGBlockNode::NGBlockNode(ComputedStyle* style) | 30 NGBlockNode::NGBlockNode(ComputedStyle* style) |
32 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), | 31 : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), |
33 layout_box_(nullptr), | 32 layout_box_(nullptr), |
34 style_(style) { | 33 style_(style) { |
35 DCHECK(style_); | 34 DCHECK(style_); |
36 } | 35 } |
37 | 36 |
38 // Need an explicit destructor in the .cc file, or the MSWIN compiler will | 37 // Need an explicit destructor in the .cc file, or the MSWIN compiler will |
39 // produce an error when attempting to generate a default one, if the .h file is | 38 // produce an error when attempting to generate a default one, if the .h file is |
40 // included from a compilation unit that lacks the ComputedStyle definition. | 39 // included from a compilation unit that lacks the ComputedStyle definition. |
41 NGBlockNode::~NGBlockNode() {} | 40 NGBlockNode::~NGBlockNode() {} |
42 | 41 |
43 void NGBlockNode::LayoutSync(NGConstraintSpace* constraint_space, | 42 NGPhysicalFragment* NGBlockNode::Layout(NGConstraintSpace* constraint_space) { |
44 NGFragment** out) { | |
45 while (!Layout(constraint_space, out)) | |
46 continue; | |
47 } | |
48 | |
49 bool NGBlockNode::Layout(NGConstraintSpace* constraint_space, | |
50 NGFragment** out) { | |
51 // We can either use the new layout code to do the layout and then copy the | 43 // We can either use the new layout code to do the layout and then copy the |
52 // resulting size to the LayoutObject, or use the old layout code and | 44 // resulting size to the LayoutObject, or use the old layout code and |
53 // synthesize a fragment. | 45 // synthesize a fragment. |
54 if (CanUseNewLayout()) { | 46 if (CanUseNewLayout()) { |
55 NGPhysicalFragment* fragment; | 47 NGLayoutAlgorithm* algorithm = |
56 | 48 NGLayoutInputNode::AlgorithmForInputNode(this, constraint_space); |
57 // Store a coordinator so Layout can preserve its existing semantic | 49 fragment_ = toNGPhysicalBoxFragment(algorithm->Layout()); |
58 // of returning false until completed. | 50 CopyFragmentDataToLayoutBox(*constraint_space); |
59 if (!layout_coordinator_) | |
60 layout_coordinator_ = new NGLayoutCoordinator(this, constraint_space); | |
61 | |
62 if (!layout_coordinator_->Tick(&fragment)) | |
63 return false; | |
64 | |
65 fragment_ = toNGPhysicalBoxFragment(fragment); | |
66 | |
67 UpdateLayoutBox(fragment_, constraint_space); | |
68 } else { | 51 } else { |
69 DCHECK(layout_box_); | 52 DCHECK(layout_box_); |
70 fragment_ = RunOldLayout(*constraint_space); | 53 fragment_ = RunOldLayout(*constraint_space); |
71 } | 54 } |
72 *out = new NGBoxFragment(FromPlatformWritingMode(Style()->getWritingMode()), | |
73 Style()->direction(), fragment_.get()); | |
74 // Reset coordinator for future use | |
75 layout_coordinator_ = nullptr; | |
76 return true; | |
77 } | |
78 | 55 |
79 void NGBlockNode::UpdateLayoutBox(NGPhysicalBoxFragment* fragment, | 56 return fragment_; |
80 const NGConstraintSpace* constraint_space) { | |
81 fragment_ = fragment; | |
82 if (layout_box_) { | |
83 CopyFragmentDataToLayoutBox(*constraint_space); | |
84 } | |
85 } | 57 } |
86 | 58 |
87 MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizesSync() { | 59 MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizesSync() { |
88 MinAndMaxContentSizes sizes; | 60 MinAndMaxContentSizes sizes; |
89 while (!ComputeMinAndMaxContentSizes(&sizes)) | 61 while (!ComputeMinAndMaxContentSizes(&sizes)) |
90 continue; | 62 continue; |
91 return sizes; | 63 return sizes; |
92 } | 64 } |
93 | 65 |
94 bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { | 66 bool NGBlockNode::ComputeMinAndMaxContentSizes(MinAndMaxContentSizes* sizes) { |
95 if (!CanUseNewLayout()) { | 67 if (!CanUseNewLayout()) { |
96 DCHECK(layout_box_); | 68 DCHECK(layout_box_); |
97 // TODO(layout-ng): This could be somewhat optimized by directly calling | 69 // TODO(layout-ng): This could be somewhat optimized by directly calling |
98 // computeIntrinsicLogicalWidths, but that function is currently private. | 70 // computeIntrinsicLogicalWidths, but that function is currently private. |
99 // Consider doing that if this becomes a performance issue. | 71 // Consider doing that if this becomes a performance issue. |
100 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); | 72 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); |
101 sizes->min_content = layout_box_->computeLogicalWidthUsing( | 73 sizes->min_content = layout_box_->computeLogicalWidthUsing( |
102 MainOrPreferredSize, Length(MinContent), | 74 MainOrPreferredSize, Length(MinContent), |
103 LayoutUnit(), layout_box_->containingBlock()) - | 75 LayoutUnit(), layout_box_->containingBlock()) - |
104 borderAndPadding; | 76 borderAndPadding; |
105 sizes->max_content = layout_box_->computeLogicalWidthUsing( | 77 sizes->max_content = layout_box_->computeLogicalWidthUsing( |
106 MainOrPreferredSize, Length(MaxContent), | 78 MainOrPreferredSize, Length(MaxContent), |
107 LayoutUnit(), layout_box_->containingBlock()) - | 79 LayoutUnit(), layout_box_->containingBlock()) - |
108 borderAndPadding; | 80 borderAndPadding; |
109 return true; | 81 return true; |
110 } | 82 } |
111 DCHECK(!layout_coordinator_) | |
112 << "Can't interleave Layout and ComputeMinAndMaxContentSizes"; | |
113 | 83 |
114 NGConstraintSpace* constraint_space = | 84 NGConstraintSpace* constraint_space = |
115 NGConstraintSpaceBuilder( | 85 NGConstraintSpaceBuilder( |
116 FromPlatformWritingMode(Style()->getWritingMode())) | 86 FromPlatformWritingMode(Style()->getWritingMode())) |
117 .SetTextDirection(Style()->direction()) | 87 .SetTextDirection(Style()->direction()) |
118 .ToConstraintSpace(); | 88 .ToConstraintSpace(); |
119 | 89 |
120 // TODO(cbiesinger): For orthogonal children, we need to always synthesize. | 90 // TODO(cbiesinger): For orthogonal children, we need to always synthesize. |
121 NGBlockLayoutAlgorithm minmax_algorithm(Style(), toNGBlockNode(FirstChild()), | 91 NGBlockLayoutAlgorithm minmax_algorithm(Style(), toNGBlockNode(FirstChild()), |
122 constraint_space); | 92 constraint_space); |
123 if (minmax_algorithm.ComputeMinAndMaxContentSizes(sizes)) | 93 if (minmax_algorithm.ComputeMinAndMaxContentSizes(sizes)) |
124 return true; | 94 return true; |
125 | 95 |
126 NGLayoutCoordinator* minmax_coordinator = | |
127 new NGLayoutCoordinator(this, constraint_space); | |
128 | |
129 // Have to synthesize this value. | 96 // Have to synthesize this value. |
130 NGPhysicalFragment* physical_fragment; | 97 NGPhysicalFragment* physical_fragment = this->Layout(constraint_space); |
cbiesinger
2017/01/20 21:21:56
Why the "this->"?
ikilpatrick
2017/01/20 23:19:57
Because I am a doofus :), done.
| |
131 while (!minmax_coordinator->Tick(&physical_fragment)) | |
132 continue; | |
133 NGBoxFragment* fragment = new NGBoxFragment( | 98 NGBoxFragment* fragment = new NGBoxFragment( |
134 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), | 99 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), |
135 toNGPhysicalBoxFragment(physical_fragment)); | 100 toNGPhysicalBoxFragment(physical_fragment)); |
136 | 101 |
137 sizes->min_content = fragment->InlineOverflow(); | 102 sizes->min_content = fragment->InlineOverflow(); |
138 | 103 |
139 // Now, redo with infinite space for max_content | 104 // Now, redo with infinite space for max_content |
140 constraint_space = | 105 constraint_space = |
141 NGConstraintSpaceBuilder( | 106 NGConstraintSpaceBuilder( |
142 FromPlatformWritingMode(Style()->getWritingMode())) | 107 FromPlatformWritingMode(Style()->getWritingMode())) |
143 .SetTextDirection(Style()->direction()) | 108 .SetTextDirection(Style()->direction()) |
144 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) | 109 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) |
145 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) | 110 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) |
146 .ToConstraintSpace(); | 111 .ToConstraintSpace(); |
147 | 112 |
148 minmax_coordinator = new NGLayoutCoordinator(this, constraint_space); | 113 physical_fragment = this->Layout(constraint_space); |
149 while (!minmax_coordinator->Tick(&physical_fragment)) | |
150 continue; | |
151 | |
152 fragment = new NGBoxFragment( | 114 fragment = new NGBoxFragment( |
153 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), | 115 FromPlatformWritingMode(Style()->getWritingMode()), Style()->direction(), |
154 toNGPhysicalBoxFragment(physical_fragment)); | 116 toNGPhysicalBoxFragment(physical_fragment)); |
155 sizes->max_content = fragment->InlineOverflow(); | 117 sizes->max_content = fragment->InlineOverflow(); |
156 return true; | 118 return true; |
157 } | 119 } |
158 | 120 |
159 ComputedStyle* NGBlockNode::MutableStyle() { | 121 ComputedStyle* NGBlockNode::MutableStyle() { |
160 if (style_) | 122 if (style_) |
161 return style_.get(); | 123 return style_.get(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
200 | 162 |
201 void NGBlockNode::SetFirstChild(NGLayoutInputNode* child) { | 163 void NGBlockNode::SetFirstChild(NGLayoutInputNode* child) { |
202 first_child_ = child; | 164 first_child_ = child; |
203 } | 165 } |
204 | 166 |
205 NGBreakToken* NGBlockNode::CurrentBreakToken() const { | 167 NGBreakToken* NGBlockNode::CurrentBreakToken() const { |
206 return fragment_ ? fragment_->BreakToken() : nullptr; | 168 return fragment_ ? fragment_->BreakToken() : nullptr; |
207 } | 169 } |
208 | 170 |
209 DEFINE_TRACE(NGBlockNode) { | 171 DEFINE_TRACE(NGBlockNode) { |
210 visitor->trace(layout_coordinator_); | |
211 visitor->trace(fragment_); | 172 visitor->trace(fragment_); |
212 visitor->trace(next_sibling_); | 173 visitor->trace(next_sibling_); |
213 visitor->trace(first_child_); | 174 visitor->trace(first_child_); |
214 NGLayoutInputNode::trace(visitor); | 175 NGLayoutInputNode::trace(visitor); |
215 } | 176 } |
216 | 177 |
217 void NGBlockNode::PositionUpdated() { | 178 void NGBlockNode::PositionUpdated() { |
218 if (!layout_box_) | 179 if (!layout_box_) |
219 return; | 180 return; |
220 DCHECK(layout_box_->parent()) << "Should be called on children only."; | 181 DCHECK(layout_box_->parent()) << "Should be called on children only."; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
252 if (child->isInline()) | 213 if (child->isInline()) |
253 return true; | 214 return true; |
254 child = child->nextSibling(); | 215 child = child->nextSibling(); |
255 } | 216 } |
256 | 217 |
257 return false; | 218 return false; |
258 } | 219 } |
259 | 220 |
260 void NGBlockNode::CopyFragmentDataToLayoutBox( | 221 void NGBlockNode::CopyFragmentDataToLayoutBox( |
261 const NGConstraintSpace& constraint_space) { | 222 const NGConstraintSpace& constraint_space) { |
262 DCHECK(layout_box_); | 223 // We may not have a layout_box_ during unit tests. |
224 if (!layout_box_) | |
225 return; | |
226 | |
263 layout_box_->setWidth(fragment_->Width()); | 227 layout_box_->setWidth(fragment_->Width()); |
264 layout_box_->setHeight(fragment_->Height()); | 228 layout_box_->setHeight(fragment_->Height()); |
265 NGBoxStrut border_and_padding = | 229 NGBoxStrut border_and_padding = |
266 ComputeBorders(*Style()) + ComputePadding(constraint_space, *Style()); | 230 ComputeBorders(*Style()) + ComputePadding(constraint_space, *Style()); |
267 LayoutUnit intrinsic_logical_height = | 231 LayoutUnit intrinsic_logical_height = |
268 layout_box_->style()->isHorizontalWritingMode() | 232 layout_box_->style()->isHorizontalWritingMode() |
269 ? fragment_->HeightOverflow() | 233 ? fragment_->HeightOverflow() |
270 : fragment_->WidthOverflow(); | 234 : fragment_->WidthOverflow(); |
271 intrinsic_logical_height -= border_and_padding.BlockSum(); | 235 intrinsic_logical_height -= border_and_padding.BlockSum(); |
272 layout_box_->setIntrinsicContentLogicalHeight(intrinsic_logical_height); | 236 layout_box_->setIntrinsicContentLogicalHeight(intrinsic_logical_height); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
347 // Save static position for legacy AbsPos layout. | 311 // Save static position for legacy AbsPos layout. |
348 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { | 312 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { |
349 DCHECK(layout_box_); | 313 DCHECK(layout_box_); |
350 DCHECK(layout_box_->isOutOfFlowPositioned()); | 314 DCHECK(layout_box_->isOutOfFlowPositioned()); |
351 DCHECK(layout_box_->layer()); | 315 DCHECK(layout_box_->layer()); |
352 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); | 316 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); |
353 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); | 317 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); |
354 } | 318 } |
355 | 319 |
356 } // namespace blink | 320 } // namespace blink |
OLD | NEW |