Move class into impl

I think this finishes all public subclasses, so we can proceed next with
moving the virtuals themselves to a private subclass.

Change-Id: I490f3cf6497a6bdcafc1ce756cfdeb32eab18585
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/411239
Reviewed-by: Tyler Denniston <tdenniston@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/include/effects/SkCornerPathEffect.h b/include/effects/SkCornerPathEffect.h
index dbd59a3..6017df4 100644
--- a/include/effects/SkCornerPathEffect.h
+++ b/include/effects/SkCornerPathEffect.h
@@ -8,7 +8,6 @@
 #ifndef SkCornerPathEffect_DEFINED
 #define SkCornerPathEffect_DEFINED
 
-#include "include/core/SkFlattenable.h"
 #include "include/core/SkPathEffect.h"
 
 /** \class SkCornerPathEffect
@@ -16,34 +15,14 @@
     SkCornerPathEffect is a subclass of SkPathEffect that can turn sharp corners
     into various treatments (e.g. rounded corners)
 */
-class SK_API SkCornerPathEffect : public SkPathEffect {
+class SK_API SkCornerPathEffect {
 public:
     /** radius must be > 0 to have an effect. It specifies the distance from each corner
         that should be "rounded".
     */
-    static sk_sp<SkPathEffect> Make(SkScalar radius) {
-        return radius > 0 ? sk_sp<SkPathEffect>(new SkCornerPathEffect(radius)) : nullptr;
-    }
+    static sk_sp<SkPathEffect> Make(SkScalar radius);
 
-protected:
-    ~SkCornerPathEffect() override;
-
-    explicit SkCornerPathEffect(SkScalar radius);
-    void flatten(SkWriteBuffer&) const override;
-    bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
-
-private:
-    SK_FLATTENABLE_HOOKS(SkCornerPathEffect)
-
-    bool computeFastBounds(SkRect*) const override {
-        // Rounding sharp corners within a path produces a new path that is still contained within
-        // the original's bounds, so leave 'bounds' unmodified.
-        return true;
-    }
-
-    SkScalar    fRadius;
-
-    using INHERITED = SkPathEffect;
+    static void RegisterFlattenables();
 };
 
 #endif
diff --git a/include/effects/SkDiscretePathEffect.h b/include/effects/SkDiscretePathEffect.h
index 7f60768..542536f 100644
--- a/include/effects/SkDiscretePathEffect.h
+++ b/include/effects/SkDiscretePathEffect.h
@@ -8,7 +8,6 @@
 #ifndef SkDiscretePathEffect_DEFINED
 #define SkDiscretePathEffect_DEFINED
 
-#include "include/core/SkFlattenable.h"
 #include "include/core/SkPathEffect.h"
 
 /** \class SkDiscretePathEffect
@@ -32,24 +31,7 @@
     */
     static sk_sp<SkPathEffect> Make(SkScalar segLength, SkScalar dev, uint32_t seedAssist = 0);
 
-protected:
-    SkDiscretePathEffect(SkScalar segLength,
-                         SkScalar deviation,
-                         uint32_t seedAssist);
-    void flatten(SkWriteBuffer&) const override;
-    bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
-
-private:
-    SK_FLATTENABLE_HOOKS(SkDiscretePathEffect)
-
-    bool computeFastBounds(SkRect* bounds) const override;
-
-    SkScalar fSegLength, fPerterb;
-
-    /* Caller-supplied 32 bit seed assist */
-    uint32_t fSeedAssist;
-
-    using INHERITED = SkPathEffect;
+    static void RegisterFlattenables();
 };
 
 #endif
diff --git a/src/effects/SkCornerPathEffect.cpp b/src/effects/SkCornerPathEffect.cpp
index 16670e5..6788537 100644
--- a/src/effects/SkCornerPathEffect.cpp
+++ b/src/effects/SkCornerPathEffect.cpp
@@ -12,15 +12,6 @@
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
 
-SkCornerPathEffect::SkCornerPathEffect(SkScalar radius) {
-    // check with ! to catch NaNs
-    if (!(radius > 0)) {
-        radius = 0;
-    }
-    fRadius = radius;
-}
-SkCornerPathEffect::~SkCornerPathEffect() {}
-
 static bool ComputeStep(const SkPoint& a, const SkPoint& b, SkScalar radius,
                         SkPoint* step) {
     SkScalar dist = SkPoint::Distance(a, b);
@@ -35,122 +26,152 @@
     }
 }
 
-bool SkCornerPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
-                                      SkStrokeRec*, const SkRect*) const {
-    if (fRadius <= 0) {
-        return false;
+class SkCornerPathEffectImpl : public SkPathEffect {
+public:
+    explicit SkCornerPathEffectImpl(SkScalar radius) : fRadius(radius) {
+        SkASSERT(radius > 0);
     }
 
-    SkPath::Iter    iter(src, false);
-    SkPath::Verb    verb, prevVerb = SkPath::kDone_Verb;
-    SkPoint         pts[4];
+    bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override {
+        if (fRadius <= 0) {
+            return false;
+        }
 
-    bool        closed;
-    SkPoint     moveTo, lastCorner;
-    SkVector    firstStep, step;
-    bool        prevIsValid = true;
+        SkPath::Iter    iter(src, false);
+        SkPath::Verb    verb, prevVerb = SkPath::kDone_Verb;
+        SkPoint         pts[4];
 
-    // to avoid warnings
-    step.set(0, 0);
-    moveTo.set(0, 0);
-    firstStep.set(0, 0);
-    lastCorner.set(0, 0);
+        bool        closed;
+        SkPoint     moveTo, lastCorner;
+        SkVector    firstStep, step;
+        bool        prevIsValid = true;
 
-    for (;;) {
-        switch (verb = iter.next(pts)) {
-            case SkPath::kMove_Verb:
-                // close out the previous (open) contour
-                if (SkPath::kLine_Verb == prevVerb) {
-                    dst->lineTo(lastCorner);
+        // to avoid warnings
+        step.set(0, 0);
+        moveTo.set(0, 0);
+        firstStep.set(0, 0);
+        lastCorner.set(0, 0);
+
+        for (;;) {
+            switch (verb = iter.next(pts)) {
+                case SkPath::kMove_Verb:
+                    // close out the previous (open) contour
+                    if (SkPath::kLine_Verb == prevVerb) {
+                        dst->lineTo(lastCorner);
+                    }
+                    closed = iter.isClosedContour();
+                    if (closed) {
+                        moveTo = pts[0];
+                        prevIsValid = false;
+                    } else {
+                        dst->moveTo(pts[0]);
+                        prevIsValid = true;
+                    }
+                    break;
+                case SkPath::kLine_Verb: {
+                    bool drawSegment = ComputeStep(pts[0], pts[1], fRadius, &step);
+                    // prev corner
+                    if (!prevIsValid) {
+                        dst->moveTo(moveTo + step);
+                        prevIsValid = true;
+                    } else {
+                        dst->quadTo(pts[0].fX, pts[0].fY, pts[0].fX + step.fX,
+                                    pts[0].fY + step.fY);
+                    }
+                    if (drawSegment) {
+                        dst->lineTo(pts[1].fX - step.fX, pts[1].fY - step.fY);
+                    }
+                    lastCorner = pts[1];
+                    prevIsValid = true;
+                    break;
                 }
-                closed = iter.isClosedContour();
-                if (closed) {
-                    moveTo = pts[0];
+                case SkPath::kQuad_Verb:
+                    // TBD - just replicate the curve for now
+                    if (!prevIsValid) {
+                        dst->moveTo(pts[0]);
+                        prevIsValid = true;
+                    }
+                    dst->quadTo(pts[1], pts[2]);
+                    lastCorner = pts[2];
+                    firstStep.set(0, 0);
+                    break;
+                case SkPath::kConic_Verb:
+                    // TBD - just replicate the curve for now
+                    if (!prevIsValid) {
+                        dst->moveTo(pts[0]);
+                        prevIsValid = true;
+                    }
+                    dst->conicTo(pts[1], pts[2], iter.conicWeight());
+                    lastCorner = pts[2];
+                    firstStep.set(0, 0);
+                    break;
+                case SkPath::kCubic_Verb:
+                    if (!prevIsValid) {
+                        dst->moveTo(pts[0]);
+                        prevIsValid = true;
+                    }
+                    // TBD - just replicate the curve for now
+                    dst->cubicTo(pts[1], pts[2], pts[3]);
+                    lastCorner = pts[3];
+                    firstStep.set(0, 0);
+                    break;
+                case SkPath::kClose_Verb:
+                    if (firstStep.fX || firstStep.fY) {
+                        dst->quadTo(lastCorner.fX, lastCorner.fY,
+                                    lastCorner.fX + firstStep.fX,
+                                    lastCorner.fY + firstStep.fY);
+                    }
+                    dst->close();
                     prevIsValid = false;
-                } else {
-                    dst->moveTo(pts[0]);
-                    prevIsValid = true;
-                }
-                break;
-            case SkPath::kLine_Verb: {
-                bool drawSegment = ComputeStep(pts[0], pts[1], fRadius, &step);
-                // prev corner
-                if (!prevIsValid) {
-                    dst->moveTo(moveTo + step);
-                    prevIsValid = true;
-                } else {
-                    dst->quadTo(pts[0].fX, pts[0].fY, pts[0].fX + step.fX,
-                                pts[0].fY + step.fY);
-                }
-                if (drawSegment) {
-                    dst->lineTo(pts[1].fX - step.fX, pts[1].fY - step.fY);
-                }
-                lastCorner = pts[1];
-                prevIsValid = true;
-                break;
+                    break;
+                case SkPath::kDone_Verb:
+                    if (prevIsValid) {
+                        dst->lineTo(lastCorner);
+                    }
+                    return true;
+                default:
+                    SkDEBUGFAIL("default should not be reached");
+                    return false;
             }
-            case SkPath::kQuad_Verb:
-                // TBD - just replicate the curve for now
-                if (!prevIsValid) {
-                    dst->moveTo(pts[0]);
-                    prevIsValid = true;
-                }
-                dst->quadTo(pts[1], pts[2]);
-                lastCorner = pts[2];
-                firstStep.set(0, 0);
-                break;
-            case SkPath::kConic_Verb:
-                // TBD - just replicate the curve for now
-                if (!prevIsValid) {
-                    dst->moveTo(pts[0]);
-                    prevIsValid = true;
-                }
-                dst->conicTo(pts[1], pts[2], iter.conicWeight());
-                lastCorner = pts[2];
-                firstStep.set(0, 0);
-                break;
-            case SkPath::kCubic_Verb:
-                if (!prevIsValid) {
-                    dst->moveTo(pts[0]);
-                    prevIsValid = true;
-                }
-                // TBD - just replicate the curve for now
-                dst->cubicTo(pts[1], pts[2], pts[3]);
-                lastCorner = pts[3];
-                firstStep.set(0, 0);
-                break;
-            case SkPath::kClose_Verb:
-                if (firstStep.fX || firstStep.fY) {
-                    dst->quadTo(lastCorner.fX, lastCorner.fY,
-                                lastCorner.fX + firstStep.fX,
-                                lastCorner.fY + firstStep.fY);
-                }
-                dst->close();
-                prevIsValid = false;
-                break;
-            case SkPath::kDone_Verb:
-                if (prevIsValid) {
-                    dst->lineTo(lastCorner);
-                }
-                return true;
-            default:
-                SkDEBUGFAIL("default should not be reached");
-                return false;
-        }
 
-        if (SkPath::kMove_Verb == prevVerb) {
-            firstStep = step;
+            if (SkPath::kMove_Verb == prevVerb) {
+                firstStep = step;
+            }
+            prevVerb = verb;
         }
-        prevVerb = verb;
+        return true;
     }
 
-    return true;
+    bool computeFastBounds(SkRect*) const override {
+        // Rounding sharp corners within a path produces a new path that is still contained within
+        // the original's bounds, so leave 'bounds' unmodified.
+        return true;
+    }
+
+    static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
+        return SkCornerPathEffect::Make(buffer.readScalar());
+    }
+
+    void flatten(SkWriteBuffer& buffer) const override {
+        buffer.writeScalar(fRadius);
+    }
+
+    Factory getFactory() const override { return CreateProc; }
+    const char* getTypeName() const override { return "SkCornerPathEffect"; }
+
+private:
+    const SkScalar fRadius;
+
+    using INHERITED = SkPathEffect;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+sk_sp<SkPathEffect> SkCornerPathEffect::Make(SkScalar radius) {
+    return SkScalarIsFinite(radius) && (radius > 0) ?
+            sk_sp<SkPathEffect>(new SkCornerPathEffectImpl(radius)) : nullptr;
 }
 
-sk_sp<SkFlattenable> SkCornerPathEffect::CreateProc(SkReadBuffer& buffer) {
-    return SkCornerPathEffect::Make(buffer.readScalar());
-}
-
-void SkCornerPathEffect::flatten(SkWriteBuffer& buffer) const {
-    buffer.writeScalar(fRadius);
+void SkCornerPathEffect::RegisterFlattenables() {
+    SkFlattenable::Register("SkCornerPathEffect", SkCornerPathEffectImpl::CreateProc);
 }
diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp
index 342fe2e..e6dabcf 100644
--- a/src/effects/SkDiscretePathEffect.cpp
+++ b/src/effects/SkDiscretePathEffect.cpp
@@ -14,31 +14,6 @@
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
 
-sk_sp<SkPathEffect> SkDiscretePathEffect::Make(SkScalar segLength, SkScalar deviation,
-                                               uint32_t seedAssist) {
-    if (!SkScalarIsFinite(segLength) || !SkScalarIsFinite(deviation)) {
-        return nullptr;
-    }
-    if (segLength <= SK_ScalarNearlyZero) {
-        return nullptr;
-    }
-    return sk_sp<SkPathEffect>(new SkDiscretePathEffect(segLength, deviation, seedAssist));
-}
-
-static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) {
-    SkVector normal = tangent;
-    SkPointPriv::RotateCCW(&normal);
-    normal.setLength(scale);
-    *p += normal;
-}
-
-SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength,
-                                           SkScalar deviation,
-                                           uint32_t seedAssist)
-    : fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
-{
-}
-
 /** \class LCGRandom
 
     Utility class that implements pseudo random 32bit numbers using a fast
@@ -49,7 +24,6 @@
     methods used by SkDiscretePathEffect::filterPath, with methods that were
     not called directly moved to private.
 */
-
 class LCGRandom {
 public:
     LCGRandom(uint32_t seed) : fSeed(seed) {}
@@ -81,78 +55,124 @@
     uint32_t fSeed;
 };
 
-bool SkDiscretePathEffect::onFilterPath(SkPath* dst, const SkPath& src,
-                                        SkStrokeRec* rec, const SkRect*) const {
-    bool doFill = rec->isFillStyle();
+static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) {
+    SkVector normal = tangent;
+    SkPointPriv::RotateCCW(&normal);
+    normal.setLength(scale);
+    *p += normal;
+}
 
-    SkPathMeasure   meas(src, doFill);
+class SK_API SkDiscretePathEffectImpl : public SkPathEffect {
+public:
+    SkDiscretePathEffectImpl(SkScalar segLength, SkScalar deviation, uint32_t seedAssist)
+        : fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
+    {
+        SkASSERT(SkScalarIsFinite(segLength));
+        SkASSERT(SkScalarIsFinite(deviation));
+        SkASSERT(segLength > SK_ScalarNearlyZero);
+    }
 
-    /* Caller may supply their own seed assist, which by default is 0 */
-    uint32_t seed = fSeedAssist ^ SkScalarRoundToInt(meas.getLength());
+    bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
+                      const SkRect*) const override {
+        bool doFill = rec->isFillStyle();
 
-    LCGRandom   rand(seed ^ ((seed << 16) | (seed >> 16)));
-    SkScalar    scale = fPerterb;
-    SkPoint     p;
-    SkVector    v;
+        SkPathMeasure   meas(src, doFill);
 
-    do {
-        SkScalar    length = meas.getLength();
-#if defined(SK_BUILD_FOR_FUZZER)
-        if (length > 1000) {
-            return false;
-        }
-#endif
+        /* Caller may supply their own seed assist, which by default is 0 */
+        uint32_t seed = fSeedAssist ^ SkScalarRoundToInt(meas.getLength());
 
-        if (fSegLength * (2 + doFill) > length) {
-            meas.getSegment(0, length, dst, true);  // to short for us to mangle
-        } else {
-            int         n = SkScalarRoundToInt(length / fSegLength);
-            constexpr int kMaxReasonableIterations = 100000;
-            n = std::min(n, kMaxReasonableIterations);
-            SkScalar    delta = length / n;
-            SkScalar    distance = 0;
+        LCGRandom   rand(seed ^ ((seed << 16) | (seed >> 16)));
+        SkScalar    scale = fPerterb;
+        SkPoint     p;
+        SkVector    v;
 
-            if (meas.isClosed()) {
-                n -= 1;
-                distance += delta/2;
+        do {
+            SkScalar    length = meas.getLength();
+    #if defined(SK_BUILD_FOR_FUZZER)
+            if (length > 1000) {
+                return false;
             }
+    #endif
 
-            if (meas.getPosTan(distance, &p, &v)) {
-                Perterb(&p, v, rand.nextSScalar1() * scale);
-                dst->moveTo(p);
-            }
-            while (--n >= 0) {
-                distance += delta;
+            if (fSegLength * (2 + doFill) > length) {
+                meas.getSegment(0, length, dst, true);  // to short for us to mangle
+            } else {
+                int         n = SkScalarRoundToInt(length / fSegLength);
+                constexpr int kMaxReasonableIterations = 100000;
+                n = std::min(n, kMaxReasonableIterations);
+                SkScalar    delta = length / n;
+                SkScalar    distance = 0;
+
+                if (meas.isClosed()) {
+                    n -= 1;
+                    distance += delta/2;
+                }
+
                 if (meas.getPosTan(distance, &p, &v)) {
                     Perterb(&p, v, rand.nextSScalar1() * scale);
-                    dst->lineTo(p);
+                    dst->moveTo(p);
+                }
+                while (--n >= 0) {
+                    distance += delta;
+                    if (meas.getPosTan(distance, &p, &v)) {
+                        Perterb(&p, v, rand.nextSScalar1() * scale);
+                        dst->lineTo(p);
+                    }
+                }
+                if (meas.isClosed()) {
+                    dst->close();
                 }
             }
-            if (meas.isClosed()) {
-                dst->close();
-            }
-        }
-    } while (meas.nextContour());
-    return true;
-}
-
-bool SkDiscretePathEffect::computeFastBounds(SkRect* bounds) const {
-    if (bounds) {
-        SkScalar maxOutset = SkScalarAbs(fPerterb);
-        bounds->outset(maxOutset, maxOutset);
+        } while (meas.nextContour());
+        return true;
     }
-    return true;
+
+    bool computeFastBounds(SkRect* bounds) const override {
+        if (bounds) {
+            SkScalar maxOutset = SkScalarAbs(fPerterb);
+            bounds->outset(maxOutset, maxOutset);
+        }
+        return true;
+    }
+
+    static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer) {
+        SkScalar segLength = buffer.readScalar();
+        SkScalar perterb = buffer.readScalar();
+        uint32_t seed = buffer.readUInt();
+        return SkDiscretePathEffect::Make(segLength, perterb, seed);
+    }
+
+    void flatten(SkWriteBuffer& buffer) const override {
+        buffer.writeScalar(fSegLength);
+        buffer.writeScalar(fPerterb);
+        buffer.writeUInt(fSeedAssist);
+    }
+
+    Factory getFactory() const override { return CreateProc; }
+    const char* getTypeName() const override { return "SkDiscretePathEffect"; }
+
+private:
+    const SkScalar fSegLength,
+                   fPerterb;
+    /* Caller-supplied 32 bit seed assist */
+    const uint32_t fSeedAssist;
+
+    using INHERITED = SkPathEffect;
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+sk_sp<SkPathEffect> SkDiscretePathEffect::Make(SkScalar segLength, SkScalar deviation,
+                                               uint32_t seedAssist) {
+    if (!SkScalarIsFinite(segLength) || !SkScalarIsFinite(deviation)) {
+        return nullptr;
+    }
+    if (segLength <= SK_ScalarNearlyZero) {
+        return nullptr;
+    }
+    return sk_sp<SkPathEffect>(new SkDiscretePathEffectImpl(segLength, deviation, seedAssist));
 }
 
-sk_sp<SkFlattenable> SkDiscretePathEffect::CreateProc(SkReadBuffer& buffer) {
-    SkScalar segLength = buffer.readScalar();
-    SkScalar perterb = buffer.readScalar();
-    uint32_t seed = buffer.readUInt();
-    return Make(segLength, perterb, seed);
-}
-
-void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
-    buffer.writeScalar(fSegLength);
-    buffer.writeScalar(fPerterb);
-    buffer.writeUInt(fSeedAssist);
+void SkDiscretePathEffect::RegisterFlattenables() {
+    SkFlattenable::Register("SkDiscretePathEffect", SkDiscretePathEffectImpl::CreateProc);
 }
diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp
index 97f4bfb..29fe799 100644
--- a/src/ports/SkGlobalInitialization_default.cpp
+++ b/src/ports/SkGlobalInitialization_default.cpp
@@ -86,9 +86,9 @@
         SkShaderMaskFilter::RegisterFlattenables();
 
         // Path effects.
-        SK_REGISTER_FLATTENABLE(SkCornerPathEffect);
+        SkCornerPathEffect::RegisterFlattenables();
         SK_REGISTER_FLATTENABLE(SkDashImpl);
-        SK_REGISTER_FLATTENABLE(SkDiscretePathEffect);
+        SkDiscretePathEffect::RegisterFlattenables();
         SkLine2DPathEffect::RegisterFlattenables();
         SkPath2DPathEffect::RegisterFlattenables();
         SK_REGISTER_FLATTENABLE(SkMatrixPE);