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!) 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 26 static sk_sp<SkShader> make_solid_shader() { 27 return make_color_shader(SkColorSetARGB(0xFF, 0x42, 0x82, 0x21)); 28 } 29 30 static sk_sp<SkShader> make_transparent_shader() { 31 return make_color_shader(SkColorSetARGB(0x80, 0x10, 0x70, 0x20)); 32 } 33 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 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: 57 ModeColorFilterGM() { 58 this->setBGColor(sk_tool_utils::color_to_565(0xFF303030)); 59 } 60 61 protected: 62 SkString onShortName() override { 63 return SkString("modecolorfilters"); 64 } 65 66 SkISize onISize() override { 67 return SkISize::Make(WIDTH, HEIGHT); 68 } 69 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 156 static GM* MyFactory(void*) { return new ModeColorFilterGM; } 157 static GMRegistry reg(MyFactory); 158 159 } 160