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