Browse Source

LibWeb: Apply CSS scaling to SVG elements

Not sure why this was not done before, not now it works easily :^)
MacDue 2 năm trước cách đây
mục cha
commit
d0496ae9b8

+ 8 - 0
Userland/Libraries/LibWeb/Painting/PaintContext.cpp

@@ -67,6 +67,14 @@ DevicePixelPoint PaintContext::rounded_device_point(CSSPixelPoint point) const
     };
 }
 
+DevicePixelPoint PaintContext::floored_device_point(CSSPixelPoint point) const
+{
+    return {
+        floorf(point.x().value() * m_device_pixels_per_css_pixel),
+        floorf(point.y().value() * m_device_pixels_per_css_pixel)
+    };
+}
+
 DevicePixelRect PaintContext::enclosing_device_rect(CSSPixelRect rect) const
 {
     return {

+ 1 - 0
Userland/Libraries/LibWeb/Painting/PaintContext.h

@@ -42,6 +42,7 @@ public:
     DevicePixels floored_device_pixels(CSSPixels css_pixels) const;
     DevicePixels rounded_device_pixels(CSSPixels css_pixels) const;
     DevicePixelPoint rounded_device_point(CSSPixelPoint) const;
+    DevicePixelPoint floored_device_point(CSSPixelPoint) const;
     DevicePixelRect enclosing_device_rect(CSSPixelRect) const;
     DevicePixelRect rounded_device_rect(CSSPixelRect) const;
     DevicePixelSize enclosing_device_size(CSSPixelSize) const;

+ 5 - 3
Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp

@@ -42,15 +42,17 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const
     Gfx::AntiAliasingPainter painter { context.painter() };
     auto& svg_context = context.svg_context();
 
-    auto offset = svg_context.svg_element_position();
+    // FIXME: This should not be trucated to an int.
+    auto offset = context.floored_device_point(svg_context.svg_element_position()).to_type<int>().to_type<float>();
     painter.translate(offset);
 
     auto const* svg_element = geometry_element.first_ancestor_of_type<SVG::SVGSVGElement>();
     auto maybe_view_box = svg_element->view_box();
 
     context.painter().add_clip_rect(context.enclosing_device_rect(absolute_rect()).to_type<int>());
+    auto css_scale = context.device_pixels_per_css_pixel();
 
-    Gfx::Path path = const_cast<SVG::SVGGeometryElement&>(geometry_element).get_path().copy_transformed(Gfx::AffineTransform {}.multiply(layout_box().layout_transform()));
+    Gfx::Path path = const_cast<SVG::SVGGeometryElement&>(geometry_element).get_path().copy_transformed(Gfx::AffineTransform {}.scale(css_scale, css_scale).multiply(layout_box().layout_transform()));
 
     if (auto fill_color = geometry_element.fill_color().value_or(svg_context.fill_color()); fill_color.alpha() > 0) {
         // We need to fill the path before applying the stroke, however the filled
@@ -70,7 +72,7 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const
         painter.stroke_path(
             path,
             stroke_color,
-            geometry_element.stroke_width().value_or(svg_context.stroke_width()));
+            geometry_element.stroke_width().value_or(svg_context.stroke_width()) * context.device_pixels_per_css_pixel());
     }
 
     painter.translate(-offset);

+ 1 - 1
Userland/Libraries/LibWeb/Painting/SVGSVGPaintable.cpp

@@ -30,7 +30,7 @@ void SVGSVGPaintable::before_children_paint(PaintContext& context, PaintPhase ph
         return;
 
     if (!context.has_svg_context())
-        context.set_svg_context(SVGContext(absolute_rect().to_type<float>()));
+        context.set_svg_context(SVGContext(absolute_rect()));
 
     PaintableBox::before_children_paint(context, phase);
 }

+ 3 - 3
Userland/Libraries/LibWeb/SVG/SVGContext.h

@@ -14,7 +14,7 @@ namespace Web {
 
 class SVGContext {
 public:
-    SVGContext(Gfx::FloatRect svg_element_bounds)
+    SVGContext(CSSPixelRect svg_element_bounds)
         : m_svg_element_bounds(svg_element_bounds)
     {
         m_states.append(State());
@@ -28,7 +28,7 @@ public:
     void set_stroke_color(Gfx::Color color) { state().stroke_color = color; }
     void set_stroke_width(float width) { state().stroke_width = width; }
 
-    Gfx::FloatPoint svg_element_position() const { return m_svg_element_bounds.top_left(); }
+    CSSPixelPoint svg_element_position() const { return m_svg_element_bounds.top_left(); }
 
     void save() { m_states.append(m_states.last()); }
     void restore() { m_states.take_last(); }
@@ -43,7 +43,7 @@ private:
     State const& state() const { return m_states.last(); }
     State& state() { return m_states.last(); }
 
-    Gfx::FloatRect m_svg_element_bounds;
+    CSSPixelRect m_svg_element_bounds;
     Vector<State> m_states;
 };