From 18bc5972f4285accc1ad56a7c3d5e3d451a93ac7 Mon Sep 17 00:00:00 2001 From: mierenhoop <46939409+mierenhoop@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:51:26 +0200 Subject: [PATCH] LibGfx: Add Path::contains() With this new method, it is possible to check whether a 2D point is inside of the path. --- Userland/Libraries/LibGfx/Path.h | 2 ++ Userland/Libraries/LibGfx/PathSkia.cpp | 18 ++++++++++++++++++ Userland/Libraries/LibGfx/PathSkia.h | 1 + 3 files changed, 21 insertions(+) diff --git a/Userland/Libraries/LibGfx/Path.h b/Userland/Libraries/LibGfx/Path.h index f13ce69b87f..c9fe6ee027b 100644 --- a/Userland/Libraries/LibGfx/Path.h +++ b/Userland/Libraries/LibGfx/Path.h @@ -39,6 +39,7 @@ public: [[nodiscard]] virtual bool is_empty() const = 0; virtual Gfx::FloatPoint last_point() const = 0; virtual Gfx::FloatRect bounding_box() const = 0; + virtual bool contains(FloatPoint point, Gfx::WindingRule) const = 0; virtual NonnullOwnPtr clone() const = 0; virtual NonnullOwnPtr copy_transformed(Gfx::AffineTransform const&) const = 0; @@ -84,6 +85,7 @@ public: [[nodiscard]] bool is_empty() const { return impl().is_empty(); } Gfx::FloatPoint last_point() const { return impl().last_point(); } Gfx::FloatRect bounding_box() const { return impl().bounding_box(); } + bool contains(FloatPoint point, Gfx::WindingRule winding_rule) const { return impl().contains(point, winding_rule); } Gfx::Path clone() const { return Gfx::Path { impl().clone() }; } Gfx::Path copy_transformed(Gfx::AffineTransform const& transform) const { return Gfx::Path { impl().copy_transformed(transform) }; } diff --git a/Userland/Libraries/LibGfx/PathSkia.cpp b/Userland/Libraries/LibGfx/PathSkia.cpp index 0d53aef8413..94db9cdce1b 100644 --- a/Userland/Libraries/LibGfx/PathSkia.cpp +++ b/Userland/Libraries/LibGfx/PathSkia.cpp @@ -199,6 +199,24 @@ Gfx::FloatRect PathImplSkia::bounding_box() const return { bounds.fLeft, bounds.fTop, bounds.fRight - bounds.fLeft, bounds.fBottom - bounds.fTop }; } +static SkPathFillType to_skia_path_fill_type(Gfx::WindingRule winding_rule) +{ + switch (winding_rule) { + case Gfx::WindingRule::Nonzero: + return SkPathFillType::kWinding; + case Gfx::WindingRule::EvenOdd: + return SkPathFillType::kEvenOdd; + } + VERIFY_NOT_REACHED(); +} + +bool PathImplSkia::contains(FloatPoint point, Gfx::WindingRule winding_rule) const +{ + SkPath temp_path = *m_path; + temp_path.setFillType(to_skia_path_fill_type(winding_rule)); + return temp_path.contains(point.x(), point.y()); +} + NonnullOwnPtr PathImplSkia::clone() const { auto new_path = PathImplSkia::create(); diff --git a/Userland/Libraries/LibGfx/PathSkia.h b/Userland/Libraries/LibGfx/PathSkia.h index a8be8cb5854..6039281eab2 100644 --- a/Userland/Libraries/LibGfx/PathSkia.h +++ b/Userland/Libraries/LibGfx/PathSkia.h @@ -35,6 +35,7 @@ public: [[nodiscard]] virtual bool is_empty() const override; virtual Gfx::FloatPoint last_point() const override; virtual Gfx::FloatRect bounding_box() const override; + virtual bool contains(FloatPoint point, Gfx::WindingRule) const override; virtual NonnullOwnPtr clone() const override; virtual NonnullOwnPtr copy_transformed(Gfx::AffineTransform const&) const override;