summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/Painting
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2023-05-24 10:50:57 +0200
committerAndreas Kling <kling@serenityos.org>2023-05-24 14:40:35 +0200
commit655d9d14628d73113d0e1a891fe79c3b3052caf3 (patch)
tree7f04312628c7ebda45b174043bc02adab8385480 /Userland/Libraries/LibWeb/Painting
parent30262d702356cdef330a7a3e57da3183b643ba86 (diff)
downloadserenity-655d9d14628d73113d0e1a891fe79c3b3052caf3.zip
LibWeb: Make CSSPixels and Length use 64-bit (double) floating point
This fixes a plethora of rounding problems on many websites. In the future, we may want to replace this with fixed-point arithmetic (bug #18566) for performance (and consistency with other engines), but in the meantime this makes the web look a bit better. :^) There's a lot more things that could be converted to doubles, which would reduce the amount of casting necessary in this patch. We can do that incrementally, however.
Diffstat (limited to 'Userland/Libraries/LibWeb/Painting')
-rw-r--r--Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp16
-rw-r--r--Userland/Libraries/LibWeb/Painting/BorderPainting.cpp10
-rw-r--r--Userland/Libraries/LibWeb/Painting/GradientPainting.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Painting/PaintContext.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Painting/PaintContext.h6
-rw-r--r--Userland/Libraries/LibWeb/Painting/PaintableBox.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Painting/StackingContext.cpp4
-rw-r--r--Userland/Libraries/LibWeb/Painting/VideoPaintable.cpp2
10 files changed, 28 insertions, 28 deletions
diff --git a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
index 0661debd4b..a78e4b76a4 100644
--- a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
@@ -148,16 +148,16 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
CSSPixelRect image_rect;
switch (layer.size_type) {
case CSS::BackgroundSize::Contain: {
- float max_width_ratio = (background_positioning_area.width() / natural_image_width).value();
- float max_height_ratio = (background_positioning_area.height() / natural_image_height).value();
- float ratio = min(max_width_ratio, max_height_ratio);
+ double max_width_ratio = (background_positioning_area.width() / natural_image_width).value();
+ double max_height_ratio = (background_positioning_area.height() / natural_image_height).value();
+ double ratio = min(max_width_ratio, max_height_ratio);
image_rect.set_size(natural_image_width * ratio, natural_image_height * ratio);
break;
}
case CSS::BackgroundSize::Cover: {
- float max_width_ratio = (background_positioning_area.width() / natural_image_width).value();
- float max_height_ratio = (background_positioning_area.height() / natural_image_height).value();
- float ratio = max(max_width_ratio, max_height_ratio);
+ double max_width_ratio = (background_positioning_area.width() / natural_image_width).value();
+ double max_height_ratio = (background_positioning_area.height() / natural_image_height).value();
+ double ratio = max(max_width_ratio, max_height_ratio);
image_rect.set_size(natural_image_width * ratio, natural_image_height * ratio);
break;
}
@@ -253,7 +253,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
repeat_x = false;
} else {
auto space = fmod(background_positioning_area.width(), image_rect.width());
- x_step = image_rect.width() + (space / (float)(whole_images - 1));
+ x_step = image_rect.width() + (space / static_cast<double>(whole_images - 1));
repeat_x = true;
}
break;
@@ -284,7 +284,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
repeat_y = false;
} else {
auto space = fmod(background_positioning_area.height(), image_rect.height());
- y_step = image_rect.height() + ((float)space / (float)(whole_images - 1));
+ y_step = image_rect.height() + (static_cast<double>(space) / static_cast<double>(whole_images - 1));
repeat_y = true;
}
break;
diff --git a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp
index 80f6bda200..9f92331a0f 100644
--- a/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/BorderPainting.cpp
@@ -33,14 +33,14 @@ BorderRadiiData normalized_border_radii_data(Layout::Node const& node, CSSPixelR
// Scale overlapping curves according to https://www.w3.org/TR/css-backgrounds-3/#corner-overlap
CSSPixels f = 1.0f;
- auto width_reciprocal = 1.0f / rect.width().value();
- auto height_reciprocal = 1.0f / rect.height().value();
+ auto width_reciprocal = 1.0 / rect.width().value();
+ auto height_reciprocal = 1.0 / rect.height().value();
f = max(f, width_reciprocal * (top_left_radius_px.horizontal_radius + top_right_radius_px.horizontal_radius));
f = max(f, height_reciprocal * (top_right_radius_px.vertical_radius + bottom_right_radius_px.vertical_radius));
f = max(f, width_reciprocal * (bottom_left_radius_px.horizontal_radius + bottom_right_radius_px.horizontal_radius));
f = max(f, height_reciprocal * (top_left_radius_px.vertical_radius + bottom_left_radius_px.vertical_radius));
- f = 1.0f / f.value();
+ f = 1.0 / f.value();
top_left_radius_px.horizontal_radius *= f;
top_left_radius_px.vertical_radius *= f;
@@ -149,8 +149,8 @@ void paint_border(PaintContext& context, BorderEdge edge, DevicePixelRect const&
auto draw_border = [&](auto const& border, auto const& radius, auto const& opposite_border, auto const& opposite_radius, auto p1_step_translate, auto p2_step_translate) {
auto [p1, p2] = points_for_edge(edge, rect);
- auto p1_step = radius ? 0 : border.width / static_cast<float>(device_pixel_width.value());
- auto p2_step = opposite_radius ? 0 : opposite_border.width / static_cast<float>(device_pixel_width.value());
+ auto p1_step = radius ? 0 : border.width / device_pixel_width.value();
+ auto p2_step = opposite_radius ? 0 : opposite_border.width / device_pixel_width.value();
for (DevicePixels i = 0; i < device_pixel_width; ++i) {
draw_horizontal_or_vertical_line(p1, p2);
p1_step_translate(p1, p1_step);
diff --git a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
index 3d0543478d..78cb3db804 100644
--- a/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/GradientPainting.cpp
@@ -111,11 +111,11 @@ static ColorStopData resolve_color_stop_positions(auto const& color_stop_list, a
LinearGradientData resolve_linear_gradient_data(Layout::Node const& node, CSSPixelSize gradient_size, CSS::LinearGradientStyleValue const& linear_gradient)
{
auto gradient_angle = linear_gradient.angle_degrees(gradient_size);
- auto gradient_length_px = Gfx::calculate_gradient_length(gradient_size, gradient_angle);
+ auto gradient_length_px = Gfx::calculate_gradient_length(gradient_size.to_type<double>().to_type<float>(), gradient_angle);
auto resolved_color_stops = resolve_color_stop_positions(
linear_gradient.color_stop_list(), [&](auto const& length_percentage) {
- return length_percentage.to_px(node, gradient_length_px).value() / gradient_length_px;
+ return length_percentage.to_px(node, gradient_length_px).value() / static_cast<double>(gradient_length_px);
},
linear_gradient.is_repeating());
diff --git a/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp b/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp
index 5e347f3454..4263a3b44e 100644
--- a/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp
+++ b/Userland/Libraries/LibWeb/Painting/MarkerPaintable.cpp
@@ -32,10 +32,10 @@ void MarkerPaintable::paint(PaintContext& context, PaintPhase phase) const
return;
// FIXME: All this does is round to the nearest whole CSS pixel, but it's goofy.
- CSSPixelRect enclosing = absolute_rect().to_type<float>().to_rounded<float>().to_type<CSSPixels>();
+ CSSPixelRect enclosing = absolute_rect().to_type<double>().to_type<float>().to_rounded<float>().to_type<CSSPixels>();
auto device_enclosing = context.enclosing_device_rect(enclosing);
- CSSPixels marker_width = enclosing.height() / 2.0f;
+ CSSPixels marker_width = enclosing.height() / 2.0;
if (auto const* list_style_image = layout_box().list_style_image()) {
CSSPixelRect image_rect {
diff --git a/Userland/Libraries/LibWeb/Painting/PaintContext.cpp b/Userland/Libraries/LibWeb/Painting/PaintContext.cpp
index 86c40fe89a..f767a2e03f 100644
--- a/Userland/Libraries/LibWeb/Painting/PaintContext.cpp
+++ b/Userland/Libraries/LibWeb/Painting/PaintContext.cpp
@@ -10,7 +10,7 @@
namespace Web {
-PaintContext::PaintContext(Gfx::Painter& painter, Palette const& palette, float device_pixels_per_css_pixel)
+PaintContext::PaintContext(Gfx::Painter& painter, Palette const& palette, double device_pixels_per_css_pixel)
: m_painter(painter)
, m_palette(palette)
, m_device_pixels_per_css_pixel(device_pixels_per_css_pixel)
diff --git a/Userland/Libraries/LibWeb/Painting/PaintContext.h b/Userland/Libraries/LibWeb/Painting/PaintContext.h
index d8fd425147..0f590eefa6 100644
--- a/Userland/Libraries/LibWeb/Painting/PaintContext.h
+++ b/Userland/Libraries/LibWeb/Painting/PaintContext.h
@@ -18,7 +18,7 @@ namespace Web {
class PaintContext {
public:
- PaintContext(Gfx::Painter& painter, Palette const& palette, float device_pixels_per_css_pixel);
+ PaintContext(Gfx::Painter& painter, Palette const& palette, double device_pixels_per_css_pixel);
Gfx::Painter& painter() const { return m_painter; }
Palette const& palette() const { return m_palette; }
@@ -64,13 +64,13 @@ public:
return clone;
}
- float device_pixels_per_css_pixel() const { return m_device_pixels_per_css_pixel; }
+ double device_pixels_per_css_pixel() const { return m_device_pixels_per_css_pixel; }
private:
Gfx::Painter& m_painter;
Palette m_palette;
Optional<SVGContext> m_svg_context;
- float m_device_pixels_per_css_pixel;
+ double m_device_pixels_per_css_pixel { 0 };
DevicePixelRect m_device_viewport_rect;
bool m_should_show_line_box_borders { false };
bool m_focus { false };
diff --git a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
index e243c8475f..e358622e3a 100644
--- a/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
+++ b/Userland/Libraries/LibWeb/Painting/PaintableBox.cpp
@@ -155,7 +155,7 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
if (should_clip_rect) {
context.painter().save();
auto border_box = absolute_border_box_rect();
- context.painter().add_clip_rect(context.rounded_device_rect(clip_rect.to_rect().resolved(Paintable::layout_node(), border_box.to_type<float>()).to_type<CSSPixels>()).to_type<int>());
+ context.painter().add_clip_rect(context.rounded_device_rect(clip_rect.to_rect().resolved(Paintable::layout_node(), border_box.to_type<double>()).to_type<CSSPixels>()).to_type<int>());
}
paint_backdrop_filter(context);
paint_background(context);
@@ -434,7 +434,7 @@ static void paint_text_decoration(PaintContext& context, Gfx::Painter& painter,
CSSPixels css_line_thickness = [&] {
CSS::Length computed_thickness = text_node.computed_values().text_decoration_thickness().resolved(text_node, CSS::Length(1, CSS::Length::Type::Em));
if (computed_thickness.is_auto())
- return max(glyph_height * 0.1f, 1.f);
+ return max(glyph_height * 0.1, 1.);
return computed_thickness.to_px(text_node);
}();
diff --git a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp
index 09ac1270a5..7fc3076b39 100644
--- a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp
+++ b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp
@@ -36,7 +36,7 @@ Optional<HitTestResult> SVGGeometryPaintable::hit_test(CSSPixelPoint position, H
if (auto transform = layout_box().layout_transform(); transform.has_value()) {
auto transformed_bounding_box = transform->map_to_quad(
const_cast<SVG::SVGGeometryElement&>(geometry_element).get_path().bounding_box());
- if (!transformed_bounding_box.contains(position.to_type<float>()))
+ if (!transformed_bounding_box.contains(position.to_type<double>().to_type<float>()))
return {};
}
return result;
@@ -92,7 +92,7 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const
auto svg_viewport = [&] {
if (maybe_view_box.has_value())
return Gfx::FloatRect { maybe_view_box->min_x, maybe_view_box->min_y, maybe_view_box->width, maybe_view_box->height };
- return Gfx::FloatRect { { 0, 0 }, svg_context.svg_element_size().to_type<float>() };
+ return Gfx::FloatRect { { 0, 0 }, svg_context.svg_element_size().to_type<double>().to_type<float>() };
}();
SVG::SVGPaintContext paint_context {
diff --git a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
index 8a98a76afa..4c83296c34 100644
--- a/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
+++ b/Userland/Libraries/LibWeb/Painting/StackingContext.cpp
@@ -232,7 +232,7 @@ Gfx::FloatMatrix4x4 StackingContext::get_transformation_matrix(CSS::Transformati
auto count = transformation.values.size();
auto value = [this, transformation](size_t index, Optional<CSS::Length const&> reference_length = {}) -> float {
return transformation.values[index].visit(
- [this, reference_length](CSS::LengthPercentage const& value) {
+ [this, reference_length](CSS::LengthPercentage const& value) -> float {
if (reference_length.has_value()) {
return value.resolved(m_box, reference_length.value()).to_px(m_box).value();
}
@@ -430,7 +430,7 @@ Gfx::FloatPoint StackingContext::compute_transform_origin() const
auto reference_box = paintable_box().absolute_border_box_rect();
auto x = reference_box.left() + style_value.x.to_px(m_box, reference_box.width());
auto y = reference_box.top() + style_value.y.to_px(m_box, reference_box.height());
- return { x, y };
+ return { static_cast<float>(x.value()), static_cast<float>(y.value()) };
}
template<typename U, typename Callback>
diff --git a/Userland/Libraries/LibWeb/Painting/VideoPaintable.cpp b/Userland/Libraries/LibWeb/Painting/VideoPaintable.cpp
index 96a5d36232..078db4eaca 100644
--- a/Userland/Libraries/LibWeb/Painting/VideoPaintable.cpp
+++ b/Userland/Libraries/LibWeb/Painting/VideoPaintable.cpp
@@ -378,7 +378,7 @@ VideoPaintable::DispatchEventOfSameName VideoPaintable::handle_mouseup(Badge<Eve
if (cached_layout_boxes.timeline_rect.has_value() && cached_layout_boxes.timeline_rect->contains(position)) {
auto x_offset = position.x() - cached_layout_boxes.timeline_rect->x();
- auto x_percentage = static_cast<float>(x_offset) / static_cast<float>(cached_layout_boxes.timeline_rect->width());
+ auto x_percentage = static_cast<double>(x_offset) / static_cast<double>(cached_layout_boxes.timeline_rect->width());
auto position = static_cast<double>(x_percentage) * video_element.duration();
video_element.set_current_time(position);