move patheffect virtuals to protected and rename

- change filterPath to safely handle if src and dst are aliases

Bug: skia:8254
Change-Id: I125d19404ca0a610f73271abb5c5455d1d50f9ed
Reviewed-on: https://skia-review.googlesource.com/147466
Commit-Queue: Mike Reed <reed@google.com>
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
Auto-Submit: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2018-08-16 13:22:16 -04:00 committed by Skia Commit-Bot
parent cbb7d572aa
commit 6d10f8bda1
20 changed files with 150 additions and 131 deletions

View File

@ -58,14 +58,13 @@ public:
* If this method returns true, the caller will apply (as needed) the
* resulting stroke-rec to dst and then draw.
*/
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect* cullR) const = 0;
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect* cullR) const;
/**
* Compute a conservative bounds for its effect, given the src bounds.
* The baseline implementation just assigns src to dst.
*/
virtual void computeFastBounds(SkRect* dst, const SkRect& src) const;
void computeFastBounds(SkRect* dst, const SkRect& src) const;
/** \class PointData
@ -112,7 +111,7 @@ public:
* Does applying this path effect to 'src' yield a set of points? If so,
* optionally return the points in 'results'.
*/
virtual bool asPoints(PointData* results, const SkPath& src,
bool asPoints(PointData* results, const SkPath& src,
const SkStrokeRec&, const SkMatrix&,
const SkRect* cullR) const;
@ -143,7 +142,7 @@ public:
// mod the sum of all intervals
};
virtual DashType asADash(DashInfo* info) const;
DashType asADash(DashInfo* info) const;
static void InitializeFlattenables();
@ -170,6 +169,18 @@ public:
protected:
SkPathEffect() {}
virtual bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const = 0;
virtual SkRect onComputeFastBounds(const SkRect& src) const {
return src;
}
virtual bool onAsPoints(PointData*, const SkPath&, const SkStrokeRec&, const SkMatrix&,
const SkRect*) const {
return false;
}
virtual DashType onAsADash(DashInfo*) const {
return kNone_DashType;
}
private:
// illegal
SkPathEffect(const SkPathEffect&);

View File

@ -17,10 +17,9 @@ class SkPathMeasure;
// This class is not exported to java.
class SK_API Sk1DPathEffect : public SkPathEffect {
public:
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override;
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
/** Called at the start of each contour, returns the initial offset
into that contour.
*/
@ -59,14 +58,12 @@ public:
*/
static sk_sp<SkPathEffect> Make(const SkPath& path, SkScalar advance, SkScalar phase, Style);
virtual bool filterPath(SkPath*, const SkPath&,
SkStrokeRec*, const SkRect*) const override;
Factory getFactory() const override { return CreateProc; }
protected:
SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const override;
// overrides from Sk1DPathEffect
SkScalar begin(SkScalar contourLength) const override;

View File

@ -14,9 +14,6 @@
#include "SkMatrix.h"
class SK_API Sk2DPathEffect : public SkPathEffect {
public:
bool filterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const override;
protected:
/** New virtual, to be overridden by subclasses.
This is called once from filterPath, and provides the
@ -39,6 +36,7 @@ protected:
// protected so that subclasses can call this during unflattening
explicit Sk2DPathEffect(const SkMatrix& mat);
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const override;
private:
SkMatrix fMatrix, fInverse;
@ -61,8 +59,6 @@ public:
return sk_sp<SkPathEffect>(new SkLine2DPathEffect(width, matrix));
}
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override;
Factory getFactory() const override { return CreateProc; }
@ -72,6 +68,7 @@ protected:
SkASSERT(width >= 0);
}
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
void nextSpan(int u, int v, int ucount, SkPath*) const override;

View File

@ -25,9 +25,6 @@ public:
return radius > 0 ? sk_sp<SkPathEffect>(new SkCornerPathEffect(radius)) : nullptr;
}
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override;
Factory getFactory() const override { return CreateProc; }
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@ -41,6 +38,7 @@ protected:
explicit SkCornerPathEffect(SkScalar radius);
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
private:
SkScalar fRadius;

View File

@ -32,9 +32,6 @@ public:
*/
static sk_sp<SkPathEffect> Make(SkScalar segLength, SkScalar dev, uint32_t seedAssist = 0);
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override;
Factory getFactory() const override { return CreateProc; }
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@ -46,6 +43,7 @@ protected:
SkScalar deviation,
uint32_t seedAssist);
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);

View File

@ -77,8 +77,8 @@ sk_sp<SkFlattenable> Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) {
class InverseFillPE : public SkPathEffect {
public:
InverseFillPE() {}
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override {
virtual bool onFilterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override {
*dst = src;
dst->setFillType(SkPath::kInverseWinding_FillType);
return true;

View File

@ -12,17 +12,32 @@
///////////////////////////////////////////////////////////////////////////////
void SkPathEffect::computeFastBounds(SkRect* dst, const SkRect& src) const {
*dst = src;
}
bool SkPathEffect::asPoints(PointData* results, const SkPath& src,
const SkStrokeRec&, const SkMatrix&, const SkRect*) const {
bool SkPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* bounds) const {
SkPath tmp, *tmpDst = dst;
if (dst == &src) {
tmpDst = &tmp;
}
if (this->onFilterPath(tmpDst, src, rec, bounds)) {
if (dst == &src) {
*dst = tmp;
}
return true;
}
return false;
}
void SkPathEffect::computeFastBounds(SkRect* dst, const SkRect& src) const {
*dst = this->onComputeFastBounds(src);
}
bool SkPathEffect::asPoints(PointData* results, const SkPath& src,
const SkStrokeRec& rec, const SkMatrix& mx, const SkRect* rect) const {
return this->onAsPoints(results, src, rec, mx, rect);
}
SkPathEffect::DashType SkPathEffect::asADash(DashInfo* info) const {
return kNone_DashType;
return this->onAsADash(info);
}
///////////////////////////////////////////////////////////////////////////////
@ -79,18 +94,6 @@ public:
return sk_sp<SkPathEffect>(new SkComposePathEffect(outer, inner));
}
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const override {
SkPath tmp;
const SkPath* ptr = &src;
if (fPE1->filterPath(&tmp, src, rec, cullRect)) {
ptr = &tmp;
}
return fPE0->filterPath(dst, *ptr, rec, cullRect);
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@ -101,6 +104,17 @@ protected:
SkComposePathEffect(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner)
: INHERITED(outer, inner) {}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const override {
SkPath tmp;
const SkPath* ptr = &src;
if (fPE1->filterPath(&tmp, src, rec, cullRect)) {
ptr = &tmp;
}
return fPE0->filterPath(dst, *ptr, rec, cullRect);
}
private:
// illegal
SkComposePathEffect(const SkComposePathEffect&);
@ -140,14 +154,6 @@ public:
return sk_sp<SkPathEffect>(new SkSumPathEffect(first, second));
}
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const override {
// use bit-or so that we always call both, even if the first one succeeds
return fPE0->filterPath(dst, src, rec, cullRect) |
fPE1->filterPath(dst, src, rec, cullRect);
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@ -156,7 +162,14 @@ public:
protected:
SkSumPathEffect(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second)
: INHERITED(first, second) {}
: INHERITED(first, second) {}
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const override {
// use bit-or so that we always call both, even if the first one succeeds
return fPE0->filterPath(dst, src, rec, cullRect) |
fPE1->filterPath(dst, src, rec, cullRect);
}
private:
// illegal

View File

@ -16,8 +16,8 @@
// Put in a governor to limit crash values from looping too long (and allocating too much ram).
#define MAX_REASONABLE_ITERATIONS 100000
bool Sk1DPathEffect::filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const {
bool Sk1DPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const {
SkPathMeasure meas(src, false);
do {
int governor = MAX_REASONABLE_ITERATIONS;
@ -69,10 +69,10 @@ SkPath1DPathEffect::SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkS
fStyle = style;
}
bool SkPath1DPathEffect::filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec* rec, const SkRect* cullRect) const {
bool SkPath1DPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
SkStrokeRec* rec, const SkRect* cullRect) const {
rec->setFillStyle();
return this->INHERITED::filterPath(dst, src, rec, cullRect);
return this->INHERITED::onFilterPath(dst, src, rec, cullRect);
}
static bool morphpoints(SkPoint dst[], const SkPoint src[], int count,

View File

@ -18,8 +18,8 @@ Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
fMatrixIsInvertible = fMatrix.invert(&fInverse);
}
bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const {
bool Sk2DPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const {
if (!fMatrixIsInvertible) {
return false;
}
@ -76,8 +76,8 @@ void Sk2DPathEffect::flatten(SkWriteBuffer& buffer) const {
///////////////////////////////////////////////////////////////////////////////
bool SkLine2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec* rec, const SkRect* cullRect) const {
bool SkLine2DPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
SkStrokeRec* rec, const SkRect* cullRect) const {
if (this->INHERITED::filterPath(dst, src, rec, cullRect)) {
rec->setStrokeStyle(fWidth);
return true;

View File

@ -35,8 +35,8 @@ static bool ComputeStep(const SkPoint& a, const SkPoint& b, SkScalar radius,
}
}
bool SkCornerPathEffect::filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const {
bool SkCornerPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const {
if (fRadius <= 0) {
return false;
}

View File

@ -14,13 +14,6 @@ class SkDashImpl : public SkPathEffect {
public:
SkDashImpl(const SkScalar intervals[], int count, SkScalar phase);
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
bool asPoints(PointData* results, const SkPath& src, const SkStrokeRec&, const SkMatrix&,
const SkRect*) const override;
DashType asADash(DashInfo* info) const override;
Factory getFactory() const override { return CreateProc; }
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
@ -30,6 +23,12 @@ public:
protected:
~SkDashImpl() override;
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
bool onAsPoints(PointData* results, const SkPath& src, const SkStrokeRec&, const SkMatrix&,
const SkRect*) const override;
DashType onAsADash(DashInfo* info) const override;
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);

View File

@ -40,8 +40,8 @@ SkDashImpl::~SkDashImpl() {
sk_free(fIntervals);
}
bool SkDashImpl::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const {
bool SkDashImpl::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const {
return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals, fCount,
fInitialDashLength, fInitialDashIndex, fIntervalLength);
}
@ -164,8 +164,8 @@ static bool cull_line(SkPoint* pts, const SkStrokeRec& rec,
// we need to:
// allow kRound_Cap capping (could allow rotations in the matrix with this)
// allow paths to be returned
bool SkDashImpl::asPoints(PointData* results, const SkPath& src, const SkStrokeRec& rec,
const SkMatrix& matrix, const SkRect* cullRect) const {
bool SkDashImpl::onAsPoints(PointData* results, const SkPath& src, const SkStrokeRec& rec,
const SkMatrix& matrix, const SkRect* cullRect) const {
// width < 0 -> fill && width == 0 -> hairline so requiring width > 0 rules both out
if (0 >= rec.getWidth()) {
return false;
@ -357,7 +357,7 @@ bool SkDashImpl::asPoints(PointData* results, const SkPath& src, const SkStrokeR
return true;
}
SkPathEffect::DashType SkDashImpl::asADash(DashInfo* info) const {
SkPathEffect::DashType SkDashImpl::onAsADash(DashInfo* info) const {
if (info) {
if (info->fCount >= fCount && info->fIntervals) {
memcpy(info->fIntervals, fIntervals, fCount * sizeof(SkScalar));

View File

@ -81,8 +81,8 @@ private:
uint32_t fSeed;
};
bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec* rec, const SkRect*) const {
bool SkDiscretePathEffect::onFilterPath(SkPath* dst, const SkPath& src,
SkStrokeRec* rec, const SkRect*) const {
bool doFill = rec->isFillStyle();
SkPathMeasure meas(src, doFill);

View File

@ -14,12 +14,11 @@ class SkOpPE : public SkPathEffect {
public:
SkOpPE(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two, SkPathOp op);
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
Factory getFactory() const override { return CreateProc; }
protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);
@ -36,12 +35,11 @@ class SkMatrixPE : public SkPathEffect {
public:
SkMatrixPE(const SkMatrix&);
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
Factory getFactory() const override { return CreateProc; }
protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);
@ -56,12 +54,12 @@ class SkStrokePE : public SkPathEffect {
public:
SkStrokePE(SkScalar width, SkPaint::Join, SkPaint::Cap, SkScalar miter);
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
Factory getFactory() const override { return CreateProc; }
protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
// TODO: override onComputeFastBounds (I think)
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);

View File

@ -18,8 +18,8 @@ sk_sp<SkPathEffect> SkMergePathEffect::Make(sk_sp<SkPathEffect> one, sk_sp<SkPat
SkOpPE::SkOpPE(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two, SkPathOp op)
: fOne(std::move(one)), fTwo(std::move(two)), fOp(op) {}
bool SkOpPE::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cull) const {
bool SkOpPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cull) const {
SkPath one, two;
if (fOne) {
if (!fOne->filterPath(&one, src, rec, cull)) {
@ -71,7 +71,7 @@ SkMatrixPE::SkMatrixPE(const SkMatrix& matrix) : fMatrix(matrix) {
SkASSERT(matrix.isFinite());
}
bool SkMatrixPE::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
bool SkMatrixPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
src.transform(fMatrix, dst);
return true;
}
@ -99,7 +99,7 @@ sk_sp<SkPathEffect> SkStrokePathEffect::Make(SkScalar width, SkPaint::Join join,
SkStrokePE::SkStrokePE(SkScalar width, SkPaint::Join join, SkPaint::Cap cap, SkScalar miter)
: fWidth(width), fMiter(miter), fJoin(join), fCap(cap) {}
bool SkStrokePE::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
bool SkStrokePE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
rec.setStrokeStyle(fWidth);
rec.setStrokeParams(fCap, fJoin, fMiter);

View File

@ -17,12 +17,11 @@ class SkTrimPE : public SkPathEffect {
public:
SkTrimPE(SkScalar startT, SkScalar stopT, SkTrimPathEffect::Mode);
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTrimPE)
protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override;
private:
const SkScalar fStartT,

View File

@ -53,7 +53,7 @@ private:
SkTrimPE::SkTrimPE(SkScalar startT, SkScalar stopT, SkTrimPathEffect::Mode mode)
: fStartT(startT), fStopT(stopT), fMode(mode) {}
bool SkTrimPE::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
bool SkTrimPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const {
if (fStartT >= fStopT) {
SkASSERT(fMode == SkTrimPathEffect::Mode::kNormal);

View File

@ -285,13 +285,13 @@ TestDashPathEffect::TestDashPathEffect(const SkScalar* intervals, int count, SkS
&fInitialDashIndex, &fIntervalLength, &fPhase);
}
bool TestDashPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const {
bool TestDashPathEffect::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
const SkRect* cullRect) const {
return SkDashPath::InternalFilter(dst, src, rec, cullRect, fIntervals.get(), fCount,
fInitialDashLength, fInitialDashIndex, fIntervalLength);
}
SkPathEffect::DashType TestDashPathEffect::asADash(DashInfo* info) const {
SkPathEffect::DashType TestDashPathEffect::onAsADash(DashInfo* info) const {
if (info) {
if (info->fCount >= fCount && info->fIntervals) {
memcpy(info->fIntervals, fIntervals.get(), fCount * sizeof(SkScalar));

View File

@ -72,10 +72,12 @@ public:
return sk_sp<SkPathEffect>(new TestDashPathEffect(intervals, count, phase));
}
bool filterPath(SkPath* dst, const SkPath&, SkStrokeRec* , const SkRect*) const override;
DashType asADash(DashInfo* info) const override;
Factory getFactory() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath&, SkStrokeRec* , const SkRect*) const override;
DashType onAsADash(DashInfo* info) const override;
private:
TestDashPathEffect(const SkScalar* intervals, int count, SkScalar phase);

View File

@ -1152,17 +1152,21 @@ void test_path_effect_makes_rrect(skiatest::Reporter* reporter, const Geo& geo)
return kRRect;
}
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new RRectPathEffect); }
Factory getFactory() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
dst->reset();
dst->addRRect(RRect());
return true;
}
void computeFastBounds(SkRect* dst, const SkRect& src) const override {
*dst = RRect().getBounds();
SkRect onComputeFastBounds(const SkRect& src) const override {
return RRect().getBounds();
}
static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new RRectPathEffect); }
Factory getFactory() const override { return nullptr; }
private:
RRectPathEffect() {}
};
@ -1229,8 +1233,12 @@ void test_unknown_path_effect(skiatest::Reporter* reporter, const Geo& geo) {
*/
class AddLineTosPathEffect : SkPathEffect {
public:
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new AddLineTosPathEffect); }
Factory getFactory() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
*dst = src;
// To avoid triggering data-based keying of paths with few verbs we add many segments.
for (int i = 0; i < 100; ++i) {
@ -1238,13 +1246,12 @@ void test_unknown_path_effect(skiatest::Reporter* reporter, const Geo& geo) {
}
return true;
}
void computeFastBounds(SkRect* dst, const SkRect& src) const override {
*dst = src;
SkRectPriv::GrowToInclude(dst, {0, 0});
SkRectPriv::GrowToInclude(dst, {100, 100});
SkRect onComputeFastBounds(const SkRect& src) const override {
SkRect dst = src;
SkRectPriv::GrowToInclude(&dst, {0, 0});
SkRectPriv::GrowToInclude(&dst, {100, 100});
return dst;
}
static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new AddLineTosPathEffect); }
Factory getFactory() const override { return nullptr; }
private:
AddLineTosPathEffect() {}
};
@ -1270,17 +1277,18 @@ void test_make_hairline_path_effect(skiatest::Reporter* reporter, const Geo& geo
*/
class MakeHairlinePathEffect : SkPathEffect {
public:
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* strokeRec,
const SkRect* cullR) const override {
*dst = src;
strokeRec->setHairlineStyle();
return true;
}
void computeFastBounds(SkRect* dst, const SkRect& src) const override { *dst = src; }
static sk_sp<SkPathEffect> Make() {
return sk_sp<SkPathEffect>(new MakeHairlinePathEffect);
}
Factory getFactory() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* strokeRec,
const SkRect* cullR) const override {
*dst = src;
strokeRec->setHairlineStyle();
return true;
}
private:
MakeHairlinePathEffect() {}
};
@ -1351,21 +1359,22 @@ void test_path_effect_makes_empty_shape(skiatest::Reporter* reporter, const Geo&
*/
class EmptyPathEffect : SkPathEffect {
public:
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
static sk_sp<SkPathEffect> Make(bool invert) {
return sk_sp<SkPathEffect>(new EmptyPathEffect(invert));
}
Factory getFactory() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
dst->reset();
if (fInvert) {
dst->toggleInverseFillType();
}
return true;
}
void computeFastBounds(SkRect* dst, const SkRect& src) const override {
dst->setEmpty();
SkRect onComputeFastBounds(const SkRect& src) const override {
return { 0, 0, 0, 0 };
}
static sk_sp<SkPathEffect> Make(bool invert) {
return sk_sp<SkPathEffect>(new EmptyPathEffect(invert));
}
Factory getFactory() const override { return nullptr; }
private:
bool fInvert;
EmptyPathEffect(bool invert) : fInvert(invert) {}
@ -1437,15 +1446,13 @@ void test_path_effect_fails(skiatest::Reporter* reporter, const Geo& geo) {
*/
class FailurePathEffect : SkPathEffect {
public:
bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
return false;
}
void computeFastBounds(SkRect* dst, const SkRect& src) const override {
*dst = src;
}
static sk_sp<SkPathEffect> Make() { return sk_sp<SkPathEffect>(new FailurePathEffect); }
Factory getFactory() const override { return nullptr; }
protected:
bool onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*,
const SkRect* cullR) const override {
return false;
}
private:
FailurePathEffect() {}
};