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