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