blob: f9fa6e99502aa1c2487859dca492ab33ca0ab4fe [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@google.comc2807002011-04-11 13:57:04 +00008#include "gm.h"
9#include "SkPicture.h"
10#include "SkRectShape.h"
11#include "SkGroupShape.h"
12
13typedef SkScalar (*MakePathProc)(SkPath*);
14
15static SkScalar make_frame(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000016 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
17 SkIntToScalar(630), SkIntToScalar(470) };
18 path->addRoundRect(r, SkIntToScalar(15), SkIntToScalar(15));
reed@google.comc2807002011-04-11 13:57:04 +000019
20 SkPaint paint;
21 paint.setStyle(SkPaint::kStroke_Style);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000022 paint.setStrokeWidth(SkIntToScalar(5));
reed@google.comc2807002011-04-11 13:57:04 +000023 paint.getFillPath(*path, path);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000024 return SkIntToScalar(15);
reed@google.comc2807002011-04-11 13:57:04 +000025}
26
27static SkScalar make_triangle(SkPath* path) {
28 static const int gCoord[] = {
29 10, 20, 15, 5, 30, 30
30 };
31 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
32 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
33 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
34 path->close();
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000035 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000036 return SkIntToScalar(30);
37}
38
39static SkScalar make_rect(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000040 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
41 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000042 path->addRect(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000043 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000044 return SkIntToScalar(30);
45}
46
47static SkScalar make_oval(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000048 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
49 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000050 path->addOval(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000051 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000052 return SkIntToScalar(30);
53}
54
55static SkScalar make_sawtooth(SkPath* path) {
56 SkScalar x = SkIntToScalar(20);
57 SkScalar y = SkIntToScalar(20);
58 const SkScalar x0 = x;
59 const SkScalar dx = SK_Scalar1 * 5;
60 const SkScalar dy = SK_Scalar1 * 10;
61
62 path->moveTo(x, y);
63 for (int i = 0; i < 32; i++) {
64 x += dx;
65 path->lineTo(x, y - dy);
66 x += dx;
67 path->lineTo(x, y + dy);
68 }
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000069 path->lineTo(x, y + (2 * dy));
70 path->lineTo(x0, y + (2 * dy));
reed@google.comc2807002011-04-11 13:57:04 +000071 path->close();
72 return SkIntToScalar(30);
73}
74
75static SkScalar make_star(SkPath* path, int n) {
76 const SkScalar c = SkIntToScalar(45);
77 const SkScalar r = SkIntToScalar(20);
78
79 SkScalar rad = -SK_ScalarPI / 2;
80 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
81
82 path->moveTo(c, c - r);
83 for (int i = 1; i < n; i++) {
84 rad += drad;
85 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
86 path->lineTo(c + SkScalarMul(cosV, r), c + SkScalarMul(sinV, r));
87 }
88 path->close();
89 return r * 2 * 6 / 5;
90}
91
92static SkScalar make_star_5(SkPath* path) { return make_star(path, 5); }
93static SkScalar make_star_13(SkPath* path) { return make_star(path, 13); }
94
vandebo@chromium.org683001c2012-05-09 17:17:51 +000095// We don't expect any output from this path.
96static SkScalar make_line(SkPath* path) {
97 path->moveTo(SkIntToScalar(30), SkIntToScalar(30));
98 path->lineTo(SkIntToScalar(120), SkIntToScalar(40));
99 path->close();
100 path->moveTo(SkIntToScalar(150), SkIntToScalar(30));
101 path->lineTo(SkIntToScalar(150), SkIntToScalar(30));
102 path->lineTo(SkIntToScalar(300), SkIntToScalar(40));
103 path->close();
104 return SkIntToScalar(40);
105}
106
reed@google.comc2807002011-04-11 13:57:04 +0000107static const MakePathProc gProcs[] = {
108 make_frame,
109 make_triangle,
110 make_rect,
111 make_oval,
112 make_sawtooth,
113 make_star_5,
vandebo@chromium.org683001c2012-05-09 17:17:51 +0000114 make_star_13,
115 make_line,
reed@google.comc2807002011-04-11 13:57:04 +0000116};
117
118#define N SK_ARRAY_COUNT(gProcs)
119
reed@google.com5ee64912012-06-11 17:30:33 +0000120class PathFillGM : public skiagm::GM {
reed@google.comc2807002011-04-11 13:57:04 +0000121 SkPath fPath[N];
122 SkScalar fDY[N];
123public:
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000124 PathFillGM() {
reed@google.comc2807002011-04-11 13:57:04 +0000125 for (size_t i = 0; i < N; i++) {
126 fDY[i] = gProcs[i](&fPath[i]);
127 }
128 }
reed@google.com5ee64912012-06-11 17:30:33 +0000129
reed@google.comc2807002011-04-11 13:57:04 +0000130protected:
131 virtual SkString onShortName() {
132 return SkString("pathfill");
133 }
reed@google.com5ee64912012-06-11 17:30:33 +0000134
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000135 virtual SkISize onISize() {
reed@google.com5ee64912012-06-11 17:30:33 +0000136 return SkISize::Make(640, 480);
reed@google.comc2807002011-04-11 13:57:04 +0000137 }
reed@google.com5ee64912012-06-11 17:30:33 +0000138
reed@google.comc2807002011-04-11 13:57:04 +0000139 virtual void onDraw(SkCanvas* canvas) {
reed@google.comc2807002011-04-11 13:57:04 +0000140 SkPaint paint;
141 paint.setAntiAlias(true);
142
143 for (size_t i = 0; i < N; i++) {
144 canvas->drawPath(fPath[i], paint);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000145 canvas->translate(SkIntToScalar(0), fDY[i]);
reed@google.comc2807002011-04-11 13:57:04 +0000146 }
147 }
reed@google.com5ee64912012-06-11 17:30:33 +0000148
reed@google.comc2807002011-04-11 13:57:04 +0000149private:
reed@google.com5ee64912012-06-11 17:30:33 +0000150 typedef skiagm::GM INHERITED;
151};
152
153// test inverse-fill w/ a clip that completely excludes the geometry
154class PathInverseFillGM : public skiagm::GM {
155 SkPath fPath[N];
156 SkScalar fDY[N];
157public:
158 PathInverseFillGM() {
159 for (size_t i = 0; i < N; i++) {
160 fDY[i] = gProcs[i](&fPath[i]);
161 }
162 }
163
164protected:
165 virtual SkString onShortName() {
166 return SkString("pathinvfill");
167 }
168
169 virtual SkISize onISize() {
170 return SkISize::Make(450, 220);
171 }
172
173 static void show(SkCanvas* canvas, const SkPath& path, const SkPaint& paint,
174 const SkRect* clip, SkScalar top, const SkScalar bottom) {
175 canvas->save();
176 if (clip) {
177 SkRect r = *clip;
178 r.fTop = top;
179 r.fBottom = bottom;
180 canvas->clipRect(r);
181 }
182 canvas->drawPath(path, paint);
183 canvas->restore();
184 }
185
186 virtual void onDraw(SkCanvas* canvas) {
187 SkPath path;
188
189 path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
190 path.toggleInverseFillType();
191
192 SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
193
194 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
195
196 for (int doclip = 0; doclip <= 1; ++doclip) {
197 for (int aa = 0; aa <= 1; ++aa) {
198 SkPaint paint;
199 paint.setAntiAlias(SkToBool(aa));
200
201 canvas->save();
202 canvas->clipRect(clipR);
203
204 const SkRect* clipPtr = doclip ? &clipR : NULL;
205
206 show(canvas, path, paint, clipPtr, clipR.fTop, clipR.centerY());
207 show(canvas, path, paint, clipPtr, clipR.centerY(), clipR.fBottom);
208
209 canvas->restore();
210 canvas->translate(SkIntToScalar(110), 0);
211 }
212 }
213 }
214
215private:
216 typedef skiagm::GM INHERITED;
reed@google.comc2807002011-04-11 13:57:04 +0000217};
218
219///////////////////////////////////////////////////////////////////////////////
220
reed@google.com5ee64912012-06-11 17:30:33 +0000221static skiagm::GM* MyFactory(void*) { return new PathFillGM; }
222static skiagm::GMRegistry reg(MyFactory);
reed@google.comc2807002011-04-11 13:57:04 +0000223
reed@google.com5ee64912012-06-11 17:30:33 +0000224static skiagm::GM* F1(void*) { return new PathInverseFillGM; }
225static skiagm::GMRegistry gR1(F1);
226