diff options
author | Andreas Kling <kling@serenityos.org> | 2023-05-23 11:27:16 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-05-23 14:38:45 +0200 |
commit | fe92b54137dff91de9183217d028c5c641908f6b (patch) | |
tree | 1242f20d8542ca464098accd1316b1b3f214abfc /Userland/Libraries/LibWeb | |
parent | df1bb0ff49b0f52f61da8d19c46cdbfa4ef6cfeb (diff) | |
download | serenity-fe92b54137dff91de9183217d028c5c641908f6b.zip |
LibWeb: Don't draw text fragments that would be clipped by the painter
This avoids a ton of work when painting large documents. Even though it
would eventually get clipped by the painter anyway, by bailing out
earlier, we avoid a lot more work (UTF-8 iteration, OpenType lookups,
etc).
It would be even nicer if we could skip entire line boxes, but we don't
have a fast way to get the bounding rect of a line box at the moment.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r-- | Userland/Libraries/LibWeb/Painting/PaintContext.cpp | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Painting/PaintContext.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Painting/PaintableBox.cpp | 7 |
3 files changed, 13 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/Painting/PaintContext.cpp b/Userland/Libraries/LibWeb/Painting/PaintContext.cpp index 394ac15d50..86c40fe89a 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintContext.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintContext.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibGfx/Painter.h> #include <LibWeb/Painting/PaintContext.h> namespace Web { @@ -140,4 +141,9 @@ CSSPixelRect PaintContext::scale_to_css_rect(DevicePixelRect rect) const }; } +bool PaintContext::would_be_fully_clipped_by_painter(DevicePixelRect rect) const +{ + return !painter().clip_rect().intersects(rect.to_type<int>().translated(painter().translation())); +} + } diff --git a/Userland/Libraries/LibWeb/Painting/PaintContext.h b/Userland/Libraries/LibWeb/Painting/PaintContext.h index cf5ef72e25..d8fd425147 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintContext.h +++ b/Userland/Libraries/LibWeb/Painting/PaintContext.h @@ -35,6 +35,8 @@ public: void set_device_viewport_rect(DevicePixelRect const& rect) { m_device_viewport_rect = rect; } CSSPixelRect css_viewport_rect() const; + [[nodiscard]] bool would_be_fully_clipped_by_painter(DevicePixelRect) const; + bool has_focus() const { return m_focus; } void set_has_focus(bool focus) { m_focus = focus; } diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp index f7e29f5889..e243c8475f 100644 --- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp +++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp @@ -598,9 +598,12 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const for (auto& line_box : m_line_boxes) { for (auto& fragment : line_box.fragments()) { + auto fragment_absolute_rect = fragment.absolute_rect(); + auto fragment_absolute_device_rect = context.enclosing_device_rect(fragment_absolute_rect); + if (context.would_be_fully_clipped_by_painter(fragment_absolute_device_rect)) + continue; if (context.should_show_line_box_borders()) { - auto fragment_absolute_rect = fragment.absolute_rect(); - context.painter().draw_rect(context.enclosing_device_rect(fragment_absolute_rect).to_type<int>(), Color::Green); + context.painter().draw_rect(fragment_absolute_device_rect.to_type<int>(), Color::Green); context.painter().draw_line( context.rounded_device_point(fragment_absolute_rect.top_left().translated(0, fragment.baseline())).to_type<int>(), context.rounded_device_point(fragment_absolute_rect.top_right().translated(-1, fragment.baseline())).to_type<int>(), Color::Red); |