blob: ef8d5e6016f0f847172d3590cc31c37dc8fde31d [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkCanvas.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040010#include "include/core/SkColor.h"
11#include "include/core/SkFont.h"
12#include "include/core/SkMatrix.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkPaint.h"
14#include "include/core/SkPath.h"
Ben Wagner7fde8e12019-05-01 17:28:53 -040015#include "include/core/SkPoint.h"
16#include "include/core/SkRect.h"
17#include "include/core/SkScalar.h"
18#include "include/core/SkSize.h"
19#include "include/core/SkString.h"
20#include "include/core/SkTypeface.h"
21#include "include/core/SkTypes.h"
Arman Uguray92fd1a72023-06-16 15:19:23 -070022#include "include/effects/SkGradientShader.h"
Kevin Lubick0d4d1142023-02-13 09:13:10 -050023#include "src/base/SkRandom.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#include "tools/ToolUtils.h"
Kevin Lubicke836c3a2023-10-20 06:55:35 -040025#include "tools/fonts/FontToolUtils.h"
schenney@chromium.org4da06ab2011-12-20 15:14:18 +000026
halcanary6950de62015-11-07 05:29:00 -080027// https://bug.skia.org/1316 shows that this cubic, when slightly clipped, creates big
reed@google.com22999c62013-05-23 19:30:48 +000028// (incorrect) changes to its control points.
29class ClippedCubicGM : public skiagm::GM {
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000030 SkString getName() const override { return SkString("clippedcubic"); }
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000031
Leandro Lovisolo8f023882023-08-15 21:13:52 +000032 SkISize getISize() override { return {1240, 390}; }
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +000033
John Stiles1cf2c8d2020-08-13 22:58:04 -040034 void onDraw(SkCanvas* canvas) override {
reed@google.com22999c62013-05-23 19:30:48 +000035 SkPath path;
36 path.moveTo(0, 0);
37 path.cubicTo(140, 150, 40, 10, 170, 150);
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000038
reed@google.com22999c62013-05-23 19:30:48 +000039 SkPaint paint;
40 SkRect bounds = path.getBounds();
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000041
reed@google.com0f8990c2013-05-23 19:47:05 +000042 for (SkScalar dy = -1; dy <= 1; dy += 1) {
reed@google.com22999c62013-05-23 19:30:48 +000043 canvas->save();
reed@google.com0f8990c2013-05-23 19:47:05 +000044 for (SkScalar dx = -1; dx <= 1; dx += 1) {
reed@google.com22999c62013-05-23 19:30:48 +000045 canvas->save();
46 canvas->clipRect(bounds);
47 canvas->translate(dx, dy);
48 canvas->drawPath(path, paint);
49 canvas->restore();
skia.committer@gmail.com3e2345a2013-05-24 07:01:26 +000050
reed@google.com22999c62013-05-23 19:30:48 +000051 canvas->translate(bounds.width(), 0);
52 }
53 canvas->restore();
54 canvas->translate(0, bounds.height());
55 }
56 }
reed@google.com22999c62013-05-23 19:30:48 +000057};
58
caryclark7d173402015-08-20 08:23:52 -070059
60class ClippedCubic2GM : public skiagm::GM {
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000061 SkString getName() const override { return SkString("clippedcubic2"); }
caryclark7d173402015-08-20 08:23:52 -070062
Leandro Lovisolo8f023882023-08-15 21:13:52 +000063 SkISize getISize() override { return {1240, 390}; }
caryclark7d173402015-08-20 08:23:52 -070064
65 void onDraw(SkCanvas* canvas) override {
66 canvas->save();
caryclark05424f72015-08-20 10:35:43 -070067 canvas->translate(-2, 120);
caryclark7d173402015-08-20 08:23:52 -070068 drawOne(canvas, fPath, SkRect::MakeLTRB(0, 0, 80, 150));
69 canvas->translate(0, 170);
70 drawOne(canvas, fPath, SkRect::MakeLTRB(0, 0, 80, 100));
71 canvas->translate(0, 170);
72 drawOne(canvas, fPath, SkRect::MakeLTRB(0, 0, 30, 150));
73 canvas->translate(0, 170);
74 drawOne(canvas, fPath, SkRect::MakeLTRB(0, 0, 10, 150));
75 canvas->restore();
caryclark05424f72015-08-20 10:35:43 -070076 canvas->save();
77 canvas->translate(20, -2);
78 drawOne(canvas, fFlipped, SkRect::MakeLTRB(0, 0, 150, 80));
79 canvas->translate(170, 0);
80 drawOne(canvas, fFlipped, SkRect::MakeLTRB(0, 0, 100, 80));
81 canvas->translate(170, 0);
82 drawOne(canvas, fFlipped, SkRect::MakeLTRB(0, 0, 150, 30));
83 canvas->translate(170, 0);
84 drawOne(canvas, fFlipped, SkRect::MakeLTRB(0, 0, 150, 10));
85 canvas->restore();
caryclark7d173402015-08-20 08:23:52 -070086 }
87
88 void drawOne(SkCanvas* canvas, const SkPath& path, const SkRect& clip) {
89 SkPaint framePaint, fillPaint;
90 framePaint.setStyle(SkPaint::kStroke_Style);
91 canvas->drawRect(clip, framePaint);
92 canvas->drawPath(path, framePaint);
93 canvas->save();
94 canvas->clipRect(clip);
95 canvas->drawPath(path, fillPaint);
96 canvas->restore();
97 }
98
99 void onOnceBeforeDraw() override {
100 fPath.moveTo(69.7030518991886f, 0);
101 fPath.cubicTo( 69.7030518991886f, 21.831149999999997f,
102 58.08369508178456f, 43.66448333333333f, 34.8449814469765f, 65.5f);
103 fPath.cubicTo( 11.608591683531916f, 87.33115f, -0.010765133872116195f, 109.16448333333332f,
104 -0.013089005235602302f, 131);
105 fPath.close();
caryclark05424f72015-08-20 10:35:43 -0700106 fFlipped = fPath;
107 SkMatrix matrix;
108 matrix.reset();
109 matrix.setScaleX(0);
110 matrix.setScaleY(0);
111 matrix.setSkewX(1);
112 matrix.setSkewY(1);
113 fFlipped.transform(matrix);
caryclark7d173402015-08-20 08:23:52 -0700114 }
115
116 SkPath fPath;
caryclark05424f72015-08-20 10:35:43 -0700117 SkPath fFlipped;
caryclark7d173402015-08-20 08:23:52 -0700118private:
John Stiles7571f9e2020-09-02 22:42:33 -0400119 using INHERITED = skiagm::GM;
caryclark7d173402015-08-20 08:23:52 -0700120};
121
reed@google.com27b90fa2013-03-08 18:44:01 +0000122class CubicPathGM : public skiagm::GM {
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000123 SkString getName() const override { return SkString("cubicpath"); }
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000124
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000125 SkISize getISize() override { return {1240, 390}; }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000126
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000127 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
128 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
Mike Reed7d34dc72019-11-26 12:17:17 -0500129 SkPaint::Style style, SkPathFillType fill,
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000130 SkScalar strokeWidth) {
131 path.setFillType(fill);
132 SkPaint paint;
133 paint.setStrokeCap(cap);
134 paint.setStrokeWidth(strokeWidth);
135 paint.setStrokeJoin(join);
136 paint.setColor(color);
137 paint.setStyle(style);
138 canvas->save();
139 canvas->clipRect(clip);
140 canvas->drawPath(path, paint);
141 canvas->restore();
142 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000143
Hal Canaryfa3305a2019-07-18 12:36:54 -0400144 void onDraw(SkCanvas* canvas) override {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000145 struct FillAndName {
Mike Reed7d34dc72019-11-26 12:17:17 -0500146 SkPathFillType fFill;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000147 const char* fName;
148 };
mtkleindbfd7ab2016-09-01 11:24:54 -0700149 constexpr FillAndName gFills[] = {
Mike Reed7d34dc72019-11-26 12:17:17 -0500150 {SkPathFillType::kWinding, "Winding"},
151 {SkPathFillType::kEvenOdd, "Even / Odd"},
152 {SkPathFillType::kInverseWinding, "Inverse Winding"},
153 {SkPathFillType::kInverseEvenOdd, "Inverse Even / Odd"},
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000154 };
155 struct StyleAndName {
156 SkPaint::Style fStyle;
157 const char* fName;
158 };
mtkleindbfd7ab2016-09-01 11:24:54 -0700159 constexpr StyleAndName gStyles[] = {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000160 {SkPaint::kFill_Style, "Fill"},
161 {SkPaint::kStroke_Style, "Stroke"},
162 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
163 };
164 struct CapAndName {
165 SkPaint::Cap fCap;
166 SkPaint::Join fJoin;
167 const char* fName;
168 };
mtkleindbfd7ab2016-09-01 11:24:54 -0700169 constexpr CapAndName gCaps[] = {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000170 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
171 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
172 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
173 };
174 struct PathAndName {
175 SkPath fPath;
176 const char* fName;
177 };
178 PathAndName path;
179 path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
180 path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
181 60*SK_Scalar1, 20*SK_Scalar1,
182 75*SK_Scalar1, 10*SK_Scalar1);
183 path.fName = "moveTo-cubic";
184
185 SkPaint titlePaint;
186 titlePaint.setColor(SK_ColorBLACK);
187 titlePaint.setAntiAlias(true);
Kevin Lubicke836c3a2023-10-20 06:55:35 -0400188 SkFont font(ToolUtils::DefaultPortableTypeface(), 15);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000189 const char title[] = "Cubic Drawn Into Rectangle Clips With "
190 "Indicated Style, Fill and Linecaps, with stroke width 10";
Mike Reed1af9b482019-01-07 11:01:57 -0500191 canvas->drawString(title, 20, 20, font, titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000192
scroggof9d61012014-12-15 12:54:51 -0800193 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000194 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
195 canvas->save();
196 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
197 canvas->save();
Herb Derbyc37b3862022-06-21 09:49:17 -0400198 for (size_t cap = 0; cap < std::size(gCaps); ++cap) {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000199 if (0 < cap) {
Herb Derbyc37b3862022-06-21 09:49:17 -0400200 canvas->translate((rect.width() + 40 * SK_Scalar1) * std::size(gStyles), 0);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000201 }
202 canvas->save();
Herb Derbyc37b3862022-06-21 09:49:17 -0400203 for (size_t fill = 0; fill < std::size(gFills); ++fill) {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000204 if (0 < fill) {
205 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
206 }
207 canvas->save();
Herb Derbyc37b3862022-06-21 09:49:17 -0400208 for (size_t style = 0; style < std::size(gStyles); ++style) {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000209 if (0 < style) {
210 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
211 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000212
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000213 SkColor color = 0xff007000;
214 this->drawPath(path.fPath, canvas, color, rect,
215 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
216 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000217
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000218 SkPaint rectPaint;
219 rectPaint.setColor(SK_ColorBLACK);
220 rectPaint.setStyle(SkPaint::kStroke_Style);
221 rectPaint.setStrokeWidth(-1);
222 rectPaint.setAntiAlias(true);
223 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000224
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000225 SkPaint labelPaint;
226 labelPaint.setColor(color);
Mike Reed1af9b482019-01-07 11:01:57 -0500227 font.setSize(10);
228 canvas->drawString(gStyles[style].fName, 0, rect.height() + 12, font, labelPaint);
229 canvas->drawString(gFills[fill].fName, 0, rect.height() + 24, font, labelPaint);
230 canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36, font, labelPaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000231 }
232 canvas->restore();
233 }
234 canvas->restore();
235 }
236 canvas->restore();
237 canvas->restore();
238 }
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000239};
240
reed@google.com27b90fa2013-03-08 18:44:01 +0000241class CubicClosePathGM : public skiagm::GM {
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000242 SkString getName() const override { return SkString("cubicclosepath"); }
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000243
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000244 SkISize getISize() override { return {1240, 390}; }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000245
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000246 void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
247 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
Mike Reed7d34dc72019-11-26 12:17:17 -0500248 SkPaint::Style style, SkPathFillType fill,
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000249 SkScalar strokeWidth) {
250 path.setFillType(fill);
251 SkPaint paint;
252 paint.setStrokeCap(cap);
253 paint.setStrokeWidth(strokeWidth);
254 paint.setStrokeJoin(join);
255 paint.setColor(color);
256 paint.setStyle(style);
257 canvas->save();
258 canvas->clipRect(clip);
259 canvas->drawPath(path, paint);
260 canvas->restore();
261 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000262
John Stiles1cf2c8d2020-08-13 22:58:04 -0400263 void onDraw(SkCanvas* canvas) override {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000264 struct FillAndName {
Mike Reed7d34dc72019-11-26 12:17:17 -0500265 SkPathFillType fFill;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000266 const char* fName;
267 };
mtkleindbfd7ab2016-09-01 11:24:54 -0700268 constexpr FillAndName gFills[] = {
Mike Reed7d34dc72019-11-26 12:17:17 -0500269 {SkPathFillType::kWinding, "Winding"},
270 {SkPathFillType::kEvenOdd, "Even / Odd"},
271 {SkPathFillType::kInverseWinding, "Inverse Winding"},
272 {SkPathFillType::kInverseEvenOdd, "Inverse Even / Odd"},
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000273 };
274 struct StyleAndName {
275 SkPaint::Style fStyle;
276 const char* fName;
277 };
mtkleindbfd7ab2016-09-01 11:24:54 -0700278 constexpr StyleAndName gStyles[] = {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000279 {SkPaint::kFill_Style, "Fill"},
280 {SkPaint::kStroke_Style, "Stroke"},
281 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
282 };
283 struct CapAndName {
284 SkPaint::Cap fCap;
285 SkPaint::Join fJoin;
286 const char* fName;
287 };
mtkleindbfd7ab2016-09-01 11:24:54 -0700288 constexpr CapAndName gCaps[] = {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000289 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
290 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
291 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
292 };
293 struct PathAndName {
294 SkPath fPath;
295 const char* fName;
296 };
297 PathAndName path;
298 path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
299 path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
300 60*SK_Scalar1, 20*SK_Scalar1,
301 75*SK_Scalar1, 10*SK_Scalar1);
302 path.fPath.close();
303 path.fName = "moveTo-cubic-close";
304
305 SkPaint titlePaint;
306 titlePaint.setColor(SK_ColorBLACK);
307 titlePaint.setAntiAlias(true);
Kevin Lubicke836c3a2023-10-20 06:55:35 -0400308 SkFont font(ToolUtils::DefaultPortableTypeface(), 15);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000309 const char title[] = "Cubic Closed Drawn Into Rectangle Clips With "
310 "Indicated Style, Fill and Linecaps, with stroke width 10";
Mike Reed1af9b482019-01-07 11:01:57 -0500311 canvas->drawString(title, 20, 20, font, titlePaint);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000312
scroggof9d61012014-12-15 12:54:51 -0800313 SkRandom rand;
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000314 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
315 canvas->save();
316 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
317 canvas->save();
Herb Derbyc37b3862022-06-21 09:49:17 -0400318 for (size_t cap = 0; cap < std::size(gCaps); ++cap) {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000319 if (0 < cap) {
Herb Derbyc37b3862022-06-21 09:49:17 -0400320 canvas->translate((rect.width() + 40 * SK_Scalar1) * std::size(gStyles), 0);
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000321 }
322 canvas->save();
Herb Derbyc37b3862022-06-21 09:49:17 -0400323 for (size_t fill = 0; fill < std::size(gFills); ++fill) {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000324 if (0 < fill) {
325 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
326 }
327 canvas->save();
Herb Derbyc37b3862022-06-21 09:49:17 -0400328 for (size_t style = 0; style < std::size(gStyles); ++style) {
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000329 if (0 < style) {
330 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
331 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000332
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000333 SkColor color = 0xff007000;
334 this->drawPath(path.fPath, canvas, color, rect,
335 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
336 gFills[fill].fFill, SK_Scalar1*10);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000337
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000338 SkPaint rectPaint;
339 rectPaint.setColor(SK_ColorBLACK);
340 rectPaint.setStyle(SkPaint::kStroke_Style);
341 rectPaint.setStrokeWidth(-1);
342 rectPaint.setAntiAlias(true);
343 canvas->drawRect(rect, rectPaint);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000344
schenney@chromium.org45cbfdd2011-12-20 21:48:14 +0000345 SkPaint labelPaint;
346 labelPaint.setColor(color);
347 labelPaint.setAntiAlias(true);
Mike Reed1af9b482019-01-07 11:01:57 -0500348 font.setSize(10);
349 canvas->drawString(gStyles[style].fName, 0, rect.height() + 12, font, labelPaint);
350 canvas->drawString(gFills[fill].fName, 0, rect.height() + 24, font, labelPaint);
351 canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36, font, labelPaint);
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000352 }
353 canvas->restore();
354 }
355 canvas->restore();
356 }
357 canvas->restore();
358 canvas->restore();
359 }
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000360};
361
Arman Uguray92fd1a72023-06-16 15:19:23 -0700362class CubicPathShaderGM : public skiagm::GM {
Leandro Lovisolo24fa2112023-08-15 19:05:17 +0000363 SkString getName() const override { return SkString("cubicpath_shader"); }
Arman Uguray92fd1a72023-06-16 15:19:23 -0700364
Leandro Lovisolo8f023882023-08-15 21:13:52 +0000365 SkISize getISize() override { return {1240, 390}; }
Arman Uguray92fd1a72023-06-16 15:19:23 -0700366
367 void drawPath(SkPath& path,SkCanvas* canvas,
368 const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
369 SkPaint::Style style, SkPathFillType fill,
370 SkScalar strokeWidth) {
371 const SkScalar s = 50.f;
372 const SkPoint kPts[] = { { 0, 0 }, { s, s } };
373 const SkScalar kPos[] = { 0, SK_Scalar1/2, SK_Scalar1 };
374 const SkColor kColors[] = {0x80F00080, 0xF0F08000, 0x800080F0 };
375
376 path.setFillType(fill);
377
378 SkPaint paint;
379 paint.setStrokeCap(cap);
380 paint.setStrokeWidth(strokeWidth);
381 paint.setStrokeJoin(join);
382 paint.setShader(SkGradientShader::MakeLinear(kPts, kColors, kPos,
383 std::size(kColors), SkTileMode::kClamp));
384 paint.setStyle(style);
385 canvas->save();
386 canvas->clipRect(clip);
387 canvas->drawPath(path, paint);
388 canvas->restore();
389 }
390
391 void onDraw(SkCanvas* canvas) override {
392 struct FillAndName {
393 SkPathFillType fFill;
394 const char* fName;
395 };
396 constexpr FillAndName gFills[] = {
397 {SkPathFillType::kWinding, "Winding"},
398 {SkPathFillType::kEvenOdd, "Even / Odd"},
399 {SkPathFillType::kInverseWinding, "Inverse Winding"},
400 {SkPathFillType::kInverseEvenOdd, "Inverse Even / Odd"},
401 };
402 struct StyleAndName {
403 SkPaint::Style fStyle;
404 const char* fName;
405 };
406 constexpr StyleAndName gStyles[] = {
407 {SkPaint::kFill_Style, "Fill"},
408 {SkPaint::kStroke_Style, "Stroke"},
409 {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
410 };
411 struct CapAndName {
412 SkPaint::Cap fCap;
413 SkPaint::Join fJoin;
414 const char* fName;
415 };
416 constexpr CapAndName gCaps[] = {
417 {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
418 {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
419 {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
420 };
421 struct PathAndName {
422 SkPath fPath;
423 const char* fName;
424 };
425 PathAndName path;
426 path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
427 path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1,
428 60*SK_Scalar1, 20*SK_Scalar1,
429 75*SK_Scalar1, 10*SK_Scalar1);
430 path.fName = "moveTo-cubic";
431
432 SkPaint titlePaint;
433 titlePaint.setColor(SK_ColorBLACK);
434 titlePaint.setAntiAlias(true);
Kevin Lubicke836c3a2023-10-20 06:55:35 -0400435 SkFont font(ToolUtils::DefaultPortableTypeface(), 15);
Arman Uguray92fd1a72023-06-16 15:19:23 -0700436 const char title[] = "Cubic Drawn Into Rectangle Clips With "
437 "Indicated Style, Fill and Linecaps, with stroke width 10";
438 canvas->drawString(title, 20, 20, font, titlePaint);
439
440 SkRandom rand;
441 SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
442 canvas->save();
443 canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
444 canvas->save();
445 for (size_t cap = 0; cap < std::size(gCaps); ++cap) {
446 if (0 < cap) {
447 canvas->translate((rect.width() + 40 * SK_Scalar1) * std::size(gStyles), 0);
448 }
449 canvas->save();
450 for (size_t fill = 0; fill < std::size(gFills); ++fill) {
451 if (0 < fill) {
452 canvas->translate(0, rect.height() + 40 * SK_Scalar1);
453 }
454 canvas->save();
455 for (size_t style = 0; style < std::size(gStyles); ++style) {
456 if (0 < style) {
457 canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
458 }
459
460 SkColor color = 0xff007000;
461 this->drawPath(path.fPath, canvas, rect,
462 gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
463 gFills[fill].fFill, SK_Scalar1*10);
464
465 SkPaint rectPaint;
466 rectPaint.setColor(SK_ColorBLACK);
467 rectPaint.setStyle(SkPaint::kStroke_Style);
468 rectPaint.setStrokeWidth(-1);
469 rectPaint.setAntiAlias(true);
470 canvas->drawRect(rect, rectPaint);
471
472 SkPaint labelPaint;
473 labelPaint.setColor(color);
474 font.setSize(10);
475 canvas->drawString(gStyles[style].fName, 0, rect.height() + 12, font, labelPaint);
476 canvas->drawString(gFills[fill].fName, 0, rect.height() + 24, font, labelPaint);
477 canvas->drawString(gCaps[cap].fName, 0, rect.height() + 36, font, labelPaint);
478 }
479 canvas->restore();
480 }
481 canvas->restore();
482 }
483 canvas->restore();
484 canvas->restore();
485 }
486};
487
caryclark4693a172016-04-06 08:54:06 -0700488DEF_SIMPLE_GM(bug5099, canvas, 50, 50) {
489 SkPaint p;
490 p.setColor(SK_ColorRED);
491 p.setAntiAlias(true);
492 p.setStyle(SkPaint::kStroke_Style);
493 p.setStrokeWidth(10);
494
495 SkPath path;
496 path.moveTo(6, 27);
497 path.cubicTo(31.5f, 1.5f, 3.5f, 4.5f, 29, 29);
498 canvas->drawPath(path, p);
499}
500
Cary Clarkd4631982017-01-05 12:08:38 -0500501DEF_SIMPLE_GM(bug6083, canvas, 100, 50) {
Ben Wagner29380bd2017-10-09 14:43:00 -0400502 SkPaint p;
503 p.setColor(SK_ColorRED);
504 p.setAntiAlias(true);
505 p.setStyle(SkPaint::kStroke_Style);
506 p.setStrokeWidth(15);
507 canvas->translate(-500, -130);
508 SkPath path;
509 path.moveTo(500.988f, 155.200f);
510 path.lineTo(526.109f, 155.200f);
511 SkPoint p1 = { 526.109f, 155.200f };
512 SkPoint p2 = { 525.968f, 212.968f };
513 SkPoint p3 = { 526.109f, 241.840f };
514 path.cubicTo(p1, p2, p3);
515 canvas->drawPath(path, p);
516 canvas->translate(50, 0);
517 path.reset();
518 p2.set(525.968f, 213.172f);
519 path.moveTo(500.988f, 155.200f);
520 path.lineTo(526.109f, 155.200f);
521 path.cubicTo(p1, p2, p3);
522 canvas->drawPath(path, p);
Cary Clarkd4631982017-01-05 12:08:38 -0500523}
524
schenney@chromium.org4da06ab2011-12-20 15:14:18 +0000525//////////////////////////////////////////////////////////////////////////////
526
reed@google.com27b90fa2013-03-08 18:44:01 +0000527DEF_GM( return new CubicPathGM; )
Arman Uguray92fd1a72023-06-16 15:19:23 -0700528DEF_GM( return new CubicPathShaderGM; )
reed@google.com27b90fa2013-03-08 18:44:01 +0000529DEF_GM( return new CubicClosePathGM; )
reed@google.com22999c62013-05-23 19:30:48 +0000530DEF_GM( return new ClippedCubicGM; )
caryclark7d173402015-08-20 08:23:52 -0700531DEF_GM( return new ClippedCubic2GM; )