blob: a36ab1f4591429095fe707db90bc05c7122f8dc0 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 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 */
bungemand3ebb482015-08-05 13:57:49 -07007
reed@google.comc2807002011-04-11 13:57:04 +00008#include "gm.h"
bungemand3ebb482015-08-05 13:57:49 -07009#include "SkPath.h"
reed@google.comc2807002011-04-11 13:57:04 +000010
11typedef SkScalar (*MakePathProc)(SkPath*);
12
13static SkScalar make_frame(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000014 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
15 SkIntToScalar(630), SkIntToScalar(470) };
16 path->addRoundRect(r, SkIntToScalar(15), SkIntToScalar(15));
rmistry@google.comd6176b02012-08-23 18:14:13 +000017
reed@google.comc2807002011-04-11 13:57:04 +000018 SkPaint paint;
19 paint.setStyle(SkPaint::kStroke_Style);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000020 paint.setStrokeWidth(SkIntToScalar(5));
reed@google.comc2807002011-04-11 13:57:04 +000021 paint.getFillPath(*path, path);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000022 return SkIntToScalar(15);
reed@google.comc2807002011-04-11 13:57:04 +000023}
24
25static SkScalar make_triangle(SkPath* path) {
mtkleindbfd7ab2016-09-01 11:24:54 -070026 constexpr int gCoord[] = {
reed@google.comc2807002011-04-11 13:57:04 +000027 10, 20, 15, 5, 30, 30
28 };
29 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
30 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
31 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
32 path->close();
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000033 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000034 return SkIntToScalar(30);
35}
36
37static SkScalar make_rect(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000038 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
39 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000040 path->addRect(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000041 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000042 return SkIntToScalar(30);
43}
44
45static SkScalar make_oval(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000046 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
47 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000048 path->addOval(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000049 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000050 return SkIntToScalar(30);
51}
52
Jim Van Verthecdb6862016-12-13 18:17:47 -050053static SkScalar make_sawtooth(SkPath* path, int teeth) {
reed@google.comc2807002011-04-11 13:57:04 +000054 SkScalar x = SkIntToScalar(20);
55 SkScalar y = SkIntToScalar(20);
56 const SkScalar x0 = x;
Jim Van Verthecdb6862016-12-13 18:17:47 -050057 const SkScalar dx = SkIntToScalar(5);
58 const SkScalar dy = SkIntToScalar(10);
rmistry@google.comd6176b02012-08-23 18:14:13 +000059
reed@google.comc2807002011-04-11 13:57:04 +000060 path->moveTo(x, y);
Jim Van Verthecdb6862016-12-13 18:17:47 -050061 for (int i = 0; i < teeth; i++) {
reed@google.comc2807002011-04-11 13:57:04 +000062 x += dx;
63 path->lineTo(x, y - dy);
64 x += dx;
65 path->lineTo(x, y + dy);
66 }
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000067 path->lineTo(x, y + (2 * dy));
68 path->lineTo(x0, y + (2 * dy));
reed@google.comc2807002011-04-11 13:57:04 +000069 path->close();
70 return SkIntToScalar(30);
71}
72
Jim Van Verthecdb6862016-12-13 18:17:47 -050073static SkScalar make_sawtooth_3(SkPath* path) { return make_sawtooth(path, 3); }
74static SkScalar make_sawtooth_32(SkPath* path) { return make_sawtooth(path, 32); }
75
76static SkScalar make_house(SkPath* path) {
77 path->moveTo(21, 23);
78 path->lineTo(21, 11.534f);
79 path->lineTo(22.327f, 12.741f);
80 path->lineTo(23.673f, 11.261f);
81 path->lineTo(12, 0.648f);
82 path->lineTo(8, 4.285f);
83 path->lineTo(8, 2);
84 path->lineTo(4, 2);
85 path->lineTo(4, 7.921f);
86 path->lineTo(0.327f, 11.26f);
87 path->lineTo(1.673f, 12.74f);
88 path->lineTo(3, 11.534f);
89 path->lineTo(3, 23);
90 path->lineTo(11, 23);
91 path->lineTo(11, 18);
92 path->lineTo(13, 18);
93 path->lineTo(13, 23);
94 path->lineTo(21, 23);
95 path->close();
96 path->lineTo(9, 16);
97 path->lineTo(9, 21);
98 path->lineTo(5, 21);
99 path->lineTo(5, 9.715f);
100 path->lineTo(12, 3.351f);
101 path->lineTo(19, 9.715f);
102 path->lineTo(19, 21);
103 path->lineTo(15, 21);
104 path->lineTo(15, 16);
105 path->lineTo(9, 16);
106 path->close();
107 path->offset(20, 0);
108 return SkIntToScalar(30);
109}
110
reed@google.comc2807002011-04-11 13:57:04 +0000111static SkScalar make_star(SkPath* path, int n) {
112 const SkScalar c = SkIntToScalar(45);
113 const SkScalar r = SkIntToScalar(20);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000114
reed@google.comc2807002011-04-11 13:57:04 +0000115 SkScalar rad = -SK_ScalarPI / 2;
116 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000117
reed@google.comc2807002011-04-11 13:57:04 +0000118 path->moveTo(c, c - r);
119 for (int i = 1; i < n; i++) {
120 rad += drad;
121 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
Mike Reeddf85c382017-02-14 10:59:19 -0500122 path->lineTo(c + cosV * r, c + sinV * r);
reed@google.comc2807002011-04-11 13:57:04 +0000123 }
124 path->close();
125 return r * 2 * 6 / 5;
126}
127
128static SkScalar make_star_5(SkPath* path) { return make_star(path, 5); }
129static SkScalar make_star_13(SkPath* path) { return make_star(path, 13); }
130
vandebo@chromium.org683001c2012-05-09 17:17:51 +0000131// We don't expect any output from this path.
132static SkScalar make_line(SkPath* path) {
133 path->moveTo(SkIntToScalar(30), SkIntToScalar(30));
134 path->lineTo(SkIntToScalar(120), SkIntToScalar(40));
135 path->close();
136 path->moveTo(SkIntToScalar(150), SkIntToScalar(30));
137 path->lineTo(SkIntToScalar(150), SkIntToScalar(30));
138 path->lineTo(SkIntToScalar(300), SkIntToScalar(40));
139 path->close();
140 return SkIntToScalar(40);
141}
142
Jim Van Verthf9e678d2017-02-15 15:46:52 -0500143static void make_info(SkPath* path) {
Jim Van Verth77047542017-01-11 14:17:00 -0500144 path->moveTo(24, 4);
145 path->cubicTo(12.94999980926514f,
146 4,
147 4,
148 12.94999980926514f,
149 4,
150 24);
151 path->cubicTo(4,
152 35.04999923706055f,
153 12.94999980926514f,
154 44,
155 24,
156 44);
157 path->cubicTo(35.04999923706055f,
158 44,
159 44,
160 35.04999923706055f,
161 44,
162 24);
163 path->cubicTo(44,
164 12.95000076293945f,
165 35.04999923706055f,
166 4,
167 24,
168 4);
169 path->close();
170 path->moveTo(26, 34);
171 path->lineTo(22, 34);
172 path->lineTo(22, 22);
173 path->lineTo(26, 22);
174 path->lineTo(26, 34);
175 path->close();
176 path->moveTo(26, 18);
177 path->lineTo(22, 18);
178 path->lineTo(22, 14);
179 path->lineTo(26, 14);
180 path->lineTo(26, 18);
181 path->close();
Jim Van Verthf9e678d2017-02-15 15:46:52 -0500182}
Jim Van Verth77047542017-01-11 14:17:00 -0500183
Jim Van Verthf9e678d2017-02-15 15:46:52 -0500184static void make_accessibility(SkPath* path) {
185 path->moveTo(12, 2);
186 path->cubicTo(13.10000038146973f,
187 2,
188 14,
189 2.900000095367432f,
190 14,
191 4);
192 path->cubicTo(14,
193 5.099999904632568f,
194 13.10000038146973f,
195 6,
196 12,
197 6);
198 path->cubicTo(10.89999961853027f,
199 6,
200 10,
201 5.099999904632568f,
202 10,
203 4);
204 path->cubicTo(10,
205 2.900000095367432f,
206 10.89999961853027f,
207 2,
208 12,
209 2);
210 path->close();
211 path->moveTo(21, 9);
212 path->lineTo(15, 9);
213 path->lineTo(15, 22);
214 path->lineTo(13, 22);
215 path->lineTo(13, 16);
216 path->lineTo(11, 16);
217 path->lineTo(11, 22);
218 path->lineTo(9, 22);
219 path->lineTo(9, 9);
220 path->lineTo(3, 9);
221 path->lineTo(3, 7);
222 path->lineTo(21, 7);
223 path->lineTo(21, 9);
224 path->close();
Jim Van Verth77047542017-01-11 14:17:00 -0500225}
226
mtkleindbfd7ab2016-09-01 11:24:54 -0700227constexpr MakePathProc gProcs[] = {
reed@google.comc2807002011-04-11 13:57:04 +0000228 make_frame,
229 make_triangle,
230 make_rect,
231 make_oval,
Jim Van Verthecdb6862016-12-13 18:17:47 -0500232 make_sawtooth_32,
reed@google.comc2807002011-04-11 13:57:04 +0000233 make_star_5,
vandebo@chromium.org683001c2012-05-09 17:17:51 +0000234 make_star_13,
235 make_line,
Jim Van Verthecdb6862016-12-13 18:17:47 -0500236 make_house,
237 make_sawtooth_3,
reed@google.comc2807002011-04-11 13:57:04 +0000238};
239
240#define N SK_ARRAY_COUNT(gProcs)
241
reed@google.com5ee64912012-06-11 17:30:33 +0000242class PathFillGM : public skiagm::GM {
reed@google.comc2807002011-04-11 13:57:04 +0000243 SkPath fPath[N];
244 SkScalar fDY[N];
Jim Van Verth77047542017-01-11 14:17:00 -0500245 SkPath fInfoPath;
Jim Van Verthf9e678d2017-02-15 15:46:52 -0500246 SkPath fAccessibilityPath;
caryclark88c748a2015-02-18 10:56:00 -0800247protected:
mtklein36352bf2015-03-25 18:17:31 -0700248 void onOnceBeforeDraw() override {
reed@google.comc2807002011-04-11 13:57:04 +0000249 for (size_t i = 0; i < N; i++) {
250 fDY[i] = gProcs[i](&fPath[i]);
251 }
Jim Van Verth77047542017-01-11 14:17:00 -0500252
Jim Van Verthf9e678d2017-02-15 15:46:52 -0500253 make_info(&fInfoPath);
254 make_accessibility(&fAccessibilityPath);
reed@google.comc2807002011-04-11 13:57:04 +0000255 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000256
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000257
mtklein36352bf2015-03-25 18:17:31 -0700258 SkString onShortName() override {
reed@google.comc2807002011-04-11 13:57:04 +0000259 return SkString("pathfill");
260 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000261
mtklein36352bf2015-03-25 18:17:31 -0700262 SkISize onISize() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000263 return SkISize::Make(640, 480);
reed@google.comc2807002011-04-11 13:57:04 +0000264 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000265
mtklein36352bf2015-03-25 18:17:31 -0700266 void onDraw(SkCanvas* canvas) override {
reed@google.comc2807002011-04-11 13:57:04 +0000267 SkPaint paint;
268 paint.setAntiAlias(true);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000269
reed@google.comc2807002011-04-11 13:57:04 +0000270 for (size_t i = 0; i < N; i++) {
271 canvas->drawPath(fPath[i], paint);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000272 canvas->translate(SkIntToScalar(0), fDY[i]);
reed@google.comc2807002011-04-11 13:57:04 +0000273 }
Jim Van Verth77047542017-01-11 14:17:00 -0500274
Jim Van Verthf9e678d2017-02-15 15:46:52 -0500275 canvas->save();
Jim Van Verth77047542017-01-11 14:17:00 -0500276 canvas->scale(0.300000011920929f, 0.300000011920929f);
277 canvas->translate(50, 50);
278 canvas->drawPath(fInfoPath, paint);
Jim Van Verthf9e678d2017-02-15 15:46:52 -0500279 canvas->restore();
280
281 canvas->scale(2, 2);
282 canvas->translate(5, 15);
283 canvas->drawPath(fAccessibilityPath, paint);
reed@google.comc2807002011-04-11 13:57:04 +0000284 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000285
reed@google.comc2807002011-04-11 13:57:04 +0000286private:
reed@google.com5ee64912012-06-11 17:30:33 +0000287 typedef skiagm::GM INHERITED;
288};
289
290// test inverse-fill w/ a clip that completely excludes the geometry
291class PathInverseFillGM : public skiagm::GM {
292 SkPath fPath[N];
293 SkScalar fDY[N];
caryclark88c748a2015-02-18 10:56:00 -0800294protected:
mtklein36352bf2015-03-25 18:17:31 -0700295 void onOnceBeforeDraw() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000296 for (size_t i = 0; i < N; i++) {
297 fDY[i] = gProcs[i](&fPath[i]);
298 }
299 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000300
mtklein36352bf2015-03-25 18:17:31 -0700301 SkString onShortName() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000302 return SkString("pathinvfill");
303 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000304
mtklein36352bf2015-03-25 18:17:31 -0700305 SkISize onISize() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000306 return SkISize::Make(450, 220);
307 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000308
reed@google.com5ee64912012-06-11 17:30:33 +0000309 static void show(SkCanvas* canvas, const SkPath& path, const SkPaint& paint,
310 const SkRect* clip, SkScalar top, const SkScalar bottom) {
311 canvas->save();
312 if (clip) {
313 SkRect r = *clip;
314 r.fTop = top;
315 r.fBottom = bottom;
316 canvas->clipRect(r);
317 }
318 canvas->drawPath(path, paint);
319 canvas->restore();
320 }
321
mtklein36352bf2015-03-25 18:17:31 -0700322 void onDraw(SkCanvas* canvas) override {
reed@google.com5ee64912012-06-11 17:30:33 +0000323 SkPath path;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000324
reed@google.com5ee64912012-06-11 17:30:33 +0000325 path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
326 path.toggleInverseFillType();
327
328 SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
329
330 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
331
332 for (int doclip = 0; doclip <= 1; ++doclip) {
333 for (int aa = 0; aa <= 1; ++aa) {
334 SkPaint paint;
335 paint.setAntiAlias(SkToBool(aa));
336
337 canvas->save();
338 canvas->clipRect(clipR);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000339
halcanary96fcdcc2015-08-27 07:41:13 -0700340 const SkRect* clipPtr = doclip ? &clipR : nullptr;
reed@google.com5ee64912012-06-11 17:30:33 +0000341
342 show(canvas, path, paint, clipPtr, clipR.fTop, clipR.centerY());
343 show(canvas, path, paint, clipPtr, clipR.centerY(), clipR.fBottom);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000344
reed@google.com5ee64912012-06-11 17:30:33 +0000345 canvas->restore();
346 canvas->translate(SkIntToScalar(110), 0);
347 }
348 }
349 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000350
reed@google.com5ee64912012-06-11 17:30:33 +0000351private:
352 typedef skiagm::GM INHERITED;
reed@google.comc2807002011-04-11 13:57:04 +0000353};
354
caryclarke3e8c722016-03-01 09:42:03 -0800355DEF_SIMPLE_GM(rotatedcubicpath, canvas, 200, 200) {
356 SkPaint p;
357 p.setAntiAlias(true);
358 p.setStyle(SkPaint::kFill_Style);
359
360 canvas->translate(50, 50);
361 SkPath path;
362 path.moveTo(48,-23);
363 path.cubicTo(48,-29.5, 6,-30, 6,-30);
364 path.cubicTo(6,-30, 2,0, 2,0);
365 path.cubicTo(2,0, 44,-21.5, 48,-23);
366 path.close();
367
368 p.setColor(SK_ColorBLUE);
369 canvas->drawPath(path, p);
370
371 // Rotated path, which is not antialiased on GPU
372 p.setColor(SK_ColorRED);
373 canvas->rotate(90);
374 canvas->drawPath(path, p);
375}
376
reed@google.comc2807002011-04-11 13:57:04 +0000377///////////////////////////////////////////////////////////////////////////////
378
scroggo96f16e82015-12-10 13:31:59 -0800379DEF_GM( return new PathFillGM; )
380DEF_GM( return new PathInverseFillGM; )