blob: 80e38ca6ab2cf48e3cf68b27ecbb24619991e82e [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
14class CubicPathsGM : public GM {
15public:
16 CubicPathsGM() {}
17
18protected:
19 SkString onShortName() {
20 return SkString("cubicpaths");
21 }
22
23 SkISize onISize() { return make_isize(1800, 1110); }
24
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 };
74 PathAndName gPaths[4];
75 gPaths[0].fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
76 gPaths[0].fPath.cubicTo(50*SK_Scalar1, 15*SK_Scalar1,
77 50*SK_Scalar1, 15*SK_Scalar1,
78 50*SK_Scalar1, 15*SK_Scalar1);
79 gPaths[0].fName = "moveTo-zerocubic";
80 gPaths[1].fPath.moveTo(50*SK_Scalar1, 15*SK_Scalar1);
81 gPaths[1].fPath.cubicTo(50*SK_Scalar1, 15*SK_Scalar1,
82 50*SK_Scalar1, 15*SK_Scalar1,
83 50*SK_Scalar1, 15*SK_Scalar1);
84 gPaths[1].fPath.close();
85 gPaths[1].fName = "moveTo-zerocubic-close";
86 gPaths[2].fPath.moveTo(30*SK_Scalar1, 10*SK_Scalar1);
87 gPaths[2].fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
88 60*SK_Scalar1, 20*SK_Scalar1,
89 70*SK_Scalar1, 10*SK_Scalar1);
90 gPaths[2].fName = "moveTo-cubic";
91 gPaths[3].fPath.moveTo(30*SK_Scalar1, 10*SK_Scalar1);
92 gPaths[3].fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
93 60*SK_Scalar1, 20*SK_Scalar1,
94 70*SK_Scalar1, 10*SK_Scalar1);
95 gPaths[3].fPath.close();
96 gPaths[3].fName = "moveTo-cubic-close";
97
98 SkPaint titlePaint;
99 titlePaint.setColor(SK_ColorBLACK);
100 titlePaint.setAntiAlias(true);
101 titlePaint.setLCDRenderText(true);
102 titlePaint.setTextSize(15 * SK_Scalar1);
103 const char title[] = "Cubic Paths Drawn Into Rectangle Clips With "
104 "Indicated Style, Fill and Linecaps, "
105 "with random stroke widths";
106 canvas->drawText(title, strlen(title),
107 20 * SK_Scalar1,
108 20 * SK_Scalar1,
109 titlePaint);
110
111 SkRandom rand;
112 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
113 canvas->save();
114 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
115 canvas->save();
116 for (size_t path = 0; path < SK_ARRAY_COUNT(gPaths); ++path) {
117 if (0 < path) {
118 canvas->translate(0, (rect.height() + 60 * SK_Scalar1) * 3);
119 }
120 canvas->save();
121 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
122 if (0 < cap) {
123 canvas->translate((rect.width() + 40 * SK_Scalar1) * 4, 0);
124 }
125 canvas->save();
126 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
127 if (0 < style) {
128 canvas->translate(0, rect.height() + 60 * SK_Scalar1);
129 }
130 canvas->save();
131 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
132 if (0 < fill) {
133 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
134 }
135
136 SkColor color = 0xff007000;
137 this->drawPath(gPaths[path].fPath, canvas, color, rect,
138 gCaps[cap].fCap, gStyles[style].fStyle,
139 gFills[fill].fFill, SK_Scalar1*10);
140
141 SkPaint rectPaint;
142 rectPaint.setColor(SK_ColorBLACK);
143 rectPaint.setStyle(SkPaint::kStroke_Style);
144 rectPaint.setStrokeWidth(-1);
145 rectPaint.setAntiAlias(true);
146 canvas->drawRect(rect, rectPaint);
147
148 SkPaint labelPaint;
149 labelPaint.setColor(color);
150 labelPaint.setAntiAlias(true);
151 labelPaint.setLCDRenderText(true);
152 labelPaint.setTextSize(10 * SK_Scalar1);
153 canvas->drawText(gStyles[style].fName,
154 strlen(gStyles[style].fName),
155 0, rect.height() + 12 * SK_Scalar1,
156 labelPaint);
157 canvas->drawText(gFills[fill].fName,
158 strlen(gFills[fill].fName),
159 0, rect.height() + 24 * SK_Scalar1,
160 labelPaint);
161 canvas->drawText(gCaps[cap].fName,
162 strlen(gCaps[cap].fName),
163 0, rect.height() + 36 * SK_Scalar1,
164 labelPaint);
165 canvas->drawText(gPaths[path].fName,
166 strlen(gPaths[path].fName),
167 0, rect.height() + 48 * SK_Scalar1,
168 labelPaint);
169 }
170 canvas->restore();
171 }
172 canvas->restore();
173 }
174 canvas->restore();
175 }
176 canvas->restore();
177 canvas->restore();
178 }
179
180private:
181 typedef GM INHERITED;
182};
183
184//////////////////////////////////////////////////////////////////////////////
185
186static GM* MyFactory(void*) { return new CubicPathsGM; }
187static GMRegistry reg(MyFactory);
188
189}