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