|  | /* | 
|  | * Copyright 2013 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 "SkGradientShader.h" | 
|  | #include "SkLumaColorFilter.h" | 
|  |  | 
|  | static SkScalar kSize   = 80; | 
|  | static SkScalar kInset  = 10; | 
|  | static SkColor  kColor1 = SkColorSetARGB(0xff, 0xff, 0xff, 0); | 
|  | static SkColor  kColor2 = SkColorSetARGB(0xff, 0x80, 0xff, 0); | 
|  |  | 
|  | static void draw_label(SkCanvas* canvas, const char* label, | 
|  | const SkPoint& offset) { | 
|  | SkPaint paint; | 
|  | size_t len = strlen(label); | 
|  |  | 
|  | SkScalar width = paint.measureText(label, len); | 
|  | canvas->drawText(label, len, offset.x() - width / 2, offset.y(), | 
|  | paint); | 
|  | } | 
|  |  | 
|  | static void draw_scene(SkCanvas* canvas, SkColorFilter* filter, | 
|  | SkXfermode::Mode mode, SkShader* s1, | 
|  | SkShader* s2) { | 
|  | SkPaint paint; | 
|  | paint.setAntiAlias(true); | 
|  | SkRect r, c, bounds = SkRect::MakeWH(kSize, kSize); | 
|  |  | 
|  | c = bounds; | 
|  | c.fRight = bounds.centerX(); | 
|  | paint.setARGB(0x20, 0, 0, 0xff); | 
|  | canvas->drawRect(bounds, paint); | 
|  |  | 
|  | canvas->saveLayer(&bounds, NULL); | 
|  |  | 
|  | r = bounds; | 
|  | r.inset(kInset, 0); | 
|  | paint.setShader(s1); | 
|  | paint.setColor(s1 ? SK_ColorBLACK : SkColorSetA(kColor1, 0x80)); | 
|  | canvas->drawOval(r, paint); | 
|  | if (!s1) { | 
|  | canvas->save(); | 
|  | canvas->clipRect(c); | 
|  | paint.setColor(kColor1); | 
|  | canvas->drawOval(r, paint); | 
|  | canvas->restore(); | 
|  | } | 
|  |  | 
|  | SkPaint xferPaint; | 
|  | xferPaint.setXfermodeMode(mode); | 
|  | canvas->saveLayer(&bounds, &xferPaint); | 
|  |  | 
|  | r = bounds; | 
|  | r.inset(0, kInset); | 
|  | paint.setShader(s2); | 
|  | paint.setColor(s2 ? SK_ColorBLACK : SkColorSetA(kColor2, 0x80)); | 
|  | paint.setColorFilter(filter); | 
|  | canvas->drawOval(r, paint); | 
|  | if (!s2) { | 
|  | canvas->save(); | 
|  | canvas->clipRect(c); | 
|  | paint.setColor(kColor2); | 
|  | canvas->drawOval(r, paint); | 
|  | canvas->restore(); | 
|  | } | 
|  |  | 
|  | canvas->restore(); | 
|  | canvas->restore(); | 
|  | } | 
|  |  | 
|  | class LumaFilterGM : public skiagm::GM { | 
|  | public: | 
|  | LumaFilterGM() { | 
|  | SkColor  g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) }; | 
|  | SkColor  g2Colors[] = { kColor2, SkColorSetA(kColor2, 0x20) }; | 
|  | SkPoint  g1Points[] = { { 0, 0 }, { 0,     100 } }; | 
|  | SkPoint  g2Points[] = { { 0, 0 }, { kSize, 0   } }; | 
|  | SkScalar pos[] = { 0.2f, 1.0f }; | 
|  |  | 
|  | fFilter.reset(SkLumaColorFilter::Create()); | 
|  | fGr1.reset(SkGradientShader::CreateLinear(g1Points, | 
|  | g1Colors, | 
|  | pos, | 
|  | SK_ARRAY_COUNT(g1Colors), | 
|  | SkShader::kClamp_TileMode)); | 
|  | fGr2.reset(SkGradientShader::CreateLinear(g2Points, | 
|  | g2Colors, | 
|  | pos, | 
|  | SK_ARRAY_COUNT(g2Colors), | 
|  | SkShader::kClamp_TileMode)); | 
|  | } | 
|  |  | 
|  | protected: | 
|  | virtual uint32_t onGetFlags() const SK_OVERRIDE { | 
|  | return kSkipTiled_Flag; | 
|  | } | 
|  |  | 
|  | virtual SkString onShortName() SK_OVERRIDE { | 
|  | return SkString("lumafilter"); | 
|  | } | 
|  |  | 
|  | virtual SkISize onISize() SK_OVERRIDE { | 
|  | return SkISize::Make(600, 420); | 
|  | } | 
|  |  | 
|  | virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 
|  | SkXfermode::Mode modes[] = { SkXfermode::kSrcOver_Mode, | 
|  | SkXfermode::kDstOver_Mode, | 
|  | SkXfermode::kSrcATop_Mode, | 
|  | SkXfermode::kDstATop_Mode, | 
|  | SkXfermode::kSrcIn_Mode, | 
|  | SkXfermode::kDstIn_Mode, | 
|  | }; | 
|  | struct { | 
|  | SkShader*   fShader1; | 
|  | SkShader*   fShader2; | 
|  | } shaders[] = { | 
|  | { NULL, NULL }, | 
|  | { NULL, fGr2 }, | 
|  | { fGr1, NULL }, | 
|  | { fGr1, fGr2 }, | 
|  | }; | 
|  |  | 
|  | SkScalar gridStep = kSize + 2 * kInset; | 
|  | for (size_t i = 0; i < SK_ARRAY_COUNT(modes); ++i) { | 
|  | draw_label(canvas, SkXfermode::ModeName(modes[i]), | 
|  | SkPoint::Make(gridStep * (0.5f + i), 20)); | 
|  | } | 
|  |  | 
|  | for (size_t i = 0; i < SK_ARRAY_COUNT(shaders); ++i) { | 
|  | canvas->save(); | 
|  | canvas->translate(kInset, gridStep * i + 30); | 
|  | for (size_t m = 0; m < SK_ARRAY_COUNT(modes); ++m) { | 
|  | draw_scene(canvas, fFilter, modes[m], shaders[i].fShader1, | 
|  | shaders[i].fShader2); | 
|  | canvas->translate(gridStep, 0); | 
|  | } | 
|  | canvas->restore(); | 
|  | } | 
|  | } | 
|  |  | 
|  | private: | 
|  | SkAutoTUnref<SkColorFilter> fFilter; | 
|  | SkAutoTUnref<SkShader>      fGr1, fGr2; | 
|  |  | 
|  | typedef skiagm::GM INHERITED; | 
|  | }; | 
|  |  | 
|  | ////////////////////////////////////////////////////////////////////////////// | 
|  |  | 
|  | DEF_GM( return SkNEW(LumaFilterGM); ) |