From 9d8ab826cb015cead7acdfbf84abc526447525bd Mon Sep 17 00:00:00 2001 From: MacDue Date: Sat, 20 Apr 2024 23:10:26 +0100 Subject: [PATCH] LibWeb: Add an initial implementation of the SVG `.getBBox()` method This just reuses the layout to compute the bounding box rather than implementing the full bounding box algorithm, which is likely the slower option, but also much simpler to implement. This is enough to fix the faces on https://zengm.com/facesjs/. --- .../Libraries/LibWeb/SVG/SVGGraphicsElement.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp index 018b6a6dc1a..74dc7d9b32d 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -246,8 +248,19 @@ Optional SVGGraphicsElement::stroke_width() const JS::NonnullGCPtr SVGGraphicsElement::get_b_box(Optional) { - dbgln("(STUBBED) SVGGraphicsElement::get_b_box(). Called on: {}", debug_description()); - return Geometry::DOMRect::create(realm()); + // FIXME: It should be possible to compute this without layout updates. The bounding box is within the + // SVG coordinate space (before any viewbox or other transformations), so it should be possible to + // calculate this from SVG geometry without a full layout tree (at least for simple cases). + // See: https://svgwg.org/svg2-draft/coords.html#BoundingBoxes + const_cast(document()).update_layout(); + if (!layout_node()) + return Geometry::DOMRect::create(realm()); + // Invert the SVG -> screen space transform. + auto svg_element_rect = shadow_including_first_ancestor_of_type()->paintable_box()->absolute_rect(); + auto inverse_transform = static_cast(*paintable_box()).computed_transforms().svg_to_css_pixels_transform().inverse(); + return Geometry::DOMRect::create(realm(), + inverse_transform->map( + paintable_box()->absolute_rect().to_type().translated(-svg_element_rect.location().to_type()))); } JS::NonnullGCPtr SVGGraphicsElement::transform() const