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