• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2013 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 
9 #include "gm.h"
10 #include "SkTArray.h"
11 #include "SkRandom.h"
12 #include "SkMatrix.h"
13 #include "SkBlurMaskFilter.h"
14 #include "SkGradientShader.h"
15 #include "SkBlurDrawLooper.h"
16 #include "SkRect.h"
17 #include "SkRRect.h"
18 
19 namespace skiagm {
20 
21 class RoundRectGM : public GM {
22 public:
RoundRectGM()23     RoundRectGM() {
24         this->setBGColor(0xFF000000);
25         this->makePaints();
26         this->makeMatrices();
27     }
28 
29 protected:
onShortName()30     virtual SkString onShortName() SK_OVERRIDE {
31         return SkString("roundrects");
32     }
33 
onISize()34     virtual SkISize onISize() SK_OVERRIDE {
35         return make_isize(1200, 900);
36     }
37 
makePaints()38     void makePaints() {
39         {
40         // no AA
41         SkPaint p;
42         fPaints.push_back(p);
43         }
44 
45         {
46         // AA
47         SkPaint p;
48         p.setAntiAlias(true);
49         fPaints.push_back(p);
50         }
51 
52         {
53         // AA with stroke style
54         SkPaint p;
55         p.setAntiAlias(true);
56         p.setStyle(SkPaint::kStroke_Style);
57         p.setStrokeWidth(SkIntToScalar(5));
58         fPaints.push_back(p);
59         }
60 
61         {
62         // AA with stroke style, width = 0
63         SkPaint p;
64         p.setAntiAlias(true);
65         p.setStyle(SkPaint::kStroke_Style);
66         fPaints.push_back(p);
67         }
68 
69         {
70         // AA with stroke and fill style
71         SkPaint p;
72         p.setAntiAlias(true);
73         p.setStyle(SkPaint::kStrokeAndFill_Style);
74         p.setStrokeWidth(SkIntToScalar(3));
75         fPaints.push_back(p);
76         }
77     }
78 
makeMatrices()79     void makeMatrices() {
80         {
81         SkMatrix m;
82         m.setIdentity();
83         fMatrices.push_back(m);
84         }
85 
86         {
87         SkMatrix m;
88         m.setScale(SkIntToScalar(3), SkIntToScalar(2));
89         fMatrices.push_back(m);
90         }
91 
92         {
93         SkMatrix m;
94         m.setScale(SkIntToScalar(2), SkIntToScalar(2));
95         fMatrices.push_back(m);
96         }
97 
98         {
99         SkMatrix m;
100         m.setScale(SkIntToScalar(1), SkIntToScalar(2));
101         fMatrices.push_back(m);
102         }
103 
104         {
105         SkMatrix m;
106         m.setScale(SkIntToScalar(4), SkIntToScalar(1));
107         fMatrices.push_back(m);
108         }
109 
110         {
111         SkMatrix m;
112         m.setRotate(SkIntToScalar(90));
113         fMatrices.push_back(m);
114         }
115 
116         {
117         SkMatrix m;
118         m.setSkew(SkIntToScalar(2), SkIntToScalar(3));
119         fMatrices.push_back(m);
120         }
121 
122         {
123         SkMatrix m;
124         m.setRotate(SkIntToScalar(60));
125         fMatrices.push_back(m);
126         }
127     }
128 
genColor(SkRandom * rand)129     SkColor genColor(SkRandom* rand) {
130         SkScalar hsv[3];
131         hsv[0] = rand->nextRangeF(0.0f, 360.0f);
132         hsv[1] = rand->nextRangeF(0.75f, 1.0f);
133         hsv[2] = rand->nextRangeF(0.75f, 1.0f);
134 
135         return SkHSVToColor(hsv);
136     }
137 
onDraw(SkCanvas * canvas)138     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
139         SkRandom rand(1);
140         canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
141         SkRect rect = SkRect::MakeLTRB(-20, -30, 20, 30);
142         SkRRect circleRect;
143         circleRect.setRectXY(rect, 5, 5);
144 
145         const SkScalar kXStart = 60.0f;
146         const SkScalar kYStart = 80.0f;
147         const int kXStep = 150;
148         const int kYStep = 160;
149         int maxX = fMatrices.count();
150 
151         SkPaint rectPaint;
152         rectPaint.setAntiAlias(true);
153         rectPaint.setStyle(SkPaint::kStroke_Style);
154         rectPaint.setStrokeWidth(SkIntToScalar(0));
155         rectPaint.setColor(SK_ColorLTGRAY);
156 
157         int testCount = 0;
158         for (int i = 0; i < fPaints.count(); ++i) {
159             for (int j = 0; j < fMatrices.count(); ++j) {
160                 canvas->save();
161                 SkMatrix mat = fMatrices[j];
162                 // position the roundrect, and make it at off-integer coords.
163                 mat.postTranslate(kXStart + SK_Scalar1 * kXStep * (testCount % maxX) +
164                                   SK_Scalar1 / 4,
165                                   kYStart + SK_Scalar1 * kYStep * (testCount / maxX) +
166                                   3 * SK_Scalar1 / 4);
167                 canvas->concat(mat);
168 
169                 SkColor color = genColor(&rand);
170                 fPaints[i].setColor(color);
171 
172                 canvas->drawRect(rect, rectPaint);
173                 canvas->drawRRect(circleRect, fPaints[i]);
174 
175                 canvas->restore();
176 
177                 ++testCount;
178             }
179         }
180 
181         // special cases
182 
183         // non-scaled tall and skinny roundrect
184         for (int i = 0; i < fPaints.count(); ++i) {
185             SkRect rect = SkRect::MakeLTRB(-20, -60, 20, 60);
186             SkRRect ellipseRect;
187             ellipseRect.setRectXY(rect, 5, 10);
188 
189             canvas->save();
190             // position the roundrect, and make it at off-integer coords.
191             canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.55f + SK_Scalar1 / 4,
192                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
193 
194             SkColor color = genColor(&rand);
195             fPaints[i].setColor(color);
196 
197             canvas->drawRect(rect, rectPaint);
198             canvas->drawRRect(ellipseRect, fPaints[i]);
199             canvas->restore();
200         }
201 
202         // non-scaled wide and short roundrect
203         for (int i = 0; i < fPaints.count(); ++i) {
204             SkRect rect = SkRect::MakeLTRB(-80, -30, 80, 30);
205             SkRRect ellipseRect;
206             ellipseRect.setRectXY(rect, 20, 5);
207 
208             canvas->save();
209             // position the roundrect, and make it at off-integer coords.
210             canvas->translate(kXStart + SK_Scalar1 * kXStep * 4 + SK_Scalar1 / 4,
211                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
212                               SK_ScalarHalf * kYStep);
213 
214             SkColor color = genColor(&rand);
215             fPaints[i].setColor(color);
216 
217             canvas->drawRect(rect, rectPaint);
218             canvas->drawRRect(ellipseRect, fPaints[i]);
219             canvas->restore();
220         }
221 
222         // super skinny roundrect
223         for (int i = 0; i < fPaints.count(); ++i) {
224             SkRect rect = SkRect::MakeLTRB(0, -60, 1, 60);
225             SkRRect circleRect;
226             circleRect.setRectXY(rect, 5, 5);
227 
228             canvas->save();
229             // position the roundrect, and make it at off-integer coords.
230             canvas->translate(kXStart + SK_Scalar1 * kXStep * 3.25f + SK_Scalar1 / 4,
231                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
232 
233             SkColor color = genColor(&rand);
234             fPaints[i].setColor(color);
235 
236             canvas->drawRRect(circleRect, fPaints[i]);
237             canvas->restore();
238         }
239 
240         // super short roundrect
241         for (int i = 0; i < fPaints.count(); ++i) {
242             SkRect rect = SkRect::MakeLTRB(-80, -1, 80, 0);
243             SkRRect circleRect;
244             circleRect.setRectXY(rect, 5, 5);
245 
246             canvas->save();
247             // position the roundrect, and make it at off-integer coords.
248             canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.5f + SK_Scalar1 / 4,
249                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
250                               SK_ScalarHalf * kYStep);
251 
252             SkColor color = genColor(&rand);
253             fPaints[i].setColor(color);
254 
255             canvas->drawRRect(circleRect, fPaints[i]);
256             canvas->restore();
257         }
258 
259         // radial gradient
260         SkPoint center = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0));
261         SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
262         SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
263         SkAutoTUnref<SkShader> shader(SkGradientShader::CreateRadial(center,
264                                                      SkIntToScalar(20),
265                                                      colors,
266                                                      pos,
267                                                      SK_ARRAY_COUNT(colors),
268                                                      SkShader::kClamp_TileMode));
269 
270         for (int i = 0; i < fPaints.count(); ++i) {
271             canvas->save();
272             // position the path, and make it at off-integer coords.
273             canvas->translate(kXStart + SK_Scalar1 * kXStep * 0 + SK_Scalar1 / 4,
274                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
275                               SK_ScalarHalf * kYStep);
276 
277             SkColor color = genColor(&rand);
278             fPaints[i].setColor(color);
279             fPaints[i].setShader(shader);
280 
281             canvas->drawRect(rect, rectPaint);
282             canvas->drawRRect(circleRect, fPaints[i]);
283 
284             fPaints[i].setShader(NULL);
285 
286             canvas->restore();
287         }
288 
289         // strokes and radii
290         {
291             SkScalar radii[][2] = {
292                 {10,10},
293                 {5,15},
294                 {5,15},
295                 {5,15}
296             };
297 
298             SkScalar strokeWidths[] = {
299                 20, 10, 20, 40
300             };
301 
302             for (int i = 0; i < 4; ++i) {
303                 SkRRect circleRect;
304                 circleRect.setRectXY(rect, radii[i][0], radii[i][1]);
305 
306                 canvas->save();
307                 // position the roundrect, and make it at off-integer coords.
308                 canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
309                                   kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
310                                   SK_ScalarHalf * kYStep);
311 
312                 SkColor color = genColor(&rand);
313 
314                 SkPaint p;
315                 p.setAntiAlias(true);
316                 p.setStyle(SkPaint::kStroke_Style);
317                 p.setStrokeWidth(strokeWidths[i]);
318                 p.setColor(color);
319 
320                 canvas->drawRRect(circleRect, p);
321                 canvas->restore();
322             }
323         }
324 
325     }
326 
327 private:
328     SkTArray<SkPaint> fPaints;
329     SkTArray<SkMatrix> fMatrices;
330 
331     typedef GM INHERITED;
332 };
333 
334 //////////////////////////////////////////////////////////////////////////////
335 
MyFactory(void *)336 static GM* MyFactory(void*) { return new RoundRectGM; }
337 static GMRegistry reg(MyFactory);
338 
339 }
340