mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-21 15:40:28 +00:00
When rounding a CSSPixelRect to a DevicePixelRect, we simply pulled its width and height through round() and called it a day. Unfortunately this could negatively affect the rect's perceived positioning. A rect at { 0.5, 0.0 } with size { 19.5 x 20.0 } should have its right edge at position 20, but after rounding it would end up at { 1, 0 } with size { 20 x 20 }, causing its right edge to be at position 21 instead. Fix this by first rounding the right and bottom edges of the input rect, and then determining the dimensions by subtracting its rounded position. Fixes #245.
94 lines
2.9 KiB
C++
94 lines
2.9 KiB
C++
/*
|
|
* Copyright (c) 2018-2022, Andreas Kling <andreas@ladybird.org>
|
|
* Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
|
|
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibWeb/Forward.h>
|
|
#include <LibWeb/PixelUnits.h>
|
|
|
|
namespace Web::Painting {
|
|
|
|
class DevicePixelConverter {
|
|
public:
|
|
DevicePixels rounded_device_pixels(CSSPixels css_pixels) const
|
|
{
|
|
return round(css_pixels.to_double() * m_device_pixels_per_css_pixel);
|
|
}
|
|
|
|
DevicePixels enclosing_device_pixels(CSSPixels css_pixels) const
|
|
{
|
|
return ceil(css_pixels.to_double() * m_device_pixels_per_css_pixel);
|
|
}
|
|
|
|
DevicePixels floored_device_pixels(CSSPixels css_pixels) const
|
|
{
|
|
return floor(css_pixels.to_double() * m_device_pixels_per_css_pixel);
|
|
}
|
|
|
|
DevicePixelPoint rounded_device_point(CSSPixelPoint point) const
|
|
{
|
|
return {
|
|
round(point.x().to_double() * m_device_pixels_per_css_pixel),
|
|
round(point.y().to_double() * m_device_pixels_per_css_pixel)
|
|
};
|
|
}
|
|
|
|
DevicePixelPoint floored_device_point(CSSPixelPoint point) const
|
|
{
|
|
return {
|
|
floor(point.x().to_double() * m_device_pixels_per_css_pixel),
|
|
floor(point.y().to_double() * m_device_pixels_per_css_pixel)
|
|
};
|
|
}
|
|
|
|
DevicePixelRect enclosing_device_rect(CSSPixelRect rect) const
|
|
{
|
|
return {
|
|
floor(rect.x().to_double() * m_device_pixels_per_css_pixel),
|
|
floor(rect.y().to_double() * m_device_pixels_per_css_pixel),
|
|
ceil(rect.width().to_double() * m_device_pixels_per_css_pixel),
|
|
ceil(rect.height().to_double() * m_device_pixels_per_css_pixel)
|
|
};
|
|
}
|
|
|
|
DevicePixelRect rounded_device_rect(CSSPixelRect rect) const
|
|
{
|
|
auto scaled_rect = rect.to_type<double>().scaled(m_device_pixels_per_css_pixel);
|
|
auto x = round(scaled_rect.x());
|
|
auto y = round(scaled_rect.y());
|
|
return { x, y, round(scaled_rect.right()) - x, round(scaled_rect.bottom()) - y };
|
|
}
|
|
|
|
DevicePixelSize enclosing_device_size(CSSPixelSize size) const
|
|
{
|
|
return {
|
|
ceil(size.width().to_double() * m_device_pixels_per_css_pixel),
|
|
ceil(size.height().to_double() * m_device_pixels_per_css_pixel)
|
|
};
|
|
}
|
|
|
|
DevicePixelSize rounded_device_size(CSSPixelSize size) const
|
|
{
|
|
return {
|
|
round(size.width().to_double() * m_device_pixels_per_css_pixel),
|
|
round(size.height().to_double() * m_device_pixels_per_css_pixel)
|
|
};
|
|
}
|
|
|
|
double device_pixels_per_css_pixel() const { return m_device_pixels_per_css_pixel; }
|
|
|
|
DevicePixelConverter(double device_pixels_per_css_pixel)
|
|
: m_device_pixels_per_css_pixel(device_pixels_per_css_pixel)
|
|
{
|
|
}
|
|
|
|
private:
|
|
double m_device_pixels_per_css_pixel { 0 };
|
|
};
|
|
|
|
}
|