Home | History | Annotate | Download | only in gm
      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