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 "sk_tool_utils.h"
10 #include "SkTArray.h"
11 #include "SkRandom.h"
12 #include "SkMatrix.h"
13 #include "SkBlurMaskFilter.h"
14 #include "SkColorFilter.h"
15 #include "SkGradientShader.h"
16 #include "SkBlurDrawLooper.h"
17 #include "SkRect.h"
18
19 namespace skiagm {
20
21 class OvalGM : public GM {
22 public:
OvalGM()23 OvalGM() {
24 this->setBGColor(0xFF000000);
25 this->makePaints();
26 this->makeMatrices();
27 }
28
29 protected:
30
onShortName()31 SkString onShortName() override {
32 return SkString("ovals");
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 sk_tool_utils::color_to_565(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 oval = SkRect::MakeLTRB(-20, -30, 20, 30);
143
144 const SkScalar kXStart = 60.0f;
145 const SkScalar kYStart = 80.0f;
146 const int kXStep = 150;
147 const int kYStep = 160;
148 int maxX = fMatrices.count();
149
150 SkPaint rectPaint;
151 rectPaint.setAntiAlias(true);
152 rectPaint.setStyle(SkPaint::kStroke_Style);
153 rectPaint.setStrokeWidth(SkIntToScalar(0));
154 rectPaint.setColor(sk_tool_utils::color_to_565(SK_ColorLTGRAY));
155
156 int testCount = 0;
157 for (int i = 0; i < fPaints.count(); ++i) {
158 for (int j = 0; j < fMatrices.count(); ++j) {
159 canvas->save();
160 SkMatrix mat = fMatrices[j];
161 // position the oval, and make it at off-integer coords.
162 mat.postTranslate(kXStart + SK_Scalar1 * kXStep * (testCount % maxX) +
163 SK_Scalar1 / 4,
164 kYStart + SK_Scalar1 * kYStep * (testCount / maxX) +
165 3 * SK_Scalar1 / 4);
166 canvas->concat(mat);
167
168 SkColor color = genColor(&rand);
169 fPaints[i].setColor(color);
170
171 canvas->drawRect(oval, rectPaint);
172 canvas->drawOval(oval, fPaints[i]);
173
174 canvas->restore();
175
176 ++testCount;
177 }
178 }
179
180 // special cases
181
182 // non-scaled tall and skinny oval
183 for (int i = 0; i < fPaints.count(); ++i) {
184 SkRect oval = SkRect::MakeLTRB(-20, -60, 20, 60);
185 canvas->save();
186 // position the oval, and make it at off-integer coords.
187 canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.55f + SK_Scalar1 / 4,
188 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
189
190 SkColor color = genColor(&rand);
191 fPaints[i].setColor(color);
192
193 canvas->drawRect(oval, rectPaint);
194 canvas->drawOval(oval, fPaints[i]);
195 canvas->restore();
196 }
197
198 // non-scaled wide and short oval
199 for (int i = 0; i < fPaints.count(); ++i) {
200 SkRect oval = SkRect::MakeLTRB(-80, -30, 80, 30);
201 canvas->save();
202 // position the oval, and make it at off-integer coords.
203 canvas->translate(kXStart + SK_Scalar1 * kXStep * 4 + SK_Scalar1 / 4,
204 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
205 SK_ScalarHalf * kYStep);
206
207 SkColor color = genColor(&rand);
208 fPaints[i].setColor(color);
209
210 canvas->drawRect(oval, rectPaint);
211 canvas->drawOval(oval, fPaints[i]);
212 canvas->restore();
213 }
214
215 // super skinny oval
216 for (int i = 0; i < fPaints.count(); ++i) {
217 SkRect oval = SkRect::MakeLTRB(0, -60, 1, 60);
218 canvas->save();
219 // position the oval, and make it at off-integer coords.
220 canvas->translate(kXStart + SK_Scalar1 * kXStep * 3.25f + SK_Scalar1 / 4,
221 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
222
223 SkColor color = genColor(&rand);
224 fPaints[i].setColor(color);
225
226 canvas->drawOval(oval, fPaints[i]);
227 canvas->restore();
228 }
229
230 // super short oval
231 for (int i = 0; i < fPaints.count(); ++i) {
232 SkRect oval = SkRect::MakeLTRB(-80, -1, 80, 0);
233 canvas->save();
234 // position the oval, and make it at off-integer coords.
235 canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.5f + SK_Scalar1 / 4,
236 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
237 SK_ScalarHalf * kYStep);
238
239 SkColor color = genColor(&rand);
240 fPaints[i].setColor(color);
241
242 canvas->drawOval(oval, fPaints[i]);
243 canvas->restore();
244 }
245
246 // radial gradient
247 SkPoint center = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0));
248 SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
249 SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
250 auto shader = SkGradientShader::MakeRadial(center, 20, colors, pos, SK_ARRAY_COUNT(colors),
251 SkShader::kClamp_TileMode);
252
253 for (int i = 0; i < fPaints.count(); ++i) {
254 canvas->save();
255 // position the path, and make it at off-integer coords.
256 canvas->translate(kXStart + SK_Scalar1 * kXStep * 0 + SK_Scalar1 / 4,
257 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
258 SK_ScalarHalf * kYStep);
259
260 SkColor color = genColor(&rand);
261 fPaints[i].setColor(color);
262 fPaints[i].setShader(shader);
263
264 canvas->drawRect(oval, rectPaint);
265 canvas->drawOval(oval, fPaints[i]);
266
267 fPaints[i].setShader(nullptr);
268
269 canvas->restore();
270 }
271
272 // reflected oval
273 for (int i = 0; i < fPaints.count(); ++i) {
274 SkRect oval = SkRect::MakeLTRB(-30, -30, 30, 30);
275 canvas->save();
276 // position the oval, and make it at off-integer coords.
277 canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
278 kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
279 SK_ScalarHalf * kYStep);
280 canvas->rotate(90);
281 canvas->scale(1, -1);
282 canvas->scale(1, 0.66f);
283
284 SkColor color = genColor(&rand);
285 fPaints[i].setColor(color);
286
287 canvas->drawRect(oval, rectPaint);
288 canvas->drawOval(oval, fPaints[i]);
289 canvas->restore();
290 }
291 }
292
293 private:
294 SkTArray<SkPaint> fPaints;
295 SkTArray<SkMatrix> fMatrices;
296
297 typedef GM INHERITED;
298 };
299
300 //////////////////////////////////////////////////////////////////////////////
301
MyFactory(void *)302 static GM* MyFactory(void*) { return new OvalGM; }
303 static GMRegistry reg(MyFactory);
304
305 }
306