diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc b/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc index eddb2067b2e..5a75ed36bf2 100644 --- a/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc +++ b/chromium/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.cc @@ -9,17 +9,10 @@ #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h" #include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/platform/text/writing_mode.h" namespace blink { -NGContainerFragmentBuilder::NGContainerFragmentBuilder( - scoped_refptr<const ComputedStyle> style, - WritingMode writing_mode, - TextDirection direction) - : NGBaseFragmentBuilder(std::move(style), writing_mode, direction) {} - -NGContainerFragmentBuilder::~NGContainerFragmentBuilder() = default; - NGContainerFragmentBuilder& NGContainerFragmentBuilder::AddChild( const NGLayoutResult& child, const NGLogicalOffset& child_offset) { @@ -59,17 +52,60 @@ NGContainerFragmentBuilder& NGContainerFragmentBuilder::AddChild( } for (const NGOutOfFlowPositionedDescendant& descendant : out_of_flow_descendants) { - oof_positioned_candidates_.push_back( - NGOutOfFlowPositionedCandidate{descendant, top_left_offset}); + // If we are inside the inline algorithm, (and creating a fragment for a + // <span> or similar), we may add a child (e.g. an atomic-inline) which + // has OOF descandants. + // + // This checks if the object creating this box will be the container for + // the given descendant. + if (layout_object_ && layout_object_->IsLayoutInline() && + layout_object_->CanContainOutOfFlowPositionedElement( + descendant.node.Style().GetPosition()) && + !descendant.inline_container) { + NGOutOfFlowPositionedDescendant descendant_copy(descendant); + descendant_copy.inline_container = layout_object_; + oof_positioned_candidates_.push_back( + NGOutOfFlowPositionedCandidate(descendant_copy, top_left_offset)); + } else { + oof_positioned_candidates_.push_back( + NGOutOfFlowPositionedCandidate{descendant, top_left_offset}); + } } } + if (child.HasOrthogonalFlowRoots()) + has_orthogonal_flow_roots_ = true; + return AddChild(child.PhysicalFragment(), child_offset); } NGContainerFragmentBuilder& NGContainerFragmentBuilder::AddChild( scoped_refptr<const NGPhysicalFragment> child, const NGLogicalOffset& child_offset) { + NGBreakToken* child_break_token = child->BreakToken(); + if (child_break_token) { + switch (child->Type()) { + case NGPhysicalFragment::kFragmentBox: + case NGPhysicalFragment::kFragmentRenderedLegend: + child_break_tokens_.push_back(child_break_token); + break; + case NGPhysicalFragment::kFragmentLineBox: + // NGInlineNode produces multiple line boxes in an anonymous box. We + // won't know up front which line box to insert a fragment break before + // (due to widows), so keep them all until we know. + inline_break_tokens_.push_back(child_break_token); + break; + case NGPhysicalFragment::kFragmentText: + default: + NOTREACHED(); + break; + } + } + + if (!IsParallelWritingMode(child->Style().GetWritingMode(), + Style().GetWritingMode())) + has_orthogonal_flow_roots_ = true; + if (!has_last_resort_break_) { if (const auto* token = child->BreakToken()) { if (token->IsBlockType() && @@ -77,11 +113,7 @@ NGContainerFragmentBuilder& NGContainerFragmentBuilder::AddChild( has_last_resort_break_ = true; } } - // Assume that if we have one child, we may have more than one and try to - // limit the number of allocations we would do in that case. - if (!children_.capacity()) - children_.ReserveCapacity(16); - children_.emplace_back(std::move(child), NGPhysicalOffset()); + children_.emplace_back(std::move(child)); offsets_.push_back(child_offset); return *this; } @@ -139,8 +171,8 @@ void NGContainerFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates( DCHECK_GE(InlineSize(), LayoutUnit()); DCHECK_GE(BlockSize(), LayoutUnit()); - NGPhysicalSize builder_physical_size{ - Size().ConvertToPhysical(GetWritingMode())}; + NGPhysicalSize builder_physical_size = + ToNGPhysicalSize(Size(), GetWritingMode()); for (NGOutOfFlowPositionedCandidate& candidate : oof_positioned_candidates_) { TextDirection direction = @@ -171,19 +203,13 @@ void NGContainerFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates( // The descendant may be a "position: absolute" which contains a "position: // fixed" for example. (This fragment isn't the containing block for the // fixed descendant). - oof_positioned_candidates_.clear(); + oof_positioned_candidates_.Shrink(0); } -void NGContainerFragmentBuilder::MoveOutOfFlowDescendantCandidatesToDescendants( - const LayoutObject* inline_container) { +void NGContainerFragmentBuilder:: + MoveOutOfFlowDescendantCandidatesToDescendants() { GetAndClearOutOfFlowDescendantCandidates(&oof_positioned_descendants_, nullptr); - if (inline_container) { - for (auto& descendant : oof_positioned_descendants_) { - if (!descendant.inline_container) - descendant.inline_container = inline_container; - } - } } #ifndef NDEBUG |