add guard to switch to SkPathTypes

Change-Id: I44d8b5ae8a5172d11a6d4cd9d994373dd3816d6f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/241278
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/bench/AAClipBench.cpp b/bench/AAClipBench.cpp
index abd7ec5..5570ad0 100644
--- a/bench/AAClipBench.cpp
+++ b/bench/AAClipBench.cpp
@@ -34,7 +34,7 @@
                      doAA ? "AA" : "BW");
 
         fClipRect.setLTRB(10.5f, 10.5f, 50.5f, 50.5f);
-        fClipPath.addRoundRect(fClipRect, SkIntToScalar(10), SkIntToScalar(10));
+        fClipPath.addRRect(SkRRect::MakeRectXY(fClipRect, SkIntToScalar(10), SkIntToScalar(10)));
         fDrawRect.setWH(100, 100);
 
         SkASSERT(fClipPath.isConvex());
@@ -51,8 +51,7 @@
             // jostle the clip regions each time to prevent caching
             fClipRect.offset((i % 2) == 0 ? SkIntToScalar(10) : SkIntToScalar(-10), 0);
             fClipPath.reset();
-            fClipPath.addRoundRect(fClipRect,
-                                   SkIntToScalar(5), SkIntToScalar(5));
+            fClipPath.addRRect(SkRRect::MakeRectXY(fClipRect, 5, 5));
             SkASSERT(fClipPath.isConvex());
 
             canvas->save();
diff --git a/bench/BlurRectsBench.cpp b/bench/BlurRectsBench.cpp
index ed2b254..df1775c 100644
--- a/bench/BlurRectsBench.cpp
+++ b/bench/BlurRectsBench.cpp
@@ -34,8 +34,8 @@
         paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, fRadius));
 
         SkPath path;
-        path.addRect(fOuter, SkPath::kCW_Direction);
-        path.addRect(fInner, SkPath::kCW_Direction);
+        path.addRect(fOuter, SkPathDirection::kCW);
+        path.addRect(fInner, SkPathDirection::kCW);
 
         for (int i = 0; i < loops; i++) {
             canvas->drawPath(path, paint);
diff --git a/bench/GeometryBench.cpp b/bench/GeometryBench.cpp
index 457151d..634ff09 100644
--- a/bench/GeometryBench.cpp
+++ b/bench/GeometryBench.cpp
@@ -271,7 +271,7 @@
 
     void onDraw(int loops, SkCanvas* canvas) override {
         for (int i = 0; i < loops; ++i) {
-            fPath.setConvexity(SkPath::kUnknown_Convexity);
+            fPath.setConvexity(SkPathConvexityType::kUnknown);
             (void)fPath.isConvex();
         }
     }
diff --git a/bench/PathBench.cpp b/bench/PathBench.cpp
index eb4d4a3..58dfb14 100644
--- a/bench/PathBench.cpp
+++ b/bench/PathBench.cpp
@@ -691,7 +691,7 @@
 
             // mimic how Chrome does circles
             temp.arcTo(r, 0, 0, false);
-            temp.addOval(r, SkPath::kCCW_Direction);
+            temp.addOval(r, SkPathDirection::kCCW);
             temp.arcTo(r, 360, 0, true);
             temp.close();
 
@@ -825,7 +825,7 @@
                 break;
             case kRoundRect_Type:
                 fName.append("round_rect");
-                fPath.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1]);
+                fPath.addRRect(SkRRect::MakeRectXY(kBaseRect, kRRRadii[0], kRRRadii[1]));
                 break;
             case kOval_Type:
                 fName.append("oval");
diff --git a/example/SkiaSDLExample.cpp b/example/SkiaSDLExample.cpp
index 7aebbbc..6dcee90 100644
--- a/example/SkiaSDLExample.cpp
+++ b/example/SkiaSDLExample.cpp
@@ -97,7 +97,7 @@
     for (int i = 0; i < kNumPoints; ++i) {
         concavePath.lineTo(points[(2 * i) % kNumPoints]);
     }
-    concavePath.setFillType(SkPath::kEvenOdd_FillType);
+    concavePath.setFillType(SkPathFillType::kEvenOdd);
     SkASSERT(!concavePath.isConvex());
     concavePath.close();
     return concavePath;
diff --git a/experimental/svg/model/SkSVGCircle.cpp b/experimental/svg/model/SkSVGCircle.cpp
index 66e7d28..47da074 100644
--- a/experimental/svg/model/SkSVGCircle.cpp
+++ b/experimental/svg/model/SkSVGCircle.cpp
@@ -54,7 +54,7 @@
     return std::make_tuple(SkPoint::Make(cx, cy), r);
 }
 void SkSVGCircle::onDraw(SkCanvas* canvas, const SkSVGLengthContext& lctx,
-                         const SkPaint& paint, SkPath::FillType) const {
+                         const SkPaint& paint, SkPathFillType) const {
     SkPoint pos;
     SkScalar r;
     std::tie(pos, r) = this->resolve(lctx);
diff --git a/experimental/svg/model/SkSVGCircle.h b/experimental/svg/model/SkSVGCircle.h
index c53cf4a..fc774a1 100644
--- a/experimental/svg/model/SkSVGCircle.h
+++ b/experimental/svg/model/SkSVGCircle.h
@@ -26,7 +26,7 @@
     void onSetAttribute(SkSVGAttribute, const SkSVGValue&) override;
 
     void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&,
-                SkPath::FillType) const override;
+                SkPathFillType) const override;
 
     SkPath onAsPath(const SkSVGRenderContext&) const override;
 
diff --git a/experimental/svg/model/SkSVGEllipse.cpp b/experimental/svg/model/SkSVGEllipse.cpp
index b7d4fad..60d3048 100644
--- a/experimental/svg/model/SkSVGEllipse.cpp
+++ b/experimental/svg/model/SkSVGEllipse.cpp
@@ -67,7 +67,7 @@
 }
 
 void SkSVGEllipse::onDraw(SkCanvas* canvas, const SkSVGLengthContext& lctx,
-                          const SkPaint& paint, SkPath::FillType) const {
+                          const SkPaint& paint, SkPathFillType) const {
     canvas->drawOval(this->resolve(lctx), paint);
 }
 
diff --git a/experimental/svg/model/SkSVGEllipse.h b/experimental/svg/model/SkSVGEllipse.h
index c6bd2b3..ec0a753 100644
--- a/experimental/svg/model/SkSVGEllipse.h
+++ b/experimental/svg/model/SkSVGEllipse.h
@@ -27,7 +27,7 @@
     void onSetAttribute(SkSVGAttribute, const SkSVGValue&) override;
 
     void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&,
-                SkPath::FillType) const override;
+                SkPathFillType) const override;
 
     SkPath onAsPath(const SkSVGRenderContext&) const override;
 
diff --git a/experimental/svg/model/SkSVGLine.cpp b/experimental/svg/model/SkSVGLine.cpp
index 3d0efa1..05fc1f9 100644
--- a/experimental/svg/model/SkSVGLine.cpp
+++ b/experimental/svg/model/SkSVGLine.cpp
@@ -64,7 +64,7 @@
 }
 
 void SkSVGLine::onDraw(SkCanvas* canvas, const SkSVGLengthContext& lctx,
-                       const SkPaint& paint, SkPath::FillType) const {
+                       const SkPaint& paint, SkPathFillType) const {
     SkPoint p0, p1;
     std::tie(p0, p1) = this->resolve(lctx);
 
diff --git a/experimental/svg/model/SkSVGLine.h b/experimental/svg/model/SkSVGLine.h
index 08e0fe6..c4de847 100644
--- a/experimental/svg/model/SkSVGLine.h
+++ b/experimental/svg/model/SkSVGLine.h
@@ -27,7 +27,7 @@
     void onSetAttribute(SkSVGAttribute, const SkSVGValue&) override;
 
     void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&,
-                SkPath::FillType) const override;
+                SkPathFillType) const override;
 
     SkPath onAsPath(const SkSVGRenderContext&) const override;
 
diff --git a/experimental/svg/model/SkSVGPath.cpp b/experimental/svg/model/SkSVGPath.cpp
index f3f4524..07fc348 100644
--- a/experimental/svg/model/SkSVGPath.cpp
+++ b/experimental/svg/model/SkSVGPath.cpp
@@ -26,7 +26,7 @@
 }
 
 void SkSVGPath::onDraw(SkCanvas* canvas, const SkSVGLengthContext&, const SkPaint& paint,
-                       SkPath::FillType fillType) const {
+                       SkPathFillType fillType) const {
     // the passed fillType follows inheritance rules and needs to be applied at draw time.
     fPath.setFillType(fillType);
     canvas->drawPath(fPath, paint);
diff --git a/experimental/svg/model/SkSVGPath.h b/experimental/svg/model/SkSVGPath.h
index 5b41637..1b7b17d 100644
--- a/experimental/svg/model/SkSVGPath.h
+++ b/experimental/svg/model/SkSVGPath.h
@@ -22,7 +22,7 @@
     void onSetAttribute(SkSVGAttribute, const SkSVGValue&) override;
 
     void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&,
-                SkPath::FillType) const override;
+                SkPathFillType) const override;
 
     SkPath onAsPath(const SkSVGRenderContext&) const override;
 
diff --git a/experimental/svg/model/SkSVGPoly.cpp b/experimental/svg/model/SkSVGPoly.cpp
index 6bacb1a..29af890 100644
--- a/experimental/svg/model/SkSVGPoly.cpp
+++ b/experimental/svg/model/SkSVGPoly.cpp
@@ -33,7 +33,7 @@
 }
 
 void SkSVGPoly::onDraw(SkCanvas* canvas, const SkSVGLengthContext&, const SkPaint& paint,
-                       SkPath::FillType fillType) const {
+                       SkPathFillType fillType) const {
     // the passed fillType follows inheritance rules and needs to be applied at draw time.
     fPath.setFillType(fillType);
     canvas->drawPath(fPath, paint);
diff --git a/experimental/svg/model/SkSVGPoly.h b/experimental/svg/model/SkSVGPoly.h
index f47b764..ef9c3a5 100644
--- a/experimental/svg/model/SkSVGPoly.h
+++ b/experimental/svg/model/SkSVGPoly.h
@@ -30,7 +30,7 @@
     void onSetAttribute(SkSVGAttribute, const SkSVGValue&) override;
 
     void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&,
-                SkPath::FillType) const override;
+                SkPathFillType) const override;
 
     SkPath onAsPath(const SkSVGRenderContext&) const override;
 
diff --git a/experimental/svg/model/SkSVGRect.cpp b/experimental/svg/model/SkSVGRect.cpp
index 24267d0..5c518bd 100644
--- a/experimental/svg/model/SkSVGRect.cpp
+++ b/experimental/svg/model/SkSVGRect.cpp
@@ -83,7 +83,7 @@
 }
 
 void SkSVGRect::onDraw(SkCanvas* canvas, const SkSVGLengthContext& lctx,
-                       const SkPaint& paint, SkPath::FillType) const {
+                       const SkPaint& paint, SkPathFillType) const {
     canvas->drawRRect(this->resolve(lctx), paint);
 }
 
diff --git a/experimental/svg/model/SkSVGRect.h b/experimental/svg/model/SkSVGRect.h
index 7d749b0..fca15e0 100644
--- a/experimental/svg/model/SkSVGRect.h
+++ b/experimental/svg/model/SkSVGRect.h
@@ -29,7 +29,7 @@
     void onSetAttribute(SkSVGAttribute, const SkSVGValue&) override;
 
     void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&,
-                SkPath::FillType) const override;
+                SkPathFillType) const override;
 
     SkPath onAsPath(const SkSVGRenderContext&) const override;
 
diff --git a/experimental/svg/model/SkSVGShape.h b/experimental/svg/model/SkSVGShape.h
index bfbad0e..ff57d5b 100644
--- a/experimental/svg/model/SkSVGShape.h
+++ b/experimental/svg/model/SkSVGShape.h
@@ -26,7 +26,7 @@
     void onRender(const SkSVGRenderContext&) const final;
 
     virtual void onDraw(SkCanvas*, const SkSVGLengthContext&, const SkPaint&,
-                        SkPath::FillType) const = 0;
+                        SkPathFillType) const = 0;
 
 private:
     typedef SkSVGTransformableNode INHERITED;
diff --git a/experimental/svg/model/SkSVGTypes.h b/experimental/svg/model/SkSVGTypes.h
index 9ac7654..00a09bf 100644
--- a/experimental/svg/model/SkSVGTypes.h
+++ b/experimental/svg/model/SkSVGTypes.h
@@ -239,9 +239,9 @@
 
     Type type() const { return fType; }
 
-    SkPath::FillType asFillType() const {
+    SkPathFillType asFillType() const {
         SkASSERT(fType != Type::kInherit); // should never be called for unresolved values.
-        return fType == Type::kEvenOdd ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
+        return fType == Type::kEvenOdd ? SkPathFillType::kEvenOdd : SkPathFillType::kWinding;
     }
 
 private:
diff --git a/fuzz/FuzzCommon.cpp b/fuzz/FuzzCommon.cpp
index 3a2108e..1b953da 100644
--- a/fuzz/FuzzCommon.cpp
+++ b/fuzz/FuzzCommon.cpp
@@ -33,8 +33,8 @@
         return;
     }
     uint8_t fillType;
-    fuzz->nextRange(&fillType, 0, (uint8_t)SkPath::kInverseEvenOdd_FillType);
-    path->setFillType((SkPath::FillType)fillType);
+    fuzz->nextRange(&fillType, 0, (uint8_t)SkPathFillType::kInverseEvenOdd);
+    path->setFillType((SkPathFillType)fillType);
     uint8_t numOps;
     fuzz->nextRange(&numOps, 0, maxOps);
     for (uint8_t i = 0; i < numOps; ++i) {
@@ -52,7 +52,7 @@
         SkMatrix m;
         SkRRect rr;
         SkRect r;
-        SkPath::Direction dir;
+        SkPathDirection dir;
         unsigned int ui;
         SkScalar a, b, c, d, e, f;
         switch (op) {
@@ -112,32 +112,32 @@
             case 13:
                 fuzz_nice_rect(fuzz, &r);
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
+                dir = static_cast<SkPathDirection>(ui);
                 path->addRect(r, dir);
                 break;
             case 14:
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
+                dir = static_cast<SkPathDirection>(ui);
                 fuzz_nice_rect(fuzz, &r);
                 fuzz->next(&ui);
                 path->addRect(r, dir, ui);
                 break;
             case 15:
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
+                dir = static_cast<SkPathDirection>(ui);
                 fuzz_nice_rect(fuzz, &r);
                 path->addOval(r, dir);
                 break;
             case 16:
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
+                dir = static_cast<SkPathDirection>(ui);
                 fuzz_nice_rect(fuzz, &r);
                 fuzz->next(&ui);
                 path->addOval(r, dir, ui);
                 break;
             case 17:
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
+                dir = static_cast<SkPathDirection>(ui);
                 fuzz_nice_float(fuzz, &a, &b, &c);
                 path->addCircle(a, b, c, dir);
                 break;
@@ -150,18 +150,18 @@
                 fuzz_nice_float(fuzz, &a, &b);
                 fuzz_nice_rect(fuzz, &r);
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
-                path->addRoundRect(r, a, b, dir);
+                dir = static_cast<SkPathDirection>(ui);
+                path->addRRect(SkRRect::MakeRectXY(r, a, b), dir);
                 break;
             case 20:
                 FuzzNiceRRect(fuzz, &rr);
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
+                dir = static_cast<SkPathDirection>(ui);
                 path->addRRect(rr, dir);
                 break;
             case 21:
                 fuzz->nextRange(&ui, 0, 1);
-                dir = static_cast<SkPath::Direction>(ui);
+                dir = static_cast<SkPathDirection>(ui);
                 FuzzNiceRRect(fuzz, &rr);
                 path->addRRect(rr, dir, ui);
                 break;
diff --git a/fuzz/FuzzPathop.cpp b/fuzz/FuzzPathop.cpp
index 63862a9..79a3616 100644
--- a/fuzz/FuzzPathop.cpp
+++ b/fuzz/FuzzPathop.cpp
@@ -25,8 +25,8 @@
             for (uint8_t i = 0; i < ops && !fuzz->exhausted(); i++) {
                 SkPath path;
                 FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
-                SkPath::FillType ft;
-                fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
+                SkPathFillType ft;
+                fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
                 path.setFillType(ft);
 
                 SkPathOp op;
@@ -41,8 +41,8 @@
         case 1: {
             SkPath path;
             FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
-            SkPath::FillType ft;
-            fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
+            SkPathFillType ft;
+            fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
             path.setFillType(ft);
 
             SkPath result;
@@ -57,13 +57,13 @@
         case 2: {
             SkPath path;
             FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
-            SkPath::FillType ft;
-            fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
+            SkPathFillType ft;
+            fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
             path.setFillType(ft);
 
             SkPath path2;
             FuzzEvilPath(fuzz, &path2, SkPath::Verb::kDone_Verb);
-            fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
+            fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
             path.setFillType(ft);
 
             SkPathOp op;
@@ -83,8 +83,8 @@
         case 3: {
             SkPath path;
             FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
-            SkPath::FillType ft;
-            fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
+            SkPathFillType ft;
+            fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
             path.setFillType(ft);
 
             SkPath result;
@@ -99,8 +99,8 @@
         case 4: {
             SkPath path;
             FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
-            SkPath::FillType ft;
-            fuzz->nextRange(&ft, 0, SkPath::kInverseEvenOdd_FillType);
+            SkPathFillType ft;
+            fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
             path.setFillType(ft);
 
             SkRect result;
diff --git a/gm/arcto.cpp b/gm/arcto.cpp
index f28d86c..ba0207c 100644
--- a/gm/arcto.cpp
+++ b/gm/arcto.cpp
@@ -79,13 +79,13 @@
             SkScalar ovalHeight = oval.height() / oHeight;
             svgArc.moveTo(oval.fLeft, oval.fTop);
             svgArc.arcTo(oval.width() / 2, ovalHeight, SkIntToScalar(angle), SkPath::kSmall_ArcSize,
-                    SkPath::kCW_Direction, oval.right(), oval.bottom());
+                    SkPathDirection::kCW, oval.right(), oval.bottom());
             canvas->drawPath(svgArc, paint);
             svgArc.reset();
 
             svgArc.moveTo(oval.fLeft + 100, oval.fTop + 100);
             svgArc.arcTo(oval.width() / 2, ovalHeight, SkIntToScalar(angle), SkPath::kLarge_ArcSize,
-                    SkPath::kCCW_Direction, oval.right(), oval.bottom() + 100);
+                    SkPathDirection::kCCW, oval.right(), oval.bottom() + 100);
             canvas->drawPath(svgArc, paint);
             oval.offset(50, 0);
             svgArc.reset();
diff --git a/gm/circularclips.cpp b/gm/circularclips.cpp
index 025b693..b213838 100644
--- a/gm/circularclips.cpp
+++ b/gm/circularclips.cpp
@@ -28,8 +28,8 @@
         fY = 50;
         fR = 40;
 
-        fCircle1.addCircle(fX1, fY, fR, SkPath::kCW_Direction);
-        fCircle2.addCircle(fX2, fY, fR, SkPath::kCW_Direction);
+        fCircle1.addCircle(fX1, fY, fR, SkPathDirection::kCW);
+        fCircle2.addCircle(fX2, fY, fR, SkPathDirection::kCW);
     }
 
 
diff --git a/gm/collapsepaths.cpp b/gm/collapsepaths.cpp
index 7335171..82233c9 100644
--- a/gm/collapsepaths.cpp
+++ b/gm/collapsepaths.cpp
@@ -21,7 +21,7 @@
     path.moveTo(  370.50653076171875,   73.684051513671875);
     path.lineTo(  525.02093505859375, 208.6413726806640625);
     path.lineTo(    478.403564453125, 213.5998992919921875);
-    path.setFillType(SkPath::FillType::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
     canvas->drawPath(path, paint);
 }
 
@@ -70,7 +70,7 @@
     path.moveTo(154.6182708740234375,  188.230926513671875);
     path.lineTo( 430.242095947265625,   546.76605224609375);
     path.lineTo(      373.1005859375,    559.0906982421875);
-    path.setFillType(SkPath::FillType::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
     canvas->drawPath(path, paint);
 }
 
@@ -83,7 +83,7 @@
     path.moveTo(39.09362030029296875, 47.59223175048828125);
     path.lineTo(108.7822418212890625,  138.244110107421875);
     path.lineTo(94.33460235595703125,  141.360260009765625);
-    path.setFillType(SkPath::FillType::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
     canvas->drawPath(path, paint);
 }
 
@@ -96,7 +96,7 @@
     path.moveTo(40.33458709716796875, 49.10297393798828125);
     path.lineTo(112.2353668212890625,    142.6324462890625);
     path.lineTo(97.32910919189453125, 145.8475189208984375);
-    path.setFillType(SkPath::FillType::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
     canvas->drawPath(path, paint);
 }
 
@@ -109,7 +109,7 @@
     path.moveTo( 34.50,  42.00);
     path.lineTo( 96.00, 122.00);
     path.lineTo( 83.25, 124.75);
-    path.setFillType(SkPath::FillType::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
     canvas->drawPath(path, paint);
 }
 
@@ -125,7 +125,7 @@
     path.lineTo(SkDoubleToScalar(100.167),  SkDoubleToScalar(140.096));
     path.lineTo(SkDoubleToScalar( 99.0364), SkDoubleToScalar(140.364));
     path.lineTo(SkDoubleToScalar( 94.25),   SkDoubleToScalar(141.50));
-    path.setFillType(SkPath::FillType::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
     canvas->drawPath(path, paint);
 }
 
diff --git a/gm/complexclip2.cpp b/gm/complexclip2.cpp
index 46e2aad..340d62b 100644
--- a/gm/complexclip2.cpp
+++ b/gm/complexclip2.cpp
@@ -67,27 +67,27 @@
 
         fRects[0].setLTRB(xB, yB, xE, yE);
         fRRects[0].setRectXY(fRects[0], 7, 7);
-        fPaths[0].addRoundRect(fRects[0], 5, 5);
+        fPaths[0].addRRect(SkRRect::MakeRectXY(fRects[0], 5, 5));
         fRectColors[0] = SK_ColorRED;
 
         fRects[1].setLTRB(xA, yA, xD, yD);
         fRRects[1].setRectXY(fRects[1], 7, 7);
-        fPaths[1].addRoundRect(fRects[1], 5, 5);
+        fPaths[1].addRRect(SkRRect::MakeRectXY(fRects[1], 5, 5));
         fRectColors[1] = SK_ColorGREEN;
 
         fRects[2].setLTRB(xC, yA, xF, yD);
         fRRects[2].setRectXY(fRects[2], 7, 7);
-        fPaths[2].addRoundRect(fRects[2], 5, 5);
+        fPaths[2].addRRect(SkRRect::MakeRectXY(fRects[2], 5, 5));
         fRectColors[2] = SK_ColorBLUE;
 
         fRects[3].setLTRB(xA, yC, xD, yF);
         fRRects[3].setRectXY(fRects[3], 7, 7);
-        fPaths[3].addRoundRect(fRects[3], 5, 5);
+        fPaths[3].addRRect(SkRRect::MakeRectXY(fRects[3], 5, 5));
         fRectColors[3] = SK_ColorYELLOW;
 
         fRects[4].setLTRB(xC, yC, xF, yF);
         fRRects[4].setRectXY(fRects[4], 7, 7);
-        fPaths[4].addRoundRect(fRects[4], 5, 5);
+        fPaths[4].addRRect(SkRRect::MakeRectXY(fRects[4], 5, 5));
         fRectColors[4] = SK_ColorCYAN;
 
         const SkClipOp ops[] = {
diff --git a/gm/convex_all_line_paths.cpp b/gm/convex_all_line_paths.cpp
index 2fa2adf..1936dfc 100644
--- a/gm/convex_all_line_paths.cpp
+++ b/gm/convex_all_line_paths.cpp
@@ -183,7 +183,7 @@
     SkISize onISize() override { return SkISize::Make(kGMWidth, kGMHeight); }
     bool runAsBench() const override { return true; }
 
-    static SkPath GetPath(int index, SkPath::Direction dir) {
+    static SkPath GetPath(int index, SkPathDirection dir) {
         std::unique_ptr<SkPoint[]> data(nullptr);
         const SkPoint* points;
         int numPts;
@@ -238,7 +238,7 @@
 
         SkPath path;
 
-        if (SkPath::kCW_Direction == dir) {
+        if (SkPathDirection::kCW == dir) {
             path.moveTo(points[0]);
             for (int i = 1; i < numPts; ++i) {
                 path.lineTo(points[i]);
@@ -273,7 +273,7 @@
 
         SkPoint center;
         {
-            SkPath path = GetPath(index, SkPath::kCW_Direction);
+            SkPath path = GetPath(index, SkPathDirection::kCW);
             if (offset->fX+path.getBounds().width() > kGMWidth) {
                 offset->fX = 0;
                 offset->fY += kMaxPathHeight;
@@ -290,7 +290,7 @@
         }
 
         const SkColor colors[2] = { SK_ColorBLACK, SK_ColorWHITE };
-        const SkPath::Direction dirs[2] = { SkPath::kCW_Direction, SkPath::kCCW_Direction };
+        const SkPathDirection dirs[2] = { SkPathDirection::kCW, SkPathDirection::kCCW };
         const float scales[] = { 1.0f, 0.75f, 0.5f, 0.25f, 0.1f, 0.01f, 0.001f };
         const SkPaint::Join joins[3] = { SkPaint::kRound_Join,
                                          SkPaint::kBevel_Join,
diff --git a/gm/crbug_908646.cpp b/gm/crbug_908646.cpp
index 843799e..3d11276 100644
--- a/gm/crbug_908646.cpp
+++ b/gm/crbug_908646.cpp
@@ -14,7 +14,7 @@
     SkPaint paint;
     paint.setAntiAlias(true);
     SkPath path;
-    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
     path.moveTo(50,  50);
     path.lineTo(50,  300);
     path.lineTo(250, 300);
diff --git a/gm/distantclip.cpp b/gm/distantclip.cpp
index b0da264..a213a2a 100644
--- a/gm/distantclip.cpp
+++ b/gm/distantclip.cpp
@@ -38,7 +38,7 @@
         rec->save();
         SkRect r = SkRect::MakeXYWH(-kExtents, kOffset - kExtents, 2 * kExtents, 2 * kExtents);
         SkPath p;
-        p.addRoundRect(r, 5, 5);
+        p.addRRect(SkRRect::MakeRectXY(r, 5, 5));
         rec->clipPath(p, true);
         rec->drawColor(SK_ColorGREEN);
         rec->restore();
diff --git a/gm/inversepaths.cpp b/gm/inversepaths.cpp
index 0726983..7ddf088 100644
--- a/gm/inversepaths.cpp
+++ b/gm/inversepaths.cpp
@@ -34,7 +34,7 @@
 
 static SkPath generate_circle(SkScalar cx, SkScalar cy, SkScalar d) {
     SkPath path;
-    path.addCircle(cx, cy, d/2, SkPath::kCW_Direction);
+    path.addCircle(cx, cy, d/2, SkPathDirection::kCW);
     return path;
 }
 
diff --git a/gm/nested.cpp b/gm/nested.cpp
index 859077f..9c1370c 100644
--- a/gm/nested.cpp
+++ b/gm/nested.cpp
@@ -53,7 +53,7 @@
         kShapeCount
     };
 
-    static void AddShape(SkPath* path, const SkRect& rect, Shapes shape, SkPath::Direction dir) {
+    static void AddShape(SkPath* path, const SkRect& rect, Shapes shape, SkPathDirection dir) {
         switch (shape) {
             case kRect_Shape:
                 path->addRect(rect, dir);
@@ -105,9 +105,9 @@
                 for (size_t innerRect = 0; innerRect < SK_ARRAY_COUNT(innerRects); ++innerRect) {
                     SkPath path;
 
-                    AddShape(&path, outerRect, (Shapes) outerShape, SkPath::kCW_Direction);
+                    AddShape(&path, outerRect, (Shapes) outerShape, SkPathDirection::kCW);
                     AddShape(&path, innerRects[innerRect], (Shapes) innerShape,
-                             SkPath::kCCW_Direction);
+                             SkPathDirection::kCCW);
 
                     canvas->save();
                     if (fFlipped) {
diff --git a/gm/patheffects.cpp b/gm/patheffects.cpp
index 33a6841..37715f1 100644
--- a/gm/patheffects.cpp
+++ b/gm/patheffects.cpp
@@ -148,9 +148,9 @@
 
         path.reset();
         SkRect r = { 0, 0, 250, 120 };
-        path.addOval(r, SkPath::kCW_Direction);
+        path.addOval(r, SkPathDirection::kCW);
         r.inset(50, 50);
-        path.addRect(r, SkPath::kCCW_Direction);
+        path.addRect(r, SkPathDirection::kCCW);
 
         canvas->translate(320, 20);
         for (size_t i = 0; i < SK_ARRAY_COUNT(gPE2); i++) {
diff --git a/gm/pathfill.cpp b/gm/pathfill.cpp
index 6a00f39..529bf72 100644
--- a/gm/pathfill.cpp
+++ b/gm/pathfill.cpp
@@ -21,7 +21,7 @@
 static SkScalar make_frame(SkPath* path) {
     SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
                  SkIntToScalar(630), SkIntToScalar(470) };
-    path->addRoundRect(r, SkIntToScalar(15), SkIntToScalar(15));
+    path->addRRect(SkRRect::MakeRectXY(r, 15, 15));
 
     SkPaint paint;
     paint.setStyle(SkPaint::kStroke_Style);
diff --git a/gm/pathopsskpclip.cpp b/gm/pathopsskpclip.cpp
index 75e7bd8..a2d7cee 100644
--- a/gm/pathopsskpclip.cpp
+++ b/gm/pathopsskpclip.cpp
@@ -42,7 +42,7 @@
             SkIntToScalar(400),
             SkIntToScalar(700)
         };
-        p.addRoundRect(r, SkIntToScalar(50), SkIntToScalar(50));
+        p.addRRect(SkRRect::MakeRectXY(r, 50, 50));
         rec->clipPath(p, true);
         rec->translate(SkIntToScalar(250), SkIntToScalar(250));
         rec->clipPath(p, true);
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index 6a87648..151758d 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -15,6 +15,8 @@
 
 #include <initializer_list>
 
+#define SK_SUPPORT_LEGACY_PATH_ENUMS
+
 class SkAutoPathBoundsUpdate;
 class SkData;
 class SkRRect;
@@ -41,6 +43,7 @@
 class SK_API SkPath {
 public:
 
+#ifdef SK_SUPPORT_LEGACY_PATH_ENUMS
     /** \enum SkPath::Direction
         Direction describes whether contour is clockwise or counterclockwise.
         When SkPath contains multiple overlapping contours, Direction together with
@@ -58,6 +61,7 @@
         kCW_Direction  = static_cast<int>(SkPathDirection::kCW),
         kCCW_Direction = static_cast<int>(SkPathDirection::kCCW)
     };
+#endif
 
     /** Constructs an empty SkPath. By default, SkPath has no verbs, no SkPoint, and no weights.
         SkPath::FillType is set to kWinding_FillType.
@@ -151,6 +155,7 @@
     */
     bool interpolate(const SkPath& ending, SkScalar weight, SkPath* out) const;
 
+#ifdef SK_SUPPORT_LEGACY_PATH_ENUMS
     /** \enum SkPath::FillType
         FillType selects the rule used to fill SkPath. SkPath set to kWinding_FillType
         fills if the sum of contour edges is not zero, where clockwise edges add one, and
@@ -166,7 +171,6 @@
         kInverseWinding_FillType = static_cast<int>(SkPathFillType::kInverseWinding),
         kInverseEvenOdd_FillType = static_cast<int>(SkPathFillType::kInverseEvenOdd)
     };
-
     /** Returns FillType, the rule used to fill SkPath. FillType of a new SkPath is
         kWinding_FillType.
 
@@ -175,13 +179,26 @@
     */
     FillType getFillType() const { return (FillType)fFillType; }
 
+    void setFillType(FillType ft) {
+        this->setFillType(static_cast<SkPathFillType>(ft));
+    }
+#else
+    /** Returns FillType, the rule used to fill SkPath. FillType of a new SkPath is
+     kWinding_FillType.
+
+     @return  one of: kWinding_FillType, kEvenOdd_FillType,  kInverseWinding_FillType,
+     kInverseEvenOdd_FillType
+     */
+    SkPathFillType getFillType() const { return (SkPathFillType)fFillType; }
+#endif
+
     /** Sets FillType, the rule used to fill SkPath. While there is no check
         that ft is legal, values outside of FillType are not supported.
 
         @param ft  one of: kWinding_FillType, kEvenOdd_FillType,  kInverseWinding_FillType,
                    kInverseEvenOdd_FillType
     */
-    void setFillType(FillType ft) {
+    void setFillType(SkPathFillType ft) {
         fFillType = SkToU8(ft);
     }
 
@@ -190,7 +207,7 @@
 
         @return  true if FillType is kInverseWinding_FillType or kInverseEvenOdd_FillType
     */
-    bool isInverseFillType() const { return IsInverseFillType((FillType)fFillType); }
+    bool isInverseFillType() const;
 
     /** Replaces FillType with its inverse. The inverse of FillType describes the area
         unmodified by the original FillType.
@@ -199,6 +216,7 @@
         fFillType ^= 2;
     }
 
+#ifdef SK_SUPPORT_LEGACY_PATH_ENUMS
     /** \enum SkPath::Convexity
         SkPath is convex if it contains one contour and contour loops no more than
         360 degrees, and contour angles all have same Direction. Convex SkPath
@@ -228,7 +246,7 @@
         if (convexity != kUnknown_Convexity) {
             return convexity;
         }
-        return this->internalGetConvexity();
+        return (Convexity)this->internalGetConvexity();
     }
 
     /** Returns last computed SkPath::Convexity, or kUnknown_Convexity if
@@ -236,7 +254,9 @@
 
         @return  stored SkPath::Convexity
     */
-    Convexity getConvexityOrUnknown() const { return fConvexity.load(std::memory_order_relaxed); }
+    Convexity getConvexityOrUnknown() const {
+        return (Convexity)fConvexity.load(std::memory_order_relaxed);
+    }
 
     /** Stores convexity so that it is later returned by getConvexity() or getConvexityOrUnknown().
         convexity may differ from getConvexity(), although setting an incorrect value may
@@ -251,7 +271,47 @@
 
         @param convexity  one of: kUnknown_Convexity, kConvex_Convexity, or kConcave_Convexity
     */
-    void setConvexity(Convexity convexity);
+    void setConvexity(Convexity convexity) {
+        this->setConvexity(static_cast<SkPathConvexityType>(convexity));
+    }
+#else
+    /** Computes SkPath::Convexity if required, and returns stored value.
+     SkPath::Convexity is computed if stored value is kUnknown_Convexity,
+     or if SkPath has been altered since SkPath::Convexity was computed or set.
+
+     @return  computed or stored SkPath::Convexity
+     */
+    SkPathConvexityType getConvexity() const {
+        SkPathConvexityType convexity = this->getConvexityOrUnknown();
+        if (convexity != SkPathConvexityType::kUnknown) {
+            return convexity;
+        }
+        return this->internalGetConvexity();
+    }
+
+    /** Returns last computed SkPath::Convexity, or kUnknown_Convexity if
+     SkPath has been altered since SkPath::Convexity was computed or set.
+
+     @return  stored SkPath::Convexity
+     */
+    SkPathConvexityType getConvexityOrUnknown() const {
+        return static_cast<SkPathConvexityType>(fConvexity.load(std::memory_order_relaxed));
+    }
+#endif
+    /** Stores convexity so that it is later returned by getConvexity() or getConvexityOrUnknown().
+     convexity may differ from getConvexity(), although setting an incorrect value may
+     cause incorrect or inefficient drawing.
+
+     If convexity is kUnknown_Convexity: getConvexity() will
+     compute SkPath::Convexity, and getConvexityOrUnknown() will return kUnknown_Convexity.
+
+     If convexity is kConvex_Convexity or kConcave_Convexity, getConvexity()
+     and getConvexityOrUnknown() will return convexity until the path is
+     altered.
+
+     @param convexity  one of: kUnknown_Convexity, kConvex_Convexity, or kConcave_Convexity
+     */
+    void setConvexity(SkPathConvexityType convexity);
 
     /** Computes SkPath::Convexity if required, and returns true if value is kConvex_Convexity.
         If setConvexity() was called with kConvex_Convexity or kConcave_Convexity, and
@@ -260,7 +320,7 @@
         @return  true if SkPath::Convexity stored or computed is kConvex_Convexity
     */
     bool isConvex() const {
-        return kConvex_Convexity == this->getConvexity();
+        return SkPathConvexityType::kConvex == (SkPathConvexityType)this->getConvexity();
     }
 
     /** Returns true if this path is recognized as an oval or circle.
@@ -899,35 +959,7 @@
         @return             reference to SkPath
     */
     SkPath& arcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
-                  Direction sweep, SkScalar x, SkScalar y);
-
-    /** Appends arc to SkPath. Arc is implemented by one or more conic weighted to describe
-        part of oval with radii (r.fX, r.fY) rotated by xAxisRotate degrees. Arc curves
-        from last SkPath SkPoint to (xy.fX, xy.fY), choosing one of four possible routes:
-        clockwise or counterclockwise,
-        and smaller or larger.
-
-        Arc sweep is always less than 360 degrees. arcTo() appends line to xy if either
-        radii are zero, or if last SkPath SkPoint equals (xy.fX, xy.fY). arcTo() scales radii r to
-        fit last SkPath SkPoint and xy if both are greater than zero but too small to describe
-        an arc.
-
-        arcTo() appends up to four conic curves.
-        arcTo() implements the functionality of SVG arc, although SVG sweep-flag value is
-        opposite the integer value of sweep; SVG sweep-flag uses 1 for clockwise, while
-        kCW_Direction cast to int is zero.
-
-        @param r            radii on axes before x-axis rotation
-        @param xAxisRotate  x-axis rotation in degrees; positive values are clockwise
-        @param largeArc     chooses smaller or larger arc
-        @param sweep        chooses clockwise or counterclockwise arc
-        @param xy           end of arc
-        @return             reference to SkPath
-    */
-    SkPath& arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep,
-               const SkPoint xy) {
-        return this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY);
-    }
+                  SkPathDirection sweep, SkScalar x, SkScalar y);
 
     /** Appends arc to SkPath, relative to last SkPath SkPoint. Arc is implemented by one or
         more conic, weighted to describe part of oval with radii (rx, ry) rotated by
@@ -956,7 +988,7 @@
         @return             reference to SkPath
     */
     SkPath& rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, ArcSize largeArc,
-                   Direction sweep, SkScalar dx, SkScalar dy);
+                   SkPathDirection sweep, SkScalar dx, SkScalar dy);
 
     /** Appends kClose_Verb to SkPath. A closed contour connects the first and last SkPoint
         with line, forming a continuous loop. Open and closed contour draw the same
@@ -970,6 +1002,7 @@
     */
     SkPath& close();
 
+#ifdef SK_SUPPORT_LEGACY_PATH_ENUMS
     /** Returns true if fill is inverted and SkPath with fill represents area outside
         of its geometric bounds.
 
@@ -999,6 +1032,7 @@
         static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch");
         return (FillType)(fill & 1);
     }
+#endif
 
     /** Approximates conic with quad array. Conic is constructed from start SkPoint p0,
         control SkPoint p1, end SkPoint p2, and weight w.
@@ -1041,7 +1075,7 @@
         @param direction  storage set to SkRect direction; may be nullptr
         @return           true if SkPath contains SkRect
     */
-    bool isRect(SkRect* rect, bool* isClosed = nullptr, Direction* direction = nullptr) const;
+    bool isRect(SkRect* rect, bool* isClosed = nullptr, SkPathDirection* dir = nullptr) const;
 
     /** Adds SkRect to SkPath, appending kMove_Verb, three kLine_Verb, and kClose_Verb,
         starting with top-left corner of SkRect; followed by top-right, bottom-right,
@@ -1052,7 +1086,7 @@
         @param dir   SkPath::Direction to wind added contour
         @return      reference to SkPath
     */
-    SkPath& addRect(const SkRect& rect, Direction dir = kCW_Direction);
+    SkPath& addRect(const SkRect& rect, SkPathDirection dir = SkPathDirection::kCW);
 
     /** Adds SkRect to SkPath, appending kMove_Verb, three kLine_Verb, and kClose_Verb.
         If dir is kCW_Direction, SkRect corners are added clockwise; if dir is
@@ -1064,23 +1098,7 @@
         @param start  initial corner of SkRect to add
         @return       reference to SkPath
     */
-    SkPath& addRect(const SkRect& rect, Direction dir, unsigned start);
-
-    /** Adds SkRect (left, top, right, bottom) to SkPath,
-        appending kMove_Verb, three kLine_Verb, and kClose_Verb,
-        starting with top-left corner of SkRect; followed by top-right, bottom-right,
-        and bottom-left if dir is kCW_Direction; or followed by bottom-left,
-        bottom-right, and top-right if dir is kCCW_Direction.
-
-        @param left    smaller x-axis value of SkRect
-        @param top     smaller y-axis value of SkRect
-        @param right   larger x-axis value of SkRect
-        @param bottom  larger y-axis value of SkRect
-        @param dir     SkPath::Direction to wind added contour
-        @return        reference to SkPath
-    */
-    SkPath& addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
-                    Direction dir = kCW_Direction);
+    SkPath& addRect(const SkRect& rect, SkPathDirection dir, unsigned start);
 
     /** Adds oval to path, appending kMove_Verb, four kConic_Verb, and kClose_Verb.
         Oval is upright ellipse bounded by SkRect oval with radii equal to half oval width
@@ -1091,7 +1109,7 @@
         @param dir   SkPath::Direction to wind ellipse
         @return      reference to SkPath
     */
-    SkPath& addOval(const SkRect& oval, Direction dir = kCW_Direction);
+    SkPath& addOval(const SkRect& oval, SkPathDirection dir = SkPathDirection::kCW);
 
     /** Adds oval to SkPath, appending kMove_Verb, four kConic_Verb, and kClose_Verb.
         Oval is upright ellipse bounded by SkRect oval with radii equal to half oval width
@@ -1103,7 +1121,7 @@
         @param start  index of initial point of ellipse
         @return       reference to SkPath
     */
-    SkPath& addOval(const SkRect& oval, Direction dir, unsigned start);
+    SkPath& addOval(const SkRect& oval, SkPathDirection dir, unsigned start);
 
     /** Adds circle centered at (x, y) of size radius to SkPath, appending kMove_Verb,
         four kConic_Verb, and kClose_Verb. Circle begins at: (x + radius, y), continuing
@@ -1118,7 +1136,7 @@
         @return        reference to SkPath
     */
     SkPath& addCircle(SkScalar x, SkScalar y, SkScalar radius,
-                      Direction dir = kCW_Direction);
+                      SkPathDirection dir = SkPathDirection::kCW);
 
     /** Appends arc to SkPath, as the start of new contour. Arc added is part of ellipse
         bounded by oval, from startAngle through sweepAngle. Both startAngle and
@@ -1136,39 +1154,6 @@
     */
     SkPath& addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
 
-    /** Appends SkRRect to SkPath, creating a new closed contour. SkRRect has bounds
-        equal to rect; each corner is 90 degrees of an ellipse with radii (rx, ry). If
-        dir is kCW_Direction, SkRRect starts at top-left of the lower-left corner and
-        winds clockwise. If dir is kCCW_Direction, SkRRect starts at the bottom-left
-        of the upper-left corner and winds counterclockwise.
-
-        If either rx or ry is too large, rx and ry are scaled uniformly until the
-        corners fit. If rx or ry is less than or equal to zero, addRoundRect() appends
-        SkRect rect to SkPath.
-
-        After appending, SkPath may be empty, or may contain: SkRect, oval, or SkRRect.
-
-        @param rect  bounds of SkRRect
-        @param rx    x-axis radius of rounded corners on the SkRRect
-        @param ry    y-axis radius of rounded corners on the SkRRect
-        @param dir   SkPath::Direction to wind SkRRect
-        @return      reference to SkPath
-    */
-    SkPath& addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
-                         Direction dir = kCW_Direction);
-
-    /** Appends SkRRect to SkPath, creating a new closed contour. SkRRect has bounds
-        equal to rect; each corner is 90 degrees of an ellipse with radii from the
-        array.
-
-        @param rect   bounds of SkRRect
-        @param radii  array of 8 SkScalar values, a radius pair for each corner
-        @param dir    SkPath::Direction to wind SkRRect
-        @return       reference to SkPath
-    */
-    SkPath& addRoundRect(const SkRect& rect, const SkScalar radii[],
-                         Direction dir = kCW_Direction);
-
     /** Adds rrect to SkPath, creating a new closed contour. If
         dir is kCW_Direction, rrect starts at top-left of the lower-left corner and
         winds clockwise. If dir is kCCW_Direction, rrect starts at the bottom-left
@@ -1180,7 +1165,7 @@
         @param dir    SkPath::Direction to wind SkRRect
         @return       reference to SkPath
     */
-    SkPath& addRRect(const SkRRect& rrect, Direction dir = kCW_Direction);
+    SkPath& addRRect(const SkRRect& rrect, SkPathDirection dir = SkPathDirection::kCW);
 
     /** Adds rrect to SkPath, creating a new closed contour. If dir is kCW_Direction, rrect
         winds clockwise; if dir is kCCW_Direction, rrect winds counterclockwise.
@@ -1191,7 +1176,7 @@
         @param start  index of initial point of SkRRect
         @return       reference to SkPath
     */
-    SkPath& addRRect(const SkRRect& rrect, Direction dir, unsigned start);
+    SkPath& addRRect(const SkRRect& rrect, SkPathDirection dir, unsigned start);
 
     /** Adds contour created from line array, adding (count - 1) line segments.
         Contour added starts at pts[0], then adds a line for every additional SkPoint
@@ -1651,10 +1636,66 @@
     */
     bool isValid() const { return this->isValidImpl() && fPathRef->isValid(); }
 
+#ifdef SK_SUPPORT_LEGACY_PATH_ENUMS
+    SkPath& arcTo(SkScalar rx, SkScalar ry, SkScalar xRotate, ArcSize largeArc,
+                  Direction sweep, SkScalar x, SkScalar y) {
+        return this->arcTo(rx, ry, xRotate, largeArc, static_cast<SkPathDirection>(sweep), x, y);
+    }
+    SkPath& arcTo(const SkPoint r, SkScalar xAxisRotate, ArcSize largeArc, Direction sweep,
+                  const SkPoint xy) {
+        return this->arcTo(r.fX, r.fY, xAxisRotate, largeArc, sweep, xy.fX, xy.fY);
+    }
+    SkPath& rArcTo(SkScalar rx, SkScalar ry, SkScalar xRotate, ArcSize largeArc,
+                   Direction sweep, SkScalar dx, SkScalar dy) {
+        return this->rArcTo(rx, ry, xRotate, largeArc, static_cast<SkPathDirection>(sweep), dx, dy);
+    }
+    bool isRect(SkRect* rect, bool* isClosed, Direction* direction) const {
+        return this->isRect(rect, isClosed, reinterpret_cast<SkPathDirection*>(direction));
+    }
+    bool isRect(SkRect* rect, bool* isClosed, std::nullptr_t) const {
+        return this->isRect(rect, isClosed, (SkPathDirection*)nullptr);
+    }
+    SkPath& addRect(const SkRect& rect, Direction dir) {
+        return this->addRect(rect, static_cast<SkPathDirection>(dir));
+    }
+    SkPath& addRect(const SkRect& rect, Direction dir, unsigned start) {
+        return this->addRect(rect, static_cast<SkPathDirection>(dir), start);
+    }
+    SkPath& addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
+                    Direction dir = kCW_Direction) {
+        return this->addRect({left, top, right, bottom}, static_cast<SkPathDirection>(dir));
+    }
+    SkPath& addOval(const SkRect& oval, Direction dir) {
+        return this->addOval(oval, static_cast<SkPathDirection>(dir));
+    }
+    SkPath& addOval(const SkRect& oval, Direction dir, unsigned start) {
+        return this->addOval(oval, static_cast<SkPathDirection>(dir), start);
+    }
+    SkPath& addCircle(SkScalar x, SkScalar y, SkScalar radius, Direction dir) {
+        return this->addCircle(x, y, radius, static_cast<SkPathDirection>(dir));
+    }
+    SkPath& addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
+                         Direction dir = kCW_Direction) {
+        return this->addRRect(SkRRect::MakeRectXY(rect, rx, ry), static_cast<SkPathDirection>(dir));
+    }
+    SkPath& addRoundRect(const SkRect& rect, const SkScalar radii[],
+                         Direction dir = kCW_Direction) {
+        SkRRect rr;
+        rr.setRectRadii(rect, reinterpret_cast<const SkPoint*>(radii));
+        return this->addRRect(rr, static_cast<SkPathDirection>(dir));
+    }
+    SkPath& addRRect(const SkRRect& rrect, Direction dir) {
+        return this->addRRect(rrect, static_cast<SkPathDirection>(dir));
+    }
+    SkPath& addRRect(const SkRRect& rrect, Direction dir, unsigned start) {
+        return this->addRRect(rrect, static_cast<SkPathDirection>(dir), start);
+    }
+#endif
+
 private:
     sk_sp<SkPathRef>               fPathRef;
     int                            fLastMoveToIndex;
-    mutable std::atomic<Convexity> fConvexity;
+    mutable std::atomic<uint8_t>   fConvexity;
     mutable std::atomic<uint8_t>   fFirstDirection; // really an SkPathPriv::FirstDirection
     uint8_t                        fFillType    : 2;
     uint8_t                        fIsVolatile  : 1;
@@ -1695,7 +1736,7 @@
 
     inline bool hasOnlyMoveTos() const;
 
-    Convexity internalGetConvexity() const;
+    SkPathConvexityType internalGetConvexity() const;
 
     /** Asserts if SkPath data is inconsistent.
         Debugging check intended for internal use only.
@@ -1727,7 +1768,7 @@
 
     // Bottlenecks for working with fConvexity and fFirstDirection.
     // Notice the setters are const... these are mutable atomic fields.
-    void    setConvexity(Convexity) const;
+    void    setConvexity(SkPathConvexityType) const;
     void    setFirstDirection(uint8_t) const;
     uint8_t getFirstDirection() const;
 
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index cc36958..5802721 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -251,12 +251,12 @@
 };
 
 inline GrFillRule GrFillRuleForSkPath(const SkPath& path) {
-    switch (path.getFillType()) {
-        case SkPath::kWinding_FillType:
-        case SkPath::kInverseWinding_FillType:
+    switch ((SkPathFillType)path.getFillType()) {
+        case SkPathFillType::kWinding:
+        case SkPathFillType::kInverseWinding:
             return GrFillRule::kNonzero;
-        case SkPath::kEvenOdd_FillType:
-        case SkPath::kInverseEvenOdd_FillType:
+        case SkPathFillType::kEvenOdd:
+        case SkPathFillType::kInverseEvenOdd:
             return GrFillRule::kEvenOdd;
     }
     SkUNREACHABLE;
diff --git a/modules/pathkit/pathkit_wasm_bindings.cpp b/modules/pathkit/pathkit_wasm_bindings.cpp
index c47af69..7e2f285 100644
--- a/modules/pathkit/pathkit_wasm_bindings.cpp
+++ b/modules/pathkit/pathkit_wasm_bindings.cpp
@@ -318,7 +318,7 @@
 // Path2D API things
 // ======================================================================================
 void ApplyAddRect(SkPath& path, SkScalar x, SkScalar y, SkScalar width, SkScalar height) {
-    path.addRect(x, y, x+width, y+height);
+    path.addRect({x, y, x+width, y+height});
 }
 
 void ApplyAddArc(SkPath& path, SkScalar x, SkScalar y, SkScalar radius,
@@ -356,9 +356,9 @@
 }
 
 JSString GetFillTypeString(const SkPath& path) {
-    if (path.getFillType() == SkPath::FillType::kWinding_FillType) {
+    if ((SkPathFillType)path.getFillType() == SkPathFillType::kWinding) {
         return emscripten::val("nonzero");
-    } else if (path.getFillType() == SkPath::FillType::kEvenOdd_FillType) {
+    } else if ((SkPathFillType)path.getFillType() == SkPathFillType::kEvenOdd) {
         return emscripten::val("evenodd");
     } else {
         SkDebugf("warning: can't translate inverted filltype to HTML Canvas\n");
@@ -503,7 +503,7 @@
         .function("_rect", &ApplyAddRect)
 
         // Extra features
-        .function("setFillType", &SkPath::setFillType)
+        .function("setFillType", select_overload<void(SkPathFillType)>(&SkPath::setFillType))
         .function("getFillType", &SkPath::getFillType)
         .function("getFillTypeString", &GetFillTypeString)
         .function("getBounds", &SkPath::getBounds)
@@ -564,11 +564,11 @@
         .value("XOR",                SkPathOp::kXOR_SkPathOp)
         .value("REVERSE_DIFFERENCE", SkPathOp::kReverseDifference_SkPathOp);
 
-    enum_<SkPath::FillType>("FillType")
-        .value("WINDING",            SkPath::FillType::kWinding_FillType)
-        .value("EVENODD",            SkPath::FillType::kEvenOdd_FillType)
-        .value("INVERSE_WINDING",    SkPath::FillType::kInverseWinding_FillType)
-        .value("INVERSE_EVENODD",    SkPath::FillType::kInverseEvenOdd_FillType);
+    enum_<SkPathFillType>("FillType")
+        .value("WINDING",            SkPathFillType::kWinding)
+        .value("EVENODD",            SkPathFillType::kEvenOdd)
+        .value("INVERSE_WINDING",    SkPathFillType::kInverseWinding)
+        .value("INVERSE_EVENODD",    SkPathFillType::kInverseEvenOdd);
 
     constant("MOVE_VERB",  MOVE);
     constant("LINE_VERB",  LINE);
diff --git a/modules/skottie/src/layers/ShapeLayer.cpp b/modules/skottie/src/layers/ShapeLayer.cpp
index 3b7f98c..d2baab2 100644
--- a/modules/skottie/src/layers/ShapeLayer.cpp
+++ b/modules/skottie/src/layers/ShapeLayer.cpp
@@ -41,8 +41,8 @@
 sk_sp<sksg::GeometryNode> AttachRRectGeometry(const skjson::ObjectValue& jrect,
                                               const AnimationBuilder* abuilder) {
     auto rect_node = sksg::RRect::Make();
-    rect_node->setDirection(ParseDefault(jrect["d"], -1) == 3 ? SkPath::kCCW_Direction
-                                                              : SkPath::kCW_Direction);
+    rect_node->setDirection(ParseDefault(jrect["d"], -1) == 3 ? SkPathDirection::kCCW
+                                                              : SkPathDirection::kCW);
     rect_node->setInitialPointIndex(2); // starting point: (Right, Top - radius.y)
 
     auto adapter = sk_make_sp<RRectAdapter>(rect_node);
@@ -70,8 +70,8 @@
 sk_sp<sksg::GeometryNode> AttachEllipseGeometry(const skjson::ObjectValue& jellipse,
                                                 const AnimationBuilder* abuilder) {
     auto rect_node = sksg::RRect::Make();
-    rect_node->setDirection(ParseDefault(jellipse["d"], -1) == 3 ? SkPath::kCCW_Direction
-                                                                 : SkPath::kCW_Direction);
+    rect_node->setDirection(ParseDefault(jellipse["d"], -1) == 3 ? SkPathDirection::kCCW
+                                                                 : SkPathDirection::kCW);
     rect_node->setInitialPointIndex(1); // starting point: (Center, Top)
 
     auto adapter = sk_make_sp<RRectAdapter>(rect_node);
diff --git a/modules/sksg/include/SkSGRect.h b/modules/sksg/include/SkSGRect.h
index 29456a0..c7966f4 100644
--- a/modules/sksg/include/SkSGRect.h
+++ b/modules/sksg/include/SkSGRect.h
@@ -32,8 +32,8 @@
     SG_ATTRIBUTE(R, SkScalar, fRect.fRight )
     SG_ATTRIBUTE(B, SkScalar, fRect.fBottom)
 
-    SG_MAPPED_ATTRIBUTE(Direction        , SkPath::Direction, fAttrContaier)
-    SG_MAPPED_ATTRIBUTE(InitialPointIndex, uint8_t          , fAttrContaier)
+    SG_MAPPED_ATTRIBUTE(Direction        , SkPathDirection, fAttrContaier)
+    SG_MAPPED_ATTRIBUTE(InitialPointIndex, uint8_t        , fAttrContaier)
 
 protected:
     void onClip(SkCanvas*, bool antiAlias) const override;
@@ -52,15 +52,15 @@
         uint8_t fDirection         : 1;
         uint8_t fInitialPointIndex : 2;
 
-        SkPath::Direction getDirection() const {
-            return static_cast<SkPath::Direction>(fDirection);
+        SkPathDirection getDirection() const {
+            return static_cast<SkPathDirection>(fDirection);
         }
-        void setDirection(SkPath::Direction dir) { fDirection = SkTo<uint8_t>(dir); }
+        void setDirection(SkPathDirection dir) { fDirection = SkTo<uint8_t>(dir); }
 
         uint8_t getInitialPointIndex() const { return fInitialPointIndex; }
         void setInitialPointIndex(uint8_t idx) { fInitialPointIndex = idx; }
     };
-    AttrContainer fAttrContaier = { SkPath::kCW_Direction, 0 };
+    AttrContainer fAttrContaier = { (uint8_t)SkPathDirection::kCW, 0 };
 
     using INHERITED = GeometryNode;
 };
@@ -75,8 +75,8 @@
 
     SG_ATTRIBUTE(RRect, SkRRect, fRRect)
 
-    SG_MAPPED_ATTRIBUTE(Direction        , SkPath::Direction, fAttrContaier)
-    SG_MAPPED_ATTRIBUTE(InitialPointIndex, uint8_t          , fAttrContaier)
+    SG_MAPPED_ATTRIBUTE(Direction        , SkPathDirection, fAttrContaier)
+    SG_MAPPED_ATTRIBUTE(InitialPointIndex, uint8_t        , fAttrContaier)
 
 protected:
     void onClip(SkCanvas*, bool antiAlias) const override;
@@ -95,15 +95,15 @@
         uint8_t fDirection         : 1;
         uint8_t fInitialPointIndex : 2;
 
-        SkPath::Direction getDirection() const {
-            return static_cast<SkPath::Direction>(fDirection);
+        SkPathDirection getDirection() const {
+            return static_cast<SkPathDirection>(fDirection);
         }
-        void setDirection(SkPath::Direction dir) { fDirection = SkTo<uint8_t>(dir); }
+        void setDirection(SkPathDirection dir) { fDirection = SkTo<uint8_t>(dir); }
 
         uint8_t getInitialPointIndex() const { return fInitialPointIndex; }
         void setInitialPointIndex(uint8_t idx) { fInitialPointIndex = idx; }
     };
-    AttrContainer fAttrContaier = { SkPath::kCW_Direction, 0 };
+    AttrContainer fAttrContaier = { (uint8_t)SkPathDirection::kCW, 0 };
 
     using INHERITED = GeometryNode;
 };
diff --git a/samplecode/SampleAAClip.cpp b/samplecode/SampleAAClip.cpp
index 46e4fe2..b762066 100644
--- a/samplecode/SampleAAClip.cpp
+++ b/samplecode/SampleAAClip.cpp
@@ -70,7 +70,7 @@
 
 //        path.addRect(bounds);
 //        path.addOval(bounds);
-        path.addRoundRect(bounds, 4, 4);
+        path.addRRect(SkRRect::MakeRectXY(bounds, 4, 4));
         aaclip.setPath(path);
         canvas->translate(30, 30);
         drawClip(canvas, aaclip);
diff --git a/samplecode/SampleAndroidShadows.cpp b/samplecode/SampleAndroidShadows.cpp
index 71eb22a..7ee80b0 100644
--- a/samplecode/SampleAndroidShadows.cpp
+++ b/samplecode/SampleAndroidShadows.cpp
@@ -51,9 +51,8 @@
         fCirclePath.addCircle(0, 0, 50);
         fRectPath.addRect(SkRect::MakeXYWH(-100, -50, 200, 100));
         fRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -50, 200, 100), 4, 4));
-        fFunkyRRPath.addRoundRect(SkRect::MakeXYWH(-50, -50, SK_Scalar1 * 100, SK_Scalar1 * 100),
-                                  40 * SK_Scalar1, 20 * SK_Scalar1,
-                                  SkPath::kCW_Direction);
+        fFunkyRRPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-50, -50, 100, 100), 40, 20),
+                              SkPathDirection::kCW);
         fCubicPath.cubicTo(100 * SK_Scalar1, 50 * SK_Scalar1,
                            20 * SK_Scalar1, 100 * SK_Scalar1,
                            0 * SK_Scalar1, 0 * SK_Scalar1);
diff --git a/samplecode/SampleClip.cpp b/samplecode/SampleClip.cpp
index e931881..cbc76e9 100644
--- a/samplecode/SampleClip.cpp
+++ b/samplecode/SampleClip.cpp
@@ -114,7 +114,7 @@
         SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
         SkPath clipPath;
         r.inset(SK_Scalar1 / 4, SK_Scalar1 / 4);
-        clipPath.addRoundRect(r, SkIntToScalar(20), SkIntToScalar(20));
+        clipPath.addRRect(SkRRect::MakeRectXY(r, 20, 20));
 
 //        clipPath.toggleInverseFillType();
 
diff --git a/samplecode/SampleClock.cpp b/samplecode/SampleClock.cpp
index a90ecf1..f7332ce 100644
--- a/samplecode/SampleClock.cpp
+++ b/samplecode/SampleClock.cpp
@@ -160,7 +160,7 @@
 #ifdef USE_PATH
         path.reset();
         path.arcTo(rect, 0, 0, false);
-        path.addOval(rect, SkPath::kCCW_Direction);
+        path.addOval(rect, SkPathDirection::kCCW);
         path.arcTo(rect, 360, 0, true);
         canvas->drawPath(path, paintFill);
 #else
@@ -170,7 +170,7 @@
 #ifdef USE_PATH
         path.reset();
         path.arcTo(rect, 0, 0, false);
-        path.addOval(rect, SkPath::kCCW_Direction);
+        path.addOval(rect, SkPathDirection::kCCW);
         path.arcTo(rect, 360, 0, true);
         canvas->drawPath(path, paintStroke);
 #else
@@ -180,7 +180,7 @@
 #ifdef USE_PATH
         rect = SkRect::MakeLTRB(-6, -6, 6, 6);
         path.arcTo(rect, 0, 0, false);
-        path.addOval(rect, SkPath::kCCW_Direction);
+        path.addOval(rect, SkPathDirection::kCCW);
         path.arcTo(rect, 360, 0, true);
         canvas->drawPath(path, paintFill);
 #else
@@ -196,7 +196,7 @@
 #ifdef USE_PATH
         path.reset();
         path.arcTo(rect, 0, 0, false);
-        path.addOval(rect, SkPath::kCCW_Direction);
+        path.addOval(rect, SkPathDirection::kCCW);
         path.arcTo(rect, 360, 0, true);
         canvas->drawPath(path, paintStroke);
 #else
diff --git a/samplecode/SampleComplexClip.cpp b/samplecode/SampleComplexClip.cpp
index 4e811a0..d903148 100644
--- a/samplecode/SampleComplexClip.cpp
+++ b/samplecode/SampleComplexClip.cpp
@@ -34,7 +34,7 @@
         path.quadTo(SkIntToScalar(150), SkIntToScalar(150), SkIntToScalar(125), SkIntToScalar(150));
         path.lineTo(SkIntToScalar(50),  SkIntToScalar(150));
         path.close();
-        path.setFillType(SkPath::kEvenOdd_FillType);
+        path.setFillType(SkPathFillType::kEvenOdd);
         SkColor pathColor = SK_ColorBLACK;
         SkPaint pathPaint;
         pathPaint.setAntiAlias(true);
@@ -99,8 +99,8 @@
                 }
                 canvas->save();
                     // set clip
-                    clipA.setFillType(invA ? SkPath::kInverseEvenOdd_FillType :
-                                             SkPath::kEvenOdd_FillType);
+                    clipA.setFillType(invA ? SkPathFillType::kInverseEvenOdd :
+                                             SkPathFillType::kEvenOdd);
                     canvas->clipPath(clipA);
                     canvas->clipPath(clipB, gOps[op].fOp);
 
diff --git a/samplecode/SampleFillType.cpp b/samplecode/SampleFillType.cpp
index 58e954a..2678491 100644
--- a/samplecode/SampleFillType.cpp
+++ b/samplecode/SampleFillType.cpp
@@ -27,7 +27,7 @@
 protected:
     virtual SkString name() { return SkString("FillType"); }
 
-    void showPath(SkCanvas* canvas, int x, int y, SkPath::FillType ft,
+    void showPath(SkCanvas* canvas, int x, int y, SkPathFillType ft,
                   SkScalar scale, const SkPaint& paint) {
 
         const SkRect r = { 0, 0, SkIntToScalar(150), SkIntToScalar(150) };
@@ -45,14 +45,10 @@
     }
 
     void showFour(SkCanvas* canvas, SkScalar scale, const SkPaint& paint) {
-        showPath(canvas,   0,   0, SkPath::kWinding_FillType,
-                 scale, paint);
-        showPath(canvas, 200,   0, SkPath::kEvenOdd_FillType,
-                 scale, paint);
-        showPath(canvas,  00, 200, SkPath::kInverseWinding_FillType,
-                 scale, paint);
-        showPath(canvas, 200, 200, SkPath::kInverseEvenOdd_FillType,
-                 scale, paint);
+        showPath(canvas,   0,   0, SkPathFillType::kWinding, scale, paint);
+        showPath(canvas, 200,   0, SkPathFillType::kEvenOdd, scale, paint);
+        showPath(canvas,  00, 200, SkPathFillType::kInverseWinding, scale, paint);
+        showPath(canvas, 200, 200, SkPathFillType::kInverseEvenOdd, scale, paint);
     }
 
     virtual void onDrawContent(SkCanvas* canvas) {
diff --git a/samplecode/SampleFilterQuality.cpp b/samplecode/SampleFilterQuality.cpp
index 54fe4af..f18a1a6 100644
--- a/samplecode/SampleFilterQuality.cpp
+++ b/samplecode/SampleFilterQuality.cpp
@@ -42,7 +42,7 @@
     canvas->drawColor(SK_ColorWHITE);
 
     SkPath path;
-    path.setFillType(SkPath::kEvenOdd_FillType);
+    path.setFillType(SkPathFillType::kEvenOdd);
 
     path.addRect(SkRect::MakeWH(N/2, N));
     path.addRect(SkRect::MakeWH(N, N/2));
diff --git a/samplecode/SampleIdentityScale.cpp b/samplecode/SampleIdentityScale.cpp
index 4e7b1dd..dcfdc0a 100644
--- a/samplecode/SampleIdentityScale.cpp
+++ b/samplecode/SampleIdentityScale.cpp
@@ -56,7 +56,7 @@
 
           SkRect r = { 100, 100, 356, 356 };
           SkPath clipPath;
-          clipPath.addRoundRect(r, SkIntToScalar(5), SkIntToScalar(5));
+          clipPath.addRRect(SkRRect::MakeRectXY(r, 5, 5));
           canvas->clipPath(clipPath, kIntersect_SkClipOp, true);
           text = "Scaled = 0";
         }
diff --git a/samplecode/SampleLayerMask.cpp b/samplecode/SampleLayerMask.cpp
index 9785e88..546c6c4 100644
--- a/samplecode/SampleLayerMask.cpp
+++ b/samplecode/SampleLayerMask.cpp
@@ -42,7 +42,7 @@
         } else {
             SkPath p;
             p.addOval(r);
-            p.setFillType(SkPath::kInverseWinding_FillType);
+            p.setFillType(SkPathFillType::kInverseWinding);
             paint.setBlendMode(SkBlendMode::kDstOut);
             canvas->drawPath(p, paint);
         }
diff --git a/samplecode/SamplePathEffects.cpp b/samplecode/SamplePathEffects.cpp
index ccdc541..8666940 100644
--- a/samplecode/SamplePathEffects.cpp
+++ b/samplecode/SamplePathEffects.cpp
@@ -99,7 +99,7 @@
             SkRect  oval;
             oval.setLTRB(20, 30, 100, 60);
             oval.offset(x, 0);
-            fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8));
+            fPath.addRRect(SkRRect::MakeRectXY(oval, 8, 8));
         }
 
         fClickPt.set(SkIntToScalar(200), SkIntToScalar(200));
diff --git a/samplecode/SampleQuadStroker.cpp b/samplecode/SampleQuadStroker.cpp
index 72dfabc..6b679e2 100644
--- a/samplecode/SampleQuadStroker.cpp
+++ b/samplecode/SampleQuadStroker.cpp
@@ -488,7 +488,7 @@
         paint.setColor(0x3f0f1f3f);
         canvas->drawPath(path, paint);
         path.reset();
-        path.setFillType(SkPath::kEvenOdd_FillType);
+        path.setFillType(SkPathFillType::kEvenOdd);
         path.addCircle(center.fX, center.fY, maxSide + width / 2);
         SkRect outside = SkRect::MakeXYWH(center.fX - maxSide - width, center.fY - maxSide - width,
                 (maxSide + width) * 2, (maxSide + width) * 2);
@@ -646,9 +646,9 @@
             path.reset();
             SkRRect rr2;
             rr.inset(width/2, width/2, &rr2);
-            path.addRRect(rr2, SkPath::kCCW_Direction);
+            path.addRRect(rr2, SkPathDirection::kCCW);
             rr.inset(-width/2, -width/2, &rr2);
-            path.addRRect(rr2, SkPath::kCW_Direction);
+            path.addRRect(rr2, SkPathDirection::kCW);
             SkPaint paint;
             paint.setAntiAlias(true);
             paint.setColor(0x40FF8844);
diff --git a/samplecode/SampleRegion.cpp b/samplecode/SampleRegion.cpp
index 58ad5e0..7adb9ef 100644
--- a/samplecode/SampleRegion.cpp
+++ b/samplecode/SampleRegion.cpp
@@ -30,9 +30,7 @@
     SkScalar dy = 20;
 
     SkPath path;
-    path.addRect(0.0f, 0.0f,
-                 SkIntToScalar(width), SkIntToScalar(height),
-                 SkPath::kCW_Direction);
+    path.addRect({0.0f, 0.0f, SkIntToScalar(width), SkIntToScalar(height)}, SkPathDirection::kCW);
     SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
 
     SkCanvas c(bitmap);
diff --git a/samplecode/SampleShadowUtils.cpp b/samplecode/SampleShadowUtils.cpp
index 86151c1..b3023fa 100644
--- a/samplecode/SampleShadowUtils.cpp
+++ b/samplecode/SampleShadowUtils.cpp
@@ -42,7 +42,7 @@
 
 protected:
     void onOnceBeforeDraw() override {
-        fConvexPaths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10);
+        fConvexPaths.push_back().addRRect(SkRRect::MakeRectXY(SkRect::MakeWH(50, 50), 10, 10));
         SkRRect oddRRect;
         oddRRect.setNinePatch(SkRect::MakeWH(50, 50), 9, 13, 6, 16);
         fConvexPaths.push_back().addRRect(oddRRect);
diff --git a/samplecode/SampleSlides.cpp b/samplecode/SampleSlides.cpp
index 09cb87c..d58f4f1 100644
--- a/samplecode/SampleSlides.cpp
+++ b/samplecode/SampleSlides.cpp
@@ -136,9 +136,9 @@
 
     path.reset();
     SkRect r = { 0, 0, 250, 120 };
-    path.addOval(r, SkPath::kCW_Direction);
+    path.addOval(r, SkPathDirection::kCW);
     r.inset(50, 50);
-    path.addRect(r, SkPath::kCCW_Direction);
+    path.addRect(r, SkPathDirection::kCCW);
 
     canvas->translate(320, 20);
     for (i = 0; i < SK_ARRAY_COUNT(gPE2); i++) {
diff --git a/samplecode/SampleStrokePath.cpp b/samplecode/SampleStrokePath.cpp
index 4963f97..b22ba8d 100644
--- a/samplecode/SampleStrokePath.cpp
+++ b/samplecode/SampleStrokePath.cpp
@@ -112,8 +112,8 @@
             "Z";
         SkParsePath::FromSVGString(str, &fPath);
 #else
-        fPath.addCircle(0, 0, SkIntToScalar(50), SkPath::kCW_Direction);
-        fPath.addCircle(0, SkIntToScalar(-50), SkIntToScalar(30), SkPath::kCW_Direction);
+        fPath.addCircle(0, 0, SkIntToScalar(50), SkPathDirection::kCW);
+        fPath.addCircle(0, SkIntToScalar(-50), SkIntToScalar(30), SkPathDirection::kCW);
 #endif
 
         scale_to_width(&fPath, fWidth);
@@ -192,11 +192,11 @@
         fPath.offset(100, 0);
 #endif
 
-        fPath.setFillType(SkPath::kWinding_FillType);
+        fPath.setFillType(SkPathFillType::kWinding);
         drawSet(canvas, &paint);
 
         canvas->translate(0, fPath.getBounds().height() * 5 / 4);
-        fPath.setFillType(SkPath::kEvenOdd_FillType);
+        fPath.setFillType(SkPathFillType::kEvenOdd);
         drawSet(canvas, &paint);
     }
 
diff --git a/samplecode/SampleTextEffects.cpp b/samplecode/SampleTextEffects.cpp
index 2303288..8e57750 100644
--- a/samplecode/SampleTextEffects.cpp
+++ b/samplecode/SampleTextEffects.cpp
@@ -82,7 +82,7 @@
     virtual bool onFilterPath(SkPath* dst, const SkPath& src,
                               SkStrokeRec*, const SkRect*) const override {
         *dst = src;
-        dst->setFillType(SkPath::kInverseWinding_FillType);
+        dst->setFillType(SkPathFillType::kInverseWinding);
         return true;
     }
 
diff --git a/src/c/sk_surface.cpp b/src/c/sk_surface.cpp
index b3f203f..65fe209 100644
--- a/src/c/sk_surface.cpp
+++ b/src/c/sk_surface.cpp
@@ -56,13 +56,13 @@
 
 const struct {
     sk_path_direction_t fC;
-    SkPath::Direction   fSk;
+    SkPathDirection   fSk;
 } gPathDirMap[] = {
-    { CW_SK_PATH_DIRECTION,  SkPath::kCW_Direction },
-    { CCW_SK_PATH_DIRECTION, SkPath::kCCW_Direction },
+    { CW_SK_PATH_DIRECTION,  SkPathDirection::kCW },
+    { CCW_SK_PATH_DIRECTION, SkPathDirection::kCCW },
 };
 
-static bool from_c_path_direction(sk_path_direction_t cdir, SkPath::Direction* dir) {
+static bool from_c_path_direction(sk_path_direction_t cdir, SkPathDirection* dir) {
     for (size_t i = 0; i < SK_ARRAY_COUNT(gPathDirMap); ++i) {
         if (gPathDirMap[i].fC == cdir) {
             if (dir) {
@@ -202,7 +202,7 @@
 }
 
 void sk_path_add_rect(sk_path_t* cpath, const sk_rect_t* crect, sk_path_direction_t cdir) {
-    SkPath::Direction dir;
+    SkPathDirection dir;
     if (!from_c_path_direction(cdir, &dir)) {
         return;
     }
@@ -210,7 +210,7 @@
 }
 
 void sk_path_add_oval(sk_path_t* cpath, const sk_rect_t* crect, sk_path_direction_t cdir) {
-    SkPath::Direction dir;
+    SkPathDirection dir;
     if (!from_c_path_direction(cdir, &dir)) {
         return;
     }
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp
index 9219f67..f8dad04 100644
--- a/src/core/SkClipStack.cpp
+++ b/src/core/SkClipStack.cpp
@@ -129,13 +129,13 @@
         case DeviceSpaceType::kRect:
             fDeviceSpacePath.init();
             fDeviceSpacePath.get()->addRect(this->getDeviceSpaceRect());
-            fDeviceSpacePath.get()->setFillType(SkPath::kInverseEvenOdd_FillType);
+            fDeviceSpacePath.get()->setFillType(SkPathFillType::kInverseEvenOdd);
             fDeviceSpaceType = DeviceSpaceType::kPath;
             break;
         case DeviceSpaceType::kRRect:
             fDeviceSpacePath.init();
             fDeviceSpacePath.get()->addRRect(fDeviceSpaceRRect);
-            fDeviceSpacePath.get()->setFillType(SkPath::kInverseEvenOdd_FillType);
+            fDeviceSpacePath.get()->setFillType(SkPathFillType::kInverseEvenOdd);
             fDeviceSpaceType = DeviceSpaceType::kPath;
             break;
         case DeviceSpaceType::kPath:
@@ -752,7 +752,7 @@
     bool isAA = false;
 
     path->reset();
-    path->setFillType(SkPath::kInverseEvenOdd_FillType);
+    path->setFillType(SkPathFillType::kInverseEvenOdd);
 
     SkClipStack::Iter iter(*this, SkClipStack::Iter::kBottom_IterStart);
     while (const SkClipStack::Element* element = iter.next()) {
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 0847ea5..d5dd2e2 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -107,8 +107,8 @@
     }
 
     ~SkAutoPathBoundsUpdate() {
-        fPath->setConvexity(fDegenerate ? SkPath::kConvex_Convexity
-                                        : SkPath::kUnknown_Convexity);
+        fPath->setConvexity(fDegenerate ? SkPathConvexityType::kConvex
+                                        : SkPathConvexityType::kUnknown);
         if ((fEmpty || fHasValidBounds) && fRect.isFinite()) {
             fPath->setBounds(fRect);
         }
@@ -151,8 +151,8 @@
 void SkPath::resetFields() {
     //fPathRef is assumed to have been emptied by the caller.
     fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE;
-    fFillType = kWinding_FillType;
-    this->setConvexity(kUnknown_Convexity);
+    fFillType = static_cast<uint8_t>(SkPathFillType::kWinding);
+    this->setConvexity(SkPathConvexityType::kUnknown);
     this->setFirstDirection(SkPathPriv::kUnknown_FirstDirection);
 
     // We don't touch Android's fSourcePath.  It's used to track texture garbage collection, so we
@@ -212,7 +212,7 @@
         that.fIsVolatile = iv;
 
         // Non-atomic swaps of atomic values.
-        Convexity c = this->getConvexityOrUnknown();
+        SkPathConvexityType c = (SkPathConvexityType)this->getConvexityOrUnknown();
         this->setConvexity(that.getConvexityOrUnknown());
         that.setConvexity(c);
 
@@ -271,7 +271,7 @@
 
 bool SkPath::conservativelyContainsRect(const SkRect& rect) const {
     // This only handles non-degenerate convex paths currently.
-    if (kConvex_Convexity != this->getConvexity()) {
+    if (SkPathConvexityType::kConvex != (SkPathConvexityType)this->getConvexity()) {
         return false;
     }
 
@@ -363,6 +363,10 @@
     return genID;
 }
 
+bool SkPath::isInverseFillType() const {
+    return SkPathPriv::IsInverseFillType((SkPathFillType)this->getFillType());
+}
+
 SkPath& SkPath::reset() {
     SkDEBUGCODE(this->validate();)
 
@@ -455,7 +459,7 @@
     return ((0 != dx) << 0) | ((dx > 0 || dy > 0) << 1);
 }
 
-bool SkPath::isRect(SkRect* rect, bool* isClosed, Direction* direction) const {
+bool SkPath::isRect(SkRect* rect, bool* isClosed, SkPathDirection* direction) const {
     SkDEBUGCODE(this->validate();)
     int currVerb = 0;
     const SkPoint* pts = fPathRef->points();
@@ -559,13 +563,13 @@
 }
 
 // This is the public-facing non-const setConvexity().
-void SkPath::setConvexity(Convexity c) {
-    fConvexity.store(c, std::memory_order_relaxed);
+void SkPath::setConvexity(SkPathConvexityType c) {
+    fConvexity.store(static_cast<uint8_t>(c), std::memory_order_relaxed);
 }
 
 // Const hooks for working with fConvexity and fFirstDirection from const methods.
-void SkPath::setConvexity(Convexity c) const {
-    fConvexity.store(c, std::memory_order_relaxed);
+void SkPath::setConvexity(SkPathConvexityType c) const {
+    fConvexity.store(static_cast<uint8_t>(c), std::memory_order_relaxed);
 }
 void SkPath::setFirstDirection(uint8_t d) const {
     fFirstDirection.store(d, std::memory_order_relaxed);
@@ -579,7 +583,7 @@
 
 #define DIRTY_AFTER_EDIT                                               \
     do {                                                               \
-        this->setConvexity(kUnknown_Convexity);                        \
+        this->setConvexity(SkPathConvexityType::kUnknown);             \
         this->setFirstDirection(SkPathPriv::kUnknown_FirstDirection);  \
     } while (0)
 
@@ -760,21 +764,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static void assert_known_direction(int dir) {
-    SkASSERT(SkPath::kCW_Direction == dir || SkPath::kCCW_Direction == dir);
-}
-
-SkPath& SkPath::addRect(const SkRect& rect, Direction dir) {
+SkPath& SkPath::addRect(const SkRect& rect, SkPathDirection dir) {
     return this->addRect(rect, dir, 0);
 }
 
-SkPath& SkPath::addRect(SkScalar left, SkScalar top, SkScalar right,
-                     SkScalar bottom, Direction dir) {
-    return this->addRect(SkRect::MakeLTRB(left, top, right, bottom), dir, 0);
-}
-
-SkPath& SkPath::addRect(const SkRect &rect, Direction dir, unsigned startIndex) {
-    assert_known_direction(dir);
+SkPath& SkPath::addRect(const SkRect &rect, SkPathDirection dir, unsigned startIndex) {
     this->setFirstDirection(this->hasOnlyMoveTos() ? (SkPathPriv::FirstDirection)dir
                                                    : SkPathPriv::kUnknown_FirstDirection);
     SkAutoDisableDirectionCheck addc(this);
@@ -902,21 +896,12 @@
     return count;
 }
 
-SkPath& SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[],
-                          Direction dir) {
-    SkRRect rrect;
-    rrect.setRectRadii(rect, (const SkVector*) radii);
-    return this->addRRect(rrect, dir);
-}
-
-SkPath& SkPath::addRRect(const SkRRect& rrect, Direction dir) {
+SkPath& SkPath::addRRect(const SkRRect& rrect, SkPathDirection dir) {
     // legacy start indices: 6 (CW) and 7(CCW)
-    return this->addRRect(rrect, dir, dir == kCW_Direction ? 6 : 7);
+    return this->addRRect(rrect, dir, dir == SkPathDirection::kCW ? 6 : 7);
 }
 
-SkPath& SkPath::addRRect(const SkRRect &rrect, Direction dir, unsigned startIndex) {
-    assert_known_direction(dir);
-
+SkPath& SkPath::addRRect(const SkRRect &rrect, SkPathDirection dir, unsigned startIndex) {
     bool isRRect = hasOnlyMoveTos();
     const SkRect& bounds = rrect.getBounds();
 
@@ -934,7 +919,7 @@
         SkAutoDisableDirectionCheck addc(this);
 
         // we start with a conic on odd indices when moving CW vs. even indices when moving CCW
-        const bool startsWithConic = ((startIndex & 1) == (dir == kCW_Direction));
+        const bool startsWithConic = ((startIndex & 1) == (dir == SkPathDirection::kCW));
         const SkScalar weight = SK_ScalarRoot2Over2;
 
         SkDEBUGCODE(int initialVerbCount = this->countVerbs());
@@ -946,7 +931,7 @@
         SkPath_RRectPointIterator rrectIter(rrect, dir, startIndex);
         // Corner iterator indices follow the collapsed radii model,
         // adjusted such that the start pt is "behind" the radii start pt.
-        const unsigned rectStartIndex = startIndex / 2 + (dir == kCW_Direction ? 0 : 1);
+        const unsigned rectStartIndex = startIndex / 2 + (dir == SkPathDirection::kCW ? 0 : 1);
         SkPath_RectPointIterator rectIter(bounds, dir, rectStartIndex);
 
         this->moveTo(rrectIter.current());
@@ -966,7 +951,7 @@
         this->close();
 
         SkPathRef::Editor ed(&fPathRef);
-        ed.setIsRRect(isRRect, dir, startIndex % 8);
+        ed.setIsRRect(isRRect, dir == SkPathDirection::kCCW, startIndex % 8);
 
         SkASSERT(this->countVerbs() == initialVerbCount + kVerbs);
     }
@@ -1005,27 +990,12 @@
     return true;
 }
 
-SkPath& SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
-                             Direction dir) {
-    assert_known_direction(dir);
-
-    if (rx < 0 || ry < 0) {
-        return *this;
-    }
-
-    SkRRect rrect;
-    rrect.setRectXY(rect, rx, ry);
-    return this->addRRect(rrect, dir);
-}
-
-SkPath& SkPath::addOval(const SkRect& oval, Direction dir) {
+SkPath& SkPath::addOval(const SkRect& oval, SkPathDirection dir) {
     // legacy start index: 1
     return this->addOval(oval, dir, 1);
 }
 
-SkPath& SkPath::addOval(const SkRect &oval, Direction dir, unsigned startPointIndex) {
-    assert_known_direction(dir);
-
+SkPath& SkPath::addOval(const SkRect &oval, SkPathDirection dir, unsigned startPointIndex) {
     /* If addOval() is called after previous moveTo(),
        this path is still marked as an oval. This is used to
        fit into WebKit's calling sequences.
@@ -1048,7 +1018,7 @@
 
     SkPath_OvalPointIterator ovalIter(oval, dir, startPointIndex);
     // The corner iterator pts are tracking "behind" the oval/radii pts.
-    SkPath_RectPointIterator rectIter(oval, dir, startPointIndex + (dir == kCW_Direction ? 0 : 1));
+    SkPath_RectPointIterator rectIter(oval, dir, startPointIndex + (dir == SkPathDirection::kCW ? 0 : 1));
     const SkScalar weight = SK_ScalarRoot2Over2;
 
     this->moveTo(ovalIter.current());
@@ -1061,11 +1031,11 @@
 
     SkPathRef::Editor ed(&fPathRef);
 
-    ed.setIsOval(isOval, kCCW_Direction == dir, startPointIndex % 4);
+    ed.setIsOval(isOval, SkPathDirection::kCCW == dir, startPointIndex % 4);
     return *this;
 }
 
-SkPath& SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) {
+SkPath& SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, SkPathDirection dir) {
     if (r > 0) {
         this->addOval(SkRect::MakeLTRB(x - r, y - r, x + r, y + r), dir);
     }
@@ -1145,7 +1115,7 @@
 // http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter
 // Note that arcSweep bool value is flipped from the original implementation.
 SkPath& SkPath::arcTo(SkScalar rx, SkScalar ry, SkScalar angle, SkPath::ArcSize arcLarge,
-                      SkPath::Direction arcSweep, SkScalar x, SkScalar y) {
+                      SkPathDirection arcSweep, SkScalar x, SkScalar y) {
     this->injectMoveToIfNeeded();
     SkPoint srcPts[2];
     this->getLastPt(&srcPts[0]);
@@ -1196,7 +1166,8 @@
     SkScalar scaleFactorSquared = SkTMax(1 / d - 0.25f, 0.f);
 
     SkScalar scaleFactor = SkScalarSqrt(scaleFactorSquared);
-    if (SkToBool(arcSweep) != SkToBool(arcLarge)) {  // flipped from the original implementation
+    if ((arcSweep == SkPathDirection::kCCW) != SkToBool(arcLarge)) {
+        // flipped from the original implementation
         scaleFactor = -scaleFactor;
     }
     delta.scale(scaleFactor);
@@ -1208,9 +1179,11 @@
     SkScalar theta1 = SkScalarATan2(unitPts[0].fY, unitPts[0].fX);
     SkScalar theta2 = SkScalarATan2(unitPts[1].fY, unitPts[1].fX);
     SkScalar thetaArc = theta2 - theta1;
-    if (thetaArc < 0 && !arcSweep) {  // arcSweep flipped from the original implementation
+    if (thetaArc < 0 && arcSweep == SkPathDirection::kCW) {
+        // arcSweep flipped from the original implementation
         thetaArc += SK_ScalarPI * 2;
-    } else if (thetaArc > 0 && arcSweep) {  // arcSweep flipped from the original implementation
+    } else if (thetaArc > 0 && arcSweep == SkPathDirection::kCCW) {
+        // arcSweep flipped from the original implementation
         thetaArc -= SK_ScalarPI * 2;
     }
 
@@ -1270,7 +1243,7 @@
 }
 
 SkPath& SkPath::rArcTo(SkScalar rx, SkScalar ry, SkScalar xAxisRotate, SkPath::ArcSize largeArc,
-                       SkPath::Direction sweep, SkScalar dx, SkScalar dy) {
+                       SkPathDirection sweep, SkScalar dx, SkScalar dy) {
     SkPoint currentPoint;
     this->getLastPt(&currentPoint);
     return this->arcTo(rx, ry, xAxisRotate, largeArc, sweep,
@@ -1294,7 +1267,8 @@
             // Index 1 is at startAngle == 0.
             SkScalar startIndex = std::fmod(startOver90I + 1.f, 4.f);
             startIndex = startIndex < 0 ? startIndex + 4.f : startIndex;
-            return this->addOval(oval, sweepAngle > 0 ? kCW_Direction : kCCW_Direction,
+            return this->addOval(oval,
+                                 sweepAngle > 0 ? SkPathDirection::kCW : SkPathDirection::kCCW,
                                  (unsigned) startIndex);
         }
     }
@@ -1597,7 +1571,7 @@
         matrix.mapPoints(ed.writablePoints(), ed.pathRef()->countPoints());
         dst->setFirstDirection(SkPathPriv::kUnknown_FirstDirection);
     } else {
-        Convexity convexity = this->getConvexityOrUnknown();
+        auto convexity = this->getConvexityOrUnknown();
 
         SkPathRef::CreateTransformedCopy(&dst->fPathRef, *fPathRef.get(), matrix);
 
@@ -1619,7 +1593,7 @@
         if (matrix.isScaleTranslate() && SkPathPriv::IsAxisAligned(*this)) {
             dst->setConvexity(convexity);
         } else {
-            dst->setConvexity(kUnknown_Convexity);
+            dst->setConvexity(SkPathConvexityType::kUnknown);
         }
 
         if (this->getFirstDirection() == SkPathPriv::kUnknown_FirstDirection) {
@@ -1992,7 +1966,7 @@
 struct Convexicator {
     Convexicator()
     : fPtCount(0)
-    , fConvexity(SkPath::kConvex_Convexity)
+    , fConvexity(SkPathConvexityType::kConvex)
     , fFirstDirection(SkPathPriv::kUnknown_FirstDirection)
     , fIsFinite(true)
     , fIsCurve(false)
@@ -2009,7 +1983,7 @@
         fSx = fSy = kValueNeverReturnedBySign;
     }
 
-    SkPath::Convexity getConvexity() const { return fConvexity; }
+    SkPathConvexityType getConvexity() const { return fConvexity; }
 
     /** The direction returned is only valid if the path is determined convex */
     SkPathPriv::FirstDirection getFirstDirection() const { return fFirstDirection; }
@@ -2151,7 +2125,7 @@
     SkVector            fLastVec, fFirstVec;
     int                 fPtCount;   // non-degenerate points
     DirChange           fExpectedDir;
-    SkPath::Convexity   fConvexity;
+    SkPathConvexityType fConvexity;
     SkPathPriv::FirstDirection   fFirstDirection;
     int                 fDx, fDy, fSx, fSy;
     bool                fIsFinite;
@@ -2294,7 +2268,7 @@
         return true;
     }
 
-    static SkPath::Convexity BySign(const SkPoint points[], int count) {
+    static SkPathConvexityType BySign(const SkPoint points[], int count) {
         const SkPoint* last = points + count;
         SkPoint currPt = *points++;
         SkPoint firstPt = currPt;
@@ -2308,14 +2282,14 @@
                 if (!vec.isZero()) {
                     // give up if vector construction failed
                     if (!vec.isFinite()) {
-                        return SkPath::kUnknown_Convexity;
+                        return SkPathConvexityType::kUnknown;
                     }
                     int sx = sign(vec.fX);
                     int sy = sign(vec.fY);
                     dxes += (sx != lastSx);
                     dyes += (sy != lastSy);
                     if (dxes > 3 || dyes > 3) {
-                        return SkPath::kConcave_Convexity;
+                        return SkPathConvexityType::kConcave;
                     }
                     lastSx = sx;
                     lastSy = sy;
@@ -2327,7 +2301,7 @@
             }
             points = &firstPt;
         }
-        return SkPath::kConvex_Convexity;  // that is, it may be convex, don't know yet
+        return SkPathConvexityType::kConvex;  // that is, it may be convex, don't know yet
     }
 
     bool close() {
@@ -2407,12 +2381,12 @@
     bool                fIsFinite { true };
 };
 
-SkPath::Convexity SkPath::internalGetConvexity() const {
+SkPathConvexityType SkPath::internalGetConvexity() const {
     SkPoint         pts[4];
     SkPath::Verb    verb;
     SkPath::Iter    iter(*this, true);
-    auto setComputedConvexity = [=](Convexity convexity){
-        SkASSERT(kUnknown_Convexity != convexity);
+    auto setComputedConvexity = [=](SkPathConvexityType convexity){
+        SkASSERT(SkPathConvexityType::kUnknown != convexity);
         this->setConvexity(convexity);
         return convexity;
     };
@@ -2431,15 +2405,15 @@
             ++points;
         }
         --points;
-        SkPath::Convexity convexity = Convexicator::BySign(points, (int) (last - points));
-        if (SkPath::kConcave_Convexity == convexity) {
-            return setComputedConvexity(SkPath::kConcave_Convexity);
-        } else if (SkPath::kUnknown_Convexity == convexity) {
-            return SkPath::kUnknown_Convexity;
+        SkPathConvexityType convexity = Convexicator::BySign(points, (int) (last - points));
+        if (SkPathConvexityType::kConcave == convexity) {
+            return setComputedConvexity(SkPathConvexityType::kConcave);
+        } else if (SkPathConvexityType::kUnknown == convexity) {
+            return SkPathConvexityType::kUnknown;
         }
         iter.setPath(*this, true);
     } else if (!this->isFinite()) {
-        return kUnknown_Convexity;
+        return SkPathConvexityType::kUnknown;
     }
 
     int             contourCount = 0;
@@ -2447,16 +2421,16 @@
     Convexicator    state;
     auto setFail = [=](){
         if (!state.isFinite()) {
-            return SkPath::kUnknown_Convexity;
+            return SkPathConvexityType::kUnknown;
         }
-        return setComputedConvexity(SkPath::kConcave_Convexity);
+        return setComputedConvexity(SkPathConvexityType::kConcave);
     };
 
     while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
         switch (verb) {
             case kMove_Verb:
                 if (++contourCount > 1) {
-                    return setComputedConvexity(kConcave_Convexity);
+                    return setComputedConvexity(SkPathConvexityType::kConcave);
                 }
                 state.setMovePt(pts[0]);
                 count = 0;
@@ -2480,7 +2454,7 @@
                 break;
             default:
                 SkDEBUGFAIL("bad verb");
-                return setComputedConvexity(kConcave_Convexity);
+                return setComputedConvexity(SkPathConvexityType::kConcave);
         }
         for (int i = 1; i <= count; i++) {
             if (!state.addPt(pts[i])) {
@@ -2493,16 +2467,16 @@
         if (state.getFirstDirection() == SkPathPriv::kUnknown_FirstDirection
                 && !this->getBounds().isEmpty()) {
             return setComputedConvexity(state.reversals() < 3 ?
-                    kConvex_Convexity : kConcave_Convexity);
+                                    SkPathConvexityType::kConvex : SkPathConvexityType::kConcave);
         }
         this->setFirstDirection(state.getFirstDirection());
     }
-    return setComputedConvexity(kConvex_Convexity);
+    return setComputedConvexity(SkPathConvexityType::kConvex);
 }
 
 bool SkPathPriv::IsConvex(const SkPoint points[], int count) {
-    SkPath::Convexity convexity = Convexicator::BySign(points, count);
-    if (SkPath::kConvex_Convexity != convexity) {
+    SkPathConvexityType convexity = Convexicator::BySign(points, count);
+    if (SkPathConvexityType::kConvex != convexity) {
         return false;
     }
     Convexicator state;
@@ -2701,7 +2675,7 @@
 
     // We don't want to pay the cost for computing convexity if it is unknown,
     // so we call getConvexityOrUnknown() instead of isConvex().
-    if (path.getConvexityOrUnknown() == SkPath::kConvex_Convexity) {
+    if ((SkPathConvexityType)path.getConvexityOrUnknown() == SkPathConvexityType::kConvex) {
         SkASSERT(path.getFirstDirection() == kUnknown_FirstDirection);
         *dir = static_cast<FirstDirection>(path.getFirstDirection());
         return false;
@@ -3224,8 +3198,8 @@
                 break;
        }
     } while (!done);
-    bool evenOddFill = SkPath::kEvenOdd_FillType == this->getFillType()
-            || SkPath::kInverseEvenOdd_FillType == this->getFillType();
+    bool evenOddFill = SkPathFillType::kEvenOdd == (SkPathFillType)this->getFillType()
+             || SkPathFillType::kInverseEvenOdd == (SkPathFillType)this->getFillType();
     if (evenOddFill) {
         w &= 1;
     }
@@ -3294,7 +3268,7 @@
     return conic.chopIntoQuadsPOW2(pts, pow2);
 }
 
-bool SkPathPriv::IsSimpleClosedRect(const SkPath& path, SkRect* rect, SkPath::Direction* direction,
+bool SkPathPriv::IsSimpleClosedRect(const SkPath& path, SkRect* rect, SkPathDirection* direction,
                                     unsigned* start) {
     if (path.getSegmentMasks() != SkPath::kLine_SegmentMask) {
         return false;
@@ -3364,22 +3338,22 @@
     switch (sortFlags) {
         case 0b00:
             rect->setLTRB(rectPts[0].fX, rectPts[0].fY, rectPts[2].fX, rectPts[2].fY);
-            *direction = vec03IsVertical ? SkPath::kCW_Direction : SkPath::kCCW_Direction;
+            *direction = vec03IsVertical ? SkPathDirection::kCW : SkPathDirection::kCCW;
             *start = 0;
             break;
         case 0b01:
             rect->setLTRB(rectPts[2].fX, rectPts[0].fY, rectPts[0].fX, rectPts[2].fY);
-            *direction = vec03IsVertical ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+            *direction = vec03IsVertical ? SkPathDirection::kCCW : SkPathDirection::kCW;
             *start = 1;
             break;
         case 0b10:
             rect->setLTRB(rectPts[0].fX, rectPts[2].fY, rectPts[2].fX, rectPts[0].fY);
-            *direction = vec03IsVertical ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+            *direction = vec03IsVertical ? SkPathDirection::kCCW : SkPathDirection::kCW;
             *start = 3;
             break;
         case 0b11:
             rect->setLTRB(rectPts[2].fX, rectPts[2].fY, rectPts[0].fX, rectPts[0].fY);
-            *direction = vec03IsVertical ? SkPath::kCW_Direction : SkPath::kCCW_Direction;
+            *direction = vec03IsVertical ? SkPathDirection::kCW : SkPathDirection::kCCW;
             *start = 2;
             break;
     }
@@ -3407,7 +3381,7 @@
 
     path->reset();
     path->setIsVolatile(true);
-    path->setFillType(SkPath::kWinding_FillType);
+    path->setFillType(SkPathFillType::kWinding);
     if (isFillNoPathEffect && SkScalarAbs(sweepAngle) >= 360.f) {
         path->addOval(oval);
         SkASSERT(path->isConvex() && DrawArcIsConvex(sweepAngle, false, isFillNoPathEffect));
@@ -3441,7 +3415,7 @@
     if (useCenter) {
         path->close();
     }
-    path->setConvexity(convex ? SkPath::kConvex_Convexity : SkPath::kConcave_Convexity);
+    path->setConvexity(convex ? SkPathConvexityType::kConvex : SkPathConvexityType::kConcave);
     path->setFirstDirection(firstDir);
 }
 
@@ -3560,7 +3534,7 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
 bool SkPathPriv::IsRectContour(const SkPath& path, bool allowPartial, int* currVerb,
-                               const SkPoint** ptsPtr, bool* isClosed, SkPath::Direction* direction,
+                               const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
                                SkRect* rect) {
     int corners = 0;
     SkPoint closeXY;  // used to determine if final line falls on a diagonal
@@ -3693,17 +3667,17 @@
     }
     if (direction) {
         *direction = directions[0] == ((directions[1] + 1) & 3) ?
-                     SkPath::kCW_Direction : SkPath::kCCW_Direction;
+                     SkPathDirection::kCW : SkPathDirection::kCCW;
     }
     return true;
 }
 
 
-bool SkPathPriv::IsNestedFillRects(const SkPath& path, SkRect rects[2], SkPath::Direction dirs[2]) {
+bool SkPathPriv::IsNestedFillRects(const SkPath& path, SkRect rects[2], SkPathDirection dirs[2]) {
     SkDEBUGCODE(path.validate();)
     int currVerb = 0;
     const SkPoint* pts = path.fPathRef->points();
-    SkPath::Direction testDirs[2];
+    SkPathDirection testDirs[2];
     SkRect testRects[2];
     if (!IsRectContour(path, true, &currVerb, &pts, nullptr, &testDirs[0], &testRects[0])) {
         return false;
diff --git a/src/core/SkPathMakers.h b/src/core/SkPathMakers.h
index a4ef7e1..8e668e5 100644
--- a/src/core/SkPathMakers.h
+++ b/src/core/SkPathMakers.h
@@ -8,15 +8,15 @@
 #ifndef SkPathMakers_DEFINED
 #define SkPathMakers_DEFINED
 
-#include "include/core/SkPath.h"    // just for direction
+#include "include/core/SkPathTypes.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkRRect.h"
 
 template <unsigned N> class SkPath_PointIterator {
 public:
-    SkPath_PointIterator(SkPath::Direction dir, unsigned startIndex)
+    SkPath_PointIterator(SkPathDirection dir, unsigned startIndex)
     : fCurrent(startIndex % N)
-    , fAdvance(dir == SkPath::kCW_Direction ? 1 : N - 1) { }
+    , fAdvance(dir == SkPathDirection::kCW ? 1 : N - 1) { }
 
     const SkPoint& current() const {
         SkASSERT(fCurrent < N);
@@ -38,7 +38,7 @@
 
 class SkPath_RectPointIterator : public SkPath_PointIterator<4> {
 public:
-    SkPath_RectPointIterator(const SkRect& rect, SkPath::Direction dir, unsigned startIndex)
+    SkPath_RectPointIterator(const SkRect& rect, SkPathDirection dir, unsigned startIndex)
         : SkPath_PointIterator(dir, startIndex) {
 
         fPts[0] = SkPoint::Make(rect.fLeft, rect.fTop);
@@ -50,7 +50,7 @@
 
 class SkPath_OvalPointIterator : public SkPath_PointIterator<4> {
 public:
-    SkPath_OvalPointIterator(const SkRect& oval, SkPath::Direction dir, unsigned startIndex)
+    SkPath_OvalPointIterator(const SkRect& oval, SkPathDirection dir, unsigned startIndex)
         : SkPath_PointIterator(dir, startIndex) {
 
         const SkScalar cx = oval.centerX();
@@ -65,7 +65,7 @@
 
 class SkPath_RRectPointIterator : public SkPath_PointIterator<8> {
 public:
-    SkPath_RRectPointIterator(const SkRRect& rrect, SkPath::Direction dir, unsigned startIndex)
+    SkPath_RRectPointIterator(const SkRRect& rrect, SkPathDirection dir, unsigned startIndex)
         : SkPath_PointIterator(dir, startIndex) {
 
         const SkRect& bounds = rrect.getBounds();
diff --git a/src/core/SkPathPriv.h b/src/core/SkPathPriv.h
index 7fc5966..c3f571e 100644
--- a/src/core/SkPathPriv.h
+++ b/src/core/SkPathPriv.h
@@ -10,6 +10,11 @@
 
 #include "include/core/SkPath.h"
 
+static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
+static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch");
+static_assert(2 == static_cast<int>(SkPathFillType::kInverseWinding), "fill_type_mismatch");
+static_assert(3 == static_cast<int>(SkPathFillType::kInverseEvenOdd), "fill_type_mismatch");
+
 class SkPathPriv {
 public:
 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@@ -24,7 +29,7 @@
         kUnknown_FirstDirection,
     };
 
-    static FirstDirection AsFirstDirection(SkPath::Direction dir) {
+    static FirstDirection AsFirstDirection(SkPathDirection dir) {
         // since we agree numerically for the values in Direction, we can just cast.
         return (FirstDirection)dir;
     }
@@ -96,7 +101,7 @@
      * followed by four lines or a move followed by 3 lines and a close. None of the parameters are
      * optional. This does not permit degenerate line or point rectangles.
      */
-    static bool IsSimpleClosedRect(const SkPath& path, SkRect* rect, SkPath::Direction* direction,
+    static bool IsSimpleClosedRect(const SkPath& path, SkRect* rect, SkPathDirection* direction,
                                    unsigned* start);
 
     /**
@@ -192,11 +197,11 @@
      @param start  storage for start of oval; may be nullptr
      @return       true if SkPath was constructed by method that reduces to oval
      */
-    static bool IsOval(const SkPath& path, SkRect* rect, SkPath::Direction* dir, unsigned* start) {
+    static bool IsOval(const SkPath& path, SkRect* rect, SkPathDirection* dir, unsigned* start) {
         bool isCCW = false;
         bool result = path.fPathRef->isOval(rect, &isCCW, start);
         if (dir && result) {
-            *dir = isCCW ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+            *dir = isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
         }
         return result;
     }
@@ -219,12 +224,12 @@
      @param start  storage for start of SkRRect; may be nullptr
      @return       true if SkPath contains only SkRRect
      */
-    static bool IsRRect(const SkPath& path, SkRRect* rrect, SkPath::Direction* dir,
+    static bool IsRRect(const SkPath& path, SkRRect* rrect, SkPathDirection* dir,
                         unsigned* start) {
         bool isCCW = false;
         bool result = path.fPathRef->isRRect(rrect, &isCCW, start);
         if (dir && result) {
-            *dir = isCCW ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+            *dir = isCCW ? SkPathDirection::kCCW : SkPathDirection::kCW;
         }
         return result;
     }
@@ -282,7 +287,7 @@
     }
 
     static bool IsRectContour(const SkPath&, bool allowPartial, int* currVerb,
-                              const SkPoint** ptsPtr, bool* isClosed, SkPath::Direction* direction,
+                              const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
                               SkRect* rect);
 
     /** Returns true if SkPath is equivalent to nested SkRect pair when filled.
@@ -297,7 +302,22 @@
      @return      true if SkPath contains nested SkRect pair
      */
     static bool IsNestedFillRects(const SkPath&, SkRect rect[2],
-                                  SkPath::Direction dirs[2] = nullptr);
+                                  SkPathDirection dirs[2] = nullptr);
+
+    static bool IsInverseFillType(SkPathFillType fill) {
+        return (static_cast<int>(fill) & 2) != 0;
+    }
+
+    /** Returns equivalent SkPath::FillType representing SkPath fill inside its bounds.
+     .
+
+     @param fill  one of: kWinding_FillType, kEvenOdd_FillType,
+     kInverseWinding_FillType, kInverseEvenOdd_FillType
+     @return      fill, or kWinding_FillType or kEvenOdd_FillType if fill is inverted
+     */
+    static SkPathFillType ConvertToNonInverseFillType(SkPathFillType fill) {
+        return (SkPathFillType)(static_cast<int>(fill) & 1);
+    }
 };
 
 // Lightweight variant of SkPath::Iter that only returns segments (e.g. lines/conics).
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index ecfefdf..098251e 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -1391,7 +1391,7 @@
     {
         SkRect rect;
         bool isClosed;
-        SkPath::Direction dir;
+        SkPathDirection dir;
         if (src.isRect(&rect, &isClosed, &dir) && isClosed) {
             this->strokeRect(rect, dst, dir);
             // our answer should preserve the inverseness of the src
@@ -1498,15 +1498,15 @@
     }
 }
 
-static SkPath::Direction reverse_direction(SkPath::Direction dir) {
-    static const SkPath::Direction gOpposite[] = { SkPath::kCCW_Direction, SkPath::kCW_Direction };
-    return gOpposite[dir];
+static SkPathDirection reverse_direction(SkPathDirection dir) {
+    static const SkPathDirection gOpposite[] = { SkPathDirection::kCCW, SkPathDirection::kCW };
+    return gOpposite[(unsigned)dir];
 }
 
-static void addBevel(SkPath* path, const SkRect& r, const SkRect& outer, SkPath::Direction dir) {
+static void addBevel(SkPath* path, const SkRect& r, const SkRect& outer, SkPathDirection dir) {
     SkPoint pts[8];
 
-    if (SkPath::kCW_Direction == dir) {
+    if (SkPathDirection::kCW == dir) {
         pts[0].set(r.fLeft, outer.fTop);
         pts[1].set(r.fRight, outer.fTop);
         pts[2].set(outer.fRight, r.fTop);
@@ -1529,7 +1529,7 @@
 }
 
 void SkStroke::strokeRect(const SkRect& origRect, SkPath* dst,
-                          SkPath::Direction dir) const {
+                          SkPathDirection dir) const {
     SkASSERT(dst != nullptr);
     dst->reset();
 
@@ -1565,7 +1565,7 @@
             addBevel(dst, rect, r, dir);
             break;
         case SkPaint::kRound_Join:
-            dst->addRoundRect(r, radius, radius, dir);
+            dst->addRRect(SkRRect::MakeRectXY(r, radius, radius), dir);
             break;
         default:
             break;
diff --git a/src/core/SkStroke.h b/src/core/SkStroke.h
index 66edf3d..b0458d3 100644
--- a/src/core/SkStroke.h
+++ b/src/core/SkStroke.h
@@ -62,7 +62,7 @@
      *  Stroke the specified rect, winding it in the specified direction..
      */
     void    strokeRect(const SkRect& rect, SkPath* result,
-                       SkPath::Direction = SkPath::kCW_Direction) const;
+                       SkPathDirection = SkPathDirection::kCW) const;
     void    strokePath(const SkPath& path, SkPath*) const;
 
     ////////////////////////////////////////////////////////////////
diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp
index 913d851..a13fa07 100644
--- a/src/effects/SkDashPathEffect.cpp
+++ b/src/effects/SkDashPathEffect.cpp
@@ -297,8 +297,8 @@
                     }
                     if (clampedInitialDashLength < fIntervals[0]) {
                         // This one will not be like the others
-                        results->fFirst.addRect(x - halfWidth, y - halfHeight,
-                                                x + halfWidth, y + halfHeight);
+                        results->fFirst.addRect({x - halfWidth, y - halfHeight,
+                                                 x + halfWidth, y + halfHeight});
                     } else {
                         SkASSERT(curPt < results->fNumPoints);
                         results->fPoints[curPt].set(x, y);
@@ -346,8 +346,7 @@
                 halfWidth = SkScalarHalf(rec.getWidth());
                 halfHeight = SkScalarHalf(temp);
             }
-            results->fLast.addRect(x - halfWidth, y - halfHeight,
-                                   x + halfWidth, y + halfHeight);
+            results->fLast.addRect({x - halfWidth, y - halfHeight, x + halfWidth, y + halfHeight});
         }
 
         SkASSERT(curPt == results->fNumPoints);
diff --git a/src/gpu/GrDistanceFieldGenFromVector.cpp b/src/gpu/GrDistanceFieldGenFromVector.cpp
index 29aa16d..fc505e5 100644
--- a/src/gpu/GrDistanceFieldGenFromVector.cpp
+++ b/src/gpu/GrDistanceFieldGenFromVector.cpp
@@ -763,7 +763,7 @@
         workingPath = path;
     }
 
-    if (!IsDistanceFieldSupportedFillType(workingPath.getFillType())) {
+    if (!IsDistanceFieldSupportedFillType((SkPathFillType)workingPath.getFillType())) {
         return false;
     }
 
@@ -829,15 +829,19 @@
                 kOutside = 1
             } dfSign;
 
-            if (workingPath.getFillType() == SkPath::kWinding_FillType) {
-                dfSign = windingNumber ? kInside : kOutside;
-            } else if (workingPath.getFillType() == SkPath::kInverseWinding_FillType) {
-                dfSign = windingNumber ? kOutside : kInside;
-            } else if (workingPath.getFillType() == SkPath::kEvenOdd_FillType) {
-                dfSign = (windingNumber % 2) ? kInside : kOutside;
-            } else {
-                SkASSERT(workingPath.getFillType() == SkPath::kInverseEvenOdd_FillType);
-                dfSign = (windingNumber % 2) ? kOutside : kInside;
+            switch ((SkPathFillType)workingPath.getFillType()) {
+                case SkPathFillType::kWinding:
+                    dfSign = windingNumber ? kInside : kOutside;
+                    break;
+                case SkPathFillType::kInverseWinding:
+                    dfSign = windingNumber ? kOutside : kInside;
+                    break;
+                case SkPathFillType::kEvenOdd:
+                    dfSign = (windingNumber % 2) ? kInside : kOutside;
+                    break;
+                case SkPathFillType::kInverseEvenOdd:
+                    dfSign = (windingNumber % 2) ? kOutside : kInside;
+                    break;
             }
 
             // The winding number at the end of a scanline should be zero.
diff --git a/src/gpu/GrDistanceFieldGenFromVector.h b/src/gpu/GrDistanceFieldGenFromVector.h
index 8e8d1b3..0362166 100644
--- a/src/gpu/GrDistanceFieldGenFromVector.h
+++ b/src/gpu/GrDistanceFieldGenFromVector.h
@@ -30,10 +30,10 @@
                                      const SkPath& path, const SkMatrix& viewMatrix,
                                      int width, int height, size_t rowBytes);
 
-inline bool IsDistanceFieldSupportedFillType(SkPath::FillType fFillType)
+inline bool IsDistanceFieldSupportedFillType(SkPathFillType fFillType)
 {
-    return (SkPath::kEvenOdd_FillType == fFillType ||
-            SkPath::kInverseEvenOdd_FillType == fFillType);
+    return (SkPathFillType::kEvenOdd == fFillType ||
+            SkPathFillType::kInverseEvenOdd == fFillType);
 }
 
 #endif
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index dd3472c..edb7611 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1493,7 +1493,7 @@
     assert_alive(paint);
     this->drawShapeUsingPathRenderer(
             clip, std::move(paint), aa, viewMatrix,
-            GrShape(SkRRect::MakeOval(oval), SkPath::kCW_Direction, 2, false, style));
+            GrShape(SkRRect::MakeOval(oval), SkPathDirection::kCW, 2, false, style));
 }
 
 void GrRenderTargetContext::drawArc(const GrClip& clip,
diff --git a/src/gpu/GrTestUtils.cpp b/src/gpu/GrTestUtils.cpp
index c6e95a3..cabac43 100644
--- a/src/gpu/GrTestUtils.cpp
+++ b/src/gpu/GrTestUtils.cpp
@@ -232,7 +232,7 @@
         gPath[2].lineTo(-50.0f,  31.0f);
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(gPath); i++) {
-            SkASSERT(SkPath::kConvex_Convexity == gPath[i].getConvexity());
+            SkASSERT(SkPathConvexityType::kConvex == (SkPathConvexityType)gPath[i].getConvexity());
         }
     }
 
diff --git a/src/gpu/ccpr/GrCCFiller.cpp b/src/gpu/ccpr/GrCCFiller.cpp
index 9c09b4a..9a6c9dd 100644
--- a/src/gpu/ccpr/GrCCFiller.cpp
+++ b/src/gpu/ccpr/GrCCFiller.cpp
@@ -135,7 +135,7 @@
         // We use "winding" fill type right now because we are producing a coverage count, and must
         // fill in every region that has non-zero wind. The path processor will convert coverage
         // count to the appropriate fill type later.
-        fan.setFillType(SkPath::kWinding_FillType);
+        fan.setFillType(SkPathFillType::kWinding);
     } else {
         // When counting winding numbers in the stencil buffer, it works to just tessellate the
         // Redbook fan with the same fill type as the path.
diff --git a/src/gpu/geometry/GrShape.cpp b/src/gpu/geometry/GrShape.cpp
index 4fc3472..a510a19 100644
--- a/src/gpu/geometry/GrShape.cpp
+++ b/src/gpu/geometry/GrShape.cpp
@@ -201,7 +201,7 @@
     const int conicWeightCnt = SkPathPriv::ConicWeightCnt(path);
     SkASSERT(verbCnt <= GrShape::kMaxKeyFromDataVerbCnt);
     SkASSERT(pointCnt && verbCnt);
-    *key++ = path.getFillType();
+    *key++ = (uint32_t)path.getFillType();
     *key++ = verbCnt;
     memcpy(key, SkPathPriv::VerbData(path), verbCnt * sizeof(uint8_t));
     int verbKeySize = SkAlign4(verbCnt);
@@ -273,7 +273,7 @@
             case Type::kRRect:
                 fRRectData.fRRect.writeToMemory(key);
                 key += SkRRect::kSizeInMemory / sizeof(uint32_t);
-                *key = (fRRectData.fDir == SkPath::kCCW_Direction) ? (1 << 31) : 0;
+                *key = (fRRectData.fDir == SkPathDirection::kCCW) ? (1 << 31) : 0;
                 *key |= fRRectData.fInverted ? (1 << 30) : 0;
                 *key++ |= fRRectData.fStart;
                 SkASSERT(fRRectData.fStart < 8);
@@ -297,7 +297,7 @@
                 *key++ = fPathData.fGenID;
                 // We could canonicalize the fill rule for paths that don't differentiate between
                 // even/odd or winding fill (e.g. convex).
-                *key++ = this->path().getFillType();
+                *key++ = (uint32_t)this->path().getFillType();
                 break;
             }
         }
@@ -507,7 +507,7 @@
 void GrShape::attemptToSimplifyPath() {
     SkRect rect;
     SkRRect rrect;
-    SkPath::Direction rrectDir;
+    SkPathDirection rrectDir;
     unsigned rrectStart;
     bool inverted = this->path().isInverseFillType();
     SkPoint pts[2];
diff --git a/src/gpu/geometry/GrShape.h b/src/gpu/geometry/GrShape.h
index 37f38f8..8771c94 100644
--- a/src/gpu/geometry/GrShape.h
+++ b/src/gpu/geometry/GrShape.h
@@ -61,7 +61,7 @@
         this->attemptToSimplifyRRect();
     }
 
-    GrShape(const SkRRect& rrect, SkPath::Direction dir, unsigned start, bool inverted,
+    GrShape(const SkRRect& rrect, SkPathDirection dir, unsigned start, bool inverted,
             const GrStyle& style)
         : fStyle(style) {
         this->initType(Type::kRRect);
@@ -160,7 +160,7 @@
     }
 
     /** Returns the unstyled geometry as a rrect if possible. */
-    bool asRRect(SkRRect* rrect, SkPath::Direction* dir, unsigned* start, bool* inverted) const {
+    bool asRRect(SkRRect* rrect, SkPathDirection* dir, unsigned* start, bool* inverted) const {
         if (Type::kRRect != fType) {
             return false;
         }
@@ -255,12 +255,12 @@
             return false;
         }
 
-        SkPath::Direction dirs[2];
+        SkPathDirection dirs[2];
         if (!SkPathPriv::IsNestedFillRects(this->path(), rects, dirs)) {
             return false;
         }
 
-        if (SkPath::kWinding_FillType == this->path().getFillType() && dirs[0] == dirs[1]) {
+        if (SkPathFillType::kWinding == (SkPathFillType)this->path().getFillType() && dirs[0] == dirs[1]) {
             // The two rects need to be wound opposite to each other
             return false;
         }
@@ -550,15 +550,15 @@
     const SkPath* originalPathForListeners() const;
 
     // Defaults to use when there is no distinction between even/odd and winding fills.
-    static constexpr SkPath::FillType kDefaultPathFillType = SkPath::kEvenOdd_FillType;
-    static constexpr SkPath::FillType kDefaultPathInverseFillType =
-            SkPath::kInverseEvenOdd_FillType;
+    static constexpr SkPathFillType kDefaultPathFillType = SkPathFillType::kEvenOdd;
+    static constexpr SkPathFillType kDefaultPathInverseFillType =
+            SkPathFillType::kInverseEvenOdd;
 
-    static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction;
+    static constexpr SkPathDirection kDefaultRRectDir = SkPathDirection::kCW;
     static constexpr unsigned kDefaultRRectStart = 0;
 
     static unsigned DefaultRectDirAndStartIndex(const SkRect& rect, bool hasPathEffect,
-                                                SkPath::Direction* dir) {
+                                                SkPathDirection* dir) {
         *dir = kDefaultRRectDir;
         // This comes from SkPath's interface. The default for adding a SkRect is counter clockwise
         // beginning at index 0 (which happens to correspond to rrect index 0 or 7).
@@ -575,11 +575,11 @@
             // 0 becomes start index 2 and times 2 to convert from rect the rrect indices.
             return 2 * 2;
         } else if (swapX) {
-            *dir = SkPath::kCCW_Direction;
+            *dir = SkPathDirection::kCCW;
             // 0 becomes start index 1 and times 2 to convert from rect the rrect indices.
             return 2 * 1;
         } else if (swapY) {
-            *dir = SkPath::kCCW_Direction;
+            *dir = SkPathDirection::kCCW;
             // 0 becomes start index 3 and times 2 to convert from rect the rrect indices.
             return 2 * 3;
         }
@@ -587,7 +587,7 @@
     }
 
     static unsigned DefaultRRectDirAndStartIndex(const SkRRect& rrect, bool hasPathEffect,
-                                                 SkPath::Direction* dir) {
+                                                 SkPathDirection* dir) {
         // This comes from SkPath's interface. The default for adding a SkRRect to a path is
         // clockwise beginning at starting index 6.
         static constexpr unsigned kPathRRectStartIdx = 6;
@@ -602,7 +602,7 @@
     union {
         struct {
             SkRRect fRRect;
-            SkPath::Direction fDir;
+            SkPathDirection fDir;
             unsigned fStart;
             bool fInverted;
         } fRRectData;
diff --git a/src/gpu/ops/GrAAConvexTessellator.cpp b/src/gpu/ops/GrAAConvexTessellator.cpp
index 9952491..9468692 100644
--- a/src/gpu/ops/GrAAConvexTessellator.cpp
+++ b/src/gpu/ops/GrAAConvexTessellator.cpp
@@ -369,7 +369,7 @@
 }
 
 bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& path) {
-    SkASSERT(SkPath::kConvex_Convexity == path.getConvexity());
+    SkASSERT(SkPathConvexityType::kConvex == (SkPathConvexityType)path.getConvexity());
 
     SkRect bounds = path.getBounds();
     m.mapRect(&bounds);
diff --git a/src/pathops/SkOpBuilder.cpp b/src/pathops/SkOpBuilder.cpp
index 9dac160..bada1c4 100644
--- a/src/pathops/SkOpBuilder.cpp
+++ b/src/pathops/SkOpBuilder.cpp
@@ -36,11 +36,11 @@
 }
 
 bool SkOpBuilder::FixWinding(SkPath* path) {
-    SkPath::FillType fillType = path->getFillType();
-    if (fillType == SkPath::kInverseEvenOdd_FillType) {
-        fillType = SkPath::kInverseWinding_FillType;
-    } else if (fillType == SkPath::kEvenOdd_FillType) {
-        fillType = SkPath::kWinding_FillType;
+    SkPathFillType fillType = (SkPathFillType)path->getFillType();
+    if (fillType == SkPathFillType::kInverseEvenOdd) {
+        fillType = SkPathFillType::kInverseWinding;
+    } else if (fillType == SkPathFillType::kEvenOdd) {
+        fillType = SkPathFillType::kWinding;
     }
     SkPathPriv::FirstDirection dir;
     if (one_contour(*path) && SkPathPriv::CheapComputeFirstDirection(*path, &dir)) {
diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp
index 3efb0e0..7e97c03 100644
--- a/src/pathops/SkOpEdgeBuilder.cpp
+++ b/src/pathops/SkOpEdgeBuilder.cpp
@@ -10,7 +10,7 @@
 
 void SkOpEdgeBuilder::init() {
     fOperand = false;
-    fXorMask[0] = fXorMask[1] = (fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
+    fXorMask[0] = fXorMask[1] = ((int)fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
             : kWinding_PathOpsMask;
     fUnparseable = false;
     fSecondHalf = preFetch();
@@ -40,7 +40,7 @@
     SkASSERT(fPathVerbs.count() > 0 && fPathVerbs.end()[-1] == SkPath::kDone_Verb);
     fPathVerbs.pop();
     fPath = &path;
-    fXorMask[1] = (fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
+    fXorMask[1] = ((int)fPath->getFillType() & 1) ? kEvenOdd_PathOpsMask
             : kWinding_PathOpsMask;
     preFetch();
 }
diff --git a/src/pathops/SkPathOpsAsWinding.cpp b/src/pathops/SkPathOpsAsWinding.cpp
index 80e52be..c415087 100644
--- a/src/pathops/SkPathOpsAsWinding.cpp
+++ b/src/pathops/SkPathOpsAsWinding.cpp
@@ -367,7 +367,7 @@
     const SkPath& fPath;
 };
 
-static bool set_result_path(SkPath* result, const SkPath& path, SkPath::FillType fillType) {
+static bool set_result_path(SkPath* result, const SkPath& path, SkPathFillType fillType) {
     *result = path;
     result->setFillType(fillType);
     return true;
@@ -377,13 +377,13 @@
     if (!path.isFinite()) {
         return false;
     }
-    SkPath::FillType fillType = path.getFillType();
-    if (fillType == SkPath::kWinding_FillType
-            || fillType == SkPath::kInverseWinding_FillType ) {
+    SkPathFillType fillType = (SkPathFillType)path.getFillType();
+    if (fillType == SkPathFillType::kWinding
+            || fillType == SkPathFillType::kInverseWinding ) {
         return set_result_path(result, path, fillType);
     }
-    fillType = path.isInverseFillType() ? SkPath::kInverseWinding_FillType :
-            SkPath::kWinding_FillType;
+    fillType = path.isInverseFillType() ? SkPathFillType::kInverseWinding :
+            SkPathFillType::kWinding;
     if (path.isEmpty() || path.isConvex()) {
         return set_result_path(result, path, fillType);
     }
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index 7ee44de..367de68 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -2927,12 +2927,12 @@
         return;
     }
 #endif
-    SkPath::FillType fillType = path.getFillType();
-    SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInverseEvenOdd_FillType);
+    SkPathFillType fillType = (SkPathFillType)path.getFillType();
+    SkASSERT(fillType >= SkPathFillType::kWinding && fillType <= SkPathFillType::kInverseEvenOdd);
     if (includeDeclaration) {
         SkDebugf("    SkPath %s;\n", name);
     }
-    SkDebugf("    %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]);
+    SkDebugf("    %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[(unsigned)fillType]);
     iter.setPath(path);
     showPathContours(iter, name);
 }
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
index 825ae7b1..2c89f35 100644
--- a/src/pathops/SkPathOpsOp.cpp
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -248,8 +248,8 @@
 #endif
     op = gOpInverse[op][one.isInverseFillType()][two.isInverseFillType()];
     bool inverseFill = gOutInverse[op][one.isInverseFillType()][two.isInverseFillType()];
-    SkPath::FillType fillType = inverseFill ? SkPath::kInverseEvenOdd_FillType :
-            SkPath::kEvenOdd_FillType;
+    SkPathFillType fillType = inverseFill ? SkPathFillType::kInverseEvenOdd :
+            SkPathFillType::kEvenOdd;
     SkRect rect1, rect2;
     if (kIntersect_SkPathOp == op && one.isRect(&rect1) && two.isRect(&rect2)) {
         result->reset();
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
index f079b50..6c522f4 100644
--- a/src/pathops/SkPathOpsSimplify.cpp
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -140,8 +140,8 @@
 bool SimplifyDebug(const SkPath& path, SkPath* result
         SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) {
     // returns 1 for evenodd, -1 for winding, regardless of inverse-ness
-    SkPath::FillType fillType = path.isInverseFillType() ? SkPath::kInverseEvenOdd_FillType
-            : SkPath::kEvenOdd_FillType;
+    SkPathFillType fillType = path.isInverseFillType() ? SkPathFillType::kInverseEvenOdd
+            : SkPathFillType::kEvenOdd;
     if (path.isConvex()) {
         if (result != &path) {
             *result = path;
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 3ed6f797..1b98c14 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -511,7 +511,8 @@
             maskDevice->makeFormXObjectFromDevice(dstMaskBounds, true), false,
             SkPDFGraphicState::kLuminosity_SMaskMode, fDocument), content.stream());
     SkPDFUtils::AppendRectangle(SkRect::Make(dstMaskBounds), content.stream());
-    SkPDFUtils::PaintPath(SkPaint::kFill_Style, path.getFillType(), content.stream());
+    SkPDFUtils::PaintPath(SkPaint::kFill_Style, (SkPathFillType)path.getFillType(),
+                          content.stream());
     this->clearMaskOnGraphicState(content.stream());
 }
 
@@ -598,7 +599,8 @@
             paint->getStrokeCap() != SkPaint::kSquare_Cap);
     SkPDFUtils::EmitPath(*pathPtr, paint->getStyle(), consumeDegeratePathSegments, content.stream(),
                          tolerance);
-    SkPDFUtils::PaintPath(paint->getStyle(), pathPtr->getFillType(), content.stream());
+    SkPDFUtils::PaintPath(paint->getStyle(), (SkPathFillType)pathPtr->getFillType(),
+                          content.stream());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1568,7 +1570,7 @@
                 maskDevice->makeFormXObjectFromDevice(maskDeviceBounds, true), false,
                 SkPDFGraphicState::kLuminosity_SMaskMode, fDocument), content.stream());
         SkPDFUtils::AppendRectangle(SkRect::Make(this->size()), content.stream());
-        SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPath::kWinding_FillType, content.stream());
+        SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPathFillType::kWinding, content.stream());
         this->clearMaskOnGraphicState(content.stream());
         return;
     }
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index ba79a15..ff8a61e 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -573,7 +573,8 @@
             if (path && !path->isEmpty()) {
                 setGlyphWidthAndBoundingBox(glyph->advanceX(), glyphBBox, &content);
                 SkPDFUtils::EmitPath(*path, SkPaint::kFill_Style, &content);
-                SkPDFUtils::PaintPath(SkPaint::kFill_Style, path->getFillType(), &content);
+                SkPDFUtils::PaintPath(SkPaint::kFill_Style, (SkPathFillType)path->getFillType(),
+                                      &content);
             } else {
                 auto pimg = to_image(gID, cache.get());
                 if (!pimg.fImage) {
diff --git a/src/pdf/SkPDFGradientShader.cpp b/src/pdf/SkPDFGradientShader.cpp
index 919c07a5..ad2a65d 100644
--- a/src/pdf/SkPDFGradientShader.cpp
+++ b/src/pdf/SkPDFGradientShader.cpp
@@ -780,7 +780,7 @@
     }
     SkPDFUtils::ApplyPattern(patternIndex, &content);
     SkPDFUtils::AppendRectangle(bounds, &content);
-    SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPath::kEvenOdd_FillType, &content);
+    SkPDFUtils::PaintPath(SkPaint::kFill_Style, SkPathFillType::kEvenOdd, &content);
     return content.detachAsStream();
 }
 
diff --git a/src/pdf/SkPDFGraphicStackState.cpp b/src/pdf/SkPDFGraphicStackState.cpp
index a27170b..89aa6cf 100644
--- a/src/pdf/SkPDFGraphicStackState.cpp
+++ b/src/pdf/SkPDFGraphicStackState.cpp
@@ -104,10 +104,10 @@
 
 static void append_clip_path(const SkPath& clipPath, SkWStream* wStream) {
     SkPDFUtils::EmitPath(clipPath, SkPaint::kFill_Style, wStream);
-    SkPath::FillType clipFill = clipPath.getFillType();
-    NOT_IMPLEMENTED(clipFill == SkPath::kInverseEvenOdd_FillType, false);
-    NOT_IMPLEMENTED(clipFill == SkPath::kInverseWinding_FillType, false);
-    if (clipFill == SkPath::kEvenOdd_FillType) {
+    SkPathFillType clipFill = (SkPathFillType)clipPath.getFillType();
+    NOT_IMPLEMENTED(clipFill == SkPathFillType::kInverseEvenOdd, false);
+    NOT_IMPLEMENTED(clipFill == SkPathFillType::kInverseWinding, false);
+    if (clipFill == SkPathFillType::kEvenOdd) {
         wStream->writeText("W* n\n");
     } else {
         wStream->writeText("W n\n");
diff --git a/src/pdf/SkPDFUtils.cpp b/src/pdf/SkPDFUtils.cpp
index 9beedfb..a29cee7 100644
--- a/src/pdf/SkPDFUtils.cpp
+++ b/src/pdf/SkPDFUtils.cpp
@@ -213,7 +213,7 @@
     content->writeText("h\n");
 }
 
-void SkPDFUtils::PaintPath(SkPaint::Style style, SkPath::FillType fill,
+void SkPDFUtils::PaintPath(SkPaint::Style style, SkPathFillType fill,
                            SkWStream* content) {
     if (style == SkPaint::kFill_Style) {
         content->writeText("f");
@@ -224,9 +224,9 @@
     }
 
     if (style != SkPaint::kStroke_Style) {
-        NOT_IMPLEMENTED(fill == SkPath::kInverseEvenOdd_FillType, false);
-        NOT_IMPLEMENTED(fill == SkPath::kInverseWinding_FillType, false);
-        if (fill == SkPath::kEvenOdd_FillType) {
+        NOT_IMPLEMENTED(fill == SkPathFillType::kInverseEvenOdd, false);
+        NOT_IMPLEMENTED(fill == SkPathFillType::kInverseWinding, false);
+        if (fill == SkPathFillType::kEvenOdd) {
             content->writeText("*");
         }
     }
@@ -235,7 +235,7 @@
 
 void SkPDFUtils::StrokePath(SkWStream* content) {
     SkPDFUtils::PaintPath(
-        SkPaint::kStroke_Style, SkPath::kWinding_FillType, content);
+        SkPaint::kStroke_Style, SkPathFillType::kWinding, content);
 }
 
 void SkPDFUtils::ApplyGraphicState(int objectIndex, SkWStream* content) {
diff --git a/src/pdf/SkPDFUtils.h b/src/pdf/SkPDFUtils.h
index 90b1c57..45218e6 100644
--- a/src/pdf/SkPDFUtils.h
+++ b/src/pdf/SkPDFUtils.h
@@ -58,7 +58,7 @@
     SkPDFUtils::EmitPath(path, paintStyle, true, content, tolerance);
 }
 void ClosePath(SkWStream* content);
-void PaintPath(SkPaint::Style style, SkPath::FillType fill,
+void PaintPath(SkPaint::Style style, SkPathFillType fill,
                       SkWStream* content);
 void StrokePath(SkWStream* content);
 void ApplyGraphicState(int objectIndex, SkWStream* content);
diff --git a/src/utils/SkDashPath.cpp b/src/utils/SkDashPath.cpp
index 92e4bdb..e166cc0 100644
--- a/src/utils/SkDashPath.cpp
+++ b/src/utils/SkDashPath.cpp
@@ -425,7 +425,7 @@
     } while (meas.nextContour());
 
     if (segCount > 1) {
-        dst->setConvexity(SkPath::kConcave_Convexity);
+        dst->setConvexity(SkPathConvexityType::kConcave);
     }
 
     return true;
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index 03318bb..a437fb2 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -1248,22 +1248,22 @@
     return 1;
 }
 
-static const char* fill_type_to_str(SkPath::FillType fill) {
+static const char* fill_type_to_str(SkPathFillType fill) {
     switch (fill) {
-        case SkPath::kEvenOdd_FillType:
+        case SkPathFillType::kEvenOdd:
             return "even-odd";
-        case SkPath::kWinding_FillType:
+        case SkPathFillType::kWinding:
             return "winding";
-        case SkPath::kInverseEvenOdd_FillType:
+        case SkPathFillType::kInverseEvenOdd:
             return "inverse-even-odd";
-        case SkPath::kInverseWinding_FillType:
+        case SkPathFillType::kInverseWinding:
             return "inverse-winding";
     }
     return "unknown";
 }
 
 static int lpath_getFillType(lua_State* L) {
-    SkPath::FillType fill = get_obj<SkPath>(L, 1)->getFillType();
+    SkPathFillType fill = (SkPathFillType)get_obj<SkPath>(L, 1)->getFillType();
     SkLua(L).pushString(fill_type_to_str(fill));
     return 1;
 }
@@ -1310,7 +1310,8 @@
 }
 
 static int lpath_isConvex(lua_State* L) {
-    bool isConvex = SkPath::kConvex_Convexity == get_obj<SkPath>(L, 1)->getConvexity();
+    bool isConvex = SkPathConvexityType::kConvex ==
+                   (SkPathConvexityType)get_obj<SkPath>(L, 1)->getConvexity();
     SkLua(L).pushBool(isConvex);
     return 1;
 }
diff --git a/src/utils/SkParsePath.cpp b/src/utils/SkParsePath.cpp
index 8c9469b..beddaa1 100644
--- a/src/utils/SkParsePath.cpp
+++ b/src/utils/SkParsePath.cpp
@@ -174,8 +174,8 @@
                         && (data = find_scalar(data, &sweep, false, 0))
                         && (data = skip_sep(data))
                         && (data = find_points(data, &points[0], 1, relative, &c))) {
-                    path.arcTo(radii, angle, (SkPath::ArcSize) SkToBool(largeArc),
-                            (SkPath::Direction) !SkToBool(sweep), points[0]);
+                    path.arcTo(radii.fX, radii.fY, angle, (SkPath::ArcSize) SkToBool(largeArc),
+                            (SkPathDirection) !SkToBool(sweep), points[0].fX, points[0].fY);
                     path.getLastPt(&c);
                 }
                 } break;
diff --git a/tests/GrShapeTest.cpp b/tests/GrShapeTest.cpp
index 548bd04..44d43be 100644
--- a/tests/GrShapeTest.cpp
+++ b/tests/GrShapeTest.cpp
@@ -119,7 +119,7 @@
     // The asRRect() output params are all initialized just to silence compiler warnings about
     // uninitialized variables.
     SkRRect rrectA = SkRRect::MakeEmpty(), rrectB = SkRRect::MakeEmpty();
-    SkPath::Direction dirA = SkPath::kCW_Direction, dirB = SkPath::kCW_Direction;
+    SkPathDirection dirA = SkPathDirection::kCW, dirB = SkPathDirection::kCW;
     unsigned startA = ~0U, startB = ~0U;
     bool invertedA = true, invertedB = true;
 
@@ -457,7 +457,7 @@
         }
         SkRect rect;
         unsigned start;
-        SkPath::Direction dir;
+        SkPathDirection dir;
         if (SkPathPriv::IsSimpleClosedRect(fPath, &rect, &dir, &start)) {
             return RectGeo(rect).strokeAndFillIsConvertedToFill(paint);
         }
@@ -1577,7 +1577,7 @@
     dashAndStrokeEmptyRRectCase.compare(reporter, fillEmptyCase,
                                         TestCase::kAllSame_ComparisonExpecation);
 
-    static constexpr SkPath::Direction kDir = SkPath::kCCW_Direction;
+    static constexpr SkPathDirection kDir = SkPathDirection::kCCW;
     static constexpr int kStart = 0;
 
     TestCase fillInvertedEmptyRRectCase(reporter, emptyRRect, kDir, kStart, true, GrStyle(fill));
@@ -1646,21 +1646,21 @@
     static constexpr Style kStyleCnt = static_cast<Style>(SK_ARRAY_COUNT(strokeRecs));
 
     auto index = [](bool inverted,
-                    SkPath::Direction dir,
+                    SkPathDirection dir,
                     unsigned start,
                     Style style,
                     bool dash) -> int {
         return inverted * (2 * 8 * kStyleCnt * 2) +
-               dir      * (    8 * kStyleCnt * 2) +
+               (int)dir * (    8 * kStyleCnt * 2) +
                start    * (        kStyleCnt * 2) +
                style    * (                    2) +
                dash;
     };
-    static const SkPath::Direction kSecondDirection = static_cast<SkPath::Direction>(1);
+    static const SkPathDirection kSecondDirection = static_cast<SkPathDirection>(1);
     const int cnt = index(true, kSecondDirection, 7, static_cast<Style>(kStyleCnt - 1), true) + 1;
     SkAutoTArray<GrShape> shapes(cnt);
     for (bool inverted : {false, true}) {
-        for (SkPath::Direction dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+        for (SkPathDirection dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
             for (unsigned start = 0; start < 8; ++start) {
                 for (Style style : {kFill, kStroke, kHairline, kStrokeAndFill}) {
                     for (bool dash : {false, true}) {
@@ -1676,7 +1676,7 @@
 
     // Get the keys for some example shape instances that we'll use for comparision against the
     // rest.
-    static constexpr SkPath::Direction kExamplesDir = SkPath::kCW_Direction;
+    static constexpr SkPathDirection kExamplesDir = SkPathDirection::kCW;
     static constexpr unsigned kExamplesStart = 0;
     const GrShape& exampleFillCase = shapes[index(false, kExamplesDir, kExamplesStart, kFill,
                                                   false)];
@@ -1720,61 +1720,61 @@
 
     // These are dummy initializations to suppress warnings.
     SkRRect queryRR = SkRRect::MakeEmpty();
-    SkPath::Direction queryDir = SkPath::kCW_Direction;
+    SkPathDirection queryDir = SkPathDirection::kCW;
     unsigned queryStart = ~0U;
     bool queryInverted = true;
 
     REPORTER_ASSERT(r, exampleFillCase.asRRect(&queryRR, &queryDir, &queryStart, &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, !queryInverted);
 
     REPORTER_ASSERT(r, exampleInvFillCase.asRRect(&queryRR, &queryDir, &queryStart,
                                                   &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, queryInverted);
 
     REPORTER_ASSERT(r, exampleStrokeAndFillCase.asRRect(&queryRR, &queryDir, &queryStart,
                                                         &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, !queryInverted);
 
     REPORTER_ASSERT(r, exampleInvStrokeAndFillCase.asRRect(&queryRR, &queryDir, &queryStart,
                                                            &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, queryInverted);
 
     REPORTER_ASSERT(r, exampleHairlineCase.asRRect(&queryRR, &queryDir, &queryStart,
                                                    &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, !queryInverted);
 
     REPORTER_ASSERT(r, exampleInvHairlineCase.asRRect(&queryRR, &queryDir, &queryStart,
                                                       &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, queryInverted);
 
     REPORTER_ASSERT(r, exampleStrokeCase.asRRect(&queryRR, &queryDir, &queryStart, &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, !queryInverted);
 
     REPORTER_ASSERT(r, exampleInvStrokeCase.asRRect(&queryRR, &queryDir, &queryStart,
                                                     &queryInverted));
     REPORTER_ASSERT(r, queryRR == rrect);
-    REPORTER_ASSERT(r, SkPath::kCW_Direction == queryDir);
+    REPORTER_ASSERT(r, SkPathDirection::kCW == queryDir);
     REPORTER_ASSERT(r, 0 == queryStart);
     REPORTER_ASSERT(r, queryInverted);
 
@@ -1791,7 +1791,7 @@
     REPORTER_ASSERT(r, exampleInvStrokeAndFillCaseKey == exampleInvHairlineCaseKey);
 
     for (bool inverted : {false, true}) {
-        for (SkPath::Direction dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+        for (SkPathDirection dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
             for (unsigned start = 0; start < 8; ++start) {
                 for (bool dash : {false, true}) {
                     const GrShape& fillCase = shapes[index(inverted, dir, start, kFill, dash)];
@@ -1846,7 +1846,7 @@
 
                         // The pre-style case for the dash will match the non-dash example iff the
                         // dir and start match (dir=cw, start=0).
-                        if (0 == expectedStart && SkPath::kCW_Direction == dir) {
+                        if (0 == expectedStart && SkPathDirection::kCW == dir) {
                             e.compare(r, f, TestCase::kSameUpToPE_ComparisonExpecation);
                             g.compare(r, h, TestCase::kSameUpToPE_ComparisonExpecation);
                         } else {
diff --git a/tests/ParsePathTest.cpp b/tests/ParsePathTest.cpp
index 00f5c86..5fcd002 100644
--- a/tests/ParsePathTest.cpp
+++ b/tests/ParsePathTest.cpp
@@ -60,7 +60,7 @@
     test_to_from(reporter, p);
     p.addOval(r);
     test_to_from(reporter, p);
-    p.addRoundRect(r, 4, 4.5f);
+    p.addRRect(SkRRect::MakeRectXY(r, 4, 4.5f));
     test_to_from(reporter, p);
 }
 
diff --git a/tests/PathOpsBuilderConicTest.cpp b/tests/PathOpsBuilderConicTest.cpp
index f776b43..062578c 100644
--- a/tests/PathOpsBuilderConicTest.cpp
+++ b/tests/PathOpsBuilderConicTest.cpp
@@ -54,7 +54,7 @@
 
 static void testOne(skiatest::Reporter* reporter, const OvalSet& set) {
     SkPath oval, regionResult, builderResult, opResult;
-    oval.setFillType(SkPath::kWinding_FillType);
+    oval.setFillType(SkPathFillType::kWinding);
     oval.addOval(set.fBounds);
     SkOpBuilder builder;
     SkRegion region;
@@ -412,7 +412,7 @@
 
 DEF_TEST(SixtyOvalsA, reporter) {
 SkPath path;
-path.setFillType(SkPath::kEvenOdd_FillType);
+path.setFillType(SkPathFillType::kEvenOdd);
 path.moveTo(11.1722f, -8.10398f);
 path.conicTo(22.9143f, -10.3787f, 23.7764f, -7.72542f, 1.00863f);
 path.conicTo(24.6671f, -4.98406f, 13.8147f, 0.0166066f, 0.973016f);
@@ -439,7 +439,7 @@
 path.close();
 SkPath one(path);
 path.reset();
-path.setFillType(SkPath::kWinding_FillType);
+path.setFillType(SkPathFillType::kWinding);
 path.moveTo(-1.54509f, -4.75528f);
 path.conicTo(22.2313f, -12.4807f, 23.7764f, -7.72543f, 0.707107f);
 path.conicTo(25.3215f, -2.97014f, 1.54509f, 4.75528f, 0.707107f);
@@ -453,7 +453,7 @@
 
 DEF_TEST(SixtyOvalsAX, reporter) {
 SkPath path;
-path.setFillType(SkPath::kEvenOdd_FillType);
+path.setFillType(SkPathFillType::kEvenOdd);
 path.moveTo(SkBits2Float(0x4132c174), SkBits2Float(0xc101a9e5));  // 11.1722f, -8.10398f
 path.conicTo(SkBits2Float(0x41b7508a), SkBits2Float(0xc1260efe), SkBits2Float(0x41be3618), SkBits2Float(0xc0f736ad), SkBits2Float(0x3f811abd));  // 22.9143f, -10.3787f, 23.7764f, -7.72542f, 1.00863f
 path.conicTo(SkBits2Float(0x41c5564b), SkBits2Float(0xc09f7d6d), SkBits2Float(0x415d0934), SkBits2Float(0x3c880a93), SkBits2Float(0x3f79179a));  // 24.6671f, -4.98406f, 13.8147f, 0.0166066f, 0.973016f
@@ -481,7 +481,7 @@
 path.close();
 SkPath one(path);
 path.reset();
-path.setFillType(SkPath::kWinding_FillType);
+path.setFillType(SkPathFillType::kWinding);
 path.moveTo(SkBits2Float(0xbfc5c55c), SkBits2Float(0xc0982b46));  // -1.54509f, -4.75528f
 path.conicTo(SkBits2Float(0x41b1d9c2), SkBits2Float(0xc147b0fc), SkBits2Float(0x41be3618), SkBits2Float(0xc0f736b3), SkBits2Float(0x3f3504f3));  // 22.2313f, -12.4807f, 23.7764f, -7.72543f, 0.707107f
 path.conicTo(SkBits2Float(0x41ca926e), SkBits2Float(0xc03e16da), SkBits2Float(0x3fc5c55c), SkBits2Float(0x40982b46), SkBits2Float(0x3f3504f3));  // 25.3215f, -2.97014f, 1.54509f, 4.75528f, 0.707107f
diff --git a/tests/PathOpsChalkboardTest.cpp b/tests/PathOpsChalkboardTest.cpp
index 6c03f2c..70148f5 100644
--- a/tests/PathOpsChalkboardTest.cpp
+++ b/tests/PathOpsChalkboardTest.cpp
@@ -15,7 +15,7 @@
 
 static void chalkboard(skiatest::Reporter* reporter, uint64_t testlines) {
     SkPath path;
-    path.setFillType((SkPath::FillType) 0);
+    path.setFillType((SkPathFillType) 0);
 uint64_t i = 0;
 path.moveTo(SkBits2Float(0x4470eed9), SkBits2Float(0x439c1ac1));  // 963.732f, 312.209f
 if (testlines & (1LL << i++)) path.lineTo(SkBits2Float(0x4470dde3), SkBits2Float(0x439c63d8));  // 963.467f, 312.78f
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp
index 45699d7..6ce9972 100644
--- a/tests/PathOpsExtendedTest.cpp
+++ b/tests/PathOpsExtendedTest.cpp
@@ -772,12 +772,12 @@
     }
 }
 
-void PathOpsThreadState::outputProgress(const char* pathStr, SkPath::FillType pathFillType) {
+void PathOpsThreadState::outputProgress(const char* pathStr, SkPathFillType pathFillType) {
     const char testFunction[] = "testSimplify(path);";
     const char* pathPrefix = nullptr;
     const char* nameSuffix = nullptr;
-    if (pathFillType == SkPath::kEvenOdd_FillType) {
-        pathPrefix = "    path.setFillType(SkPath::kEvenOdd_FillType);\n";
+    if (pathFillType == SkPathFillType::kEvenOdd) {
+        pathPrefix = "    path.setFillType(SkPathFillType::kEvenOdd);\n";
         nameSuffix = "x";
     }
     appendTest(pathStr, pathPrefix, nameSuffix, testFunction, false, fPathStr);
diff --git a/tests/PathOpsInverseTest.cpp b/tests/PathOpsInverseTest.cpp
index 6f0034b..196c580 100644
--- a/tests/PathOpsInverseTest.cpp
+++ b/tests/PathOpsInverseTest.cpp
@@ -10,19 +10,19 @@
     SkPath one, two;
     int testCount = 0;
     for (int op = kDifference_SkPathOp; op <= kReverseDifference_SkPathOp; ++op) {
-        for (int oneFill = SkPath::kWinding_FillType; oneFill <= SkPath::kInverseEvenOdd_FillType;
+        for (int oneFill = (int)SkPathFillType::kWinding; oneFill <= (int)SkPathFillType::kInverseEvenOdd;
                     ++oneFill) {
-            for (int oneDir = SkPath::kCW_Direction; oneDir != SkPath::kCCW_Direction; ++oneDir) {
+            for (int oneDir = (int)SkPathDirection::kCW; oneDir != (int)SkPathDirection::kCCW; ++oneDir) {
                 one.reset();
                 one.setFillType((SkPath::FillType) oneFill);
                 one.addRect(0, 0, 6, 6, (SkPath::Direction) oneDir);
-                for (int twoFill = SkPath::kWinding_FillType;
-                        twoFill <= SkPath::kInverseEvenOdd_FillType; ++twoFill) {
+                for (int twoFill = (int)SkPathFillType::kWinding;
+                        twoFill <= (int)SkPathFillType::kInverseEvenOdd; ++twoFill) {
                     for (int twoDir = SkPath::kCW_Direction; twoDir != SkPath::kCCW_Direction;
                             ++twoDir) {
                         two.reset();
-                        two.setFillType((SkPath::FillType) twoFill);
-                        two.addRect(3, 3, 9, 9, (SkPath::Direction) twoDir);
+                        two.setFillType((SkPathFillType) twoFill);
+                        two.addRect({3, 3, 9, 9}, (SkPathDirection) twoDir);
                         SkString testName;
                         testName.printf("inverseTest%d", ++testCount);
                         testPathOp(reporter, one, two, (SkPathOp) op, testName.c_str());
diff --git a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
index cf36924..cb0554a 100644
--- a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
+++ b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
@@ -32,7 +32,7 @@
                 }
                 SkString pathStr;
                 SkPath path, out;
-                path.setFillType(SkPath::kWinding_FillType);
+                path.setFillType(SkPathFillType::kWinding);
                 path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay));
                 path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
                 path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
@@ -50,12 +50,12 @@
                     pathStr.appendf("    path.lineTo(%d, %d);\n", ex, ey);
                     pathStr.appendf("    path.lineTo(%d, %d);\n", fx, fy);
                     pathStr.appendf("    path.close();\n");
-                    state.outputProgress(pathStr.c_str(), SkPath::kWinding_FillType);
+                    state.outputProgress(pathStr.c_str(), SkPathFillType::kWinding);
                 }
                 testSimplify(path, false, out, state, pathStr.c_str());
                 path.setFillType(SkPath::kEvenOdd_FillType);
                 if (state.fReporter->verbose()) {
-                    state.outputProgress(pathStr.c_str(), SkPath::kEvenOdd_FillType);
+                    state.outputProgress(pathStr.c_str(), SkPathFillType::kEvenOdd);
                 }
                 testSimplify(path, true, out, state, pathStr.c_str());
             }
diff --git a/tests/PathOpsSimplifyFailTest.cpp b/tests/PathOpsSimplifyFailTest.cpp
index 6e7c650..e1e037a 100644
--- a/tests/PathOpsSimplifyFailTest.cpp
+++ b/tests/PathOpsSimplifyFailTest.cpp
@@ -59,11 +59,11 @@
         case 12: path.moveTo(nonFinitePts[i]); break;
     }
     SkPath result;
-    result.setFillType(SkPath::kWinding_FillType);
+    result.setFillType(SkPathFillType::kWinding);
     bool success = Simplify(path, &result);
     REPORTER_ASSERT(reporter, !success);
     REPORTER_ASSERT(reporter, result.isEmpty());
-    REPORTER_ASSERT(reporter, result.getFillType() == SkPath::kWinding_FillType);
+    REPORTER_ASSERT(reporter, (SkPathFillType)result.getFillType() == SkPathFillType::kWinding);
     reporter->bumpTestCount();
 }
 
@@ -85,10 +85,10 @@
         case 10: path.moveTo(finitePts[f]); break;
     }
     SkPath result;
-    result.setFillType(SkPath::kWinding_FillType);
+    result.setFillType(SkPathFillType::kWinding);
     bool success = Simplify(path, &result);
     REPORTER_ASSERT(reporter, success);
-    REPORTER_ASSERT(reporter, result.getFillType() != SkPath::kWinding_FillType);
+    REPORTER_ASSERT(reporter, (SkPathFillType)result.getFillType() != SkPathFillType::kWinding);
     reporter->bumpTestCount();
 }
 
@@ -126,7 +126,7 @@
 
 static void fuzz763_1(skiatest::Reporter* reporter, const char* filename) {
     SkPath path;
-    path.setFillType((SkPath::FillType) 0);
+    path.setFillType((SkPathFillType) 0);
 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
 path.cubicTo(SkBits2Float(0xbcb63000), SkBits2Float(0xb6b6b6b7), SkBits2Float(0x38b6b6b6), SkBits2Float(0xafb63a5a), SkBits2Float(0xca000087), SkBits2Float(0xe93ae9e9));  // -0.0222397f, -5.44529e-06f, 8.71247e-05f, -3.31471e-10f, -2.09719e+06f, -1.41228e+25f
 path.quadTo(SkBits2Float(0xb6007fb6), SkBits2Float(0xb69fb6b6), SkBits2Float(0xe9e964b6), SkBits2Float(0xe9e9e9e9));  // -1.91478e-06f, -4.75984e-06f, -3.52694e+25f, -3.5348e+25f
@@ -157,7 +157,7 @@
 
 static void fuzz763_2s(skiatest::Reporter* reporter, const char* filename) {
     SkPath path;
-    path.setFillType((SkPath::FillType) 0);
+    path.setFillType((SkPathFillType) 0);
 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
 path.cubicTo(SkBits2Float(0x76773011), SkBits2Float(0x5d66fe78), SkBits2Float(0xbbeeff66), SkBits2Float(0x637677a2), SkBits2Float(0x205266fe), SkBits2Float(0xec296fdf));  // 1.25339e+33f, 1.0403e+18f, -0.00729363f, 4.54652e+21f, 1.78218e-19f, -8.19347e+26f
 path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
@@ -217,7 +217,7 @@
 
 static void fuzz_x3(skiatest::Reporter* reporter, const char* filename) {
     SkPath path;
-path.setFillType(SkPath::kWinding_FillType);
+path.setFillType(SkPathFillType::kWinding);
 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
 path.cubicTo(SkBits2Float(0x92743420), SkBits2Float(0x74747474), SkBits2Float(0x0f747c74), SkBits2Float(0xff538565), SkBits2Float(0x74744374), SkBits2Float(0x20437474));  // -7.70571e-28f, 7.74708e+31f, 1.20541e-29f, -2.8116e+38f, 7.74102e+31f, 1.65557e-19f
 path.conicTo(SkBits2Float(0x7474926d), SkBits2Float(0x7c747474), SkBits2Float(0x00170f74), SkBits2Float(0x3a7410d7), SkBits2Float(0x3a3a3a3a));  // 7.7508e+31f, 5.07713e+36f, 2.11776e-39f, 0.000931037f, 0.000710401f
@@ -229,7 +229,7 @@
 
 static void fuzz_k1(skiatest::Reporter* reporter, const char* filename) {
     SkPath path;
-path.setFillType(SkPath::kWinding_FillType);
+path.setFillType(SkPathFillType::kWinding);
 path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
 path.conicTo(SkBits2Float(0x2073732f), SkBits2Float(0x73f17f00), SkBits2Float(0x737b7b73), SkBits2Float(0x73916773), SkBits2Float(0x00738773));  // 2.0621e-19f, 3.82666e+31f, 1.99245e+31f, 2.30402e+31f, 1.06097e-38f
 path.lineTo(SkBits2Float(0x5803736d), SkBits2Float(0x807b5ba1));  // 5.78127e+14f, -1.13286e-38f
diff --git a/tests/PathOpsSimplifyQuadThreadedTest.cpp b/tests/PathOpsSimplifyQuadThreadedTest.cpp
index fc5f646..b722976 100644
--- a/tests/PathOpsSimplifyQuadThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadThreadedTest.cpp
@@ -61,12 +61,12 @@
                         pathStr.appendf("    path.close();\n");
                         pathStr.appendf("    testSimplify(reporter, path, filename);\n");
                         pathStr.appendf("}\n");
-                        state.outputProgress(pathStr.c_str(), SkPath::kWinding_FillType);
+                        state.outputProgress(pathStr.c_str(), SkPathFillType::kWinding);
                     }
                     testSimplify(path, false, out, state, pathStr.c_str());
                     path.setFillType(SkPath::kEvenOdd_FillType);
                     if (state.fReporter->verbose()) {
-                        state.outputProgress(pathStr.c_str(), SkPath::kEvenOdd_FillType);
+                        state.outputProgress(pathStr.c_str(), SkPathFillType::kEvenOdd);
                     }
                     testSimplify(path, true, out, state, pathStr.c_str());
                 }
diff --git a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
index 2cfca49..678988c 100644
--- a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
@@ -63,12 +63,12 @@
                         pathStr.appendf("    path.close();\n");
                         pathStr.appendf("    testPathSimplify(reporter, path, filename);\n");
                         pathStr.appendf("}\n");
-                        state.outputProgress(pathStr.c_str(), SkPath::kWinding_FillType);
+                        state.outputProgress(pathStr.c_str(), SkPathFillType::kWinding);
                     }
                     testSimplify(path, false, out, state, pathStr.c_str());
                     path.setFillType(SkPath::kEvenOdd_FillType);
                     if (state.fReporter->verbose()) {
-                        state.outputProgress(pathStr.c_str(), SkPath::kEvenOdd_FillType);
+                        state.outputProgress(pathStr.c_str(), SkPathFillType::kEvenOdd);
                     }
                     testSimplify(path, true, out, state, pathStr.c_str());
                 }
diff --git a/tests/PathOpsSimplifyRectThreadedTest.cpp b/tests/PathOpsSimplifyRectThreadedTest.cpp
index e3b58a3..9f8b27b 100644
--- a/tests/PathOpsSimplifyRectThreadedTest.cpp
+++ b/tests/PathOpsSimplifyRectThreadedTest.cpp
@@ -168,11 +168,11 @@
         }
         path.close();
         if (state.fReporter->verbose()) {
-            state.outputProgress(pathStr.c_str(), SkPath::kWinding_FillType);
+            state.outputProgress(pathStr.c_str(), SkPathFillType::kWinding);
         }
         testSimplify(path, false, out, state, pathStr.c_str());
         if (state.fReporter->verbose()) {
-            state.outputProgress(pathStr.c_str(), SkPath::kEvenOdd_FillType);
+            state.outputProgress(pathStr.c_str(), SkPathFillType::kEvenOdd);
         }
         testSimplify(path, true, out, state, pathStr.c_str());
     }
diff --git a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
index 52f0a84..d421ce0 100644
--- a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
+++ b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
@@ -53,13 +53,13 @@
                     pathStr.appendf("    path.lineTo(%d, %d);\n", ex, ey);
                     pathStr.appendf("    path.lineTo(%d, %d);\n", fx, fy);
                     pathStr.appendf("    path.close();\n");
-                    state.outputProgress(pathStr.c_str(), SkPath::kWinding_FillType);
+                    state.outputProgress(pathStr.c_str(), SkPathFillType::kWinding);
                 }
                 ShowTestName(&state, d, e, f, 0);
                 testSimplify(path, false, out, state, pathStr.c_str());
                 path.setFillType(SkPath::kEvenOdd_FillType);
                 if (state.fReporter->verbose()) {
-                    state.outputProgress(pathStr.c_str(), SkPath::kEvenOdd_FillType);
+                    state.outputProgress(pathStr.c_str(), SkPathFillType::kEvenOdd);
                 }
                 ShowTestName(&state, d, e, f, 1);
                 testSimplify(path, true, out, state, pathStr.c_str());
diff --git a/tests/PathOpsThreadedCommon.h b/tests/PathOpsThreadedCommon.h
index 4b4c9b8..1248fde 100644
--- a/tests/PathOpsThreadedCommon.h
+++ b/tests/PathOpsThreadedCommon.h
@@ -34,7 +34,7 @@
     skiatest::Reporter* fReporter;
     SkBitmap* fBitmap;
 
-    void outputProgress(const char* pathStr, SkPath::FillType);
+    void outputProgress(const char* pathStr, SkPathFillType);
     void outputProgress(const char* pathStr, SkPathOp);
 };
 
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index 54ef767..be62a79 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -1129,13 +1129,13 @@
     // Test two donuts, each wound a different direction. Only the outer contour
     // determines the cheap direction
     path.reset();
-    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCW_Direction);
-    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCCW_Direction);
+    path.addCircle(0, 0, SkIntToScalar(2), SkPathDirection::kCW);
+    path.addCircle(0, 0, SkIntToScalar(1), SkPathDirection::kCCW);
     check_direction(reporter, path, SkPathPriv::kCW_FirstDirection);
 
     path.reset();
-    path.addCircle(0, 0, SkIntToScalar(1), SkPath::kCW_Direction);
-    path.addCircle(0, 0, SkIntToScalar(2), SkPath::kCCW_Direction);
+    path.addCircle(0, 0, SkIntToScalar(1), SkPathDirection::kCW);
+    path.addCircle(0, 0, SkIntToScalar(2), SkPathDirection::kCCW);
     check_direction(reporter, path, SkPathPriv::kCCW_FirstDirection);
 
     // triangle with one point really far from the origin.
@@ -1155,7 +1155,7 @@
     path.lineTo(1, 1e7f);
     path.lineTo(1e7f, 2e7f);
     path.close();
-    REPORTER_ASSERT(reporter, SkPath::kConvex_Convexity == path.getConvexity());
+    REPORTER_ASSERT(reporter, SkPathConvexityType::kConvex == (SkPathConvexityType)path.getConvexity());
     check_direction(reporter, path, SkPathPriv::kCCW_FirstDirection);
 }
 
@@ -1913,7 +1913,7 @@
                 swap(qRect.fTop, qRect.fBottom);
             }
             for (int d = 0; d < 2; ++d) {
-                SkPath::Direction dir = d ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+                SkPathDirection dir = d ? SkPathDirection::kCCW : SkPathDirection::kCW;
                 path.reset();
                 path.addRect(kBaseRect, dir);
                 REPORTER_ASSERT(reporter, kQueries[q].fInRect ==
@@ -1925,7 +1925,7 @@
                                           path.conservativelyContainsRect(qRect));
 
                 path.reset();
-                path.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1], dir);
+                path.addRRect(SkRRect::MakeRectXY(kBaseRect, kRRRadii[0], kRRRadii[1]), dir);
                 REPORTER_ASSERT(reporter, kQueries[q].fInRR ==
                                           path.conservativelyContainsRect(qRect));
 
@@ -2157,7 +2157,7 @@
         if (tests[testIndex].fIsRect) {
             SkRect computed, expected;
             bool isClosed;
-            SkPath::Direction direction;
+            SkPathDirection direction;
             SkPathPriv::FirstDirection cheapDirection;
             int pointCount = tests[testIndex].fPointCount - (d2 == tests[testIndex].fPoints);
             expected.setBounds(tests[testIndex].fPoints, pointCount);
@@ -2170,9 +2170,9 @@
             SkRect computed;
             computed.setLTRB(123, 456, 789, 1011);
             for (auto c : {true, false})
-            for (auto d : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+            for (auto d : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
               bool isClosed = c;
-              SkPath::Direction direction = d;
+              SkPathDirection direction = d;
               REPORTER_ASSERT(reporter, !path.isRect(&computed, &isClosed, &direction));
               REPORTER_ASSERT(reporter, computed.fLeft == 123 && computed.fTop == 456);
               REPORTER_ASSERT(reporter, computed.fRight == 789 && computed.fBottom == 1011);
@@ -2239,9 +2239,9 @@
 }
 
 static void check_simple_closed_rect(skiatest::Reporter* reporter, const SkPath& path,
-                                     const SkRect& rect, SkPath::Direction dir, unsigned start) {
+                                     const SkRect& rect, SkPathDirection dir, unsigned start) {
     SkRect r = SkRect::MakeEmpty();
-    SkPath::Direction d = SkPath::kCCW_Direction;
+    SkPathDirection d = SkPathDirection::kCCW;
     unsigned s = ~0U;
 
     REPORTER_ASSERT(reporter, SkPathPriv::IsSimpleClosedRect(path, &r, &d, &s));
@@ -2253,14 +2253,14 @@
 static void test_is_simple_closed_rect(skiatest::Reporter* reporter) {
     using std::swap;
     SkRect r = SkRect::MakeEmpty();
-    SkPath::Direction d = SkPath::kCCW_Direction;
+    SkPathDirection d = SkPathDirection::kCCW;
     unsigned s = ~0U;
 
     const SkRect testRect = SkRect::MakeXYWH(10, 10, 50, 70);
     const SkRect emptyRect = SkRect::MakeEmpty();
     SkPath path;
     for (int start = 0; start < 4; ++start) {
-        for (auto dir : {SkPath::kCCW_Direction, SkPath::kCW_Direction}) {
+        for (auto dir : {SkPathDirection::kCCW, SkPathDirection::kCW}) {
             SkPath path;
             path.addRect(testRect, dir, start);
             check_simple_closed_rect(reporter, path, testRect, dir, start);
@@ -2317,9 +2317,9 @@
             path2.addRect(degenRect, dir, start);
             REPORTER_ASSERT(reporter, !SkPathPriv::IsSimpleClosedRect(path2, &r, &d, &s));
             // An inverted rect makes a rect path, but changes the winding dir and start point.
-            SkPath::Direction swapDir = (dir == SkPath::kCW_Direction)
-                                            ? SkPath::kCCW_Direction
-                                            : SkPath::kCW_Direction;
+            SkPathDirection swapDir = (dir == SkPathDirection::kCW)
+                                            ? SkPathDirection::kCCW
+                                            : SkPathDirection::kCW;
             static constexpr unsigned kXSwapStarts[] = { 1, 0, 3, 2 };
             static constexpr unsigned kYSwapStarts[] = { 3, 2, 1, 0 };
             SkRect swapRect = testRect;
@@ -2341,7 +2341,7 @@
     path.lineTo(1, 1);
     path.lineTo(0, 1);
     SkRect rect;
-    SkPath::Direction  dir;
+    SkPathDirection  dir;
     unsigned start;
     path.close();
     REPORTER_ASSERT(reporter, !SkPathPriv::IsSimpleClosedRect(path, &rect, &dir, &start));
@@ -2444,7 +2444,7 @@
         for (size_t testIndex = 0; testIndex < testCount; ++testIndex) {
             SkPath path;
             if (rectFirst) {
-                path.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
+                path.addRect({-1, -1, 2, 2}, SkPathDirection::kCW);
             }
             path.moveTo(tests[testIndex].fPoints[0].fX, tests[testIndex].fPoints[0].fY);
             for (index = 1; index < tests[testIndex].fPointCount; ++index) {
@@ -2454,14 +2454,14 @@
                 path.close();
             }
             if (!rectFirst) {
-                path.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
+                path.addRect({-1, -1, 2, 2}, SkPathDirection::kCCW);
             }
             REPORTER_ASSERT(reporter,
                             tests[testIndex].fIsNestedRect == SkPathPriv::IsNestedFillRects(path, nullptr));
             if (tests[testIndex].fIsNestedRect) {
                 SkRect expected[2], computed[2];
                 SkPathPriv::FirstDirection expectedDirs[2];
-                SkPath::Direction computedDirs[2];
+                SkPathDirection computedDirs[2];
                 SkRect testBounds;
                 testBounds.setBounds(tests[testIndex].fPoints, tests[testIndex].fPointCount);
                 expected[0] = SkRect::MakeLTRB(-1, -1, 2, 2);
@@ -2483,7 +2483,7 @@
         // fail, close then line
         SkPath path1;
         if (rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCW);
         }
         path1.moveTo(r1[0].fX, r1[0].fY);
         for (index = 1; index < SkToInt(SK_ARRAY_COUNT(r1)); ++index) {
@@ -2492,14 +2492,14 @@
         path1.close();
         path1.lineTo(1, 0);
         if (!rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCCW);
         }
         REPORTER_ASSERT(reporter, !SkPathPriv::IsNestedFillRects(path1, nullptr));
 
         // fail, move in the middle
         path1.reset();
         if (rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCW);
         }
         path1.moveTo(r1[0].fX, r1[0].fY);
         for (index = 1; index < SkToInt(SK_ARRAY_COUNT(r1)); ++index) {
@@ -2510,14 +2510,14 @@
         }
         path1.close();
         if (!rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCCW);
         }
         REPORTER_ASSERT(reporter, !SkPathPriv::IsNestedFillRects(path1, nullptr));
 
         // fail, move on the edge
         path1.reset();
         if (rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCW);
         }
         for (index = 1; index < SkToInt(SK_ARRAY_COUNT(r1)); ++index) {
             path1.moveTo(r1[index - 1].fX, r1[index - 1].fY);
@@ -2525,14 +2525,14 @@
         }
         path1.close();
         if (!rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCCW);
         }
         REPORTER_ASSERT(reporter, !SkPathPriv::IsNestedFillRects(path1, nullptr));
 
         // fail, quad
         path1.reset();
         if (rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCW);
         }
         path1.moveTo(r1[0].fX, r1[0].fY);
         for (index = 1; index < SkToInt(SK_ARRAY_COUNT(r1)); ++index) {
@@ -2543,14 +2543,14 @@
         }
         path1.close();
         if (!rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCCW);
         }
         REPORTER_ASSERT(reporter, !SkPathPriv::IsNestedFillRects(path1, nullptr));
 
         // fail, cubic
         path1.reset();
         if (rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCW);
         }
         path1.moveTo(r1[0].fX, r1[0].fY);
         for (index = 1; index < SkToInt(SK_ARRAY_COUNT(r1)); ++index) {
@@ -2561,14 +2561,14 @@
         }
         path1.close();
         if (!rectFirst) {
-            path1.addRect(-1, -1, 2, 2, SkPath::kCCW_Direction);
+            path1.addRect({-1, -1, 2, 2}, SkPathDirection::kCCW);
         }
         REPORTER_ASSERT(reporter, !SkPathPriv::IsNestedFillRects(path1, nullptr));
 
         // fail,  not nested
         path1.reset();
-        path1.addRect(1, 1, 3, 3, SkPath::kCW_Direction);
-        path1.addRect(2, 2, 4, 4, SkPath::kCW_Direction);
+        path1.addRect({1, 1, 3, 3}, SkPathDirection::kCW);
+        path1.addRect({2, 2, 4, 4}, SkPathDirection::kCW);
         REPORTER_ASSERT(reporter, !SkPathPriv::IsNestedFillRects(path1, nullptr));
     }
 
@@ -2588,7 +2588,7 @@
 
     // pass, stroke rect
     SkPath src, dst;
-    src.addRect(1, 1, 7, 7, SkPath::kCW_Direction);
+    src.addRect({1, 1, 7, 7}, SkPathDirection::kCW);
     SkPaint strokePaint;
     strokePaint.setStyle(SkPaint::kStroke_Style);
     strokePaint.setStrokeWidth(2);
@@ -2614,7 +2614,7 @@
                               p.getConvexityOrUnknown());
 
     SkRect oval0, oval1;
-    SkPath::Direction dir0, dir1;
+    SkPathDirection dir0, dir1;
     unsigned start0, start1;
     REPORTER_ASSERT(reporter, readBack.isOval(nullptr) == p.isOval(nullptr));
     if (SkPathPriv::IsOval(p, &oval0, &dir0, &start0) &&
@@ -2756,7 +2756,7 @@
     }
 
     p.reset();
-    p.addCircle(0, 0, 1, SkPath::kCW_Direction);
+    p.addCircle(0, 0, 1, SkPathDirection::kCW);
 
     {
         SkMatrix matrix;
@@ -3286,7 +3286,7 @@
                              SkPathPriv::FirstDirection expectedDir) {
     SkRect rect = SkRect::MakeEmpty();
     REPORTER_ASSERT(reporter, path.isOval(&rect) == expectedCircle);
-    SkPath::Direction isOvalDir;
+    SkPathDirection isOvalDir;
     unsigned isOvalStart;
     if (SkPathPriv::IsOval(path, &rect, &isOvalDir, &isOvalStart)) {
         REPORTER_ASSERT(reporter, rect.height() == rect.width());
@@ -3406,7 +3406,7 @@
 }
 
 static void test_circle_with_direction(skiatest::Reporter* reporter,
-                                       SkPath::Direction inDir) {
+                                       SkPathDirection inDir) {
     const SkPathPriv::FirstDirection dir = SkPathPriv::AsFirstDirection(inDir);
     SkPath path;
 
@@ -3453,8 +3453,8 @@
     SkPath rect;
     SkPath empty;
 
-    const SkPath::Direction kCircleDir = SkPath::kCW_Direction;
-    const SkPath::Direction kCircleDirOpposite = SkPath::kCCW_Direction;
+    const SkPathDirection kCircleDir = SkPathDirection::kCW;
+    const SkPathDirection kCircleDirOpposite = SkPathDirection::kCCW;
 
     circle.addCircle(0, 0, SkIntToScalar(10), kCircleDir);
     rect.addRect(SkIntToScalar(5), SkIntToScalar(5),
@@ -3484,24 +3484,24 @@
 }
 
 static void test_circle(skiatest::Reporter* reporter) {
-    test_circle_with_direction(reporter, SkPath::kCW_Direction);
-    test_circle_with_direction(reporter, SkPath::kCCW_Direction);
+    test_circle_with_direction(reporter, SkPathDirection::kCW);
+    test_circle_with_direction(reporter, SkPathDirection::kCCW);
 
     // multiple addCircle()
     SkPath path;
-    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
-    path.addCircle(0, 0, SkIntToScalar(20), SkPath::kCW_Direction);
+    path.addCircle(0, 0, SkIntToScalar(10), SkPathDirection::kCW);
+    path.addCircle(0, 0, SkIntToScalar(20), SkPathDirection::kCW);
     check_for_circle(reporter, path, false, SkPathPriv::kCW_FirstDirection);
 
     // some extra lineTo() would make isOval() fail
     path.reset();
-    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
+    path.addCircle(0, 0, SkIntToScalar(10), SkPathDirection::kCW);
     path.lineTo(0, 0);
     check_for_circle(reporter, path, false, SkPathPriv::kCW_FirstDirection);
 
     // not back to the original point
     path.reset();
-    path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction);
+    path.addCircle(0, 0, SkIntToScalar(10), SkPathDirection::kCW);
     path.setLastPt(SkIntToScalar(5), SkIntToScalar(5));
     check_for_circle(reporter, path, false, SkPathPriv::kCW_FirstDirection);
 
@@ -3509,7 +3509,7 @@
 
     // test negative radius
     path.reset();
-    path.addCircle(0, 0, -1, SkPath::kCW_Direction);
+    path.addCircle(0, 0, -1, SkPathDirection::kCW);
     REPORTER_ASSERT(reporter, path.isEmpty());
 }
 
@@ -3518,7 +3518,7 @@
     SkMatrix m;
     SkPath path;
     unsigned start = 0;
-    SkPath::Direction dir = SkPath::kCCW_Direction;
+    SkPathDirection dir = SkPathDirection::kCCW;
 
     rect = SkRect::MakeWH(SkIntToScalar(30), SkIntToScalar(50));
     path.addOval(rect);
@@ -3533,7 +3533,7 @@
     // is unchanged.
     REPORTER_ASSERT(reporter, SkPathPriv::IsOval(tmp, nullptr, &dir, &start));
     REPORTER_ASSERT(reporter, 2 == start);
-    REPORTER_ASSERT(reporter, SkPath::kCW_Direction == dir);
+    REPORTER_ASSERT(reporter, SkPathDirection::kCW == dir);
 
     m.reset();
     m.setRotate(SkIntToScalar(30));
@@ -3572,7 +3572,7 @@
     tmp.addOval(rect);
     path = tmp;
     REPORTER_ASSERT(reporter, SkPathPriv::IsOval(path, nullptr, &dir, &start));
-    REPORTER_ASSERT(reporter, SkPath::kCW_Direction == dir);
+    REPORTER_ASSERT(reporter, SkPathDirection::kCW == dir);
     REPORTER_ASSERT(reporter, 1 == start);
 }
 
@@ -3591,7 +3591,7 @@
 }
 
 static void test_rrect_is_convex(skiatest::Reporter* reporter, SkPath* path,
-                                 SkPath::Direction dir) {
+                                 SkPathDirection dir) {
     REPORTER_ASSERT(reporter, path->isConvex());
     REPORTER_ASSERT(reporter, SkPathPriv::CheapIsFirstDirection(*path, SkPathPriv::AsFirstDirection(dir)));
     path->setConvexity(SkPath::kUnknown_Convexity);
@@ -3600,7 +3600,7 @@
 }
 
 static void test_rrect_convexity_is_unknown(skiatest::Reporter* reporter, SkPath* path,
-                                 SkPath::Direction dir) {
+                                 SkPathDirection dir) {
     REPORTER_ASSERT(reporter, path->isConvex());
     REPORTER_ASSERT(reporter, SkPathPriv::CheapIsFirstDirection(*path, SkPathPriv::AsFirstDirection(dir)));
     path->setConvexity(SkPath::kUnknown_Convexity);
@@ -3615,39 +3615,39 @@
     SkRect r = {10, 20, 30, 40};
     rr.setRectRadii(r, radii);
     p.addRRect(rr);
-    test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
-    p.addRRect(rr, SkPath::kCCW_Direction);
-    test_rrect_is_convex(reporter, &p, SkPath::kCCW_Direction);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCW);
+    p.addRRect(rr, SkPathDirection::kCCW);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCCW);
     p.addRoundRect(r, &radii[0].fX);
-    test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCW);
     p.addRoundRect(r, &radii[0].fX, SkPath::kCCW_Direction);
-    test_rrect_is_convex(reporter, &p, SkPath::kCCW_Direction);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCCW);
     p.addRoundRect(r, radii[1].fX, radii[1].fY);
-    test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCW);
     p.addRoundRect(r, radii[1].fX, radii[1].fY, SkPath::kCCW_Direction);
-    test_rrect_is_convex(reporter, &p, SkPath::kCCW_Direction);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCCW);
     for (size_t i = 0; i < SK_ARRAY_COUNT(radii); ++i) {
         SkVector save = radii[i];
         radii[i].set(0, 0);
         rr.setRectRadii(r, radii);
         p.addRRect(rr);
-        test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
+        test_rrect_is_convex(reporter, &p, SkPathDirection::kCW);
         radii[i] = save;
     }
     p.addRoundRect(r, 0, 0);
     SkRect returnedRect;
     REPORTER_ASSERT(reporter, p.isRect(&returnedRect));
     REPORTER_ASSERT(reporter, returnedRect == r);
-    test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCW);
     SkVector zeroRadii[] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
     rr.setRectRadii(r, zeroRadii);
     p.addRRect(rr);
     bool closed;
-    SkPath::Direction dir;
+    SkPathDirection dir;
     REPORTER_ASSERT(reporter, p.isRect(nullptr, &closed, &dir));
     REPORTER_ASSERT(reporter, closed);
-    REPORTER_ASSERT(reporter, SkPath::kCW_Direction == dir);
-    test_rrect_is_convex(reporter, &p, SkPath::kCW_Direction);
+    REPORTER_ASSERT(reporter, SkPathDirection::kCW == dir);
+    test_rrect_is_convex(reporter, &p, SkPathDirection::kCW);
     p.addRRect(rr, SkPath::kCW_Direction);
     p.addRRect(rr, SkPath::kCW_Direction);
     REPORTER_ASSERT(reporter, !p.isConvex());
@@ -3666,7 +3666,7 @@
     SkRect largeR = {0, 0, SK_ScalarMax, SK_ScalarMax};
     rr.setRectRadii(largeR, radii);
     p.addRRect(rr);
-    test_rrect_convexity_is_unknown(reporter, &p, SkPath::kCW_Direction);
+    test_rrect_convexity_is_unknown(reporter, &p, SkPathDirection::kCW);
 
     // we check for non-finites
     SkRect infR = {0, 0, SK_ScalarMax, SK_ScalarInfinity};
@@ -3676,7 +3676,7 @@
     // We consider any path with very small (numerically unstable) edges to be concave.
     SkRect tinyR = {0, 0, 1e-9f, 1e-9f};
     p.addRoundRect(tinyR, 5e-11f, 5e-11f);
-    test_rrect_convexity_is_unknown(reporter, &p, SkPath::kCW_Direction);
+    test_rrect_convexity_is_unknown(reporter, &p, SkPathDirection::kCW);
 }
 
 static void test_arc(skiatest::Reporter* reporter) {
@@ -3738,7 +3738,7 @@
 static void check_oval_arc(skiatest::Reporter* reporter, SkScalar start, SkScalar sweep,
                            const SkPath& path) {
     SkRect r = SkRect::MakeEmpty();
-    SkPath::Direction d = SkPath::kCCW_Direction;
+    SkPathDirection d = SkPathDirection::kCCW;
     unsigned s = ~0U;
     bool isOval = SkPathPriv::IsOval(path, &r, &d, &s);
     REPORTER_ASSERT(reporter, isOval);
@@ -3746,7 +3746,7 @@
     recreatedPath.addOval(r, d, s);
     REPORTER_ASSERT(reporter, path == recreatedPath);
     REPORTER_ASSERT(reporter, oval_start_index_to_angle(s) == canonical_start_angle(start));
-    REPORTER_ASSERT(reporter, (SkPath::kCW_Direction == d) == (sweep > 0.f));
+    REPORTER_ASSERT(reporter, (SkPathDirection::kCW == d) == (sweep > 0.f));
 }
 
 static void test_arc_ovals(skiatest::Reporter* reporter) {
diff --git a/tests/PictureTest.cpp b/tests/PictureTest.cpp
index d4fdd2d..be90e49 100644
--- a/tests/PictureTest.cpp
+++ b/tests/PictureTest.cpp
@@ -379,7 +379,7 @@
 
     SkPath invPath;
     invPath.addOval(rect1);
-    invPath.setFillType(SkPath::kInverseEvenOdd_FillType);
+    invPath.setFillType(SkPathFillType::kInverseEvenOdd);
     SkPath path;
     path.addOval(rect2);
     SkPath path2;
diff --git a/tests/RRectInPathTest.cpp b/tests/RRectInPathTest.cpp
index a25ad45..c36a5ba 100644
--- a/tests/RRectInPathTest.cpp
+++ b/tests/RRectInPathTest.cpp
@@ -12,7 +12,7 @@
 #include "tests/Test.h"
 
 static SkRRect path_contains_rrect(skiatest::Reporter* reporter, const SkPath& path,
-                                   SkPath::Direction* dir, unsigned* start) {
+                                   SkPathDirection* dir, unsigned* start) {
     SkRRect out;
     REPORTER_ASSERT(reporter, SkPathPriv::IsRRect(path, &out, dir, start));
     SkPath recreatedPath;
@@ -30,7 +30,7 @@
         SkPath xformed;
         path.transform(m, &xformed);
         SkRRect xrr = SkRRect::MakeRect(SkRect::MakeEmpty());
-        SkPath::Direction xd = SkPath::kCCW_Direction;
+        SkPathDirection xd = SkPathDirection::kCCW;
         unsigned xs = ~0U;
         REPORTER_ASSERT(reporter, SkPathPriv::IsRRect(xformed, &xrr, &xd, &xs));
         recreatedPath.reset();
@@ -41,7 +41,7 @@
 }
 
 static SkRRect inner_path_contains_rrect(skiatest::Reporter* reporter, const SkRRect& in,
-                                         SkPath::Direction dir, unsigned start) {
+                                         SkPathDirection dir, unsigned start) {
     switch (in.getType()) {
         case SkRRect::kEmpty_Type:
         case SkRRect::kRect_Type:
@@ -52,7 +52,7 @@
     }
     SkPath path;
     path.addRRect(in, dir, start);
-    SkPath::Direction outDir;
+    SkPathDirection outDir;
     unsigned outStart;
     SkRRect rrect = path_contains_rrect(reporter, path, &outDir, &outStart);
     REPORTER_ASSERT(reporter, outDir == dir && outStart == start);
@@ -60,7 +60,7 @@
 }
 
 static void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRRect& in,
-                                      SkPath::Direction dir, unsigned start) {
+                                      SkPathDirection dir, unsigned start) {
     SkRRect out = inner_path_contains_rrect(reporter, in, dir, start);
     if (in != out) {
         SkDebugf("");
@@ -69,7 +69,7 @@
 }
 
 static void path_contains_rrect_nocheck(skiatest::Reporter* reporter, const SkRRect& in,
-                                        SkPath::Direction dir, unsigned start) {
+                                        SkPathDirection dir, unsigned start) {
     SkRRect out = inner_path_contains_rrect(reporter, in, dir, start);
     if (in == out) {
         SkDebugf("");
@@ -77,7 +77,7 @@
 }
 
 static void path_contains_rrect_check(skiatest::Reporter* reporter, const SkRect& r,
-        SkVector v[4], SkPath::Direction dir, unsigned start) {
+        SkVector v[4], SkPathDirection dir, unsigned start) {
     SkRRect rrect;
     rrect.setRectRadii(r, v);
     path_contains_rrect_check(reporter, rrect, dir, start);
@@ -85,15 +85,15 @@
 
 class ForceIsRRect_Private {
 public:
-    ForceIsRRect_Private(SkPath* path, SkPath::Direction dir, unsigned start) {
-        path->fPathRef->setIsRRect(true, dir == SkPath::kCCW_Direction, start);
+    ForceIsRRect_Private(SkPath* path, SkPathDirection dir, unsigned start) {
+        path->fPathRef->setIsRRect(true, dir == SkPathDirection::kCCW, start);
     }
 };
 
 static void force_path_contains_rrect(skiatest::Reporter* reporter, SkPath& path,
-                                      SkPath::Direction dir, unsigned start) {
+                                      SkPathDirection dir, unsigned start) {
     ForceIsRRect_Private force_rrect(&path, dir, start);
-    SkPath::Direction outDir;
+    SkPathDirection outDir;
     unsigned outStart;
     path_contains_rrect(reporter, path, &outDir, &outStart);
     REPORTER_ASSERT(reporter, outDir == dir && outStart == start);
@@ -124,7 +124,7 @@
     path.lineTo(3.5f, 66);
     path.conicTo(0, 66, 0, 62.5, weight);
     path.close();
-    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
+    force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6);
 
     path.reset();
     path.moveTo(0, 81.5f);
@@ -137,7 +137,7 @@
     path.lineTo(3.5f, 85);
     path.conicTo(0, 85, 0, 81.5f, weight);
     path.close();
-    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
+    force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6);
 
     path.reset();
     path.moveTo(14, 1189);
@@ -150,7 +150,7 @@
     path.lineTo(21, 1196);
     path.conicTo(14, 1196, 14, 1189, weight);
     path.close();
-    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
+    force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6);
 
     path.reset();
     path.moveTo(14, 1743);
@@ -163,14 +163,14 @@
     path.lineTo(21, 1750);
     path.conicTo(14, 1750, 14, 1743, weight);
     path.close();
-    force_path_contains_rrect(reporter, path, SkPath::kCW_Direction, 6);
+    force_path_contains_rrect(reporter, path, SkPathDirection::kCW, 6);
 }
 
 static const SkScalar kWidth = 100.0f;
 static const SkScalar kHeight = 100.0f;
 
 static void test_tricky_radii(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             {
                 // crbug.com/458522
@@ -197,7 +197,7 @@
 }
 
 static void test_empty_crbug_458524(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             SkRRect rr;
             const SkRect bounds = { 3709, 3709, 3709 + 7402, 3709 + 29825 };
@@ -215,7 +215,7 @@
 }
 
 static void test_inset(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             SkRRect rr, rr2;
             SkRect r = { 0, 0, 100, 100 };
@@ -244,7 +244,7 @@
                               const SkRect& rect,
                               SkScalar l, SkScalar t, SkScalar r, SkScalar b,
                               bool checkRadii) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             SkRRect rr;
             rr.setNinePatch(rect, l, t, r, b);
@@ -268,7 +268,7 @@
 
 // Test out the basic API entry points
 static void test_round_rect_basic(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             //----
             SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
@@ -342,7 +342,7 @@
 
 // Test out the cases when the RR degenerates to a rect
 static void test_round_rect_rects(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             //----
             SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
@@ -371,7 +371,7 @@
 
 // Test out the cases when the RR degenerates to an oval
 static void test_round_rect_ovals(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             //----
             SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
@@ -385,7 +385,7 @@
 
 // Test out the non-degenerate RR cases
 static void test_round_rect_general(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             //----
             SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
@@ -406,7 +406,7 @@
 }
 
 static void test_round_rect_iffy_parameters(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             SkRect rect = SkRect::MakeLTRB(0, 0, kWidth, kHeight);
             SkPoint radii[4] = { { 50, 100 }, { 100, 50 }, { 50, 100 }, { 100, 50 } };
@@ -432,7 +432,7 @@
     const SkRect rectx = SkRect::MakeLTRB(min, min, max, big);
     const SkRect recty = SkRect::MakeLTRB(min, min, big, max);
 
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             SkVector radii[4];
             for (int i = 0; i < 4; ++i) {
@@ -445,7 +445,7 @@
 }
 
 static void test_mix(skiatest::Reporter* reporter) {
-    for (auto dir : {SkPath::kCW_Direction, SkPath::kCCW_Direction}) {
+    for (auto dir : {SkPathDirection::kCW, SkPathDirection::kCCW}) {
         for (int start = 0; start < 8; ++start) {
             // Test out mixed degenerate and non-degenerate geometry with Conics
             const SkVector radii[4] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 100, 100 } };
diff --git a/tests/RegionTest.cpp b/tests/RegionTest.cpp
index 239ffaa..a7d585d 100644
--- a/tests/RegionTest.cpp
+++ b/tests/RegionTest.cpp
@@ -421,7 +421,7 @@
 
 DEF_TEST(region_inverse_union_skbug_7491, reporter) {
     SkPath path;
-    path.setFillType(SkPath::kInverseWinding_FillType);
+    path.setFillType(SkPathFillType::kInverseWinding);
     path.moveTo(10, 20); path.lineTo(10, 30); path.lineTo(10.1f, 10); path.close();
 
     SkRegion clip;
diff --git a/tests/StrokeTest.cpp b/tests/StrokeTest.cpp
index e13a775..2f3a01d 100644
--- a/tests/StrokeTest.cpp
+++ b/tests/StrokeTest.cpp
@@ -168,7 +168,7 @@
     paint.setStrokeWidth(1.49679073e+10f);
 
     SkPath path;
-    path.setFillType(SkPath::kWinding_FillType);
+    path.setFillType(SkPathFillType::kWinding);
     path.moveTo(SkBits2Float(0x46380000), SkBits2Float(0xc6380000));  // 11776, -11776
     path.lineTo(SkBits2Float(0x46a00000), SkBits2Float(0xc6a00000));  // 20480, -20480
     path.lineTo(SkBits2Float(0x468c0000), SkBits2Float(0xc68c0000));  // 17920, -17920
diff --git a/tools/debugger/DrawCommand.cpp b/tools/debugger/DrawCommand.cpp
index 31f7e63..569ea2b 100644
--- a/tools/debugger/DrawCommand.cpp
+++ b/tools/debugger/DrawCommand.cpp
@@ -518,18 +518,18 @@
 
 void DrawCommand::MakeJsonPath(SkJSONWriter& writer, const SkPath& path) {
     writer.beginObject();
-    switch (path.getFillType()) {
-        case SkPath::kWinding_FillType:
+    switch ((SkPathFillType)path.getFillType()) {
+        case SkPathFillType::kWinding:
             writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_WINDING);
             break;
-        case SkPath::kEvenOdd_FillType:
+        case SkPathFillType::kEvenOdd:
             writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE, DEBUGCANVAS_FILLTYPE_EVENODD);
             break;
-        case SkPath::kInverseWinding_FillType:
+        case SkPathFillType::kInverseWinding:
             writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
                                 DEBUGCANVAS_FILLTYPE_INVERSEWINDING);
             break;
-        case SkPath::kInverseEvenOdd_FillType:
+        case SkPathFillType::kInverseEvenOdd:
             writer.appendString(DEBUGCANVAS_ATTRIBUTE_FILLTYPE,
                                 DEBUGCANVAS_FILLTYPE_INVERSEEVENODD);
             break;