diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-29 10:46:47 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-11-02 12:02:10 +0000 |
commit | 99677208ff3b216fdfec551fbe548da5520cd6fb (patch) | |
tree | 476a4865c10320249360e859d8fdd3e01833b03a /chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc | |
parent | c30a6232df03e1efbd9f3b226777b07e087a1122 (diff) | |
download | qtwebengine-chromium-99677208ff3b216fdfec551fbe548da5520cd6fb.tar.gz |
BASELINE: Update Chromium to 86.0.4240.124
Change-Id: Ide0ff151e94cd665ae6521a446995d34a9d1d644
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc | 254 |
1 files changed, 159 insertions, 95 deletions
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index 2be39a801ef..9244e6fc1f7 100644 --- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc @@ -13,7 +13,6 @@ #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_table_cell.h" -#include "third_party/blink/renderer/core/layout/ng/geometry/ng_border_edges.h" #include "third_party/blink/renderer/core/layout/ng/geometry/ng_box_strut.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h" @@ -39,6 +38,7 @@ #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/paint/paint_phase.h" #include "third_party/blink/renderer/core/paint/paint_timing_detector.h" +#include "third_party/blink/renderer/core/paint/rounded_border_geometry.h" #include "third_party/blink/renderer/core/paint/scoped_paint_state.h" #include "third_party/blink/renderer/core/paint/scrollable_area_painter.h" #include "third_party/blink/renderer/core/paint/theme_painter.h" @@ -94,8 +94,8 @@ inline bool IsVisibleToPaint(const NGFragmentItem& item, style.Visibility() == EVisibility::kVisible; } -inline bool IsVisibleToHitTest(const HitTestRequest& request, - const ComputedStyle& style) { +inline bool IsVisibleToHitTest(const ComputedStyle& style, + const HitTestRequest& request) { return request.IgnorePointerEventsNone() || style.PointerEvents() != EPointerEvents::kNone; } @@ -103,14 +103,14 @@ inline bool IsVisibleToHitTest(const HitTestRequest& request, inline bool IsVisibleToHitTest(const NGFragmentItem& item, const HitTestRequest& request) { const ComputedStyle& style = item.Style(); - return IsVisibleToPaint(item, style) && IsVisibleToHitTest(request, style); + return IsVisibleToPaint(item, style) && IsVisibleToHitTest(style, request); } -bool FragmentVisibleToHitTestRequest(const NGPhysicalFragment& fragment, - const HitTestRequest& request) { +inline bool IsVisibleToHitTest(const NGPhysicalFragment& fragment, + const HitTestRequest& request) { const ComputedStyle& style = fragment.Style(); return IsVisibleToPaint(fragment, style) && - IsVisibleToHitTest(request, style); + IsVisibleToHitTest(style, request); } // Hit tests inline ancestor elements of |fragment| who do not have their own @@ -170,6 +170,10 @@ bool HitTestCulledInlineAncestors( const PhysicalOffset& physical_offset) { DCHECK(fragment.Parent()); DCHECK(fragment.PhysicalFragment().IsInline()); + // Ellipsis can appear under a different parent from the ellipsized object + // that it can confuse culled inline logic. + if (UNLIKELY(fragment.IsEllipsis())) + return false; const NGPaintFragment& parent = *fragment.Parent(); // To be passed as |accumulated_offset| to LayoutInline::HitTestCulledInline, // where it equals the physical offset of the containing block in paint layer. @@ -191,6 +195,10 @@ bool HitTestCulledInlineAncestors( const NGInlineCursorPosition& previous_sibling, const HitTestLocation& hit_test_location, const PhysicalOffset& physical_offset) { + // Ellipsis can appear under a different parent from the ellipsized object + // that it can confuse culled inline logic. + if (UNLIKELY(item.IsEllipsis())) + return false; // To be passed as |accumulated_offset| to LayoutInline::HitTestCulledInline, // where it equals the physical offset of the containing block in paint layer. const PhysicalOffset fallback_accumulated_offset = @@ -346,15 +354,6 @@ unsigned FragmentainerUniqueIdentifier(const NGPhysicalBoxFragment& fragment) { } // anonymous namespace -const NGBorderEdges& NGBoxFragmentPainter::BorderEdges() const { - if (border_edges_.has_value()) - return *border_edges_; - const NGPhysicalBoxFragment& fragment = PhysicalFragment(); - border_edges_ = NGBorderEdges::FromPhysical( - fragment.BorderEdges(), fragment.Style().GetWritingMode()); - return *border_edges_; -} - PhysicalRect NGBoxFragmentPainter::SelfInkOverflow() const { if (paint_fragment_) return paint_fragment_->SelfInkOverflow(); @@ -512,12 +511,12 @@ void NGBoxFragmentPainter::PaintObject( const NGPhysicalBoxFragment& physical_box_fragment = PhysicalFragment(); const ComputedStyle& style = box_fragment_.Style(); bool is_visible = IsVisibleToPaint(physical_box_fragment, style); - if (!is_visible) - suppress_box_decoration_background = true; if (ShouldPaintSelfBlockBackground(paint_phase)) { - PaintBoxDecorationBackground(paint_info, paint_offset, - suppress_box_decoration_background); + if (is_visible) { + PaintBoxDecorationBackground(paint_info, paint_offset, + suppress_box_decoration_background); + } // We're done. We don't bother painting any children. if (paint_phase == PaintPhase::kSelfBlockBackgroundOnly) return; @@ -541,9 +540,9 @@ void NGBoxFragmentPainter::PaintObject( (!physical_box_fragment.Children().empty() || physical_box_fragment.HasItems() || inline_box_cursor_) && !paint_info.DescendantPaintingBlocked()) { - if (UNLIKELY(paint_phase == PaintPhase::kForeground && - box_fragment_.IsCSSBox() && - box_fragment_.Style().HasColumnRule())) + if (is_visible && UNLIKELY(paint_phase == PaintPhase::kForeground && + box_fragment_.IsCSSBox() && + box_fragment_.Style().HasColumnRule())) PaintColumnRules(paint_info, paint_offset); if (paint_phase != PaintPhase::kFloat) { @@ -568,8 +567,32 @@ void NGBoxFragmentPainter::PaintObject( PaintInlineItems(paint_info.ForDescendants(), paint_offset, PhysicalOffset(), &cursor); } - } else if (physical_box_fragment.IsInlineFormattingContext()) { - DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()); + } else if (!physical_box_fragment.IsInlineFormattingContext()) { + PaintBlockChildren(paint_info, paint_offset); + } else if (!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled()) { + // This is the NGPaintFragment code path. We need the check for + // !LayoutNGFragmentItemEnabled above, since it's possible to come up + // with an empty (item-less) box that's in an inline formatting context, + // even when that feature is enabled. This happens when an inline-level + // float descendant gets block-fragmented. When resuming float layout in + // the next fragment, the float will no longer be associated with a line + // or a fragment item (this is an implementation detail), but rather a + // regular box fragment child of this container. If there's no inline + // content to put in that fragment, there'll be no items, just the box + // fragment for the float. In that case, we have no work to do here. + // + // <div style="columns:2; column-fill:auto; height:100px;"> + // <div id="child"> + // <div id="fl" style="float:left; height:150px;"></div> + // text + // </div> + // </div> + // + // #child will get two fragments. The first one will contain a line with + // items for a 100px tall #fl fragment, and the text. The second + // fragment of #child will just contain a regular box fragment child for + // the remaining 50px of #fl - no items (all in-flow content fits in the + // first fragment). DCHECK(paint_fragment_); if (physical_box_fragment.IsBlockFlow()) { PaintBlockFlowContents(paint_info, paint_offset); @@ -583,8 +606,6 @@ void NGBoxFragmentPainter::PaintObject( PaintInlineChildren(paint_fragment_->Children(), paint_info, paint_offset); } - } else { - PaintBlockChildren(paint_info, paint_offset); } } @@ -596,7 +617,7 @@ void NGBoxFragmentPainter::PaintObject( } } - if (ShouldPaintSelfOutline(paint_phase)) { + if (is_visible && ShouldPaintSelfOutline(paint_phase)) { NGFragmentPainter(box_fragment_, GetDisplayItemClient()) .PaintOutline(paint_info, paint_offset); } @@ -645,8 +666,7 @@ void NGBoxFragmentPainter::PaintBlockFlowContents( // |ContentsInkOverflow()|. PhysicalRect content_ink_rect = fragment.LocalRect(); content_ink_rect.Unite(ContentsInkOverflow()); - content_ink_rect.offset += PhysicalOffset(paint_offset); - if (!paint_info.GetCullRect().Intersects(content_ink_rect.ToLayoutRect())) + if (!paint_info.IntersectsCullRect(content_ink_rect, paint_offset)) return; if (paint_fragment_) { @@ -725,22 +745,28 @@ void NGBoxFragmentPainter::PaintBlockChildren(const PaintInfo& paint_info, void NGBoxFragmentPainter::PaintFloatingItems(const PaintInfo& paint_info, NGInlineCursor* cursor) { - for (; *cursor; cursor->MoveToNext()) { + while (*cursor) { const NGFragmentItem* item = cursor->Current().Item(); DCHECK(item); const NGPhysicalBoxFragment* child_fragment = item->BoxFragment(); - if (!child_fragment || child_fragment->HasSelfPaintingLayer() || - !child_fragment->IsFloating()) + if (!child_fragment) { + cursor->MoveToNext(); continue; - // TODO(kojii): The float is outside of the inline formatting context and - // that it maybe another NG inline formatting context, NG block layout, or - // legacy. NGBoxFragmentPainter can handle only the first case. In order - // to cover more tests for other two cases, we always fallback to legacy, - // which will forward back to NGBoxFragmentPainter if the float is for - // NGBoxFragmentPainter. We can shortcut this for the first case when - // we're more stable. - ObjectPainter(*child_fragment->GetLayoutObject()) - .PaintAllPhasesAtomically(paint_info); + } + if (child_fragment->HasSelfPaintingLayer()) { + cursor->MoveToNextSkippingChildren(); + continue; + } + if (child_fragment->IsFloating()) { + if (child_fragment->CanTraverse()) { + NGBoxFragmentPainter(*child_fragment).Paint(paint_info); + } else { + ObjectPainter(*child_fragment->GetLayoutObject()) + .PaintAllPhasesAtomically(paint_info); + } + } + DCHECK(child_fragment->IsInlineBox() || !cursor->Current().HasChildren()); + cursor->MoveToNext(); } } @@ -750,23 +776,6 @@ void NGBoxFragmentPainter::PaintFloatingChildren( const PaintInfo& float_paint_info) { DCHECK(container.HasFloatingDescendantsForPaint()); - if (const NGPhysicalBoxFragment* box = - DynamicTo<NGPhysicalBoxFragment>(&container)) { - if (const NGFragmentItems* items = box->Items()) { - NGInlineCursor cursor(*items); - PaintFloatingItems(float_paint_info, &cursor); - return; - } - if (inline_box_cursor_) { - DCHECK(box->IsInlineBox()); - NGInlineCursor descendants = inline_box_cursor_->CursorForDescendants(); - PaintFloatingItems(float_paint_info, &descendants); - return; - } - DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled() || - !box->IsInlineBox()); - } - for (const NGLink& child : container.Children()) { const NGPhysicalFragment& child_fragment = *child; if (child_fragment.HasSelfPaintingLayer()) @@ -841,6 +850,27 @@ void NGBoxFragmentPainter::PaintFloatingChildren( PaintFloatingChildren(*child_container, paint_info, float_paint_info); } } + + // Now process the inline formatting context, if any. Note that even if this + // is an inline formatting context, we still need to walk the box fragment + // children (like we did above). If a float is block-fragmented, it is resumed + // as a regular box fragment child, rather than becoming a fragment item. + if (const NGPhysicalBoxFragment* box = + DynamicTo<NGPhysicalBoxFragment>(&container)) { + if (const NGFragmentItems* items = box->Items()) { + NGInlineCursor cursor(*items); + PaintFloatingItems(float_paint_info, &cursor); + return; + } + if (inline_box_cursor_) { + DCHECK(box->IsInlineBox()); + NGInlineCursor descendants = inline_box_cursor_->CursorForDescendants(); + PaintFloatingItems(float_paint_info, &descendants); + return; + } + DCHECK(!RuntimeEnabledFeatures::LayoutNGFragmentItemEnabled() || + !box->IsInlineBox()); + } } void NGBoxFragmentPainter::PaintFloats(const PaintInfo& paint_info) { @@ -865,16 +895,20 @@ void NGBoxFragmentPainter::PaintMask(const PaintInfo& paint_info, paint_info.context, GetDisplayItemClient(), paint_info.phase)) return; + if (physical_box_fragment.IsFieldsetContainer()) { + NGFieldsetPainter(box_fragment_).PaintMask(paint_info, paint_offset); + return; + } + // TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry. BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>( box_fragment_.GetLayoutObject())); DrawingRecorder recorder(paint_info.context, GetDisplayItemClient(), - paint_info.phase); + paint_info.phase, VisualRect(paint_offset)); PhysicalRect paint_rect(paint_offset, box_fragment_.Size()); - const NGBorderEdges& border_edges = BorderEdges(); PaintMaskImages(paint_info, paint_rect, *box_fragment_.GetLayoutObject(), - geometry, border_edges.line_left, border_edges.line_right); + geometry, box_fragment_.SidesToInclude()); } // TODO(kojii): This logic is kept in sync with BoxPainter. Not much efforts to @@ -891,6 +925,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground( base::Optional<ScopedBoxContentsPaintState> contents_paint_state; bool painting_scrolling_background = IsPaintingScrollingBackground(paint_info); + IntRect visual_rect; if (painting_scrolling_background) { // For the case where we are painting the background into the scrolling // contents layer of a composited scroller we need to include the entire @@ -908,6 +943,8 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground( background_client = &layout_box.GetScrollableArea() ->GetScrollingBackgroundDisplayItemClient(); + visual_rect = layout_box.GetScrollableArea()->ScrollingBackgroundVisualRect( + paint_offset); } else { paint_rect.offset = paint_offset; paint_rect.size = box_fragment_.Size(); @@ -916,6 +953,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground( PhysicalSize(ToLayoutBox(layout_object).PixelSnappedSize()); } background_client = &GetDisplayItemClient(); + visual_rect = VisualRect(paint_offset); } if (!suppress_box_decoration_background) { @@ -928,7 +966,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground( PaintBoxDecorationBackgroundWithRect( contents_paint_state ? contents_paint_state->GetPaintInfo() : paint_info, - paint_rect, *background_client); + visual_rect, paint_rect, *background_client); } } @@ -962,6 +1000,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground( void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRect( const PaintInfo& paint_info, + const IntRect& visual_rect, const PhysicalRect& paint_rect, const DisplayItemClient& background_client) { const LayoutBox& layout_box = ToLayoutBox(*box_fragment_.GetLayoutObject()); @@ -981,7 +1020,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRect( return; DrawingRecorder recorder(paint_info.context, background_client, - DisplayItem::kBoxDecorationBackground); + DisplayItem::kBoxDecorationBackground, visual_rect); PaintBoxDecorationBackgroundWithRectImpl(paint_info, paint_rect, box_decoration_data); @@ -999,10 +1038,9 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRectImpl( GraphicsContextStateSaver state_saver(paint_info.context, false); - const NGBorderEdges& border_edges = BorderEdges(); if (box_decoration_data.ShouldPaintShadow()) { - PaintNormalBoxShadow(paint_info, paint_rect, style, border_edges.line_left, - border_edges.line_right, + PaintNormalBoxShadow(paint_info, paint_rect, style, + box_fragment_.SidesToInclude(), !box_decoration_data.ShouldPaintBackground()); } @@ -1021,9 +1059,9 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRectImpl( } else if (BleedAvoidanceIsClipping( box_decoration_data.GetBackgroundBleedAvoidance())) { state_saver.Save(); - FloatRoundedRect border = style.GetRoundedBorderFor( - paint_rect.ToLayoutRect(), border_edges.line_left, - border_edges.line_right); + FloatRoundedRect border = + RoundedBorderGeometry::PixelSnappedRoundedBorder( + style, paint_rect, box_fragment_.SidesToInclude()); paint_info.context.ClipRoundedRect(border); if (box_decoration_data.GetBackgroundBleedAvoidance() == @@ -1065,8 +1103,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRectImpl( style); } else { PaintInsetBoxShadowWithBorderRect(paint_info, paint_rect, style, - border_edges.line_left, - border_edges.line_right); + box_fragment_.SidesToInclude()); } } @@ -1085,7 +1122,7 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRectImpl( PaintBorder(*box_fragment_.GetLayoutObject(), document, generating_node, paint_info, paint_rect, style, box_decoration_data.GetBackgroundBleedAvoidance(), - border_edges.line_left, border_edges.line_right); + box_fragment_.SidesToInclude()); } } @@ -1109,7 +1146,7 @@ void NGBoxFragmentPainter::PaintColumnRules( return; DrawingRecorder recorder(paint_info.context, GetDisplayItemClient(), - DisplayItem::kColumnRules); + DisplayItem::kColumnRules, IntRect()); const Color& rule_color = LayoutObject::ResolveColor(style, GetCSSPropertyColumnRuleColor()); @@ -1187,6 +1224,7 @@ void NGBoxFragmentPainter::PaintColumnRules( snapped_rule.Y(), snapped_rule.MaxX(), snapped_rule.MaxY(), box_side, rule_color, rule_style, 0, 0, true); + recorder.UniteVisualRect(snapped_rule); previous_column = current_column; } @@ -1424,6 +1462,8 @@ void NGBoxFragmentPainter::PaintLineBoxChildItems( for (; *children; children->MoveToNextSkippingChildren()) { const NGFragmentItem* child_item = children->CurrentItem(); DCHECK(child_item); + if (child_item->IsFloating()) + continue; // Check if CullRect intersects with this child, only in block direction // because soft-wrap and <br> needs to paint outside of InkOverflow() in @@ -1458,6 +1498,7 @@ void NGBoxFragmentPainter::PaintLineBoxChildItems( if (const NGPhysicalBoxFragment* child_fragment = child_item->BoxFragment()) { + DCHECK(!child_fragment->IsOutOfFlowPositioned()); if (child_fragment->IsListMarker()) { PaintBoxItem(*child_item, *child_fragment, *children, paint_info, paint_offset); @@ -1475,9 +1516,11 @@ void NGBoxFragmentPainter::PaintBackplate(NGInlineCursor* line_boxes, if (paint_info.phase != PaintPhase::kForcedColorsModeBackplate) return; - // Only paint backplates behind text when forced-color-adjust is auto. + // Only paint backplates behind text when forced-color-adjust is auto and the + // element is visible. const ComputedStyle& style = PhysicalFragment().Style(); - if (style.ForcedColorAdjust() == EForcedColorAdjust::kNone) + if (style.ForcedColorAdjust() == EForcedColorAdjust::kNone || + style.Visibility() != EVisibility::kVisible) return; if (DrawingRecorder::UseCachedDrawingIfPossible( @@ -1485,14 +1528,15 @@ void NGBoxFragmentPainter::PaintBackplate(NGInlineCursor* line_boxes, DisplayItem::kForcedColorsModeBackplate)) return; - DrawingRecorder recorder(paint_info.context, GetDisplayItemClient(), - DisplayItem::kForcedColorsModeBackplate); Color backplate_color = PhysicalFragment() .GetLayoutObject() ->GetDocument() .GetStyleEngine() .ForcedBackgroundColor(); const auto& backplates = BuildBackplate(line_boxes, paint_offset); + DrawingRecorder recorder(paint_info.context, GetDisplayItemClient(), + DisplayItem::kForcedColorsModeBackplate, + EnclosingIntRect(UnionRect(backplates))); for (const auto backplate : backplates) paint_info.context.FillRect(FloatRect(backplate), backplate_color); } @@ -1774,13 +1818,12 @@ BoxPainterBase::FillLayerInfo NGBoxFragmentPainter::GetFillLayerInfo( const FillLayer& bg_layer, BackgroundBleedAvoidance bleed_avoidance, bool is_painting_scrolling_background) const { - const NGBorderEdges& border_edges = BorderEdges(); const NGPhysicalBoxFragment& fragment = PhysicalFragment(); return BoxPainterBase::FillLayerInfo( fragment.GetLayoutObject()->GetDocument(), fragment.Style(), fragment.HasOverflowClip(), color, bg_layer, bleed_avoidance, LayoutObject::ShouldRespectImageOrientation(fragment.GetLayoutObject()), - border_edges.line_left, border_edges.line_right, + box_fragment_.SidesToInclude(), fragment.GetLayoutObject()->IsLayoutInline(), is_painting_scrolling_background); } @@ -1841,7 +1884,8 @@ bool NGBoxFragmentPainter::NodeAtPoint(const HitTestContext& hit_test, if (!skip_children && style.HasBorderRadius()) { PhysicalRect bounds_rect(physical_offset, size); skip_children = !hit_test.location.Intersects( - style.GetRoundedInnerBorderFor(bounds_rect.ToLayoutRect())); + RoundedBorderGeometry::PixelSnappedRoundedInnerBorder(style, + bounds_rect)); } } @@ -1867,7 +1911,7 @@ bool NGBoxFragmentPainter::NodeAtPoint(const HitTestContext& hit_test, // Now hit test ourselves. if (hit_test_self && - VisibleToHitTestRequest(hit_test.result->GetHitTestRequest())) { + IsVisibleToHitTest(box_fragment_, hit_test.result->GetHitTestRequest())) { PhysicalRect bounds_rect(physical_offset, size); if (UNLIKELY(hit_test.result->GetHitTestRequest().GetType() & HitTestRequest::kHitTestVisualOverflow)) { @@ -1940,11 +1984,6 @@ bool NGBoxFragmentPainter::HitTestAllPhases( return inside; } -bool NGBoxFragmentPainter::VisibleToHitTestRequest( - const HitTestRequest& request) const { - return FragmentVisibleToHitTestRequest(box_fragment_, request); -} - bool NGBoxFragmentPainter::HitTestTextFragment( const HitTestContext& hit_test, const NGInlineBackwardCursor& cursor, @@ -1956,8 +1995,7 @@ bool NGBoxFragmentPainter::HitTestTextFragment( DCHECK(text_paint_fragment); const auto& text_fragment = To<NGPhysicalTextFragment>(text_paint_fragment->PhysicalFragment()); - if (!FragmentVisibleToHitTestRequest(text_fragment, - hit_test.result->GetHitTestRequest())) + if (!IsVisibleToHitTest(text_fragment, hit_test.result->GetHitTestRequest())) return false; // TODO(layout-dev): Clip to line-top/bottom. @@ -2015,7 +2053,7 @@ bool NGBoxFragmentPainter::HitTestLineBoxFragment( if (hit_test.action != kHitTestForeground) return false; - if (!VisibleToHitTestRequest(hit_test.result->GetHitTestRequest())) + if (!IsVisibleToHitTest(box_fragment_, hit_test.result->GetHitTestRequest())) return false; const PhysicalOffset overflow_location = @@ -2027,7 +2065,8 @@ bool NGBoxFragmentPainter::HitTestLineBoxFragment( const ComputedStyle& containing_box_style = box_fragment_.Style(); if (containing_box_style.HasBorderRadius() && !hit_test.location.Intersects( - containing_box_style.GetRoundedBorderFor(bounds_rect.ToLayoutRect()))) + RoundedBorderGeometry::PixelSnappedRoundedBorder(containing_box_style, + bounds_rect))) return false; // Now hit test ourselves. @@ -2214,6 +2253,8 @@ bool NGBoxFragmentPainter::HitTestBlockChildren( auto children = box_fragment_.Children(); for (const NGLink& child : base::Reversed(children)) { const auto& block_child = To<NGPhysicalBoxFragment>(*child); + if (UNLIKELY(block_child.IsLayoutObjectDestroyedOrMoved())) + continue; if (block_child.HasSelfPaintingLayer() || block_child.IsFloating()) continue; @@ -2365,13 +2406,20 @@ bool NGBoxFragmentPainter::HitTestFloatingChildren( if (const auto* box = DynamicTo<NGPhysicalBoxFragment>(&container)) { if (const NGFragmentItems* items = box->Items()) { NGInlineCursor children(*items); - return HitTestFloatingChildItems(hit_test, children, accumulated_offset); + if (HitTestFloatingChildItems(hit_test, children, accumulated_offset)) + return true; + // Even if this turned out to be an inline formatting context, we need to + // continue walking the box fragment children now. If a float is + // block-fragmented, it is resumed as a regular box fragment child, rather + // than becoming a fragment item. } } auto children = container.Children(); for (const NGLink& child : base::Reversed(children)) { const NGPhysicalFragment& child_fragment = *child.fragment; + if (UNLIKELY(child_fragment.IsLayoutObjectDestroyedOrMoved())) + continue; if (child_fragment.HasSelfPaintingLayer()) continue; @@ -2482,9 +2530,9 @@ bool NGBoxFragmentPainter::HitTestClippedOutByBorder( const ComputedStyle& style = box_fragment_.Style(); PhysicalRect rect(PhysicalOffset(), PhysicalFragment().Size()); rect.Move(border_box_location); - const NGBorderEdges& border_edges = BorderEdges(); - return !hit_test_location.Intersects(style.GetRoundedBorderFor( - rect.ToLayoutRect(), border_edges.line_left, border_edges.line_right)); + return !hit_test_location.Intersects( + RoundedBorderGeometry::PixelSnappedRoundedBorder( + style, rect, box_fragment_.SidesToInclude())); } bool NGBoxFragmentPainter::HitTestOverflowControl( @@ -2496,4 +2544,20 @@ bool NGBoxFragmentPainter::HitTestOverflowControl( accumulated_offset); } +IntRect NGBoxFragmentPainter::VisualRect(const PhysicalOffset& paint_offset) { + if (const auto* layout_box = + ToLayoutBoxOrNull(box_fragment_.GetLayoutObject())) + return BoxPainter(*layout_box).VisualRect(paint_offset); + + PhysicalRect ink_overflow; + if (paint_fragment_) + ink_overflow = paint_fragment_->InkOverflow(); + else if (box_item_) + ink_overflow = box_item_->InkOverflow(); + else + NOTREACHED(); + ink_overflow.Move(paint_offset); + return EnclosingIntRect(ink_overflow); +} + } // namespace blink |