mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:58:12 +00:00
LibWeb+WebContent: Move paint recording init into Navigable
This refactoring makes WebContent less aware of LibWeb internals. The code that initializes paint recording commands now resides in `Navigable::paint()`. Additionally, we no longer need to reuse PaintContext across iframes, allowing us to avoid saving and restoring its state before recursing into an iframe.
This commit is contained in:
parent
72dd37438d
commit
cc447c9c80
6 changed files with 65 additions and 47 deletions
Binary file not shown.
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 42 KiB |
|
@ -32,6 +32,7 @@
|
||||||
#include <LibWeb/Loader/GeneratedPagesLoader.h>
|
#include <LibWeb/Loader/GeneratedPagesLoader.h>
|
||||||
#include <LibWeb/Page/Page.h>
|
#include <LibWeb/Page/Page.h>
|
||||||
#include <LibWeb/Painting/Paintable.h>
|
#include <LibWeb/Painting/Paintable.h>
|
||||||
|
#include <LibWeb/Painting/ViewportPaintable.h>
|
||||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||||
#include <LibWeb/XHR/FormData.h>
|
#include <LibWeb/XHR/FormData.h>
|
||||||
|
|
||||||
|
@ -2032,4 +2033,45 @@ void Navigable::inform_the_navigation_api_about_aborting_navigation()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Navigable::paint(Painting::RecordingPainter& recording_painter, PaintConfig config)
|
||||||
|
{
|
||||||
|
auto document = active_document();
|
||||||
|
if (!document)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto const& page = traversable_navigable()->page();
|
||||||
|
auto viewport_rect = page.css_to_device_rect(this->viewport_rect());
|
||||||
|
Gfx::IntRect bitmap_rect { {}, viewport_rect.size().to_type<int>() };
|
||||||
|
|
||||||
|
document->update_layout();
|
||||||
|
auto background_color = document->background_color();
|
||||||
|
|
||||||
|
recording_painter.fill_rect(bitmap_rect, background_color);
|
||||||
|
if (!document->paintable())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Web::PaintContext context(recording_painter, page.palette(), page.client().device_pixels_per_css_pixel());
|
||||||
|
context.set_device_viewport_rect(viewport_rect);
|
||||||
|
context.set_should_show_line_box_borders(config.should_show_line_box_borders);
|
||||||
|
context.set_should_paint_overlay(config.paint_overlay);
|
||||||
|
context.set_has_focus(config.has_focus);
|
||||||
|
|
||||||
|
if (is_traversable()) {
|
||||||
|
document->paintable()->collect_scroll_frames(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
document->paintable()->paint_all_phases(context);
|
||||||
|
|
||||||
|
// FIXME: Support scrollable frames inside iframes.
|
||||||
|
if (is_traversable()) {
|
||||||
|
Vector<Gfx::IntPoint> scroll_offsets_by_frame_id;
|
||||||
|
scroll_offsets_by_frame_id.resize(context.scroll_frames().size());
|
||||||
|
for (auto [_, scrollable_frame] : context.scroll_frames())
|
||||||
|
scroll_offsets_by_frame_id[scrollable_frame.id] = context.rounded_device_point(
|
||||||
|
scrollable_frame.offset)
|
||||||
|
.to_type<int>();
|
||||||
|
recording_painter.apply_scroll_offsets(scroll_offsets_by_frame_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,6 +170,13 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] TargetSnapshotParams snapshot_target_snapshot_params();
|
[[nodiscard]] TargetSnapshotParams snapshot_target_snapshot_params();
|
||||||
|
|
||||||
|
struct PaintConfig {
|
||||||
|
bool paint_overlay { false };
|
||||||
|
bool should_show_line_box_borders { false };
|
||||||
|
bool has_focus { false };
|
||||||
|
};
|
||||||
|
void paint(Painting::RecordingPainter&, PaintConfig);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Navigable();
|
Navigable();
|
||||||
|
|
||||||
|
|
|
@ -41,25 +41,25 @@ void NestedBrowsingContextPaintable::paint(PaintContext& context, PaintPhase pha
|
||||||
auto clip_rect = context.rounded_device_rect(absolute_rect);
|
auto clip_rect = context.rounded_device_rect(absolute_rect);
|
||||||
ScopedCornerRadiusClip corner_clip { context, clip_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
ScopedCornerRadiusClip corner_clip { context, clip_rect, normalized_border_radii_data(ShrinkRadiiForBorders::Yes) };
|
||||||
|
|
||||||
auto* hosted_document = layout_box().dom_node().content_document_without_origin_check();
|
auto const* hosted_document = layout_box().dom_node().content_document_without_origin_check();
|
||||||
if (!hosted_document)
|
if (!hosted_document)
|
||||||
return;
|
return;
|
||||||
auto* hosted_paint_tree = hosted_document->paintable();
|
auto const* hosted_paint_tree = hosted_document->paintable();
|
||||||
if (!hosted_paint_tree)
|
if (!hosted_paint_tree)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
context.recording_painter().save();
|
context.recording_painter().save();
|
||||||
auto old_viewport_rect = context.device_viewport_rect();
|
|
||||||
|
|
||||||
context.recording_painter().add_clip_rect(clip_rect.to_type<int>());
|
context.recording_painter().add_clip_rect(clip_rect.to_type<int>());
|
||||||
|
|
||||||
auto absolute_device_rect = context.enclosing_device_rect(absolute_rect);
|
auto absolute_device_rect = context.enclosing_device_rect(absolute_rect);
|
||||||
context.recording_painter().translate(absolute_device_rect.x().value(), absolute_device_rect.y().value());
|
context.recording_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().content_navigable()->size()) });
|
HTML::Navigable::PaintConfig paint_config;
|
||||||
const_cast<ViewportPaintable*>(hosted_paint_tree)->paint_all_phases(context);
|
paint_config.paint_overlay = context.should_paint_overlay();
|
||||||
|
paint_config.should_show_line_box_borders = context.should_show_line_box_borders();
|
||||||
|
paint_config.has_focus = context.has_focus();
|
||||||
|
const_cast<DOM::Document*>(hosted_document)->navigable()->paint(context.recording_painter(), paint_config);
|
||||||
|
|
||||||
context.set_device_viewport_rect(old_viewport_rect);
|
|
||||||
context.recording_painter().restore();
|
context.recording_painter().restore();
|
||||||
|
|
||||||
if constexpr (HIGHLIGHT_FOCUSED_FRAME_DEBUG) {
|
if constexpr (HIGHLIGHT_FOCUSED_FRAME_DEBUG) {
|
||||||
|
|
|
@ -171,48 +171,18 @@ Web::Layout::Viewport* PageClient::layout_root()
|
||||||
return document->layout_node();
|
return document->layout_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::Color PageClient::background_color() const
|
|
||||||
{
|
|
||||||
auto document = page().top_level_browsing_context().active_document();
|
|
||||||
if (!document)
|
|
||||||
return Gfx::Color::Transparent;
|
|
||||||
return document->background_color();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PageClient::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& target, Web::PaintOptions paint_options)
|
void PageClient::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& target, Web::PaintOptions paint_options)
|
||||||
{
|
{
|
||||||
Gfx::IntRect bitmap_rect { {}, content_rect.size().to_type<int>() };
|
|
||||||
|
|
||||||
auto document = page().top_level_browsing_context().active_document();
|
|
||||||
if (document) {
|
|
||||||
document->update_layout();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto background_color = this->background_color();
|
|
||||||
|
|
||||||
Web::Painting::RecordingPainter recording_painter;
|
Web::Painting::RecordingPainter recording_painter;
|
||||||
Web::PaintContext context(recording_painter, palette(), device_pixels_per_css_pixel());
|
|
||||||
|
|
||||||
if (background_color.alpha() < 255)
|
Gfx::IntRect bitmap_rect { {}, content_rect.size().to_type<int>() };
|
||||||
recording_painter.fill_rect(bitmap_rect, Web::CSS::SystemColor::canvas());
|
recording_painter.fill_rect(bitmap_rect, Web::CSS::SystemColor::canvas());
|
||||||
recording_painter.fill_rect(bitmap_rect, background_color);
|
|
||||||
|
|
||||||
if (!document->paintable())
|
Web::HTML::Navigable::PaintConfig paint_config;
|
||||||
return;
|
paint_config.paint_overlay = paint_options.paint_overlay == Web::PaintOptions::PaintOverlay::Yes;
|
||||||
|
paint_config.should_show_line_box_borders = m_should_show_line_box_borders;
|
||||||
context.set_should_show_line_box_borders(m_should_show_line_box_borders);
|
paint_config.has_focus = m_has_focus;
|
||||||
context.set_should_paint_overlay(paint_options.paint_overlay == Web::PaintOptions::PaintOverlay::Yes);
|
page().top_level_traversable()->paint(recording_painter, paint_config);
|
||||||
context.set_device_viewport_rect(content_rect);
|
|
||||||
context.set_has_focus(m_has_focus);
|
|
||||||
|
|
||||||
document->paintable()->collect_scroll_frames(context);
|
|
||||||
document->paintable()->paint_all_phases(context);
|
|
||||||
|
|
||||||
Vector<Gfx::IntPoint> scroll_offsets_by_frame_id;
|
|
||||||
scroll_offsets_by_frame_id.resize(context.scroll_frames().size());
|
|
||||||
for (auto [_, scrollable_frame] : context.scroll_frames())
|
|
||||||
scroll_offsets_by_frame_id[scrollable_frame.id] = context.rounded_device_point(scrollable_frame.offset).to_type<int>();
|
|
||||||
recording_painter.apply_scroll_offsets(scroll_offsets_by_frame_id);
|
|
||||||
|
|
||||||
if (s_use_gpu_painter) {
|
if (s_use_gpu_painter) {
|
||||||
#ifdef HAS_ACCELERATED_GRAPHICS
|
#ifdef HAS_ACCELERATED_GRAPHICS
|
||||||
|
|
|
@ -61,12 +61,12 @@ public:
|
||||||
void color_picker_update(Optional<Color> picked_color, Web::HTML::ColorPickerUpdateState state);
|
void color_picker_update(Optional<Color> picked_color, Web::HTML::ColorPickerUpdateState state);
|
||||||
void select_dropdown_closed(Optional<String> value);
|
void select_dropdown_closed(Optional<String> value);
|
||||||
|
|
||||||
[[nodiscard]] Gfx::Color background_color() const;
|
|
||||||
|
|
||||||
void set_user_style(String source);
|
void set_user_style(String source);
|
||||||
|
|
||||||
void ready_to_paint();
|
void ready_to_paint();
|
||||||
|
|
||||||
|
virtual double device_pixels_per_css_pixel() const override { return m_device_pixels_per_css_pixel; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PageClient(PageHost&, u64 id);
|
PageClient(PageHost&, u64 id);
|
||||||
|
|
||||||
|
@ -76,7 +76,6 @@ private:
|
||||||
virtual bool is_connection_open() const override;
|
virtual bool is_connection_open() const override;
|
||||||
virtual Gfx::Palette palette() const override;
|
virtual Gfx::Palette palette() const override;
|
||||||
virtual Web::DevicePixelRect screen_rect() const override { return m_screen_rect; }
|
virtual Web::DevicePixelRect screen_rect() const override { return m_screen_rect; }
|
||||||
virtual double device_pixels_per_css_pixel() const override { return m_device_pixels_per_css_pixel; }
|
|
||||||
virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override { return m_preferred_color_scheme; }
|
virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override { return m_preferred_color_scheme; }
|
||||||
virtual void page_did_invalidate(Web::CSSPixelRect const&) override;
|
virtual void page_did_invalidate(Web::CSSPixelRect const&) override;
|
||||||
virtual void page_did_request_cursor_change(Gfx::StandardCursor) override;
|
virtual void page_did_request_cursor_change(Gfx::StandardCursor) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue