blob: 30a5dfded37086e2a6c92faff6f8ee6b3f4bb6cb [file] [log] [blame]
schenney@chromium.org4da06ab2011-12-20 15:14:18 +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 */
7#include "gm.h"
8#include "SkCanvas.h"
9#include "SkPaint.h"
10#include "SkRandom.h"
11
12namespace skiagm {
13
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000014class MovePathGM : public GM {
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000015public:
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000016 MovePathGM() {}
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000017
18protected:
19 SkString onShortName() {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000020 return SkString("movepath");
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000021 }
22
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000023 SkISize onISize() { return make_isize(1240, 390); }
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000024
25 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
26 const SkRect& clip,SkPaint::Cap cap,
27 SkPaint::Style style, SkPath::FillType fill,
28 SkScalar strokeWidth) {
29 path.setFillType(fill);
30 SkPaint paint;
31 paint.setStrokeCap(cap);
32 paint.setStrokeWidth(strokeWidth);
33 paint.setColor(color);
34 paint.setStyle(style);
35 canvas->save();
36 canvas->clipRect(clip);
37 canvas->drawPath(path, paint);
38 canvas->restore();
39 }
40
41 virtual void onDraw(SkCanvas* canvas) {
42 struct FillAndName {
43 SkPath::FillType fFill;
44 const char* fName;
45 };
46 static const FillAndName gFills[] = {
47 {SkPath::kWinding_FillType, "Winding"},
48 {SkPath::kEvenOdd_FillType, "Even / Odd"},
49 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
50 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
51 };
52 struct StyleAndName {
53 SkPaint::Style fStyle;
54 const char* fName;
55 };
56 static const StyleAndName gStyles[] = {
57 {SkPaint::kFill_Style, "Fill"},
58 {SkPaint::kStroke_Style, "Stroke"},
59 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
60 };
61 struct CapAndName {
62 SkPaint::Cap fCap;
63 const char* fName;
64 };
65 static const CapAndName gCaps[] = {
66 {SkPaint::kButt_Cap, "Butt"},
67 {SkPaint::kRound_Cap, "Round"},
68 {SkPaint::kSquare_Cap, "Square"},
69 };
70 struct PathAndName {
71 SkPath fPath;
72 const char* fName;
73 };
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000074 PathAndName path;
75 path.fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
76 path.fName = "moveTo";
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000077
78 SkPaint titlePaint;
79 titlePaint.setColor(SK_ColorBLACK);
80 titlePaint.setAntiAlias(true);
81 titlePaint.setLCDRenderText(true);
82 titlePaint.setTextSize(15 * SK_Scalar1);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000083 const char title[] = "Lone Move Drawn Into Rectangle Clips With "
84 "Indicated Style, Fill and Linecaps, with stroke width 10";
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000085 canvas->drawText(title, strlen(title),
86 20 * SK_Scalar1,
87 20 * SK_Scalar1,
88 titlePaint);
89
90 SkRandom rand;
91 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
92 canvas->save();
93 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
94 canvas->save();
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000095 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
96 if (0 < cap) {
97 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000098 }
99 canvas->save();
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000100 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
101 if (0 < fill) {
102 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000103 }
104 canvas->save();
105 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
106 if (0 < style) {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000107 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000108 }
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000109
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000110 SkColor color = 0xff007000;
111 this->drawPath(path.fPath, canvas, color, rect,
112 gCaps[cap].fCap, gStyles[style].fStyle,
113 gFills[fill].fFill, SK_Scalar1*10);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000114
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000115 SkPaint rectPaint;
116 rectPaint.setColor(SK_ColorBLACK);
117 rectPaint.setStyle(SkPaint::kStroke_Style);
118 rectPaint.setStrokeWidth(-1);
119 rectPaint.setAntiAlias(true);
120 canvas->drawRect(rect, rectPaint);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000121
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000122 SkPaint labelPaint;
123 labelPaint.setColor(color);
124 labelPaint.setAntiAlias(true);
125 labelPaint.setLCDRenderText(true);
126 labelPaint.setTextSize(10 * SK_Scalar1);
127 canvas->drawText(gStyles[style].fName,
128 strlen(gStyles[style].fName),
129 0, rect.height() + 12 * SK_Scalar1,
130 labelPaint);
131 canvas->drawText(gFills[fill].fName,
132 strlen(gFills[fill].fName),
133 0, rect.height() + 24 * SK_Scalar1,
134 labelPaint);
135 canvas->drawText(gCaps[cap].fName,
136 strlen(gCaps[cap].fName),
137 0, rect.height() + 36 * SK_Scalar1,
138 labelPaint);
139 }
140 canvas->restore();
141 }
142 canvas->restore();
143 }
144 canvas->restore();
145 canvas->restore();
146 }
147
148private:
149 typedef GM INHERITED;
150};
151
152class MoveClosePathGM : public GM {
153public:
154 MoveClosePathGM() {}
155
156protected:
157 SkString onShortName() {
158 return SkString("moveclosepath");
159 }
160
161 SkISize onISize() { return make_isize(1240, 390); }
162
163 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
164 const SkRect& clip,SkPaint::Cap cap,
165 SkPaint::Style style, SkPath::FillType fill,
166 SkScalar strokeWidth) {
167 path.setFillType(fill);
168 SkPaint paint;
169 paint.setStrokeCap(cap);
170 paint.setStrokeWidth(strokeWidth);
171 paint.setColor(color);
172 paint.setStyle(style);
173 canvas->save();
174 canvas->clipRect(clip);
175 canvas->drawPath(path, paint);
176 canvas->restore();
177 }
178
179 virtual void onDraw(SkCanvas* canvas) {
180 struct FillAndName {
181 SkPath::FillType fFill;
182 const char* fName;
183 };
184 static const FillAndName gFills[] = {
185 {SkPath::kWinding_FillType, "Winding"},
186 {SkPath::kEvenOdd_FillType, "Even / Odd"},
187 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
188 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
189 };
190 struct StyleAndName {
191 SkPaint::Style fStyle;
192 const char* fName;
193 };
194 static const StyleAndName gStyles[] = {
195 {SkPaint::kFill_Style, "Fill"},
196 {SkPaint::kStroke_Style, "Stroke"},
197 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
198 };
199 struct CapAndName {
200 SkPaint::Cap fCap;
201 const char* fName;
202 };
203 static const CapAndName gCaps[] = {
204 {SkPaint::kButt_Cap, "Butt"},
205 {SkPaint::kRound_Cap, "Round"},
206 {SkPaint::kSquare_Cap, "Square"},
207 };
208 struct PathAndName {
209 SkPath fPath;
210 const char* fName;
211 };
212 PathAndName path;
213 path.fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
214 path.fPath.close();
215 path.fName = "moveTo-close";
216
217 SkPaint titlePaint;
218 titlePaint.setColor(SK_ColorBLACK);
219 titlePaint.setAntiAlias(true);
220 titlePaint.setLCDRenderText(true);
221 titlePaint.setTextSize(15 * SK_Scalar1);
222 const char title[] = "Move Close Drawn Into Rectangle Clips With "
223 "Indicated Style, Fill and Linecaps, with stroke width 10";
224 canvas->drawText(title, strlen(title),
225 20 * SK_Scalar1,
226 20 * SK_Scalar1,
227 titlePaint);
228
229 SkRandom rand;
230 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
231 canvas->save();
232 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
233 canvas->save();
234 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
235 if (0 < cap) {
236 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
237 }
238 canvas->save();
239 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
240 if (0 < fill) {
241 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
242 }
243 canvas->save();
244 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
245 if (0 < style) {
246 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000247 }
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000248
249 SkColor color = 0xff007000;
250 this->drawPath(path.fPath, canvas, color, rect,
251 gCaps[cap].fCap, gStyles[style].fStyle,
252 gFills[fill].fFill, SK_Scalar1*10);
253
254 SkPaint rectPaint;
255 rectPaint.setColor(SK_ColorBLACK);
256 rectPaint.setStyle(SkPaint::kStroke_Style);
257 rectPaint.setStrokeWidth(-1);
258 rectPaint.setAntiAlias(true);
259 canvas->drawRect(rect, rectPaint);
260
261 SkPaint labelPaint;
262 labelPaint.setColor(color);
263 labelPaint.setAntiAlias(true);
264 labelPaint.setLCDRenderText(true);
265 labelPaint.setTextSize(10 * SK_Scalar1);
266 canvas->drawText(gStyles[style].fName,
267 strlen(gStyles[style].fName),
268 0, rect.height() + 12 * SK_Scalar1,
269 labelPaint);
270 canvas->drawText(gFills[fill].fName,
271 strlen(gFills[fill].fName),
272 0, rect.height() + 24 * SK_Scalar1,
273 labelPaint);
274 canvas->drawText(gCaps[cap].fName,
275 strlen(gCaps[cap].fName),
276 0, rect.height() + 36 * SK_Scalar1,
277 labelPaint);
278 }
279 canvas->restore();
280 }
281 canvas->restore();
282 }
283 canvas->restore();
284 canvas->restore();
285 }
286
287private:
288 typedef GM INHERITED;
289};
290
291class MoveMovePathGM : public GM {
292public:
293 MoveMovePathGM() {}
294
295protected:
296 SkString onShortName() {
297 return SkString("movemovepath");
298 }
299
300 SkISize onISize() { return make_isize(1240, 390); }
301
302 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
303 const SkRect& clip,SkPaint::Cap cap,
304 SkPaint::Style style, SkPath::FillType fill,
305 SkScalar strokeWidth) {
306 path.setFillType(fill);
307 SkPaint paint;
308 paint.setStrokeCap(cap);
309 paint.setStrokeWidth(strokeWidth);
310 paint.setColor(color);
311 paint.setStyle(style);
312 canvas->save();
313 canvas->clipRect(clip);
314 canvas->drawPath(path, paint);
315 canvas->restore();
316 }
317
318 virtual void onDraw(SkCanvas* canvas) {
319 struct FillAndName {
320 SkPath::FillType fFill;
321 const char* fName;
322 };
323 static const FillAndName gFills[] = {
324 {SkPath::kWinding_FillType, "Winding"},
325 {SkPath::kEvenOdd_FillType, "Even / Odd"},
326 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
327 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
328 };
329 struct StyleAndName {
330 SkPaint::Style fStyle;
331 const char* fName;
332 };
333 static const StyleAndName gStyles[] = {
334 {SkPaint::kFill_Style, "Fill"},
335 {SkPaint::kStroke_Style, "Stroke"},
336 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
337 };
338 struct CapAndName {
339 SkPaint::Cap fCap;
340 const char* fName;
341 };
342 static const CapAndName gCaps[] = {
343 {SkPaint::kButt_Cap, "Butt"},
344 {SkPaint::kRound_Cap, "Round"},
345 {SkPaint::kSquare_Cap, "Square"},
346 };
347 struct PathAndName {
348 SkPath fPath;
349 const char* fName;
350 };
351 PathAndName path;
352 path.fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
353 path.fPath.moveTo(75*SK_Scalar1, 15*SK_Scalar1);
354 path.fName = "moveTo-moveTo";
355
356 SkPaint titlePaint;
357 titlePaint.setColor(SK_ColorBLACK);
358 titlePaint.setAntiAlias(true);
359 titlePaint.setLCDRenderText(true);
360 titlePaint.setTextSize(15 * SK_Scalar1);
361 const char title[] = "Move Move Drawn Into Rectangle Clips With "
362 "Indicated Style, Fill and Linecaps, with stroke width 10";
363 canvas->drawText(title, strlen(title),
364 20 * SK_Scalar1,
365 20 * SK_Scalar1,
366 titlePaint);
367
368 SkRandom rand;
369 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
370 canvas->save();
371 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
372 canvas->save();
373 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
374 if (0 < cap) {
375 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
376 }
377 canvas->save();
378 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
379 if (0 < fill) {
380 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
381 }
382 canvas->save();
383 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
384 if (0 < style) {
385 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
386 }
387
388 SkColor color = 0xff007000;
389 this->drawPath(path.fPath, canvas, color, rect,
390 gCaps[cap].fCap, gStyles[style].fStyle,
391 gFills[fill].fFill, SK_Scalar1*10);
392
393 SkPaint rectPaint;
394 rectPaint.setColor(SK_ColorBLACK);
395 rectPaint.setStyle(SkPaint::kStroke_Style);
396 rectPaint.setStrokeWidth(-1);
397 rectPaint.setAntiAlias(true);
398 canvas->drawRect(rect, rectPaint);
399
400 SkPaint labelPaint;
401 labelPaint.setColor(color);
402 labelPaint.setAntiAlias(true);
403 labelPaint.setLCDRenderText(true);
404 labelPaint.setTextSize(10 * SK_Scalar1);
405 canvas->drawText(gStyles[style].fName,
406 strlen(gStyles[style].fName),
407 0, rect.height() + 12 * SK_Scalar1,
408 labelPaint);
409 canvas->drawText(gFills[fill].fName,
410 strlen(gFills[fill].fName),
411 0, rect.height() + 24 * SK_Scalar1,
412 labelPaint);
413 canvas->drawText(gCaps[cap].fName,
414 strlen(gCaps[cap].fName),
415 0, rect.height() + 36 * SK_Scalar1,
416 labelPaint);
417 }
418 canvas->restore();
419 }
420 canvas->restore();
421 }
422 canvas->restore();
423 canvas->restore();
424 }
425
426private:
427 typedef GM INHERITED;
428};
429
430class MoveCloseMoveClosePathGM : public GM {
431public:
432 MoveCloseMoveClosePathGM() {}
433
434protected:
435 SkString onShortName() {
436 return SkString("moveclosemoveclosepath");
437 }
438
439 SkISize onISize() { return make_isize(1240, 390); }
440
441 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
442 const SkRect& clip,SkPaint::Cap cap,
443 SkPaint::Style style, SkPath::FillType fill,
444 SkScalar strokeWidth) {
445 path.setFillType(fill);
446 SkPaint paint;
447 paint.setStrokeCap(cap);
448 paint.setStrokeWidth(strokeWidth);
449 paint.setColor(color);
450 paint.setStyle(style);
451 canvas->save();
452 canvas->clipRect(clip);
453 canvas->drawPath(path, paint);
454 canvas->restore();
455 }
456
457 virtual void onDraw(SkCanvas* canvas) {
458 struct FillAndName {
459 SkPath::FillType fFill;
460 const char* fName;
461 };
462 static const FillAndName gFills[] = {
463 {SkPath::kWinding_FillType, "Winding"},
464 {SkPath::kEvenOdd_FillType, "Even / Odd"},
465 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
466 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
467 };
468 struct StyleAndName {
469 SkPaint::Style fStyle;
470 const char* fName;
471 };
472 static const StyleAndName gStyles[] = {
473 {SkPaint::kFill_Style, "Fill"},
474 {SkPaint::kStroke_Style, "Stroke"},
475 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
476 };
477 struct CapAndName {
478 SkPaint::Cap fCap;
479 const char* fName;
480 };
481 static const CapAndName gCaps[] = {
482 {SkPaint::kButt_Cap, "Butt"},
483 {SkPaint::kRound_Cap, "Round"},
484 {SkPaint::kSquare_Cap, "Square"},
485 };
486 struct PathAndName {
487 SkPath fPath;
488 const char* fName;
489 };
490 PathAndName path;
491 path.fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
492 path.fPath.close();
493 path.fPath.moveTo(75*SK_Scalar1, 15*SK_Scalar1);
494 path.fPath.close();
495 path.fName = "moveTo-close-moveTo-close";
496
497 SkPaint titlePaint;
498 titlePaint.setColor(SK_ColorBLACK);
499 titlePaint.setAntiAlias(true);
500 titlePaint.setLCDRenderText(true);
501 titlePaint.setTextSize(15 * SK_Scalar1);
502 const char title[] = "Move-Close-Move-Close Drawn Into Rectangle Clips With "
503 "Indicated Style, Fill and Linecaps, with stroke width 10";
504 canvas->drawText(title, strlen(title),
505 20 * SK_Scalar1,
506 20 * SK_Scalar1,
507 titlePaint);
508
509 SkRandom rand;
510 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
511 canvas->save();
512 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
513 canvas->save();
514 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
515 if (0 < cap) {
516 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
517 }
518 canvas->save();
519 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
520 if (0 < fill) {
521 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
522 }
523 canvas->save();
524 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
525 if (0 < style) {
526 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
527 }
528
529 SkColor color = 0xff007000;
530 this->drawPath(path.fPath, canvas, color, rect,
531 gCaps[cap].fCap, gStyles[style].fStyle,
532 gFills[fill].fFill, SK_Scalar1*10);
533
534 SkPaint rectPaint;
535 rectPaint.setColor(SK_ColorBLACK);
536 rectPaint.setStyle(SkPaint::kStroke_Style);
537 rectPaint.setStrokeWidth(-1);
538 rectPaint.setAntiAlias(true);
539 canvas->drawRect(rect, rectPaint);
540
541 SkPaint labelPaint;
542 labelPaint.setColor(color);
543 labelPaint.setAntiAlias(true);
544 labelPaint.setLCDRenderText(true);
545 labelPaint.setTextSize(10 * SK_Scalar1);
546 canvas->drawText(gStyles[style].fName,
547 strlen(gStyles[style].fName),
548 0, rect.height() + 12 * SK_Scalar1,
549 labelPaint);
550 canvas->drawText(gFills[fill].fName,
551 strlen(gFills[fill].fName),
552 0, rect.height() + 24 * SK_Scalar1,
553 labelPaint);
554 canvas->drawText(gCaps[cap].fName,
555 strlen(gCaps[cap].fName),
556 0, rect.height() + 36 * SK_Scalar1,
557 labelPaint);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000558 }
559 canvas->restore();
560 }
561 canvas->restore();
562 }
563 canvas->restore();
564 canvas->restore();
565 }
566
567private:
568 typedef GM INHERITED;
569};
570
571//////////////////////////////////////////////////////////////////////////////
572
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000573static GM* MPathFactory(void*) { return new MovePathGM; }
574static GMRegistry regMPath(MPathFactory);
575
576static GM* MCPathFactory(void*) { return new MoveClosePathGM; }
577static GMRegistry regMCPath(MCPathFactory);
578
579static GM* MMPathFactory(void*) { return new MoveMovePathGM; }
580static GMRegistry regMMPath(MMPathFactory);
581
582static GM* MCMCPathFactory(void*) { return new MoveCloseMoveClosePathGM; }
583static GMRegistry regMCMCPath(MCMCPathFactory);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000584
585}