blob: 3dd230c21932844e833a664b53856379e3c8ebef [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);
caryclark5fb6bd42014-06-23 11:25:00 -0700127 sk_tool_utils::set_portable_typeface(&titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000128 titlePaint.setLCDRenderText(true);
129 titlePaint.setTextSize(15 * SK_Scalar1);
130 const char title[] = "Cubic Drawn Into Rectangle Clips With "
131 "Indicated Style, Fill and Linecaps, with stroke width 10";
132 canvas->drawText(title, strlen(title),
133 20 * SK_Scalar1,
134 20 * SK_Scalar1,
135 titlePaint);
136
scroggof9d61012014-12-15 12:54:51 -0800137 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000138 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
139 canvas->save();
140 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
141 canvas->save();
142 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
143 if (0 < cap) {
144 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
145 }
146 canvas->save();
147 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
148 if (0 < fill) {
149 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
150 }
151 canvas->save();
152 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
153 if (0 < style) {
154 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
155 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000156
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000157 SkColor color = 0xff007000;
158 this->drawPath(path.fPath, canvas, color, rect,
159 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
160 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000161
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000162 SkPaint rectPaint;
163 rectPaint.setColor(SK_ColorBLACK);
164 rectPaint.setStyle(SkPaint::kStroke_Style);
165 rectPaint.setStrokeWidth(-1);
166 rectPaint.setAntiAlias(true);
167 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000168
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000169 SkPaint labelPaint;
170 labelPaint.setColor(color);
171 labelPaint.setAntiAlias(true);
caryclark5fb6bd42014-06-23 11:25:00 -0700172 sk_tool_utils::set_portable_typeface(&labelPaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000173 labelPaint.setLCDRenderText(true);
174 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);
Cary Clark992c7b02014-07-31 08:58:44 -0400274 sk_tool_utils::set_portable_typeface(&titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000275 titlePaint.setLCDRenderText(true);
276 titlePaint.setTextSize(15 * SK_Scalar1);
277 const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
278 "Indicated Style, Fill and Linecaps, with stroke width 10";
279 canvas->drawText(title, strlen(title),
280 20 * SK_Scalar1,
281 20 * SK_Scalar1,
282 titlePaint);
283
scroggof9d61012014-12-15 12:54:51 -0800284 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000285 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
286 canvas->save();
287 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
288 canvas->save();
289 for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
290 if (0 < cap) {
291 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
292 }
293 canvas->save();
294 for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
295 if (0 < fill) {
296 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
297 }
298 canvas->save();
299 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
300 if (0 < style) {
301 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
302 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000303
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000304 SkColor color = 0xff007000;
305 this->drawPath(path.fPath, canvas, color, rect,
306 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
307 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000308
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000309 SkPaint rectPaint;
310 rectPaint.setColor(SK_ColorBLACK);
311 rectPaint.setStyle(SkPaint::kStroke_Style);
312 rectPaint.setStrokeWidth(-1);
313 rectPaint.setAntiAlias(true);
314 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000315
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000316 SkPaint labelPaint;
317 labelPaint.setColor(color);
318 labelPaint.setAntiAlias(true);
Cary Clark992c7b02014-07-31 08:58:44 -0400319 sk_tool_utils::set_portable_typeface(&labelPaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000320 labelPaint.setLCDRenderText(true);
321 labelPaint.setTextSize(10 * SK_Scalar1);
322 canvas->drawText(gStyles[style].fName,
323 strlen(gStyles[style].fName),
324 0, rect.height() + 12 * SK_Scalar1,
325 labelPaint);
326 canvas->drawText(gFills[fill].fName,
327 strlen(gFills[fill].fName),
328 0, rect.height() + 24 * SK_Scalar1,
329 labelPaint);
330 canvas->drawText(gCaps[cap].fName,
331 strlen(gCaps[cap].fName),
332 0, rect.height() + 36 * SK_Scalar1,
333 labelPaint);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000334 }
335 canvas->restore();
336 }
337 canvas->restore();
338 }
339 canvas->restore();
340 canvas->restore();
341 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000342
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000343private:
reed@google.com27b90fa2013-03-08 18:44:01 +0000344 typedef skiagm::GM INHERITED;
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000345};
346
347//////////////////////////////////////////////////////////////////////////////
348
reed@google.com27b90fa2013-03-08 18:44:01 +0000349DEF_GM( return new CubicPathGM; )
350DEF_GM( return new CubicClosePathGM; )
reed@google.com22999c62013-05-23 19:30:48 +0000351DEF_GM( return new ClippedCubicGM; )