1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "gm.h" 9 #include "SkBitmap.h" 10 #include "SkShader.h" 11 #include "SkXfermode.h" 12 13 namespace skiagm { 14 15 static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) { 16 src->setConfig(SkBitmap::kARGB_8888_Config, w, h); 17 src->allocPixels(); 18 src->eraseColor(0); 19 20 SkCanvas c(*src); 21 SkPaint p; 22 SkRect r; 23 SkScalar ww = SkIntToScalar(w); 24 SkScalar hh = SkIntToScalar(h); 25 26 p.setAntiAlias(true); 27 p.setColor(0xFFFFCC44); 28 r.set(0, 0, ww*3/4, hh*3/4); 29 c.drawOval(r, p); 30 31 dst->setConfig(SkBitmap::kARGB_8888_Config, w, h); 32 dst->allocPixels(); 33 dst->eraseColor(0); 34 c.setBitmapDevice(*dst); 35 36 p.setColor(0xFF66AAFF); 37 r.set(ww/3, hh/3, ww*19/20, hh*19/20); 38 c.drawRect(r, p); 39 } 40 41 class XfermodesGM : public GM { 42 SkBitmap fBG; 43 SkBitmap fSrcB, fDstB; 44 bool fOnce; 45 46 void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha, 47 SkScalar x, SkScalar y) { 48 SkPaint p; 49 50 canvas->drawBitmap(fSrcB, x, y, &p); 51 p.setAlpha(alpha); 52 p.setXfermode(mode); 53 canvas->drawBitmap(fDstB, x, y, &p); 54 } 55 56 void init() { 57 if (!fOnce) { 58 // Do all this work in a temporary so we get a deep copy 59 uint16_t localData[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF }; 60 SkBitmap scratchBitmap; 61 scratchBitmap.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4); 62 scratchBitmap.setPixels(localData); 63 scratchBitmap.setIsOpaque(true); 64 scratchBitmap.copyTo(&fBG, SkBitmap::kARGB_4444_Config); 65 66 make_bitmaps(W, H, &fSrcB, &fDstB); 67 fOnce = true; 68 } 69 } 70 71 public: 72 const static int W = 64; 73 const static int H = 64; 74 XfermodesGM() : fOnce(false) {} 75 76 protected: 77 virtual SkString onShortName() { 78 return SkString("xfermodes"); 79 } 80 81 virtual SkISize onISize() { 82 return make_isize(790, 640); 83 } 84 85 virtual void onDraw(SkCanvas* canvas) { 86 this->init(); 87 88 canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); 89 90 const struct { 91 SkXfermode::Mode fMode; 92 const char* fLabel; 93 } gModes[] = { 94 { SkXfermode::kClear_Mode, "Clear" }, 95 { SkXfermode::kSrc_Mode, "Src" }, 96 { SkXfermode::kDst_Mode, "Dst" }, 97 { SkXfermode::kSrcOver_Mode, "SrcOver" }, 98 { SkXfermode::kDstOver_Mode, "DstOver" }, 99 { SkXfermode::kSrcIn_Mode, "SrcIn" }, 100 { SkXfermode::kDstIn_Mode, "DstIn" }, 101 { SkXfermode::kSrcOut_Mode, "SrcOut" }, 102 { SkXfermode::kDstOut_Mode, "DstOut" }, 103 { SkXfermode::kSrcATop_Mode, "SrcATop" }, 104 { SkXfermode::kDstATop_Mode, "DstATop" }, 105 { SkXfermode::kXor_Mode, "Xor" }, 106 107 { SkXfermode::kPlus_Mode, "Plus" }, 108 { SkXfermode::kMultiply_Mode, "Multiply" }, 109 { SkXfermode::kScreen_Mode, "Screen" }, 110 { SkXfermode::kOverlay_Mode, "Overlay" }, 111 { SkXfermode::kDarken_Mode, "Darken" }, 112 { SkXfermode::kLighten_Mode, "Lighten" }, 113 { SkXfermode::kColorDodge_Mode, "ColorDodge" }, 114 { SkXfermode::kColorBurn_Mode, "ColorBurn" }, 115 { SkXfermode::kHardLight_Mode, "HardLight" }, 116 { SkXfermode::kSoftLight_Mode, "SoftLight" }, 117 { SkXfermode::kDifference_Mode, "Difference" }, 118 { SkXfermode::kExclusion_Mode, "Exclusion" }, 119 }; 120 121 const SkScalar w = SkIntToScalar(W); 122 const SkScalar h = SkIntToScalar(H); 123 SkShader* s = SkShader::CreateBitmapShader(fBG, 124 SkShader::kRepeat_TileMode, 125 SkShader::kRepeat_TileMode); 126 SkMatrix m; 127 m.setScale(SkIntToScalar(6), SkIntToScalar(6)); 128 s->setLocalMatrix(m); 129 130 SkPaint labelP; 131 labelP.setAntiAlias(true); 132 labelP.setTextAlign(SkPaint::kCenter_Align); 133 134 const int W = 5; 135 136 SkScalar x0 = 0; 137 for (int twice = 0; twice < 2; twice++) { 138 SkScalar x = x0, y = 0; 139 for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) { 140 SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); 141 SkAutoUnref aur(mode); 142 SkRect r; 143 r.set(x, y, x+w, y+h); 144 145 SkPaint p; 146 p.setStyle(SkPaint::kFill_Style); 147 p.setShader(s); 148 canvas->drawRect(r, p); 149 150 canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); 151 draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop); 152 canvas->restore(); 153 154 r.inset(-SK_ScalarHalf, -SK_ScalarHalf); 155 p.setStyle(SkPaint::kStroke_Style); 156 p.setShader(NULL); 157 canvas->drawRect(r, p); 158 159 #if 1 160 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel), 161 x + w/2, y - labelP.getTextSize()/2, labelP); 162 #endif 163 x += w + SkIntToScalar(10); 164 if ((i % W) == W - 1) { 165 x = x0; 166 y += h + SkIntToScalar(30); 167 } 168 } 169 x0 += SkIntToScalar(400); 170 } 171 s->unref(); 172 } 173 174 private: 175 typedef GM INHERITED; 176 }; 177 178 ////////////////////////////////////////////////////////////////////////////// 179 180 static GM* MyFactory(void*) { return new XfermodesGM; } 181 static GMRegistry reg(MyFactory); 182 183 } 184