diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index 8508ab8d719..ea65051ae34 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp @@ -46,6 +46,7 @@ #include #include #include +#include namespace Web::CSS { @@ -834,9 +835,9 @@ RefPtr ResolvedCSSStyleDeclaration::style_value_for_property(L return IdentifierStyleValue::create(ValueID::None); // The transform matrix is held by the StackingContext, so we need to make sure we have one first. - auto const* viewport = layout_node.document().layout_node(); + auto const* viewport = layout_node.document().paintable_box(); VERIFY(viewport); - const_cast(*viewport).build_stacking_context_tree_if_needed(); + const_cast(verify_cast(*viewport)).build_stacking_context_tree_if_needed(); VERIFY(layout_node.paintable()); auto const& paintable_box = verify_cast(layout_node.paintable()); diff --git a/Userland/Libraries/LibWeb/Layout/Viewport.cpp b/Userland/Libraries/LibWeb/Layout/Viewport.cpp index a3e11684359..9db6562cbaf 100644 --- a/Userland/Libraries/LibWeb/Layout/Viewport.cpp +++ b/Userland/Libraries/LibWeb/Layout/Viewport.cpp @@ -25,42 +25,6 @@ JS::GCPtr Viewport::selection() const return const_cast(document()).get_selection(); } -void Viewport::build_stacking_context_tree_if_needed() -{ - if (paintable_box()->stacking_context()) - return; - build_stacking_context_tree(); -} - -void Viewport::build_stacking_context_tree() -{ - paintable_box()->set_stacking_context(make(*this, nullptr, 0)); - - size_t index_in_tree_order = 1; - for_each_in_subtree_of_type([&](Box& box) { - if (!box.paintable_box()) - return IterationDecision::Continue; - box.paintable_box()->invalidate_stacking_context(); - if (!box.establishes_stacking_context()) { - VERIFY(!box.paintable_box()->stacking_context()); - return IterationDecision::Continue; - } - auto* parent_context = box.paintable_box()->enclosing_stacking_context(); - VERIFY(parent_context); - box.paintable_box()->set_stacking_context(make(box, parent_context, index_in_tree_order++)); - return IterationDecision::Continue; - }); - - paintable_box()->stacking_context()->sort(); -} - -void Viewport::paint_all_phases(PaintContext& context) -{ - build_stacking_context_tree_if_needed(); - context.painter().translate(-context.device_viewport_rect().location().to_type()); - paintable_box()->stacking_context()->paint(context); -} - void Viewport::recompute_selection_states() { // 1. Start by resetting the selection state of all layout nodes to None. diff --git a/Userland/Libraries/LibWeb/Layout/Viewport.h b/Userland/Libraries/LibWeb/Layout/Viewport.h index 485d67ae290..cf9f450764c 100644 --- a/Userland/Libraries/LibWeb/Layout/Viewport.h +++ b/Userland/Libraries/LibWeb/Layout/Viewport.h @@ -21,17 +21,13 @@ public: const DOM::Document& dom_node() const { return static_cast(*Node::dom_node()); } - void paint_all_phases(PaintContext&); - JS::GCPtr selection() const; - void build_stacking_context_tree_if_needed(); void recompute_selection_states(); private: virtual JS::GCPtr create_paintable() const override; - void build_stacking_context_tree(); virtual bool is_viewport() const override { return true; } }; diff --git a/Userland/Libraries/LibWeb/Painting/NestedBrowsingContextPaintable.cpp b/Userland/Libraries/LibWeb/Painting/NestedBrowsingContextPaintable.cpp index 8f355b44ac9..8ce1d38f70a 100644 --- a/Userland/Libraries/LibWeb/Painting/NestedBrowsingContextPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/NestedBrowsingContextPaintable.cpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace Web::Painting { @@ -43,8 +44,8 @@ void NestedBrowsingContextPaintable::paint(PaintContext& context, PaintPhase pha auto* hosted_document = layout_box().dom_node().content_document_without_origin_check(); if (!hosted_document) return; - auto* hosted_layout_tree = hosted_document->layout_node(); - if (!hosted_layout_tree) + auto* hosted_paint_tree = hosted_document->paintable_box(); + if (!hosted_paint_tree) return; context.painter().save(); @@ -56,7 +57,7 @@ void NestedBrowsingContextPaintable::paint(PaintContext& context, PaintPhase pha context.painter().translate(absolute_device_rect.x().value(), absolute_device_rect.y().value()); context.set_device_viewport_rect({ {}, context.enclosing_device_size(layout_box().dom_node().nested_browsing_context()->size()) }); - const_cast(hosted_layout_tree)->paint_all_phases(context); + const_cast(verify_cast(*hosted_paint_tree)).paint_all_phases(context); context.set_device_viewport_rect(old_viewport_rect); context.painter().restore(); diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index b952e4f2bc6..9be619ee09e 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include namespace Web::Painting { @@ -739,7 +740,7 @@ Optional PaintableBox::hit_test(CSSPixelPoint position, HitTestTy return {}; if (layout_box().is_viewport()) { - const_cast(static_cast(layout_box())).build_stacking_context_tree_if_needed(); + const_cast(static_cast(*this)).build_stacking_context_tree_if_needed(); return stacking_context()->hit_test(position, type); } diff --git a/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp b/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp index d0bea390db0..bb5ce534053 100644 --- a/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/ViewportPaintable.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace Web::Painting { @@ -21,4 +22,39 @@ ViewportPaintable::ViewportPaintable(Layout::Viewport const& layout_viewport) ViewportPaintable::~ViewportPaintable() = default; +void ViewportPaintable::build_stacking_context_tree_if_needed() +{ + if (stacking_context()) + return; + build_stacking_context_tree(); +} + +void ViewportPaintable::build_stacking_context_tree() +{ + set_stacking_context(make(layout_box(), nullptr, 0)); + + size_t index_in_tree_order = 1; + for_each_in_subtree_of_type([&](PaintableBox const& paintable) { + auto& paintable_box = const_cast(paintable); + paintable_box.invalidate_stacking_context(); + if (!paintable_box.layout_box().establishes_stacking_context()) { + VERIFY(!paintable_box.stacking_context()); + return TraversalDecision::Continue; + } + auto* parent_context = paintable_box.enclosing_stacking_context(); + VERIFY(parent_context); + paintable_box.set_stacking_context(make(paintable_box.layout_box(), parent_context, index_in_tree_order++)); + return TraversalDecision::Continue; + }); + + stacking_context()->sort(); +} + +void ViewportPaintable::paint_all_phases(PaintContext& context) +{ + build_stacking_context_tree_if_needed(); + context.painter().translate(-context.device_viewport_rect().location().to_type()); + stacking_context()->paint(context); +} + } diff --git a/Userland/Libraries/LibWeb/Painting/ViewportPaintable.h b/Userland/Libraries/LibWeb/Painting/ViewportPaintable.h index f4ca864156d..1d1d9731eb9 100644 --- a/Userland/Libraries/LibWeb/Painting/ViewportPaintable.h +++ b/Userland/Libraries/LibWeb/Painting/ViewportPaintable.h @@ -17,7 +17,12 @@ public: static JS::NonnullGCPtr create(Layout::Viewport const&); virtual ~ViewportPaintable() override; + void paint_all_phases(PaintContext&); + void build_stacking_context_tree_if_needed(); + private: + void build_stacking_context_tree(); + explicit ViewportPaintable(Layout::Viewport const&); }; diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp index 702d45a3854..53027b03522 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -99,7 +100,7 @@ void SVGDecodedImageData::render(Gfx::IntSize size) const Gfx::Painter painter(*m_bitmap); PaintContext context(painter, m_page_client->palette(), m_page_client->device_pixels_per_css_pixel()); - m_document->layout_node()->paint_all_phases(context); + verify_cast(*m_document->paintable_box()).paint_all_phases(context); } RefPtr SVGDecodedImageData::bitmap(size_t, Gfx::IntSize size) const diff --git a/Userland/Services/WebContent/PageHost.cpp b/Userland/Services/WebContent/PageHost.cpp index c0176972488..cfd7e9a831d 100644 --- a/Userland/Services/WebContent/PageHost.cpp +++ b/Userland/Services/WebContent/PageHost.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -139,7 +140,7 @@ void PageHost::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& targ context.set_should_show_line_box_borders(m_should_show_line_box_borders); context.set_device_viewport_rect(content_rect); context.set_has_focus(m_has_focus); - layout_root->paint_all_phases(context); + verify_cast(*layout_root->paintable_box()).paint_all_phases(context); } void PageHost::set_viewport_rect(Web::DevicePixelRect const& rect)