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

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

Issue 2679343002: Fragment that establishes new BFC knows it's BFC offset in parent space (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 26 matching lines...) Expand all
37 bool is_in_parallel_flow = 37 bool is_in_parallel_flow =
38 (parent_space.WritingMode() == kHorizontalTopBottom) == 38 (parent_space.WritingMode() == kHorizontalTopBottom) ==
39 (child_writing_mode == kHorizontalTopBottom); 39 (child_writing_mode == kHorizontalTopBottom);
40 40
41 return child_style.display() == EDisplay::InlineBlock || 41 return child_style.display() == EDisplay::InlineBlock ||
42 child_style.isFloating() || !is_in_parallel_flow; 42 child_style.isFloating() || !is_in_parallel_flow;
43 } 43 }
44 44
45 // Updates the fragment's BFC offset if it's not already set. 45 // Updates the fragment's BFC offset if it's not already set.
46 void UpdateFragmentBfcOffset(const NGLogicalOffset& offset, 46 void UpdateFragmentBfcOffset(const NGLogicalOffset& offset,
47 const NGConstraintSpace& space,
48 NGFragmentBuilder* builder) { 47 NGFragmentBuilder* builder) {
49 NGLogicalOffset fragment_offset =
50 space.IsNewFormattingContext() ? space.BfcOffset() : offset;
51 if (!builder->BfcOffset()) 48 if (!builder->BfcOffset())
52 builder->SetBfcOffset(fragment_offset); 49 builder->SetBfcOffset(offset);
53 } 50 }
54 51
55 // Adjusts content_size to respect the CSS "clear" property. 52 // Adjusts content_size to respect the CSS "clear" property.
56 // Picks up the maximum between left/right exclusions and content_size depending 53 // Picks up the maximum between left/right exclusions and content_size depending
57 // on the value of style.clear() property. 54 // on the value of style.clear() property.
58 void AdjustToClearance(const std::shared_ptr<NGExclusions>& exclusions, 55 void AdjustToClearance(const std::shared_ptr<NGExclusions>& exclusions,
59 const ComputedStyle& style, 56 const ComputedStyle& style,
60 const NGLogicalOffset& from_offset, 57 const NGLogicalOffset& from_offset,
61 LayoutUnit* content_size) { 58 LayoutUnit* content_size) {
62 DCHECK(content_size) << "content_size cannot be null here"; 59 DCHECK(content_size) << "content_size cannot be null here";
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 ComputeMinAndMaxContentContribution(block_child->Style(), child_minmax); 315 ComputeMinAndMaxContentContribution(block_child->Style(), child_minmax);
319 316
320 sizes.min_content = std::max(sizes.min_content, child_sizes.min_content); 317 sizes.min_content = std::max(sizes.min_content, child_sizes.min_content);
321 sizes.max_content = std::max(sizes.max_content, child_sizes.max_content); 318 sizes.max_content = std::max(sizes.max_content, child_sizes.max_content);
322 } 319 }
323 320
324 sizes.max_content = std::max(sizes.min_content, sizes.max_content); 321 sizes.max_content = std::max(sizes.min_content, sizes.max_content);
325 return sizes; 322 return sizes;
326 } 323 }
327 324
328 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateRelativeOffset( 325 NGLogicalOffset NGBlockLayoutAlgorithm::CalculateLogicalOffset(
329 const NGBoxFragment& fragment) { 326 const WTF::Optional<NGLogicalOffset>& known_fragment_offset) {
330 LayoutUnit inline_offset = 327 LayoutUnit inline_offset =
331 border_and_padding_.inline_start + curr_child_margins_.inline_start; 328 border_and_padding_.inline_start + curr_child_margins_.inline_start;
332 LayoutUnit block_offset = content_size_; 329 LayoutUnit block_offset = content_size_;
333 if (fragment.BfcOffset()) { 330 if (known_fragment_offset) {
334 block_offset = fragment.BfcOffset().value().block_offset - 331 block_offset = known_fragment_offset.value().block_offset -
335 builder_->BfcOffset().value().block_offset; 332 builder_->BfcOffset().value().block_offset;
336 } 333 }
337 return {inline_offset, block_offset}; 334 return {inline_offset, block_offset};
338 } 335 }
339 336
340 RefPtr<NGPhysicalFragment> NGBlockLayoutAlgorithm::Layout() { 337 RefPtr<NGPhysicalFragment> NGBlockLayoutAlgorithm::Layout() {
341 WTF::Optional<MinAndMaxContentSizes> sizes; 338 WTF::Optional<MinAndMaxContentSizes> sizes;
342 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style())) 339 if (NeedMinAndMaxContentSizes(ConstraintSpace(), Style()))
343 sizes = ComputeMinAndMaxContentSizes(); 340 sizes = ComputeMinAndMaxContentSizes();
344 341
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 block_size = 446 block_size =
450 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); 447 ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_);
451 builder_->SetBlockSize(block_size); 448 builder_->SetBlockSize(block_size);
452 449
453 // Layout our absolute and fixed positioned children. 450 // Layout our absolute and fixed positioned children.
454 NGOutOfFlowLayoutPart(Style(), builder_.get()).Run(); 451 NGOutOfFlowLayoutPart(Style(), builder_.get()).Run();
455 452
456 // Non empty blocks always know their position in space: 453 // Non empty blocks always know their position in space:
457 if (block_size) { 454 if (block_size) {
458 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 455 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
459 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), 456 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
460 builder_.get());
461 PositionPendingFloats(curr_bfc_offset_, builder_.get()); 457 PositionPendingFloats(curr_bfc_offset_, builder_.get());
462 } 458 }
463 459
464 // Margins collapsing: 460 // Margins collapsing:
465 // Do not collapse margins between the last in-flow child and bottom margin 461 // Do not collapse margins between the last in-flow child and bottom margin
466 // of its parent if the parent has height != auto() 462 // of its parent if the parent has height != auto()
467 if (!Style().logicalHeight().isAuto()) { 463 if (!Style().logicalHeight().isAuto()) {
468 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight. 464 // TODO(glebl): handle minLogicalHeight, maxLogicalHeight.
469 curr_margin_strut_ = NGMarginStrut(); 465 curr_margin_strut_ = NGMarginStrut();
470 } 466 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 NGLogicalOffset origin_point = curr_bfc_offset_; 516 NGLogicalOffset origin_point = curr_bfc_offset_;
521 // Adjust origin point to the margins of the last child. 517 // Adjust origin point to the margins of the last child.
522 // Example: <div style="margin-bottom: 20px"><float></div> 518 // Example: <div style="margin-bottom: 20px"><float></div>
523 // <div style="margin-bottom: 30px"></div> 519 // <div style="margin-bottom: 30px"></div>
524 origin_point.block_offset += curr_margin_strut_.Sum(); 520 origin_point.block_offset += curr_margin_strut_.Sum();
525 PositionPendingFloats(origin_point, builder_.get()); 521 PositionPendingFloats(origin_point, builder_.get());
526 } 522 }
527 return; 523 return;
528 } 524 }
529 525
530 // Fragment that knows its offset can be used to set parent's BFC position. 526 // Determine the fragment's position in the parent space either by using
531 if (fragment.BfcOffset()) { 527 // content_size_ or known fragment's BFC offset.
528 WTF::Optional<NGLogicalOffset> bfc_offset;
529 if (CurrentChildConstraintSpace().IsNewFormattingContext()) {
530 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
531 bfc_offset = curr_bfc_offset_;
532 } else if (fragment.BfcOffset()) {
533 // Fragment that knows its offset can be used to set parent's BFC position.
532 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset; 534 curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset;
533 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), 535 bfc_offset = curr_bfc_offset_;
534 builder_.get()); 536 }
537 if (bfc_offset) {
538 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
535 PositionPendingFloats(curr_bfc_offset_, builder_.get()); 539 PositionPendingFloats(curr_bfc_offset_, builder_.get());
536 } 540 }
537 NGLogicalOffset fragment_offset = CalculateRelativeOffset(fragment); 541 NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset);
538 542
539 if (fragmentainer_mapper_) 543 if (fragmentainer_mapper_)
540 fragmentainer_mapper_->ToVisualOffset(fragment_offset); 544 fragmentainer_mapper_->ToVisualOffset(logical_offset);
541 else 545 else
542 fragment_offset.block_offset -= PreviousBreakOffset(); 546 logical_offset.block_offset -= PreviousBreakOffset();
543 547
544 // Update margin strut. 548 // Update margin strut.
545 curr_margin_strut_ = fragment.EndMarginStrut(); 549 curr_margin_strut_ = fragment.EndMarginStrut();
546 curr_margin_strut_.Append(curr_child_margins_.block_end); 550 curr_margin_strut_.Append(curr_child_margins_.block_end);
547 551
548 content_size_ = fragment.BlockSize() + fragment_offset.block_offset; 552 content_size_ = fragment.BlockSize() + logical_offset.block_offset;
549 max_inline_size_ = 553 max_inline_size_ =
550 std::max(max_inline_size_, fragment.InlineSize() + 554 std::max(max_inline_size_, fragment.InlineSize() +
551 curr_child_margins_.InlineSum() + 555 curr_child_margins_.InlineSum() +
552 border_and_padding_.InlineSum()); 556 border_and_padding_.InlineSum());
553 557
554 builder_->AddChild(std::move(physical_fragment), fragment_offset); 558 builder_->AddChild(std::move(physical_fragment), logical_offset);
555 } 559 }
556 560
557 bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling( 561 bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling(
558 NGPhysicalFragment* child_fragment) { 562 NGPhysicalFragment* child_fragment) {
559 DCHECK(current_child_); 563 DCHECK(current_child_);
560 NGBlockNode* finished_child = toNGBlockNode(current_child_); 564 NGBlockNode* finished_child = toNGBlockNode(current_child_);
561 current_child_ = current_child_->NextSibling(); 565 current_child_ = current_child_->NextSibling();
562 if (!ConstraintSpace().HasBlockFragmentation() && !fragmentainer_mapper_) 566 if (!ConstraintSpace().HasBlockFragmentation() && !fragmentainer_mapper_)
563 return true; 567 return true;
564 // If we're resuming layout after a fragmentainer break, we need to skip 568 // If we're resuming layout after a fragmentainer break, we need to skip
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 space_builder_->SetFragmentainerSpaceAvailable(space_available); 746 space_builder_->SetFragmentainerSpaceAvailable(space_available);
743 747
744 // Clearance : 748 // Clearance :
745 // - Collapse margins 749 // - Collapse margins
746 // - Update curr_bfc_offset and parent BFC offset if needed. 750 // - Update curr_bfc_offset and parent BFC offset if needed.
747 // - Position all pending floats as position is known now. 751 // - Position all pending floats as position is known now.
748 // TODO(glebl): Fix the use case with clear: left and an intruding right. 752 // TODO(glebl): Fix the use case with clear: left and an intruding right.
749 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847 753 // https://software.hixie.ch/utilities/js/live-dom-viewer/saved/4847
750 if (current_child_style.clear() != EClear::kNone) { 754 if (current_child_style.clear() != EClear::kNone) {
751 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum(); 755 curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
752 UpdateFragmentBfcOffset(curr_bfc_offset_, ConstraintSpace(), 756 UpdateFragmentBfcOffset(curr_bfc_offset_, builder_.get());
753 builder_.get());
754 // Only collapse margins if it's an adjoining block with clearance. 757 // Only collapse margins if it's an adjoining block with clearance.
755 if (!content_size_) { 758 if (!content_size_) {
756 curr_margin_strut_ = NGMarginStrut(); 759 curr_margin_strut_ = NGMarginStrut();
757 curr_child_margins_.block_start = LayoutUnit(); 760 curr_child_margins_.block_start = LayoutUnit();
758 } 761 }
759 PositionPendingFloats(curr_bfc_offset_, builder_.get()); 762 PositionPendingFloats(curr_bfc_offset_, builder_.get());
760 AdjustToClearance(constraint_space_->Exclusions(), current_child_style, 763 AdjustToClearance(constraint_space_->Exclusions(), current_child_style,
761 builder_->BfcOffset().value(), &content_size_); 764 builder_->BfcOffset().value(), &content_size_);
762 } 765 }
763 766
(...skipping 10 matching lines...) Expand all
774 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start; 777 curr_bfc_offset_.inline_offset += border_and_padding_.inline_start;
775 if (ConstraintSpace().IsNewFormattingContext()) { 778 if (ConstraintSpace().IsNewFormattingContext()) {
776 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start; 779 curr_bfc_offset_.inline_offset += curr_child_margins_.inline_start;
777 } 780 }
778 space_builder_->SetBfcOffset(curr_bfc_offset_); 781 space_builder_->SetBfcOffset(curr_bfc_offset_);
779 782
780 return space_builder_->ToConstraintSpace(); 783 return space_builder_->ToConstraintSpace();
781 } 784 }
782 785
783 } // namespace blink 786 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698