/* * 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 "SkBitmap.h" #include "SkShader.h" #include "SkXfermode.h" #include "SkColorPriv.h" namespace skiagm { class Xfermodes2GM : public GM { public: Xfermodes2GM() {} protected: virtual SkString onShortName() SK_OVERRIDE { return SkString("xfermodes2"); } virtual SkISize onISize() SK_OVERRIDE { return make_isize(455, 475); } virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); const SkScalar w = SkIntToScalar(kSize); const SkScalar h = SkIntToScalar(kSize); SkPaint labelP; labelP.setAntiAlias(true); labelP.setTextAlign(SkPaint::kCenter_Align); const int W = 6; SkScalar x = 0, y = 0; for (size_t m = 0; m <= SkXfermode::kLastMode; m++) { SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(m); SkXfermode* xm = SkXfermode::Create(mode); SkAutoUnref aur(xm); canvas->save(); canvas->translate(x, y); SkPaint p; p.setAntiAlias(false); p.setStyle(SkPaint::kFill_Style); p.setShader(fBG); SkRect r = SkRect::MakeWH(w, h); canvas->drawRect(r, p); canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); p.setShader(fDst); canvas->drawRect(r, p); p.setShader(fSrc); p.setXfermode(xm); canvas->drawRect(r, p); canvas->restore(); r.inset(-SK_ScalarHalf, -SK_ScalarHalf); p.setStyle(SkPaint::kStroke_Style); p.setShader(NULL); p.setXfermode(NULL); canvas->drawRect(r, p); canvas->restore(); #if 1 canvas->drawText(SkXfermode::ModeName(mode), strlen(SkXfermode::ModeName(mode)), x + w/2, y - labelP.getTextSize()/2, labelP); #endif x += w + SkIntToScalar(10); if ((m % W) == W - 1) { x = 0; y += h + SkIntToScalar(30); } } } private: virtual void onOnceBeforeDraw() SK_OVERRIDE { static const uint32_t kCheckData[] = { SkPackARGB32(0xFF, 0x40, 0x40, 0x40), SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0), SkPackARGB32(0xFF, 0xD0, 0xD0, 0xD0), SkPackARGB32(0xFF, 0x40, 0x40, 0x40) }; SkBitmap bg; bg.setConfig(SkBitmap::kARGB_8888_Config, 2, 2, 0, kOpaque_SkAlphaType); bg.allocPixels(); SkAutoLockPixels bgAlp(bg); memcpy(bg.getPixels(), kCheckData, sizeof(kCheckData)); fBG.reset(SkShader::CreateBitmapShader(bg, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode)); SkMatrix lm; lm.setScale(SkIntToScalar(16), SkIntToScalar(16)); fBG->setLocalMatrix(lm); SkBitmap dstBmp; dstBmp.setConfig(SkBitmap::kARGB_8888_Config, kSize, kSize); dstBmp.allocPixels(); SkAutoLockPixels dstAlp(dstBmp); SkPMColor* pixels = reinterpret_cast<SkPMColor*>(dstBmp.getPixels()); for (int y = 0; y < kSize; ++y) { int c = y * (1 << kShift); SkPMColor rowColor = SkPackARGB32(c, c, 0, c/2); for (int x = 0; x < kSize; ++x) { pixels[kSize * y + x] = rowColor; } } fSrc.reset(SkShader::CreateBitmapShader(dstBmp, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)); SkBitmap srcBmp; srcBmp.setConfig(SkBitmap::kARGB_8888_Config, kSize, kSize); srcBmp.allocPixels(); SkAutoLockPixels srcAlp(srcBmp); pixels = reinterpret_cast<SkPMColor*>(srcBmp.getPixels()); for (int x = 0; x < kSize; ++x) { int c = x * (1 << kShift); SkPMColor colColor = SkPackARGB32(c, 0, c, c/2); for (int y = 0; y < kSize; ++y) { pixels[kSize * y + x] = colColor; } } fDst.reset(SkShader::CreateBitmapShader(srcBmp, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode)); } enum { kShift = 2, kSize = 256 >> kShift, }; SkAutoTUnref<SkShader> fBG; SkAutoTUnref<SkShader> fSrc; SkAutoTUnref<SkShader> fDst; typedef GM INHERITED; }; ////////////////////////////////////////////////////////////////////////////// static GM* MyFactory(void*) { return new Xfermodes2GM; } static GMRegistry reg(MyFactory); }