aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@chromium.org>2014-12-17 01:47:32 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-12-17 01:47:32 -0800
commit8b5752443f34680d26a73bb6e1e72a8d7cf0f320 (patch)
tree25d12c07db584d2bc71b57bd87126f27b06c8916
parent287ccfece68de4f2c5fc464a583f202626b38f8c (diff)
add arcto patheffect
BUG=skia: TBR= Review URL: https://codereview.chromium.org/813513003
-rw-r--r--gyp/effects.gypi1
-rw-r--r--include/effects/SkArcToPathEffect.h39
-rw-r--r--samplecode/SamplePath.cpp65
-rw-r--r--src/effects/SkArcToPathEffect.cpp70
-rw-r--r--src/ports/SkGlobalInitialization_chromium.cpp2
-rw-r--r--src/ports/SkGlobalInitialization_default.cpp2
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)