1/*
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 */
7
8#include "SampleCode.h"
9#include "SkView.h"
10#include "SkCanvas.h"
11#include "SkColorPriv.h"
12#include "SkDevice.h"
13#include "SkPaint.h"
14#include "SkRandom.h"
15
16#define W   150
17#define H   200
18
19static void show_text(SkCanvas* canvas, bool doAA) {
20    SkRandom rand;
21    SkPaint paint;
22    paint.setAntiAlias(doAA);
23    paint.setLCDRenderText(true);
24    paint.setTextSize(SkIntToScalar(20));
25
26    for (int i = 0; i < 200; ++i) {
27        paint.setColor((SK_A32_MASK << SK_A32_SHIFT) | rand.nextU());
28        canvas->drawText("Hamburgefons", 12,
29                         rand.nextSScalar1() * W, rand.nextSScalar1() * H + 20,
30                         paint);
31    }
32}
33
34static bool valid(int i) {
35    return i < 15 && i > 7;
36}
37
38static void show_fill(SkCanvas* canvas, bool doAA) {
39    SkRandom rand;
40    SkPaint paint;
41    paint.setAntiAlias(doAA);
42
43    for (int i = 0; i < 50; ++i) {
44        SkRect r;
45        SkPath p;
46
47        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
48                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
49        paint.setColor(rand.nextU());
50        canvas->drawRect(r, paint);
51
52        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
53                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
54        paint.setColor(rand.nextU());
55        p.addOval(r);
56        canvas->drawPath(p, paint);
57    }
58}
59
60static SkScalar randRange(SkRandom& rand, SkScalar min, SkScalar max) {
61    SkASSERT(min <= max);
62    return min + SkScalarMul(rand.nextUScalar1(), max - min);
63}
64
65static void show_stroke(SkCanvas* canvas, bool doAA, SkScalar strokeWidth, int n) {
66    SkRandom rand;
67    SkPaint paint;
68    paint.setAntiAlias(doAA);
69    paint.setStyle(SkPaint::kStroke_Style);
70    paint.setStrokeWidth(strokeWidth);
71
72    for (int i = 0; i < n; ++i) {
73        SkRect r;
74        SkPath p;
75
76        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
77                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
78        paint.setColor(rand.nextU());
79        canvas->drawRect(r, paint);
80
81        r.setXYWH(rand.nextSScalar1() * W, rand.nextSScalar1() * H,
82                  rand.nextUScalar1() * W, rand.nextUScalar1() * H);
83        paint.setColor(rand.nextU());
84        p.addOval(r);
85        canvas->drawPath(p, paint);
86
87        const SkScalar minx = -SkIntToScalar(W)/4;
88        const SkScalar maxx = 5*SkIntToScalar(W)/4;
89        const SkScalar miny = -SkIntToScalar(H)/4;
90        const SkScalar maxy = 5*SkIntToScalar(H)/4;
91        paint.setColor(rand.nextU());
92        canvas->drawLine(randRange(rand, minx, maxx), randRange(rand, miny, maxy),
93                         randRange(rand, minx, maxx), randRange(rand, miny, maxy),
94                         paint);
95    }
96}
97
98static void show_hair(SkCanvas* canvas, bool doAA) {
99    show_stroke(canvas, doAA, 0, 150);
100}
101
102static void show_thick(SkCanvas* canvas, bool doAA) {
103    show_stroke(canvas, doAA, SkIntToScalar(5), 50);
104}
105
106typedef void (*CanvasProc)(SkCanvas*, bool);
107
108#include "SkAAClip.h"
109
110class ClipView : public SampleView {
111public:
112    ClipView() {
113        SkAAClip clip;
114        SkIRect r = { -2, -3, 842, 18 };
115        clip.setRect(r);
116    }
117
118    virtual ~ClipView() {
119    }
120
121protected:
122    // overrides from SkEventSink
123    virtual bool onQuery(SkEvent* evt) {
124        if (SampleCode::TitleQ(*evt)) {
125            SampleCode::TitleR(evt, "Clip");
126            return true;
127        }
128        return this->INHERITED::onQuery(evt);
129    }
130
131    virtual void onDrawContent(SkCanvas* canvas) {
132        canvas->drawColor(SK_ColorWHITE);
133        canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
134
135        static const CanvasProc gProc[] = {
136            show_text, show_thick, show_hair, show_fill
137        };
138
139        SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
140        SkPath clipPath;
141        r.inset(SK_Scalar1 / 4, SK_Scalar1 / 4);
142        clipPath.addRoundRect(r, SkIntToScalar(20), SkIntToScalar(20));
143
144//        clipPath.toggleInverseFillType();
145
146        for (int aa = 0; aa <= 1; ++aa) {
147            canvas->save();
148            for (size_t i = 0; i < SK_ARRAY_COUNT(gProc); ++i) {
149                canvas->save();
150                canvas->clipPath(clipPath, SkRegion::kIntersect_Op, true);
151//                canvas->drawColor(SK_ColorWHITE);
152                gProc[i](canvas, SkToBool(aa));
153                canvas->restore();
154                canvas->translate(W * SK_Scalar1 * 8 / 7, 0);
155            }
156            canvas->restore();
157            canvas->translate(0, H * SK_Scalar1 * 8 / 7);
158        }
159    }
160
161private:
162    typedef SampleView INHERITED;
163};
164
165//////////////////////////////////////////////////////////////////////////////
166
167static SkView* MyFactory() { return new ClipView; }
168static SkViewRegister reg(MyFactory);
169
170