xfermodes2.cpp revision cbbdab5513ee013af0f590cf8aad09634c90c7aa
1
2/*
3 * Copyright 2013 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 "gm.h"
9#include "SkBitmap.h"
10#include "SkShader.h"
11#include "SkXfermode.h"
12#include "SkColorPriv.h"
13
14namespace skiagm {
15
16class Xfermodes2GM : public GM {
17public:
18    Xfermodes2GM() {}
19
20protected:
21    virtual SkString onShortName() SK_OVERRIDE {
22        return SkString("xfermodes2");
23    }
24
25    virtual SkISize onISize() SK_OVERRIDE {
26        return make_isize(455, 475);
27    }
28
29    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
30        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
31
32        const SkScalar w = SkIntToScalar(kSize);
33        const SkScalar h = SkIntToScalar(kSize);
34
35        SkPaint labelP;
36        labelP.setAntiAlias(true);
37        labelP.setTextAlign(SkPaint::kCenter_Align);
38
39        const int W = 6;
40
41        SkScalar x = 0, y = 0;
42        for (size_t m = 0; m <= SkXfermode::kLastMode; m++) {
43            SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(m);
44            SkXfermode* xm = SkXfermode::Create(mode);
45            SkAutoUnref aur(xm);
46
47            canvas->save();
48
49            canvas->translate(x, y);
50            SkPaint p;
51            p.setAntiAlias(false);
52            p.setStyle(SkPaint::kFill_Style);
53            p.setShader(fBG);
54            SkRect r = SkRect::MakeWH(w, h);
55            canvas->drawRect(r, p);
56
57            canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
58
59            p.setShader(fDst);
60            canvas->drawRect(r, p);
61            p.setShader(fSrc);
62            p.setXfermode(xm);
63            canvas->drawRect(r, p);
64
65            canvas->restore();
66
67            r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
68            p.setStyle(SkPaint::kStroke_Style);
69            p.setShader(NULL);
70            p.setXfermode(NULL);
71            canvas->drawRect(r, p);
72
73            canvas->restore();
74
75#if 1
76            canvas->drawText(SkXfermode::ModeName(mode), strlen(SkXfermode::ModeName(mode)),
77                             x + w/2, y - labelP.getTextSize()/2, labelP);
78#endif
79            x += w + SkIntToScalar(10);
80            if ((m % W) == W - 1) {
81                x = 0;
82                y += h + SkIntToScalar(30);
83            }
84        }
85    }
86
87private:
88    virtual void onOnceBeforeDraw() SK_OVERRIDE {
89        const uint32_t kCheckData[] = {
90            SkPackARGB32(0xFF, 0x40, 0x40, 0x40),
91            SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0),
92            SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0),
93            SkPackARGB32(0xFF, 0x40, 0x40, 0x40)
94        };
95        SkBitmap bg;
96        bg.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
97        bg.allocPixels();
98        SkAutoLockPixels bgAlp(bg);
99        memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData));
100        bg.setIsOpaque(true);
101
102        fBG.reset(SkShader::CreateBitmapShader(bg,
103                                               SkShader::kRepeat_TileMode,
104                                               SkShader::kRepeat_TileMode));
105        SkMatrix lm;
106        lm.setScale(SkIntToScalar(16), SkIntToScalar(16));
107        fBG->setLocalMatrix(lm);
108
109        SkBitmap dstBmp;
110        dstBmp.setConfig(SkBitmap::kARGB_8888_Config, kSize, kSize);
111        dstBmp.allocPixels();
112        SkAutoLockPixels dstAlp(dstBmp);
113        SkPMColor* pixels = reinterpret_cast<SkPMColor*>(dstBmp.getPixels());
114
115        for (int y = 0; y < kSize; ++y) {
116            int c = y * (1 << kShift);
117            SkPMColor rowColor = SkPackARGB32(c, c, 0, c/2);
118            for (int x = 0; x < kSize; ++x) {
119                pixels[kSize * y + x] = rowColor;
120            }
121        }
122        fSrc.reset(SkShader::CreateBitmapShader(dstBmp,
123                                                SkShader::kClamp_TileMode,
124                                                SkShader::kClamp_TileMode));
125        SkBitmap srcBmp;
126        srcBmp.setConfig(SkBitmap::kARGB_8888_Config, kSize, kSize);
127        srcBmp.allocPixels();
128        SkAutoLockPixels srcAlp(srcBmp);
129        pixels = reinterpret_cast<SkPMColor*>(srcBmp.getPixels());
130
131        for (int x = 0; x < kSize; ++x) {
132            int c = x * (1 << kShift);
133            SkPMColor colColor = SkPackARGB32(c, 0, c, c/2);
134            for (int y = 0; y < kSize; ++y) {
135                pixels[kSize * y + x] = colColor;
136            }
137        }
138        fDst.reset(SkShader::CreateBitmapShader(srcBmp,
139                                                SkShader::kClamp_TileMode,
140                                                SkShader::kClamp_TileMode));
141    }
142
143    enum {
144        kShift = 2,
145        kSize = 256 >> kShift,
146    };
147
148    SkAutoTUnref<SkShader> fBG;
149    SkAutoTUnref<SkShader> fSrc;
150    SkAutoTUnref<SkShader> fDst;
151
152    typedef GM INHERITED;
153};
154
155//////////////////////////////////////////////////////////////////////////////
156
157static GM* MyFactory(void*) { return new Xfermodes2GM; }
158static GMRegistry reg(MyFactory);
159
160}
161