Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: gm/reveal.cpp

Issue 2321713004: Add shader-based GaussianEdgeShader for reveal case (Closed)
Patch Set: Clean up Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | gyp/effects.gypi » ('j') | include/effects/SkRRectsGaussianEdgeShader.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 Google Inc. 2 * Copyright 2016 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "gm.h" 8 #include "gm.h"
9 #include "SkAnimTimer.h" 9 #include "SkAnimTimer.h"
10 #include "SkBlurMaskFilter.h" 10 #include "SkBlurMaskFilter.h"
11 #include "SkGaussianEdgeShader.h" 11 #include "SkGaussianEdgeShader.h"
12 #include "SkRRectsGaussianEdgeShader.h"
12 #include "SkPath.h" 13 #include "SkPath.h"
13 #include "SkPathOps.h" 14 #include "SkPathOps.h"
14 #include "SkRRect.h" 15 #include "SkRRect.h"
15 #include "SkStroke.h" 16 #include "SkStroke.h"
16 17
17 constexpr int kNumCols = 2; 18 constexpr int kNumCols = 2;
18 constexpr int kNumRows = 5; 19 constexpr int kNumRows = 5;
19 constexpr int kCellSize = 128; 20 constexpr int kCellSize = 128;
20 constexpr SkScalar kPad = 8.0f; 21 constexpr SkScalar kPad = 8.0f;
21 constexpr SkScalar kPeriod = 8.0f; 22 constexpr SkScalar kPeriod = 8.0f;
22 constexpr int kClipOffset = 32; 23 constexpr int kClipOffset = 32;
23 24
24 //////////////////////////////////////////////////////////////////////////////// /////////////////// 25 //////////////////////////////////////////////////////////////////////////////// ///////////////////
25 typedef SkPath (*PFDrawMthd)(SkCanvas*, const SkRect&, bool); 26
26 27 class Object {
27 static SkPath draw_rrect(SkCanvas* canvas, const SkRect& r, bool stroked) { 28 public:
28 SkRRect rr = SkRRect::MakeRectXY(r, 2*kPad, 2*kPad); 29 virtual bool asRRect(SkRRect* rr) const = 0;
29 30 virtual SkPath asPath() const = 0;
30 SkPaint paint; 31 virtual void draw(SkCanvas* canvas, const SkPaint& paint) const = 0;
31 paint.setAntiAlias(true); 32 virtual void clip(SkCanvas* canvas) const = 0;
32 if (stroked) { 33 virtual bool contains(const SkRect& r) const = 0;
34 virtual const SkRect& bounds() const = 0;
35 };
36
37 typedef Object* (*PFMakeMthd)(const SkRect& r);
38
39 class RRect : public Object {
40 public:
41 RRect(const SkRect& r) {
42 fRRect = SkRRect::MakeRectXY(r, 4*kPad, 4*kPad);
43 }
44
45 bool asRRect(SkRRect* rr) const override {
46 *rr = fRRect;
47 return true;
48 }
49
50 SkPath asPath() const override {
51 SkPath p;
52 p.addRRect(fRRect);
53 return p;
54 }
55
56 void draw(SkCanvas* canvas, const SkPaint& paint) const override {
57 canvas->drawRRect(fRRect, paint);
58 }
59
60 void clip(SkCanvas* canvas) const override {
61 canvas->clipRRect(fRRect);
62 }
63
64 bool contains(const SkRect& r) const override {
65 return fRRect.contains(r);
66 }
67
68 const SkRect& bounds() const override {
69 return fRRect.getBounds();
70 }
71
72 static Object* Make(const SkRect& r) {
73 return new RRect(r);
74 }
75
76 private:
77 SkRRect fRRect;
78 };
79
80 class StrokedRRect : public Object {
81 public:
82 StrokedRRect(const SkRect& r) {
83 fRRect = SkRRect::MakeRectXY(r, 2*kPad, 2*kPad);
84 fStrokedBounds = r.makeOutset(kPad, kPad);
85 }
86
87 bool asRRect(SkRRect* rr) const override {
88 return false;
89 }
90
91 SkPath asPath() const override {
92 // In this case we want the outline of the stroked rrect
93 SkPaint paint;
94 paint.setAntiAlias(true);
33 paint.setStyle(SkPaint::kStroke_Style); 95 paint.setStyle(SkPaint::kStroke_Style);
34 paint.setColor(SK_ColorRED); 96 paint.setStrokeWidth(kPad);
35 } else { 97
36 // G channel is an F6.2 radius
37 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)(4*kPad), 0));
38 paint.setShader(SkGaussianEdgeShader::Make());
39 }
40 canvas->drawRRect(rr, paint);
41
42 SkPath p;
43 p.addRoundRect(r, 2*kPad, 2*kPad);
44 return p;
45 }
46
47 static SkPath draw_stroked_rrect(SkCanvas* canvas, const SkRect& r, bool stroked ) {
48 SkRect insetRect = r;
49 insetRect.inset(kPad, kPad);
50 SkRRect rr = SkRRect::MakeRectXY(insetRect, 2*kPad, 2*kPad);
51
52 SkPaint paint;
53 paint.setAntiAlias(true);
54 paint.setStyle(SkPaint::kStroke_Style);
55 paint.setStrokeWidth(kPad);
56
57 if (stroked) {
58 // In this case we want to draw a stroked representation of the stroked rrect
59 SkPath p, stroked; 98 SkPath p, stroked;
60 p.addRRect(rr); 99 p.addRRect(fRRect);
61 SkStroke stroke(paint); 100 SkStroke stroke(paint);
62 stroke.strokePath(p, &stroked); 101 stroke.strokePath(p, &stroked);
63 102 return stroked;
64 paint.setStrokeWidth(0); 103 }
65 paint.setColor(SK_ColorRED); 104
66 canvas->drawPath(stroked, paint); 105 void draw(SkCanvas* canvas, const SkPaint& paint) const override {
67 } else { 106 SkPaint stroke(paint);
68 // G channel is an F6.2 radius 107 stroke.setStyle(SkPaint::kStroke_Style);
69 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)(4*kPad), 0)); 108 stroke.setStrokeWidth(kPad);
70 paint.setShader(SkGaussianEdgeShader::Make()); 109
71 110 canvas->drawRRect(fRRect, stroke);
72 canvas->drawRRect(rr, paint); 111 }
73 } 112
74 113 void clip(SkCanvas* canvas) const override {
75 SkPath p; 114 canvas->clipPath(this->asPath());
76 insetRect.outset(kPad/2.0f, kPad/2.0f); 115 }
77 p.addRoundRect(insetRect, 2*kPad, 2*kPad); 116
78 return p; 117 bool contains(const SkRect& r) const override {
79 } 118 return false;
80 119 }
81 static SkPath draw_oval(SkCanvas* canvas, const SkRect& r, bool stroked) { 120
82 SkRRect rr = SkRRect::MakeOval(r); 121 const SkRect& bounds() const override {
83 122 return fStrokedBounds;
84 SkPaint paint; 123 }
85 paint.setAntiAlias(true); 124
86 if (stroked) { 125 static Object* Make(const SkRect& r) {
87 paint.setStyle(SkPaint::kStroke_Style); 126 return new StrokedRRect(r);
88 paint.setColor(SK_ColorRED); 127 }
89 } else { 128
90 // G channel is an F6.2 radius 129 private:
91 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)(4*kPad), 0)); 130 SkRRect fRRect;
92 paint.setShader(SkGaussianEdgeShader::Make()); 131 SkRect fStrokedBounds;
93 } 132 };
94 canvas->drawRRect(rr, paint); 133
95 134 class Oval : public Object {
96 SkPath p; 135 public:
97 p.addOval(r); 136 Oval(const SkRect& r) {
98 return p; 137 fRRect = SkRRect::MakeOval(r);
99 } 138 }
100 139
101 static SkPath draw_square(SkCanvas* canvas, const SkRect& r, bool stroked) { 140 bool asRRect(SkRRect* rr) const override {
102 SkPaint paint; 141 *rr = fRRect;
103 paint.setAntiAlias(true); 142 return true;
104 if (stroked) { 143 }
105 paint.setStyle(SkPaint::kStroke_Style); 144
106 paint.setColor(SK_ColorRED); 145 SkPath asPath() const override {
107 } else { 146 SkPath p;
108 // G channel is an F6.2 radius 147 p.addRRect(fRRect);
109 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)(4*kPad), 0)); 148 return p;
110 paint.setShader(SkGaussianEdgeShader::Make()); 149 }
111 } 150
112 canvas->drawRect(r, paint); 151 void draw(SkCanvas* canvas, const SkPaint& paint) const override {
113 152 canvas->drawRRect(fRRect, paint);
114 SkPath p; 153 }
115 p.addRect(r); 154
116 return p; 155 void clip(SkCanvas* canvas) const override {
117 } 156 canvas->clipRRect(fRRect);
118 157 }
119 static SkPath draw_pentagon(SkCanvas* canvas, const SkRect& r, bool stroked) { 158
120 SkPath p; 159 bool contains(const SkRect& r) const override {
121 160 return fRRect.contains(r);
122 SkPoint points[5] = { 161 }
123 { 0.000000f, -1.000000f }, 162
124 { -0.951056f, -0.309017f }, 163 const SkRect& bounds() const override {
125 { -0.587785f, 0.809017f }, 164 return fRRect.getBounds();
126 { 0.587785f, 0.809017f }, 165 }
127 { 0.951057f, -0.309017f }, 166
128 }; 167 static Object* Make(const SkRect& r) {
129 168 return new Oval(r);
130 SkScalar height = r.height()/2.0f; 169 }
131 SkScalar width = r.width()/2.0f; 170
132 171 private:
133 p.moveTo(r.centerX() + points[0].fX * width, r.centerY() + points[0].fY * he ight); 172 SkRRect fRRect;
134 p.lineTo(r.centerX() + points[1].fX * width, r.centerY() + points[1].fY * he ight); 173 };
135 p.lineTo(r.centerX() + points[2].fX * width, r.centerY() + points[2].fY * he ight); 174
136 p.lineTo(r.centerX() + points[3].fX * width, r.centerY() + points[3].fY * he ight); 175 class Rect : public Object {
137 p.lineTo(r.centerX() + points[4].fX * width, r.centerY() + points[4].fY * he ight); 176 public:
138 p.close(); 177 Rect(const SkRect& r) : fRect(r) { }
139 178
140 SkPaint paint; 179 bool asRRect(SkRRect* rr) const override {
141 paint.setAntiAlias(true); 180 *rr = SkRRect::MakeRect(fRect);
142 if (stroked) { 181 return true;
143 paint.setStyle(SkPaint::kStroke_Style); 182 }
144 paint.setColor(SK_ColorRED); 183
145 } else { 184 SkPath asPath() const override {
146 // G channel is an F6.2 radius 185 SkPath p;
147 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)(4*kPad), 0)); 186 p.addRect(fRect);
148 // This currently goes through the GrAAConvexPathRenderer and produces a 187 return p;
149 // AAConvexPathBatch (i.e., it doesn't have a analytic distance) 188 }
150 // paint.setShader(SkGaussianEdgeShader::Make()); 189
151 } 190 void draw(SkCanvas* canvas, const SkPaint& paint) const override {
152 canvas->drawPath(p, paint); 191 canvas->drawRect(fRect, paint);
153 192 }
154 return p; 193
155 } 194 void clip(SkCanvas* canvas) const override {
156 195 canvas->clipRect(fRect);
157 //////////////////////////////////////////////////////////////////////////////// /////////////////// 196 }
158 typedef void (*PFClipMthd)(SkCanvas* canvas, const SkPoint&, SkScalar); 197
159 198 bool contains(const SkRect& r) const override {
160 static void circle_clip(SkCanvas* canvas, const SkPoint& center, SkScalar rad) { 199 return fRect.contains(r);
161 SkRect r = SkRect::MakeLTRB(center.fX - rad, center.fY - rad, center.fX + ra d, center.fY + rad); 200 }
162 SkRRect rr = SkRRect::MakeOval(r); 201
163 202 const SkRect& bounds() const override {
164 canvas->clipRRect(rr); 203 return fRect;
165 } 204 }
166 205
167 static void square_clip(SkCanvas* canvas, const SkPoint& center, SkScalar size) { 206 static Object* Make(const SkRect& r) {
168 SkScalar newSize = SK_ScalarRoot2Over2 * size; 207 return new Rect(r);
169 SkRect r = SkRect::MakeLTRB(center.fX - newSize, center.fY - newSize, 208 }
170 center.fX + newSize, center.fY + newSize); 209
171 210 private:
172 canvas->clipRect(r); 211 SkRect fRect;
173 } 212 };
174 213
175 //////////////////////////////////////////////////////////////////////////////// /////////////////// 214 class Pentagon : public Object {
176 // These are stand alone methods (rather than just, say, returning the SkPath fo r the clip 215 public:
177 // object) so that we can catch the clip-contains-victim case. 216 Pentagon(const SkRect& r) {
178 typedef SkPath (*PFGeometricClipMthd)(const SkPoint&, SkScalar, const SkPath&); 217 SkPoint points[5] = {
179 218 { 0.000000f, -1.000000f },
180 static SkPath circle_geometric_clip(const SkPoint& center, SkScalar rad, const S kPath& victim) { 219 { -0.951056f, -0.309017f },
181 const SkRect bound = victim.getBounds(); 220 { -0.587785f, 0.809017f },
182 SkPoint pts[4]; 221 { 0.587785f, 0.809017f },
183 bound.toQuad(pts); 222 { 0.951057f, -0.309017f },
184 223 };
185 bool clipContainsVictim = true; 224
186 for (int i = 0; i < 4; ++i) { 225 SkScalar height = r.height()/2.0f;
187 SkScalar distSq = (pts[i].fX - center.fX) * (pts[i].fX - center.fX) + 226 SkScalar width = r.width()/2.0f;
188 (pts[i].fY - center.fY) * (pts[i].fY - center.fY); 227
189 if (distSq >= rad*rad) { 228 fPath.moveTo(r.centerX() + points[0].fX * width, r.centerY() + points[0] .fY * height);
190 clipContainsVictim = false; 229 fPath.lineTo(r.centerX() + points[1].fX * width, r.centerY() + points[1] .fY * height);
191 } 230 fPath.lineTo(r.centerX() + points[2].fX * width, r.centerY() + points[2] .fY * height);
192 } 231 fPath.lineTo(r.centerX() + points[3].fX * width, r.centerY() + points[3] .fY * height);
193 232 fPath.lineTo(r.centerX() + points[4].fX * width, r.centerY() + points[4] .fY * height);
194 if (clipContainsVictim) { 233 fPath.close();
195 return victim; 234 }
196 } 235
197 236 bool asRRect(SkRRect* rr) const override {
198 // Add victim contains clip test? 237 return false;
199 238 }
200 SkPath clipPath; 239
201 clipPath.addCircle(center.fX, center.fY, rad); 240 SkPath asPath() const override { return fPath; }
202 241
203 SkPath result; 242 void draw(SkCanvas* canvas, const SkPaint& paint) const override {
204 SkAssertResult(Op(clipPath, victim, kIntersect_SkPathOp, &result)); 243 canvas->drawPath(fPath, paint);
205 244 }
206 return result; 245
207 } 246 void clip(SkCanvas* canvas) const override {
208 247 canvas->clipPath(this->asPath());
209 static SkPath square_geometric_clip(const SkPoint& center, SkScalar size, const SkPath& victim) { 248 }
210 SkScalar newSize = SK_ScalarRoot2Over2 * size; 249
211 SkRect r = SkRect::MakeLTRB(center.fX - newSize, center.fY - newSize, 250 bool contains(const SkRect& r) const override {
212 center.fX + newSize, center.fY + newSize); 251 return false;
213 252 }
214 const SkRect bound = victim.getBounds(); 253
215 254 const SkRect& bounds() const override {
216 if (r.contains(bound)) { 255 return fPath.getBounds();
217 return victim; 256 }
218 } 257
219 258 static Object* Make(const SkRect& r) {
220 // Add victim contains clip test? 259 return new Pentagon(r);
221 260 }
222 SkPath clipPath; 261
223 clipPath.addRect(r); 262 private:
224 263 SkPath fPath;
225 SkPath result; 264 };
226 SkAssertResult(Op(clipPath, victim, kIntersect_SkPathOp, &result));
227
228 return result;
229 }
230 265
231 //////////////////////////////////////////////////////////////////////////////// /////////////////// 266 //////////////////////////////////////////////////////////////////////////////// ///////////////////
232 namespace skiagm { 267 namespace skiagm {
233 268
234 // This GM attempts to mimic Android's reveal animation 269 // This GM attempts to mimic Android's reveal animation
235 class RevealGM : public GM { 270 class RevealGM : public GM {
236 public: 271 public:
237 RevealGM() : fFraction(0.5f), fDrawWithGaussianEdge(true) { 272 enum Mode {
273 kGaussianEdge_Mode,
274 kBlurMask_Mode,
bsalomon 2016/09/12 14:56:52 Are the other modes just for debugging? Would it m
robertphillips 2016/09/12 15:13:49 The other two modes are just so I can toggle the r
275 kRRectsGaussianEdge_Mode,
276
277 kLast_Mode = kRRectsGaussianEdge_Mode
278 };
279
280 static const int kModeCount = kLast_Mode + 1;
281
282 RevealGM() : fFraction(0.5f), fMode(kGaussianEdge_Mode) {
238 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); 283 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
239 } 284 }
240 285
241 protected: 286 protected:
242 287
243 SkString onShortName() override { 288 SkString onShortName() override {
244 return SkString("reveal"); 289 return SkString("reveal");
245 } 290 }
246 291
247 SkISize onISize() override { 292 SkISize onISize() override {
248 return SkISize::Make(kNumCols * kCellSize, kNumRows * kCellSize); 293 return SkISize::Make(kNumCols * kCellSize, kNumRows * kCellSize);
249 } 294 }
250 295
251 void onDraw(SkCanvas* canvas) override { 296 void onDraw(SkCanvas* canvas) override {
252 PFClipMthd clips[kNumCols] = { circle_clip, square_clip }; 297 PFMakeMthd clipMakes[kNumCols] = { Oval::Make, Rect::Make };
253 PFGeometricClipMthd geometricClips[kNumCols] = { 298 PFMakeMthd drawMakes[kNumRows] = {
254 circle_geometric_clip, 299 RRect::Make, StrokedRRect::Make, Oval::Make, Rect::Make, Pentagon::M ake
255 square_geometric_clip
256 };
257 PFDrawMthd draws[kNumRows] = {
258 draw_rrect,
259 draw_stroked_rrect,
260 draw_oval,
261 draw_square,
262 draw_pentagon
263 }; 300 };
264 301
265 SkPaint strokePaint; 302 SkPaint strokePaint;
266 strokePaint.setColor(SK_ColorGREEN); 303 strokePaint.setColor(SK_ColorGREEN);
267 strokePaint.setStyle(SkPaint::kStroke_Style); 304 strokePaint.setStyle(SkPaint::kStroke_Style);
268 strokePaint.setStrokeWidth(0.0f); 305 strokePaint.setStrokeWidth(0.0f);
269 306
270 for (int y = 0; y < kNumRows; ++y) { 307 for (int y = 0; y < kNumRows; ++y) {
271 for (int x = 0; x < kNumCols; ++x) { 308 for (int x = 0; x < kNumCols; ++x) {
272 SkRect cell = SkRect::MakeXYWH(SkIntToScalar(x*kCellSize), 309 SkRect cell = SkRect::MakeXYWH(SkIntToScalar(x*kCellSize),
273 SkIntToScalar(y*kCellSize), 310 SkIntToScalar(y*kCellSize),
274 SkIntToScalar(kCellSize), 311 SkIntToScalar(kCellSize),
275 SkIntToScalar(kCellSize)); 312 SkIntToScalar(kCellSize));
276 313
314 canvas->save();
315 canvas->clipRect(cell);
316
277 cell.inset(kPad, kPad); 317 cell.inset(kPad, kPad);
278 SkPoint clipCenter = SkPoint::Make(cell.centerX() - kClipOffset, 318 SkPoint clipCenter = SkPoint::Make(cell.centerX() - kClipOffset,
279 cell.centerY() + kClipOffset) ; 319 cell.centerY() + kClipOffset) ;
320 SkScalar curSize = kCellSize * fFraction;
321 const SkRect clipRect = SkRect::MakeLTRB(clipCenter.fX - curSize ,
322 clipCenter.fY - curSize ,
323 clipCenter.fX + curSize ,
324 clipCenter.fY + curSize );
280 325
281 SkScalar curSize = kCellSize * fFraction; 326 SkAutoTDelete<Object> clipObj((*clipMakes[x])(clipRect));
327 SkAutoTDelete<Object> drawObj((*drawMakes[y])(cell));
282 328
283 // The goal is to replace this clipped draw (which clips the 329 // The goal is to replace this clipped draw (which clips the
284 // shadow) with a draw using the geometric clip 330 // shadow) with a draw using the geometric clip
285 if (fDrawWithGaussianEdge) { 331 if (kGaussianEdge_Mode == fMode) {
286 canvas->save(); 332 canvas->save();
287 (*clips[x])(canvas, clipCenter, curSize); 333 clipObj->clip(canvas);
288 (*draws[y])(canvas, cell, false); 334
335 // Draw with GaussianEdgeShader
336 SkPaint paint;
337 paint.setAntiAlias(true);
338 // G channel is an F6.2 radius
339 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)( 4*kPad), 0));
340 paint.setShader(SkGaussianEdgeShader::Make());
341 drawObj->draw(canvas, paint);
289 canvas->restore(); 342 canvas->restore();
290 } 343 } else if (kBlurMask_Mode == fMode) {
344 SkPath clippedPath;
291 345
292 SkPath drawnPath = (*draws[y])(canvas, cell, true); 346 if (clipObj->contains(drawObj->bounds())) {
347 clippedPath = drawObj->asPath();
348 } else {
349 SkPath drawnPath = drawObj->asPath();
350 SkPath clipPath = clipObj->asPath();
293 351
294 if (!fDrawWithGaussianEdge) { 352 SkAssertResult(Op(clipPath, drawnPath, kIntersect_SkPath Op, &clippedPath));
295 SkPath clippedPath = (*geometricClips[x])(clipCenter, curSiz e, drawnPath); 353 }
296 SkASSERT(clippedPath.isConvex());
297 354
298 SkPaint blurPaint; 355 SkPaint blurPaint;
299 blurPaint.setAntiAlias(true); 356 blurPaint.setAntiAlias(true);
300 blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlu rStyle, 3.0f)); 357 blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlu rStyle, 3.0f));
301 canvas->drawPath(clippedPath, blurPaint); 358 canvas->drawPath(clippedPath, blurPaint);
359 } else {
360 SkASSERT(kRRectsGaussianEdge_Mode == fMode);
361
362 SkRect cover = drawObj->bounds();
363 SkAssertResult(cover.intersect(clipObj->bounds()));
364
365 SkPaint paint;
366
367 SkRRect clipRR, drawnRR;
368
369 if (clipObj->asRRect(&clipRR) && drawObj->asRRect(&drawnRR)) {
370 paint.setShader(SkRRectsGaussianEdgeShader::Make(clipRR, drawnRR,
371 kPad, 0 .0f));
372 }
373
374 canvas->drawRect(cover, paint);
302 } 375 }
376
377 // Draw the clip and draw objects for reference
378 SkPaint strokePaint;
379 strokePaint.setStyle(SkPaint::kStroke_Style);
380 strokePaint.setStrokeWidth(0);
381 strokePaint.setColor(SK_ColorRED);
382 canvas->drawPath(drawObj->asPath(), strokePaint);
383 strokePaint.setColor(SK_ColorGREEN);
384 canvas->drawPath(clipObj->asPath(), strokePaint);
385
386 canvas->restore();
303 } 387 }
304 } 388 }
305 } 389 }
306 390
307 bool onHandleKey(SkUnichar uni) override { 391 bool onHandleKey(SkUnichar uni) override {
308 switch (uni) { 392 switch (uni) {
309 case 'C': 393 case 'C':
310 fDrawWithGaussianEdge = !fDrawWithGaussianEdge; 394 fMode = (Mode)((fMode + 1) % kModeCount);
311 return true; 395 return true;
312 } 396 }
313 397
314 return false; 398 return false;
315 } 399 }
316 400
317 bool onAnimate(const SkAnimTimer& timer) override { 401 bool onAnimate(const SkAnimTimer& timer) override {
318 fFraction = timer.pingPong(kPeriod, 0.0f, 0.0f, 1.0f); 402 fFraction = timer.pingPong(kPeriod, 0.0f, 0.0f, 1.0f);
319 return true; 403 return true;
320 } 404 }
321 405
322 private: 406 private:
323 SkScalar fFraction; 407 SkScalar fFraction;
324 bool fDrawWithGaussianEdge; 408 Mode fMode;
325 409
326 typedef GM INHERITED; 410 typedef GM INHERITED;
327 }; 411 };
328 412
329 ////////////////////////////////////////////////////////////////////////////// 413 //////////////////////////////////////////////////////////////////////////////
330 414
331 DEF_GM(return new RevealGM;) 415 DEF_GM(return new RevealGM;)
332 } 416 }
OLDNEW
« no previous file with comments | « no previous file | gyp/effects.gypi » ('j') | include/effects/SkRRectsGaussianEdgeShader.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698