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 "SkCanvas.h"
     10 #include "SkColorMatrixFilter.h"
     11 #include "SkColorPriv.h"
     12 #include "SkShader.h"
     13 
     14 #include "SkBlurImageFilter.h"
     15 #include "SkColorFilterImageFilter.h"
     16 
     17 #define FILTER_WIDTH    SkIntToScalar(30)
     18 #define FILTER_HEIGHT   SkIntToScalar(30)
     19 #define MARGIN          SkIntToScalar(10)
     20 
     21 static SkColorFilter* cf_make_brightness(float brightness) {
     22     SkScalar amount255 = SkScalarMul(brightness, SkIntToScalar(255));
     23     SkScalar matrix[20] = {
     24         1, 0, 0, 0, amount255,
     25         0, 1, 0, 0, amount255,
     26         0, 0, 1, 0, amount255,
     27         0, 0, 0, 1, 0 };
     28     return SkColorMatrixFilter::Create(matrix);
     29 }
     30 
     31 static SkColorFilter* cf_make_grayscale() {
     32     SkScalar matrix[20];
     33     memset(matrix, 0, 20 * sizeof(SkScalar));
     34     matrix[0] = matrix[5] = matrix[10] = 0.2126f;
     35     matrix[1] = matrix[6] = matrix[11] = 0.7152f;
     36     matrix[2] = matrix[7] = matrix[12] = 0.0722f;
     37     matrix[18] = 1.0f;
     38     return SkColorMatrixFilter::Create(matrix);
     39 }
     40 
     41 static SkColorFilter* cf_make_colorize(SkColor color) {
     42     return SkColorFilter::CreateModeFilter(color, SkXfermode::kSrc_Mode);
     43 }
     44 
     45 static void sk_gm_get_colorfilters(SkTDArray<SkColorFilter*>* array) {
     46     *array->append() = cf_make_brightness(0.5f);
     47     *array->append() = cf_make_grayscale();
     48     *array->append() = cf_make_colorize(SK_ColorBLUE);
     49 }
     50 
     51 ///////////////////////////////////////////////////////////////////////////////////////////////////
     52 #include "SkGradientShader.h"
     53 #include "SkImage.h"
     54 #include "Resources.h"
     55 
     56 static SkShader* sh_make_lineargradient0() {
     57     const SkPoint pts[] = { { 0, 0 }, { 100, 100 } };
     58     const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
     59     return SkGradientShader::CreateLinear(pts, colors, nullptr, 3, SkShader::kRepeat_TileMode);
     60 }
     61 
     62 static SkShader* sh_make_lineargradient1() {
     63     const SkPoint pts[] = { { 0, 0 }, { 100, 100 } };
     64     const SkColor colors[] = { SK_ColorRED, 0x0000FF00, SK_ColorBLUE };
     65     return SkGradientShader::CreateLinear(pts, colors, nullptr, 3, SkShader::kRepeat_TileMode);
     66 }
     67 
     68 static SkShader* sh_make_image() {
     69     SkAutoTUnref<SkImage> image(GetResourceAsImage("mandrill_128.png"));
     70     if (!image) {
     71         return nullptr;
     72     }
     73     return image->newShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
     74 }
     75 
     76 static void sk_gm_get_shaders(SkTDArray<SkShader*>* array) {
     77     if (SkShader* shader = sh_make_lineargradient0()) {
     78         *array->append() = shader;
     79     }
     80     if (SkShader* shader = sh_make_lineargradient1()) {
     81         *array->append() = shader;
     82     }
     83     if (SkShader* shader = sh_make_image()) {
     84         *array->append() = shader;
     85     }
     86 }
     87 
     88 ///////////////////////////////////////////////////////////////////////////////////////////////////
     89 
     90 static SkImageFilter* make_blur(float amount, SkImageFilter* input = nullptr) {
     91     return SkBlurImageFilter::Create(amount, amount, input);
     92 }
     93 
     94 static SkImageFilter* make_brightness(float amount, SkImageFilter* input = nullptr) {
     95     SkAutoTUnref<SkColorFilter> filter(cf_make_brightness(amount));
     96     return SkColorFilterImageFilter::Create(filter, input);
     97 }
     98 
     99 static SkImageFilter* make_grayscale(SkImageFilter* input = nullptr) {
    100     SkAutoTUnref<SkColorFilter> filter(cf_make_grayscale());
    101     return SkColorFilterImageFilter::Create(filter, input);
    102 }
    103 
    104 static SkImageFilter* make_mode_blue(SkImageFilter* input = nullptr) {
    105     SkAutoTUnref<SkColorFilter> filter(cf_make_colorize(SK_ColorBLUE));
    106     return SkColorFilterImageFilter::Create(filter, input);
    107 }
    108 
    109 static void drawClippedRect(SkCanvas* canvas,
    110                             const SkRect& r,
    111                             const SkPaint& paint,
    112                             float outset = 0.0f) {
    113         canvas->save();
    114         SkRect clip(r);
    115         clip.outset(outset, outset);
    116         canvas->clipRect(clip);
    117         canvas->drawRect(r, paint);
    118         canvas->restore();
    119 }
    120 
    121 DEF_SIMPLE_GM(colorfilterimagefilter, canvas, 400, 100){
    122         SkRect r = SkRect::MakeWH(FILTER_WIDTH, FILTER_HEIGHT);
    123         SkPaint paint;
    124         paint.setColor(SK_ColorRED);
    125         canvas->save();
    126         for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.2f) {
    127             SkAutoTUnref<SkImageFilter> dim(make_brightness(-brightness));
    128             SkAutoTUnref<SkImageFilter> bright(make_brightness(brightness, dim));
    129             paint.setImageFilter(bright);
    130             drawClippedRect(canvas, r, paint);
    131             canvas->translate(FILTER_WIDTH + MARGIN, 0);
    132         }
    133         canvas->restore();
    134         canvas->translate(0, FILTER_HEIGHT + MARGIN);
    135         {
    136             SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f));
    137             SkAutoTUnref<SkImageFilter> grayscale(make_grayscale(brightness));
    138             paint.setImageFilter(grayscale);
    139             drawClippedRect(canvas, r, paint);
    140             canvas->translate(FILTER_WIDTH + MARGIN, 0);
    141         }
    142         {
    143             SkAutoTUnref<SkImageFilter> grayscale(make_grayscale());
    144             SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.9f, grayscale));
    145             paint.setImageFilter(brightness);
    146             drawClippedRect(canvas, r, paint);
    147             canvas->translate(FILTER_WIDTH + MARGIN, 0);
    148         }
    149         {
    150             SkAutoTUnref<SkImageFilter> blue(make_mode_blue());
    151             SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f, blue));
    152             paint.setImageFilter(brightness);
    153             drawClippedRect(canvas, r, paint);
    154             canvas->translate(FILTER_WIDTH + MARGIN, 0);
    155         }
    156         {
    157             SkAutoTUnref<SkImageFilter> brightness(make_brightness(1.0f));
    158             SkAutoTUnref<SkImageFilter> blue(make_mode_blue(brightness));
    159             paint.setImageFilter(blue);
    160             drawClippedRect(canvas, r, paint);
    161             canvas->translate(FILTER_WIDTH + MARGIN, 0);
    162         }
    163         {
    164             SkAutoTUnref<SkImageFilter> blur(make_blur(3.0f));
    165             SkAutoTUnref<SkImageFilter> brightness(make_brightness(0.5f, blur));
    166             paint.setImageFilter(brightness);
    167             drawClippedRect(canvas, r, paint, 3);
    168             canvas->translate(FILTER_WIDTH + MARGIN, 0);
    169         }
    170         {
    171             SkAutoTUnref<SkImageFilter> blue(make_mode_blue());
    172             paint.setImageFilter(blue.get());
    173             drawClippedRect(canvas, r, paint, 5);
    174             canvas->translate(FILTER_WIDTH + MARGIN, 0);
    175         }
    176 }
    177 
    178 DEF_SIMPLE_GM(colorfilterimagefilter_layer, canvas, 32, 32) {
    179     SkAutoCanvasRestore autoCanvasRestore(canvas, false);
    180     SkColorMatrix cm;
    181     cm.setSaturation(0.0f);
    182     SkAutoTUnref<SkColorFilter> cf(SkColorMatrixFilter::Create(cm));
    183     SkAutoTUnref<SkImageFilter> imf(SkColorFilterImageFilter::Create(cf));
    184     SkPaint p;
    185     p.setImageFilter(imf);
    186     canvas->saveLayer(NULL, &p);
    187     canvas->clear(SK_ColorRED);
    188 }
    189 
    190 ///////////////////////////////////////////////////////////////////////////////////////////////////
    191 
    192 template <typename T> class SkTRefArray : public SkTDArray<T> {
    193 public:
    194     ~SkTRefArray() { this->unrefAll(); }
    195 };
    196 
    197 DEF_SIMPLE_GM(colorfiltershader, canvas, 800, 800) {
    198     SkTRefArray<SkColorFilter*> filters;
    199     sk_gm_get_colorfilters(&filters);
    200 
    201     SkTRefArray<SkShader*> shaders;
    202     sk_gm_get_shaders(&shaders);
    203 
    204     SkPaint paint;
    205     SkRect r = SkRect::MakeWH(120, 120);
    206 
    207     canvas->translate(20, 20);
    208     for (int y = 0; y < shaders.count(); ++y) {
    209         SkShader* shader = shaders[y];
    210 
    211         canvas->save();
    212         for (int x = -1; x < filters.count(); ++x) {
    213             SkColorFilter* filter = x >= 0 ? filters[x] : nullptr;
    214 
    215             paint.setShader(shader->newWithColorFilter(filter))->unref();
    216             canvas->drawRect(r, paint);
    217             canvas->translate(150, 0);
    218         }
    219         canvas->restore();
    220         canvas->translate(0, 150);
    221     }
    222 }
    223