xfermodes.cpp revision 8015dd83ae37147bb630d4751030868051ad0cae
1#include "gm.h"
2#include "SkBitmap.h"
3#include "SkShader.h"
4#include "SkXfermode.h"
5
6namespace skiagm {
7
8static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
9    src->setConfig(SkBitmap::kARGB_8888_Config, w, h);
10    src->allocPixels();
11    src->eraseColor(0);
12
13    SkCanvas c(*src);
14    SkPaint p;
15    SkRect r;
16    SkScalar ww = SkIntToScalar(w);
17    SkScalar hh = SkIntToScalar(h);
18
19    p.setAntiAlias(true);
20    p.setColor(0xFFFFCC44);
21    r.set(0, 0, ww*3/4, hh*3/4);
22    c.drawOval(r, p);
23
24    dst->setConfig(SkBitmap::kARGB_8888_Config, w, h);
25    dst->allocPixels();
26    dst->eraseColor(0);
27    c.setBitmapDevice(*dst);
28
29    p.setColor(0xFF66AAFF);
30    r.set(ww/3, hh/3, ww*19/20, hh*19/20);
31    c.drawRect(r, p);
32}
33
34static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
35
36class XfermodesGM : public GM {
37    SkBitmap    fBitmap;
38    SkBitmap    fBG;
39    SkBitmap    fSrcB, fDstB;
40
41    void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha) {
42        SkPaint p;
43
44        canvas->drawBitmap(fSrcB, 0, 0, &p);
45        p.setAlpha(alpha);
46        p.setXfermode(mode);
47        canvas->drawBitmap(fDstB, 0, 0, &p);
48    }
49
50public:
51	XfermodesGM() {
52        const int W = 64;
53        const int H = 64;
54
55        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, W, H);
56        fBitmap.allocPixels();
57
58        fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
59        fBG.setPixels(gBG);
60        fBG.setIsOpaque(true);
61
62        make_bitmaps(W, H, &fSrcB, &fDstB);
63    }
64
65protected:
66    SkString onShortName() {
67        return SkString("xfermodes");
68    }
69
70	SkISize onISize() { return make_isize(400, 250); }
71
72    void drawBG(SkCanvas* canvas) {
73        canvas->drawColor(SK_ColorWHITE);
74        return;
75        SkShader* s = SkShader::CreateBitmapShader(fBG,
76                                                   SkShader::kRepeat_TileMode,
77                                                   SkShader::kRepeat_TileMode);
78        SkPaint p;
79        SkMatrix m;
80
81        p.setShader(s)->unref();
82        m.setScale(SkIntToScalar(8), SkIntToScalar(8));
83        s->setLocalMatrix(m);
84        canvas->drawPaint(p);
85    }
86
87    virtual void onDraw(SkCanvas* canvas) {
88        this->drawBG(canvas);
89
90        const struct {
91            SkPorterDuff::Mode  fMode;
92            const char*         fLabel;
93        } gModes[] = {
94            { SkPorterDuff::kClear_Mode,    "Clear"     },
95            { SkPorterDuff::kSrc_Mode,      "Src"       },
96            { SkPorterDuff::kDst_Mode,      "Dst"       },
97            { SkPorterDuff::kSrcOver_Mode,  "SrcOver"   },
98            { SkPorterDuff::kDstOver_Mode,  "DstOver"   },
99            { SkPorterDuff::kSrcIn_Mode,    "SrcIn"     },
100            { SkPorterDuff::kDstIn_Mode,    "DstIn"     },
101            { SkPorterDuff::kSrcOut_Mode,   "SrcOut"    },
102            { SkPorterDuff::kDstOut_Mode,   "DstOut"    },
103            { SkPorterDuff::kSrcATop_Mode,  "SrcATop"   },
104            { SkPorterDuff::kDstATop_Mode,  "DstATop"   },
105            { SkPorterDuff::kXor_Mode,      "Xor"       },
106            { SkPorterDuff::kDarken_Mode,   "Darken"    },
107            { SkPorterDuff::kLighten_Mode,  "Lighten"   },
108            { SkPorterDuff::kMultiply_Mode, "Multiply"  },
109            { SkPorterDuff::kScreen_Mode,   "Screen"    }
110        };
111
112        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
113
114        SkCanvas c(fBitmap);
115        const SkScalar w = SkIntToScalar(fBitmap.width());
116        const SkScalar h = SkIntToScalar(fBitmap.height());
117        SkShader* s = SkShader::CreateBitmapShader(fBG,
118                                                   SkShader::kRepeat_TileMode,
119                                                   SkShader::kRepeat_TileMode);
120        SkMatrix m;
121        m.setScale(SkIntToScalar(6), SkIntToScalar(6));
122        s->setLocalMatrix(m);
123
124        SkPaint labelP;
125        labelP.setAntiAlias(true);
126        labelP.setTextAlign(SkPaint::kCenter_Align);
127
128        SkScalar x0 = 0;
129        for (int twice = 0; twice < 2; twice++) {
130            SkScalar x = x0, y = 0;
131            for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
132                SkXfermode* mode = SkPorterDuff::CreateXfermode(gModes[i].fMode);
133
134                fBitmap.eraseColor(0);
135                draw_mode(&c, mode, twice ? 0x88 : 0xFF);
136                mode->safeUnref();
137
138                SkPaint p;
139                SkRect r;
140                r.set(x, y, x+w, y+h);
141                r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
142                p.setStyle(SkPaint::kStroke_Style);
143                canvas->drawRect(r, p);
144                p.setStyle(SkPaint::kFill_Style);
145                p.setShader(s);
146                r.inset(SK_ScalarHalf, SK_ScalarHalf);
147                canvas->drawRect(r, p);
148
149                canvas->drawBitmap(fBitmap, x, y, NULL);
150
151#if 1
152                canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
153                                 x + w/2, y - labelP.getTextSize()/2, labelP);
154#endif
155                x += w + SkIntToScalar(10);
156                if ((i & 3) == 3) {
157                    x = x0;
158                    y += h + SkIntToScalar(30);
159                }
160            }
161            x0 += SkIntToScalar(330);
162        }
163        s->unref();
164    }
165
166private:
167    typedef GM INHERITED;
168};
169
170//////////////////////////////////////////////////////////////////////////////
171
172static GM* MyFactory(void*) { return new XfermodesGM; }
173static GMRegistry reg(MyFactory);
174
175}
176
177