mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 08:37:45 +00:00
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.
This commit is contained in:
parent
df1bb0ff49
commit
fe92b54137
3 changed files with 13 additions and 2 deletions
|
@ -5,6 +5,7 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <LibGfx/Painter.h>
|
||||||
#include <LibWeb/Painting/PaintContext.h>
|
#include <LibWeb/Painting/PaintContext.h>
|
||||||
|
|
||||||
namespace Web {
|
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()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ public:
|
||||||
void set_device_viewport_rect(DevicePixelRect const& rect) { m_device_viewport_rect = rect; }
|
void set_device_viewport_rect(DevicePixelRect const& rect) { m_device_viewport_rect = rect; }
|
||||||
CSSPixelRect css_viewport_rect() const;
|
CSSPixelRect css_viewport_rect() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool would_be_fully_clipped_by_painter(DevicePixelRect) const;
|
||||||
|
|
||||||
bool has_focus() const { return m_focus; }
|
bool has_focus() const { return m_focus; }
|
||||||
void set_has_focus(bool focus) { m_focus = focus; }
|
void set_has_focus(bool focus) { m_focus = focus; }
|
||||||
|
|
||||||
|
|
|
@ -598,9 +598,12 @@ void PaintableWithLines::paint(PaintContext& context, PaintPhase phase) const
|
||||||
|
|
||||||
for (auto& line_box : m_line_boxes) {
|
for (auto& line_box : m_line_boxes) {
|
||||||
for (auto& fragment : line_box.fragments()) {
|
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()) {
|
if (context.should_show_line_box_borders()) {
|
||||||
auto fragment_absolute_rect = fragment.absolute_rect();
|
context.painter().draw_rect(fragment_absolute_device_rect.to_type<int>(), Color::Green);
|
||||||
context.painter().draw_rect(context.enclosing_device_rect(fragment_absolute_rect).to_type<int>(), Color::Green);
|
|
||||||
context.painter().draw_line(
|
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_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);
|
context.rounded_device_point(fragment_absolute_rect.top_right().translated(-1, fragment.baseline())).to_type<int>(), Color::Red);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue