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