1#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkBlurMaskFilter.h"
5#include "SkCamera.h"
6#include "SkColorFilter.h"
7#include "SkColorPriv.h"
8#include "SkDevice.h"
9#include "SkGradientShader.h"
10#include "SkImageDecoder.h"
11#include "SkInterpolator.h"
12#include "SkMaskFilter.h"
13#include "SkPath.h"
14#include "SkRegion.h"
15#include "SkShader.h"
16#include "SkTime.h"
17#include "SkTypeface.h"
18#include "SkUtils.h"
19#include "SkKey.h"
20#include "SkXfermode.h"
21#include "SkDrawFilter.h"
22
23static void make_paint(SkPaint* paint) {
24    SkColor colors[] = { 0, SK_ColorWHITE };
25    SkPoint pts[] = { { 0, 0 }, { 0, SK_Scalar1*20 } };
26    SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
27
28    paint->setShader(s)->unref();
29    paint->setXfermodeMode(SkXfermode::kDstIn_Mode);
30}
31
32static void dump_layers(const char label[], SkCanvas* canvas) {
33    SkDebugf("Dump Layers(%s)\n", label);
34
35    SkCanvas::LayerIter iter(canvas, true);
36    int index = 0;
37    while (!iter.done()) {
38        const SkBitmap& bm = iter.device()->accessBitmap(false);
39        const SkIRect& clip = iter.clip().getBounds();
40        SkDebugf("Layer[%d] bitmap [%d %d] X=%d Y=%d clip=[%d %d %d %d] alpha=%d\n", index++,
41                 bm.width(), bm.height(), iter.x(), iter.y(),
42                 clip.fLeft, clip.fTop, clip.fRight, clip.fBottom,
43                 iter.paint().getAlpha());
44        iter.next();
45    }
46}
47
48// test drawing with strips of fading gradient above and below
49static void test_fade(SkCanvas* canvas) {
50    SkAutoCanvasRestore ar(canvas, true);
51
52    SkRect r;
53
54    SkPaint p;
55    p.setAlpha(0x88);
56
57    SkAutoCanvasRestore(canvas, false);
58
59    // create the layers
60
61    r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
62    canvas->clipRect(r);
63
64    r.fBottom = SkIntToScalar(20);
65    canvas->saveLayer(&r, NULL, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
66
67    r.fTop = SkIntToScalar(80);
68    r.fBottom = SkIntToScalar(100);
69    canvas->saveLayer(&r, NULL, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
70
71    // now draw the "content"
72
73    if (true) {
74        r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
75
76        canvas->saveLayerAlpha(&r, 0x80);
77
78        SkPaint p;
79        p.setColor(SK_ColorRED);
80        p.setAntiAlias(true);
81        canvas->drawOval(r, p);
82
83        dump_layers("inside layer alpha", canvas);
84
85        canvas->restore();
86    } else {
87        r.set(0, 0, SkIntToScalar(100), SkIntToScalar(100));
88
89        SkPaint p;
90        p.setColor(SK_ColorRED);
91        p.setAntiAlias(true);
92        canvas->drawOval(r, p);
93    }
94
95//    return;
96
97    dump_layers("outside layer alpha", canvas);
98
99    // now apply an effect
100
101    SkPaint paint;
102    make_paint(&paint);
103    r.set(0, 0, SkIntToScalar(100), SkIntToScalar(20));
104//    SkDebugf("--------- draw top grad\n");
105    canvas->drawRect(r, paint);
106
107    SkMatrix m;
108    SkShader* s = paint.getShader();
109    m.setScale(SK_Scalar1, -SK_Scalar1);
110    m.postTranslate(0, SkIntToScalar(100));
111    s->setLocalMatrix(m);
112
113    r.fTop = SkIntToScalar(80);
114    r.fBottom = SkIntToScalar(100);
115//    SkDebugf("--------- draw bot grad\n");
116    canvas->drawRect(r, paint);
117}
118
119class RedFilter : public SkDrawFilter {
120public:
121    virtual bool filter(SkCanvas*, SkPaint* p, SkDrawFilter::Type) {
122        fColor = p->getColor();
123        if (fColor == SK_ColorRED) {
124            p->setColor(SK_ColorGREEN);
125        }
126        return true;
127    }
128    virtual void restore(SkCanvas*, SkPaint* p, SkDrawFilter::Type) {
129        p->setColor(fColor);
130    }
131
132private:
133    SkColor fColor;
134};
135
136class LayersView : public SkView {
137public:
138	LayersView() {}
139
140protected:
141    // overrides from SkEventSink
142    virtual bool onQuery(SkEvent* evt) {
143        if (SampleCode::TitleQ(*evt)) {
144            SampleCode::TitleR(evt, "Layers");
145            return true;
146        }
147        return this->INHERITED::onQuery(evt);
148    }
149
150    void drawBG(SkCanvas* canvas) {
151        canvas->drawColor(SK_ColorGRAY);
152    }
153
154    virtual void onDraw(SkCanvas* canvas) {
155        this->drawBG(canvas);
156
157        if (true) {
158            SkRect r;
159			r.set(SkIntToScalar(0), SkIntToScalar(0),
160				  SkIntToScalar(220), SkIntToScalar(120));
161            SkPaint p;
162            canvas->saveLayer(&r, &p);
163            canvas->drawColor(0xFFFF0000);
164            p.setAlpha(0);  // or 0
165            p.setXfermodeMode(SkXfermode::kSrc_Mode);
166            canvas->drawOval(r, p);
167            canvas->restore();
168            return;
169        }
170
171        if (false) {
172            SkRect r;
173			r.set(SkIntToScalar(0), SkIntToScalar(0),
174				  SkIntToScalar(220), SkIntToScalar(120));
175            SkPaint p;
176            p.setAlpha(0x88);
177            p.setAntiAlias(true);
178
179            if (true) {
180                canvas->saveLayer(&r, &p);
181                p.setColor(0xFFFF0000);
182                canvas->drawOval(r, p);
183                canvas->restore();
184            }
185
186            p.setColor(0xFF0000FF);
187            r.offset(SkIntToScalar(20), SkIntToScalar(50));
188            canvas->drawOval(r, p);
189        }
190
191        if (false) {
192            SkPaint p;
193            p.setAlpha(0x88);
194            p.setAntiAlias(true);
195
196            canvas->translate(SkIntToScalar(300), 0);
197
198            SkRect r;
199			r.set(SkIntToScalar(0), SkIntToScalar(0),
200				  SkIntToScalar(220), SkIntToScalar(60));
201
202            canvas->saveLayer(&r, &p, (SkCanvas::SaveFlags)(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag));
203//            canvas->clipRect(r, SkRegion::kDifference_Op);
204//            canvas->clipRect(r, SkRegion::kIntersect_Op);
205
206			r.set(SkIntToScalar(0), SkIntToScalar(0),
207				  SkIntToScalar(220), SkIntToScalar(120));
208            p.setColor(SK_ColorBLUE);
209            canvas->drawOval(r, p);
210            canvas->restore();
211            return;
212        }
213
214        //canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
215        test_fade(canvas);
216        return;
217
218    //    canvas->setDrawFilter(new RedFilter)->unref();
219
220        SkRect  r;
221        SkPaint p;
222
223        canvas->translate(SkIntToScalar(220), SkIntToScalar(20));
224
225        p.setAntiAlias(true);
226        r.set(SkIntToScalar(20), SkIntToScalar(20),
227              SkIntToScalar(220), SkIntToScalar(120));
228
229        p.setColor(SK_ColorBLUE);
230     //   p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(8), SkBlurMaskFilter::kNormal_BlurStyle))->unref();
231        canvas->drawRect(r, p);
232        p.setMaskFilter(NULL);
233
234        SkRect bounds = r;
235        bounds.fBottom = bounds.centerY();
236        canvas->saveLayer(&bounds, NULL, SkCanvas::kARGB_NoClipLayer_SaveFlag);
237
238        p.setColor(SK_ColorRED);
239        canvas->drawOval(r, p);
240
241        p.setAlpha(0x80);
242        p.setXfermodeMode(SkXfermode::kDstIn_Mode);
243        canvas->drawRect(bounds, p);
244
245        canvas->restore();
246    }
247
248    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
249        this->inval(NULL);
250
251        return this->INHERITED::onFindClickHandler(x, y);
252    }
253
254    virtual bool onClick(Click* click) {
255        return this->INHERITED::onClick(click);
256    }
257
258	virtual bool handleKey(SkKey key) {
259        this->inval(NULL);
260        return true;
261    }
262
263private:
264    typedef SkView INHERITED;
265};
266
267//////////////////////////////////////////////////////////////////////////////
268
269static SkView* MyFactory() { return new LayersView; }
270static SkViewRegister reg(MyFactory);
271
272