diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index 8508ab8d719cd1efb6030c7370f1ba49d3b2ad33..ea65051ae3404360cd90d3a3aa37c3b75559c3c8 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 a3e11684359ffe52ea90780efd6e6ece1db6a438..9db6562cbafdcad5794237d3922269564514eee2 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 485d67ae2907e6994b5b83e13118b6ac4da4906f..cf9f450764cc8e275b6d441514c03d3b9965d104 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 8f355b44ac958725de5777dc782773634a3e09ed..8ce1d38f70ae292fd6303beb8873628d8ddec4f4 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 b952e4f2bc68e10d79f86b39edd85b4bf6f65261..9be619ee09e87331cb8a912a94af66ba9b023e56 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 d0bea390db07bb74df63a9423bc1d44cb4ff4884..bb5ce534053ae6dc8e44046d62ebe87badedf7b4 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 f4ca864156d65eed974e6dfaaa6daa591a904fdb..1d1d9731eb9bcbc8bdbc4ecc6c8198ff02275d12 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 702d45a38548ea610cdd535c81cd12c932142866..53027b03522a47e90e7f5c0d947c597f67023ac1 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 c0176972488679ba0a3f423576870f7cd644379c..cfd7e9a831df9a19279b6ad9a1d8b9daf29865a9 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)