• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
getName() const76     SkString getName() const override { return SkString("modecolorfilters"); }
77 
getISize()78     SkISize getISize() override { return SkISize::Make(WIDTH, HEIGHT); }
79 
onDraw(SkCanvas * canvas)80     void onDraw(SkCanvas* canvas) override {
81         // size of rect for each test case
82         constexpr int kRectWidth  = 20;
83         constexpr int kRectHeight = 20;
84 
85         constexpr int kCheckSize  = 10;
86 
87         if (!fBmpShader) {
88             fBmpShader = make_bg_shader(kCheckSize);
89         }
90         SkPaint bgPaint;
91         bgPaint.setShader(fBmpShader);
92         bgPaint.setBlendMode(SkBlendMode::kSrc);
93 
94         sk_sp<SkShader> shaders[] = {
95             nullptr,                                   // use a paint color instead of a shader
96             make_solid_shader(),
97             make_transparent_shader(),
98             make_trans_black_shader(),
99         };
100 
101         // used without shader
102         SkColor colors[] = {
103             SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF),
104             SkColorSetARGB(0xFF, 0x00, 0x00, 0x00),
105             SkColorSetARGB(0x00, 0x00, 0x00, 0x00),
106             SkColorSetARGB(0xFF, 0x10, 0x20, 0x42),
107             SkColorSetARGB(0xA0, 0x20, 0x30, 0x90),
108         };
109 
110         // used with shaders
111         SkColor alphas[] = {0xFFFFFFFF, 0x80808080};
112 
113         const SkBlendMode modes[]  = { // currently just doing the Modes expressible as Coeffs
114             SkBlendMode::kClear,
115             SkBlendMode::kSrc,
116             SkBlendMode::kDst,
117             SkBlendMode::kSrcOver,
118             SkBlendMode::kDstOver,
119             SkBlendMode::kSrcIn,
120             SkBlendMode::kDstIn,
121             SkBlendMode::kSrcOut,
122             SkBlendMode::kDstOut,
123             SkBlendMode::kSrcATop,
124             SkBlendMode::kDstATop,
125             SkBlendMode::kXor,
126             SkBlendMode::kPlus,
127             SkBlendMode::kModulate,
128         };
129 
130         SkPaint paint;
131         int idx = 0;
132         const int kRectsPerRow = std::max(this->getISize().fWidth / kRectWidth, 1);
133         for (size_t cfm = 0; cfm < std::size(modes); ++cfm) {
134             for (size_t cfc = 0; cfc < std::size(colors); ++cfc) {
135                 paint.setColorFilter(SkColorFilters::Blend(colors[cfc], modes[cfm]));
136                 for (size_t s = 0; s < std::size(shaders); ++s) {
137                     paint.setShader(shaders[s]);
138                     bool hasShader = nullptr == paint.getShader();
139                     int paintColorCnt = hasShader ? std::size(alphas) : std::size(colors);
140                     SkColor* paintColors = hasShader ? alphas : colors;
141                     for (int pc = 0; pc < paintColorCnt; ++pc) {
142                         paint.setColor(paintColors[pc]);
143                         SkScalar x = SkIntToScalar(idx % kRectsPerRow);
144                         SkScalar y = SkIntToScalar(idx / kRectsPerRow);
145                         SkRect rect = SkRect::MakeXYWH(x * kRectWidth, y * kRectHeight,
146                                                        SkIntToScalar(kRectWidth),
147                                                        SkIntToScalar(kRectHeight));
148                         canvas->saveLayer(&rect, nullptr);
149                         canvas->drawRect(rect, bgPaint);
150                         canvas->drawRect(rect, paint);
151                         canvas->restore();
152                         ++idx;
153                     }
154                 }
155             }
156         }
157     }
158 
159 private:
160     sk_sp<SkShader> fBmpShader;
161     using INHERITED = GM;
162 };
163 
164 //////////////////////////////////////////////////////////////////////////////
165 
166 DEF_GM( return new ModeColorFilterGM; )
167 
168 }  // namespace skiagm
169