1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 23:57:44 +00:00

LibWeb: Move painting logic from Layout::Viewport to ViewportPaintable

This commit is contained in:
Andreas Kling 2023-08-19 08:38:51 +02:00
parent c01c4b41e2
commit 8bb275f2ea
9 changed files with 54 additions and 48 deletions

View file

@ -10,6 +10,7 @@
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Painting/BorderRadiusCornerClipper.h>
#include <LibWeb/Painting/NestedBrowsingContextPaintable.h>
#include <LibWeb/Painting/ViewportPaintable.h>
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<Layout::Viewport*>(hosted_layout_tree)->paint_all_phases(context);
const_cast<ViewportPaintable&>(verify_cast<ViewportPaintable>(*hosted_paint_tree)).paint_all_phases(context);
context.set_device_viewport_rect(old_viewport_rect);
context.painter().restore();

View file

@ -15,6 +15,7 @@
#include <LibWeb/Painting/FilterPainting.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/StackingContext.h>
#include <LibWeb/Painting/ViewportPaintable.h>
#include <LibWeb/Platform/FontPlugin.h>
namespace Web::Painting {
@ -739,7 +740,7 @@ Optional<HitTestResult> PaintableBox::hit_test(CSSPixelPoint position, HitTestTy
return {};
if (layout_box().is_viewport()) {
const_cast<Layout::Viewport&>(static_cast<Layout::Viewport const&>(layout_box())).build_stacking_context_tree_if_needed();
const_cast<ViewportPaintable&>(static_cast<ViewportPaintable const&>(*this)).build_stacking_context_tree_if_needed();
return stacking_context()->hit_test(position, type);
}

View file

@ -5,6 +5,7 @@
*/
#include <LibWeb/Layout/Viewport.h>
#include <LibWeb/Painting/StackingContext.h>
#include <LibWeb/Painting/ViewportPaintable.h>
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<StackingContext>(layout_box(), nullptr, 0));
size_t index_in_tree_order = 1;
for_each_in_subtree_of_type<PaintableBox>([&](PaintableBox const& paintable) {
auto& paintable_box = const_cast<PaintableBox&>(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<Painting::StackingContext>(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<int>());
stacking_context()->paint(context);
}
}

View file

@ -17,7 +17,12 @@ public:
static JS::NonnullGCPtr<ViewportPaintable> 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&);
};