11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc. 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */ 8e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed#include "gm.h" 9e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed#include "SkBitmap.h" 10e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed#include "SkShader.h" 11e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed#include "SkXfermode.h" 12e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 13e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reednamespace skiagm { 14e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 1535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenbergerstatic void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) { 16e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed src->setConfig(SkBitmap::kARGB_8888_Config, w, h); 17e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed src->allocPixels(); 18e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed src->eraseColor(0); 19e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 20e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkCanvas c(*src); 21e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkPaint p; 22e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkRect r; 23e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkScalar ww = SkIntToScalar(w); 24e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkScalar hh = SkIntToScalar(h); 25e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 26e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed p.setAntiAlias(true); 2735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger p.setColor(0xFFFFCC44); 28e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed r.set(0, 0, ww*3/4, hh*3/4); 29e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed c.drawOval(r, p); 3035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 31e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed dst->setConfig(SkBitmap::kARGB_8888_Config, w, h); 32e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed dst->allocPixels(); 33e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed dst->eraseColor(0); 34e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed c.setBitmapDevice(*dst); 35e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 36e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed p.setColor(0xFF66AAFF); 37e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed r.set(ww/3, hh/3, ww*19/20, hh*19/20); 38e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed c.drawRect(r, p); 39e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed} 40e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 41e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reedclass XfermodesGM : public GM { 42e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkBitmap fBG; 43e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkBitmap fSrcB, fDstB; 441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger bool fOnce; 45e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 4640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha, 4740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkScalar x, SkScalar y) { 48e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkPaint p; 4935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 5035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger canvas->drawBitmap(fSrcB, x, y, &p); 51e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed p.setAlpha(alpha); 52e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed p.setXfermode(mode); 5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger canvas->drawBitmap(fDstB, x, y, &p); 54e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } 5535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger void init() { 571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger if (!fOnce) { 581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger // Do all this work in a temporary so we get a deep copy 591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger uint16_t localData[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF }; 601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkBitmap scratchBitmap; 611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger scratchBitmap.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4); 621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger scratchBitmap.setPixels(localData); 631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger scratchBitmap.setIsOpaque(true); 641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger scratchBitmap.copyTo(&fBG, SkBitmap::kARGB_4444_Config); 651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger make_bitmaps(W, H, &fSrcB, &fDstB); 671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger fOnce = true; 681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger } 701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 71e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reedpublic: 7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const static int W = 64; 7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const static int H = 64; 741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger XfermodesGM() : fOnce(false) {} 7535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 76e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reedprotected: 77e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed virtual SkString onShortName() { 78e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed return SkString("xfermodes"); 79e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } 80e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 8135e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger virtual SkISize onISize() { 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return make_isize(790, 640); 83e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } 84e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 85e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed virtual void onDraw(SkCanvas* canvas) { 861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger this->init(); 8735e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); 8935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 90e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed const struct { 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkXfermode::Mode fMode; 92e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed const char* fLabel; 93e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } gModes[] = { 94e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kClear_Mode, "Clear" }, 95e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kSrc_Mode, "Src" }, 96e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kDst_Mode, "Dst" }, 97e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kSrcOver_Mode, "SrcOver" }, 98e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kDstOver_Mode, "DstOver" }, 99e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kSrcIn_Mode, "SrcIn" }, 100e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kDstIn_Mode, "DstIn" }, 101e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kSrcOut_Mode, "SrcOut" }, 102e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kDstOut_Mode, "DstOut" }, 103e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kSrcATop_Mode, "SrcATop" }, 104e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kDstATop_Mode, "DstATop" }, 105e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kXor_Mode, "Xor" }, 10635e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 107e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kPlus_Mode, "Plus" }, 108e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kMultiply_Mode, "Multiply" }, 109e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kScreen_Mode, "Screen" }, 110e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kOverlay_Mode, "Overlay" }, 111e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kDarken_Mode, "Darken" }, 112e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kLighten_Mode, "Lighten" }, 113e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kColorDodge_Mode, "ColorDodge" }, 114e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kColorBurn_Mode, "ColorBurn" }, 115e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kHardLight_Mode, "HardLight" }, 116e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kSoftLight_Mode, "SoftLight" }, 117e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kDifference_Mode, "Difference" }, 118e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed { SkXfermode::kExclusion_Mode, "Exclusion" }, 119e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed }; 12035e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkScalar w = SkIntToScalar(W); 12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const SkScalar h = SkIntToScalar(H); 123e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkShader* s = SkShader::CreateBitmapShader(fBG, 124e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkShader::kRepeat_TileMode, 125e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkShader::kRepeat_TileMode); 126e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkMatrix m; 127e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed m.setScale(SkIntToScalar(6), SkIntToScalar(6)); 128e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed s->setLocalMatrix(m); 12935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 130e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkPaint labelP; 131e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed labelP.setAntiAlias(true); 132e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed labelP.setTextAlign(SkPaint::kCenter_Align); 13335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 134e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed const int W = 5; 13535e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 136e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkScalar x0 = 0; 137e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed for (int twice = 0; twice < 2; twice++) { 138e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkScalar x = x0, y = 0; 139e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) { 140e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); 14140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoUnref aur(mode); 142e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed SkRect r; 143e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed r.set(x, y, x+w, y+h); 14435e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 14540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkPaint p; 146e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed p.setStyle(SkPaint::kFill_Style); 147e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed p.setShader(s); 148e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed canvas->drawRect(r, p); 14935e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); 15140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop); 15240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger canvas->restore(); 15335e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger r.inset(-SK_ScalarHalf, -SK_ScalarHalf); 15540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger p.setStyle(SkPaint::kStroke_Style); 15640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger p.setShader(NULL); 15740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger canvas->drawRect(r, p); 15835e2e62b55598210f6999fc2ea26ff8f41446ffeDerek Sollenberger 15940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#if 1 160e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel), 161e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed x + w/2, y - labelP.getTextSize()/2, labelP); 16240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 163e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed x += w + SkIntToScalar(10); 164e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed if ((i % W) == W - 1) { 165e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed x = x0; 166e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed y += h + SkIntToScalar(30); 167e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } 168e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } 169e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed x0 += SkIntToScalar(400); 170e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } 171e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed s->unref(); 172e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed } 173e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 174e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reedprivate: 175e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed typedef GM INHERITED; 176e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed}; 177e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 178e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed////////////////////////////////////////////////////////////////////////////// 179e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 180e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reedstatic GM* MyFactory(void*) { return new XfermodesGM; } 181e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reedstatic GMRegistry reg(MyFactory); 182e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed 183e32706edd70b0f847fe4d124a195cd2927dc8021Mike Reed} 184