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

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

Issue 2719373002: [LayoutNG] Move NGConstraintSpaceBuilder off Oilpan and DISALLOW_NEW. (Closed)
Patch Set: rebase Created 3 years, 9 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/ng_absolute_utils.h" 7 #include "core/layout/ng/ng_absolute_utils.h"
8 #include "core/layout/ng/ng_block_break_token.h" 8 #include "core/layout/ng/ng_block_break_token.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_box_fragment.h" 10 #include "core/layout/ng/ng_box_fragment.h"
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 303
304 } // namespace 304 } // namespace
305 305
306 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( 306 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
307 NGBlockNode* node, 307 NGBlockNode* node,
308 NGConstraintSpace* constraint_space, 308 NGConstraintSpace* constraint_space,
309 NGBlockBreakToken* break_token) 309 NGBlockBreakToken* break_token)
310 : node_(node), 310 : node_(node),
311 constraint_space_(constraint_space), 311 constraint_space_(constraint_space),
312 break_token_(break_token), 312 break_token_(break_token),
313 builder_(WTF::wrapUnique( 313 builder_(NGPhysicalFragment::kFragmentBox, node),
314 new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox, node))) {} 314 space_builder_(constraint_space_) {}
315 315
316 Optional<MinAndMaxContentSizes> 316 Optional<MinAndMaxContentSizes>
317 NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes() const { 317 NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes() const {
318 MinAndMaxContentSizes sizes; 318 MinAndMaxContentSizes sizes;
319 319
320 // Size-contained elements don't consider their contents for intrinsic sizing. 320 // Size-contained elements don't consider their contents for intrinsic sizing.
321 if (Style().containsSize()) 321 if (Style().containsSize())
322 return sizes; 322 return sizes;
323 323
324 // TODO: handle floats & orthogonal children. 324 // TODO: handle floats & orthogonal children.
(...skipping 28 matching lines...) Expand all
353 return sizes; 353 return sizes;
354 } 354 }
355 355
356 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset( 356 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
357 const WTF::Optional<NGLogicalOffset>& known_fragment_offset) { 357 const WTF::Optional<NGLogicalOffset>& known_fragment_offset) {
358 LayoutUnit inline_offset = 358 LayoutUnit inline_offset =
359 border_and_padding_.inline_start + curr_child_margins_.inline_start; 359 border_and_padding_.inline_start + curr_child_margins_.inline_start;
360 LayoutUnit block_offset = content_size_; 360 LayoutUnit block_offset = content_size_;
361 if (known_fragment_offset) { 361 if (known_fragment_offset) {
362 block_offset = known_fragment_offset.value().block_offset - 362 block_offset = known_fragment_offset.value().block_offset -
363 builder_->BfcOffset().value().block_offset; 363 builder_.BfcOffset().value().block_offset;
364 } 364 }
365 return {inline_offset, block_offset}; 365 return {inline_offset, block_offset};
366 } 366 }
367 367
368 void NGBlockLayoutAlgorithm::UpdateFragmentBfcOffset( 368 void NGBlockLayoutAlgorithm::UpdateFragmentBfcOffset(
369 const NGLogicalOffset& offset) { 369 const NGLogicalOffset& offset) {
370 if (!builder_->BfcOffset()) { 370 if (!builder_.BfcOffset()) {
371 NGLogicalOffset bfc_offset = offset; 371 NGLogicalOffset bfc_offset = offset;
372 if (ConstraintSpace().ClearanceOffset()) { 372 if (ConstraintSpace().ClearanceOffset()) {
373 bfc_offset.block_offset = std::max( 373 bfc_offset.block_offset = std::max(
374 ConstraintSpace().ClearanceOffset().value(), offset.block_offset); 374 ConstraintSpace().ClearanceOffset().value(), offset.block_offset);
375 } 375 }
376 builder_->SetBfcOffset(bfc_offset); 376 builder_.SetBfcOffset(bfc_offset);
377 } 377 }
378 } 378 }
379 379
380 RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { 380 RefPtr<NGLayoutResult> NGBlockLayoutAlgorithm::Layout() {
381 WTF::Optional<MinAndMaxContentSizes> sizes; 381 WTF::Optional<MinAndMaxContentSizes> sizes;
382 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) 382 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style()))
383 sizes = ComputeMinAndMaxContentSizes(); 383 sizes = ComputeMinAndMaxContentSizes();
384 384
385 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) + 385 border_and_padding_ = ComputeBorders(ConstraintSpace(), Style()) +
386 ComputePadding(ConstraintSpace(), Style()); 386 ComputePadding(ConstraintSpace(), Style());
387 387
388 LayoutUnit inline_size = 388 LayoutUnit inline_size =
389 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); 389 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes);
390 LayoutUnit adjusted_inline_size = 390 LayoutUnit adjusted_inline_size =
391 inline_size - border_and_padding_.InlineSum(); 391 inline_size - border_and_padding_.InlineSum();
392 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of 392 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of
393 // -1? 393 // -1?
394 LayoutUnit block_size = 394 LayoutUnit block_size =
395 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite); 395 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite);
396 LayoutUnit adjusted_block_size(block_size); 396 LayoutUnit adjusted_block_size(block_size);
397 // Our calculated block-axis size may be indefinite at this point. 397 // Our calculated block-axis size may be indefinite at this point.
398 // If so, just leave the size as NGSizeIndefinite instead of subtracting 398 // If so, just leave the size as NGSizeIndefinite instead of subtracting
399 // borders and padding. 399 // borders and padding.
400 if (adjusted_block_size != NGSizeIndefinite) 400 if (adjusted_block_size != NGSizeIndefinite)
401 adjusted_block_size -= border_and_padding_.BlockSum(); 401 adjusted_block_size -= border_and_padding_.BlockSum();
402 402
403 space_builder_ = new NGConstraintSpaceBuilder(constraint_space_);
404 space_builder_ 403 space_builder_
405 ->SetAvailableSize( 404 .SetAvailableSize(
406 NGLogicalSize(adjusted_inline_size, adjusted_block_size)) 405 NGLogicalSize(adjusted_inline_size, adjusted_block_size))
407 .SetPercentageResolutionSize( 406 .SetPercentageResolutionSize(
408 NGLogicalSize(adjusted_inline_size, adjusted_block_size)); 407 NGLogicalSize(adjusted_inline_size, adjusted_block_size));
409 408
410 builder_->SetDirection(constraint_space_->Direction()); 409 builder_.SetDirection(constraint_space_->Direction());
411 builder_->SetWritingMode(constraint_space_->WritingMode()); 410 builder_.SetWritingMode(constraint_space_->WritingMode());
412 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); 411 builder_.SetInlineSize(inline_size).SetBlockSize(block_size);
413 412
414 NGBlockChildIterator child_iterator(node_->FirstChild(), break_token_); 413 NGBlockChildIterator child_iterator(node_->FirstChild(), break_token_);
415 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); 414 NGBlockChildIterator::Entry entry = child_iterator.NextChild();
416 NGLayoutInputNode* child = entry.node; 415 NGLayoutInputNode* child = entry.node;
417 NGBreakToken* child_break_token = entry.token; 416 NGBreakToken* child_break_token = entry.token;
418 417
419 // If we are resuming from a break token our start border and padding is 418 // If we are resuming from a break token our start border and padding is
420 // within a previous fragment. 419 // within a previous fragment.
421 content_size_ = break_token_ ? LayoutUnit() : border_and_padding_.block_start; 420 content_size_ = break_token_ ? LayoutUnit() : border_and_padding_.block_start;
422 421
423 curr_margin_strut_ = ConstraintSpace().MarginStrut(); 422 curr_margin_strut_ = ConstraintSpace().MarginStrut();
424 curr_bfc_offset_ = ConstraintSpace().BfcOffset(); 423 curr_bfc_offset_ = ConstraintSpace().BfcOffset();
425 424
426 // Margins collapsing: 425 // Margins collapsing:
427 // Do not collapse margins between parent and its child if there is 426 // Do not collapse margins between parent and its child if there is
428 // border/padding between them. 427 // border/padding between them.
429 if (border_and_padding_.block_start) { 428 if (border_and_padding_.block_start) {
430 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 429 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
431 UpdateFragmentBfcOffset(curr_bfc_offset_); 430 UpdateFragmentBfcOffset(curr_bfc_offset_);
432 curr_margin_strut_ = NGMarginStrut(); 431 curr_margin_strut_ = NGMarginStrut();
433 } 432 }
434 433
435 // Block that establishes a new BFC knows its BFC offset == {} 434 // Block that establishes a new BFC knows its BFC offset == {}
436 // If a new formatting context hits the if branch above then the BFC offset is 435 // If a new formatting context hits the if branch above then the BFC offset is
437 // still {} as the margin strut from the constraint space must also be empty. 436 // still {} as the margin strut from the constraint space must also be empty.
438 if (ConstraintSpace().IsNewFormattingContext()) { 437 if (ConstraintSpace().IsNewFormattingContext()) {
439 UpdateFragmentBfcOffset(curr_bfc_offset_); 438 UpdateFragmentBfcOffset(curr_bfc_offset_);
440 DCHECK_EQ(builder_->BfcOffset().value(), NGLogicalOffset()); 439 DCHECK_EQ(builder_.BfcOffset().value(), NGLogicalOffset());
441 DCHECK_EQ(curr_margin_strut_, NGMarginStrut()); 440 DCHECK_EQ(curr_margin_strut_, NGMarginStrut());
442 } 441 }
443 442
444 curr_bfc_offset_.block_offset += content_size_; 443 curr_bfc_offset_.block_offset += content_size_;
445 444
446 while (child) { 445 while (child) {
447 if (child->Type() == NGLayoutInputNode::kLegacyBlock) { 446 if (child->Type() == NGLayoutInputNode::kLegacyBlock) {
448 NGBlockNode* current_block_child = toNGBlockNode(child); 447 NGBlockNode* current_block_child = toNGBlockNode(child);
449 EPosition position = current_block_child->Style().position(); 448 EPosition position = current_block_child->Style().position();
450 if (position == EPosition::kAbsolute || position == EPosition::kFixed) { 449 if (position == EPosition::kAbsolute || position == EPosition::kFixed) {
451 builder_->AddOutOfFlowChildCandidate(current_block_child, 450 builder_.AddOutOfFlowChildCandidate(current_block_child,
452 GetChildSpaceOffset()); 451 GetChildSpaceOffset());
453 NGBlockChildIterator::Entry entry = child_iterator.NextChild(); 452 NGBlockChildIterator::Entry entry = child_iterator.NextChild();
454 child = entry.node; 453 child = entry.node;
455 child_break_token = entry.token; 454 child_break_token = entry.token;
456 continue; 455 continue;
457 } 456 }
458 } 457 }
459 458
460 NGConstraintSpace* child_space = CreateConstraintSpaceForChild(child); 459 NGConstraintSpace* child_space = CreateConstraintSpaceForChild(child);
461 460
462 if (child->Type() == NGLayoutInputNode::kLegacyInline) { 461 if (child->Type() == NGLayoutInputNode::kLegacyInline) {
(...skipping 21 matching lines...) Expand all
484 content_size_ += border_and_padding_.block_end; 483 content_size_ += border_and_padding_.block_end;
485 if (border_and_padding_.block_end || 484 if (border_and_padding_.block_end ||
486 ConstraintSpace().IsNewFormattingContext()) { 485 ConstraintSpace().IsNewFormattingContext()) {
487 content_size_ += curr_margin_strut_.Sum(); 486 content_size_ += curr_margin_strut_.Sum();
488 curr_margin_strut_ = NGMarginStrut(); 487 curr_margin_strut_ = NGMarginStrut();
489 } 488 }
490 489
491 // Recompute the block-axis size now that we know our content size. 490 // Recompute the block-axis size now that we know our content size.
492 block_size = 491 block_size =
493 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); 492 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_);
494 builder_->SetBlockSize(block_size); 493 builder_.SetBlockSize(block_size);
495 494
496 // Layout our absolute and fixed positioned children. 495 // Layout our absolute and fixed positioned children.
497 NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), builder_.get()).Run(); 496 NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &builder_).Run();
498 497
499 // Non-empty blocks always know their position in space: 498 // Non-empty blocks always know their position in space:
500 if (block_size) { 499 if (block_size) {
501 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 500 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
502 UpdateFragmentBfcOffset(curr_bfc_offset_); 501 UpdateFragmentBfcOffset(curr_bfc_offset_);
503 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), 502 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
504 builder_.get()); 503 &builder_);
505 } 504 }
506 505
507 // Margins collapsing: 506 // Margins collapsing:
508 // Do not collapse margins between the last in-flow child and bottom margin 507 // Do not collapse margins between the last in-flow child and bottom margin
509 // of its parent if the parent has height != auto() 508 // of its parent if the parent has height != auto()
510 if (!Style().logicalHeight().isAuto()) { 509 if (!Style().logicalHeight().isAuto()) {
511 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight. 510 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight.
512 curr_margin_strut_ = NGMarginStrut(); 511 curr_margin_strut_ = NGMarginStrut();
513 } 512 }
514 builder_->SetEndMarginStrut(curr_margin_strut_); 513 builder_.SetEndMarginStrut(curr_margin_strut_);
515 514
516 builder_->SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_); 515 builder_.SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_);
517 516
518 if (ConstraintSpace().HasBlockFragmentation()) 517 if (ConstraintSpace().HasBlockFragmentation())
519 FinalizeForFragmentation(); 518 FinalizeForFragmentation();
520 519
521 return builder_->ToBoxFragment(); 520 return builder_.ToBoxFragment();
522 } 521 }
523 522
524 void NGBlockLayoutAlgorithm::LayoutInlineChildren( 523 void NGBlockLayoutAlgorithm::LayoutInlineChildren(
525 NGInlineNode* inline_child, 524 NGInlineNode* inline_child,
526 NGConstraintSpace* child_space) { 525 NGConstraintSpace* child_space) {
527 // TODO(kojii): This logic does not handle when children are mix of 526 // TODO(kojii): This logic does not handle when children are mix of
528 // inline/block. We need to detect the case and setup appropriately; e.g., 527 // inline/block. We need to detect the case and setup appropriately; e.g.,
529 // constraint space, margin collapsing, next siblings, etc. 528 // constraint space, margin collapsing, next siblings, etc.
530 NGLineBuilder line_builder(inline_child, child_space); 529 NGLineBuilder line_builder(inline_child, child_space);
531 // TODO(kojii): Need to determine when to invalidate PrepareLayout() more 530 // TODO(kojii): Need to determine when to invalidate PrepareLayout() more
(...skipping 14 matching lines...) Expand all
546 NGLayoutInputNode* child, 545 NGLayoutInputNode* child,
547 NGConstraintSpace* child_space, 546 NGConstraintSpace* child_space,
548 RefPtr<NGLayoutResult> layout_result) { 547 RefPtr<NGLayoutResult> layout_result) {
549 NGBoxFragment fragment( 548 NGBoxFragment fragment(
550 ConstraintSpace().WritingMode(), 549 ConstraintSpace().WritingMode(),
551 toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get())); 550 toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get()));
552 551
553 // Pull out unpositioned floats to the current fragment. This may needed if 552 // Pull out unpositioned floats to the current fragment. This may needed if
554 // for example the child fragment could not position its floats because it's 553 // for example the child fragment could not position its floats because it's
555 // empty and therefore couldn't determine its position in space. 554 // empty and therefore couldn't determine its position in space.
556 builder_->MutableUnpositionedFloats().appendVector( 555 builder_.MutableUnpositionedFloats().appendVector(
557 layout_result->UnpositionedFloats()); 556 layout_result->UnpositionedFloats());
558 557
559 if (child->Type() == NGLayoutInputNode::kLegacyBlock && 558 if (child->Type() == NGLayoutInputNode::kLegacyBlock &&
560 toNGBlockNode(child)->Style().isFloating()) { 559 toNGBlockNode(child)->Style().isFloating()) {
561 NGFloatingObject* floating_object = new NGFloatingObject( 560 NGFloatingObject* floating_object = new NGFloatingObject(
562 layout_result->PhysicalFragment().get(), child_space, constraint_space_, 561 layout_result->PhysicalFragment().get(), child_space, constraint_space_,
563 toNGBlockNode(child), toNGBlockNode(child)->Style(), 562 toNGBlockNode(child), toNGBlockNode(child)->Style(),
564 curr_child_margins_); 563 curr_child_margins_);
565 builder_->AddUnpositionedFloat(floating_object); 564 builder_.AddUnpositionedFloat(floating_object);
566 // No need to postpone the positioning if we know the correct offset. 565 // No need to postpone the positioning if we know the correct offset.
567 if (builder_->BfcOffset()) { 566 if (builder_.BfcOffset()) {
568 NGLogicalOffset origin_point = curr_bfc_offset_; 567 NGLogicalOffset origin_point = curr_bfc_offset_;
569 // Adjust origin point to the margins of the last child. 568 // Adjust origin point to the margins of the last child.
570 // Example: <div style="margin-bottom: 20px"><float></div> 569 // Example: <div style="margin-bottom: 20px"><float></div>
571 // <div style="margin-bottom: 30px"></div> 570 // <div style="margin-bottom: 30px"></div>
572 origin_point.block_offset += curr_margin_strut_.Sum(); 571 origin_point.block_offset += curr_margin_strut_.Sum();
573 PositionPendingFloats(origin_point.block_offset, ConstraintSpace(), 572 PositionPendingFloats(origin_point.block_offset, ConstraintSpace(),
574 builder_.get()); 573 &builder_);
575 } 574 }
576 return; 575 return;
577 } 576 }
578 577
579 // Determine the fragment's position in the parent space either by using 578 // Determine the fragment's position in the parent space either by using
580 // content_size_ or known fragment's BFC offset. 579 // content_size_ or known fragment's BFC offset.
581 WTF::Optional<NGLogicalOffset> bfc_offset; 580 WTF::Optional<NGLogicalOffset> bfc_offset;
582 if (child_space->IsNewFormattingContext()) { 581 if (child_space->IsNewFormattingContext()) {
583 // TODO(ikilpatrick): We may need to place ourself within the BFC 582 // TODO(ikilpatrick): We may need to place ourself within the BFC
584 // before a new formatting context child is laid out. (Not after layout as 583 // before a new formatting context child is laid out. (Not after layout as
585 // is done here). 584 // is done here).
586 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 585 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
587 bfc_offset = curr_bfc_offset_; 586 bfc_offset = curr_bfc_offset_;
588 } else if (fragment.BfcOffset()) { 587 } else if (fragment.BfcOffset()) {
589 // Fragment that knows its offset can be used to set parent's BFC position. 588 // Fragment that knows its offset can be used to set parent's BFC position.
590 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; 589 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset;
591 bfc_offset = curr_bfc_offset_; 590 bfc_offset = curr_bfc_offset_;
592 } else if (builder_->BfcOffset()) { 591 } else if (builder_.BfcOffset()) {
593 // Fragment doesn't know its offset but we can still calculate its BFC 592 // Fragment doesn't know its offset but we can still calculate its BFC
594 // position because the parent fragment's BFC is known. 593 // position because the parent fragment's BFC is known.
595 // Example: 594 // Example:
596 // BFC Offset is known here because of the padding. 595 // BFC Offset is known here because of the padding.
597 // <div style="padding: 1px"> 596 // <div style="padding: 1px">
598 // <div id="empty-div" style="margins: 1px"></div> 597 // <div id="empty-div" style="margins: 1px"></div>
599 bfc_offset = curr_bfc_offset_; 598 bfc_offset = curr_bfc_offset_;
600 bfc_offset.value().block_offset += curr_margin_strut_.Sum(); 599 bfc_offset.value().block_offset += curr_margin_strut_.Sum();
601 } 600 }
602 if (bfc_offset) { 601 if (bfc_offset) {
603 UpdateFragmentBfcOffset(curr_bfc_offset_); 602 UpdateFragmentBfcOffset(curr_bfc_offset_);
604 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), 603 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
605 builder_.get()); 604 &builder_);
606 } 605 }
607 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset); 606 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset);
608 607
609 // Update margin strut. 608 // Update margin strut.
610 curr_margin_strut_ = fragment.EndMarginStrut(); 609 curr_margin_strut_ = fragment.EndMarginStrut();
611 curr_margin_strut_.Append(curr_child_margins_.block_end); 610 curr_margin_strut_.Append(curr_child_margins_.block_end);
612 611
613 // Only modify content_size if BlockSize is not empty. It's needed to prevent 612 // Only modify content_size if BlockSize is not empty. It's needed to prevent
614 // the situation when logical_offset is included in content_size for empty 613 // the situation when logical_offset is included in content_size for empty
615 // blocks. Example: 614 // blocks. Example:
616 // <div style="overflow:hidden"> 615 // <div style="overflow:hidden">
617 // <div style="margin-top: 8px"></div> 616 // <div style="margin-top: 8px"></div>
618 // <div style="margin-top: 10px"></div> 617 // <div style="margin-top: 10px"></div>
619 // </div> 618 // </div>
620 if (fragment.BlockSize()) 619 if (fragment.BlockSize())
621 content_size_ = fragment.BlockSize() + logical_offset.block_offset; 620 content_size_ = fragment.BlockSize() + logical_offset.block_offset;
622 max_inline_size_ = 621 max_inline_size_ =
623 std::max(max_inline_size_, fragment.InlineSize() + 622 std::max(max_inline_size_, fragment.InlineSize() +
624 curr_child_margins_.InlineSum() + 623 curr_child_margins_.InlineSum() +
625 border_and_padding_.InlineSum()); 624 border_and_padding_.InlineSum());
626 625
627 builder_->AddChild(layout_result, logical_offset); 626 builder_.AddChild(layout_result, logical_offset);
628 } 627 }
629 628
630 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { 629 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
631 LayoutUnit used_block_size = 630 LayoutUnit used_block_size =
632 break_token_ ? break_token_->UsedBlockSize() : LayoutUnit(); 631 break_token_ ? break_token_->UsedBlockSize() : LayoutUnit();
633 LayoutUnit block_size = ComputeBlockSizeForFragment( 632 LayoutUnit block_size = ComputeBlockSizeForFragment(
634 ConstraintSpace(), Style(), used_block_size + content_size_); 633 ConstraintSpace(), Style(), used_block_size + content_size_);
635 634
636 block_size -= used_block_size; 635 block_size -= used_block_size;
637 DCHECK_GE(block_size, LayoutUnit()) 636 DCHECK_GE(block_size, LayoutUnit())
638 << "Adding and subtracting the used_block_size shouldn't leave the " 637 << "Adding and subtracting the used_block_size shouldn't leave the "
639 "block_size for this fragment smaller than zero."; 638 "block_size for this fragment smaller than zero.";
640 639
641 DCHECK(builder_->BfcOffset()) << "We must have our BfcOffset by this point " 640 DCHECK(builder_.BfcOffset()) << "We must have our BfcOffset by this point "
642 "to determine the space left in the flow."; 641 "to determine the space left in the flow.";
643 LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable() - 642 LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable() -
644 builder_->BfcOffset().value().block_offset; 643 builder_.BfcOffset().value().block_offset;
645 DCHECK_GE(space_left, LayoutUnit()); 644 DCHECK_GE(space_left, LayoutUnit());
646 645
647 if (builder_->DidBreak()) { 646 if (builder_.DidBreak()) {
648 // One of our children broke. Even if we fit within the remaining space we 647 // One of our children broke. Even if we fit within the remaining space we
649 // need to prepare a break token. 648 // need to prepare a break token.
650 builder_->SetUsedBlockSize(std::min(space_left, block_size) + 649 builder_.SetUsedBlockSize(std::min(space_left, block_size) +
651 used_block_size); 650 used_block_size);
652 builder_->SetBlockSize(std::min(space_left, block_size)); 651 builder_.SetBlockSize(std::min(space_left, block_size));
653 builder_->SetBlockOverflow(space_left); 652 builder_.SetBlockOverflow(space_left);
654 return; 653 return;
655 } 654 }
656 655
657 if (block_size > space_left) { 656 if (block_size > space_left) {
658 // Need a break inside this block. 657 // Need a break inside this block.
659 builder_->SetUsedBlockSize(space_left + used_block_size); 658 builder_.SetUsedBlockSize(space_left + used_block_size);
660 builder_->SetBlockSize(space_left); 659 builder_.SetBlockSize(space_left);
661 builder_->SetBlockOverflow(space_left); 660 builder_.SetBlockOverflow(space_left);
662 return; 661 return;
663 } 662 }
664 663
665 // The end of the block fits in the current fragmentainer. 664 // The end of the block fits in the current fragmentainer.
666 builder_->SetBlockSize(block_size); 665 builder_.SetBlockSize(block_size);
667 builder_->SetBlockOverflow(content_size_); 666 builder_.SetBlockOverflow(content_size_);
668 } 667 }
669 668
670 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins( 669 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
671 NGBlockNode* child, 670 NGBlockNode* child,
672 const NGConstraintSpace& space) { 671 const NGConstraintSpace& space) {
673 DCHECK(child); 672 DCHECK(child);
674 const ComputedStyle& child_style = child->Style(); 673 const ComputedStyle& child_style = child->Style();
675 674
676 WTF::Optional<MinAndMaxContentSizes> sizes; 675 WTF::Optional<MinAndMaxContentSizes> sizes;
677 if (NeedMinAndMaxContentSizes(space, child_style)) 676 if (NeedMinAndMaxContentSizes(space, child_style))
(...skipping 13 matching lines...) Expand all
691 NGLayoutInputNode* child) { 690 NGLayoutInputNode* child) {
692 DCHECK(child); 691 DCHECK(child);
693 692
694 if (child->Type() == NGLayoutInputNode::kLegacyInline) { 693 if (child->Type() == NGLayoutInputNode::kLegacyInline) {
695 // TODO(kojii): Setup space_builder_ appropriately for inline child. 694 // TODO(kojii): Setup space_builder_ appropriately for inline child.
696 695
697 // Margins collapsing: Inline block. 696 // Margins collapsing: Inline block.
698 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 697 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
699 UpdateFragmentBfcOffset(curr_bfc_offset_); 698 UpdateFragmentBfcOffset(curr_bfc_offset_);
700 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), 699 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
701 builder_.get()); 700 &builder_);
702 curr_margin_strut_ = {}; 701 curr_margin_strut_ = {};
703 702
704 return space_builder_->ToConstraintSpace( 703 return space_builder_.ToConstraintSpace(
705 FromPlatformWritingMode(Style().getWritingMode())); 704 FromPlatformWritingMode(Style().getWritingMode()));
706 } 705 }
707 706
708 NGBlockNode* block_child = toNGBlockNode(child); 707 NGBlockNode* block_child = toNGBlockNode(child);
709 const ComputedStyle& child_style = block_child->Style(); 708 const ComputedStyle& child_style = block_child->Style();
710 709
711 // Calculate margins in parent's writing mode. 710 // Calculate margins in parent's writing mode.
712 curr_child_margins_ = CalculateMargins( 711 curr_child_margins_ = CalculateMargins(
713 block_child, *space_builder_->ToConstraintSpace( 712 block_child, *space_builder_.ToConstraintSpace(
714 FromPlatformWritingMode(Style().getWritingMode()))); 713 FromPlatformWritingMode(Style().getWritingMode())));
715 714
716 bool is_new_bfc = IsNewFormattingContextForInFlowBlockLevelChild( 715 bool is_new_bfc = IsNewFormattingContextForInFlowBlockLevelChild(
717 ConstraintSpace(), child_style); 716 ConstraintSpace(), child_style);
718 space_builder_->SetIsNewFormattingContext(is_new_bfc) 717 space_builder_.SetIsNewFormattingContext(is_new_bfc)
719 .SetIsShrinkToFit(ShouldShrinkToFit(ConstraintSpace(), child_style)) 718 .SetIsShrinkToFit(ShouldShrinkToFit(ConstraintSpace(), child_style))
720 .SetTextDirection(child_style.direction()); 719 .SetTextDirection(child_style.direction());
721 720
722 // Clearance : 721 // Clearance :
723 // - *Always* collapse margins and update *container*'s BFC offset. 722 // - *Always* collapse margins and update *container*'s BFC offset.
724 // - Position all pending floats since the fragment's BFC offset is known. 723 // - Position all pending floats since the fragment's BFC offset is known.
725 // - Set the clearance offset on the constraint space's builder. 724 // - Set the clearance offset on the constraint space's builder.
726 if (child_style.clear() != EClear::kNone) { 725 if (child_style.clear() != EClear::kNone) {
727 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 726 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
728 UpdateFragmentBfcOffset(curr_bfc_offset_); 727 UpdateFragmentBfcOffset(curr_bfc_offset_);
729 // Only collapse margins if it's an adjoining block with clearance. 728 // Only collapse margins if it's an adjoining block with clearance.
730 if (!content_size_) { 729 if (!content_size_) {
731 curr_margin_strut_ = NGMarginStrut(); 730 curr_margin_strut_ = NGMarginStrut();
732 curr_child_margins_.block_start = LayoutUnit(); 731 curr_child_margins_.block_start = LayoutUnit();
733 } 732 }
734 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), 733 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
735 builder_.get()); 734 &builder_);
736 WTF::Optional<LayoutUnit> clearance_offset = 735 WTF::Optional<LayoutUnit> clearance_offset =
737 GetClearanceOffset(constraint_space_->Exclusions(), child_style); 736 GetClearanceOffset(constraint_space_->Exclusions(), child_style);
738 space_builder_->SetClearanceOffset(clearance_offset); 737 space_builder_.SetClearanceOffset(clearance_offset);
739 } 738 }
740 739
741 // Set estimated BFC offset to the next child's constraint space. 740 // Set estimated BFC offset to the next child's constraint space.
742 curr_bfc_offset_ = builder_->BfcOffset() ? builder_->BfcOffset().value() 741 curr_bfc_offset_ = builder_.BfcOffset() ? builder_.BfcOffset().value()
743 : ConstraintSpace().BfcOffset(); 742 : ConstraintSpace().BfcOffset();
744 curr_bfc_offset_.block_offset += content_size_; 743 curr_bfc_offset_.block_offset += content_size_;
745 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; 744 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start;
746 745
747 // Floats margins are not included in child's CS because 746 // Floats margins are not included in child's CS because
748 // 1) Floats do not participate in margins collapsing 747 // 1) Floats do not participate in margins collapsing
749 // 2) Floats margins are used separately to calculate floating exclusions. 748 // 2) Floats margins are used separately to calculate floating exclusions.
750 if (!child_style.isFloating()) { 749 if (!child_style.isFloating()) {
751 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; 750 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start;
752 // Append the current margin strut with child's block start margin. 751 // Append the current margin strut with child's block start margin.
753 // Non empty border/padding use cases are handled inside of the child's 752 // Non empty border/padding use cases are handled inside of the child's
754 // layout. 753 // layout.
755 curr_margin_strut_.Append(curr_child_margins_.block_start); 754 curr_margin_strut_.Append(curr_child_margins_.block_start);
756 space_builder_->SetMarginStrut(curr_margin_strut_); 755 space_builder_.SetMarginStrut(curr_margin_strut_);
757 } 756 }
758 757
759 space_builder_->SetBfcOffset(curr_bfc_offset_); 758 space_builder_.SetBfcOffset(curr_bfc_offset_);
760 759
761 LayoutUnit space_available; 760 LayoutUnit space_available;
762 if (constraint_space_->HasBlockFragmentation()) { 761 if (constraint_space_->HasBlockFragmentation()) {
763 space_available = ConstraintSpace().FragmentainerSpaceAvailable(); 762 space_available = ConstraintSpace().FragmentainerSpaceAvailable();
764 // If a block establishes a new formatting context we must know our 763 // If a block establishes a new formatting context we must know our
765 // position in the formatting context, and are able to adjust the 764 // position in the formatting context, and are able to adjust the
766 // fragmentation line. 765 // fragmentation line.
767 if (is_new_bfc) { 766 if (is_new_bfc) {
768 DCHECK(builder_->BfcOffset()); 767 DCHECK(builder_.BfcOffset());
769 space_available -= curr_bfc_offset_.block_offset; 768 space_available -= curr_bfc_offset_.block_offset;
770 } 769 }
771 } 770 }
772 space_builder_->SetFragmentainerSpaceAvailable(space_available); 771 space_builder_.SetFragmentainerSpaceAvailable(space_available);
773 772
774 return space_builder_->ToConstraintSpace( 773 return space_builder_.ToConstraintSpace(
775 FromPlatformWritingMode(child_style.getWritingMode())); 774 FromPlatformWritingMode(child_style.getWritingMode()));
776 } 775 }
777 } // namespace blink 776 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698