From c6126c182882512fce0b40be5f02a521b7e3ee8e Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Fri, 19 Oct 2012 19:26:05 +0000 Subject: [PATCH] Add a GM that tests xfermode-based color filters. Review URL: https://codereview.appspot.com/6736052 git-svn-id: http://skia.googlecode.com/svn/trunk@6022 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/modecolorfilters.cpp | 164 ++++++++++++++++++++++++++++++++++++++++++++++++ gyp/gmslides.gypi | 1 + 2 files changed, 165 insertions(+) create mode 100644 gm/modecolorfilters.cpp diff --git a/gm/modecolorfilters.cpp b/gm/modecolorfilters.cpp new file mode 100644 index 0000000..40e65fc --- /dev/null +++ b/gm/modecolorfilters.cpp @@ -0,0 +1,164 @@ +/* + * 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 "SkBitmapProcShader.h" +#include "SkColorFilter.h" +#include "SkGradientShader.h" + +#define WIDTH 512 +#define HEIGHT 1024 + +namespace skiagm { + +// Using gradients because GPU doesn't currently have an implementation of SkColorShader (duh!) +static SkShader* make_color_shader(SkColor color) { + static const SkPoint kPts[] = {{0, 0}, {1, 1}}; + SkColor colors[] = {color, color}; + + return SkGradientShader::CreateLinear(kPts, colors, NULL, 2, SkShader::kClamp_TileMode); +} + +static SkShader* make_solid_shader() { + return make_color_shader(SkColorSetARGB(0xFF, 0x40, 0x80, 0x20)); +} + +static SkShader* make_transparent_shader() { + return make_color_shader(SkColorSetARGB(0x80, 0x10, 0x70, 0x20)); +} + +static SkShader* make_trans_black_shader() { + return make_color_shader(0x0); +} + +// draws a background behind each test rect to see transparency +static SkShader* make_bg_shader(int checkSize) { + SkBitmap bmp; + bmp.setConfig(SkBitmap::kARGB_8888_Config, 2 * checkSize, 2 * checkSize); + bmp.allocPixels(); + SkCanvas canvas(bmp); + canvas.clear(0xFF800000); + SkPaint paint; + paint.setColor(0xFF000080); + SkRect rect0 = SkRect::MakeXYWH(0, 0, + SkIntToScalar(checkSize), SkIntToScalar(checkSize)); + SkRect rect1 = SkRect::MakeXYWH(SkIntToScalar(checkSize), SkIntToScalar(checkSize), + SkIntToScalar(checkSize), SkIntToScalar(checkSize)); + canvas.drawRect(rect1, paint); + canvas.drawRect(rect0, paint); + return SkNEW_ARGS(SkBitmapProcShader, (bmp, SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode)); +} + +class ModeColorFilterGM : public GM { +public: + ModeColorFilterGM() { + this->setBGColor(0xFF303030); + } + +protected: + virtual SkString onShortName() { + return SkString("modecolorfilters"); + } + + virtual SkISize onISize() { + return make_isize(WIDTH, HEIGHT); + } + + virtual void onDraw(SkCanvas* canvas) { + // size of rect for each test case + static const int kRectWidth = 20; + static const int kRectHeight = 20; + + static const int kCheckSize = 10; + + if (!fBmpShader) { + fBmpShader.reset(make_bg_shader(kCheckSize)); + } + SkPaint bgPaint; + bgPaint.setShader(fBmpShader); + bgPaint.setXfermodeMode(SkXfermode::kSrc_Mode); + + SkShader* shaders[] = { + NULL, // use a paint color instead of a shader + make_solid_shader(), + make_transparent_shader(), + make_trans_black_shader(), + }; + + // used without shader + SkColor colors[] = { + SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF), + SkColorSetARGB(0xFF, 0x00, 0x00, 0x00), + SkColorSetARGB(0x00, 0x00, 0x00, 0x00), + SkColorSetARGB(0xFF, 0x10, 0x20, 0x40), + SkColorSetARGB(0xA0, 0x20, 0x30, 0x90), + }; + + // used with shaders + SkColor alphas[] = {0xFFFFFFFF, 0x80808080}; + + SkXfermode::Mode modes[] = { // currently just doing the Modes expressible as Coeffs + SkXfermode::kClear_Mode, + SkXfermode::kSrc_Mode, + SkXfermode::kDst_Mode, + SkXfermode::kSrcOver_Mode, + SkXfermode::kDstOver_Mode, + SkXfermode::kSrcIn_Mode, + SkXfermode::kDstIn_Mode, + SkXfermode::kSrcOut_Mode, + SkXfermode::kDstOut_Mode, + SkXfermode::kSrcATop_Mode, + SkXfermode::kDstATop_Mode, + SkXfermode::kXor_Mode, + SkXfermode::kPlus_Mode, + SkXfermode::kMultiply_Mode, + }; + + SkPaint paint; + int idx = 0; + static const int kRectsPerRow = SkMax32(this->getISize().fWidth / kRectWidth, 1); + for (size_t cfm = 0; cfm < SK_ARRAY_COUNT(modes); ++cfm) { + for (int cfc = 0; cfc < SK_ARRAY_COUNT(colors); ++cfc) { + SkAutoTUnref cf(SkColorFilter::CreateModeFilter(colors[cfc], + modes[cfm])); + paint.setColorFilter(cf); + for (int s = 0; s < SK_ARRAY_COUNT(shaders); ++s) { + paint.setShader(shaders[s]); + bool hasShader = NULL == paint.getShader(); + int paintColorCnt = hasShader ? SK_ARRAY_COUNT(alphas) : SK_ARRAY_COUNT(colors); + SkColor* paintColors = hasShader ? alphas : colors; + for (int pc = 0; pc < paintColorCnt; ++pc) { + paint.setColor(paintColors[pc]); + SkScalar x = SkIntToScalar(idx % kRectsPerRow); + SkScalar y = SkIntToScalar(idx / kRectsPerRow); + SkRect rect = SkRect::MakeXYWH(x * kRectWidth, y * kRectHeight, + kRectWidth, kRectHeight); + canvas->drawRect(rect, bgPaint); + canvas->drawRect(rect, paint); + ++idx; + } + } + } + } + + for (int i = 0; i < SK_ARRAY_COUNT(shaders); ++i) { + SkSafeUnref(shaders[i]); + } + } + +private: + SkAutoTUnref fBmpShader; + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +static GM* MyFactory(void*) { return new ModeColorFilterGM; } +static GMRegistry reg(MyFactory); + +} diff --git a/gyp/gmslides.gypi b/gyp/gmslides.gypi index 46ec34d..c956150 100644 --- a/gyp/gmslides.gypi +++ b/gyp/gmslides.gypi @@ -48,6 +48,7 @@ '../gm/lcdtext.cpp', '../gm/linepaths.cpp', '../gm/matrixconvolution.cpp', + '../gm/modecolorfilters.cpp', '../gm/morphology.cpp', '../gm/ninepatchstretch.cpp', '../gm/nocolorbleed.cpp', -- 2.7.4