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