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