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