blob: 74fbe8d58b376b56b144d6d3beaedb49aaa26563 [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 */
bungemand3ebb482015-08-05 13:57:49 -07007
schenney@chromium.org4da06ab2011-12-20 15:14:18 +00008#include "gm.h"
9#include "SkCanvas.h"
10#include "SkPaint.h"
bungemand3ebb482015-08-05 13:57:49 -070011#include "SkPath.h"
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000012#include "SkRandom.h"
13
reed@google.com22999c62013-05-23 19:30:48 +000014// skbug.com/1316 shows that this cubic, when slightly clipped, creates big
15// (incorrect) changes to its control points.
16class ClippedCubicGM : public skiagm::GM {
17public:
18 ClippedCubicGM() {}
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000019
reed@google.com22999c62013-05-23 19:30:48 +000020protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000021
reed@google.com22999c62013-05-23 19:30:48 +000022 SkString onShortName() {
reed@google.com03ca64b2013-05-23 19:39:15 +000023 return SkString("clippedcubic");
reed@google.com22999c62013-05-23 19:30:48 +000024 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000025
reed@google.com22999c62013-05-23 19:30:48 +000026 SkISize onISize() { return SkISize::Make(1240, 390); }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000027
reed@google.com22999c62013-05-23 19:30:48 +000028 virtual void onDraw(SkCanvas* canvas) {
29 SkPath path;
30 path.moveTo(0, 0);
31 path.cubicTo(140, 150, 40, 10, 170, 150);
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000032
reed@google.com22999c62013-05-23 19:30:48 +000033 SkPaint paint;
34 SkRect bounds = path.getBounds();
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000035
reed@google.com0f8990c2013-05-23 19:47:05 +000036 for (SkScalar dy = -1; dy <= 1; dy += 1) {
reed@google.com22999c62013-05-23 19:30:48 +000037 canvas->save();
reed@google.com0f8990c2013-05-23 19:47:05 +000038 for (SkScalar dx = -1; dx <= 1; dx += 1) {
reed@google.com22999c62013-05-23 19:30:48 +000039 canvas->save();
40 canvas->clipRect(bounds);
41 canvas->translate(dx, dy);
42 canvas->drawPath(path, paint);
43 canvas->restore();
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000044
reed@google.com22999c62013-05-23 19:30:48 +000045 canvas->translate(bounds.width(), 0);
46 }
47 canvas->restore();
48 canvas->translate(0, bounds.height());
49 }
50 }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000051
reed@google.com22999c62013-05-23 19:30:48 +000052private:
53 typedef skiagm::GM INHERITED;
54};
55
reed@google.com27b90fa2013-03-08 18:44:01 +000056class CubicPathGM : public skiagm::GM {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000057public:
58 CubicPathGM() {}
59
60protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000061
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000062 SkString onShortName() {
63 return SkString("cubicpath");
64 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000065
reed@google.com27b90fa2013-03-08 18:44:01 +000066 SkISize onISize() { return SkISize::Make(1240, 390); }
rmistry@google.comd6176b02012-08-23 18:14:13 +000067
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000068 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
69 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
70 SkPaint::Style style, SkPath::FillType fill,
71 SkScalar strokeWidth) {
72 path.setFillType(fill);
73 SkPaint paint;
74 paint.setStrokeCap(cap);
75 paint.setStrokeWidth(strokeWidth);
76 paint.setStrokeJoin(join);
77 paint.setColor(color);
78 paint.setStyle(style);
79 canvas->save();
80 canvas->clipRect(clip);
81 canvas->drawPath(path, paint);
82 canvas->restore();
83 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000084
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +000085 virtual void onDraw(SkCanvas* canvas) {
86 struct FillAndName {
87 SkPath::FillType fFill;
88 const char* fName;
89 };
90 static const FillAndName gFills[] = {
91 {SkPath::kWinding_FillType, "Winding"},
92 {SkPath::kEvenOdd_FillType, "Even / Odd"},
93 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
94 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
95 };
96 struct StyleAndName {
97 SkPaint::Style fStyle;
98 const char* fName;
99 };
100 static const StyleAndName gStyles[] = {
101 {SkPaint::kFill_Style, "Fill"},
102 {SkPaint::kStroke_Style, "Stroke"},
103 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
104 };
105 struct CapAndName {
106 SkPaint::Cap fCap;
107 SkPaint::Join fJoin;
108 const char* fName;
109 };
110 static const CapAndName gCaps[] = {
111 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
112 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
113 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
114 };
115 struct PathAndName {
116 SkPath fPath;
117 const char* fName;
118 };
119 PathAndName path;
120 path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
121 path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
122 60*SK_Scalar1, 20*SK_Scalar1,
123 75*SK_Scalar1, 10*SK_Scalar1);
124 path.fName = "moveTo-cubic";
125
126 SkPaint titlePaint;
127 titlePaint.setColor(SK_ColorBLACK);
128 titlePaint.setAntiAlias(true);
caryclark1818acb2015-07-24 12:09:25 -0700129 sk_tool_utils::set_portable_typeface(&titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000130 titlePaint.setTextSize(15 * SK_Scalar1);
131 const char title[] = "Cubic Drawn Into Rectangle Clips With "
132 "Indicated Style, Fill and Linecaps, with stroke width 10";
133 canvas->drawText(title, strlen(title),
134 20 * SK_Scalar1,
135 20 * SK_Scalar1,
136 titlePaint);
137
scroggof9d61012014-12-15 12:54:51 -0800138 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000139 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
140 canvas->save();
141 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
142 canvas->save();
143 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
144 if (0 < cap) {
145 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
146 }
147 canvas->save();
148 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
149 if (0 < fill) {
150 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
151 }
152 canvas->save();
153 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
154 if (0 < style) {
155 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
156 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000157
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000158 SkColor color = 0xff007000;
159 this->drawPath(path.fPath, canvas, color, rect,
160 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
161 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000162
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000163 SkPaint rectPaint;
164 rectPaint.setColor(SK_ColorBLACK);
165 rectPaint.setStyle(SkPaint::kStroke_Style);
166 rectPaint.setStrokeWidth(-1);
167 rectPaint.setAntiAlias(true);
168 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000169
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000170 SkPaint labelPaint;
171 labelPaint.setColor(color);
172 labelPaint.setAntiAlias(true);
caryclark1818acb2015-07-24 12:09:25 -0700173 sk_tool_utils::set_portable_typeface(&labelPaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000174 labelPaint.setTextSize(10 * SK_Scalar1);
175 canvas->drawText(gStyles[style].fName,
176 strlen(gStyles[style].fName),
177 0, rect.height() + 12 * SK_Scalar1,
178 labelPaint);
179 canvas->drawText(gFills[fill].fName,
180 strlen(gFills[fill].fName),
181 0, rect.height() + 24 * SK_Scalar1,
182 labelPaint);
183 canvas->drawText(gCaps[cap].fName,
184 strlen(gCaps[cap].fName),
185 0, rect.height() + 36 * SK_Scalar1,
186 labelPaint);
187 }
188 canvas->restore();
189 }
190 canvas->restore();
191 }
192 canvas->restore();
193 canvas->restore();
194 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000195
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000196private:
reed@google.com27b90fa2013-03-08 18:44:01 +0000197 typedef skiagm::GM INHERITED;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000198};
199
reed@google.com27b90fa2013-03-08 18:44:01 +0000200class CubicClosePathGM : public skiagm::GM {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000201public:
202 CubicClosePathGM() {}
203
204protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000205
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000206 SkString onShortName() {
207 return SkString("cubicclosepath");
208 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000209
reed@google.com27b90fa2013-03-08 18:44:01 +0000210 SkISize onISize() { return SkISize::Make(1240, 390); }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000211
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000212 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
213 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
214 SkPaint::Style style, SkPath::FillType fill,
215 SkScalar strokeWidth) {
216 path.setFillType(fill);
217 SkPaint paint;
218 paint.setStrokeCap(cap);
219 paint.setStrokeWidth(strokeWidth);
220 paint.setStrokeJoin(join);
221 paint.setColor(color);
222 paint.setStyle(style);
223 canvas->save();
224 canvas->clipRect(clip);
225 canvas->drawPath(path, paint);
226 canvas->restore();
227 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000228
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000229 virtual void onDraw(SkCanvas* canvas) {
230 struct FillAndName {
231 SkPath::FillType fFill;
232 const char* fName;
233 };
234 static const FillAndName gFills[] = {
235 {SkPath::kWinding_FillType, "Winding"},
236 {SkPath::kEvenOdd_FillType, "Even / Odd"},
237 {SkPath::kInverseWinding_FillType, "Inverse Winding"},
238 {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
239 };
240 struct StyleAndName {
241 SkPaint::Style fStyle;
242 const char* fName;
243 };
244 static const StyleAndName gStyles[] = {
245 {SkPaint::kFill_Style, "Fill"},
246 {SkPaint::kStroke_Style, "Stroke"},
247 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
248 };
249 struct CapAndName {
250 SkPaint::Cap fCap;
251 SkPaint::Join fJoin;
252 const char* fName;
253 };
254 static const CapAndName gCaps[] = {
255 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
256 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
257 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
258 };
259 struct PathAndName {
260 SkPath fPath;
261 const char* fName;
262 };
263 PathAndName path;
264 path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
265 path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
266 60*SK_Scalar1, 20*SK_Scalar1,
267 75*SK_Scalar1, 10*SK_Scalar1);
268 path.fPath.close();
269 path.fName = "moveTo-cubic-close";
270
271 SkPaint titlePaint;
272 titlePaint.setColor(SK_ColorBLACK);
273 titlePaint.setAntiAlias(true);
caryclark1818acb2015-07-24 12:09:25 -0700274 sk_tool_utils::set_portable_typeface(&titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000275 titlePaint.setTextSize(15 * SK_Scalar1);
276 const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
277 "Indicated Style, Fill and Linecaps, with stroke width 10";
278 canvas->drawText(title, strlen(title),
279 20 * SK_Scalar1,
280 20 * SK_Scalar1,
281 titlePaint);
282
scroggof9d61012014-12-15 12:54:51 -0800283 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000284 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
285 canvas->save();
286 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
287 canvas->save();
288 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
289 if (0 < cap) {
290 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
291 }
292 canvas->save();
293 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
294 if (0 < fill) {
295 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
296 }
297 canvas->save();
298 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
299 if (0 < style) {
300 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
301 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000302
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000303 SkColor color = 0xff007000;
304 this->drawPath(path.fPath, canvas, color, rect,
305 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
306 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000307
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000308 SkPaint rectPaint;
309 rectPaint.setColor(SK_ColorBLACK);
310 rectPaint.setStyle(SkPaint::kStroke_Style);
311 rectPaint.setStrokeWidth(-1);
312 rectPaint.setAntiAlias(true);
313 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000314
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000315 SkPaint labelPaint;
316 labelPaint.setColor(color);
317 labelPaint.setAntiAlias(true);
caryclark1818acb2015-07-24 12:09:25 -0700318 sk_tool_utils::set_portable_typeface(&labelPaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000319 labelPaint.setTextSize(10 * SK_Scalar1);
320 canvas->drawText(gStyles[style].fName,
321 strlen(gStyles[style].fName),
322 0, rect.height() + 12 * SK_Scalar1,
323 labelPaint);
324 canvas->drawText(gFills[fill].fName,
325 strlen(gFills[fill].fName),
326 0, rect.height() + 24 * SK_Scalar1,
327 labelPaint);
328 canvas->drawText(gCaps[cap].fName,
329 strlen(gCaps[cap].fName),
330 0, rect.height() + 36 * SK_Scalar1,
331 labelPaint);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000332 }
333 canvas->restore();
334 }
335 canvas->restore();
336 }
337 canvas->restore();
338 canvas->restore();
339 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000340
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000341private:
reed@google.com27b90fa2013-03-08 18:44:01 +0000342 typedef skiagm::GM INHERITED;
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000343};
344
345//////////////////////////////////////////////////////////////////////////////
346
reed@google.com27b90fa2013-03-08 18:44:01 +0000347DEF_GM( return new CubicPathGM; )
348DEF_GM( return new CubicClosePathGM; )
reed@google.com22999c62013-05-23 19:30:48 +0000349DEF_GM( return new ClippedCubicGM; )