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 SkISize::Make(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);
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        static 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.allocN32Pixels(2, 2, true);
97        memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData));
98
99        SkMatrix lm;
100        lm.setScale(SkIntToScalar(16), SkIntToScalar(16));
101        fBG.reset(SkShader::CreateBitmapShader(bg,
102                                               SkShader::kRepeat_TileMode,
103                                               SkShader::kRepeat_TileMode,
104                                               &lm));
105
106        SkBitmap dstBmp;
107        dstBmp.allocN32Pixels(kSize, kSize);
108        SkPMColor* pixels = reinterpret_cast<SkPMColor*>(dstBmp.getPixels());
109
110        for (int y = 0; y < kSize; ++y) {
111            int c = y * (1 << kShift);
112            SkPMColor rowColor = SkPackARGB32(c, c, 0, c/2);
113            for (int x = 0; x < kSize; ++x) {
114                pixels[kSize * y + x] = rowColor;
115            }
116        }
117        fSrc.reset(SkShader::CreateBitmapShader(dstBmp,
118                                                SkShader::kClamp_TileMode,
119                                                SkShader::kClamp_TileMode));
120        SkBitmap srcBmp;
121        srcBmp.allocN32Pixels(kSize, kSize);
122        pixels = reinterpret_cast<SkPMColor*>(srcBmp.getPixels());
123
124        for (int x = 0; x < kSize; ++x) {
125            int c = x * (1 << kShift);
126            SkPMColor colColor = SkPackARGB32(c, 0, c, c/2);
127            for (int y = 0; y < kSize; ++y) {
128                pixels[kSize * y + x] = colColor;
129            }
130        }
131        fDst.reset(SkShader::CreateBitmapShader(srcBmp,
132                                                SkShader::kClamp_TileMode,
133                                                SkShader::kClamp_TileMode));
134    }
135
136    enum {
137        kShift = 2,
138        kSize = 256 >> kShift,
139    };
140
141    SkAutoTUnref<SkShader> fBG;
142    SkAutoTUnref<SkShader> fSrc;
143    SkAutoTUnref<SkShader> fDst;
144
145    typedef GM INHERITED;
146};
147
148//////////////////////////////////////////////////////////////////////////////
149
150static GM* MyFactory(void*) { return new Xfermodes2GM; }
151static GMRegistry reg(MyFactory);
152
153}
154