OLD | NEW |
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" |
(...skipping 10 matching lines...) Expand all Loading... |
21 constexpr SkScalar kPad = 8.0f; | 21 constexpr SkScalar kPad = 8.0f; |
22 constexpr SkScalar kPeriod = 8.0f; | 22 constexpr SkScalar kPeriod = 8.0f; |
23 constexpr int kClipOffset = 32; | 23 constexpr int kClipOffset = 32; |
24 | 24 |
25 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 25 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
26 | 26 |
27 class Object { | 27 class Object { |
28 public: | 28 public: |
29 virtual ~Object() {} | 29 virtual ~Object() {} |
30 virtual bool asRRect(SkRRect* rr) const = 0; | 30 virtual bool asRRect(SkRRect* rr) const = 0; |
31 virtual SkPath asPath() const = 0; | 31 virtual SkPath asPath(SkScalar inset) const = 0; |
32 virtual void draw(SkCanvas* canvas, const SkPaint& paint) const = 0; | 32 virtual void draw(SkCanvas* canvas, const SkPaint& paint) const = 0; |
33 virtual void clip(SkCanvas* canvas) const = 0; | 33 virtual void clip(SkCanvas* canvas) const = 0; |
34 virtual bool contains(const SkRect& r) const = 0; | 34 virtual bool contains(const SkRect& r) const = 0; |
35 virtual const SkRect& bounds() const = 0; | 35 virtual const SkRect& bounds() const = 0; |
36 }; | 36 }; |
37 | 37 |
38 typedef Object* (*PFMakeMthd)(const SkRect& r); | 38 typedef Object* (*PFMakeMthd)(const SkRect& r); |
39 | 39 |
40 class RRect : public Object { | 40 class RRect : public Object { |
41 public: | 41 public: |
42 RRect(const SkRect& r) { | 42 RRect(const SkRect& r) { |
43 fRRect = SkRRect::MakeRectXY(r, 4*kPad, 4*kPad); | 43 fRRect = SkRRect::MakeRectXY(r, 4*kPad, 4*kPad); |
44 } | 44 } |
45 | 45 |
46 bool asRRect(SkRRect* rr) const override { | 46 bool asRRect(SkRRect* rr) const override { |
47 *rr = fRRect; | 47 *rr = fRRect; |
48 return true; | 48 return true; |
49 } | 49 } |
50 | 50 |
51 SkPath asPath() const override { | 51 SkPath asPath(SkScalar inset) const override { |
| 52 SkRRect tmp = fRRect; |
| 53 tmp.inset(inset, inset); |
52 SkPath p; | 54 SkPath p; |
53 p.addRRect(fRRect); | 55 p.addRRect(tmp); |
54 return p; | 56 return p; |
55 } | 57 } |
56 | 58 |
57 void draw(SkCanvas* canvas, const SkPaint& paint) const override { | 59 void draw(SkCanvas* canvas, const SkPaint& paint) const override { |
58 canvas->drawRRect(fRRect, paint); | 60 canvas->drawRRect(fRRect, paint); |
59 } | 61 } |
60 | 62 |
61 void clip(SkCanvas* canvas) const override { | 63 void clip(SkCanvas* canvas) const override { |
62 canvas->clipRRect(fRRect); | 64 canvas->clipRRect(fRRect); |
63 } | 65 } |
(...skipping 18 matching lines...) Expand all Loading... |
82 public: | 84 public: |
83 StrokedRRect(const SkRect& r) { | 85 StrokedRRect(const SkRect& r) { |
84 fRRect = SkRRect::MakeRectXY(r, 2*kPad, 2*kPad); | 86 fRRect = SkRRect::MakeRectXY(r, 2*kPad, 2*kPad); |
85 fStrokedBounds = r.makeOutset(kPad, kPad); | 87 fStrokedBounds = r.makeOutset(kPad, kPad); |
86 } | 88 } |
87 | 89 |
88 bool asRRect(SkRRect* rr) const override { | 90 bool asRRect(SkRRect* rr) const override { |
89 return false; | 91 return false; |
90 } | 92 } |
91 | 93 |
92 SkPath asPath() const override { | 94 SkPath asPath(SkScalar inset) const override { |
| 95 SkRRect tmp = fRRect; |
| 96 tmp.inset(inset, inset); |
| 97 |
93 // In this case we want the outline of the stroked rrect | 98 // In this case we want the outline of the stroked rrect |
94 SkPaint paint; | 99 SkPaint paint; |
95 paint.setAntiAlias(true); | 100 paint.setAntiAlias(true); |
96 paint.setStyle(SkPaint::kStroke_Style); | 101 paint.setStyle(SkPaint::kStroke_Style); |
97 paint.setStrokeWidth(kPad); | 102 paint.setStrokeWidth(kPad); |
98 | 103 |
99 SkPath p, stroked; | 104 SkPath p, stroked; |
100 p.addRRect(fRRect); | 105 p.addRRect(tmp); |
101 SkStroke stroke(paint); | 106 SkStroke stroke(paint); |
102 stroke.strokePath(p, &stroked); | 107 stroke.strokePath(p, &stroked); |
103 return stroked; | 108 return stroked; |
104 } | 109 } |
105 | 110 |
106 void draw(SkCanvas* canvas, const SkPaint& paint) const override { | 111 void draw(SkCanvas* canvas, const SkPaint& paint) const override { |
107 SkPaint stroke(paint); | 112 SkPaint stroke(paint); |
108 stroke.setStyle(SkPaint::kStroke_Style); | 113 stroke.setStyle(SkPaint::kStroke_Style); |
109 stroke.setStrokeWidth(kPad); | 114 stroke.setStrokeWidth(kPad); |
110 | 115 |
111 canvas->drawRRect(fRRect, stroke); | 116 canvas->drawRRect(fRRect, stroke); |
112 } | 117 } |
113 | 118 |
114 void clip(SkCanvas* canvas) const override { | 119 void clip(SkCanvas* canvas) const override { |
115 canvas->clipPath(this->asPath()); | 120 canvas->clipPath(this->asPath(0.0f)); |
116 } | 121 } |
117 | 122 |
118 bool contains(const SkRect& r) const override { | 123 bool contains(const SkRect& r) const override { |
119 return false; | 124 return false; |
120 } | 125 } |
121 | 126 |
122 const SkRect& bounds() const override { | 127 const SkRect& bounds() const override { |
123 return fStrokedBounds; | 128 return fStrokedBounds; |
124 } | 129 } |
125 | 130 |
(...skipping 10 matching lines...) Expand all Loading... |
136 public: | 141 public: |
137 Oval(const SkRect& r) { | 142 Oval(const SkRect& r) { |
138 fRRect = SkRRect::MakeOval(r); | 143 fRRect = SkRRect::MakeOval(r); |
139 } | 144 } |
140 | 145 |
141 bool asRRect(SkRRect* rr) const override { | 146 bool asRRect(SkRRect* rr) const override { |
142 *rr = fRRect; | 147 *rr = fRRect; |
143 return true; | 148 return true; |
144 } | 149 } |
145 | 150 |
146 SkPath asPath() const override { | 151 SkPath asPath(SkScalar inset) const override { |
| 152 SkRRect tmp = fRRect; |
| 153 tmp.inset(inset, inset); |
| 154 |
147 SkPath p; | 155 SkPath p; |
148 p.addRRect(fRRect); | 156 p.addRRect(tmp); |
149 return p; | 157 return p; |
150 } | 158 } |
151 | 159 |
152 void draw(SkCanvas* canvas, const SkPaint& paint) const override { | 160 void draw(SkCanvas* canvas, const SkPaint& paint) const override { |
153 canvas->drawRRect(fRRect, paint); | 161 canvas->drawRRect(fRRect, paint); |
154 } | 162 } |
155 | 163 |
156 void clip(SkCanvas* canvas) const override { | 164 void clip(SkCanvas* canvas) const override { |
157 canvas->clipRRect(fRRect); | 165 canvas->clipRRect(fRRect); |
158 } | 166 } |
(...skipping 16 matching lines...) Expand all Loading... |
175 | 183 |
176 class Rect : public Object { | 184 class Rect : public Object { |
177 public: | 185 public: |
178 Rect(const SkRect& r) : fRect(r) { } | 186 Rect(const SkRect& r) : fRect(r) { } |
179 | 187 |
180 bool asRRect(SkRRect* rr) const override { | 188 bool asRRect(SkRRect* rr) const override { |
181 *rr = SkRRect::MakeRect(fRect); | 189 *rr = SkRRect::MakeRect(fRect); |
182 return true; | 190 return true; |
183 } | 191 } |
184 | 192 |
185 SkPath asPath() const override { | 193 SkPath asPath(SkScalar inset) const override { |
| 194 SkRect tmp = fRect; |
| 195 tmp.inset(inset, inset); |
| 196 |
186 SkPath p; | 197 SkPath p; |
187 p.addRect(fRect); | 198 p.addRect(tmp); |
188 return p; | 199 return p; |
189 } | 200 } |
190 | 201 |
191 void draw(SkCanvas* canvas, const SkPaint& paint) const override { | 202 void draw(SkCanvas* canvas, const SkPaint& paint) const override { |
192 canvas->drawRect(fRect, paint); | 203 canvas->drawRect(fRect, paint); |
193 } | 204 } |
194 | 205 |
195 void clip(SkCanvas* canvas) const override { | 206 void clip(SkCanvas* canvas) const override { |
196 canvas->clipRect(fRect); | 207 canvas->clipRect(fRect); |
197 } | 208 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 fPath.lineTo(r.centerX() + points[2].fX * width, r.centerY() + points[2]
.fY * height); | 242 fPath.lineTo(r.centerX() + points[2].fX * width, r.centerY() + points[2]
.fY * height); |
232 fPath.lineTo(r.centerX() + points[3].fX * width, r.centerY() + points[3]
.fY * height); | 243 fPath.lineTo(r.centerX() + points[3].fX * width, r.centerY() + points[3]
.fY * height); |
233 fPath.lineTo(r.centerX() + points[4].fX * width, r.centerY() + points[4]
.fY * height); | 244 fPath.lineTo(r.centerX() + points[4].fX * width, r.centerY() + points[4]
.fY * height); |
234 fPath.close(); | 245 fPath.close(); |
235 } | 246 } |
236 | 247 |
237 bool asRRect(SkRRect* rr) const override { | 248 bool asRRect(SkRRect* rr) const override { |
238 return false; | 249 return false; |
239 } | 250 } |
240 | 251 |
241 SkPath asPath() const override { return fPath; } | 252 SkPath asPath(SkScalar inset) const override { return fPath; } |
242 | 253 |
243 void draw(SkCanvas* canvas, const SkPaint& paint) const override { | 254 void draw(SkCanvas* canvas, const SkPaint& paint) const override { |
244 canvas->drawPath(fPath, paint); | 255 canvas->drawPath(fPath, paint); |
245 } | 256 } |
246 | 257 |
247 void clip(SkCanvas* canvas) const override { | 258 void clip(SkCanvas* canvas) const override { |
248 canvas->clipPath(this->asPath()); | 259 canvas->clipPath(this->asPath(0.0f)); |
249 } | 260 } |
250 | 261 |
251 bool contains(const SkRect& r) const override { | 262 bool contains(const SkRect& r) const override { |
252 return false; | 263 return false; |
253 } | 264 } |
254 | 265 |
255 const SkRect& bounds() const override { | 266 const SkRect& bounds() const override { |
256 return fPath.getBounds(); | 267 return fPath.getBounds(); |
257 } | 268 } |
258 | 269 |
(...skipping 14 matching lines...) Expand all Loading... |
273 enum Mode { | 284 enum Mode { |
274 kGaussianEdge_Mode, | 285 kGaussianEdge_Mode, |
275 kBlurMask_Mode, | 286 kBlurMask_Mode, |
276 kRRectsGaussianEdge_Mode, | 287 kRRectsGaussianEdge_Mode, |
277 | 288 |
278 kLast_Mode = kRRectsGaussianEdge_Mode | 289 kLast_Mode = kRRectsGaussianEdge_Mode |
279 }; | 290 }; |
280 | 291 |
281 static const int kModeCount = kLast_Mode + 1; | 292 static const int kModeCount = kLast_Mode + 1; |
282 | 293 |
283 RevealGM() : fFraction(0.5f), fMode(kRRectsGaussianEdge_Mode) { | 294 RevealGM() : fFraction(0.5f), fMode(kRRectsGaussianEdge_Mode), fPause(false)
{ |
284 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); | 295 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); |
285 } | 296 } |
286 | 297 |
287 protected: | 298 protected: |
288 | 299 |
289 SkString onShortName() override { | 300 SkString onShortName() override { |
290 return SkString("reveal"); | 301 return SkString("reveal"); |
291 } | 302 } |
292 | 303 |
293 SkISize onISize() override { | 304 SkISize onISize() override { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 SkPaint paint; | 348 SkPaint paint; |
338 paint.setAntiAlias(true); | 349 paint.setAntiAlias(true); |
339 // G channel is an F6.2 radius | 350 // G channel is an F6.2 radius |
340 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)(
4*kPad), 0)); | 351 paint.setColor(SkColorSetARGB(255, 255, (unsigned char)(
4*kPad), 0)); |
341 paint.setShader(SkGaussianEdgeShader::Make()); | 352 paint.setShader(SkGaussianEdgeShader::Make()); |
342 drawObj->draw(canvas, paint); | 353 drawObj->draw(canvas, paint); |
343 canvas->restore(); | 354 canvas->restore(); |
344 } else if (kBlurMask_Mode == fMode) { | 355 } else if (kBlurMask_Mode == fMode) { |
345 SkPath clippedPath; | 356 SkPath clippedPath; |
346 | 357 |
| 358 SkScalar sigma = kPad / 4.0f; |
| 359 |
347 if (clipObj->contains(drawObj->bounds())) { | 360 if (clipObj->contains(drawObj->bounds())) { |
348 clippedPath = drawObj->asPath(); | 361 clippedPath = drawObj->asPath(2.0f*sigma); |
349 } else { | 362 } else { |
350 SkPath drawnPath = drawObj->asPath(); | 363 SkPath drawnPath = drawObj->asPath(2.0f*sigma); |
351 SkPath clipPath = clipObj->asPath(); | 364 SkPath clipPath = clipObj->asPath(2.0f*sigma); |
352 | 365 |
353 SkAssertResult(Op(clipPath, drawnPath, kIntersect_SkPath
Op, &clippedPath)); | 366 SkAssertResult(Op(clipPath, drawnPath, kIntersect_SkPath
Op, &clippedPath)); |
354 } | 367 } |
355 | 368 |
356 SkPaint blurPaint; | 369 SkPaint blurPaint; |
357 blurPaint.setAntiAlias(true); | 370 blurPaint.setAntiAlias(true); |
358 blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlu
rStyle, 3.0f)); | 371 blurPaint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlu
rStyle, sigma)); |
359 canvas->drawPath(clippedPath, blurPaint); | 372 canvas->drawPath(clippedPath, blurPaint); |
360 } else { | 373 } else { |
361 SkASSERT(kRRectsGaussianEdge_Mode == fMode); | 374 SkASSERT(kRRectsGaussianEdge_Mode == fMode); |
362 | 375 |
363 SkRect cover = drawObj->bounds(); | 376 SkRect cover = drawObj->bounds(); |
364 SkAssertResult(cover.intersect(clipObj->bounds())); | 377 SkAssertResult(cover.intersect(clipObj->bounds())); |
365 | 378 |
366 SkPaint paint; | 379 SkPaint paint; |
367 | 380 |
368 SkRRect clipRR, drawnRR; | 381 SkRRect clipRR, drawnRR; |
369 | 382 |
370 if (clipObj->asRRect(&clipRR) && drawObj->asRRect(&drawnRR))
{ | 383 if (clipObj->asRRect(&clipRR) && drawObj->asRRect(&drawnRR))
{ |
371 paint.setShader(SkRRectsGaussianEdgeShader::Make(clipRR,
drawnRR, | 384 paint.setShader(SkRRectsGaussianEdgeShader::Make(clipRR,
drawnRR, |
372 kPad, 0
.0f)); | 385 kPad, 0
.0f)); |
373 } | 386 } |
374 | 387 |
375 canvas->drawRect(cover, paint); | 388 canvas->drawRect(cover, paint); |
376 } | 389 } |
377 | 390 |
378 // Draw the clip and draw objects for reference | 391 // Draw the clip and draw objects for reference |
379 SkPaint strokePaint; | 392 SkPaint strokePaint; |
380 strokePaint.setStyle(SkPaint::kStroke_Style); | 393 strokePaint.setStyle(SkPaint::kStroke_Style); |
381 strokePaint.setStrokeWidth(0); | 394 strokePaint.setStrokeWidth(0); |
382 strokePaint.setColor(SK_ColorRED); | 395 strokePaint.setColor(SK_ColorRED); |
383 canvas->drawPath(drawObj->asPath(), strokePaint); | 396 canvas->drawPath(drawObj->asPath(0.0f), strokePaint); |
384 strokePaint.setColor(SK_ColorGREEN); | 397 strokePaint.setColor(SK_ColorGREEN); |
385 canvas->drawPath(clipObj->asPath(), strokePaint); | 398 canvas->drawPath(clipObj->asPath(0.0f), strokePaint); |
386 | 399 |
387 canvas->restore(); | 400 canvas->restore(); |
388 } | 401 } |
389 } | 402 } |
390 } | 403 } |
391 | 404 |
392 bool onHandleKey(SkUnichar uni) override { | 405 bool onHandleKey(SkUnichar uni) override { |
393 switch (uni) { | 406 switch (uni) { |
394 case 'C': | 407 case 'C': |
395 fMode = (Mode)((fMode + 1) % kModeCount); | 408 fMode = (Mode)((fMode + 1) % kModeCount); |
396 return true; | 409 return true; |
| 410 case 'p': |
| 411 fPause = !fPause; |
| 412 return true; |
397 } | 413 } |
398 | 414 |
399 return false; | 415 return false; |
400 } | 416 } |
401 | 417 |
402 bool onAnimate(const SkAnimTimer& timer) override { | 418 bool onAnimate(const SkAnimTimer& timer) override { |
403 fFraction = timer.pingPong(kPeriod, 0.0f, 0.0f, 1.0f); | 419 if (!fPause) { |
| 420 fFraction = timer.pingPong(kPeriod, 0.0f, 0.0f, 1.0f); |
| 421 } |
404 return true; | 422 return true; |
405 } | 423 } |
406 | 424 |
407 private: | 425 private: |
408 SkScalar fFraction; | 426 SkScalar fFraction; |
409 Mode fMode; | 427 Mode fMode; |
| 428 bool fPause; |
410 | 429 |
411 typedef GM INHERITED; | 430 typedef GM INHERITED; |
412 }; | 431 }; |
413 | 432 |
414 ////////////////////////////////////////////////////////////////////////////// | 433 ////////////////////////////////////////////////////////////////////////////// |
415 | 434 |
416 DEF_GM(return new RevealGM;) | 435 DEF_GM(return new RevealGM;) |
417 } | 436 } |
OLD | NEW |