blob: b5361e35a6df7c11d28320f18c872a2987cc63d4 [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"
reed@android.com8a1c16f2008-12-17 15:59:43 +000015#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
reed@google.comf88d6762011-03-10 15:06:27 +000026static void setNamedTypeface(SkPaint* paint, const char name[]) {
27 SkTypeface* face = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
28 paint->setTypeface(face);
29 SkSafeUnref(face);
30}
31
reed@android.comf2b98d62010-12-20 18:26:13 +000032#if 0
reed@android.com8a1c16f2008-12-17 15:59:43 +000033static int newscale(U8CPU a, U8CPU b, int shift) {
34 unsigned prod = a * b + (1 << (shift - 1));
35 return (prod + (prod >> shift)) >> shift;
36}
37
38static 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);
reed@google.comf88d6762011-03-10 15:06:27 +000044
reed@android.com8a1c16f2008-12-17 15:59:43 +000045 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());
reed@google.comf88d6762011-03-10 15:06:27 +000053
reed@android.com8a1c16f2008-12-17 15:59:43 +000054 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;
reed@google.comf88d6762011-03-10 15:06:27 +000063
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 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 }
reed@google.comf88d6762011-03-10 15:06:27 +000071
reed@android.com8a1c16f2008-12-17 15:59:43 +000072 SkScalar dx = SkIntToScalar(width+4);
reed@google.comf88d6762011-03-10 15:06:27 +000073
reed@android.com8a1c16f2008-12-17 15:59:43 +000074 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);
reed@google.comf88d6762011-03-10 15:06:27 +000077
reed@android.com8a1c16f2008-12-17 15:59:43 +000078 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}
reed@android.comf2b98d62010-12-20 18:26:13 +000083#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +000084
reed@google.comf88d6762011-03-10 15:06:27 +000085static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000086 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);
reed@google.comf88d6762011-03-10 15:06:27 +000097 p.setColor(0xFFFFCC44);
reed@android.com8a1c16f2008-12-17 15:59:43 +000098 r.set(0, 0, ww*3/4, hh*3/4);
99 c.drawOval(r, p);
reed@google.comf88d6762011-03-10 15:06:27 +0000100
reed@android.com8a1c16f2008-12-17 15:59:43 +0000101 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
111static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
112
113class XfermodesView : public SkView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000114 SkBitmap fBG;
115 SkBitmap fSrcB, fDstB;
116
reed@android.comf2b98d62010-12-20 18:26:13 +0000117 void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha,
118 SkScalar x, SkScalar y) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119 SkPaint p;
reed@android.comf2b98d62010-12-20 18:26:13 +0000120
reed@google.comf88d6762011-03-10 15:06:27 +0000121 canvas->drawBitmap(fSrcB, x, y, &p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122 p.setAlpha(alpha);
123 p.setXfermode(mode);
reed@android.comf2b98d62010-12-20 18:26:13 +0000124 canvas->drawBitmap(fDstB, x, y, &p);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000125 }
reed@google.comf88d6762011-03-10 15:06:27 +0000126
reed@android.com8a1c16f2008-12-17 15:59:43 +0000127public:
reed@android.comf2b98d62010-12-20 18:26:13 +0000128 const static int W = 64;
129 const static int H = 64;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000130 XfermodesView() {
131 const int W = 64;
132 const int H = 64;
reed@google.comf88d6762011-03-10 15:06:27 +0000133
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
135 fBG.setPixels(gBG);
136 fBG.setIsOpaque(true);
reed@google.comf88d6762011-03-10 15:06:27 +0000137
reed@android.com8a1c16f2008-12-17 15:59:43 +0000138 make_bitmaps(W, H, &fSrcB, &fDstB);
139 }
reed@google.comf88d6762011-03-10 15:06:27 +0000140
reed@android.com8a1c16f2008-12-17 15:59:43 +0000141protected:
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 void drawBG(SkCanvas* canvas) {
152 canvas->drawColor(SK_ColorWHITE);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000153 }
reed@google.comf88d6762011-03-10 15:06:27 +0000154
reed@android.com8a1c16f2008-12-17 15:59:43 +0000155 virtual void onDraw(SkCanvas* canvas) {
reed@android.comf2b98d62010-12-20 18:26:13 +0000156 canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
157
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158 this->drawBG(canvas);
reed@google.comf88d6762011-03-10 15:06:27 +0000159
reed@android.com8a1c16f2008-12-17 15:59:43 +0000160 const struct {
reed@android.coma0f5d152009-06-22 17:38:10 +0000161 SkXfermode::Mode fMode;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000162 const char* fLabel;
163 } gModes[] = {
reed@android.coma0f5d152009-06-22 17:38:10 +0000164 { SkXfermode::kClear_Mode, "Clear" },
165 { SkXfermode::kSrc_Mode, "Src" },
166 { SkXfermode::kDst_Mode, "Dst" },
167 { SkXfermode::kSrcOver_Mode, "SrcOver" },
168 { SkXfermode::kDstOver_Mode, "DstOver" },
169 { SkXfermode::kSrcIn_Mode, "SrcIn" },
170 { SkXfermode::kDstIn_Mode, "DstIn" },
171 { SkXfermode::kSrcOut_Mode, "SrcOut" },
172 { SkXfermode::kDstOut_Mode, "DstOut" },
173 { SkXfermode::kSrcATop_Mode, "SrcATop" },
174 { SkXfermode::kDstATop_Mode, "DstATop" },
175 { SkXfermode::kXor_Mode, "Xor" },
176
177 { SkXfermode::kPlus_Mode, "Plus" },
178 { SkXfermode::kMultiply_Mode, "Multiply" },
179 { SkXfermode::kScreen_Mode, "Screen" },
180 { SkXfermode::kOverlay_Mode, "Overlay" },
181 { SkXfermode::kDarken_Mode, "Darken" },
182 { SkXfermode::kLighten_Mode, "Lighten" },
183 { SkXfermode::kColorDodge_Mode, "ColorDodge" },
184 { SkXfermode::kColorBurn_Mode, "ColorBurn" },
185 { SkXfermode::kHardLight_Mode, "HardLight" },
186 { SkXfermode::kSoftLight_Mode, "SoftLight" },
187 { SkXfermode::kDifference_Mode, "Difference" },
188 { SkXfermode::kExclusion_Mode, "Exclusion" },
reed@android.com8a1c16f2008-12-17 15:59:43 +0000189 };
reed@android.comf2b98d62010-12-20 18:26:13 +0000190
191 const SkScalar w = SkIntToScalar(W);
192 const SkScalar h = SkIntToScalar(H);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000193 SkShader* s = SkShader::CreateBitmapShader(fBG,
194 SkShader::kRepeat_TileMode,
195 SkShader::kRepeat_TileMode);
196 SkMatrix m;
197 m.setScale(SkIntToScalar(6), SkIntToScalar(6));
198 s->setLocalMatrix(m);
reed@google.comf88d6762011-03-10 15:06:27 +0000199
reed@android.com8a1c16f2008-12-17 15:59:43 +0000200 SkPaint labelP;
201 labelP.setAntiAlias(true);
reed@google.comf88d6762011-03-10 15:06:27 +0000202 labelP.setLCDRenderText(true);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000203 labelP.setTextAlign(SkPaint::kCenter_Align);
reed@google.comf88d6762011-03-10 15:06:27 +0000204 setNamedTypeface(&labelP, "Menlo Regular");
205// labelP.setTextSize(SkIntToScalar(11));
206
reed@android.coma0f5d152009-06-22 17:38:10 +0000207 const int W = 5;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000208
209 SkScalar x0 = 0;
210 for (int twice = 0; twice < 2; twice++) {
211 SkScalar x = x0, y = 0;
212 for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
reed@android.coma0f5d152009-06-22 17:38:10 +0000213 SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
reed@android.comf2b98d62010-12-20 18:26:13 +0000214 SkAutoUnref aur(mode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000215 SkRect r;
216 r.set(x, y, x+w, y+h);
reed@android.comf2b98d62010-12-20 18:26:13 +0000217
218 SkPaint p;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000219 p.setStyle(SkPaint::kFill_Style);
220 p.setShader(s);
reed@android.comf2b98d62010-12-20 18:26:13 +0000221 canvas->drawRect(r, p);
reed@google.comf88d6762011-03-10 15:06:27 +0000222
reed@android.comf2b98d62010-12-20 18:26:13 +0000223 canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
224 // canvas->save();
225 draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
226 canvas->restore();
227
228 r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
229 p.setStyle(SkPaint::kStroke_Style);
230 p.setShader(NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000231 canvas->drawRect(r, p);
232
reed@android.comf2b98d62010-12-20 18:26:13 +0000233#if 1
reed@android.com8a1c16f2008-12-17 15:59:43 +0000234 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
235 x + w/2, y - labelP.getTextSize()/2, labelP);
reed@android.comf2b98d62010-12-20 18:26:13 +0000236#endif
reed@android.com8a1c16f2008-12-17 15:59:43 +0000237 x += w + SkIntToScalar(10);
reed@android.coma0f5d152009-06-22 17:38:10 +0000238 if ((i % W) == W - 1) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000239 x = x0;
240 y += h + SkIntToScalar(30);
241 }
242 }
reed@android.coma0f5d152009-06-22 17:38:10 +0000243 x0 += SkIntToScalar(400);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000244 }
245 s->unref();
246 }
247
248private:
249 typedef SkView INHERITED;
250};
251
252//////////////////////////////////////////////////////////////////////////////
253
254static SkView* MyFactory() { return new XfermodesView; }
255static SkViewRegister reg(MyFactory);
256