summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2023-04-15 15:32:17 +0100
committerAndreas Kling <kling@serenityos.org>2023-04-15 19:28:13 +0200
commitf9c61e3ba740adfd82bc2147db2f47eb659faff7 (patch)
tree684fbc20b4df112147d06a6d0c80e5656e13c562 /Userland
parentcb79c6bc2f73dcbec927e31736056ead8a67a7a2 (diff)
downloadserenity-f9c61e3ba740adfd82bc2147db2f47eb659faff7.zip
LibWeb: Scale SVG stroke-width based on viewbox
This fixes the clipping of strokes in quite a few cases and now fixes the Gartic Phone logo :^) (Layout test updated but no visible changes there)
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp2
-rw-r--r--Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp7
-rw-r--r--Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h7
4 files changed, 15 insertions, 3 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
index de3e4c493d..f215dcf801 100644
--- a/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp
@@ -87,7 +87,7 @@ void SVGFormattingContext::run(Box const& box, LayoutMode, [[maybe_unused]] Avai
// Stroke increases the path's size by stroke_width/2 per side.
auto path_bounding_box = transform.map(path.bounding_box()).to_type<CSSPixels>();
- CSSPixels stroke_width = geometry_box.dom_node().stroke_width().value_or(0);
+ CSSPixels stroke_width = geometry_box.dom_node().visible_stroke_width() * viewbox_scale;
path_bounding_box.inflate(stroke_width, stroke_width);
geometry_box_state.set_content_offset(path_bounding_box.top_left() + offset);
geometry_box_state.set_content_width(path_bounding_box.width());
diff --git a/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp
index 486378826f..4e346a97e6 100644
--- a/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/SVGGeometryBox.cpp
@@ -38,6 +38,8 @@ Optional<Gfx::AffineTransform> SVGGeometryBox::layout_transform() const
// we now have to derive what it was from the original bounding box size.
// FIXME: It would be nice if we could store the transform from layout somewhere, so we don't have to solve for it here.
auto original_bounding_box = Gfx::AffineTransform {}.translate(-origin).multiply(transform).map(const_cast<SVG::SVGGeometryElement&>(geometry_element).get_path().bounding_box());
+ float stroke_width = geometry_element.visible_stroke_width();
+ original_bounding_box.inflate(stroke_width, stroke_width);
// If the transform (or path) results in a empty box we can't display this.
if (original_bounding_box.is_empty())
return {};
diff --git a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp
index 07aa283de4..77b0c2ad29 100644
--- a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp
+++ b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp
@@ -71,7 +71,9 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const
auto transform = layout_box().layout_transform();
if (!transform.has_value())
return;
- Gfx::Path path = const_cast<SVG::SVGGeometryElement&>(geometry_element).get_path().copy_transformed(Gfx::AffineTransform {}.scale(css_scale, css_scale).multiply(*transform));
+
+ auto paint_transform = Gfx::AffineTransform {}.scale(css_scale, css_scale).multiply(*transform);
+ Gfx::Path path = const_cast<SVG::SVGGeometryElement&>(geometry_element).get_path().copy_transformed(paint_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
@@ -91,7 +93,8 @@ void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const
painter.stroke_path(
path,
stroke_color,
- geometry_element.stroke_width().value_or(svg_context.stroke_width()) * context.device_pixels_per_css_pixel());
+ // Note: This is assuming .x_scale() == .y_scale() (which it does currently).
+ geometry_element.stroke_width().value_or(svg_context.stroke_width()) * paint_transform.x_scale());
}
}
diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h
index be0fd7f9ae..97dc46d2ef 100644
--- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h
+++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.h
@@ -28,6 +28,13 @@ public:
Optional<Gfx::Color> stroke_color() const;
Optional<float> stroke_width() const;
+ float visible_stroke_width() const
+ {
+ if (auto color = stroke_color(); color.has_value() && color->alpha() > 0)
+ return stroke_width().value_or(0);
+ return 0;
+ }
+
Gfx::AffineTransform get_transform() const;
protected: