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

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

Issue 2693193002: [LayoutNG] A different approach to multi-col. (Closed)
Patch Set: Created 3 years, 10 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_box_fragment.h" 9 #include "core/layout/ng/ng_box_fragment.h"
10 #include "core/layout/ng/ng_column_mapper.h" 10 #include "core/layout/ng/ng_column_mapper.h"
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 293
294 if (space.WritingMode() != FromPlatformWritingMode(style.getWritingMode())) 294 if (space.WritingMode() != FromPlatformWritingMode(style.getWritingMode()))
295 return true; 295 return true;
296 296
297 return false; 297 return false;
298 } 298 }
299 299
300 } // namespace 300 } // namespace
301 301
302 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( 302 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(
303 LayoutObject* layout_object, 303 NGBlockNode* node,
304 PassRefPtr<const ComputedStyle> style,
305 NGLayoutInputNode* first_child,
306 NGConstraintSpace* constraint_space, 304 NGConstraintSpace* constraint_space,
307 NGBreakToken* break_token) 305 NGBlockBreakToken* break_token)
308 : style_(style), 306 : style_(node->Style()),
309 first_child_(first_child), 307 first_child_(node->FirstChild()),
310 constraint_space_(constraint_space), 308 constraint_space_(constraint_space),
311 break_token_(break_token), 309 break_token_(break_token),
312 builder_(WTF::wrapUnique( 310 builder_(WTF::wrapUnique(
313 new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox, 311 new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox, node))),
314 layout_object))) { 312 child_iterator_(WTF::wrapUnique(
313 new NGBlockLayoutChildIterator(first_child_, break_token))) {
315 DCHECK(style_); 314 DCHECK(style_);
316 } 315 }
317 316
318 Optional<MinAndMaxContentSizes> 317 Optional<MinAndMaxContentSizes>
319 NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes() const { 318 NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes() const {
320 MinAndMaxContentSizes sizes; 319 MinAndMaxContentSizes sizes;
321 320
322 // Size-contained elements don't consider their contents for intrinsic sizing. 321 // Size-contained elements don't consider their contents for intrinsic sizing.
323 if (Style().containsSize()) 322 if (Style().containsSize())
324 return sizes; 323 return sizes;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 builder_->BfcOffset().value().block_offset; 356 builder_->BfcOffset().value().block_offset;
358 } 357 }
359 return {inline_offset, block_offset}; 358 return {inline_offset, block_offset};
360 } 359 }
361 360
362 RefPtr<NGPhysicalFragment> NGBlockLayoutAlgorithm::Layout() { 361 RefPtr<NGPhysicalFragment> NGBlockLayoutAlgorithm::Layout() {
363 WTF::Optional<MinAndMaxContentSizes> sizes; 362 WTF::Optional<MinAndMaxContentSizes> sizes;
364 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) 363 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style()))
365 sizes = ComputeMinAndMaxContentSizes(); 364 sizes = ComputeMinAndMaxContentSizes();
366 365
366 // TODO(ikilpatrick): should be no borders or padding if anon.
367 border_and_padding_ = 367 border_and_padding_ =
368 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style()); 368 ComputeBorders(Style()) + ComputePadding(ConstraintSpace(), Style());
369 369
370 LayoutUnit inline_size = 370 LayoutUnit inline_size =
371 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes); 371 ComputeInlineSizeForFragment(ConstraintSpace(), Style(), sizes);
372 LayoutUnit adjusted_inline_size = 372 LayoutUnit adjusted_inline_size =
373 inline_size - border_and_padding_.InlineSum(); 373 inline_size - border_and_padding_.InlineSum();
374 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of 374 // TODO(layout-ng): For quirks mode, should we pass blockSize instead of
375 // -1? 375 // -1?
376 LayoutUnit block_size = 376 LayoutUnit block_size =
377 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite); 377 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), NGSizeIndefinite);
378 LayoutUnit adjusted_block_size(block_size); 378 LayoutUnit adjusted_block_size(block_size);
379 // Our calculated block-axis size may be indefinite at this point. 379 // Our calculated block-axis size may be indefinite at this point.
380 // If so, just leave the size as NGSizeIndefinite instead of subtracting 380 // If so, just leave the size as NGSizeIndefinite instead of subtracting
381 // borders and padding. 381 // borders and padding.
382 if (adjusted_block_size != NGSizeIndefinite) 382 if (adjusted_block_size != NGSizeIndefinite)
383 adjusted_block_size -= border_and_padding_.BlockSum(); 383 adjusted_block_size -= border_and_padding_.BlockSum();
384 384
385 space_builder_ = new NGConstraintSpaceBuilder(constraint_space_); 385 space_builder_ = new NGConstraintSpaceBuilder(constraint_space_);
386 if (Style().specifiesColumns()) { 386 space_builder_
387 space_builder_->SetFragmentationType(kFragmentColumn); 387 ->SetAvailableSize(
388 adjusted_inline_size = 388 NGLogicalSize(adjusted_inline_size, adjusted_block_size))
389 ResolveUsedColumnInlineSize(adjusted_inline_size, Style()); 389 .SetPercentageResolutionSize(
390 LayoutUnit inline_progression = 390 NGLogicalSize(adjusted_inline_size, adjusted_block_size));
391 adjusted_inline_size + ResolveUsedColumnGap(Style());
392 fragmentainer_mapper_ =
393 new NGColumnMapper(inline_progression, adjusted_block_size);
394 }
395 space_builder_->SetAvailableSize(
396 NGLogicalSize(adjusted_inline_size, adjusted_block_size));
397 space_builder_->SetPercentageResolutionSize(
398 NGLogicalSize(adjusted_inline_size, adjusted_block_size));
399 391
400 builder_->SetDirection(constraint_space_->Direction()); 392 builder_->SetDirection(constraint_space_->Direction());
401 builder_->SetWritingMode(constraint_space_->WritingMode()); 393 builder_->SetWritingMode(constraint_space_->WritingMode());
402 builder_->SetInlineSize(inline_size).SetBlockSize(block_size); 394 builder_->SetInlineSize(inline_size).SetBlockSize(block_size);
403 395
404 // TODO(glebl): fix multicol after the new margin collapsing/floats algorithm 396 std::tie(current_child_, current_child_break_token_) =
405 // based on BFCOffset is checked in. 397 child_iterator_->NextChild();
406 if (NGBlockBreakToken* token = CurrentBlockBreakToken()) { 398
407 // Resume after a previous break. 399 content_size_ =
408 content_size_ = token->BreakOffset(); 400 break_token_ ? LayoutUnit(0) : border_and_padding_.block_start;
mstensho (USE GERRIT) 2017/02/15 21:12:22 Should use LayoutUnit() instead of LayoutUnit(0),
409 current_child_ = token->InputNode();
410 } else {
411 content_size_ = border_and_padding_.block_start;
412 current_child_ = first_child_;
413 }
414 401
415 curr_margin_strut_ = ConstraintSpace().MarginStrut(); 402 curr_margin_strut_ = ConstraintSpace().MarginStrut();
416 curr_bfc_offset_ = ConstraintSpace().BfcOffset(); 403 curr_bfc_offset_ = ConstraintSpace().BfcOffset();
417 404
418 // Margins collapsing: 405 // Margins collapsing:
419 // Do not collapse margins between parent and its child if there is 406 // Do not collapse margins between parent and its child if there is
420 // border/padding between them. 407 // border/padding between them.
421 if (border_and_padding_.block_start || 408 if (border_and_padding_.block_start ||
422 ConstraintSpace().IsNewFormattingContext()) { 409 ConstraintSpace().IsNewFormattingContext()) {
423 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 410 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
424 builder_->SetBfcOffset(curr_bfc_offset_); 411 builder_->SetBfcOffset(curr_bfc_offset_);
425 curr_margin_strut_ = NGMarginStrut(); 412 curr_margin_strut_ = NGMarginStrut();
426 } 413 }
427 curr_bfc_offset_.block_offset += content_size_; 414 curr_bfc_offset_.block_offset += content_size_;
428 415
429 while (current_child_) { 416 while (current_child_) {
430 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock) { 417 if (current_child_->Type() == NGLayoutInputNode::kLegacyBlock) {
431 NGBlockNode* current_block_child = toNGBlockNode(current_child_); 418 NGBlockNode* current_block_child = toNGBlockNode(current_child_);
432 EPosition position = current_block_child->Style().position(); 419 EPosition position = current_block_child->Style().position();
433 if (position == AbsolutePosition || position == FixedPosition) { 420 if (position == AbsolutePosition || position == FixedPosition) {
434 builder_->AddOutOfFlowChildCandidate(current_block_child, 421 builder_->AddOutOfFlowChildCandidate(current_block_child,
435 GetChildSpaceOffset()); 422 GetChildSpaceOffset());
436 current_child_ = current_block_child->NextSibling(); 423 current_child_ = current_block_child->NextSibling();
437 continue; 424 continue;
438 } 425 }
439 } 426 }
440 427
441 DCHECK(!ConstraintSpace().HasBlockFragmentation() ||
442 SpaceAvailableForCurrentChild() > LayoutUnit());
443 space_for_current_child_ = CreateConstraintSpaceForCurrentChild(); 428 space_for_current_child_ = CreateConstraintSpaceForCurrentChild();
444 429
445 if (current_child_->Type() == NGLayoutInputNode::kLegacyInline) { 430 if (current_child_->Type() == NGLayoutInputNode::kLegacyInline) {
446 LayoutInlineChildren(toNGInlineNode(current_child_)); 431 LayoutInlineChildren(toNGInlineNode(current_child_));
447 continue; 432 continue;
448 } 433 }
449 434
450 RefPtr<NGPhysicalFragment> physical_fragment = 435 RefPtr<NGPhysicalFragment> physical_fragment =
451 current_child_->Layout(space_for_current_child_); 436 current_child_->Layout(space_for_current_child_);
452 437
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 } 486 }
502 487
503 void NGBlockLayoutAlgorithm::LayoutInlineChildren(NGInlineNode* current_child) { 488 void NGBlockLayoutAlgorithm::LayoutInlineChildren(NGInlineNode* current_child) {
504 // TODO(kojii): This logic does not handle when children are mix of 489 // TODO(kojii): This logic does not handle when children are mix of
505 // inline/block. We need to detect the case and setup appropriately; e.g., 490 // inline/block. We need to detect the case and setup appropriately; e.g.,
506 // constraint space, margin collapsing, next siblings, etc. 491 // constraint space, margin collapsing, next siblings, etc.
507 NGLineBuilder line_builder(current_child, space_for_current_child_); 492 NGLineBuilder line_builder(current_child, space_for_current_child_);
508 current_child->LayoutInline(space_for_current_child_, &line_builder); 493 current_child->LayoutInline(space_for_current_child_, &line_builder);
509 // TODO(kojii): The wrapper fragment should not be needed. 494 // TODO(kojii): The wrapper fragment should not be needed.
510 NGFragmentBuilder wrapper_fragment_builder(NGPhysicalFragment::kFragmentBox, 495 NGFragmentBuilder wrapper_fragment_builder(NGPhysicalFragment::kFragmentBox,
511 current_child->GetLayoutObject()); 496 current_child);
512 line_builder.CreateFragments(&wrapper_fragment_builder); 497 line_builder.CreateFragments(&wrapper_fragment_builder);
513 RefPtr<NGPhysicalBoxFragment> child_fragment = 498 RefPtr<NGPhysicalBoxFragment> child_fragment =
514 wrapper_fragment_builder.ToBoxFragment(); 499 wrapper_fragment_builder.ToBoxFragment();
515 line_builder.CopyFragmentDataToLayoutBlockFlow(); 500 line_builder.CopyFragmentDataToLayoutBlockFlow();
516 FinishCurrentChildLayout(child_fragment.get()); 501 FinishCurrentChildLayout(child_fragment.get());
517 current_child_ = nullptr; 502 current_child_ = nullptr;
518 } 503 }
519 504
520 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout( 505 void NGBlockLayoutAlgorithm::FinishCurrentChildLayout(
521 RefPtr<NGPhysicalBoxFragment> physical_fragment) { 506 RefPtr<NGPhysicalBoxFragment> physical_fragment) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; 546 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset;
562 bfc_offset = curr_bfc_offset_; 547 bfc_offset = curr_bfc_offset_;
563 } 548 }
564 if (bfc_offset) { 549 if (bfc_offset) {
565 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get()); 550 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
566 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(), 551 PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
567 builder_.get()); 552 builder_.get());
568 } 553 }
569 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset); 554 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset);
570 555
571 if (fragmentainer_mapper_)
572 fragmentainer_mapper_->ToVisualOffset(logical_offset);
mstensho (USE GERRIT) 2017/02/15 21:12:22 Is the plan to replace the fragmentainer mapper wi
ikilpatrick 2017/02/16 16:48:31 Yeah i think most of the logic inside the fragment
573 else
574 logical_offset.block_offset -= PreviousBreakOffset();
575
576 // Update margin strut. 556 // Update margin strut.
577 curr_margin_strut_ = fragment.EndMarginStrut(); 557 curr_margin_strut_ = fragment.EndMarginStrut();
578 curr_margin_strut_.Append(curr_child_margins_.block_end); 558 curr_margin_strut_.Append(curr_child_margins_.block_end);
579 559
580 content_size_ = fragment.BlockSize() + logical_offset.block_offset; 560 content_size_ = fragment.BlockSize() + logical_offset.block_offset;
581 max_inline_size_ = 561 max_inline_size_ =
582 std::max(max_inline_size_, fragment.InlineSize() + 562 std::max(max_inline_size_, fragment.InlineSize() +
583 curr_child_margins_.InlineSum() + 563 curr_child_margins_.InlineSum() +
584 border_and_padding_.InlineSum()); 564 border_and_padding_.InlineSum());
585 565
586 builder_->AddChild(std::move(physical_fragment), logical_offset); 566 builder_->AddChild(std::move(physical_fragment), logical_offset);
587 } 567 }
588 568
589 bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling( 569 bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling(
590 NGPhysicalFragment* child_fragment) { 570 NGPhysicalFragment* child_fragment) {
591 DCHECK(current_child_); 571 DCHECK(current_child_);
592 NGBlockNode* finished_child = toNGBlockNode(current_child_); 572 std::tie(current_child_, current_child_break_token_) =
593 current_child_ = current_child_->NextSibling(); 573 child_iterator_->NextChild();
594 if (!ConstraintSpace().HasBlockFragmentation() && !fragmentainer_mapper_)
595 return true;
596 // If we're resuming layout after a fragmentainer break, we need to skip
597 // siblings that we're done with. We may have been able to fully lay out some
598 // node(s) preceding a node that we had to break inside (and therefore were
599 // not able to fully lay out). This happens when we have parallel flows [1],
600 // which are caused by floats, overflow, etc.
601 //
602 // [1] https://drafts.csswg.org/css-break/#parallel-flows
603 if (CurrentBlockBreakToken()) {
604 // TODO(layout-ng): Figure out if we need a better way to determine if the
605 // node is finished. Maybe something to encode in a break token?
606 // TODO(kojii): Handle inline children.
607 while (current_child_ &&
608 current_child_->Type() == NGLayoutInputNode::kLegacyBlock &&
609 toNGBlockNode(current_child_)->IsLayoutFinished()) {
610 current_child_ = current_child_->NextSibling();
611 }
612 }
613 LayoutUnit break_offset = NextBreakOffset();
614 bool is_out_of_space = content_size_ - PreviousBreakOffset() >= break_offset;
615 if (!HasPendingBreakToken()) {
616 bool child_broke = child_fragment->BreakToken();
617 // This block needs to break if the child broke, or if we're out of space
618 // and there's more content waiting to be laid out. Otherwise, just bail
619 // now.
620 if (!child_broke && (!is_out_of_space || !current_child_))
621 return true;
622 // Prepare a break token for this block, so that we know where to resume
623 // when the time comes for that. We may not be able to abort layout of this
624 // block right away, due to the posibility of parallel flows. We can only
625 // abort when we're out of space, or when there are no siblings left to
626 // process.
627 NGBlockBreakToken* token;
628 if (child_broke) {
629 // The child we just laid out was the first one to break. So that is
630 // where we need to resume.
631 token = new NGBlockBreakToken(finished_child, break_offset);
632 } else {
633 // Resume layout at the next sibling that needs layout.
634 DCHECK(current_child_);
635 token =
636 new NGBlockBreakToken(toNGBlockNode(current_child_), break_offset);
637 }
638 SetPendingBreakToken(token);
639 }
640 574
641 if (!fragmentainer_mapper_) { 575 bool is_out_of_space =
642 if (!is_out_of_space) 576 constraint_space_->HasBlockFragmentation()
643 return true; 577 ? content_size_ >= constraint_space_->FragmentainerSpaceAvailable()
mstensho (USE GERRIT) 2017/02/15 21:12:22 All you need is: constraint_space_->HasBlockFragme
644 // We have run out of space in this flow, so there's no work left to do for 578 : false;
645 // this block in this fragmentainer. We should finalize the fragment and get 579
646 // back to the remaining content when laying out the next fragmentainer(s). 580 // We have run out of space in this flow, so there's no work left to do for
581 // this block in this fragmentainer. We should finalize the fragment and get
582 // back to the remaining content when laying out the next fragmentainer(s).
583 if (is_out_of_space)
647 return false; 584 return false;
648 }
649 585
650 if (is_out_of_space || !current_child_) { 586 return current_child_;
651 NGBlockBreakToken* token = fragmentainer_mapper_->Advance();
652 DCHECK(token || !is_out_of_space);
653 if (token) {
654 break_token_ = token;
655 content_size_ = token->BreakOffset();
656 current_child_ = token->InputNode();
657 }
658 }
659 return true;
660 }
661
662 void NGBlockLayoutAlgorithm::SetPendingBreakToken(NGBlockBreakToken* token) {
663 if (fragmentainer_mapper_)
664 fragmentainer_mapper_->SetBreakToken(token);
665 else
666 builder_->SetBreakToken(token);
667 }
668
669 bool NGBlockLayoutAlgorithm::HasPendingBreakToken() const {
670 if (fragmentainer_mapper_)
671 return fragmentainer_mapper_->HasBreakToken();
672 return builder_->HasBreakToken();
673 } 587 }
674 588
675 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { 589 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
676 LayoutUnit block_size = 590 LayoutUnit used_block_size =
677 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); 591 break_token_ ? break_token_->UsedBlockSize() : LayoutUnit();
678 LayoutUnit previous_break_offset = PreviousBreakOffset(); 592 LayoutUnit block_size = ComputeBlockSizeForFragment(
679 block_size -= previous_break_offset; 593 ConstraintSpace(), Style(), used_block_size + content_size_);
680 block_size = std::max(LayoutUnit(), block_size); 594
681 LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable(); 595 if (!block_size)
596 return;
597
598 block_size -= used_block_size;
599 DCHECK_GE(block_size, LayoutUnit());
600
601 // This is relative to the bfc offset, we should have this if non-zero block
602 // size.
603 DCHECK(builder_->BfcOffset());
604 LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable() -
605 builder_->BfcOffset().value().block_offset;
682 DCHECK_GE(space_left, LayoutUnit()); 606 DCHECK_GE(space_left, LayoutUnit());
683 if (builder_->HasBreakToken()) { 607
608 if (builder_->DidBreak()) {
684 // A break token is ready, which means that we're going to break 609 // A break token is ready, which means that we're going to break
685 // before or inside a block-level child. 610 // before or inside a block-level child.
611 builder_->SetUsedBlockSize(std::min(space_left, block_size) +
612 used_block_size);
686 builder_->SetBlockSize(std::min(space_left, block_size)); 613 builder_->SetBlockSize(std::min(space_left, block_size));
687 builder_->SetBlockOverflow(space_left); 614 builder_->SetBlockOverflow(space_left);
688 return; 615 return;
689 } 616 }
617
690 if (block_size > space_left) { 618 if (block_size > space_left) {
691 // Need a break inside this block. 619 // Need a break inside this block.
692 builder_->SetBreakToken(new NGBlockBreakToken(nullptr, NextBreakOffset())); 620 builder_->SetUsedBlockSize(space_left + used_block_size);
693 builder_->SetBlockSize(space_left); 621 builder_->SetBlockSize(space_left);
694 builder_->SetBlockOverflow(space_left); 622 builder_->SetBlockOverflow(space_left);
695 return; 623 return;
696 } 624 }
625
697 // The end of the block fits in the current fragmentainer. 626 // The end of the block fits in the current fragmentainer.
698 builder_->SetBlockSize(block_size); 627 builder_->SetBlockSize(block_size);
699 builder_->SetBlockOverflow(content_size_ - previous_break_offset); 628 builder_->SetBlockOverflow(content_size_);
700 }
701
702 NGBlockBreakToken* NGBlockLayoutAlgorithm::CurrentBlockBreakToken() const {
703 NGBreakToken* token = break_token_;
704 if (!token || token->Type() != NGBreakToken::kBlockBreakToken)
705 return nullptr;
706 return toNGBlockBreakToken(token);
707 }
708
709 LayoutUnit NGBlockLayoutAlgorithm::PreviousBreakOffset() const {
710 const NGBlockBreakToken* token = CurrentBlockBreakToken();
711 return token ? token->BreakOffset() : LayoutUnit();
712 }
713
714 LayoutUnit NGBlockLayoutAlgorithm::NextBreakOffset() const {
715 if (fragmentainer_mapper_)
716 return fragmentainer_mapper_->NextBreakOffset();
717 DCHECK(ConstraintSpace().HasBlockFragmentation());
718 return PreviousBreakOffset() +
719 ConstraintSpace().FragmentainerSpaceAvailable();
720 }
721
722 LayoutUnit NGBlockLayoutAlgorithm::SpaceAvailableForCurrentChild() const {
723 LayoutUnit space_left;
724 if (fragmentainer_mapper_)
725 space_left = fragmentainer_mapper_->BlockSize();
726 else if (ConstraintSpace().HasBlockFragmentation())
727 space_left = ConstraintSpace().FragmentainerSpaceAvailable();
728 else
729 return NGSizeIndefinite;
730 space_left -= BorderEdgeForCurrentChild() - PreviousBreakOffset();
731 return space_left;
732 } 629 }
733 630
734 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins( 631 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
735 const NGConstraintSpace& space, 632 const NGConstraintSpace& space,
736 const ComputedStyle& style) { 633 const ComputedStyle& style) {
737 WTF::Optional<MinAndMaxContentSizes> sizes; 634 WTF::Optional<MinAndMaxContentSizes> sizes;
738 if (NeedMinAndMaxContentSizes(space, style)) { 635 if (NeedMinAndMaxContentSizes(space, style)) {
739 // TODO(ikilpatrick): Change ComputeMinAndMaxContentSizes to return 636 // TODO(ikilpatrick): Change ComputeMinAndMaxContentSizes to return
740 // MinAndMaxContentSizes. 637 // MinAndMaxContentSizes.
741 sizes = toNGBlockNode(current_child_)->ComputeMinAndMaxContentSizes(); 638 sizes = toNGBlockNode(current_child_)->ComputeMinAndMaxContentSizes();
(...skipping 21 matching lines...) Expand all
763 660
764 const ComputedStyle& current_child_style = CurrentChildStyle(); 661 const ComputedStyle& current_child_style = CurrentChildStyle();
765 bool is_new_bfc = IsNewFormattingContextForInFlowBlockLevelChild( 662 bool is_new_bfc = IsNewFormattingContextForInFlowBlockLevelChild(
766 ConstraintSpace(), current_child_style); 663 ConstraintSpace(), current_child_style);
767 space_builder_->SetIsNewFormattingContext(is_new_bfc) 664 space_builder_->SetIsNewFormattingContext(is_new_bfc)
768 .SetIsShrinkToFit( 665 .SetIsShrinkToFit(
769 ShouldShrinkToFit(ConstraintSpace(), CurrentChildStyle())) 666 ShouldShrinkToFit(ConstraintSpace(), CurrentChildStyle()))
770 .SetWritingMode( 667 .SetWritingMode(
771 FromPlatformWritingMode(current_child_style.getWritingMode())) 668 FromPlatformWritingMode(current_child_style.getWritingMode()))
772 .SetTextDirection(current_child_style.direction()); 669 .SetTextDirection(current_child_style.direction());
773 LayoutUnit space_available = SpaceAvailableForCurrentChild();
774 space_builder_->SetFragmentainerSpaceAvailable(space_available);
775 670
776 // Clearance : 671 // Clearance :
777 // - Collapse margins 672 // - Collapse margins
778 // - Update curr_bfc_offset and parent BFC offset if needed. 673 // - Update curr_bfc_offset and parent BFC offset if needed.
779 // - Position all pending floats as position is known now. 674 // - Position all pending floats as position is known now.
780 // TODO(glebl): Fix the use case with clear: left and an intruding right. 675 // TODO(glebl): Fix the use case with clear: left and an intruding right.
781 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847 676 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847
782 if (current_child_style.clear() != EClear::kNone) { 677 if (current_child_style.clear() != EClear::kNone) {
783 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 678 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
784 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get()); 679 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
(...skipping 21 matching lines...) Expand all
806 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; 701 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start;
807 702
808 // Floats margins are not included in child's CS because they are used to 703 // Floats margins are not included in child's CS because they are used to
809 // calculate floating exclusions. 704 // calculate floating exclusions.
810 if (!CurrentChildStyle().isFloating()) { 705 if (!CurrentChildStyle().isFloating()) {
811 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; 706 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start;
812 } 707 }
813 708
814 space_builder_->SetBfcOffset(curr_bfc_offset_); 709 space_builder_->SetBfcOffset(curr_bfc_offset_);
815 710
711 if (constraint_space_->HasBlockFragmentation()) {
712 LayoutUnit space_available =
713 ConstraintSpace().FragmentainerSpaceAvailable();
714 if (builder_->BfcOffset()) {
715 // TODO(ikilpatrick): this should be true for new FC's.
716 space_available -= builder_->BfcOffset().value().block_offset;
mstensho (USE GERRIT) 2017/02/15 21:12:22 I don't understand how this is supposed to work. W
ikilpatrick 2017/02/16 16:48:31 Ah yeah this is wrong, we need a IsNewFormattingCo
mstensho (USE GERRIT) 2017/02/16 21:14:47 Not sure if I misunderstand what you mean here, bu
717 }
718 space_builder_->SetFragmentainerSpaceAvailable(space_available);
719 } else {
720 space_builder_->SetFragmentainerSpaceAvailable(LayoutUnit(0));
mstensho (USE GERRIT) 2017/02/15 21:12:22 Just LayoutUnit().
721 }
722
816 return space_builder_->ToConstraintSpace(); 723 return space_builder_->ToConstraintSpace();
817 } 724 }
818 725
819 } // namespace blink 726 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698