From 809c15d1ee9132f7abf987824e863108f1f6dcc4 Mon Sep 17 00:00:00 2001 From: MacDue Date: Mon, 10 Apr 2023 12:35:33 +0100 Subject: [PATCH] LibWeb: Use (transformed) path bounding quad for SVG path hit testing This is needed for hit testing the directional arrows on the Street View office tour, and generally makes SVG hit testing more precise. Note: The rough bounding box is hit test first, so this should not be a load more overhead. --- .../LibWeb/Painting/SVGGeometryPaintable.cpp | 13 +++++++++++++ .../LibWeb/Painting/SVGGeometryPaintable.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp index 9060ac1e44..e0238659e9 100644 --- a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp +++ b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.cpp @@ -27,6 +27,19 @@ Layout::SVGGeometryBox const& SVGGeometryPaintable::layout_box() const return static_cast(layout_node()); } +Optional SVGGeometryPaintable::hit_test(CSSPixelPoint position, HitTestType type) const +{ + auto result = SVGGraphicsPaintable::hit_test(position, type); + if (!result.has_value()) + return {}; + auto& geometry_element = layout_box().dom_node(); + auto transformed_bounding_box = layout_box().layout_transform().map_to_quad( + const_cast(geometry_element).get_path().bounding_box()); + if (!transformed_bounding_box.contains(position.to_type())) + return {}; + return result; +} + void SVGGeometryPaintable::paint(PaintContext& context, PaintPhase phase) const { if (!is_visible()) diff --git a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.h b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.h index 85060eef69..6da035091d 100644 --- a/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.h +++ b/Userland/Libraries/LibWeb/Painting/SVGGeometryPaintable.h @@ -17,6 +17,8 @@ class SVGGeometryPaintable final : public SVGGraphicsPaintable { public: static JS::NonnullGCPtr create(Layout::SVGGeometryBox const&); + virtual Optional hit_test(CSSPixelPoint, HitTestType) const override; + virtual void paint(PaintContext&, PaintPhase) const override; Layout::SVGGeometryBox const& layout_box() const;