[sksg] Hit-testing API
Introduce RenderNode::nodeAt(const SkPoint&) as the entry point for the hit-testing API.
This is backed by a onNodeAt() virtual, which gets dispatched throughout the render DAG,
and normally stops at the first leaf Draw node in encounters.
To support the implementation, introduce a GeometryNode::contains(const SkPoint&) API.
This is backed by a onContains() virtual, overridden in each concrete geometry class.
Expose nodeAt() on sksg::Scene, and add some basic unit tests.
Change-Id: I0c8abd9d1e51ecf2d8b4dd699f325cd636e21084
Reviewed-on: https://skia-review.googlesource.com/c/191296
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/modules/sksg/src/SkSGDraw.cpp b/modules/sksg/src/SkSGDraw.cpp
index 24b358e..10def5b 100644
--- a/modules/sksg/src/SkSGDraw.cpp
+++ b/modules/sksg/src/SkSGDraw.cpp
@@ -7,6 +7,7 @@
#include "SkSGDraw.h"
+#include "SkPath.h"
#include "SkSGGeometryNode.h"
#include "SkSGInvalidationController.h"
#include "SkSGPaintNode.h"
@@ -40,6 +41,25 @@
}
}
+const RenderNode* Draw::onNodeAt(const SkPoint& p) const {
+ const auto paint = fPaint->makePaint();
+
+ if (!paint.getAlpha()) {
+ return nullptr;
+ }
+
+ if (paint.getStyle() == SkPaint::Style::kFill_Style && fGeometry->contains(p)) {
+ return this;
+ }
+
+ SkPath stroke_path;
+ if (!paint.getFillPath(fGeometry->asPath(), &stroke_path)) {
+ return nullptr;
+ }
+
+ return stroke_path.contains(p.x(), p.y()) ? this : nullptr;
+}
+
SkRect Draw::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
SkASSERT(this->hasInval());