blob: 01811e3c94c2ca4be8b652866d6386b7adfbcaa2 [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"
reed@google.comc2807002011-04-11 13:57:04 +00009
10typedef SkScalar (*MakePathProc)(SkPath*);
11
12static SkScalar make_frame(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000013 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
14 SkIntToScalar(630), SkIntToScalar(470) };
15 path->addRoundRect(r, SkIntToScalar(15), SkIntToScalar(15));
rmistry@google.comd6176b02012-08-23 18:14:13 +000016
reed@google.comc2807002011-04-11 13:57:04 +000017 SkPaint paint;
18 paint.setStyle(SkPaint::kStroke_Style);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000019 paint.setStrokeWidth(SkIntToScalar(5));
reed@google.comc2807002011-04-11 13:57:04 +000020 paint.getFillPath(*path, path);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000021 return SkIntToScalar(15);
reed@google.comc2807002011-04-11 13:57:04 +000022}
23
24static SkScalar make_triangle(SkPath* path) {
25 static const int gCoord[] = {
26 10, 20, 15, 5, 30, 30
27 };
28 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
29 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
30 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
31 path->close();
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000032 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000033 return SkIntToScalar(30);
34}
35
36static SkScalar make_rect(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000037 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
38 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000039 path->addRect(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000040 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000041 return SkIntToScalar(30);
42}
43
44static SkScalar make_oval(SkPath* path) {
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000045 SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
46 SkIntToScalar(30), SkIntToScalar(30) };
reed@google.comc2807002011-04-11 13:57:04 +000047 path->addOval(r);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000048 path->offset(SkIntToScalar(10), SkIntToScalar(0));
reed@google.comc2807002011-04-11 13:57:04 +000049 return SkIntToScalar(30);
50}
51
52static SkScalar make_sawtooth(SkPath* path) {
53 SkScalar x = SkIntToScalar(20);
54 SkScalar y = SkIntToScalar(20);
55 const SkScalar x0 = x;
56 const SkScalar dx = SK_Scalar1 * 5;
57 const SkScalar dy = SK_Scalar1 * 10;
rmistry@google.comd6176b02012-08-23 18:14:13 +000058
reed@google.comc2807002011-04-11 13:57:04 +000059 path->moveTo(x, y);
60 for (int i = 0; i < 32; i++) {
61 x += dx;
62 path->lineTo(x, y - dy);
63 x += dx;
64 path->lineTo(x, y + dy);
65 }
bungeman@google.com3c14d0f2011-05-20 14:05:03 +000066 path->lineTo(x, y + (2 * dy));
67 path->lineTo(x0, y + (2 * dy));
reed@google.comc2807002011-04-11 13:57:04 +000068 path->close();
69 return SkIntToScalar(30);
70}
71
72static SkScalar make_star(SkPath* path, int n) {
73 const SkScalar c = SkIntToScalar(45);
74 const SkScalar r = SkIntToScalar(20);
rmistry@google.comd6176b02012-08-23 18:14:13 +000075
reed@google.comc2807002011-04-11 13:57:04 +000076 SkScalar rad = -SK_ScalarPI / 2;
77 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
rmistry@google.comd6176b02012-08-23 18:14:13 +000078
reed@google.comc2807002011-04-11 13:57:04 +000079 path->moveTo(c, c - r);
80 for (int i = 1; i < n; i++) {
81 rad += drad;
82 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
83 path->lineTo(c + SkScalarMul(cosV, r), c + SkScalarMul(sinV, r));
84 }
85 path->close();
86 return r * 2 * 6 / 5;
87}
88
89static SkScalar make_star_5(SkPath* path) { return make_star(path, 5); }
90static SkScalar make_star_13(SkPath* path) { return make_star(path, 13); }
91
vandebo@chromium.org683001c2012-05-09 17:17:51 +000092// We don't expect any output from this path.
93static SkScalar make_line(SkPath* path) {
94 path->moveTo(SkIntToScalar(30), SkIntToScalar(30));
95 path->lineTo(SkIntToScalar(120), SkIntToScalar(40));
96 path->close();
97 path->moveTo(SkIntToScalar(150), SkIntToScalar(30));
98 path->lineTo(SkIntToScalar(150), SkIntToScalar(30));
99 path->lineTo(SkIntToScalar(300), SkIntToScalar(40));
100 path->close();
101 return SkIntToScalar(40);
102}
103
reed@google.comc2807002011-04-11 13:57:04 +0000104static const MakePathProc gProcs[] = {
105 make_frame,
106 make_triangle,
107 make_rect,
108 make_oval,
109 make_sawtooth,
110 make_star_5,
vandebo@chromium.org683001c2012-05-09 17:17:51 +0000111 make_star_13,
112 make_line,
reed@google.comc2807002011-04-11 13:57:04 +0000113};
114
115#define N SK_ARRAY_COUNT(gProcs)
116
reed@google.com5ee64912012-06-11 17:30:33 +0000117class PathFillGM : public skiagm::GM {
reed@google.comc2807002011-04-11 13:57:04 +0000118 SkPath fPath[N];
119 SkScalar fDY[N];
120public:
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000121 PathFillGM() {
reed@google.comc2807002011-04-11 13:57:04 +0000122 for (size_t i = 0; i < N; i++) {
123 fDY[i] = gProcs[i](&fPath[i]);
124 }
125 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000126
reed@google.comc2807002011-04-11 13:57:04 +0000127protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000128 virtual uint32_t onGetFlags() const SK_OVERRIDE {
129 return kSkipTiled_Flag;
130 }
131
reed@google.comc2807002011-04-11 13:57:04 +0000132 virtual SkString onShortName() {
133 return SkString("pathfill");
134 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000135
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000136 virtual SkISize onISize() {
reed@google.com5ee64912012-06-11 17:30:33 +0000137 return SkISize::Make(640, 480);
reed@google.comc2807002011-04-11 13:57:04 +0000138 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000139
reed@google.comc2807002011-04-11 13:57:04 +0000140 virtual void onDraw(SkCanvas* canvas) {
reed@google.comc2807002011-04-11 13:57:04 +0000141 SkPaint paint;
142 paint.setAntiAlias(true);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000143
reed@google.comc2807002011-04-11 13:57:04 +0000144 for (size_t i = 0; i < N; i++) {
145 canvas->drawPath(fPath[i], paint);
bungeman@google.com3c14d0f2011-05-20 14:05:03 +0000146 canvas->translate(SkIntToScalar(0), fDY[i]);
reed@google.comc2807002011-04-11 13:57:04 +0000147 }
148 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000149
reed@google.comc2807002011-04-11 13:57:04 +0000150private:
reed@google.com5ee64912012-06-11 17:30:33 +0000151 typedef skiagm::GM INHERITED;
152};
153
154// test inverse-fill w/ a clip that completely excludes the geometry
155class PathInverseFillGM : public skiagm::GM {
156 SkPath fPath[N];
157 SkScalar fDY[N];
158public:
159 PathInverseFillGM() {
160 for (size_t i = 0; i < N; i++) {
161 fDY[i] = gProcs[i](&fPath[i]);
162 }
163 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000164
reed@google.com5ee64912012-06-11 17:30:33 +0000165protected:
commit-bot@chromium.orga90c6802014-04-30 13:20:45 +0000166 virtual uint32_t onGetFlags() const SK_OVERRIDE {
167 return kSkipTiled_Flag;
168 }
169
reed@google.com5ee64912012-06-11 17:30:33 +0000170 virtual SkString onShortName() {
171 return SkString("pathinvfill");
172 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000173
reed@google.com5ee64912012-06-11 17:30:33 +0000174 virtual SkISize onISize() {
175 return SkISize::Make(450, 220);
176 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000177
reed@google.com5ee64912012-06-11 17:30:33 +0000178 static void show(SkCanvas* canvas, const SkPath& path, const SkPaint& paint,
179 const SkRect* clip, SkScalar top, const SkScalar bottom) {
180 canvas->save();
181 if (clip) {
182 SkRect r = *clip;
183 r.fTop = top;
184 r.fBottom = bottom;
185 canvas->clipRect(r);
186 }
187 canvas->drawPath(path, paint);
188 canvas->restore();
189 }
190
191 virtual void onDraw(SkCanvas* canvas) {
192 SkPath path;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000193
reed@google.com5ee64912012-06-11 17:30:33 +0000194 path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
195 path.toggleInverseFillType();
196
197 SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
198
199 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
200
201 for (int doclip = 0; doclip <= 1; ++doclip) {
202 for (int aa = 0; aa <= 1; ++aa) {
203 SkPaint paint;
204 paint.setAntiAlias(SkToBool(aa));
205
206 canvas->save();
207 canvas->clipRect(clipR);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000208
reed@google.com5ee64912012-06-11 17:30:33 +0000209 const SkRect* clipPtr = doclip ? &clipR : NULL;
210
211 show(canvas, path, paint, clipPtr, clipR.fTop, clipR.centerY());
212 show(canvas, path, paint, clipPtr, clipR.centerY(), clipR.fBottom);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000213
reed@google.com5ee64912012-06-11 17:30:33 +0000214 canvas->restore();
215 canvas->translate(SkIntToScalar(110), 0);
216 }
217 }
218 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000219
reed@google.com5ee64912012-06-11 17:30:33 +0000220private:
221 typedef skiagm::GM INHERITED;
reed@google.comc2807002011-04-11 13:57:04 +0000222};
223
224///////////////////////////////////////////////////////////////////////////////
225
reed@google.com5ee64912012-06-11 17:30:33 +0000226static skiagm::GM* MyFactory(void*) { return new PathFillGM; }
227static skiagm::GMRegistry reg(MyFactory);
reed@google.comc2807002011-04-11 13:57:04 +0000228
reed@google.com5ee64912012-06-11 17:30:33 +0000229static skiagm::GM* F1(void*) { return new PathInverseFillGM; }
230static skiagm::GMRegistry gR1(F1);