xfermodes2.cpp revision c245574ba3d0e2ade6c94b2812de3baa383bf4c4
1/*
2 * Copyright 2013 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#include "gm.h"
8#include "SkBitmap.h"
9#include "SkShader.h"
10#include "SkXfermode.h"
11#include "SkColorPriv.h"
12
13namespace skiagm {
14
15class Xfermodes2GM : public GM {
16public:
17    Xfermodes2GM() {}
18
19protected:
20    SkString onShortName() override {
21        return SkString("xfermodes2");
22    }
23
24    SkISize onISize() override {
25        return SkISize::Make(455, 475);
26    }
27
28    void onDraw(SkCanvas* canvas) override {
29        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
30
31        const SkScalar w = SkIntToScalar(kSize);
32        const SkScalar h = SkIntToScalar(kSize);
33
34        SkPaint labelP;
35        labelP.setAntiAlias(true);
36        sk_tool_utils::set_portable_typeface(&labelP);
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
45            canvas->save();
46
47            canvas->translate(x, y);
48            SkPaint p;
49            p.setAntiAlias(false);
50            p.setStyle(SkPaint::kFill_Style);
51            p.setShader(fBG);
52            SkRect r = SkRect::MakeWH(w, h);
53            canvas->drawRect(r, p);
54
55            canvas->saveLayer(&r, nullptr);
56
57            p.setShader(fDst);
58            canvas->drawRect(r, p);
59            p.setShader(fSrc);
60            p.setXfermode(SkXfermode::Make(mode));
61            canvas->drawRect(r, p);
62
63            canvas->restore();
64
65            r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
66            p.setStyle(SkPaint::kStroke_Style);
67            p.setShader(nullptr);
68            p.setXfermode(nullptr);
69            canvas->drawRect(r, p);
70
71            canvas->restore();
72
73#if 1
74            canvas->drawText(SkXfermode::ModeName(mode), strlen(SkXfermode::ModeName(mode)),
75                             x + w/2, y - labelP.getTextSize()/2, labelP);
76#endif
77            x += w + SkIntToScalar(10);
78            if ((m % W) == W - 1) {
79                x = 0;
80                y += h + SkIntToScalar(30);
81            }
82        }
83    }
84
85private:
86    void onOnceBeforeDraw() override {
87        const uint32_t kCheckData[] = {
88            SkPackARGB32(0xFF, 0x42, 0x41, 0x42),
89            SkPackARGB32(0xFF, 0xD6, 0xD3, 0xD6),
90            SkPackARGB32(0xFF, 0xD6, 0xD3, 0xD6),
91            SkPackARGB32(0xFF, 0x42, 0x41, 0x42)
92        };
93        SkBitmap bg;
94        bg.allocN32Pixels(2, 2, true);
95        memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData));
96
97        SkMatrix lm;
98        lm.setScale(SkIntToScalar(16), SkIntToScalar(16));
99        fBG = SkShader::MakeBitmapShader(bg, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode,
100                                         &lm);
101
102        SkBitmap srcBmp;
103        srcBmp.allocN32Pixels(kSize, kSize);
104        SkPMColor* pixels = reinterpret_cast<SkPMColor*>(srcBmp.getPixels());
105
106        for (int y = 0; y < kSize; ++y) {
107            int c = y * (1 << kShift);
108            SkPMColor rowColor = SkPackARGB32(c, c, 0, c/2);
109            for (int x = 0; x < kSize; ++x) {
110                pixels[kSize * y + x] = rowColor;
111            }
112        }
113        fSrc = SkShader::MakeBitmapShader(srcBmp, SkShader::kClamp_TileMode,
114                                          SkShader::kClamp_TileMode);
115        SkBitmap dstBmp;
116        dstBmp.allocN32Pixels(kSize, kSize);
117        pixels = reinterpret_cast<SkPMColor*>(dstBmp.getPixels());
118
119        for (int x = 0; x < kSize; ++x) {
120            int c = x * (1 << kShift);
121            SkPMColor colColor = SkPackARGB32(c, 0, c, c/2);
122            for (int y = 0; y < kSize; ++y) {
123                pixels[kSize * y + x] = colColor;
124            }
125        }
126        fDst = SkShader::MakeBitmapShader(dstBmp, SkShader::kClamp_TileMode,
127                                          SkShader::kClamp_TileMode);
128    }
129
130    enum {
131        kShift = 2,
132        kSize = 256 >> kShift,
133    };
134
135    sk_sp<SkShader> fBG;
136    sk_sp<SkShader> fSrc;
137    sk_sp<SkShader> fDst;
138
139    typedef GM INHERITED;
140};
141
142//////////////////////////////////////////////////////////////////////////////
143
144static GM* MyFactory(void*) { return new Xfermodes2GM; }
145static GMRegistry reg(MyFactory);
146
147}
148