1 #include "SampleCode.h" 2 #include "SkView.h" 3 #include "SkCanvas.h" 4 #include "Sk64.h" 5 #include "SkCornerPathEffect.h" 6 #include "SkGradientShader.h" 7 #include "SkGraphics.h" 8 #include "SkImageDecoder.h" 9 #include "SkKernel33MaskFilter.h" 10 #include "SkPath.h" 11 #include "SkRandom.h" 12 #include "SkRegion.h" 13 #include "SkShader.h" 14 #include "SkUtils.h" 15 #include "SkColorPriv.h" 16 #include "SkColorFilter.h" 17 #include "SkTime.h" 18 #include "SkTypeface.h" 19 #include "SkXfermode.h" 20 21 #include "SkStream.h" 22 #include "SkXMLParser.h" 23 #include "SkColorPriv.h" 24 #include "SkImageDecoder.h" 25 26 static void setNamedTypeface(SkPaint* paint, const char name[]) { 27 SkTypeface* face = SkTypeface::CreateFromName(name, SkTypeface::kNormal); 28 paint->setTypeface(face); 29 SkSafeUnref(face); 30 } 31 32 #if 0 33 static int newscale(U8CPU a, U8CPU b, int shift) { 34 unsigned prod = a * b + (1 << (shift - 1)); 35 return (prod + (prod >> shift)) >> shift; 36 } 37 38 static void test_srcover565(SkCanvas* canvas) { 39 const int width = 32; 40 SkBitmap bm1, bm2, bm3; 41 bm1.setConfig(SkBitmap::kRGB_565_Config, width, 256); bm1.allocPixels(NULL); 42 bm2.setConfig(SkBitmap::kRGB_565_Config, width, 256); bm2.allocPixels(NULL); 43 bm3.setConfig(SkBitmap::kRGB_565_Config, width, 256); bm3.allocPixels(NULL); 44 45 int rgb = 0x18; 46 int r = rgb >> 3; 47 int g = rgb >> 2; 48 uint16_t dst = SkPackRGB16(r, g, r); 49 for (int alpha = 0; alpha <= 255; alpha++) { 50 SkPMColor pm = SkPreMultiplyARGB(alpha, rgb, rgb, rgb); 51 uint16_t newdst = SkSrcOver32To16(pm, dst); 52 sk_memset16(bm1.getAddr16(0, alpha), newdst, bm1.width()); 53 54 int ia = 255 - alpha; 55 int iscale = SkAlpha255To256(ia); 56 int dr = (SkGetPackedR32(pm) + (r * iscale >> 5)) >> 3; 57 int dg = (SkGetPackedG32(pm) + (g * iscale >> 6)) >> 2; 58 59 sk_memset16(bm2.getAddr16(0, alpha), SkPackRGB16(dr, dg, dr), bm2.width()); 60 61 int dr2 = (SkMulDiv255Round(alpha, rgb) + newscale(r, ia, 5)) >> 3; 62 int dg2 = (SkMulDiv255Round(alpha, rgb) + newscale(g, ia, 6)) >> 2; 63 64 sk_memset16(bm3.getAddr16(0, alpha), SkPackRGB16(dr2, dg2, dr2), bm3.width()); 65 66 // if (mr != dr || mg != dg) 67 { 68 // SkDebugf("[%d] macro [%d %d] inline [%d %d] new [%d %d]\n", alpha, mr, mg, dr, dg, dr2, dg2); 69 } 70 } 71 72 SkScalar dx = SkIntToScalar(width+4); 73 74 canvas->drawBitmap(bm1, 0, 0, NULL); canvas->translate(dx, 0); 75 canvas->drawBitmap(bm2, 0, 0, NULL); canvas->translate(dx, 0); 76 canvas->drawBitmap(bm3, 0, 0, NULL); canvas->translate(dx, 0); 77 78 SkRect rect = { 0, 0, SkIntToScalar(bm1.width()), SkIntToScalar(bm1.height()) }; 79 SkPaint p; 80 p.setARGB(0xFF, rgb, rgb, rgb); 81 canvas->drawRect(rect, p); 82 } 83 #endif 84 85 static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) { 86 src->setConfig(SkBitmap::kARGB_8888_Config, w, h); 87 src->allocPixels(); 88 src->eraseColor(0); 89 90 SkCanvas c(*src); 91 SkPaint p; 92 SkRect r; 93 SkScalar ww = SkIntToScalar(w); 94 SkScalar hh = SkIntToScalar(h); 95 96 p.setAntiAlias(true); 97 p.setColor(0xFFFFCC44); 98 r.set(0, 0, ww*3/4, hh*3/4); 99 c.drawOval(r, p); 100 101 dst->setConfig(SkBitmap::kARGB_8888_Config, w, h); 102 dst->allocPixels(); 103 dst->eraseColor(0); 104 c.setBitmapDevice(*dst); 105 106 p.setColor(0xFF66AAFF); 107 r.set(ww/3, hh/3, ww*19/20, hh*19/20); 108 c.drawRect(r, p); 109 } 110 111 static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF }; 112 113 class XfermodesView : public SampleView { 114 SkBitmap fBG; 115 SkBitmap fSrcB, fDstB; 116 117 void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha, 118 SkScalar x, SkScalar y) { 119 SkPaint p; 120 121 canvas->drawBitmap(fSrcB, x, y, &p); 122 p.setAlpha(alpha); 123 p.setXfermode(mode); 124 canvas->drawBitmap(fDstB, x, y, &p); 125 } 126 127 public: 128 const static int W = 64; 129 const static int H = 64; 130 XfermodesView() { 131 const int W = 64; 132 const int H = 64; 133 134 fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4); 135 fBG.setPixels(gBG); 136 fBG.setIsOpaque(true); 137 138 make_bitmaps(W, H, &fSrcB, &fDstB); 139 } 140 141 protected: 142 // overrides from SkEventSink 143 virtual bool onQuery(SkEvent* evt) { 144 if (SampleCode::TitleQ(*evt)) { 145 SampleCode::TitleR(evt, "Xfermodes"); 146 return true; 147 } 148 return this->INHERITED::onQuery(evt); 149 } 150 151 virtual void onDrawContent(SkCanvas* canvas) { 152 canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); 153 154 const struct { 155 SkXfermode::Mode fMode; 156 const char* fLabel; 157 } gModes[] = { 158 { SkXfermode::kClear_Mode, "Clear" }, 159 { SkXfermode::kSrc_Mode, "Src" }, 160 { SkXfermode::kDst_Mode, "Dst" }, 161 { SkXfermode::kSrcOver_Mode, "SrcOver" }, 162 { SkXfermode::kDstOver_Mode, "DstOver" }, 163 { SkXfermode::kSrcIn_Mode, "SrcIn" }, 164 { SkXfermode::kDstIn_Mode, "DstIn" }, 165 { SkXfermode::kSrcOut_Mode, "SrcOut" }, 166 { SkXfermode::kDstOut_Mode, "DstOut" }, 167 { SkXfermode::kSrcATop_Mode, "SrcATop" }, 168 { SkXfermode::kDstATop_Mode, "DstATop" }, 169 { SkXfermode::kXor_Mode, "Xor" }, 170 171 { SkXfermode::kPlus_Mode, "Plus" }, 172 { SkXfermode::kMultiply_Mode, "Multiply" }, 173 { SkXfermode::kScreen_Mode, "Screen" }, 174 { SkXfermode::kOverlay_Mode, "Overlay" }, 175 { SkXfermode::kDarken_Mode, "Darken" }, 176 { SkXfermode::kLighten_Mode, "Lighten" }, 177 { SkXfermode::kColorDodge_Mode, "ColorDodge" }, 178 { SkXfermode::kColorBurn_Mode, "ColorBurn" }, 179 { SkXfermode::kHardLight_Mode, "HardLight" }, 180 { SkXfermode::kSoftLight_Mode, "SoftLight" }, 181 { SkXfermode::kDifference_Mode, "Difference" }, 182 { SkXfermode::kExclusion_Mode, "Exclusion" }, 183 }; 184 185 const SkScalar w = SkIntToScalar(W); 186 const SkScalar h = SkIntToScalar(H); 187 SkShader* s = SkShader::CreateBitmapShader(fBG, 188 SkShader::kRepeat_TileMode, 189 SkShader::kRepeat_TileMode); 190 SkMatrix m; 191 m.setScale(SkIntToScalar(6), SkIntToScalar(6)); 192 s->setLocalMatrix(m); 193 194 SkPaint labelP; 195 labelP.setAntiAlias(true); 196 labelP.setLCDRenderText(true); 197 labelP.setTextAlign(SkPaint::kCenter_Align); 198 setNamedTypeface(&labelP, "Menlo Regular"); 199 // labelP.setTextSize(SkIntToScalar(11)); 200 201 const int W = 5; 202 203 SkScalar x0 = 0; 204 for (int twice = 0; twice < 2; twice++) { 205 SkScalar x = x0, y = 0; 206 for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) { 207 SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); 208 SkAutoUnref aur(mode); 209 SkRect r; 210 r.set(x, y, x+w, y+h); 211 212 SkPaint p; 213 p.setStyle(SkPaint::kFill_Style); 214 p.setShader(s); 215 canvas->drawRect(r, p); 216 217 canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); 218 // canvas->save(); 219 draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop); 220 canvas->restore(); 221 222 r.inset(-SK_ScalarHalf, -SK_ScalarHalf); 223 p.setStyle(SkPaint::kStroke_Style); 224 p.setShader(NULL); 225 canvas->drawRect(r, p); 226 227 #if 1 228 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel), 229 x + w/2, y - labelP.getTextSize()/2, labelP); 230 #endif 231 x += w + SkIntToScalar(10); 232 if ((i % W) == W - 1) { 233 x = x0; 234 y += h + SkIntToScalar(30); 235 } 236 } 237 x0 += SkIntToScalar(400); 238 } 239 s->unref(); 240 } 241 242 private: 243 typedef SampleView INHERITED; 244 }; 245 246 ////////////////////////////////////////////////////////////////////////////// 247 248 static SkView* MyFactory() { return new XfermodesView; } 249 static SkViewRegister reg(MyFactory); 250 251