add new patheffects

Bug: skia:
Change-Id: Icc94eafbb26a097d5032cdb4f6e2e0f52a4e1025
Reviewed-on: https://skia-review.googlesource.com/141961
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Mike Reed 2018-07-18 13:28:42 -04:00 committed by Skia Commit-Bot
parent 0afc75e754
commit 0ef539af4c
6 changed files with 306 additions and 2 deletions

View File

@ -161,9 +161,66 @@ private:
typedef GM INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static GM* PathEffectFactory(void*) { return new PathEffectGM; }
static GMRegistry regPathEffect(PathEffectFactory);
}
//////////////////////////////////////////////////////////////////////////////
#include "SkOpPathEffect.h"
class ComboPathEfectsGM : public skiagm::GM {
public:
ComboPathEfectsGM() {}
protected:
SkString onShortName() override {
return SkString("combo-patheffects");
}
SkISize onISize() override { return SkISize::Make(360, 630); }
void onDraw(SkCanvas* canvas) override {
SkPath path0, path1, path2;
path0.addCircle(100, 100, 60);
path1.moveTo(20, 20); path1.cubicTo(20, 180, 140, 0, 140, 140);
sk_sp<SkPathEffect> effects[] = {
nullptr,
SkStrokePathEffect::Make(20, SkPaint::kRound_Join, SkPaint::kRound_Cap, 0),
SkOpPathEffect::Make(nullptr,
SkStrokePathEffect::Make(20, SkPaint::kRound_Join, SkPaint::kRound_Cap, 0),
kDifference_SkPathOp),
SkOpPathEffect::Make(SkMatrixPathEffect::MakeTranslate(50, 30),
SkStrokePathEffect::Make(20, SkPaint::kRound_Join, SkPaint::kRound_Cap, 0),
kReverseDifference_SkPathOp),
};
SkPaint wireframe;
wireframe.setStyle(SkPaint::kStroke_Style);
wireframe.setAntiAlias(true);
SkPaint paint;
paint.setColor(0xFF8888FF);
paint.setAntiAlias(true);
for (auto& path : { path0, path1 }) {
canvas->save();
for (auto pe : effects) {
paint.setPathEffect(pe);
canvas->drawPath(path, paint);
canvas->drawPath(path, wireframe);
canvas->translate(0, 150);
}
canvas->restore();
canvas->translate(180, 0);
}
}
private:
typedef GM INHERITED;
};
DEF_GM(return new ComboPathEfectsGM;)

View File

@ -23,6 +23,7 @@ skia_effects_sources = [
"$_src/effects/SkHighContrastFilter.cpp",
"$_src/effects/SkLayerDrawLooper.cpp",
"$_src/effects/SkLumaColorFilter.cpp",
"$_src/effects/SkOpPathEffect.cpp",
"$_src/effects/SkOverdrawColorFilter.cpp",
"$_src/effects/SkPackBits.cpp",
"$_src/effects/SkPackBits.h",

View File

@ -0,0 +1,38 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkOpPathEffect_DEFINED
#define SkOpPathEffect_DEFINED
#include "SkPathEffect.h"
#include "SkPaint.h"
#include "SkPathOps.h"
class SkOpPathEffect {
public:
/* Defers to two other patheffects, and then combines their outputs using the specified op.
* e.g.
* result = output_one op output_two
*
* If either one or two is nullptr, then the original path is passed through to the op.
*/
static sk_sp<SkPathEffect> Make(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two, SkPathOp op);
};
class SkMatrixPathEffect {
public:
static sk_sp<SkPathEffect> MakeTranslate(SkScalar dx, SkScalar dy);
static sk_sp<SkPathEffect> Make(const SkMatrix&);
};
class SkStrokePathEffect {
public:
static sk_sp<SkPathEffect> Make(SkScalar width, SkPaint::Join, SkPaint::Cap,
SkScalar miter = 4);
};
#endif

79
src/effects/SkOpPE.h Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkOpPE_DEFINED
#define SkOpPE_DEFINED
#include "SkOpPathEffect.h"
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;
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);
friend class SkFlattenable::PrivateInitializer;
sk_sp<SkPathEffect> fOne;
sk_sp<SkPathEffect> fTwo;
SkPathOp fOp;
typedef SkPathEffect INHERITED;
};
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;
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);
friend class SkFlattenable::PrivateInitializer;
SkMatrix fMatrix;
typedef SkPathEffect INHERITED;
};
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;
private:
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer&);
friend class SkFlattenable::PrivateInitializer;
SkScalar fWidth,
fMiter;
SkPaint::Join fJoin;
SkPaint::Cap fCap;
typedef SkPathEffect INHERITED;
};
#endif

View File

@ -0,0 +1,124 @@
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkOpPE.h"
#include "SkStrokeRec.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
sk_sp<SkPathEffect> SkOpPathEffect::Make(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two,
SkPathOp op) {
return sk_sp<SkPathEffect>(new SkOpPE(std::move(one), std::move(two), op));
}
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 {
SkPath one, two;
if (fOne) {
if (!fOne->filterPath(&one, src, rec, cull)) {
return false;
}
} else {
one = src;
}
if (fTwo) {
if (!fTwo->filterPath(&two, src, rec, cull)) {
return false;
}
} else {
two = src;
}
return Op(one, two, fOp, dst);
}
void SkOpPE::flatten(SkWriteBuffer& buffer) const {
buffer.writeFlattenable(fOne.get());
buffer.writeFlattenable(fTwo.get());
buffer.write32(fOp);
}
sk_sp<SkFlattenable> SkOpPE::CreateProc(SkReadBuffer& buffer) {
auto one = buffer.readPathEffect();
auto two = buffer.readPathEffect();
SkPathOp op = buffer.read32LE(kReverseDifference_SkPathOp);
return buffer.isValid() ? SkOpPathEffect::Make(std::move(one), std::move(two), op) : nullptr;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkPathEffect> SkMatrixPathEffect::MakeTranslate(SkScalar dx, SkScalar dy) {
if (!SkScalarsAreFinite(dx, dy)) {
return nullptr;
}
return sk_sp<SkPathEffect>(new SkMatrixPE(SkMatrix::MakeTrans(dx, dy)));
}
sk_sp<SkPathEffect> SkMatrixPathEffect::Make(const SkMatrix& matrix) {
if (!matrix.isFinite()) {
return nullptr;
}
return sk_sp<SkPathEffect>(new SkMatrixPE(matrix));
}
SkMatrixPE::SkMatrixPE(const SkMatrix& matrix) : fMatrix(matrix) {
SkASSERT(matrix.isFinite());
}
bool SkMatrixPE::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
src.transform(fMatrix, dst);
return true;
}
void SkMatrixPE::flatten(SkWriteBuffer& buffer) const {
buffer.writeMatrix(fMatrix);
}
sk_sp<SkFlattenable> SkMatrixPE::CreateProc(SkReadBuffer& buffer) {
SkMatrix mx;
buffer.readMatrix(&mx);
return buffer.isValid() ? SkMatrixPathEffect::Make(mx) : nullptr;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
sk_sp<SkPathEffect> SkStrokePathEffect::Make(SkScalar width, SkPaint::Join join, SkPaint::Cap cap,
SkScalar miter) {
if (!SkScalarsAreFinite(width, miter) || width < 0 || miter < 0) {
return nullptr;
}
return sk_sp<SkPathEffect>(new SkStrokePE(width, join, cap, miter));
}
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 {
SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
rec.setStrokeStyle(fWidth);
rec.setStrokeParams(fCap, fJoin, fMiter);
return rec.applyToPath(dst, src);
}
void SkStrokePE::flatten(SkWriteBuffer& buffer) const {
buffer.writeScalar(fWidth);
buffer.writeScalar(fMiter);
buffer.write32(fJoin);
buffer.write32(fCap);
}
sk_sp<SkFlattenable> SkStrokePE::CreateProc(SkReadBuffer& buffer) {
SkScalar width = buffer.readScalar();
SkScalar miter = buffer.readScalar();
SkPaint::Join join = buffer.read32LE(SkPaint::kLast_Join);
SkPaint::Cap cap = buffer.read32LE(SkPaint::kLast_Cap);
return buffer.isValid() ? SkStrokePathEffect::Make(width, join, cap, miter) : nullptr;
}

View File

@ -23,6 +23,7 @@
#include "SkShaderMaskFilter.h"
#include "SkTableColorFilter.h"
#include "SkToSRGBColorFilter.h"
#include "../../src/effects/SkOpPE.h"
#include "../../src/effects/SkTrimPE.h"
/*
@ -64,4 +65,8 @@ void SkFlattenable::PrivateInitializer::InitEffects() {
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTrimPE)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkOpPE)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixPE)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkStrokePE)
}