diff options
-rw-r--r-- | gm/dashcubics.cpp | 40 | ||||
-rw-r--r-- | gn/effects.gni | 1 | ||||
-rw-r--r-- | include/effects/SkTrimPathEffect.h | 36 | ||||
-rw-r--r-- | src/effects/SkDashImpl.h | 2 | ||||
-rw-r--r-- | src/effects/SkTrimPE.h | 32 | ||||
-rw-r--r-- | src/effects/SkTrimPathEffect.cpp | 63 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_default.cpp | 2 |
7 files changed, 175 insertions, 1 deletions
diff --git a/gm/dashcubics.cpp b/gm/dashcubics.cpp index e8d7f5bc8e..1d80d75b4a 100644 --- a/gm/dashcubics.cpp +++ b/gm/dashcubics.cpp @@ -58,3 +58,43 @@ DEF_SIMPLE_GM(dashcubics, canvas, 865, 750) { } } } + +#include "SkTrimPathEffect.h" +class TrimGM : public skiagm::GM { +public: + TrimGM() {} + +protected: + SkString onShortName() override { return SkString("trimpatheffect"); } + + SkISize onISize() override { return SkISize::Make(1240, 390); } + + void onDraw(SkCanvas* canvas) override { + SkPaint paint; + paint.setPathEffect(SkTrimPathEffect::Make(0.25 + fOffset, 0.75)); + paint.setStyle(SkPaint::kStroke_Style); + paint.setAntiAlias(true); + paint.setStrokeWidth(10); + + SkPath path; + path.moveTo(50, 300); + path.cubicTo(100, 50, 150, 550, 200, 300); + + paint.setColor(0xFF888888); + canvas->drawPath(path, paint); + paint.setPathEffect(nullptr); + paint.setStrokeWidth(0); + paint.setColor(0xFF000000); + canvas->drawPath(path, paint); + } + + bool onAnimate(const SkAnimTimer&) override { + // fOffset += 1; + return true; + } +private: + SkScalar fOffset = 0; + typedef skiagm::GM INHERITED; +}; +DEF_GM(return new TrimGM;) + diff --git a/gn/effects.gni b/gn/effects.gni index 5fb37e6bec..5b6a5fe21b 100644 --- a/gn/effects.gni +++ b/gn/effects.gni @@ -56,6 +56,7 @@ skia_effects_sources = [ "$_src/effects/SkTableMaskFilter.cpp", "$_src/effects/SkTileImageFilter.cpp", "$_src/effects/SkToSRGBColorFilter.cpp", + "$_src/effects/SkTrimPathEffect.cpp", "$_src/effects/SkXfermodeImageFilter.cpp", "$_src/shaders/SkPerlinNoiseShader.cpp", diff --git a/include/effects/SkTrimPathEffect.h b/include/effects/SkTrimPathEffect.h new file mode 100644 index 0000000000..d40c9e2bbf --- /dev/null +++ b/include/effects/SkTrimPathEffect.h @@ -0,0 +1,36 @@ +/* + * 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 SkTrimPathEffect_DEFINED +#define SkTrimPathEffect_DEFINED + +#include "SkPathEffect.h" + +class SK_API SkTrimPathEffect { +public: + /** + * Take start and stop "t" values (values between 0...1), and return a path that is that + * subset of the original path. + * + * e.g. + * Make(0.5, 1.0) --> return the 2nd half of the path + * Make(0.33333, 0.66667) --> return the middle third of the path + * + * The trim values apply to the entire path, so if it contains several contours, all of them + * are including in the calculation. + * + * startT and stopT must be 0..1 inclusive. If they are outside of that interval, they will + * be pinned to the nearest legal value. If either is NaN, null will be returned. + * + * Note: if startT < stopT, this will return one (logical) segment (even if it is spread + * across multiple contours). If startT > stopT, then this will return 2 logical + * segments: 0...stopT and startT...1 + */ + static sk_sp<SkPathEffect> Make(SkScalar startT, SkScalar stopT); +}; + +#endif diff --git a/src/effects/SkDashImpl.h b/src/effects/SkDashImpl.h index cf74529934..c4e81478c7 100644 --- a/src/effects/SkDashImpl.h +++ b/src/effects/SkDashImpl.h @@ -10,7 +10,7 @@ #include "SkPathEffect.h" -class SK_API SkDashImpl : public SkPathEffect { +class SkDashImpl : public SkPathEffect { public: SkDashImpl(const SkScalar intervals[], int count, SkScalar phase); diff --git a/src/effects/SkTrimPE.h b/src/effects/SkTrimPE.h new file mode 100644 index 0000000000..2cd39c4793 --- /dev/null +++ b/src/effects/SkTrimPE.h @@ -0,0 +1,32 @@ +/* + * 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 SkTrimImpl_DEFINED +#define SkTrimImpl_DEFINED + +#include "SkPathEffect.h" + +class SkTrimPE : public SkPathEffect { +public: + SkTrimPE(SkScalar startT, SkScalar stopT); + + bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const override; + + SK_TO_STRING_OVERRIDE() + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTrimPE) + +protected: + void flatten(SkWriteBuffer&) const override; + +private: + const SkScalar fStartT; + const SkScalar fStopT; + + typedef SkPathEffect INHERITED; +}; + +#endif diff --git a/src/effects/SkTrimPathEffect.cpp b/src/effects/SkTrimPathEffect.cpp new file mode 100644 index 0000000000..beaa36e17d --- /dev/null +++ b/src/effects/SkTrimPathEffect.cpp @@ -0,0 +1,63 @@ +/* + * 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 "SkPathMeasure.h" +#include "SkTrimPathEffect.h" +#include "SkTrimPE.h" +#include "SkReadBuffer.h" +#include "SkWriteBuffer.h" + +SkTrimPE::SkTrimPE(SkScalar startT, SkScalar stopT) : fStartT(startT), fStopT(stopT) { + SkASSERT(startT >= 0 && startT <= 1); + SkASSERT(stopT >= 0 && stopT <= 1); + SkASSERT(startT != stopT); +} + +bool SkTrimPE::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec, + const SkRect* cullRect) const { + SkPathMeasure meas(src, false); + SkScalar length = meas.getLength(); + + if (fStartT < fStopT) { + meas.getSegment(fStartT * length, fStopT * length, dst, true); + } else { + meas.getSegment(0, fStopT * length, dst, true); + meas.getSegment(fStartT * length, length, dst, true); + } + return true; +} + +void SkTrimPE::flatten(SkWriteBuffer& buffer) const { + buffer.writeScalar(fStartT); + buffer.writeScalar(fStopT); +} + +sk_sp<SkFlattenable> SkTrimPE::CreateProc(SkReadBuffer& buffer) { + SkScalar start = buffer.readScalar(); + SkScalar stop = buffer.readScalar(); + return SkTrimPathEffect::Make(start, stop); +} + +#ifndef SK_IGNORE_TO_STRING +void SkTrimPE::toString(SkString* str) const { + str->appendf("SkTrimPathEffect: (%g %g)", fStartT, fStopT); +} +#endif + +////////////////////////////////////////////////////////////////////////////////////////////////// + +sk_sp<SkPathEffect> SkTrimPathEffect::Make(SkScalar startT, SkScalar stopT) { + if (!SkScalarsAreFinite(startT, stopT)) { + return nullptr; + } + startT = SkTPin(startT, 0.f, 1.f); + stopT = SkTPin(stopT, 0.f, 1.f); + if (startT == stopT) { + return nullptr; + } + return sk_sp<SkPathEffect>(new SkTrimPE(startT, stopT)); +} diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp index bf6ea14323..ebfedb276d 100644 --- a/src/ports/SkGlobalInitialization_default.cpp +++ b/src/ports/SkGlobalInitialization_default.cpp @@ -40,6 +40,7 @@ #include "SkTableColorFilter.h" #include "SkTileImageFilter.h" #include "SkToSRGBColorFilter.h" +#include "../../src/effects/SkTrimPE.h" #include "SkXfermodeImageFilter.h" // Security note: @@ -90,6 +91,7 @@ void SkFlattenable::PrivateInitializer::InitEffects() { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath1DPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTrimPE) // ImageFilter SkImageFilter::InitializeFlattenables(); |