blob: c8230fc751b259dcbc3265f00fd6b999bbbc6500 [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
reed@google.com22999c62013-05-23 19:30:48 +000012// skbug.com/1316 shows that this cubic, when slightly clipped, creates big
13// (incorrect) changes to its control points.
14class ClippedCubicGM : public skiagm::GM {
15public:
16 ClippedCubicGM() {}
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000017
reed@google.com22999c62013-05-23 19:30:48 +000018protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000019
reed@google.com22999c62013-05-23 19:30:48 +000020 SkString onShortName() {
reed@google.com03ca64b2013-05-23 19:39:15 +000021 return SkString("clippedcubic");
reed@google.com22999c62013-05-23 19:30:48 +000022 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000023
reed@google.com22999c62013-05-23 19:30:48 +000024 SkISize onISize() { return SkISize::Make(1240, 390); }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000025
reed@google.com22999c62013-05-23 19:30:48 +000026 virtual void onDraw(SkCanvas* canvas) {
27 SkPath path;
28 path.moveTo(0, 0);
29 path.cubicTo(140, 150, 40, 10, 170, 150);
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000030
reed@google.com22999c62013-05-23 19:30:48 +000031 SkPaint paint;
32 SkRect bounds = path.getBounds();
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000033
reed@google.com0f8990c2013-05-23 19:47:05 +000034 for (SkScalar dy = -1; dy <= 1; dy += 1) {
reed@google.com22999c62013-05-23 19:30:48 +000035 canvas->save();
reed@google.com0f8990c2013-05-23 19:47:05 +000036 for (SkScalar dx = -1; dx <= 1; dx += 1) {
reed@google.com22999c62013-05-23 19:30:48 +000037 canvas->save();
38 canvas->clipRect(bounds);
39 canvas->translate(dx, dy);
40 canvas->drawPath(path, paint);
41 canvas->restore();
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000042
reed@google.com22999c62013-05-23 19:30:48 +000043 canvas->translate(bounds.width(), 0);
44 }
45 canvas->restore();
46 canvas->translate(0, bounds.height());
47 }
48 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000049
reed@google.com22999c62013-05-23 19:30:48 +000050private:
51 typedef skiagm::GM INHERITED;
52};
53
reed@google.com27b90fa2013-03-08 18:44:01 +000054class CubicPathGM : public skiagm::GM {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000055public:
56 CubicPathGM() {}
57
58protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000059
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000060 SkString onShortName() {
61 return SkString("cubicpath");
62 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000063
reed@google.com27b90fa2013-03-08 18:44:01 +000064 SkISize onISize() { return SkISize::Make(1240, 390); }
rmistry@google.comd6176b02012-08-23 18:14:13 +000065
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000066 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
67 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
68 SkPaint::Style style, SkPath::FillType fill,
69 SkScalar strokeWidth) {
70 path.setFillType(fill);
71 SkPaint paint;
72 paint.setStrokeCap(cap);
73 paint.setStrokeWidth(strokeWidth);
74 paint.setStrokeJoin(join);
75 paint.setColor(color);
76 paint.setStyle(style);
77 canvas->save();
78 canvas->clipRect(clip);
79 canvas->drawPath(path, paint);
80 canvas->restore();
81 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000082
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000083 virtual void onDraw(SkCanvas* canvas) {
84 struct FillAndName {
85 SkPath::FillType fFill;
86 const char* fName;
87 };
88 static const FillAndName gFills[] = {
89 {SkPath::kWinding_FillType, "Winding"},
90 {SkPath::kEvenOdd_FillType, "Even / Odd"},
91 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
92 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
93 };
94 struct StyleAndName {
95 SkPaint::Style fStyle;
96 const char* fName;
97 };
98 static const StyleAndName gStyles[] = {
99 {SkPaint::kFill_Style, "Fill"},
100 {SkPaint::kStroke_Style, "Stroke"},
101 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
102 };
103 struct CapAndName {
104 SkPaint::Cap fCap;
105 SkPaint::Join fJoin;
106 const char* fName;
107 };
108 static const CapAndName gCaps[] = {
109 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
110 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
111 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
112 };
113 struct PathAndName {
114 SkPath fPath;
115 const char* fName;
116 };
117 PathAndName path;
118 path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
119 path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
120 60*SK_Scalar1, 20*SK_Scalar1,
121 75*SK_Scalar1, 10*SK_Scalar1);
122 path.fName = "moveTo-cubic";
123
124 SkPaint titlePaint;
125 titlePaint.setColor(SK_ColorBLACK);
126 titlePaint.setAntiAlias(true);
caryclark57856a12015-06-12 08:54:38 -0700127 sk_tool_utils::set_portable_typeface_always(&titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000128 titlePaint.setTextSize(15 * SK_Scalar1);
129 const char title[] = "Cubic Drawn Into Rectangle Clips With "
130 "Indicated Style, Fill and Linecaps, with stroke width 10";
131 canvas->drawText(title, strlen(title),
132 20 * SK_Scalar1,
133 20 * SK_Scalar1,
134 titlePaint);
135
scroggof9d61012014-12-15 12:54:51 -0800136 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000137 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
138 canvas->save();
139 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
140 canvas->save();
141 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
142 if (0 < cap) {
143 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
144 }
145 canvas->save();
146 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
147 if (0 < fill) {
148 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
149 }
150 canvas->save();
151 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
152 if (0 < style) {
153 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
154 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000155
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000156 SkColor color = 0xff007000;
157 this->drawPath(path.fPath, canvas, color, rect,
158 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
159 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000160
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000161 SkPaint rectPaint;
162 rectPaint.setColor(SK_ColorBLACK);
163 rectPaint.setStyle(SkPaint::kStroke_Style);
164 rectPaint.setStrokeWidth(-1);
165 rectPaint.setAntiAlias(true);
166 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000167
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000168 SkPaint labelPaint;
169 labelPaint.setColor(color);
170 labelPaint.setAntiAlias(true);
caryclark57856a12015-06-12 08:54:38 -0700171 sk_tool_utils::set_portable_typeface_always(&labelPaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000172 labelPaint.setTextSize(10 * SK_Scalar1);
173 canvas->drawText(gStyles[style].fName,
174 strlen(gStyles[style].fName),
175 0, rect.height() + 12 * SK_Scalar1,
176 labelPaint);
177 canvas->drawText(gFills[fill].fName,
178 strlen(gFills[fill].fName),
179 0, rect.height() + 24 * SK_Scalar1,
180 labelPaint);
181 canvas->drawText(gCaps[cap].fName,
182 strlen(gCaps[cap].fName),
183 0, rect.height() + 36 * SK_Scalar1,
184 labelPaint);
185 }
186 canvas->restore();
187 }
188 canvas->restore();
189 }
190 canvas->restore();
191 canvas->restore();
192 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000193
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000194private:
reed@google.com27b90fa2013-03-08 18:44:01 +0000195 typedef skiagm::GM INHERITED;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000196};
197
reed@google.com27b90fa2013-03-08 18:44:01 +0000198class CubicClosePathGM : public skiagm::GM {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000199public:
200 CubicClosePathGM() {}
201
202protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000203
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000204 SkString onShortName() {
205 return SkString("cubicclosepath");
206 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000207
reed@google.com27b90fa2013-03-08 18:44:01 +0000208 SkISize onISize() { return SkISize::Make(1240, 390); }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000209
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000210 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
211 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
212 SkPaint::Style style, SkPath::FillType fill,
213 SkScalar strokeWidth) {
214 path.setFillType(fill);
215 SkPaint paint;
216 paint.setStrokeCap(cap);
217 paint.setStrokeWidth(strokeWidth);
218 paint.setStrokeJoin(join);
219 paint.setColor(color);
220 paint.setStyle(style);
221 canvas->save();
222 canvas->clipRect(clip);
223 canvas->drawPath(path, paint);
224 canvas->restore();
225 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000226
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000227 virtual void onDraw(SkCanvas* canvas) {
228 struct FillAndName {
229 SkPath::FillType fFill;
230 const char* fName;
231 };
232 static const FillAndName gFills[] = {
233 {SkPath::kWinding_FillType, "Winding"},
234 {SkPath::kEvenOdd_FillType, "Even / Odd"},
235 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
236 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
237 };
238 struct StyleAndName {
239 SkPaint::Style fStyle;
240 const char* fName;
241 };
242 static const StyleAndName gStyles[] = {
243 {SkPaint::kFill_Style, "Fill"},
244 {SkPaint::kStroke_Style, "Stroke"},
245 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
246 };
247 struct CapAndName {
248 SkPaint::Cap fCap;
249 SkPaint::Join fJoin;
250 const char* fName;
251 };
252 static const CapAndName gCaps[] = {
253 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
254 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
255 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
256 };
257 struct PathAndName {
258 SkPath fPath;
259 const char* fName;
260 };
261 PathAndName path;
262 path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
263 path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
264 60*SK_Scalar1, 20*SK_Scalar1,
265 75*SK_Scalar1, 10*SK_Scalar1);
266 path.fPath.close();
267 path.fName = "moveTo-cubic-close";
268
269 SkPaint titlePaint;
270 titlePaint.setColor(SK_ColorBLACK);
271 titlePaint.setAntiAlias(true);
caryclark57856a12015-06-12 08:54:38 -0700272 sk_tool_utils::set_portable_typeface_always(&titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000273 titlePaint.setTextSize(15 * SK_Scalar1);
274 const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
275 "Indicated Style, Fill and Linecaps, with stroke width 10";
276 canvas->drawText(title, strlen(title),
277 20 * SK_Scalar1,
278 20 * SK_Scalar1,
279 titlePaint);
280
scroggof9d61012014-12-15 12:54:51 -0800281 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000282 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
283 canvas->save();
284 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
285 canvas->save();
286 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
287 if (0 < cap) {
288 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
289 }
290 canvas->save();
291 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
292 if (0 < fill) {
293 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
294 }
295 canvas->save();
296 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
297 if (0 < style) {
298 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
299 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000300
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000301 SkColor color = 0xff007000;
302 this->drawPath(path.fPath, canvas, color, rect,
303 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
304 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000305
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000306 SkPaint rectPaint;
307 rectPaint.setColor(SK_ColorBLACK);
308 rectPaint.setStyle(SkPaint::kStroke_Style);
309 rectPaint.setStrokeWidth(-1);
310 rectPaint.setAntiAlias(true);
311 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000312
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000313 SkPaint labelPaint;
314 labelPaint.setColor(color);
315 labelPaint.setAntiAlias(true);
caryclark57856a12015-06-12 08:54:38 -0700316 sk_tool_utils::set_portable_typeface_always(&labelPaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000317 labelPaint.setTextSize(10 * SK_Scalar1);
318 canvas->drawText(gStyles[style].fName,
319 strlen(gStyles[style].fName),
320 0, rect.height() + 12 * SK_Scalar1,
321 labelPaint);
322 canvas->drawText(gFills[fill].fName,
323 strlen(gFills[fill].fName),
324 0, rect.height() + 24 * SK_Scalar1,
325 labelPaint);
326 canvas->drawText(gCaps[cap].fName,
327 strlen(gCaps[cap].fName),
328 0, rect.height() + 36 * SK_Scalar1,
329 labelPaint);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000330 }
331 canvas->restore();
332 }
333 canvas->restore();
334 }
335 canvas->restore();
336 canvas->restore();
337 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000338
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000339private:
reed@google.com27b90fa2013-03-08 18:44:01 +0000340 typedef skiagm::GM INHERITED;
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000341};
342
343//////////////////////////////////////////////////////////////////////////////
344
reed@google.com27b90fa2013-03-08 18:44:01 +0000345DEF_GM( return new CubicPathGM; )
346DEF_GM( return new CubicClosePathGM; )
reed@google.com22999c62013-05-23 19:30:48 +0000347DEF_GM( return new ClippedCubicGM; )