1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SampleCode.h"
9 #include "SkAnimTimer.h"
10 #include "SkView.h"
11 #include "SkCanvas.h"
12 #include "SkGradientShader.h"
13 #include "SkPath.h"
14 #include "SkRegion.h"
15 #include "SkShader.h"
16 #include "SkUtils.h"
17 #include "Sk1DPathEffect.h"
18 #include "SkCornerPathEffect.h"
19 #include "SkPathMeasure.h"
20 #include "SkRandom.h"
21 #include "SkColorPriv.h"
22
23 #define CORNER_RADIUS 12
24
25 static const int gXY[] = {
26 4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4
27 };
28
make_pe(int flags,SkScalar phase)29 static SkPathEffect* make_pe(int flags, SkScalar phase) {
30 if (flags == 1)
31 return SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS));
32
33 SkPath path;
34 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
35 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
36 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
37 path.close();
38 path.offset(SkIntToScalar(-6), 0);
39
40 SkPathEffect* outer = SkPath1DPathEffect::Create(path, 12, phase,
41 SkPath1DPathEffect::kRotate_Style);
42
43 if (flags == 2)
44 return outer;
45
46 SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS));
47
48 SkPathEffect* pe = SkComposePathEffect::Create(outer, inner);
49 outer->unref();
50 inner->unref();
51 return pe;
52 }
53
make_warp_pe(SkScalar phase)54 static SkPathEffect* make_warp_pe(SkScalar phase) {
55 SkPath path;
56 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
57 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
58 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
59 path.close();
60 path.offset(SkIntToScalar(-6), 0);
61
62 SkPathEffect* outer = SkPath1DPathEffect::Create(
63 path, 12, phase, SkPath1DPathEffect::kMorph_Style);
64 SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS));
65
66 SkPathEffect* pe = SkComposePathEffect::Create(outer, inner);
67 outer->unref();
68 inner->unref();
69 return pe;
70 }
71
72 ///////////////////////////////////////////////////////////
73
74 #include "SkColorFilter.h"
75 #include "SkLayerRasterizer.h"
76
77 class TestRastBuilder : public SkLayerRasterizer::Builder {
78 public:
TestRastBuilder()79 TestRastBuilder() {
80 SkPaint paint;
81 paint.setAntiAlias(true);
82
83 paint.setAlpha(0x66);
84 this->addLayer(paint, SkIntToScalar(4), SkIntToScalar(4));
85
86 paint.setAlpha(0xFF);
87 this->addLayer(paint);
88 }
89 };
90
91 class PathEffectView : public SampleView {
92 SkPath fPath;
93 SkPoint fClickPt;
94 SkScalar fPhase;
95
96 public:
PathEffectView()97 PathEffectView() : fPhase(0) {
98 }
99
100 protected:
onOnceBeforeDraw()101 void onOnceBeforeDraw() override {
102 SkRandom rand;
103 int steps = 20;
104 SkScalar dist = SkIntToScalar(400);
105 SkScalar x = SkIntToScalar(20);
106 SkScalar y = SkIntToScalar(50);
107
108 fPath.moveTo(x, y);
109 for (int i = 0; i < steps; i++) {
110 x += dist/steps;
111 SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25);
112 if (i == steps/2) {
113 fPath.moveTo(x, tmpY);
114 } else {
115 fPath.lineTo(x, tmpY);
116 }
117 }
118
119 {
120 SkRect oval;
121 oval.set(SkIntToScalar(20), SkIntToScalar(30),
122 SkIntToScalar(100), SkIntToScalar(60));
123 oval.offset(x, 0);
124 fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8));
125 }
126
127 fClickPt.set(SkIntToScalar(200), SkIntToScalar(200));
128
129 this->setBGColor(0xFFDDDDDD);
130 }
131
onQuery(SkEvent * evt)132 bool onQuery(SkEvent* evt) override {
133 if (SampleCode::TitleQ(*evt)) {
134 SampleCode::TitleR(evt, "PathEffects");
135 return true;
136 }
137 return this->INHERITED::onQuery(evt);
138 }
139
onDrawContent(SkCanvas * canvas)140 void onDrawContent(SkCanvas* canvas) override {
141 SkPaint paint;
142
143 canvas->translate(0, 50);
144
145 paint.setColor(SK_ColorBLUE);
146 paint.setPathEffect(make_pe(2, fPhase))->unref();
147 canvas->drawPath(fPath, paint);
148
149 canvas->translate(0, 50);
150
151 paint.setARGB(0xFF, 0, 0xBB, 0);
152 paint.setPathEffect(make_pe(3, fPhase))->unref();
153 canvas->drawPath(fPath, paint);
154
155 canvas->translate(0, 50);
156
157 paint.setARGB(0xFF, 0, 0, 0);
158 paint.setPathEffect(make_warp_pe(fPhase))->unref();
159 TestRastBuilder testRastBuilder;
160 paint.setRasterizer(testRastBuilder.detachRasterizer())->unref();
161 canvas->drawPath(fPath, paint);
162 }
163
onAnimate(const SkAnimTimer & timer)164 bool onAnimate(const SkAnimTimer& timer) override {
165 fPhase = timer.scaled(40);
166 return true;
167 }
168
169 private:
170 typedef SampleView INHERITED;
171 };
172
173 //////////////////////////////////////////////////////////////////////////////
174
MyFactory()175 static SkView* MyFactory() { return new PathEffectView; }
176 static SkViewRegister reg(MyFactory);
177