1 /*
2 * Copyright 2012 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
8 #include "gm.h"
9 #include "sk_tool_utils.h"
10 #include "SkColorFilter.h"
11 #include "SkGradientShader.h"
12
13 #define WIDTH 512
14 #define HEIGHT 1024
15
16 namespace skiagm {
17
18 // Using gradients because GPU doesn't currently have an implementation of SkColorShader (duh!)
make_color_shader(SkColor color)19 static sk_sp<SkShader> make_color_shader(SkColor color) {
20 constexpr SkPoint kPts[] = {{0, 0}, {1, 1}};
21 SkColor colors[] = {color, color};
22
23 return SkGradientShader::MakeLinear(kPts, colors, nullptr, 2, SkShader::kClamp_TileMode);
24 }
25
make_solid_shader()26 static sk_sp<SkShader> make_solid_shader() {
27 return make_color_shader(SkColorSetARGB(0xFF, 0x42, 0x82, 0x21));
28 }
29
make_transparent_shader()30 static sk_sp<SkShader> make_transparent_shader() {
31 return make_color_shader(SkColorSetARGB(0x80, 0x10, 0x70, 0x20));
32 }
33
make_trans_black_shader()34 static sk_sp<SkShader> make_trans_black_shader() {
35 return make_color_shader(0x0);
36 }
37
38 // draws a background behind each test rect to see transparency
make_bg_shader(int checkSize)39 static sk_sp<SkShader> make_bg_shader(int checkSize) {
40 SkBitmap bmp;
41 bmp.allocN32Pixels(2 * checkSize, 2 * checkSize);
42 SkCanvas canvas(bmp);
43 canvas.clear(sk_tool_utils::color_to_565(0xFF800000));
44 SkPaint paint;
45 paint.setColor(sk_tool_utils::color_to_565(0xFF000080));
46 SkRect rect0 = SkRect::MakeXYWH(0, 0,
47 SkIntToScalar(checkSize), SkIntToScalar(checkSize));
48 SkRect rect1 = SkRect::MakeXYWH(SkIntToScalar(checkSize), SkIntToScalar(checkSize),
49 SkIntToScalar(checkSize), SkIntToScalar(checkSize));
50 canvas.drawRect(rect1, paint);
51 canvas.drawRect(rect0, paint);
52 return SkShader::MakeBitmapShader(bmp, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
53 }
54
55 class ModeColorFilterGM : public GM {
56 public:
ModeColorFilterGM()57 ModeColorFilterGM() {
58 this->setBGColor(sk_tool_utils::color_to_565(0xFF303030));
59 }
60
61 protected:
onShortName()62 SkString onShortName() override {
63 return SkString("modecolorfilters");
64 }
65
onISize()66 SkISize onISize() override {
67 return SkISize::Make(WIDTH, HEIGHT);
68 }
69
onDraw(SkCanvas * canvas)70 void onDraw(SkCanvas* canvas) override {
71 // size of rect for each test case
72 constexpr int kRectWidth = 20;
73 constexpr int kRectHeight = 20;
74
75 constexpr int kCheckSize = 10;
76
77 if (!fBmpShader) {
78 fBmpShader = make_bg_shader(kCheckSize);
79 }
80 SkPaint bgPaint;
81 bgPaint.setShader(fBmpShader);
82 bgPaint.setBlendMode(SkBlendMode::kSrc);
83
84 sk_sp<SkShader> shaders[] = {
85 nullptr, // use a paint color instead of a shader
86 make_solid_shader(),
87 make_transparent_shader(),
88 make_trans_black_shader(),
89 };
90
91 // used without shader
92 SkColor colors[] = {
93 SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF),
94 SkColorSetARGB(0xFF, 0x00, 0x00, 0x00),
95 SkColorSetARGB(0x00, 0x00, 0x00, 0x00),
96 SkColorSetARGB(0xFF, 0x10, 0x20, 0x42),
97 SkColorSetARGB(0xA0, 0x20, 0x30, 0x90),
98 };
99
100 // used with shaders
101 SkColor alphas[] = {0xFFFFFFFF, 0x80808080};
102
103 const SkBlendMode modes[] = { // currently just doing the Modes expressible as Coeffs
104 SkBlendMode::kClear,
105 SkBlendMode::kSrc,
106 SkBlendMode::kDst,
107 SkBlendMode::kSrcOver,
108 SkBlendMode::kDstOver,
109 SkBlendMode::kSrcIn,
110 SkBlendMode::kDstIn,
111 SkBlendMode::kSrcOut,
112 SkBlendMode::kDstOut,
113 SkBlendMode::kSrcATop,
114 SkBlendMode::kDstATop,
115 SkBlendMode::kXor,
116 SkBlendMode::kPlus,
117 SkBlendMode::kModulate,
118 };
119
120 SkPaint paint;
121 int idx = 0;
122 const int kRectsPerRow = SkMax32(this->getISize().fWidth / kRectWidth, 1);
123 for (size_t cfm = 0; cfm < SK_ARRAY_COUNT(modes); ++cfm) {
124 for (size_t cfc = 0; cfc < SK_ARRAY_COUNT(colors); ++cfc) {
125 paint.setColorFilter(SkColorFilter::MakeModeFilter(colors[cfc], modes[cfm]));
126 for (size_t s = 0; s < SK_ARRAY_COUNT(shaders); ++s) {
127 paint.setShader(shaders[s]);
128 bool hasShader = nullptr == paint.getShader();
129 int paintColorCnt = hasShader ? SK_ARRAY_COUNT(alphas) : SK_ARRAY_COUNT(colors);
130 SkColor* paintColors = hasShader ? alphas : colors;
131 for (int pc = 0; pc < paintColorCnt; ++pc) {
132 paint.setColor(paintColors[pc]);
133 SkScalar x = SkIntToScalar(idx % kRectsPerRow);
134 SkScalar y = SkIntToScalar(idx / kRectsPerRow);
135 SkRect rect = SkRect::MakeXYWH(x * kRectWidth, y * kRectHeight,
136 SkIntToScalar(kRectWidth),
137 SkIntToScalar(kRectHeight));
138 canvas->saveLayer(&rect, nullptr);
139 canvas->drawRect(rect, bgPaint);
140 canvas->drawRect(rect, paint);
141 canvas->restore();
142 ++idx;
143 }
144 }
145 }
146 }
147 }
148
149 private:
150 sk_sp<SkShader> fBmpShader;
151 typedef GM INHERITED;
152 };
153
154 //////////////////////////////////////////////////////////////////////////////
155
MyFactory(void *)156 static GM* MyFactory(void*) { return new ModeColorFilterGM; }
157 static GMRegistry reg(MyFactory);
158
159 }
160