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