add relative segment methods

Bug: skia:9000
Change-Id: I1e7a4f3c799b7f6cd20e415880300a577a5a3c16
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/307346
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/include/core/SkPathBuilder.h b/include/core/SkPathBuilder.h
index adfd3ad..638f392 100644
--- a/include/core/SkPathBuilder.h
+++ b/include/core/SkPathBuilder.h
@@ -27,35 +27,53 @@
     SkPathBuilder& reset();
 
     SkPathBuilder& moveTo(SkPoint pt);
+    SkPathBuilder& moveTo(SkScalar x, SkScalar y) { return this->moveTo(SkPoint::Make(x, y)); }
+
     SkPathBuilder& lineTo(SkPoint pt);
+    SkPathBuilder& lineTo(SkScalar x, SkScalar y) { return this->lineTo(SkPoint::Make(x, y)); }
+
     SkPathBuilder& quadTo(SkPoint pt1, SkPoint pt2);
+    SkPathBuilder& quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
+        return this->quadTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2));
+    }
+    SkPathBuilder& quadTo(const SkPoint pts[2]) { return this->quadTo(pts[0], pts[1]); }
+
     SkPathBuilder& conicTo(SkPoint pt1, SkPoint pt2, SkScalar w);
+    SkPathBuilder& conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar w) {
+        return this->conicTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2), w);
+    }
+    SkPathBuilder& conicTo(const SkPoint pts[2], SkScalar w) {
+        return this->conicTo(pts[0], pts[1], w);
+    }
+
     SkPathBuilder& cubicTo(SkPoint pt1, SkPoint pt2, SkPoint pt3);
+    SkPathBuilder& cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3) {
+        return this->cubicTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2), SkPoint::Make(x3, y3));
+    }
+    SkPathBuilder& cubicTo(const SkPoint pts[3]) {
+        return this->cubicTo(pts[0], pts[1], pts[2]);
+    }
+
     SkPathBuilder& close();
 
+    // Relative versions of segments, relative to the previous position.
+
+    SkPathBuilder& rLineTo(SkPoint pt);
+    SkPathBuilder& rLineTo(SkScalar x, SkScalar y) { return this->rLineTo({x, y}); }
+    SkPathBuilder& rQuadTo(SkPoint pt1, SkPoint pt2);
+    SkPathBuilder& rQuadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
+        return this->rQuadTo({x1, y1}, {x2, y2});
+    }
     SkPathBuilder& rConicTo(SkPoint p1, SkPoint p2, SkScalar w);
     SkPathBuilder& rConicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar w) {
         return this->rConicTo({x1, y1}, {x2, y2}, w);
     }
+    SkPathBuilder& rCubicTo(SkPoint pt1, SkPoint pt2, SkPoint pt3);
+    SkPathBuilder& rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3) {
+        return this->rCubicTo({x1, y1}, {x2, y2}, {x3, y3});
+    }
 
-    SkPathBuilder&  moveTo(SkScalar x, SkScalar y) { return this->moveTo(SkPoint::Make(x, y)); }
-    SkPathBuilder&  lineTo(SkScalar x, SkScalar y) { return this->lineTo(SkPoint::Make(x, y)); }
-    SkPathBuilder&  quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2) {
-        return this->quadTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2));
-    }
-    SkPathBuilder&  quadTo(const SkPoint pts[2]) { return this->quadTo(pts[0], pts[1]); }
-    SkPathBuilder&  conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar w) {
-        return this->conicTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2), w);
-    }
-    SkPathBuilder&  conicTo(const SkPoint pts[2], SkScalar w) {
-        return this->conicTo(pts[0], pts[1], w);
-    }
-    SkPathBuilder&  cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3) {
-        return this->cubicTo(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2), SkPoint::Make(x3, y3));
-    }
-    SkPathBuilder&  cubicTo(const SkPoint pts[3]) {
-        return this->cubicTo(pts[0], pts[1], pts[2]);
-    }
+    // Add a closed contour
 
     SkPathBuilder& addRect(const SkRect&, SkPathDirection, unsigned startIndex);
     SkPathBuilder& addOval(const SkRect&, SkPathDirection, unsigned startIndex);
@@ -71,6 +89,8 @@
         return this->addRRect(rect, dir, 0);
     }
 
+    // Performance hint, to reserve extra storage for subsequent calls to lineTo, quadTo, etc.
+
     void incReserve(int extraPtCount, int extraVerbCount);
     void incReserve(int extraPtCount) {
         this->incReserve(extraPtCount, extraPtCount);
diff --git a/src/core/SkPathBuilder.cpp b/src/core/SkPathBuilder.cpp
index 22b97cf..0631f13 100644
--- a/src/core/SkPathBuilder.cpp
+++ b/src/core/SkPathBuilder.cpp
@@ -115,12 +115,30 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////
 
+SkPathBuilder& SkPathBuilder::rLineTo(SkPoint p1) {
+    this->ensureMove();
+    SkPoint base = fPts[fPts.count() - 1];
+    return this->lineTo(base + p1);
+}
+
+SkPathBuilder& SkPathBuilder::rQuadTo(SkPoint p1, SkPoint p2) {
+    this->ensureMove();
+    SkPoint base = fPts[fPts.count() - 1];
+    return this->quadTo(base + p1, base + p2);
+}
+
 SkPathBuilder& SkPathBuilder::rConicTo(SkPoint p1, SkPoint p2, SkScalar w) {
     this->ensureMove();
     SkPoint base = fPts[fPts.count() - 1];
     return this->conicTo(base + p1, base + p2, w);
 }
 
+SkPathBuilder& SkPathBuilder::rCubicTo(SkPoint p1, SkPoint p2, SkPoint p3) {
+    this->ensureMove();
+    SkPoint base = fPts[fPts.count() - 1];
+    return this->cubicTo(base + p1, base + p2, base + p3);
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////
 
 SkPath SkPathBuilder::snapshot() {