[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());