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 "SkDevice.h"
12#include "SkColorPriv.h"
13#include "SkShader.h"
14
15static const struct {
16    SkXfermode::Mode  fMode;
17    const char*         fLabel;
18} gModes[] = {
19    { SkXfermode::kClear_Mode,    "Clear"     },
20    { SkXfermode::kSrc_Mode,      "Src"       },
21    { SkXfermode::kDst_Mode,      "Dst"       },
22    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
23    { SkXfermode::kDstOver_Mode,  "DstOver"   },
24    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
25    { SkXfermode::kDstIn_Mode,    "DstIn"     },
26    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
27    { SkXfermode::kDstOut_Mode,   "DstOut"    },
28    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
29    { SkXfermode::kDstATop_Mode,  "DstATop"   },
30    { SkXfermode::kXor_Mode,      "Xor"       },
31};
32
33const int gWidth = 64;
34const int gHeight = 64;
35const SkScalar W = SkIntToScalar(gWidth);
36const SkScalar H = SkIntToScalar(gHeight);
37
38static SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode,
39                         SkAlpha a0, SkAlpha a1) {
40
41    SkPaint paint;
42    paint.setAntiAlias(true);
43
44    SkRect r = SkRect::MakeWH(W, H);
45    r.inset(W/10, H/10);
46
47    paint.setColor(SK_ColorBLUE);
48    paint.setAlpha(a0);
49    canvas->drawOval(r, paint);
50
51    paint.setColor(SK_ColorRED);
52    paint.setAlpha(a1);
53    paint.setXfermode(mode);
54
55    SkScalar offset = SK_Scalar1 / 3;
56    SkRect rect = SkRect::MakeXYWH(W / 4 + offset,
57                                   H / 4 + offset,
58                                   W / 2, H / 2);
59    canvas->drawRect(rect, paint);
60
61    return H;
62}
63
64static SkShader* make_bg_shader() {
65    SkBitmap bm;
66    bm.allocN32Pixels(2, 2);
67    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
68    *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC,
69                                                             0xCC, 0xCC);
70
71    SkMatrix m;
72    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
73
74    return SkShader::CreateBitmapShader(bm,
75                                        SkShader::kRepeat_TileMode,
76                                        SkShader::kRepeat_TileMode,
77                                        &m);
78}
79
80class AARectsModesView : public SampleView {
81    SkPaint fBGPaint;
82public:
83    AARectsModesView () {
84        fBGPaint.setShader(make_bg_shader())->unref();
85    }
86
87protected:
88    // overrides from SkEventSink
89    virtual bool onQuery(SkEvent* evt) {
90        if (SampleCode::TitleQ(*evt)) {
91            SampleCode::TitleR(evt, "AARectsModes");
92            return true;
93        }
94        return this->INHERITED::onQuery(evt);
95    }
96
97    virtual void onDrawContent(SkCanvas* canvas) {
98        const SkRect bounds = SkRect::MakeWH(W, H);
99        static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
100
101        canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
102
103        for (int alpha = 0; alpha < 4; ++alpha) {
104            canvas->save();
105            canvas->save();
106            for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
107                if (6 == i) {
108                    canvas->restore();
109                    canvas->translate(W * 5, 0);
110                    canvas->save();
111                }
112                SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
113
114                canvas->drawRect(bounds, fBGPaint);
115                canvas->saveLayer(&bounds, NULL);
116                SkScalar dy = drawCell(canvas, mode,
117                                       gAlphaValue[alpha & 1],
118                                       gAlphaValue[alpha & 2]);
119                canvas->restore();
120
121                canvas->translate(0, dy * 5 / 4);
122                SkSafeUnref(mode);
123            }
124            canvas->restore();
125            canvas->restore();
126            canvas->translate(W * 5 / 4, 0);
127        }
128    }
129
130private:
131    typedef SampleView INHERITED;
132};
133
134///////////////////////////////////////////////////////////////////////////////
135
136static SkView* MyFactory() { return new AARectsModesView; }
137static SkViewRegister reg(MyFactory);
138