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