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_break_token.h" | 7 #include "core/layout/ng/ng_break_token.h" |
8 #include "core/layout/ng/ng_constraint_space.h" | 8 #include "core/layout/ng/ng_constraint_space.h" |
9 #include "core/layout/ng/ng_constraint_space_builder.h" | 9 #include "core/layout/ng/ng_constraint_space_builder.h" |
10 #include "core/layout/ng/ng_fragment_base.h" | 10 #include "core/layout/ng/ng_fragment_base.h" |
11 #include "core/layout/ng/ng_fragment_builder.h" | 11 #include "core/layout/ng/ng_fragment_builder.h" |
12 #include "core/layout/ng/ng_fragment.h" | 12 #include "core/layout/ng/ng_fragment.h" |
13 #include "core/layout/ng/ng_layout_opportunity_iterator.h" | 13 #include "core/layout/ng/ng_layout_opportunity_iterator.h" |
14 #include "core/layout/ng/ng_length_utils.h" | 14 #include "core/layout/ng/ng_length_utils.h" |
15 #include "core/layout/ng/ng_out_of_flow_layout_part.h" | |
15 #include "core/layout/ng/ng_units.h" | 16 #include "core/layout/ng/ng_units.h" |
16 #include "core/style/ComputedStyle.h" | 17 #include "core/style/ComputedStyle.h" |
17 #include "platform/LengthFunctions.h" | 18 #include "platform/LengthFunctions.h" |
18 #include "wtf/Optional.h" | 19 #include "wtf/Optional.h" |
19 | 20 |
20 namespace blink { | 21 namespace blink { |
21 namespace { | 22 namespace { |
22 | 23 |
23 // Adjusts content's offset to CSS "clear" property. | 24 // Adjusts content's offset to CSS "clear" property. |
24 // TODO(glebl): Support margin collapsing edge cases, e.g. margin collapsing | 25 // TODO(glebl): Support margin collapsing edge cases, e.g. margin collapsing |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 builder_->SetDirection(constraint_space_->Direction()); | 237 builder_->SetDirection(constraint_space_->Direction()); |
237 builder_->SetWritingMode(constraint_space_->WritingMode()); | 238 builder_->SetWritingMode(constraint_space_->WritingMode()); |
238 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); | 239 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); |
239 | 240 |
240 current_child_ = first_child_; | 241 current_child_ = first_child_; |
241 state_ = kStatePrepareForChildLayout; | 242 state_ = kStatePrepareForChildLayout; |
242 return kNotFinished; | 243 return kNotFinished; |
243 } | 244 } |
244 case kStatePrepareForChildLayout: { | 245 case kStatePrepareForChildLayout: { |
245 if (current_child_) { | 246 if (current_child_) { |
246 // TODO(atotic): uncomment this code when implementing oof layout. | 247 EPosition position = current_child_->Style()->position(); |
247 // This code cannot be turned on because it prevents layout of | 248 if ((position == AbsolutePosition || position == FixedPosition)) { |
248 // oof children, and non-layedout objects trigger a DCHECK. | 249 builder_->AddOutOfFlowChildCandidate(current_child_, |
249 // EPosition position = current_child_->Style()->position(); | 250 GetChildSpaceOffset()); |
250 // if ((position == AbsolutePosition || position == FixedPosition)) { | 251 current_child_ = current_child_->NextSibling(); |
251 // builder_->AddOutOfFlowCandidateChild(current_child_, | 252 return kNotFinished; |
252 // GetChildSpaceOffset()); | 253 } else { |
cbiesinger
2016/12/21 21:38:50
No need for an "else" after a return.
atotic
2016/12/28 19:36:46
done
| |
253 // } | 254 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); |
254 // else | 255 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( |
255 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); | 256 current_child_, space_for_current_child_); |
256 *algorithm_out = NGLayoutInputNode::AlgorithmForInputNode( | 257 state_ = kStateChildLayout; |
257 current_child_, space_for_current_child_); | 258 return kChildAlgorithmRequired; |
258 state_ = kStateChildLayout; | 259 } |
259 return kChildAlgorithmRequired; | |
260 } | 260 } |
261 | 261 |
262 state_ = kStateFinalize; | 262 // Prepare for kStateOutOfFlowLayout |
263 content_size_ += border_and_padding_.block_end; | |
264 | |
265 // Recompute the block-axis size now that we know our content size. | |
266 LayoutUnit block_size = ComputeBlockSizeForFragment( | |
267 ConstraintSpace(), Style(), content_size_); | |
268 builder_->SetBlockSize(block_size); | |
269 | |
270 // Out of flow setup. | |
271 out_of_flow_layout_ = new NGOutOfFlowLayoutPart(style_, builder_->Size()); | |
272 builder_->GetAndClearOutOfFlowDescendantCandidates( | |
273 &out_of_flow_candidates_, &out_of_flow_candidate_positions_); | |
274 out_of_flow_candidate_positions_index_ = 0; | |
275 current_child_ = nullptr; | |
276 state_ = kStateOutOfFlowLayout; | |
263 return kNotFinished; | 277 return kNotFinished; |
264 } | 278 } |
265 case kStateChildLayout: { | 279 case kStateChildLayout: { |
266 DCHECK(current_child_); | 280 DCHECK(current_child_); |
267 DCHECK(child_fragment); | 281 DCHECK(child_fragment); |
268 | 282 |
269 // TODO(layout_ng): Seems like a giant hack to call this here. | 283 // TODO(layout_ng): Seems like a giant hack to call this here. |
270 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), | 284 current_child_->UpdateLayoutBox(toNGPhysicalFragment(child_fragment), |
271 space_for_current_child_); | 285 space_for_current_child_); |
272 | 286 |
273 FinishCurrentChildLayout(new NGFragment( | 287 FinishCurrentChildLayout(new NGFragment( |
274 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), | 288 ConstraintSpace().WritingMode(), ConstraintSpace().Direction(), |
275 toNGPhysicalFragment(child_fragment))); | 289 toNGPhysicalFragment(child_fragment))); |
276 current_child_ = current_child_->NextSibling(); | 290 current_child_ = current_child_->NextSibling(); |
277 state_ = kStatePrepareForChildLayout; | 291 state_ = kStatePrepareForChildLayout; |
278 return kNotFinished; | 292 return kNotFinished; |
279 } | 293 } |
294 case kStateOutOfFlowLayout: | |
295 if (LayoutOutOfFlowChild()) | |
296 state_ = kStateFinalize; | |
297 return kNotFinished; | |
280 case kStateFinalize: { | 298 case kStateFinalize: { |
281 content_size_ += border_and_padding_.block_end; | |
282 | |
283 // Recompute the block-axis size now that we know our content size. | 299 // Recompute the block-axis size now that we know our content size. |
284 LayoutUnit block_size = ComputeBlockSizeForFragment( | 300 LayoutUnit block_size = ComputeBlockSizeForFragment( |
cbiesinger
2016/12/21 21:38:50
You don't need this anymore since you're now calli
atotic
2016/12/28 19:36:45
done. Thanks, nice catch, I blame this on persiste
| |
285 ConstraintSpace(), Style(), content_size_); | 301 ConstraintSpace(), Style(), content_size_); |
286 | 302 |
287 builder_->SetBlockSize(block_size) | 303 builder_->SetBlockSize(block_size) |
288 .SetInlineOverflow(max_inline_size_) | 304 .SetInlineOverflow(max_inline_size_) |
289 .SetBlockOverflow(content_size_); | 305 .SetBlockOverflow(content_size_); |
290 *fragment_out = builder_->ToFragment(); | 306 *fragment_out = builder_->ToFragment(); |
291 state_ = kStateInit; | 307 state_ = kStateInit; |
292 return kNewFragment; | 308 return kNewFragment; |
293 } | 309 } |
294 }; | 310 }; |
(...skipping 12 matching lines...) Expand all Loading... | |
307 if (CurrentChildStyle().isFloating()) { | 323 if (CurrentChildStyle().isFloating()) { |
308 fragment_offset = PositionFloatFragment(*fragment, child_margins); | 324 fragment_offset = PositionFloatFragment(*fragment, child_margins); |
309 } else { | 325 } else { |
310 ApplyAutoMargins(*space_for_current_child_, CurrentChildStyle(), *fragment, | 326 ApplyAutoMargins(*space_for_current_child_, CurrentChildStyle(), *fragment, |
311 &child_margins); | 327 &child_margins); |
312 fragment_offset = PositionFragment(*fragment, child_margins); | 328 fragment_offset = PositionFragment(*fragment, child_margins); |
313 } | 329 } |
314 builder_->AddChild(fragment, fragment_offset); | 330 builder_->AddChild(fragment, fragment_offset); |
315 } | 331 } |
316 | 332 |
333 bool NGBlockLayoutAlgorithm::LayoutOutOfFlowChild() { | |
cbiesinger
2016/12/21 21:38:50
Maybe use NGLayoutStatus as the return type so it'
atotic
2016/12/28 19:36:45
Unsure about this.
Pros: not necessary to remembe
cbiesinger
2017/01/04 00:13:16
Just documentation is fine with me, though it seem
| |
334 if (!current_child_) { | |
335 if (out_of_flow_candidates_.isEmpty()) { | |
336 out_of_flow_layout_ = nullptr; | |
337 out_of_flow_candidate_positions_.clear(); | |
338 return true; | |
339 } | |
340 current_child_ = out_of_flow_candidates_.first(); | |
341 out_of_flow_candidates_.removeFirst(); | |
342 NGStaticPosition position = out_of_flow_candidate_positions_ | |
343 [out_of_flow_candidate_positions_index_++]; | |
344 | |
345 if (!out_of_flow_layout_->StartLayout(current_child_, position)) { | |
346 builder_->AddOutOfFlowDescendant(current_child_, position); | |
347 current_child_ = nullptr; | |
348 return false; | |
349 } | |
350 } | |
351 NGFragmentBase* fragment; | |
352 NGLogicalOffset offset; | |
353 if (out_of_flow_layout_->Layout(&fragment, &offset)) { | |
354 // TODO(atotic) Do we need to adjust builder content size here? | |
cbiesinger
2016/12/21 21:38:50
abspos does not change the width/height of the con
atotic
2016/12/28 19:36:46
done. Added a comment.
| |
355 builder_->AddChild(fragment, offset); | |
356 current_child_ = nullptr; | |
357 } | |
358 return false; | |
359 } | |
360 | |
317 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins( | 361 NGBoxStrut NGBlockLayoutAlgorithm::CollapseMargins( |
318 const NGBoxStrut& margins, | 362 const NGBoxStrut& margins, |
319 const NGFragment& fragment) { | 363 const NGFragment& fragment) { |
320 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() && | 364 bool is_zero_height_box = !fragment.BlockSize() && margins.IsEmpty() && |
321 fragment.MarginStrut().IsEmpty(); | 365 fragment.MarginStrut().IsEmpty(); |
322 // Create the current child's margin strut from its children's margin strut or | 366 // Create the current child's margin strut from its children's margin strut or |
323 // use margin strut from the the last non-empty child. | 367 // use margin strut from the the last non-empty child. |
324 NGMarginStrut curr_margin_strut = | 368 NGMarginStrut curr_margin_strut = |
325 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut(); | 369 is_zero_height_box ? prev_child_margin_strut_ : fragment.MarginStrut(); |
326 | 370 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 | 503 |
460 DEFINE_TRACE(NGBlockLayoutAlgorithm) { | 504 DEFINE_TRACE(NGBlockLayoutAlgorithm) { |
461 NGLayoutAlgorithm::trace(visitor); | 505 NGLayoutAlgorithm::trace(visitor); |
462 visitor->trace(first_child_); | 506 visitor->trace(first_child_); |
463 visitor->trace(constraint_space_); | 507 visitor->trace(constraint_space_); |
464 visitor->trace(break_token_); | 508 visitor->trace(break_token_); |
465 visitor->trace(builder_); | 509 visitor->trace(builder_); |
466 visitor->trace(space_builder_); | 510 visitor->trace(space_builder_); |
467 visitor->trace(space_for_current_child_); | 511 visitor->trace(space_for_current_child_); |
468 visitor->trace(current_child_); | 512 visitor->trace(current_child_); |
513 visitor->trace(out_of_flow_layout_); | |
514 visitor->trace(out_of_flow_candidates_); | |
469 } | 515 } |
470 | 516 |
471 } // namespace blink | 517 } // namespace blink |
OLD | NEW |