mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibWeb: Apply either enclosing or own clip rect depending on PaintPhase
Previously, we always applied the enclosing clip rectangle for all paint phases except overlays, and the own clip rectangle for the background and foreground phases. The problem is that applying a clip rectangle means emitting an AddClipRect display list item for each clip rectangle in the containing block. With this change, we choose whether to include the own clip based on the paint phase and this way avoid emitting AddClipRect for enclosing clip rectangles twice.
This commit is contained in:
parent
05ee3f1876
commit
773d19b406
Notes:
github-actions[bot]
2025-07-07 16:56:54 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: 773d19b406
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5341
Reviewed-by: https://github.com/gmta ✅
7 changed files with 54 additions and 46 deletions
|
@ -76,9 +76,6 @@ public:
|
|||
virtual void apply_scroll_offset(PaintContext&, PaintPhase) const { }
|
||||
virtual void reset_scroll_offset(PaintContext&, PaintPhase) const { }
|
||||
|
||||
virtual void apply_own_clip_rect(PaintContext&, PaintPhase) const { }
|
||||
virtual void clear_own_clip_rect(PaintContext&, PaintPhase) const { }
|
||||
|
||||
virtual void apply_clip_overflow_rect(PaintContext&, PaintPhase) const { }
|
||||
virtual void clear_clip_overflow_rect(PaintContext&, PaintPhase) const { }
|
||||
|
||||
|
|
|
@ -321,28 +321,28 @@ bool PaintableBox::wants_mouse_events() const
|
|||
return false;
|
||||
}
|
||||
|
||||
void PaintableBox::before_paint(PaintContext& context, [[maybe_unused]] PaintPhase phase) const
|
||||
void PaintableBox::before_paint(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
|
||||
apply_own_clip_rect(context, phase);
|
||||
|
||||
if (!has_css_transform()) {
|
||||
if (first_is_one_of(phase, PaintPhase::Background, PaintPhase::Foreground) && own_clip_frame()) {
|
||||
apply_clip(context, own_clip_frame());
|
||||
} else if (!has_css_transform()) {
|
||||
apply_clip_overflow_rect(context, phase);
|
||||
}
|
||||
apply_scroll_offset(context, phase);
|
||||
}
|
||||
|
||||
void PaintableBox::after_paint(PaintContext& context, [[maybe_unused]] PaintPhase phase) const
|
||||
void PaintableBox::after_paint(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
|
||||
clear_own_clip_rect(context, phase);
|
||||
|
||||
reset_scroll_offset(context, phase);
|
||||
if (!has_css_transform()) {
|
||||
if (first_is_one_of(phase, PaintPhase::Background, PaintPhase::Foreground) && own_clip_frame()) {
|
||||
restore_clip(context, own_clip_frame());
|
||||
} else if (!has_css_transform()) {
|
||||
clear_clip_overflow_rect(context, phase);
|
||||
}
|
||||
}
|
||||
|
@ -655,38 +655,6 @@ void PaintableBox::clear_clip_overflow_rect(PaintContext& context, PaintPhase ph
|
|||
restore_clip(context, enclosing_clip_frame());
|
||||
}
|
||||
|
||||
void PaintableBox::apply_own_clip_rect(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!own_clip_frame())
|
||||
return;
|
||||
|
||||
// FIXME: This should apply to SVGs
|
||||
if (is<SVGPaintable>(*this) || is<SVGSVGPaintable>(*this))
|
||||
return;
|
||||
|
||||
// FIXME: This should also apply to borders and outlines.
|
||||
if (!first_is_one_of(phase, PaintPhase::Background, PaintPhase::Foreground))
|
||||
return;
|
||||
|
||||
apply_clip(context, own_clip_frame());
|
||||
}
|
||||
|
||||
void PaintableBox::clear_own_clip_rect(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!own_clip_frame())
|
||||
return;
|
||||
|
||||
// FIXME: This should apply to SVGs
|
||||
if (is<SVGPaintable>(*this) || is<SVGSVGPaintable>(*this))
|
||||
return;
|
||||
|
||||
// FIXME: This should also apply to borders and outlines.
|
||||
if (!first_is_one_of(phase, PaintPhase::Background, PaintPhase::Foreground))
|
||||
return;
|
||||
|
||||
restore_clip(context, own_clip_frame());
|
||||
}
|
||||
|
||||
void paint_cursor_if_needed(PaintContext& context, TextPaintable const& paintable, PaintableFragment const& fragment)
|
||||
{
|
||||
auto const& navigable = *paintable.navigable();
|
||||
|
|
|
@ -142,9 +142,6 @@ public:
|
|||
virtual void apply_clip_overflow_rect(PaintContext&, PaintPhase) const override;
|
||||
virtual void clear_clip_overflow_rect(PaintContext&, PaintPhase) const override;
|
||||
|
||||
virtual void apply_own_clip_rect(PaintContext&, PaintPhase) const override;
|
||||
virtual void clear_own_clip_rect(PaintContext&, PaintPhase) const override;
|
||||
|
||||
[[nodiscard]] virtual TraversalDecision hit_test(CSSPixelPoint position, HitTestType type, Function<TraversalDecision(HitTestResult)> const& callback) const override;
|
||||
Optional<HitTestResult> hit_test(CSSPixelPoint, HitTestType) const;
|
||||
[[nodiscard]] TraversalDecision hit_test_children(CSSPixelPoint, HitTestType, Function<TraversalDecision(HitTestResult)> const&) const;
|
||||
|
|
|
@ -17,6 +17,26 @@ SVGPaintable::SVGPaintable(Layout::SVGBox const& layout_box)
|
|||
{
|
||||
}
|
||||
|
||||
void SVGPaintable::before_paint(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
if (!has_css_transform()) {
|
||||
apply_clip_overflow_rect(context, phase);
|
||||
}
|
||||
apply_scroll_offset(context, phase);
|
||||
}
|
||||
|
||||
void SVGPaintable::after_paint(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
reset_scroll_offset(context, phase);
|
||||
if (!has_css_transform()) {
|
||||
clear_clip_overflow_rect(context, phase);
|
||||
}
|
||||
}
|
||||
|
||||
Layout::SVGBox const& SVGPaintable::layout_box() const
|
||||
{
|
||||
return static_cast<Layout::SVGBox const&>(layout_node());
|
||||
|
|
|
@ -22,6 +22,9 @@ protected:
|
|||
|
||||
SVGPaintable(Layout::SVGBox const&);
|
||||
|
||||
virtual void before_paint(PaintContext&, PaintPhase) const override;
|
||||
virtual void after_paint(PaintContext&, PaintPhase) const override;
|
||||
|
||||
virtual CSSPixelRect compute_absolute_rect() const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,26 @@ SVGSVGPaintable::SVGSVGPaintable(Layout::SVGSVGBox const& layout_box)
|
|||
{
|
||||
}
|
||||
|
||||
void SVGSVGPaintable::before_paint(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
if (!has_css_transform()) {
|
||||
apply_clip_overflow_rect(context, phase);
|
||||
}
|
||||
apply_scroll_offset(context, phase);
|
||||
}
|
||||
|
||||
void SVGSVGPaintable::after_paint(PaintContext& context, PaintPhase phase) const
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
reset_scroll_offset(context, phase);
|
||||
if (!has_css_transform()) {
|
||||
clear_clip_overflow_rect(context, phase);
|
||||
}
|
||||
}
|
||||
|
||||
Layout::SVGSVGBox const& SVGSVGPaintable::layout_box() const
|
||||
{
|
||||
return static_cast<Layout::SVGSVGBox const&>(layout_node());
|
||||
|
|
|
@ -23,6 +23,9 @@ public:
|
|||
static void paint_svg_box(PaintContext& context, PaintableBox const& svg_box, PaintPhase phase);
|
||||
static void paint_descendants(PaintContext& context, PaintableBox const& paintable, PaintPhase phase);
|
||||
|
||||
virtual void before_paint(PaintContext&, PaintPhase) const override;
|
||||
virtual void after_paint(PaintContext&, PaintPhase) const override;
|
||||
|
||||
protected:
|
||||
SVGSVGPaintable(Layout::SVGSVGBox const&);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue