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_result.h" |
17 #include "core/layout/ng/ng_length_utils.h" | 18 #include "core/layout/ng/ng_length_utils.h" |
18 #include "core/layout/ng/ng_writing_mode.h" | 19 #include "core/layout/ng/ng_writing_mode.h" |
19 #include "core/paint/PaintLayer.h" | 20 #include "core/paint/PaintLayer.h" |
20 #include "platform/RuntimeEnabledFeatures.h" | 21 #include "platform/RuntimeEnabledFeatures.h" |
21 | 22 |
22 namespace blink { | 23 namespace blink { |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 // Copies data back to the legacy layout tree for a given child fragment. | 27 // Copies data back to the legacy layout tree for a given child fragment. |
27 void FragmentPositionUpdated(const NGPhysicalBoxFragment& box_fragment) { | 28 void FragmentPositionUpdated(const NGPhysicalFragment& fragment) { |
28 LayoutBox* layout_box = toLayoutBox(box_fragment.GetLayoutObject()); | 29 LayoutBox* layout_box = toLayoutBox(fragment.GetLayoutObject()); |
29 if (!layout_box) | 30 if (!layout_box) |
30 return; | 31 return; |
31 | 32 |
32 DCHECK(layout_box->parent()) << "Should be called on children only."; | 33 DCHECK(layout_box->parent()) << "Should be called on children only."; |
33 | 34 |
34 layout_box->setX(box_fragment.LeftOffset()); | 35 layout_box->setX(fragment.LeftOffset()); |
35 layout_box->setY(box_fragment.TopOffset()); | 36 layout_box->setY(fragment.TopOffset()); |
36 } | 37 } |
37 | 38 |
38 // Similar to FragmentPositionUpdated but for floats. | 39 // Similar to FragmentPositionUpdated but for floats. |
39 // - Updates layout object's geometric information. | 40 // - Updates layout object's geometric information. |
40 // - Creates legacy FloatingObject and attached it to the provided parent. | 41 // - Creates legacy FloatingObject and attached it to the provided parent. |
41 void FloatingObjectPositionedUpdated(NGFloatingObject* ng_floating_object, | 42 void FloatingObjectPositionedUpdated(NGFloatingObject* ng_floating_object, |
42 LayoutBox* parent) { | 43 LayoutBox* parent) { |
43 NGPhysicalBoxFragment* box_fragment = | 44 NGPhysicalBoxFragment* box_fragment = |
44 toNGPhysicalBoxFragment(ng_floating_object->fragment.get()); | 45 toNGPhysicalBoxFragment(ng_floating_object->fragment.get()); |
45 FragmentPositionUpdated(*box_fragment); | 46 FragmentPositionUpdated(*box_fragment); |
(...skipping 23 matching lines...) Expand all Loading... |
69 layout_box_(nullptr), | 70 layout_box_(nullptr), |
70 style_(style) { | 71 style_(style) { |
71 DCHECK(style_); | 72 DCHECK(style_); |
72 } | 73 } |
73 | 74 |
74 // Need an explicit destructor in the .cc file, or the MSWIN compiler will | 75 // Need an explicit destructor in the .cc file, or the MSWIN compiler will |
75 // produce an error when attempting to generate a default one, if the .h file is | 76 // produce an error when attempting to generate a default one, if the .h file is |
76 // included from a compilation unit that lacks the ComputedStyle definition. | 77 // included from a compilation unit that lacks the ComputedStyle definition. |
77 NGBlockNode::~NGBlockNode() {} | 78 NGBlockNode::~NGBlockNode() {} |
78 | 79 |
79 RefPtr<NGPhysicalFragment> NGBlockNode::Layout( | 80 RefPtr<NGLayoutResult> NGBlockNode::Layout( |
80 NGConstraintSpace* constraint_space) { | 81 NGConstraintSpace* constraint_space) { |
81 // Use the old layout code and synthesize a fragment. | 82 // Use the old layout code and synthesize a fragment. |
82 if (!CanUseNewLayout()) { | 83 if (!CanUseNewLayout()) { |
83 DCHECK(layout_box_); | 84 DCHECK(layout_box_); |
84 fragment_ = RunOldLayout(*constraint_space); | 85 layout_result_ = RunOldLayout(*constraint_space); |
85 return fragment_; | 86 return layout_result_; |
86 } | 87 } |
87 | 88 |
88 RefPtr<NGPhysicalFragment> fragment = | 89 layout_result_ = |
89 NGBlockLayoutAlgorithm(this, constraint_space, CurrentBreakToken()) | 90 NGBlockLayoutAlgorithm(this, constraint_space, CurrentBreakToken()) |
90 .Layout(); | 91 .Layout(); |
91 | 92 |
92 fragment_ = toNGPhysicalBoxFragment(fragment.get()); | |
93 CopyFragmentDataToLayoutBox(*constraint_space); | 93 CopyFragmentDataToLayoutBox(*constraint_space); |
94 return fragment_; | 94 return layout_result_; |
95 } | 95 } |
96 | 96 |
97 MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizes() { | 97 MinAndMaxContentSizes NGBlockNode::ComputeMinAndMaxContentSizes() { |
98 MinAndMaxContentSizes sizes; | 98 MinAndMaxContentSizes sizes; |
99 if (!CanUseNewLayout()) { | 99 if (!CanUseNewLayout()) { |
100 DCHECK(layout_box_); | 100 DCHECK(layout_box_); |
101 // TODO(layout-ng): This could be somewhat optimized by directly calling | 101 // TODO(layout-ng): This could be somewhat optimized by directly calling |
102 // computeIntrinsicLogicalWidths, but that function is currently private. | 102 // computeIntrinsicLogicalWidths, but that function is currently private. |
103 // Consider doing that if this becomes a performance issue. | 103 // Consider doing that if this becomes a performance issue. |
104 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); | 104 LayoutUnit borderAndPadding = layout_box_->borderAndPaddingLogicalWidth(); |
(...skipping 15 matching lines...) Expand all Loading... |
120 .ToConstraintSpace(FromPlatformWritingMode(Style().getWritingMode())); | 120 .ToConstraintSpace(FromPlatformWritingMode(Style().getWritingMode())); |
121 | 121 |
122 // TODO(cbiesinger): For orthogonal children, we need to always synthesize. | 122 // TODO(cbiesinger): For orthogonal children, we need to always synthesize. |
123 NGBlockLayoutAlgorithm minmax_algorithm(this, constraint_space); | 123 NGBlockLayoutAlgorithm minmax_algorithm(this, constraint_space); |
124 Optional<MinAndMaxContentSizes> maybe_sizes = | 124 Optional<MinAndMaxContentSizes> maybe_sizes = |
125 minmax_algorithm.ComputeMinAndMaxContentSizes(); | 125 minmax_algorithm.ComputeMinAndMaxContentSizes(); |
126 if (maybe_sizes.has_value()) | 126 if (maybe_sizes.has_value()) |
127 return *maybe_sizes; | 127 return *maybe_sizes; |
128 | 128 |
129 // Have to synthesize this value. | 129 // Have to synthesize this value. |
130 RefPtr<NGPhysicalFragment> physical_fragment = Layout(constraint_space); | 130 RefPtr<NGLayoutResult> layout_result = Layout(constraint_space); |
| 131 NGPhysicalFragment* physical_fragment = |
| 132 layout_result->PhysicalFragment().get(); |
131 NGBoxFragment min_fragment(FromPlatformWritingMode(Style().getWritingMode()), | 133 NGBoxFragment min_fragment(FromPlatformWritingMode(Style().getWritingMode()), |
132 toNGPhysicalBoxFragment(physical_fragment.get())); | 134 toNGPhysicalBoxFragment(physical_fragment)); |
133 sizes.min_content = min_fragment.InlineOverflow(); | 135 sizes.min_content = min_fragment.InlineOverflow(); |
134 | 136 |
135 // Now, redo with infinite space for max_content | 137 // Now, redo with infinite space for max_content |
136 constraint_space = | 138 constraint_space = |
137 NGConstraintSpaceBuilder( | 139 NGConstraintSpaceBuilder( |
138 FromPlatformWritingMode(Style().getWritingMode())) | 140 FromPlatformWritingMode(Style().getWritingMode())) |
139 .SetTextDirection(Style().direction()) | 141 .SetTextDirection(Style().direction()) |
140 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) | 142 .SetAvailableSize({LayoutUnit::max(), LayoutUnit()}) |
141 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) | 143 .SetPercentageResolutionSize({LayoutUnit(), LayoutUnit()}) |
142 .ToConstraintSpace(FromPlatformWritingMode(Style().getWritingMode())); | 144 .ToConstraintSpace(FromPlatformWritingMode(Style().getWritingMode())); |
143 | 145 |
144 physical_fragment = Layout(constraint_space); | 146 layout_result = Layout(constraint_space); |
| 147 physical_fragment = layout_result->PhysicalFragment().get(); |
145 NGBoxFragment max_fragment(FromPlatformWritingMode(Style().getWritingMode()), | 148 NGBoxFragment max_fragment(FromPlatformWritingMode(Style().getWritingMode()), |
146 toNGPhysicalBoxFragment(physical_fragment.get())); | 149 toNGPhysicalBoxFragment(physical_fragment)); |
147 sizes.max_content = max_fragment.InlineOverflow(); | 150 sizes.max_content = max_fragment.InlineOverflow(); |
148 return sizes; | 151 return sizes; |
149 } | 152 } |
150 | 153 |
151 const ComputedStyle& NGBlockNode::Style() const { | 154 const ComputedStyle& NGBlockNode::Style() const { |
152 if (style_) | 155 if (style_) |
153 return *style_.get(); | 156 return *style_.get(); |
154 DCHECK(layout_box_); | 157 DCHECK(layout_box_); |
155 return layout_box_->styleRef(); | 158 return layout_box_->styleRef(); |
156 } | 159 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 | 192 |
190 void NGBlockNode::SetNextSibling(NGLayoutInputNode* sibling) { | 193 void NGBlockNode::SetNextSibling(NGLayoutInputNode* sibling) { |
191 next_sibling_ = sibling; | 194 next_sibling_ = sibling; |
192 } | 195 } |
193 | 196 |
194 void NGBlockNode::SetFirstChild(NGLayoutInputNode* child) { | 197 void NGBlockNode::SetFirstChild(NGLayoutInputNode* child) { |
195 first_child_ = child; | 198 first_child_ = child; |
196 } | 199 } |
197 | 200 |
198 NGBreakToken* NGBlockNode::CurrentBreakToken() const { | 201 NGBreakToken* NGBlockNode::CurrentBreakToken() const { |
199 return fragment_ ? fragment_->BreakToken() : nullptr; | 202 return layout_result_ ? layout_result_->PhysicalFragment()->BreakToken() |
| 203 : nullptr; |
200 } | 204 } |
201 | 205 |
202 DEFINE_TRACE(NGBlockNode) { | 206 DEFINE_TRACE(NGBlockNode) { |
203 visitor->trace(next_sibling_); | 207 visitor->trace(next_sibling_); |
204 visitor->trace(first_child_); | 208 visitor->trace(first_child_); |
205 NGLayoutInputNode::trace(visitor); | 209 NGLayoutInputNode::trace(visitor); |
206 } | 210 } |
207 | 211 |
208 bool NGBlockNode::CanUseNewLayout() { | 212 bool NGBlockNode::CanUseNewLayout() { |
209 if (!layout_box_) | 213 if (!layout_box_) |
(...skipping 20 matching lines...) Expand all Loading... |
230 | 234 |
231 return false; | 235 return false; |
232 } | 236 } |
233 | 237 |
234 void NGBlockNode::CopyFragmentDataToLayoutBox( | 238 void NGBlockNode::CopyFragmentDataToLayoutBox( |
235 const NGConstraintSpace& constraint_space) { | 239 const NGConstraintSpace& constraint_space) { |
236 // We may not have a layout_box_ during unit tests. | 240 // We may not have a layout_box_ during unit tests. |
237 if (!layout_box_) | 241 if (!layout_box_) |
238 return; | 242 return; |
239 | 243 |
240 layout_box_->setWidth(fragment_->Width()); | 244 NGPhysicalBoxFragment* fragment = |
241 layout_box_->setHeight(fragment_->Height()); | 245 toNGPhysicalBoxFragment(layout_result_->PhysicalFragment().get()); |
| 246 |
| 247 layout_box_->setWidth(fragment->Width()); |
| 248 layout_box_->setHeight(fragment->Height()); |
242 NGBoxStrut border_and_padding = | 249 NGBoxStrut border_and_padding = |
243 ComputeBorders(Style()) + ComputePadding(constraint_space, Style()); | 250 ComputeBorders(Style()) + ComputePadding(constraint_space, Style()); |
244 LayoutUnit intrinsic_logical_height = | 251 LayoutUnit intrinsic_logical_height = |
245 layout_box_->style()->isHorizontalWritingMode() | 252 layout_box_->style()->isHorizontalWritingMode() |
246 ? fragment_->HeightOverflow() | 253 ? fragment->HeightOverflow() |
247 : fragment_->WidthOverflow(); | 254 : fragment->WidthOverflow(); |
248 intrinsic_logical_height -= border_and_padding.BlockSum(); | 255 intrinsic_logical_height -= border_and_padding.BlockSum(); |
249 layout_box_->setIntrinsicContentLogicalHeight(intrinsic_logical_height); | 256 layout_box_->setIntrinsicContentLogicalHeight(intrinsic_logical_height); |
250 | 257 |
251 // We may still have unpositioned floats when we reach the root box. | 258 // We may still have unpositioned floats when we reach the root box. |
252 if (!layout_box_->parent()) { | 259 if (!layout_box_->parent()) { |
253 for (const auto& floating_object : fragment_->PositionedFloats()) { | 260 for (const auto& floating_object : fragment->PositionedFloats()) { |
254 FloatingObjectPositionedUpdated(floating_object, layout_box_); | 261 FloatingObjectPositionedUpdated(floating_object, layout_box_); |
255 } | 262 } |
256 } | 263 } |
257 | 264 |
258 // TODO(layout-dev): Currently we are not actually performing layout on | 265 // TODO(layout-dev): Currently we are not actually performing layout on |
259 // inline children. For now just clear the needsLayout bit so that we can | 266 // inline children. For now just clear the needsLayout bit so that we can |
260 // run unittests. | 267 // run unittests. |
261 if (HasInlineChildren()) { | 268 if (HasInlineChildren()) { |
262 for (InlineWalker walker( | 269 for (InlineWalker walker( |
263 LineLayoutBlockFlow(toLayoutBlockFlow(layout_box_))); | 270 LineLayoutBlockFlow(toLayoutBlockFlow(layout_box_))); |
264 !walker.atEnd(); walker.advance()) { | 271 !walker.atEnd(); walker.advance()) { |
265 LayoutObject* o = LineLayoutAPIShim::layoutObjectFrom(walker.current()); | 272 LayoutObject* o = LineLayoutAPIShim::layoutObjectFrom(walker.current()); |
266 o->clearNeedsLayout(); | 273 o->clearNeedsLayout(); |
267 } | 274 } |
268 | 275 |
269 // Ensure the position of the children are copied across to the | 276 // Ensure the position of the children are copied across to the |
270 // LayoutObject tree. | 277 // LayoutObject tree. |
271 } else { | 278 } else { |
272 for (const auto& child_fragment : fragment_->Children()) { | 279 for (const auto& child_fragment : fragment->Children()) { |
273 if (child_fragment->IsPlaced()) | 280 if (child_fragment->IsPlaced()) |
274 FragmentPositionUpdated(toNGPhysicalBoxFragment(*child_fragment)); | 281 FragmentPositionUpdated(toNGPhysicalBoxFragment(*child_fragment)); |
275 | 282 |
276 for (const auto& floating_object : child_fragment->PositionedFloats()) { | 283 for (const auto& floating_object : |
| 284 toNGPhysicalBoxFragment(child_fragment.get())->PositionedFloats()) { |
277 FloatingObjectPositionedUpdated( | 285 FloatingObjectPositionedUpdated( |
278 floating_object, toLayoutBox(child_fragment->GetLayoutObject())); | 286 floating_object, toLayoutBox(child_fragment->GetLayoutObject())); |
279 } | 287 } |
280 } | 288 } |
281 } | 289 } |
282 | 290 |
283 if (layout_box_->isLayoutBlock()) | 291 if (layout_box_->isLayoutBlock()) |
284 toLayoutBlock(layout_box_)->layoutPositionedObjects(true); | 292 toLayoutBlock(layout_box_)->layoutPositionedObjects(true); |
285 layout_box_->clearNeedsLayout(); | 293 layout_box_->clearNeedsLayout(); |
286 if (layout_box_->isLayoutBlockFlow()) { | 294 if (layout_box_->isLayoutBlockFlow()) { |
287 toLayoutBlockFlow(layout_box_)->updateIsSelfCollapsing(); | 295 toLayoutBlockFlow(layout_box_)->updateIsSelfCollapsing(); |
288 } | 296 } |
289 } | 297 } |
290 | 298 |
291 RefPtr<NGPhysicalBoxFragment> NGBlockNode::RunOldLayout( | 299 RefPtr<NGLayoutResult> NGBlockNode::RunOldLayout( |
292 const NGConstraintSpace& constraint_space) { | 300 const NGConstraintSpace& constraint_space) { |
293 NGLogicalSize available_size = constraint_space.PercentageResolutionSize(); | 301 NGLogicalSize available_size = constraint_space.PercentageResolutionSize(); |
294 LayoutObject* containing_block = layout_box_->containingBlock(); | 302 LayoutObject* containing_block = layout_box_->containingBlock(); |
295 bool parallel_writing_mode; | 303 bool parallel_writing_mode; |
296 if (!containing_block) { | 304 if (!containing_block) { |
297 parallel_writing_mode = true; | 305 parallel_writing_mode = true; |
298 } else { | 306 } else { |
299 parallel_writing_mode = IsParallelWritingMode( | 307 parallel_writing_mode = IsParallelWritingMode( |
300 FromPlatformWritingMode(containing_block->styleRef().getWritingMode()), | 308 FromPlatformWritingMode(containing_block->styleRef().getWritingMode()), |
301 FromPlatformWritingMode(Style().getWritingMode())); | 309 FromPlatformWritingMode(Style().getWritingMode())); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 // Save static position for legacy AbsPos layout. | 360 // Save static position for legacy AbsPos layout. |
353 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { | 361 void NGBlockNode::SaveStaticOffsetForLegacy(const NGLogicalOffset& offset) { |
354 DCHECK(layout_box_); | 362 DCHECK(layout_box_); |
355 DCHECK(layout_box_->isOutOfFlowPositioned()); | 363 DCHECK(layout_box_->isOutOfFlowPositioned()); |
356 DCHECK(layout_box_->layer()); | 364 DCHECK(layout_box_->layer()); |
357 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); | 365 layout_box_->layer()->setStaticBlockPosition(offset.block_offset); |
358 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); | 366 layout_box_->layer()->setStaticInlinePosition(offset.inline_offset); |
359 } | 367 } |
360 | 368 |
361 } // namespace blink | 369 } // namespace blink |
OLD | NEW |