1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "gm.h"
9#include "SkBlurDrawLooper.h"
10#include "SkBlurMask.h"
11#include "SkBlurMaskFilter.h"
12#include "SkGradientShader.h"
13#include "SkMatrix.h"
14#include "SkTArray.h"
15
16namespace skiagm {
17
18class RectsGM : public GM {
19public:
20    RectsGM() {
21        this->setBGColor(0xFF000000);
22        this->makePaints();
23        this->makeMatrices();
24        this->makeRects();
25    }
26
27protected:
28    virtual SkString onShortName() SK_OVERRIDE {
29        return SkString("rects");
30    }
31
32    virtual SkISize onISize() SK_OVERRIDE {
33        return make_isize(1200, 900);
34    }
35
36    void makePaints() {
37        {
38            // no AA
39            SkPaint p;
40            p.setColor(SK_ColorWHITE);
41            fPaints.push_back(p);
42        }
43
44        {
45            // AA
46            SkPaint p;
47            p.setColor(SK_ColorWHITE);
48            p.setAntiAlias(true);
49            fPaints.push_back(p);
50        }
51
52        {
53            // AA with translucent
54            SkPaint p;
55            p.setColor(SK_ColorWHITE);
56            p.setAntiAlias(true);
57            p.setAlpha(0x66);
58            fPaints.push_back(p);
59        }
60
61        {
62            // AA with mask filter
63            SkPaint p;
64            p.setColor(SK_ColorWHITE);
65            p.setAntiAlias(true);
66            SkMaskFilter* mf = SkBlurMaskFilter::Create(
67                                   SkBlurMaskFilter::kNormal_BlurStyle,
68                                   SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)),
69                                   SkBlurMaskFilter::kHighQuality_BlurFlag);
70            p.setMaskFilter(mf)->unref();
71            fPaints.push_back(p);
72        }
73
74        {
75            // AA with radial shader
76            SkPaint p;
77            p.setColor(SK_ColorWHITE);
78            p.setAntiAlias(true);
79            SkPoint center = SkPoint::Make(SkIntToScalar(-5), SkIntToScalar(30));
80            SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
81            SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
82            SkShader* s = SkGradientShader::CreateRadial(center,
83                                                         SkIntToScalar(20),
84                                                         colors,
85                                                         pos,
86                                                         SK_ARRAY_COUNT(colors),
87                                                         SkShader::kClamp_TileMode);
88            p.setShader(s)->unref();
89            fPaints.push_back(p);
90        }
91
92        {
93            // AA with blur
94            SkPaint p;
95            p.setColor(SK_ColorWHITE);
96            p.setAntiAlias(true);
97            SkBlurDrawLooper* shadowLooper =
98                new SkBlurDrawLooper (SK_ColorWHITE,
99                                      SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(10)),
100                                      SkIntToScalar(5), SkIntToScalar(10),
101                                      SkBlurDrawLooper::kIgnoreTransform_BlurFlag |
102                                      SkBlurDrawLooper::kOverrideColor_BlurFlag |
103                                      SkBlurDrawLooper::kHighQuality_BlurFlag);
104            SkAutoUnref aurL0(shadowLooper);
105            p.setLooper(shadowLooper);
106            fPaints.push_back(p);
107        }
108
109        {
110            // AA with stroke style
111            SkPaint p;
112            p.setColor(SK_ColorWHITE);
113            p.setAntiAlias(true);
114            p.setStyle(SkPaint::kStroke_Style);
115            p.setStrokeWidth(SkIntToScalar(3));
116            fPaints.push_back(p);
117        }
118
119        {
120            // AA with bevel-stroke style
121            SkPaint p;
122            p.setColor(SK_ColorWHITE);
123            p.setAntiAlias(true);
124            p.setStyle(SkPaint::kStroke_Style);
125            p.setStrokeJoin(SkPaint::kBevel_Join);
126            p.setStrokeWidth(SkIntToScalar(3));
127            fPaints.push_back(p);
128        }
129
130        {
131            // AA with round-stroke style
132            SkPaint p;
133            p.setColor(SK_ColorWHITE);
134            p.setAntiAlias(true);
135            p.setStyle(SkPaint::kStroke_Style);
136            p.setStrokeJoin(SkPaint::kRound_Join);
137            p.setStrokeWidth(SkIntToScalar(3));
138            fPaints.push_back(p);
139        }
140
141        {
142            // AA with stroke style, width = 0
143            SkPaint p;
144            p.setColor(SK_ColorWHITE);
145            p.setAntiAlias(true);
146            p.setStyle(SkPaint::kStroke_Style);
147            fPaints.push_back(p);
148        }
149
150        {
151            // AA with stroke style, width wider than rect width and/or height
152            SkPaint p;
153            p.setColor(SK_ColorWHITE);
154            p.setAntiAlias(true);
155            p.setStyle(SkPaint::kStroke_Style);
156            p.setStrokeWidth(SkIntToScalar(40));
157            fPaints.push_back(p);
158        }
159
160        {
161            // AA with stroke and fill style
162            SkPaint p;
163            p.setColor(SK_ColorWHITE);
164            p.setAntiAlias(true);
165            p.setStyle(SkPaint::kStrokeAndFill_Style);
166            p.setStrokeWidth(SkIntToScalar(2));
167            fPaints.push_back(p);
168        }
169    }
170
171    void makeMatrices() {
172        {
173            // 1x1.5 scale
174            SkMatrix m;
175            m.setScale(1, 1.5f);
176            fMatrices.push_back(m);
177        }
178
179        {
180            // 1.5x1.5 scale
181            SkMatrix m;
182            m.setScale(1.5f, 1.5f);
183            fMatrices.push_back(m);
184        }
185
186        {
187            // 1x1.5 skew
188            SkMatrix m;
189            m.setSkew(1, 1.5f);
190            fMatrices.push_back(m);
191        }
192
193        {
194            // 1.5x1.5 skew
195            SkMatrix m;
196            m.setSkew(1.5f, 1.5f);
197            fMatrices.push_back(m);
198        }
199
200        {
201            // 30 degree rotation
202            SkMatrix m;
203            m.setRotate(SkIntToScalar(30));
204            fMatrices.push_back(m);
205        }
206
207        {
208            // 90 degree rotation
209            SkMatrix m;
210            m.setRotate(SkIntToScalar(90));
211            fMatrices.push_back(m);
212        }
213    }
214
215    void makeRects() {
216        {
217            // small square
218            SkRect r = SkRect::MakeLTRB(0, 0, 30, 30);
219            fRects.push_back(r);
220        }
221
222        {
223            // thin vertical
224            SkRect r = SkRect::MakeLTRB(0, 0, 2, 40);
225            fRects.push_back(r);
226        }
227
228        {
229            // thin horizontal
230            SkRect r = SkRect::MakeLTRB(0, 0, 40, 2);
231            fRects.push_back(r);
232        }
233
234        {
235            // very thin
236            SkRect r = SkRect::MakeLTRB(0, 0, 0.25f, 10);
237            fRects.push_back(r);
238        }
239
240        {
241            // zaftig
242            SkRect r = SkRect::MakeLTRB(0, 0, 60, 60);
243            fRects.push_back(r);
244        }
245    }
246
247    // position the current test on the canvas
248    static void position(SkCanvas* canvas, int testCount) {
249        canvas->translate(SK_Scalar1 * 100 * (testCount % 10) + SK_Scalar1 / 4,
250                          SK_Scalar1 * 100 * (testCount / 10) + 3 * SK_Scalar1 / 4);
251    }
252
253    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
254        SkAutoCommentBlock acb(canvas, "onDraw");
255
256        canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
257
258        int testCount = 0;
259
260        canvas->addComment("Test", "Various Paints");
261
262        for (int i = 0; i < fPaints.count(); ++i) {
263            for (int j = 0; j < fRects.count(); ++j, ++testCount) {
264                canvas->save();
265                this->position(canvas, testCount);
266                canvas->drawRect(fRects[j], fPaints[i]);
267                canvas->restore();
268            }
269        }
270
271        canvas->addComment("Test", "Matrices");
272
273        SkPaint paint;
274        paint.setColor(SK_ColorWHITE);
275        paint.setAntiAlias(true);
276
277        for (int i = 0; i < fMatrices.count(); ++i) {
278            for (int j = 0; j < fRects.count(); ++j, ++testCount) {
279                canvas->save();
280                this->position(canvas, testCount);
281                canvas->concat(fMatrices[i]);
282                canvas->drawRect(fRects[j], paint);
283                canvas->restore();
284            }
285        }
286    }
287
288private:
289    SkTArray<SkPaint>  fPaints;
290    SkTArray<SkMatrix> fMatrices;
291    SkTArray<SkRect>   fRects;
292
293    typedef GM INHERITED;
294};
295
296//////////////////////////////////////////////////////////////////////////////
297
298static GM* MyFactory(void*) { return new RectsGM; }
299static GMRegistry reg(MyFactory);
300
301}
302