/* * Copyright 2012 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "gm.h" #include "SkCanvas.h" #include "SkColorMatrixFilter.h" #include "SkColorPriv.h" #include "SkShader.h" #include "SkBlurImageFilter.h" #include "SkColorFilterImageFilter.h" #define FILTER_WIDTH SkIntToScalar(30) #define FILTER_HEIGHT SkIntToScalar(30) #define MARGIN SkIntToScalar(10) static SkColorFilter* cf_make_brightness(float brightness) { SkScalar amount255 = SkScalarMul(brightness, SkIntToScalar(255)); SkScalar matrix[20] = { 1, 0, 0, 0, amount255, 0, 1, 0, 0, amount255, 0, 0, 1, 0, amount255, 0, 0, 0, 1, 0 }; return SkColorMatrixFilter::Create(matrix); } static SkColorFilter* cf_make_grayscale() { SkScalar matrix[20]; memset(matrix, 0, 20 * sizeof(SkScalar)); matrix[0] = matrix[5] = matrix[10] = 0.2126f; matrix[1] = matrix[6] = matrix[11] = 0.7152f; matrix[2] = matrix[7] = matrix[12] = 0.0722f; matrix[18] = 1.0f; return SkColorMatrixFilter::Create(matrix); } static SkColorFilter* cf_make_colorize(SkColor color) { return SkColorFilter::CreateModeFilter(color, SkXfermode::kSrc_Mode); } static void sk_gm_get_colorfilters(SkTDArray* array) { *array->append() = cf_make_brightness(0.5f); *array->append() = cf_make_grayscale(); *array->append() = cf_make_colorize(SK_ColorBLUE); } /////////////////////////////////////////////////////////////////////////////////////////////////// #include "SkGradientShader.h" #include "SkImage.h" #include "Resources.h" static SkShader* sh_make_lineargradient0() { const SkPoint pts[] = { { 0, 0 }, { 100, 100 } }; const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE }; return SkGradientShader::CreateLinear(pts, colors, nullptr, 3, SkShader::kRepeat_TileMode); } static SkShader* sh_make_lineargradient1() { const SkPoint pts[] = { { 0, 0 }, { 100, 100 } }; const SkColor colors[] = { SK_ColorRED, 0x0000FF00, SK_ColorBLUE }; return SkGradientShader::CreateLinear(pts, colors, nullptr, 3, SkShader::kRepeat_TileMode); } static SkShader* sh_make_image() { SkAutoTUnref image(GetResourceAsImage("mandrill_128.png")); if (!image) { return nullptr; } return image->newShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); } static void sk_gm_get_shaders(SkTDArray* array) { if (SkShader* shader = sh_make_lineargradient0()) { *array->append() = shader; } if (SkShader* shader = sh_make_lineargradient1()) { *array->append() = shader; } if (SkShader* shader = sh_make_image()) { *array->append() = shader; } } /////////////////////////////////////////////////////////////////////////////////////////////////// static SkImageFilter* make_blur(float amount, SkImageFilter* input = nullptr) { return SkBlurImageFilter::Create(amount, amount, input); } static SkImageFilter* make_brightness(float amount, SkImageFilter* input = nullptr) { SkAutoTUnref filter(cf_make_brightness(amount)); return SkColorFilterImageFilter::Create(filter, input); } static SkImageFilter* make_grayscale(SkImageFilter* input = nullptr) { SkAutoTUnref filter(cf_make_grayscale()); return SkColorFilterImageFilter::Create(filter, input); } static SkImageFilter* make_mode_blue(SkImageFilter* input = nullptr) { SkAutoTUnref filter(cf_make_colorize(SK_ColorBLUE)); return SkColorFilterImageFilter::Create(filter, input); } static void drawClippedRect(SkCanvas* canvas, const SkRect& r, const SkPaint& paint, float outset = 0.0f) { canvas->save(); SkRect clip(r); clip.outset(outset, outset); canvas->clipRect(clip); canvas->drawRect(r, paint); canvas->restore(); } DEF_SIMPLE_GM(colorfilterimagefilter, canvas, 400, 100){ SkRect r = SkRect::MakeWH(FILTER_WIDTH, FILTER_HEIGHT); SkPaint paint; paint.setColor(SK_ColorRED); canvas->save(); for (float brightness = -1.0f; brightness <= 1.0f; brightness += 0.2f) { SkAutoTUnref dim(make_brightness(-brightness)); SkAutoTUnref bright(make_brightness(brightness, dim)); paint.setImageFilter(bright); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } canvas->restore(); canvas->translate(0, FILTER_HEIGHT + MARGIN); { SkAutoTUnref brightness(make_brightness(0.9f)); SkAutoTUnref grayscale(make_grayscale(brightness)); paint.setImageFilter(grayscale); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref grayscale(make_grayscale()); SkAutoTUnref brightness(make_brightness(0.9f, grayscale)); paint.setImageFilter(brightness); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref blue(make_mode_blue()); SkAutoTUnref brightness(make_brightness(1.0f, blue)); paint.setImageFilter(brightness); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref brightness(make_brightness(1.0f)); SkAutoTUnref blue(make_mode_blue(brightness)); paint.setImageFilter(blue); drawClippedRect(canvas, r, paint); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref blur(make_blur(3.0f)); SkAutoTUnref brightness(make_brightness(0.5f, blur)); paint.setImageFilter(brightness); drawClippedRect(canvas, r, paint, 3); canvas->translate(FILTER_WIDTH + MARGIN, 0); } { SkAutoTUnref blue(make_mode_blue()); paint.setImageFilter(blue.get()); drawClippedRect(canvas, r, paint, 5); canvas->translate(FILTER_WIDTH + MARGIN, 0); } } DEF_SIMPLE_GM(colorfilterimagefilter_layer, canvas, 32, 32) { SkAutoCanvasRestore autoCanvasRestore(canvas, false); SkColorMatrix cm; cm.setSaturation(0.0f); SkAutoTUnref cf(SkColorMatrixFilter::Create(cm)); SkAutoTUnref imf(SkColorFilterImageFilter::Create(cf)); SkPaint p; p.setImageFilter(imf); canvas->saveLayer(NULL, &p); canvas->clear(SK_ColorRED); } /////////////////////////////////////////////////////////////////////////////////////////////////// template class SkTRefArray : public SkTDArray { public: ~SkTRefArray() { this->unrefAll(); } }; DEF_SIMPLE_GM(colorfiltershader, canvas, 800, 800) { SkTRefArray filters; sk_gm_get_colorfilters(&filters); SkTRefArray shaders; sk_gm_get_shaders(&shaders); SkPaint paint; SkRect r = SkRect::MakeWH(120, 120); canvas->translate(20, 20); for (int y = 0; y < shaders.count(); ++y) { SkShader* shader = shaders[y]; canvas->save(); for (int x = -1; x < filters.count(); ++x) { SkColorFilter* filter = x >= 0 ? filters[x] : nullptr; paint.setShader(shader->newWithColorFilter(filter))->unref(); canvas->drawRect(r, paint); canvas->translate(150, 0); } canvas->restore(); canvas->translate(0, 150); } }