461a4f5fc82d69652cf2f2488e736bd925160762
[platform/upstream/libSkiaSharp.git] / gm / pathfill.cpp
1
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  */
8 #include "gm.h"
9
10 typedef SkScalar (*MakePathProc)(SkPath*);
11
12 static SkScalar make_frame(SkPath* path) {
13     SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
14                  SkIntToScalar(630), SkIntToScalar(470) };
15     path->addRoundRect(r, SkIntToScalar(15), SkIntToScalar(15));
16
17     SkPaint paint;
18     paint.setStyle(SkPaint::kStroke_Style);
19     paint.setStrokeWidth(SkIntToScalar(5));
20     paint.getFillPath(*path, path);
21     return SkIntToScalar(15);
22 }
23
24 static 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();
32     path->offset(SkIntToScalar(10), SkIntToScalar(0));
33     return SkIntToScalar(30);
34 }
35
36 static SkScalar make_rect(SkPath* path) {
37     SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
38                  SkIntToScalar(30), SkIntToScalar(30) };
39     path->addRect(r);
40     path->offset(SkIntToScalar(10), SkIntToScalar(0));
41     return SkIntToScalar(30);
42 }
43
44 static SkScalar make_oval(SkPath* path) {
45     SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
46                  SkIntToScalar(30), SkIntToScalar(30) };
47     path->addOval(r);
48     path->offset(SkIntToScalar(10), SkIntToScalar(0));
49     return SkIntToScalar(30);
50 }
51
52 static 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;
58
59     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     }
66     path->lineTo(x, y + (2 * dy));
67     path->lineTo(x0, y + (2 * dy));
68     path->close();
69     return SkIntToScalar(30);
70 }
71
72 static SkScalar make_star(SkPath* path, int n) {
73     const SkScalar c = SkIntToScalar(45);
74     const SkScalar r = SkIntToScalar(20);
75
76     SkScalar rad = -SK_ScalarPI / 2;
77     const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
78
79     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
89 static SkScalar make_star_5(SkPath* path) { return make_star(path, 5); }
90 static SkScalar make_star_13(SkPath* path) { return make_star(path, 13); }
91
92 // We don't expect any output from this path.
93 static 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
104 static const MakePathProc gProcs[] = {
105     make_frame,
106     make_triangle,
107     make_rect,
108     make_oval,
109     make_sawtooth,
110     make_star_5,
111     make_star_13,
112     make_line,
113 };
114
115 #define N   SK_ARRAY_COUNT(gProcs)
116
117 class PathFillGM : public skiagm::GM {
118     SkPath  fPath[N];
119     SkScalar fDY[N];
120 protected:
121     void onOnceBeforeDraw() SK_OVERRIDE {
122         for (size_t i = 0; i < N; i++) {
123             fDY[i] = gProcs[i](&fPath[i]);
124         }
125     }
126
127
128     SkString onShortName() SK_OVERRIDE {
129         return SkString("pathfill");
130     }
131
132     SkISize onISize() SK_OVERRIDE {
133         return SkISize::Make(640, 480);
134     }
135
136     void onDraw(SkCanvas* canvas) SK_OVERRIDE {
137         SkPaint paint;
138         paint.setAntiAlias(true);
139
140         for (size_t i = 0; i < N; i++) {
141             canvas->drawPath(fPath[i], paint);
142             canvas->translate(SkIntToScalar(0), fDY[i]);
143         }
144     }
145
146 private:
147     typedef skiagm::GM INHERITED;
148 };
149
150 // test inverse-fill w/ a clip that completely excludes the geometry
151 class PathInverseFillGM : public skiagm::GM {
152     SkPath  fPath[N];
153     SkScalar fDY[N];
154 protected:
155     void onOnceBeforeDraw() SK_OVERRIDE {
156         for (size_t i = 0; i < N; i++) {
157             fDY[i] = gProcs[i](&fPath[i]);
158         }
159     }
160
161     SkString onShortName() SK_OVERRIDE {
162         return SkString("pathinvfill");
163     }
164
165     SkISize onISize() SK_OVERRIDE {
166         return SkISize::Make(450, 220);
167     }
168
169     static void show(SkCanvas* canvas, const SkPath& path, const SkPaint& paint,
170                      const SkRect* clip, SkScalar top, const SkScalar bottom) {
171         canvas->save();
172         if (clip) {
173             SkRect r = *clip;
174             r.fTop = top;
175             r.fBottom = bottom;
176             canvas->clipRect(r);
177         }
178         canvas->drawPath(path, paint);
179         canvas->restore();
180     }
181
182     void onDraw(SkCanvas* canvas) SK_OVERRIDE {
183         SkPath path;
184
185         path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
186         path.toggleInverseFillType();
187
188         SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
189
190         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
191
192         for (int doclip = 0; doclip <= 1; ++doclip) {
193             for (int aa = 0; aa <= 1; ++aa) {
194                 SkPaint paint;
195                 paint.setAntiAlias(SkToBool(aa));
196
197                 canvas->save();
198                 canvas->clipRect(clipR);
199
200                 const SkRect* clipPtr = doclip ? &clipR : NULL;
201
202                 show(canvas, path, paint, clipPtr, clipR.fTop, clipR.centerY());
203                 show(canvas, path, paint, clipPtr, clipR.centerY(), clipR.fBottom);
204
205                 canvas->restore();
206                 canvas->translate(SkIntToScalar(110), 0);
207             }
208         }
209     }
210
211 private:
212     typedef skiagm::GM INHERITED;
213 };
214
215 ///////////////////////////////////////////////////////////////////////////////
216
217 static skiagm::GM* MyFactory(void*) { return new PathFillGM; }
218 static skiagm::GMRegistry reg(MyFactory);
219
220 static skiagm::GM* F1(void*) { return new PathInverseFillGM; }
221 static skiagm::GMRegistry gR1(F1);