blob: f4e42e8165a8e5c639a7987316d4674d08d7e959 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +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
reed@google.comc2807002011-04-11 13:57:04 +00008#include "gm.h"
bungemand3ebb482015-08-05 13:57:49 -07009#include "SkPath.h"
reed@google.comc2807002011-04-11 13:57:04 +000010
11typedef SkScalar (*MakePathProc)(SkPath*);
12
13static SkScalar make_frame(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000014 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
15 SkIntToScalar(630), SkIntToScalar(470) };
16 path->addRoundRect(r, SkIntToScalar(15), SkIntToScalar(15));
rmistry@google.comd6176b02012-08-23 18:14:13 +000017
reed@google.comc2807002011-04-11 13:57:04 +000018 SkPaint paint;
19 paint.setStyle(SkPaint::kStroke_Style);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000020 paint.setStrokeWidth(SkIntToScalar(5));
reed@google.comc2807002011-04-11 13:57:04 +000021 paint.getFillPath(*path, path);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000022 return SkIntToScalar(15);
reed@google.comc2807002011-04-11 13:57:04 +000023}
24
25static SkScalar make_triangle(SkPath* path) {
26 static const int gCoord[] = {
27 10, 20, 15, 5, 30, 30
28 };
29 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
30 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
31 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
32 path->close();
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000033 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000034 return SkIntToScalar(30);
35}
36
37static SkScalar make_rect(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000038 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
39 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000040 path->addRect(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000041 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000042 return SkIntToScalar(30);
43}
44
45static SkScalar make_oval(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000046 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
47 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000048 path->addOval(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000049 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000050 return SkIntToScalar(30);
51}
52
53static SkScalar make_sawtooth(SkPath* path) {
54 SkScalar x = SkIntToScalar(20);
55 SkScalar y = SkIntToScalar(20);
56 const SkScalar x0 = x;
57 const SkScalar dx = SK_Scalar1 * 5;
58 const SkScalar dy = SK_Scalar1 * 10;
rmistry@google.comd6176b02012-08-23 18:14:13 +000059
reed@google.comc2807002011-04-11 13:57:04 +000060 path->moveTo(x, y);
61 for (int i = 0; i < 32; i++) {
62 x += dx;
63 path->lineTo(x, y - dy);
64 x += dx;
65 path->lineTo(x, y + dy);
66 }
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000067 path->lineTo(x, y + (2 * dy));
68 path->lineTo(x0, y + (2 * dy));
reed@google.comc2807002011-04-11 13:57:04 +000069 path->close();
70 return SkIntToScalar(30);
71}
72
73static SkScalar make_star(SkPath* path, int n) {
74 const SkScalar c = SkIntToScalar(45);
75 const SkScalar r = SkIntToScalar(20);
rmistry@google.comd6176b02012-08-23 18:14:13 +000076
reed@google.comc2807002011-04-11 13:57:04 +000077 SkScalar rad = -SK_ScalarPI / 2;
78 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
rmistry@google.comd6176b02012-08-23 18:14:13 +000079
reed@google.comc2807002011-04-11 13:57:04 +000080 path->moveTo(c, c - r);
81 for (int i = 1; i < n; i++) {
82 rad += drad;
83 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
84 path->lineTo(c + SkScalarMul(cosV, r), c + SkScalarMul(sinV, r));
85 }
86 path->close();
87 return r * 2 * 6 / 5;
88}
89
90static SkScalar make_star_5(SkPath* path) { return make_star(path, 5); }
91static SkScalar make_star_13(SkPath* path) { return make_star(path, 13); }
92
vandebo@chromium.org683001c2012-05-09 17:17:51 +000093// We don't expect any output from this path.
94static SkScalar make_line(SkPath* path) {
95 path->moveTo(SkIntToScalar(30), SkIntToScalar(30));
96 path->lineTo(SkIntToScalar(120), SkIntToScalar(40));
97 path->close();
98 path->moveTo(SkIntToScalar(150), SkIntToScalar(30));
99 path->lineTo(SkIntToScalar(150), SkIntToScalar(30));
100 path->lineTo(SkIntToScalar(300), SkIntToScalar(40));
101 path->close();
102 return SkIntToScalar(40);
103}
104
reed@google.comc2807002011-04-11 13:57:04 +0000105static const MakePathProc gProcs[] = {
106 make_frame,
107 make_triangle,
108 make_rect,
109 make_oval,
110 make_sawtooth,
111 make_star_5,
vandebo@chromium.org683001c2012-05-09 17:17:51 +0000112 make_star_13,
113 make_line,
reed@google.comc2807002011-04-11 13:57:04 +0000114};
115
116#define N SK_ARRAY_COUNT(gProcs)
117
reed@google.com5ee64912012-06-11 17:30:33 +0000118class PathFillGM : public skiagm::GM {
reed@google.comc2807002011-04-11 13:57:04 +0000119 SkPath fPath[N];
120 SkScalar fDY[N];
caryclark88c748a2015-02-18 10:56:00 -0800121protected:
mtklein36352bf2015-03-25 18:17:31 -0700122 void onOnceBeforeDraw() override {
reed@google.comc2807002011-04-11 13:57:04 +0000123 for (size_t i = 0; i < N; i++) {
124 fDY[i] = gProcs[i](&fPath[i]);
125 }
126 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000127
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000128
mtklein36352bf2015-03-25 18:17:31 -0700129 SkString onShortName() override {
reed@google.comc2807002011-04-11 13:57:04 +0000130 return SkString("pathfill");
131 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000132
mtklein36352bf2015-03-25 18:17:31 -0700133 SkISize onISize() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000134 return SkISize::Make(640, 480);
reed@google.comc2807002011-04-11 13:57:04 +0000135 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000136
mtklein36352bf2015-03-25 18:17:31 -0700137 void onDraw(SkCanvas* canvas) override {
reed@google.comc2807002011-04-11 13:57:04 +0000138 SkPaint paint;
139 paint.setAntiAlias(true);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000140
reed@google.comc2807002011-04-11 13:57:04 +0000141 for (size_t i = 0; i < N; i++) {
142 canvas->drawPath(fPath[i], paint);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000143 canvas->translate(SkIntToScalar(0), fDY[i]);
reed@google.comc2807002011-04-11 13:57:04 +0000144 }
145 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000146
reed@google.comc2807002011-04-11 13:57:04 +0000147private:
reed@google.com5ee64912012-06-11 17:30:33 +0000148 typedef skiagm::GM INHERITED;
149};
150
151// test inverse-fill w/ a clip that completely excludes the geometry
152class PathInverseFillGM : public skiagm::GM {
153 SkPath fPath[N];
154 SkScalar fDY[N];
caryclark88c748a2015-02-18 10:56:00 -0800155protected:
mtklein36352bf2015-03-25 18:17:31 -0700156 void onOnceBeforeDraw() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000157 for (size_t i = 0; i < N; i++) {
158 fDY[i] = gProcs[i](&fPath[i]);
159 }
160 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000161
mtklein36352bf2015-03-25 18:17:31 -0700162 SkString onShortName() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000163 return SkString("pathinvfill");
164 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000165
mtklein36352bf2015-03-25 18:17:31 -0700166 SkISize onISize() override {
reed@google.com5ee64912012-06-11 17:30:33 +0000167 return SkISize::Make(450, 220);
168 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000169
reed@google.com5ee64912012-06-11 17:30:33 +0000170 static void show(SkCanvas* canvas, const SkPath& path, const SkPaint& paint,
171 const SkRect* clip, SkScalar top, const SkScalar bottom) {
172 canvas->save();
173 if (clip) {
174 SkRect r = *clip;
175 r.fTop = top;
176 r.fBottom = bottom;
177 canvas->clipRect(r);
178 }
179 canvas->drawPath(path, paint);
180 canvas->restore();
181 }
182
mtklein36352bf2015-03-25 18:17:31 -0700183 void onDraw(SkCanvas* canvas) override {
reed@google.com5ee64912012-06-11 17:30:33 +0000184 SkPath path;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000185
reed@google.com5ee64912012-06-11 17:30:33 +0000186 path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
187 path.toggleInverseFillType();
188
189 SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
190
191 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
192
193 for (int doclip = 0; doclip <= 1; ++doclip) {
194 for (int aa = 0; aa <= 1; ++aa) {
195 SkPaint paint;
196 paint.setAntiAlias(SkToBool(aa));
197
198 canvas->save();
199 canvas->clipRect(clipR);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000200
halcanary96fcdcc2015-08-27 07:41:13 -0700201 const SkRect* clipPtr = doclip ? &clipR : nullptr;
reed@google.com5ee64912012-06-11 17:30:33 +0000202
203 show(canvas, path, paint, clipPtr, clipR.fTop, clipR.centerY());
204 show(canvas, path, paint, clipPtr, clipR.centerY(), clipR.fBottom);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000205
reed@google.com5ee64912012-06-11 17:30:33 +0000206 canvas->restore();
207 canvas->translate(SkIntToScalar(110), 0);
208 }
209 }
210 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000211
reed@google.com5ee64912012-06-11 17:30:33 +0000212private:
213 typedef skiagm::GM INHERITED;
reed@google.comc2807002011-04-11 13:57:04 +0000214};
215
216///////////////////////////////////////////////////////////////////////////////
217
reed@google.com5ee64912012-06-11 17:30:33 +0000218static skiagm::GM* MyFactory(void*) { return new PathFillGM; }
219static skiagm::GMRegistry reg(MyFactory);
reed@google.comc2807002011-04-11 13:57:04 +0000220
reed@google.com5ee64912012-06-11 17:30:33 +0000221static skiagm::GM* F1(void*) { return new PathInverseFillGM; }
222static skiagm::GMRegistry gR1(F1);