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:
parent
0afc75e754
commit
0ef539af4c
@ -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;)
|
||||
|
||||
|
@ -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",
|
||||
|
38
include/effects/SkOpPathEffect.h
Normal file
38
include/effects/SkOpPathEffect.h
Normal 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
79
src/effects/SkOpPE.h
Normal 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
|
||||
|
124
src/effects/SkOpPathEffect.cpp
Normal file
124
src/effects/SkOpPathEffect.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user