Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc

Issue 2883353005: [LayoutNG] Refactor main-loop of block layout algorithm. (Closed)
Patch Set: rebase unused var. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/inline/ng_inline_node.h" 7 #include "core/layout/ng/inline/ng_inline_node.h"
8 #include "core/layout/ng/ng_absolute_utils.h" 8 #include "core/layout/ng/ng_absolute_utils.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_constraint_space.h" 10 #include "core/layout/ng/ng_constraint_space.h"
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, 231 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
232 &container_builder_); 232 &container_builder_);
233 DCHECK_EQ(curr_margin_strut_, NGMarginStrut()); 233 DCHECK_EQ(curr_margin_strut_, NGMarginStrut());
234 DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset()); 234 DCHECK_EQ(container_builder_.BfcOffset().value(), NGLogicalOffset());
235 curr_bfc_offset_ = {}; 235 curr_bfc_offset_ = {};
236 } 236 }
237 237
238 curr_bfc_offset_.block_offset += content_size_; 238 curr_bfc_offset_.block_offset += content_size_;
239 239
240 while (child) { 240 while (child) {
241 // TODO(ikilpatrick): Refactor the inside of this loop. 241 if (child->IsOutOfFlowPositioned()) {
242 if (child->IsBlock()) { 242 DCHECK(!child_break_token);
243 EPosition position = child->Style().GetPosition(); 243 HandleOutOfFlowPositioned(ToNGBlockNode(child));
244 if (position == EPosition::kAbsolute || position == EPosition::kFixed) { 244 } else if (child->IsFloating()) {
245 NGLogicalOffset offset = {border_and_padding_.inline_start, 245 HandleFloating(ToNGBlockNode(child),
246 content_size_}; 246 ToNGBlockBreakToken(child_break_token));
247
248 // We only include the margin strut in the OOF static-position if we
249 // know we aren't going to be a zero-block-size fragment.
250 if (container_builder_.BfcOffset())
251 offset.block_offset += curr_margin_strut_.Sum();
252
253 container_builder_.AddOutOfFlowChildCandidate(ToNGBlockNode(child),
254 offset);
255 NGBlockChildIterator::Entry entry = child_iterator.NextChild();
256 child = entry.node;
257 child_break_token = entry.token;
258 continue;
259 }
260 }
261
262 NGLogicalOffset child_bfc_offset = PrepareChildLayout(child);
263
264 if (child->IsFloating()) {
265 FinishFloatChildLayout(child->Style(), ToNGBlockNode(child),
266 ToNGBlockBreakToken(child_break_token));
267 } else { 247 } else {
248 NGLogicalOffset child_bfc_offset = PrepareChildLayout(child);
268 RefPtr<NGConstraintSpace> child_space = 249 RefPtr<NGConstraintSpace> child_space =
269 CreateConstraintSpaceForChild(child_bfc_offset, *child); 250 CreateConstraintSpaceForChild(child_bfc_offset, *child);
270 RefPtr<NGLayoutResult> layout_result = 251 RefPtr<NGLayoutResult> layout_result =
271 child->Layout(child_space.Get(), child_break_token); 252 child->Layout(child_space.Get(), child_break_token);
272 FinishChildLayout(*child_space, child, layout_result.Get()); 253 FinishChildLayout(*child_space, child, layout_result.Get());
273 } 254 }
274 255
275 entry = child_iterator.NextChild(); 256 entry = child_iterator.NextChild();
276 child = entry.node; 257 child = entry.node;
277 child_break_token = entry.token; 258 child_break_token = entry.token;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 // We only finalize for fragmentation if the fragment has a BFC offset. This 305 // We only finalize for fragmentation if the fragment has a BFC offset. This
325 // may occur with a zero block size fragment. We need to know the BFC offset 306 // may occur with a zero block size fragment. We need to know the BFC offset
326 // to determine where the fragmentation line is relative to us. 307 // to determine where the fragmentation line is relative to us.
327 if (container_builder_.BfcOffset() && 308 if (container_builder_.BfcOffset() &&
328 ConstraintSpace().HasBlockFragmentation()) 309 ConstraintSpace().HasBlockFragmentation())
329 FinalizeForFragmentation(); 310 FinalizeForFragmentation();
330 311
331 return container_builder_.ToBoxFragment(); 312 return container_builder_.ToBoxFragment();
332 } 313 }
333 314
315 void NGBlockLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode* child) {
316 NGLogicalOffset offset = {border_and_padding_.inline_start, content_size_};
317
318 // We only include the margin strut in the OOF static-position if we know we
319 // aren't going to be a zero-block-size fragment.
320 if (container_builder_.BfcOffset())
321 offset.block_offset += curr_margin_strut_.Sum();
322
323 container_builder_.AddOutOfFlowChildCandidate(child, offset);
324 }
325
326 void NGBlockLayoutAlgorithm::HandleFloating(NGBlockNode* child,
327 NGBlockBreakToken* token) {
328 // TODO(ikilpatrick): Pass in BFC offset from previous in-flow child.
329 curr_bfc_offset_ = container_builder_.BfcOffset()
330 ? container_builder_.BfcOffset().value()
331 : ConstraintSpace().BfcOffset();
332 curr_bfc_offset_.block_offset += content_size_;
333
334 // Calculate margins in the BFC's writing mode.
335 curr_child_margins_ = CalculateMargins(child);
336
337 NGLogicalOffset origin_offset = constraint_space_->BfcOffset();
338 origin_offset.inline_offset += border_and_padding_.inline_start;
339 RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create(
340 child_available_size_, child_percentage_size_, origin_offset,
341 constraint_space_->BfcOffset(), curr_child_margins_, child, token);
342 container_builder_.AddUnpositionedFloat(unpositioned_float);
343
344 // If there is a break token for a float we must be resuming layout, we must
345 // always know our position in the BFC.
346 DCHECK(!token || container_builder_.BfcOffset());
347
348 // No need to postpone the positioning if we know the correct offset.
349 if (container_builder_.BfcOffset()) {
350 NGLogicalOffset origin_point = curr_bfc_offset_;
351 // Adjust origin point to the margins of the last child.
352 // Example: <div style="margin-bottom: 20px"><float></div>
353 // <div style="margin-bottom: 30px"></div>
354 origin_point.block_offset += curr_margin_strut_.Sum();
355 PositionPendingFloats(origin_point.block_offset, &container_builder_,
356 MutableConstraintSpace());
357 }
358 }
359
334 NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout( 360 NGLogicalOffset NGBlockLayoutAlgorithm::PrepareChildLayout(
335 NGLayoutInputNode* child) { 361 NGLayoutInputNode* child) {
336 DCHECK(child); 362 DCHECK(child);
363 DCHECK(!child->IsFloating());
337 364
365 // TODO(ikilpatrick): Pass in BFC offset from previous in-flow child.
338 curr_bfc_offset_ = container_builder_.BfcOffset() 366 curr_bfc_offset_ = container_builder_.BfcOffset()
339 ? container_builder_.BfcOffset().value() 367 ? container_builder_.BfcOffset().value()
340 : ConstraintSpace().BfcOffset(); 368 : ConstraintSpace().BfcOffset();
341 curr_bfc_offset_.block_offset += content_size_; 369 curr_bfc_offset_.block_offset += content_size_;
342 370
343 // Calculate margins in parent's writing mode. 371 // Calculate margins in parent's writing mode.
344 curr_child_margins_ = CalculateMargins(child); 372 curr_child_margins_ = CalculateMargins(child);
345 373
346 bool should_position_pending_floats = 374 bool should_position_pending_floats =
347 !child->IsFloating() &&
348 !IsNewFormattingContextForBlockLevelChild(Style(), *child) && 375 !IsNewFormattingContextForBlockLevelChild(Style(), *child) &&
349 ClearanceMayAffectLayout(ConstraintSpace(), 376 ClearanceMayAffectLayout(ConstraintSpace(),
350 container_builder_.UnpositionedFloats(), 377 container_builder_.UnpositionedFloats(),
351 child->Style()); 378 child->Style());
352 379
353 // Children which may clear a float need to force all the pending floats to 380 // Children which may clear a float need to force all the pending floats to
354 // be positioned before layout. This also resolves the fragment's bfc offset. 381 // be positioned before layout. This also resolves the fragment's bfc offset.
355 if (should_position_pending_floats) { 382 if (should_position_pending_floats) {
356 LayoutUnit origin_point_block_offset = 383 LayoutUnit origin_point_block_offset =
357 curr_bfc_offset_.block_offset + curr_margin_strut_.Sum(); 384 curr_bfc_offset_.block_offset + curr_margin_strut_.Sum();
358 MaybeUpdateFragmentBfcOffset( 385 MaybeUpdateFragmentBfcOffset(
359 ConstraintSpace(), 386 ConstraintSpace(),
360 {curr_bfc_offset_.inline_offset, origin_point_block_offset}, 387 {curr_bfc_offset_.inline_offset, origin_point_block_offset},
361 &container_builder_); 388 &container_builder_);
362 PositionPendingFloats(origin_point_block_offset, &container_builder_, 389 PositionPendingFloats(origin_point_block_offset, &container_builder_,
363 MutableConstraintSpace()); 390 MutableConstraintSpace());
364 } 391 }
365 392
366 bool is_inflow = child->IsInline() || !child->IsFloating(); 393 NGLogicalOffset child_bfc_offset = curr_bfc_offset_;
394 child_bfc_offset.inline_offset +=
395 {border_and_padding_.inline_start + curr_child_margins_.inline_start};
367 396
368 NGLogicalOffset child_bfc_offset = curr_bfc_offset_; 397 // Append the current margin strut with child's block start margin.
369 child_bfc_offset.inline_offset += border_and_padding_.inline_start; 398 // Non empty border/padding, and new FC use cases are handled inside of the
370 // Only inflow children (e.g. not floats) are included in the child's margin 399 // child's layout.
371 // strut as they do not participate in margin collapsing. 400 if (!IsNewFormattingContextForBlockLevelChild(Style(), *child))
372 if (is_inflow) { 401 curr_margin_strut_.Append(curr_child_margins_.block_start);
373 child_bfc_offset.inline_offset += curr_child_margins_.inline_start;
374 // Append the current margin strut with child's block start margin.
375 // Non empty border/padding, and new FC use cases are handled inside of the
376 // child's layout.
377 if (!IsNewFormattingContextForBlockLevelChild(Style(), *child))
378 curr_margin_strut_.Append(curr_child_margins_.block_start);
379 }
380 402
381 // TODO(crbug.com/716930): We should also collapse margins below once we 403 // TODO(crbug.com/716930): We should also collapse margins below once we
382 // remove LayoutInline splitting. 404 // remove LayoutInline splitting.
383 405
384 // Should collapse margins if our child is a legacy block. 406 // Should collapse margins if our child is a legacy block.
385 if (IsLegacyBlock(*child)) { 407 if (IsLegacyBlock(*child)) {
386 curr_bfc_offset_ += 408 curr_bfc_offset_ +=
387 {border_and_padding_.inline_start + curr_child_margins_.inline_start, 409 {border_and_padding_.inline_start + curr_child_margins_.inline_start,
388 curr_margin_strut_.Sum()}; 410 curr_margin_strut_.Sum()};
389 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_, 411 MaybeUpdateFragmentBfcOffset(ConstraintSpace(), curr_bfc_offset_,
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 &container_builder_, MutableConstraintSpace()); 544 &container_builder_, MutableConstraintSpace());
523 return curr_bfc_offset_; 545 return curr_bfc_offset_;
524 } 546 }
525 547
526 NGLogicalOffset NGBlockLayoutAlgorithm::PositionLegacy( 548 NGLogicalOffset NGBlockLayoutAlgorithm::PositionLegacy(
527 const NGConstraintSpace& child_space) { 549 const NGConstraintSpace& child_space) {
528 AdjustToClearance(child_space.ClearanceOffset(), &curr_bfc_offset_); 550 AdjustToClearance(child_space.ClearanceOffset(), &curr_bfc_offset_);
529 return curr_bfc_offset_; 551 return curr_bfc_offset_;
530 } 552 }
531 553
532 void NGBlockLayoutAlgorithm::FinishFloatChildLayout(
533 const ComputedStyle& child_style,
534 NGBlockNode* child,
535 NGBlockBreakToken* token) {
536 NGLogicalOffset origin_offset = constraint_space_->BfcOffset();
537 origin_offset.inline_offset += border_and_padding_.inline_start;
538 RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create(
539 child_available_size_, child_percentage_size_, origin_offset,
540 constraint_space_->BfcOffset(), curr_child_margins_, child, token);
541 container_builder_.AddUnpositionedFloat(unpositioned_float);
542
543 // If there is a break token for a float we must be resuming layout, we must
544 // always know our position in the BFC.
545 DCHECK(!token || container_builder_.BfcOffset());
546
547 // No need to postpone the positioning if we know the correct offset.
548 if (container_builder_.BfcOffset()) {
549 NGLogicalOffset origin_point = curr_bfc_offset_;
550 // Adjust origin point to the margins of the last child.
551 // Example: <div style="margin-bottom: 20px"><float></div>
552 // <div style="margin-bottom: 30px"></div>
553 origin_point.block_offset += curr_margin_strut_.Sum();
554 PositionPendingFloats(origin_point.block_offset, &container_builder_,
555 MutableConstraintSpace());
556 }
557 }
558
559 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { 554 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
560 LayoutUnit used_block_size = 555 LayoutUnit used_block_size =
561 BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit(); 556 BreakToken() ? BreakToken()->UsedBlockSize() : LayoutUnit();
562 LayoutUnit block_size = ComputeBlockSizeForFragment( 557 LayoutUnit block_size = ComputeBlockSizeForFragment(
563 ConstraintSpace(), Style(), used_block_size + content_size_); 558 ConstraintSpace(), Style(), used_block_size + content_size_);
564 559
565 block_size -= used_block_size; 560 block_size -= used_block_size;
566 DCHECK_GE(block_size, LayoutUnit()) 561 DCHECK_GE(block_size, LayoutUnit())
567 << "Adding and subtracting the used_block_size shouldn't leave the " 562 << "Adding and subtracting the used_block_size shouldn't leave the "
568 "block_size for this fragment smaller than zero."; 563 "block_size for this fragment smaller than zero.";
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
626 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild( 621 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
627 const NGLogicalOffset& child_bfc_offset, 622 const NGLogicalOffset& child_bfc_offset,
628 const NGLayoutInputNode& child) { 623 const NGLayoutInputNode& child) {
629 NGConstraintSpaceBuilder space_builder(MutableConstraintSpace()); 624 NGConstraintSpaceBuilder space_builder(MutableConstraintSpace());
630 space_builder.SetAvailableSize(child_available_size_) 625 space_builder.SetAvailableSize(child_available_size_)
631 .SetPercentageResolutionSize(child_percentage_size_); 626 .SetPercentageResolutionSize(child_percentage_size_);
632 627
633 const ComputedStyle& child_style = child.Style(); 628 const ComputedStyle& child_style = child.Style();
634 bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child); 629 bool is_new_bfc = IsNewFormattingContextForBlockLevelChild(Style(), child);
635 space_builder.SetIsNewFormattingContext(is_new_bfc) 630 space_builder.SetIsNewFormattingContext(is_new_bfc)
636 .SetBfcOffset(child_bfc_offset); 631 .SetBfcOffset(child_bfc_offset)
637 632 .SetMarginStrut(curr_margin_strut_);
638 // Float's margins are not included in child's space because:
639 // 1) Floats do not participate in margins collapsing.
640 // 2) Floats margins are used separately to calculate floating exclusions.
641 space_builder.SetMarginStrut(child.IsFloating() ? NGMarginStrut()
642 : curr_margin_strut_);
643 633
644 if (!is_new_bfc) { 634 if (!is_new_bfc) {
645 space_builder.SetUnpositionedFloats( 635 space_builder.SetUnpositionedFloats(
646 container_builder_.MutableUnpositionedFloats()); 636 container_builder_.MutableUnpositionedFloats());
647 } 637 }
648 638
649 if (child.IsInline()) { 639 if (child.IsInline()) {
650 // TODO(kojii): Setup space_builder appropriately for inline child. 640 // TODO(kojii): Setup space_builder appropriately for inline child.
651 space_builder.SetClearanceOffset(ConstraintSpace().ClearanceOffset()); 641 space_builder.SetClearanceOffset(ConstraintSpace().ClearanceOffset());
652 return space_builder.ToConstraintSpace( 642 return space_builder.ToConstraintSpace(
(...skipping 15 matching lines...) Expand all
668 if (is_new_bfc) { 658 if (is_new_bfc) {
669 space_available -= child_bfc_offset.block_offset; 659 space_available -= child_bfc_offset.block_offset;
670 } 660 }
671 } 661 }
672 space_builder.SetFragmentainerSpaceAvailable(space_available); 662 space_builder.SetFragmentainerSpaceAvailable(space_available);
673 663
674 return space_builder.ToConstraintSpace( 664 return space_builder.ToConstraintSpace(
675 FromPlatformWritingMode(child_style.GetWritingMode())); 665 FromPlatformWritingMode(child_style.GetWritingMode()));
676 } 666 }
677 } // namespace blink 667 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698