summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2022-11-25 17:07:19 +0000
committerLinus Groh <mail@linusgroh.de>2022-12-10 12:03:19 +0000
commit8dfeb67f8ceee2491615e11895f87e5172a7eae4 (patch)
treeb67f35e2a1c5051701e363abc354fab61e20104c /Userland
parent6361584d4a92c351f4f66ddf7b7924beb11e55ae (diff)
downloadserenity-8dfeb67f8ceee2491615e11895f87e5172a7eae4.zip
LibWeb+WebContent+headless-browser: Make Page aware of the display scale
For now, we just report it as "1" everywhere. Replaced `screen_rect()` with `web_exposed_screen_area()` from the spec.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/CSS/Screen.cpp8
-rw-r--r--Userland/Libraries/LibWeb/HTML/Window.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Page/Page.cpp62
-rw-r--r--Userland/Libraries/LibWeb/Page/Page.h15
-rw-r--r--Userland/Services/WebContent/ConnectionFromClient.cpp6
-rw-r--r--Userland/Services/WebContent/PageHost.cpp14
-rw-r--r--Userland/Services/WebContent/PageHost.h17
-rw-r--r--Userland/Services/WebContent/WebDriverConnection.cpp4
-rw-r--r--Userland/Utilities/headless-browser.cpp22
9 files changed, 118 insertions, 34 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Screen.cpp b/Userland/Libraries/LibWeb/CSS/Screen.cpp
index 35fee91694..b066b744c7 100644
--- a/Userland/Libraries/LibWeb/CSS/Screen.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Screen.cpp
@@ -33,7 +33,13 @@ void Screen::visit_edges(Cell::Visitor& visitor)
Gfx::IntRect Screen::screen_rect() const
{
- return window().page()->screen_rect();
+ auto screen_rect_in_css_pixels = window().page()->web_exposed_screen_area();
+ return {
+ screen_rect_in_css_pixels.x().value(),
+ screen_rect_in_css_pixels.y().value(),
+ screen_rect_in_css_pixels.width().value(),
+ screen_rect_in_css_pixels.height().value()
+ };
}
}
diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp
index 2314e854cd..f4d39a476a 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Window.cpp
@@ -673,12 +673,12 @@ Optional<CSS::MediaFeatureValue> Window::query_media_feature(CSS::MediaFeatureID
// FIXME: device-aspect-ratio
case CSS::MediaFeatureID::DeviceHeight:
if (auto* page = this->page()) {
- return CSS::MediaFeatureValue(CSS::Length::make_px(page->screen_rect().height()));
+ return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().height().value()));
}
return CSS::MediaFeatureValue(0);
case CSS::MediaFeatureID::DeviceWidth:
if (auto* page = this->page()) {
- return CSS::MediaFeatureValue(CSS::Length::make_px(page->screen_rect().width()));
+ return CSS::MediaFeatureValue(CSS::Length::make_px(page->web_exposed_screen_area().width().value()));
}
return CSS::MediaFeatureValue(0);
case CSS::MediaFeatureID::DisplayMode:
diff --git a/Userland/Libraries/LibWeb/Page/Page.cpp b/Userland/Libraries/LibWeb/Page/Page.cpp
index 0377bb58ee..b38956699b 100644
--- a/Userland/Libraries/LibWeb/Page/Page.cpp
+++ b/Userland/Libraries/LibWeb/Page/Page.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -54,9 +55,17 @@ Gfx::Palette Page::palette() const
return m_client.palette();
}
-Gfx::IntRect Page::screen_rect() const
+// https://w3c.github.io/csswg-drafts/cssom-view-1/#web-exposed-screen-area
+CSSPixelRect Page::web_exposed_screen_area() const
{
- return m_client.screen_rect();
+ auto device_pixel_rect = m_client.screen_rect();
+ auto scale = client().device_pixels_per_css_pixel();
+ return {
+ device_pixel_rect.x().value() / scale,
+ device_pixel_rect.y().value() / scale,
+ device_pixel_rect.width().value() / scale,
+ device_pixel_rect.height().value() / scale
+ };
}
CSS::PreferredColorScheme Page::preferred_color_scheme() const
@@ -64,6 +73,55 @@ CSS::PreferredColorScheme Page::preferred_color_scheme() const
return m_client.preferred_color_scheme();
}
+CSSPixelPoint Page::device_to_css_point(DevicePixelPoint point) const
+{
+ return {
+ point.x().value() / client().device_pixels_per_css_pixel(),
+ point.y().value() / client().device_pixels_per_css_pixel(),
+ };
+}
+
+DevicePixelPoint Page::css_to_device_point(CSSPixelPoint point) const
+{
+ return {
+ point.x().value() * client().device_pixels_per_css_pixel(),
+ point.y().value() * client().device_pixels_per_css_pixel(),
+ };
+}
+
+CSSPixelRect Page::device_to_css_rect(DevicePixelRect rect) const
+{
+ auto scale = client().device_pixels_per_css_pixel();
+ return {
+ rect.x().value() / scale,
+ rect.y().value() / scale,
+ rect.width().value() / scale,
+ rect.height().value() / scale
+ };
+}
+
+DevicePixelRect Page::enclosing_device_rect(CSSPixelRect rect) const
+{
+ auto scale = client().device_pixels_per_css_pixel();
+ return {
+ floorf(rect.x().value() * scale),
+ floorf(rect.y().value() * scale),
+ ceilf(rect.width().value() * scale),
+ ceilf(rect.height().value() * scale)
+ };
+}
+
+DevicePixelRect Page::rounded_device_rect(CSSPixelRect rect) const
+{
+ auto scale = client().device_pixels_per_css_pixel();
+ return {
+ roundf(rect.x().value() * scale),
+ roundf(rect.y().value() * scale),
+ roundf(rect.width().value() * scale),
+ roundf(rect.height().value() * scale)
+ };
+}
+
bool Page::handle_mousewheel(Gfx::IntPoint position, unsigned button, unsigned buttons, unsigned modifiers, int wheel_delta_x, int wheel_delta_y)
{
return top_level_browsing_context().event_handler().handle_mousewheel(position, button, buttons, modifiers, wheel_delta_x, wheel_delta_y);
diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h
index 8e8418c1d0..dde45bf915 100644
--- a/Userland/Libraries/LibWeb/Page/Page.h
+++ b/Userland/Libraries/LibWeb/Page/Page.h
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@@ -25,6 +26,7 @@
#include <LibWeb/Cookie/Cookie.h>
#include <LibWeb/Forward.h>
#include <LibWeb/Loader/FileRequest.h>
+#include <LibWeb/PixelUnits.h>
namespace Web {
@@ -54,6 +56,12 @@ public:
void load_html(StringView, const AK::URL&);
+ CSSPixelPoint device_to_css_point(DevicePixelPoint) const;
+ DevicePixelPoint css_to_device_point(CSSPixelPoint) const;
+ CSSPixelRect device_to_css_rect(DevicePixelRect) const;
+ DevicePixelRect enclosing_device_rect(CSSPixelRect) const;
+ DevicePixelRect rounded_device_rect(CSSPixelRect) const;
+
bool handle_mouseup(Gfx::IntPoint, unsigned button, unsigned buttons, unsigned modifiers);
bool handle_mousedown(Gfx::IntPoint, unsigned button, unsigned buttons, unsigned modifiers);
bool handle_mousemove(Gfx::IntPoint, unsigned buttons, unsigned modifiers);
@@ -64,7 +72,7 @@ public:
bool handle_keyup(KeyCode, unsigned modifiers, u32 code_point);
Gfx::Palette palette() const;
- Gfx::IntRect screen_rect() const;
+ CSSPixelRect web_exposed_screen_area() const;
CSS::PreferredColorScheme preferred_color_scheme() const;
bool is_same_origin_policy_enabled() const { return m_same_origin_policy_enabled; }
@@ -139,9 +147,10 @@ public:
virtual Page const& page() const = 0;
virtual bool is_connection_open() const = 0;
virtual Gfx::Palette palette() const = 0;
- virtual Gfx::IntRect screen_rect() const = 0;
+ virtual DevicePixelRect screen_rect() const = 0;
+ virtual float device_pixels_per_css_pixel() const = 0;
virtual CSS::PreferredColorScheme preferred_color_scheme() const = 0;
- virtual void paint(Gfx::IntRect const&, Gfx::Bitmap&) = 0;
+ virtual void paint(DevicePixelRect const&, Gfx::Bitmap&) = 0;
virtual void page_did_change_title(DeprecatedString const&) { }
virtual void page_did_request_navigate_back() { }
virtual void page_did_request_navigate_forward() { }
diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp
index 5774c46f94..bc56decb02 100644
--- a/Userland/Services/WebContent/ConnectionFromClient.cpp
+++ b/Userland/Services/WebContent/ConnectionFromClient.cpp
@@ -149,7 +149,7 @@ void ConnectionFromClient::paint(Gfx::IntRect const& content_rect, i32 backing_s
void ConnectionFromClient::flush_pending_paint_requests()
{
for (auto& pending_paint : m_pending_paint_requests) {
- m_page_host->paint(pending_paint.content_rect, *pending_paint.bitmap);
+ m_page_host->paint(pending_paint.content_rect.to_type<Web::DevicePixels>(), *pending_paint.bitmap);
async_did_paint(pending_paint.content_rect, pending_paint.bitmap_id);
}
m_pending_paint_requests.clear();
@@ -461,9 +461,9 @@ Messages::WebContentServer::TakeDocumentScreenshotResponse ConnectionFromClient:
return { {} };
auto const& content_size = m_page_host->content_size();
- Gfx::IntRect rect { { 0, 0 }, content_size };
+ Web::DevicePixelRect rect { { 0, 0 }, content_size };
- auto bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, rect.size()).release_value_but_fixme_should_propagate_errors();
+ auto bitmap = Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRA8888, rect.size().to_type<int>()).release_value_but_fixme_should_propagate_errors();
m_page_host->paint(rect, *bitmap);
return { bitmap->to_shareable_bitmap() };
diff --git a/Userland/Services/WebContent/PageHost.cpp b/Userland/Services/WebContent/PageHost.cpp
index 4f5a83c303..7275b7d111 100644
--- a/Userland/Services/WebContent/PageHost.cpp
+++ b/Userland/Services/WebContent/PageHost.cpp
@@ -104,10 +104,10 @@ Web::Layout::InitialContainingBlock* PageHost::layout_root()
return document->layout_node();
}
-void PageHost::paint(Gfx::IntRect const& content_rect, Gfx::Bitmap& target)
+void PageHost::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& target)
{
Gfx::Painter painter(target);
- Gfx::IntRect bitmap_rect { {}, content_rect.size() };
+ Gfx::IntRect bitmap_rect { {}, content_rect.size().to_type<int>() };
if (auto* document = page().top_level_browsing_context().active_document())
document->update_layout();
@@ -118,9 +118,9 @@ void PageHost::paint(Gfx::IntRect const& content_rect, Gfx::Bitmap& target)
return;
}
- Web::PaintContext context(painter, palette(), content_rect.top_left());
+ Web::PaintContext context(painter, palette(), content_rect.top_left().to_type<int>());
context.set_should_show_line_box_borders(m_should_show_line_box_borders);
- context.set_viewport_rect(content_rect);
+ context.set_viewport_rect(content_rect.to_type<int>());
context.set_has_focus(m_has_focus);
layout_root->paint_all_phases(context);
}
@@ -152,10 +152,10 @@ void PageHost::page_did_layout()
auto* layout_root = this->layout_root();
VERIFY(layout_root);
if (layout_root->paint_box()->has_overflow())
- m_content_size = enclosing_int_rect(layout_root->paint_box()->scrollable_overflow_rect().value()).size();
+ m_content_size = page().enclosing_device_rect(layout_root->paint_box()->scrollable_overflow_rect().value().to_type<Web::CSSPixels>()).size();
else
- m_content_size = enclosing_int_rect(layout_root->paint_box()->absolute_rect()).size();
- m_client.async_did_layout(m_content_size);
+ m_content_size = page().enclosing_device_rect(layout_root->paint_box()->absolute_rect().to_type<Web::CSSPixels>()).size();
+ m_client.async_did_layout(m_content_size.to_type<int>());
}
void PageHost::page_did_change_title(DeprecatedString const& title)
diff --git a/Userland/Services/WebContent/PageHost.h b/Userland/Services/WebContent/PageHost.h
index ad494c05f8..94c8749b4a 100644
--- a/Userland/Services/WebContent/PageHost.h
+++ b/Userland/Services/WebContent/PageHost.h
@@ -9,6 +9,7 @@
#include <LibGfx/Rect.h>
#include <LibWeb/Page/Page.h>
+#include <LibWeb/PixelUnits.h>
#include <WebContent/Forward.h>
namespace WebContent {
@@ -26,11 +27,12 @@ public:
virtual Web::Page& page() override { return *m_page; }
virtual Web::Page const& page() const override { return *m_page; }
- virtual void paint(Gfx::IntRect const& content_rect, Gfx::Bitmap&) override;
+ virtual void paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap&) override;
void set_palette_impl(Gfx::PaletteImpl const&);
void set_viewport_rect(Gfx::IntRect const&);
- void set_screen_rects(Vector<Gfx::IntRect, 4> const& rects, size_t main_screen_index) { m_screen_rect = rects[main_screen_index]; };
+ void set_screen_rects(Vector<Gfx::IntRect, 4> const& rects, size_t main_screen_index) { m_screen_rect = rects[main_screen_index].to_type<Web::DevicePixels>(); }
+ void set_screen_display_scale(float device_pixels_per_css_pixel) { m_screen_display_scale = device_pixels_per_css_pixel; }
void set_preferred_color_scheme(Web::CSS::PreferredColorScheme);
void set_should_show_line_box_borders(bool b) { m_should_show_line_box_borders = b; }
void set_has_focus(bool);
@@ -38,7 +40,7 @@ public:
void set_window_position(Gfx::IntPoint);
void set_window_size(Gfx::IntSize);
- Gfx::IntSize content_size() const { return m_content_size; }
+ Web::DevicePixelSize content_size() const { return m_content_size; }
ErrorOr<void> connect_to_webdriver(DeprecatedString const& webdriver_ipc_path);
@@ -50,7 +52,8 @@ private:
// ^PageClient
virtual bool is_connection_open() const override;
virtual Gfx::Palette palette() const override;
- virtual Gfx::IntRect screen_rect() const override { return m_screen_rect; }
+ virtual Web::DevicePixelRect screen_rect() const override { return m_screen_rect; }
+ virtual float device_pixels_per_css_pixel() const override { return m_screen_display_scale; }
virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override { return m_preferred_color_scheme; }
virtual void page_did_invalidate(Gfx::IntRect const&) override;
virtual void page_did_change_selection() override;
@@ -104,8 +107,10 @@ private:
ConnectionFromClient& m_client;
NonnullOwnPtr<Web::Page> m_page;
RefPtr<Gfx::PaletteImpl> m_palette_impl;
- Gfx::IntRect m_screen_rect;
- Gfx::IntSize m_content_size;
+ Web::DevicePixelRect m_screen_rect;
+ Web::DevicePixelSize m_content_size;
+ // FIXME: Actually set this based on the device's pixel ratio.
+ float m_screen_display_scale { 1.0f };
bool m_should_show_line_box_borders { false };
bool m_has_focus { false };
diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp
index 94bc6990d7..7244fea996 100644
--- a/Userland/Services/WebContent/WebDriverConnection.cpp
+++ b/Userland/Services/WebContent/WebDriverConnection.cpp
@@ -1521,7 +1521,7 @@ Messages::WebDriverClient::TakeScreenshotResponse WebDriverConnection::take_scre
auto root_rect = calculate_absolute_rect_of_element(m_page_client.page(), *document->document_element());
auto encoded_string = TRY(Web::WebDriver::capture_element_screenshot(
- [&](auto const& rect, auto& bitmap) { m_page_client.paint(rect, bitmap); },
+ [&](auto const& rect, auto& bitmap) { m_page_client.paint(rect.template to_type<Web::DevicePixels>(), bitmap); },
m_page_client.page(),
*document->document_element(),
root_rect));
@@ -1554,7 +1554,7 @@ Messages::WebDriverClient::TakeElementScreenshotResponse WebDriverConnection::ta
auto element_rect = calculate_absolute_rect_of_element(m_page_client.page(), *element);
auto encoded_string = TRY(Web::WebDriver::capture_element_screenshot(
- [&](auto const& rect, auto& bitmap) { m_page_client.paint(rect, bitmap); },
+ [&](auto const& rect, auto& bitmap) { m_page_client.paint(rect.template to_type<Web::DevicePixels>(), bitmap); },
m_page_client.page(),
*element,
element_rect));
diff --git a/Userland/Utilities/headless-browser.cpp b/Userland/Utilities/headless-browser.cpp
index bed46ac996..598af2bd89 100644
--- a/Userland/Utilities/headless-browser.cpp
+++ b/Userland/Utilities/headless-browser.cpp
@@ -73,23 +73,24 @@ public:
page().load(url);
}
- virtual void paint(Gfx::IntRect const& content_rect, Gfx::Bitmap& target) override
+ virtual void paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& target) override
{
Gfx::Painter painter(target);
+ Gfx::IntRect int_content_rect { content_rect.x().value(), content_rect.y().value(), content_rect.width().value(), content_rect.height().value() };
if (auto* document = page().top_level_browsing_context().active_document())
document->update_layout();
- painter.fill_rect({ {}, content_rect.size() }, palette().base());
+ painter.fill_rect({ {}, int_content_rect.size() }, palette().base());
auto* layout_root = this->layout_root();
if (!layout_root) {
return;
}
- Web::PaintContext context(painter, palette(), content_rect.top_left());
+ Web::PaintContext context(painter, palette(), int_content_rect.top_left());
context.set_should_show_line_box_borders(false);
- context.set_viewport_rect(content_rect);
+ context.set_viewport_rect(int_content_rect);
context.set_has_focus(true);
layout_root->paint_all_phases(context);
}
@@ -104,7 +105,7 @@ public:
page().top_level_browsing_context().set_viewport_rect(viewport_rect);
}
- void set_screen_rect(Gfx::IntRect screen_rect)
+ void set_screen_rect(Web::DevicePixelRect screen_rect)
{
m_screen_rect = screen_rect;
}
@@ -141,11 +142,16 @@ public:
return Gfx::Palette(*m_palette_impl);
}
- virtual Gfx::IntRect screen_rect() const override
+ virtual Web::DevicePixelRect screen_rect() const override
{
return m_screen_rect;
}
+ virtual float device_pixels_per_css_pixel() const override
+ {
+ return 1.0f;
+ }
+
virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override
{
return m_preferred_color_scheme;
@@ -259,7 +265,7 @@ private:
NonnullOwnPtr<Web::Page> m_page;
RefPtr<Gfx::PaletteImpl> m_palette_impl;
- Gfx::IntRect m_screen_rect { 0, 0, 800, 600 };
+ Web::DevicePixelRect m_screen_rect { 0, 0, 800, 600 };
Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
RefPtr<WebContent::WebDriverConnection> m_webdriver;
@@ -699,7 +705,7 @@ static void load_page_for_screenshot_and_exit(HeadlessBrowserPageClient& page_cl
auto output_file = MUST(Core::Stream::File::open(output_file_path, Core::Stream::OpenMode::Write));
auto output_rect = page_client.screen_rect();
- auto output_bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRx8888, output_rect.size()));
+ auto output_bitmap = MUST(Gfx::Bitmap::try_create(Gfx::BitmapFormat::BGRx8888, output_rect.size().to_type<int>()));
page_client.paint(output_rect, output_bitmap);