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/.
This commit is contained in:
MacDue 2024-04-20 23:10:26 +01:00 committed by Andreas Kling
commit 9d8ab826cb
Notes: sideshowbarker 2024-07-17 03:00:02 +09:00

View file

@ -11,6 +11,8 @@
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/DOM/Document.h>
#include <LibWeb/Layout/Node.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/SVGGraphicsPaintable.h>
#include <LibWeb/SVG/AttributeNames.h>
#include <LibWeb/SVG/AttributeParser.h>
#include <LibWeb/SVG/SVGClipPathElement.h>
@ -246,8 +248,19 @@ Optional<float> SVGGraphicsElement::stroke_width() const
JS::NonnullGCPtr<Geometry::DOMRect> SVGGraphicsElement::get_b_box(Optional<SVGBoundingBoxOptions>)
{
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<DOM::Document&>(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<SVG::SVGSVGElement>()->paintable_box()->absolute_rect();
auto inverse_transform = static_cast<Painting::SVGGraphicsPaintable&>(*paintable_box()).computed_transforms().svg_to_css_pixels_transform().inverse();
return Geometry::DOMRect::create(realm(),
inverse_transform->map(
paintable_box()->absolute_rect().to_type<float>().translated(-svg_element_rect.location().to_type<float>())));
}
JS::NonnullGCPtr<SVGAnimatedTransformList> SVGGraphicsElement::transform() const