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
9
10
11#include "gm.h"
12#include "SkRandom.h"
13
14#define W   400
15#define H   400
16#define N   50
17
18static const SkScalar SW = SkIntToScalar(W);
19static const SkScalar SH = SkIntToScalar(H);
20
21static void rnd_rect(SkRect* r, SkPaint* paint, SkRandom& rand) {
22    SkScalar x = rand.nextUScalar1() * W;
23    SkScalar y = rand.nextUScalar1() * H;
24    SkScalar w = rand.nextUScalar1() * (W >> 2);
25    SkScalar h = rand.nextUScalar1() * (H >> 2);
26    SkScalar hoffset = rand.nextSScalar1();
27    SkScalar woffset = rand.nextSScalar1();
28
29    r->set(x, y, x + w, y + h);
30    r->offset(-w/2 + woffset, -h/2 + hoffset);
31
32    paint->setColor(rand.nextU());
33    paint->setAlpha(0xFF);
34}
35
36
37class StrokesGM : public skiagm::GM {
38public:
39    StrokesGM() {}
40
41protected:
42
43    SkString onShortName() override {
44        return SkString("strokes_round");
45    }
46
47    SkISize onISize() override {
48        return SkISize::Make(W, H*2);
49    }
50
51    void onDraw(SkCanvas* canvas) override {
52        SkPaint paint;
53        paint.setStyle(SkPaint::kStroke_Style);
54        paint.setStrokeWidth(SkIntToScalar(9)/2);
55
56        for (int y = 0; y < 2; y++) {
57            paint.setAntiAlias(!!y);
58            SkAutoCanvasRestore acr(canvas, true);
59            canvas->translate(0, SH * y);
60            canvas->clipRect(SkRect::MakeLTRB(
61                                              SkIntToScalar(2), SkIntToScalar(2)
62                                              , SW - SkIntToScalar(2), SH - SkIntToScalar(2)
63                                              ));
64
65            SkRandom rand;
66            for (int i = 0; i < N; i++) {
67                SkRect r;
68                rnd_rect(&r, &paint, rand);
69                canvas->drawOval(r, paint);
70                rnd_rect(&r, &paint, rand);
71                canvas->drawRoundRect(r, r.width()/4, r.height()/4, paint);
72                rnd_rect(&r, &paint, rand);
73            }
74        }
75    }
76
77private:
78    typedef skiagm::GM INHERITED;
79};
80
81class Strokes2GM : public skiagm::GM {
82    SkPath fPath;
83protected:
84    void onOnceBeforeDraw() override {
85        SkRandom rand;
86        fPath.moveTo(0, 0);
87        for (int i = 0; i < 13; i++) {
88            SkScalar x = rand.nextUScalar1() * (W >> 1);
89            SkScalar y = rand.nextUScalar1() * (H >> 1);
90            fPath.lineTo(x, y);
91        }
92    }
93
94
95    SkString onShortName() override {
96        return SkString("strokes_poly");
97    }
98
99    SkISize onISize() override {
100        return SkISize::Make(W, H*2);
101    }
102
103    static void rotate(SkScalar angle, SkScalar px, SkScalar py, SkCanvas* canvas) {
104        SkMatrix matrix;
105        matrix.setRotate(angle, px, py);
106        canvas->concat(matrix);
107    }
108
109    void onDraw(SkCanvas* canvas) override {
110        canvas->drawColor(SK_ColorWHITE);
111
112        SkPaint paint;
113        paint.setStyle(SkPaint::kStroke_Style);
114        paint.setStrokeWidth(SkIntToScalar(9)/2);
115
116        for (int y = 0; y < 2; y++) {
117            paint.setAntiAlias(!!y);
118            SkAutoCanvasRestore acr(canvas, true);
119            canvas->translate(0, SH * y);
120            canvas->clipRect(SkRect::MakeLTRB(SkIntToScalar(2),
121                                              SkIntToScalar(2),
122                                              SW - SkIntToScalar(2),
123                                              SH - SkIntToScalar(2)));
124
125            SkRandom rand;
126            for (int i = 0; i < N/2; i++) {
127                SkRect r;
128                rnd_rect(&r, &paint, rand);
129                rotate(SkIntToScalar(15), SW/2, SH/2, canvas);
130                canvas->drawPath(fPath, paint);
131            }
132        }
133    }
134
135private:
136    typedef skiagm::GM INHERITED;
137};
138
139//////////////////////////////////////////////////////////////////////////////
140
141static SkRect inset(const SkRect& r) {
142    SkRect rr(r);
143    rr.inset(r.width()/10, r.height()/10);
144    return rr;
145}
146
147class Strokes3GM : public skiagm::GM {
148    static void make0(SkPath* path, const SkRect& bounds, SkString* title) {
149        path->addRect(bounds, SkPath::kCW_Direction);
150        path->addRect(inset(bounds), SkPath::kCW_Direction);
151        title->set("CW CW");
152    }
153
154    static void make1(SkPath* path, const SkRect& bounds, SkString* title) {
155        path->addRect(bounds, SkPath::kCW_Direction);
156        path->addRect(inset(bounds), SkPath::kCCW_Direction);
157        title->set("CW CCW");
158    }
159
160    static void make2(SkPath* path, const SkRect& bounds, SkString* title) {
161        path->addOval(bounds, SkPath::kCW_Direction);
162        path->addOval(inset(bounds), SkPath::kCW_Direction);
163        title->set("CW CW");
164    }
165
166    static void make3(SkPath* path, const SkRect& bounds, SkString* title) {
167        path->addOval(bounds, SkPath::kCW_Direction);
168        path->addOval(inset(bounds), SkPath::kCCW_Direction);
169        title->set("CW CCW");
170    }
171
172    static void make4(SkPath* path, const SkRect& bounds, SkString* title) {
173        path->addRect(bounds, SkPath::kCW_Direction);
174        SkRect r = bounds;
175        r.inset(bounds.width() / 10, -bounds.height() / 10);
176        path->addOval(r, SkPath::kCW_Direction);
177        title->set("CW CW");
178    }
179
180    static void make5(SkPath* path, const SkRect& bounds, SkString* title) {
181        path->addRect(bounds, SkPath::kCW_Direction);
182        SkRect r = bounds;
183        r.inset(bounds.width() / 10, -bounds.height() / 10);
184        path->addOval(r, SkPath::kCCW_Direction);
185        title->set("CW CCW");
186    }
187
188public:
189    Strokes3GM() {}
190
191protected:
192
193    SkString onShortName() override {
194        return SkString("strokes3");
195    }
196
197    SkISize onISize() override {
198        return SkISize::Make(1500, 1500);
199    }
200
201    void onDraw(SkCanvas* canvas) override {
202        SkPaint origPaint;
203        origPaint.setAntiAlias(true);
204        origPaint.setStyle(SkPaint::kStroke_Style);
205        SkPaint fillPaint(origPaint);
206        fillPaint.setColor(SK_ColorRED);
207        SkPaint strokePaint(origPaint);
208        strokePaint.setColor(0xFF4444FF);
209
210        void (*procs[])(SkPath*, const SkRect&, SkString*) = {
211            make0, make1, make2, make3, make4, make5
212        };
213
214        canvas->translate(SkIntToScalar(20), SkIntToScalar(80));
215
216        SkRect bounds = SkRect::MakeWH(SkIntToScalar(50), SkIntToScalar(50));
217        SkScalar dx = bounds.width() * 4/3;
218        SkScalar dy = bounds.height() * 5;
219
220        for (size_t i = 0; i < SK_ARRAY_COUNT(procs); ++i) {
221            SkPath orig;
222            SkString str;
223            procs[i](&orig, bounds, &str);
224
225            canvas->save();
226            for (int j = 0; j < 13; ++j) {
227                strokePaint.setStrokeWidth(SK_Scalar1 * j * j);
228                canvas->drawPath(orig, strokePaint);
229                canvas->drawPath(orig, origPaint);
230                SkPath fill;
231                strokePaint.getFillPath(orig, &fill);
232                canvas->drawPath(fill, fillPaint);
233                canvas->translate(dx + strokePaint.getStrokeWidth(), 0);
234            }
235            canvas->restore();
236            canvas->translate(0, dy);
237        }
238    }
239
240private:
241    typedef skiagm::GM INHERITED;
242};
243
244//////////////////////////////////////////////////////////////////////////////
245
246static skiagm::GM* F0(void*) { return new StrokesGM; }
247static skiagm::GM* F1(void*) { return new Strokes2GM; }
248static skiagm::GM* F2(void*) { return new Strokes3GM; }
249
250static skiagm::GMRegistry R0(F0);
251static skiagm::GMRegistry R1(F1);
252static skiagm::GMRegistry R2(F2);
253