mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-13 14:42:51 +00:00
LibWeb: Don't clip to containing block when painting abspos descendants
This commit is contained in:
parent
f941b7aefe
commit
63c727a4a3
Notes:
sideshowbarker
2024-07-17 07:11:10 +09:00
Author: https://github.com/awesomekling
Commit: 63c727a4a3
10 changed files with 37 additions and 25 deletions
|
@ -83,8 +83,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void paint(PaintContext&, PaintPhase) const { }
|
virtual void paint(PaintContext&, PaintPhase) const { }
|
||||||
virtual void before_children_paint(PaintContext&, PaintPhase) const { }
|
|
||||||
virtual void after_children_paint(PaintContext&, PaintPhase) const { }
|
enum class ShouldClipOverflow {
|
||||||
|
No,
|
||||||
|
Yes
|
||||||
|
};
|
||||||
|
virtual void before_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const { }
|
||||||
|
virtual void after_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const { }
|
||||||
|
|
||||||
virtual Optional<HitTestResult> hit_test(Gfx::FloatPoint const&, HitTestType) const;
|
virtual Optional<HitTestResult> hit_test(Gfx::FloatPoint const&, HitTestType) const;
|
||||||
|
|
||||||
|
|
|
@ -257,11 +257,14 @@ BorderRadiiData PaintableBox::normalized_border_radii_data(ShrinkRadiiForBorders
|
||||||
return border_radius_data;
|
return border_radius_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaintableBox::before_children_paint(PaintContext& context, PaintPhase phase) const
|
void PaintableBox::before_children_paint(PaintContext& context, PaintPhase phase, ShouldClipOverflow should_clip_overflow) const
|
||||||
{
|
{
|
||||||
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground))
|
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (should_clip_overflow == ShouldClipOverflow::No)
|
||||||
|
return;
|
||||||
|
|
||||||
// FIXME: Support more overflow variations.
|
// FIXME: Support more overflow variations.
|
||||||
auto clip_rect = absolute_padding_box_rect().to_rounded<int>();
|
auto clip_rect = absolute_padding_box_rect().to_rounded<int>();
|
||||||
auto overflow_x = computed_values().overflow_x();
|
auto overflow_x = computed_values().overflow_x();
|
||||||
|
@ -293,11 +296,14 @@ void PaintableBox::before_children_paint(PaintContext& context, PaintPhase phase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaintableBox::after_children_paint(PaintContext& context, PaintPhase phase) const
|
void PaintableBox::after_children_paint(PaintContext& context, PaintPhase phase, ShouldClipOverflow should_clip_overflow) const
|
||||||
{
|
{
|
||||||
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground))
|
if (!AK::first_is_one_of(phase, PaintPhase::Background, PaintPhase::Border, PaintPhase::Foreground))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (should_clip_overflow == ShouldClipOverflow::No)
|
||||||
|
return;
|
||||||
|
|
||||||
// FIXME: Support more overflow variations.
|
// FIXME: Support more overflow variations.
|
||||||
if (m_clipping_overflow) {
|
if (m_clipping_overflow) {
|
||||||
context.painter().restore();
|
context.painter().restore();
|
||||||
|
|
|
@ -107,8 +107,8 @@ public:
|
||||||
DOM::Document const& document() const { return layout_box().document(); }
|
DOM::Document const& document() const { return layout_box().document(); }
|
||||||
DOM::Document& document() { return layout_box().document(); }
|
DOM::Document& document() { return layout_box().document(); }
|
||||||
|
|
||||||
virtual void before_children_paint(PaintContext&, PaintPhase) const override;
|
virtual void before_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const override;
|
||||||
virtual void after_children_paint(PaintContext&, PaintPhase) const override;
|
virtual void after_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const override;
|
||||||
|
|
||||||
virtual Optional<HitTestResult> hit_test(Gfx::FloatPoint const&, HitTestType) const override;
|
virtual Optional<HitTestResult> hit_test(Gfx::FloatPoint const&, HitTestType) const override;
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@ Layout::SVGGraphicsBox const& SVGGraphicsPaintable::layout_box() const
|
||||||
return static_cast<Layout::SVGGraphicsBox const&>(layout_node());
|
return static_cast<Layout::SVGGraphicsBox const&>(layout_node());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVGGraphicsPaintable::before_children_paint(PaintContext& context, PaintPhase phase) const
|
void SVGGraphicsPaintable::before_children_paint(PaintContext& context, PaintPhase phase, ShouldClipOverflow should_clip_overflow) const
|
||||||
{
|
{
|
||||||
SVGPaintable::before_children_paint(context, phase);
|
SVGPaintable::before_children_paint(context, phase, should_clip_overflow);
|
||||||
if (phase != PaintPhase::Foreground)
|
if (phase != PaintPhase::Foreground)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Web::Painting {
|
||||||
|
|
||||||
class SVGGraphicsPaintable : public SVGPaintable {
|
class SVGGraphicsPaintable : public SVGPaintable {
|
||||||
public:
|
public:
|
||||||
virtual void before_children_paint(PaintContext&, PaintPhase) const override;
|
virtual void before_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const override;
|
||||||
|
|
||||||
Layout::SVGGraphicsBox const& layout_box() const;
|
Layout::SVGGraphicsBox const& layout_box() const;
|
||||||
|
|
||||||
|
|
|
@ -20,17 +20,17 @@ Layout::SVGBox const& SVGPaintable::layout_box() const
|
||||||
return static_cast<Layout::SVGBox const&>(layout_node());
|
return static_cast<Layout::SVGBox const&>(layout_node());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVGPaintable::before_children_paint(PaintContext& context, PaintPhase phase) const
|
void SVGPaintable::before_children_paint(PaintContext& context, PaintPhase phase, ShouldClipOverflow should_clip_overflow) const
|
||||||
{
|
{
|
||||||
PaintableBox::before_children_paint(context, phase);
|
PaintableBox::before_children_paint(context, phase, should_clip_overflow);
|
||||||
if (phase != PaintPhase::Foreground)
|
if (phase != PaintPhase::Foreground)
|
||||||
return;
|
return;
|
||||||
context.svg_context().save();
|
context.svg_context().save();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVGPaintable::after_children_paint(PaintContext& context, PaintPhase phase) const
|
void SVGPaintable::after_children_paint(PaintContext& context, PaintPhase phase, ShouldClipOverflow should_clip_overflow) const
|
||||||
{
|
{
|
||||||
PaintableBox::after_children_paint(context, phase);
|
PaintableBox::after_children_paint(context, phase, should_clip_overflow);
|
||||||
if (phase != PaintPhase::Foreground)
|
if (phase != PaintPhase::Foreground)
|
||||||
return;
|
return;
|
||||||
context.svg_context().restore();
|
context.svg_context().restore();
|
||||||
|
|
|
@ -13,8 +13,8 @@ namespace Web::Painting {
|
||||||
|
|
||||||
class SVGPaintable : public PaintableBox {
|
class SVGPaintable : public PaintableBox {
|
||||||
public:
|
public:
|
||||||
virtual void before_children_paint(PaintContext&, PaintPhase) const override;
|
virtual void before_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const override;
|
||||||
virtual void after_children_paint(PaintContext&, PaintPhase) const override;
|
virtual void after_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const override;
|
||||||
|
|
||||||
Layout::SVGBox const& layout_box() const;
|
Layout::SVGBox const& layout_box() const;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ Layout::SVGSVGBox const& SVGSVGPaintable::layout_box() const
|
||||||
return static_cast<Layout::SVGSVGBox const&>(layout_node());
|
return static_cast<Layout::SVGSVGBox const&>(layout_node());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVGSVGPaintable::before_children_paint(PaintContext& context, PaintPhase phase) const
|
void SVGSVGPaintable::before_children_paint(PaintContext& context, PaintPhase phase, ShouldClipOverflow should_clip_overflow) const
|
||||||
{
|
{
|
||||||
if (phase != PaintPhase::Foreground)
|
if (phase != PaintPhase::Foreground)
|
||||||
return;
|
return;
|
||||||
|
@ -32,12 +32,12 @@ void SVGSVGPaintable::before_children_paint(PaintContext& context, PaintPhase ph
|
||||||
if (!context.has_svg_context())
|
if (!context.has_svg_context())
|
||||||
context.set_svg_context(SVGContext(absolute_rect()));
|
context.set_svg_context(SVGContext(absolute_rect()));
|
||||||
|
|
||||||
PaintableBox::before_children_paint(context, phase);
|
PaintableBox::before_children_paint(context, phase, should_clip_overflow);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVGSVGPaintable::after_children_paint(PaintContext& context, PaintPhase phase) const
|
void SVGSVGPaintable::after_children_paint(PaintContext& context, PaintPhase phase, ShouldClipOverflow should_clip_overflow) const
|
||||||
{
|
{
|
||||||
PaintableBox::after_children_paint(context, phase);
|
PaintableBox::after_children_paint(context, phase, should_clip_overflow);
|
||||||
if (phase != PaintPhase::Foreground)
|
if (phase != PaintPhase::Foreground)
|
||||||
return;
|
return;
|
||||||
context.clear_svg_context();
|
context.clear_svg_context();
|
||||||
|
|
|
@ -15,8 +15,8 @@ class SVGSVGPaintable : public PaintableBox {
|
||||||
public:
|
public:
|
||||||
static NonnullRefPtr<SVGSVGPaintable> create(Layout::SVGSVGBox const&);
|
static NonnullRefPtr<SVGSVGPaintable> create(Layout::SVGSVGBox const&);
|
||||||
|
|
||||||
virtual void before_children_paint(PaintContext&, PaintPhase) const override;
|
virtual void before_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const override;
|
||||||
virtual void after_children_paint(PaintContext&, PaintPhase) const override;
|
virtual void after_children_paint(PaintContext&, PaintPhase, ShouldClipOverflow) const override;
|
||||||
|
|
||||||
Layout::SVGSVGBox const& layout_box() const;
|
Layout::SVGSVGBox const& layout_box() const;
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ static PaintPhase to_paint_phase(StackingContext::StackingContextPaintPhase phas
|
||||||
void StackingContext::paint_descendants(PaintContext& context, Layout::Node& box, StackingContextPaintPhase phase) const
|
void StackingContext::paint_descendants(PaintContext& context, Layout::Node& box, StackingContextPaintPhase phase) const
|
||||||
{
|
{
|
||||||
if (auto* paintable = box.paintable())
|
if (auto* paintable = box.paintable())
|
||||||
paintable->before_children_paint(context, to_paint_phase(phase));
|
paintable->before_children_paint(context, to_paint_phase(phase), Paintable::ShouldClipOverflow::Yes);
|
||||||
|
|
||||||
box.for_each_child([&](auto& child) {
|
box.for_each_child([&](auto& child) {
|
||||||
// If `child` establishes its own stacking context, skip over it.
|
// If `child` establishes its own stacking context, skip over it.
|
||||||
|
@ -123,7 +123,7 @@ void StackingContext::paint_descendants(PaintContext& context, Layout::Node& box
|
||||||
});
|
});
|
||||||
|
|
||||||
if (auto* paintable = box.paintable())
|
if (auto* paintable = box.paintable())
|
||||||
paintable->after_children_paint(context, to_paint_phase(phase));
|
paintable->after_children_paint(context, to_paint_phase(phase), Paintable::ShouldClipOverflow::Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StackingContext::paint_internal(PaintContext& context) const
|
void StackingContext::paint_internal(PaintContext& context) const
|
||||||
|
@ -135,12 +135,13 @@ void StackingContext::paint_internal(PaintContext& context) const
|
||||||
|
|
||||||
auto paint_child = [&](auto* child) {
|
auto paint_child = [&](auto* child) {
|
||||||
auto parent = child->m_box.parent();
|
auto parent = child->m_box.parent();
|
||||||
|
auto should_clip_overflow = child->m_box.is_positioned() ? Paintable::ShouldClipOverflow::No : Paintable::ShouldClipOverflow::Yes;
|
||||||
auto* paintable = parent ? parent->paintable() : nullptr;
|
auto* paintable = parent ? parent->paintable() : nullptr;
|
||||||
if (paintable)
|
if (paintable)
|
||||||
paintable->before_children_paint(context, PaintPhase::Foreground);
|
paintable->before_children_paint(context, PaintPhase::Foreground, should_clip_overflow);
|
||||||
child->paint(context);
|
child->paint(context);
|
||||||
if (paintable)
|
if (paintable)
|
||||||
paintable->after_children_paint(context, PaintPhase::Foreground);
|
paintable->after_children_paint(context, PaintPhase::Foreground, should_clip_overflow);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw positioned descendants with negative z-indices (step 3)
|
// Draw positioned descendants with negative z-indices (step 3)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue