diff options
author | reed <reed@chromium.org> | 2014-12-17 01:47:32 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-17 01:47:32 -0800 |
commit | 8b5752443f34680d26a73bb6e1e72a8d7cf0f320 (patch) | |
tree | 25d12c07db584d2bc71b57bd87126f27b06c8916 | |
parent | 287ccfece68de4f2c5fc464a583f202626b38f8c (diff) |
add arcto patheffect
BUG=skia:
TBR=
Review URL: https://codereview.chromium.org/813513003
-rw-r--r-- | gyp/effects.gypi | 1 | ||||
-rw-r--r-- | include/effects/SkArcToPathEffect.h | 39 | ||||
-rw-r--r-- | samplecode/SamplePath.cpp | 65 | ||||
-rw-r--r-- | src/effects/SkArcToPathEffect.cpp | 70 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_chromium.cpp | 2 | ||||
-rw-r--r-- | src/ports/SkGlobalInitialization_default.cpp | 2 |
6 files changed, 159 insertions, 20 deletions
diff --git a/gyp/effects.gypi b/gyp/effects.gypi index c82d886318..88d5d1a842 100644 --- a/gyp/effects.gypi +++ b/gyp/effects.gypi @@ -10,6 +10,7 @@ '<(skia_src_path)/effects/Sk1DPathEffect.cpp', '<(skia_src_path)/effects/Sk2DPathEffect.cpp', '<(skia_src_path)/effects/SkAlphaThresholdFilter.cpp', + '<(skia_src_path)/effects/SkArcToPathEffect.cpp', '<(skia_src_path)/effects/SkArithmeticMode.cpp', '<(skia_src_path)/effects/SkAvoidXfermode.cpp', '<(skia_src_path)/effects/SkBitmapSource.cpp', diff --git a/include/effects/SkArcToPathEffect.h b/include/effects/SkArcToPathEffect.h new file mode 100644 index 0000000000..6b6e2c721c --- /dev/null +++ b/include/effects/SkArcToPathEffect.h @@ -0,0 +1,39 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkArcToPathEffect_DEFINED +#define SkArcToPathEffect_DEFINED + +#include "SkPathEffect.h" + +class SK_API SkArcToPathEffect : public SkPathEffect { +public: + /** radius must be > 0 to have an effect. It specifies the distance from each corner + that should be "rounded". + */ + static SkPathEffect* Create(SkScalar radius) { + if (radius <= 0) { + return NULL; + } + return SkNEW_ARGS(SkArcToPathEffect, (radius)); + } + + bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const SK_OVERRIDE; + + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArcToPathEffect) + +protected: + explicit SkArcToPathEffect(SkScalar radius); + virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; + +private: + SkScalar fRadius; + + typedef SkPathEffect INHERITED; +}; + +#endif diff --git a/samplecode/SamplePath.cpp b/samplecode/SamplePath.cpp index 49c51d3ad0..14aae8285c 100644 --- a/samplecode/SamplePath.cpp +++ b/samplecode/SamplePath.cpp @@ -214,45 +214,56 @@ DEF_SAMPLE( return new PathView; ) ////////////////////////////////////////////////////////////////////////////// +#include "SkArcToPathEffect.h" #include "SkCornerPathEffect.h" #include "SkRandom.h" class ArcToView : public SampleView { - SkPaint fPtsPaint, fArcPaint, fSkeletonPaint, fCornerPaint; + bool fDoFrame, fDoArcTo, fDoCorner, fDoConic; + SkPaint fPtsPaint, fArcToPaint, fSkeletonPaint, fCornerPaint; public: enum { N = 4 }; SkPoint fPts[N]; - SkScalar fRadius; - ArcToView() : fRadius(50) { + ArcToView() + : fDoFrame(false), fDoArcTo(false), fDoCorner(false), fDoConic(false) + { SkRandom rand; for (int i = 0; i < N; ++i) { fPts[i].fX = 20 + rand.nextUScalar1() * 640; fPts[i].fY = 20 + rand.nextUScalar1() * 480; } + + const SkScalar rad = 50; fPtsPaint.setAntiAlias(true); fPtsPaint.setStrokeWidth(15); fPtsPaint.setStrokeCap(SkPaint::kRound_Cap); - fArcPaint.setAntiAlias(true); - fArcPaint.setStyle(SkPaint::kStroke_Style); - fArcPaint.setStrokeWidth(9); - fArcPaint.setColor(0x800000FF); + fArcToPaint.setAntiAlias(true); + fArcToPaint.setStyle(SkPaint::kStroke_Style); + fArcToPaint.setStrokeWidth(9); + fArcToPaint.setColor(0x800000FF); + fArcToPaint.setPathEffect(SkArcToPathEffect::Create(rad))->unref(); fCornerPaint.setAntiAlias(true); fCornerPaint.setStyle(SkPaint::kStroke_Style); fCornerPaint.setStrokeWidth(13); fCornerPaint.setColor(SK_ColorGREEN); - fCornerPaint.setPathEffect(SkCornerPathEffect::Create(fRadius*2))->unref(); + fCornerPaint.setPathEffect(SkCornerPathEffect::Create(rad*2))->unref(); fSkeletonPaint.setAntiAlias(true); fSkeletonPaint.setStyle(SkPaint::kStroke_Style); fSkeletonPaint.setColor(SK_ColorRED); } + void toggle(bool& value) { + value = !value; + this->inval(NULL); + } + protected: // overrides from SkEventSink bool onQuery(SkEvent* evt) SK_OVERRIDE { @@ -260,29 +271,43 @@ protected: SampleCode::TitleR(evt, "ArcTo"); return true; } + SkUnichar uni; + if (SampleCode::CharQ(*evt, &uni)) { + switch (uni) { + case '1': this->toggle(fDoFrame); return true; + case '2': this->toggle(fDoArcTo); return true; + case '3': this->toggle(fDoCorner); return true; + case '4': this->toggle(fDoConic); return true; + default: break; + } + } return this->INHERITED::onQuery(evt); } + + void makePath(SkPath* path) { + path->moveTo(fPts[0]); + for (int i = 1; i < N; ++i) { + path->lineTo(fPts[i]); + } + if (!fDoFrame) { + path->close(); + } + } void onDrawContent(SkCanvas* canvas) SK_OVERRIDE { canvas->drawPoints(SkCanvas::kPoints_PointMode, N, fPts, fPtsPaint); SkPath path; + this->makePath(&path); - path.moveTo(fPts[0]); - for (int i = 1; i < N; ++i) { - path.lineTo(fPts[i].fX, fPts[i].fY); + if (fDoCorner) { + canvas->drawPath(path, fCornerPaint); } - canvas->drawPath(path, fCornerPaint); - - path.reset(); - path.moveTo(fPts[0]); - for (int i = 1; i < N - 1; ++i) { - path.arcTo(fPts[i].fX, fPts[i].fY, fPts[i+1].fX, fPts[i+1].fY, fRadius); + if (fDoArcTo) { + canvas->drawPath(path, fArcToPaint); } - path.lineTo(fPts[N - 1]); - canvas->drawPath(path, fArcPaint); - canvas->drawPoints(SkCanvas::kPolygon_PointMode, N, fPts, fSkeletonPaint); + canvas->drawPath(path, fSkeletonPaint); } bool onClick(Click* click) SK_OVERRIDE { diff --git a/src/effects/SkArcToPathEffect.cpp b/src/effects/SkArcToPathEffect.cpp new file mode 100644 index 0000000000..79398b3b82 --- /dev/null +++ b/src/effects/SkArcToPathEffect.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkArcToPathEffect.h" +#include "SkPath.h" +#include "SkPoint.h" +#include "SkReadBuffer.h" +#include "SkWriteBuffer.h" + +SkArcToPathEffect::SkArcToPathEffect(SkScalar radius) : fRadius(radius) {} + +bool SkArcToPathEffect::filterPath(SkPath* dst, const SkPath& src, + SkStrokeRec*, const SkRect*) const { + SkPath::Iter iter(src, false); + SkPath::Verb verb; + SkPoint pts[4]; + + SkPoint lastCorner = { 0, 0 }; // avoid warning + SkPath::Verb prevVerb = SkPath::kMove_Verb; + + for (;;) { + switch (verb = iter.next(pts, false)) { + case SkPath::kMove_Verb: + if (SkPath::kLine_Verb == prevVerb) { + dst->lineTo(lastCorner); + } + dst->moveTo(pts[0]); + break; + case SkPath::kLine_Verb: + if (prevVerb == SkPath::kLine_Verb) { + dst->arcTo(pts[0], pts[1], fRadius); + } + lastCorner = pts[1]; + break; + case SkPath::kQuad_Verb: + dst->quadTo(pts[1], pts[2]); + lastCorner = pts[2]; + break; + case SkPath::kConic_Verb: + dst->conicTo(pts[1], pts[2], iter.conicWeight()); + lastCorner = pts[2]; + break; + case SkPath::kCubic_Verb: + dst->cubicTo(pts[1], pts[2], pts[3]); + lastCorner = pts[3]; + break; + case SkPath::kClose_Verb: + dst->lineTo(lastCorner); + break; + case SkPath::kDone_Verb: + dst->lineTo(lastCorner); + goto DONE; + } + prevVerb = verb; + } +DONE: + return true; +} + +SkFlattenable* SkArcToPathEffect::CreateProc(SkReadBuffer& buffer) { + return SkArcToPathEffect::Create(buffer.readScalar()); +} + +void SkArcToPathEffect::flatten(SkWriteBuffer& buffer) const { + buffer.writeScalar(fRadius); +} diff --git a/src/ports/SkGlobalInitialization_chromium.cpp b/src/ports/SkGlobalInitialization_chromium.cpp index 9f5614cb74..a5115d3df6 100644 --- a/src/ports/SkGlobalInitialization_chromium.cpp +++ b/src/ports/SkGlobalInitialization_chromium.cpp @@ -16,6 +16,7 @@ #include "Sk1DPathEffect.h" #include "Sk2DPathEffect.h" #include "SkArithmeticMode.h" +#include "SkArcToPathEffect.h" #include "SkAvoidXfermode.h" #include "SkBitmapSource.h" #include "SkBlurDrawLooper.h" @@ -63,6 +64,7 @@ class SkPrivateEffectInitializer { public: static void Init() { + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArcToPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource) diff --git a/src/ports/SkGlobalInitialization_default.cpp b/src/ports/SkGlobalInitialization_default.cpp index 9f5614cb74..a5115d3df6 100644 --- a/src/ports/SkGlobalInitialization_default.cpp +++ b/src/ports/SkGlobalInitialization_default.cpp @@ -16,6 +16,7 @@ #include "Sk1DPathEffect.h" #include "Sk2DPathEffect.h" #include "SkArithmeticMode.h" +#include "SkArcToPathEffect.h" #include "SkAvoidXfermode.h" #include "SkBitmapSource.h" #include "SkBlurDrawLooper.h" @@ -63,6 +64,7 @@ class SkPrivateEffectInitializer { public: static void Init() { + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArcToPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkAvoidXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapProcShader) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBitmapSource) |