• 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 "SkCanvas.h"
10 #include "SkView.h"
11 #include "Sk1DPathEffect.h"
12 #include "Sk2DPathEffect.h"
13 #include "SkAvoidXfermode.h"
14 #include "SkBlurMaskFilter.h"
15 #include "SkColorFilter.h"
16 #include "SkColorPriv.h"
17 #include "SkCornerPathEffect.h"
18 #include "SkDashPathEffect.h"
19 #include "SkDiscretePathEffect.h"
20 #include "SkEmbossMaskFilter.h"
21 #include "SkGradientShader.h"
22 #include "SkImageDecoder.h"
23 #include "SkLayerRasterizer.h"
24 #include "SkMath.h"
25 #include "SkPath.h"
26 #include "SkRegion.h"
27 #include "SkShader.h"
28 #include "SkComposeShader.h"
29 #include "SkCornerPathEffect.h"
30 #include "SkPathMeasure.h"
31 #include "SkPicture.h"
32 #include "SkRandom.h"
33 #include "SkTransparentShader.h"
34 #include "SkTypeface.h"
35 #include "SkUnitMappers.h"
36 #include "SkUtils.h"
37 #include "SkXfermode.h"
38 
39 #include <math.h>
40 
rgb2gray(SkPMColor c)41 static inline SkPMColor rgb2gray(SkPMColor c) {
42     unsigned r = SkGetPackedR32(c);
43     unsigned g = SkGetPackedG32(c);
44     unsigned b = SkGetPackedB32(c);
45 
46     unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
47 
48     return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
49 }
50 
51 class SkGrayScaleColorFilter : public SkColorFilter {
52 public:
filterSpan(const SkPMColor src[],int count,SkPMColor result[])53     virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
54         for (int i = 0; i < count; i++)
55             result[i] = rgb2gray(src[i]);
56     }
57 };
58 
59 class SkChannelMaskColorFilter : public SkColorFilter {
60 public:
SkChannelMaskColorFilter(U8CPU redMask,U8CPU greenMask,U8CPU blueMask)61     SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
62         fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
63     }
64 
filterSpan(const SkPMColor src[],int count,SkPMColor result[])65     virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) {
66         SkPMColor mask = fMask;
67         for (int i = 0; i < count; i++) {
68             result[i] = src[i] & mask;
69         }
70     }
71 
72 private:
73     SkPMColor   fMask;
74 };
75 
76 ///////////////////////////////////////////////////////////
77 
r0(SkLayerRasterizer * rast,SkPaint & p)78 static void r0(SkLayerRasterizer* rast, SkPaint& p) {
79     p.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3),
80                                              SkBlurMaskFilter::kNormal_BlurStyle))->unref();
81     rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
82 
83     p.setMaskFilter(NULL);
84     p.setStyle(SkPaint::kStroke_Style);
85     p.setStrokeWidth(SK_Scalar1);
86     rast->addLayer(p);
87 
88     p.setAlpha(0x11);
89     p.setStyle(SkPaint::kFill_Style);
90     p.setXfermodeMode(SkXfermode::kSrc_Mode);
91     rast->addLayer(p);
92 }
93 
r1(SkLayerRasterizer * rast,SkPaint & p)94 static void r1(SkLayerRasterizer* rast, SkPaint& p) {
95     rast->addLayer(p);
96 
97     p.setAlpha(0x40);
98     p.setXfermodeMode(SkXfermode::kSrc_Mode);
99     p.setStyle(SkPaint::kStroke_Style);
100     p.setStrokeWidth(SK_Scalar1*2);
101     rast->addLayer(p);
102 }
103 
r2(SkLayerRasterizer * rast,SkPaint & p)104 static void r2(SkLayerRasterizer* rast, SkPaint& p) {
105     p.setStyle(SkPaint::kStrokeAndFill_Style);
106     p.setStrokeWidth(SK_Scalar1*4);
107     rast->addLayer(p);
108 
109     p.setStyle(SkPaint::kStroke_Style);
110     p.setStrokeWidth(SK_Scalar1*3/2);
111     p.setXfermodeMode(SkXfermode::kClear_Mode);
112     rast->addLayer(p);
113 }
114 
r3(SkLayerRasterizer * rast,SkPaint & p)115 static void r3(SkLayerRasterizer* rast, SkPaint& p) {
116     p.setStyle(SkPaint::kStroke_Style);
117     p.setStrokeWidth(SK_Scalar1*3);
118     rast->addLayer(p);
119 
120     p.setAlpha(0x20);
121     p.setStyle(SkPaint::kFill_Style);
122     p.setXfermodeMode(SkXfermode::kSrc_Mode);
123     rast->addLayer(p);
124 }
125 
r4(SkLayerRasterizer * rast,SkPaint & p)126 static void r4(SkLayerRasterizer* rast, SkPaint& p) {
127     p.setAlpha(0x60);
128     rast->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
129 
130     p.setAlpha(0xFF);
131     p.setXfermodeMode(SkXfermode::kClear_Mode);
132     rast->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
133 
134     p.setXfermode(NULL);
135     rast->addLayer(p);
136 }
137 
r5(SkLayerRasterizer * rast,SkPaint & p)138 static void r5(SkLayerRasterizer* rast, SkPaint& p) {
139     rast->addLayer(p);
140 
141     p.setPathEffect(new SkDiscretePathEffect(SK_Scalar1*4, SK_Scalar1*3))->unref();
142     p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
143     rast->addLayer(p);
144 }
145 
r6(SkLayerRasterizer * rast,SkPaint & p)146 static void r6(SkLayerRasterizer* rast, SkPaint& p) {
147     rast->addLayer(p);
148 
149     p.setAntiAlias(false);
150     SkLayerRasterizer* rast2 = new SkLayerRasterizer;
151     r5(rast2, p);
152     p.setRasterizer(rast2)->unref();
153     p.setXfermodeMode(SkXfermode::kClear_Mode);
154     rast->addLayer(p);
155 }
156 
157 class Dot2DPathEffect : public Sk2DPathEffect {
158 public:
Dot2DPathEffect(SkScalar radius,const SkMatrix & matrix)159     Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
160         : Sk2DPathEffect(matrix), fRadius(radius) {}
161 
flatten(SkFlattenableWriteBuffer & buffer)162     virtual void flatten(SkFlattenableWriteBuffer& buffer) {
163         this->INHERITED::flatten(buffer);
164 
165         buffer.writeScalar(fRadius);
166     }
getFactory()167     virtual Factory getFactory() { return CreateProc; }
168 
169 protected:
next(const SkPoint & loc,int u,int v,SkPath * dst)170 	virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) {
171         dst->addCircle(loc.fX, loc.fY, fRadius);
172     }
173 
Dot2DPathEffect(SkFlattenableReadBuffer & buffer)174     Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) {
175         fRadius = buffer.readScalar();
176     }
177 private:
178     SkScalar fRadius;
179 
CreateProc(SkFlattenableReadBuffer & buffer)180     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
181         return new Dot2DPathEffect(buffer);
182     }
183 
184     typedef Sk2DPathEffect INHERITED;
185 };
186 
r7(SkLayerRasterizer * rast,SkPaint & p)187 static void r7(SkLayerRasterizer* rast, SkPaint& p) {
188     SkMatrix    lattice;
189     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
190     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
191     p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
192     rast->addLayer(p);
193 }
194 
r8(SkLayerRasterizer * rast,SkPaint & p)195 static void r8(SkLayerRasterizer* rast, SkPaint& p) {
196     rast->addLayer(p);
197 
198     SkMatrix    lattice;
199     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
200     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
201     p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
202     p.setXfermodeMode(SkXfermode::kClear_Mode);
203     rast->addLayer(p);
204 
205     p.setPathEffect(NULL);
206     p.setXfermode(NULL);
207     p.setStyle(SkPaint::kStroke_Style);
208     p.setStrokeWidth(SK_Scalar1);
209     rast->addLayer(p);
210 }
211 
212 class Line2DPathEffect : public Sk2DPathEffect {
213 public:
Line2DPathEffect(SkScalar width,const SkMatrix & matrix)214     Line2DPathEffect(SkScalar width, const SkMatrix& matrix)
215         : Sk2DPathEffect(matrix), fWidth(width) {}
216 
filterPath(SkPath * dst,const SkPath & src,SkScalar * width)217 	virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) {
218         if (this->INHERITED::filterPath(dst, src, width)) {
219             *width = fWidth;
220             return true;
221         }
222         return false;
223     }
224 
getFactory()225     virtual Factory getFactory() { return CreateProc; }
flatten(SkFlattenableWriteBuffer & buffer)226     virtual void flatten(SkFlattenableWriteBuffer& buffer) {
227         this->INHERITED::flatten(buffer);
228         buffer.writeScalar(fWidth);
229     }
230 protected:
nextSpan(int u,int v,int ucount,SkPath * dst)231 	virtual void nextSpan(int u, int v, int ucount, SkPath* dst) {
232         if (ucount > 1) {
233             SkPoint	src[2], dstP[2];
234 
235             src[0].set(SkIntToScalar(u) + SK_ScalarHalf,
236                        SkIntToScalar(v) + SK_ScalarHalf);
237             src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf,
238                        SkIntToScalar(v) + SK_ScalarHalf);
239             this->getMatrix().mapPoints(dstP, src, 2);
240 
241             dst->moveTo(dstP[0]);
242             dst->lineTo(dstP[1]);
243         }
244     }
245 
Line2DPathEffect(SkFlattenableReadBuffer & buffer)246     Line2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) {
247         fWidth = buffer.readScalar();
248     }
249 
250 private:
251     SkScalar fWidth;
252 
CreateProc(SkFlattenableReadBuffer & buffer)253     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return new Line2DPathEffect(buffer); }
254 
255     typedef Sk2DPathEffect INHERITED;
256 };
257 
r9(SkLayerRasterizer * rast,SkPaint & p)258 static void r9(SkLayerRasterizer* rast, SkPaint& p) {
259     rast->addLayer(p);
260 
261     SkMatrix    lattice;
262     lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
263     lattice.postRotate(SkIntToScalar(30), 0, 0);
264     p.setPathEffect(new Line2DPathEffect(SK_Scalar1*2, lattice))->unref();
265     p.setXfermodeMode(SkXfermode::kClear_Mode);
266     rast->addLayer(p);
267 
268     p.setPathEffect(NULL);
269     p.setXfermode(NULL);
270     p.setStyle(SkPaint::kStroke_Style);
271     p.setStrokeWidth(SK_Scalar1);
272     rast->addLayer(p);
273 }
274 
275 typedef void (*raster_proc)(SkLayerRasterizer*, SkPaint&);
276 
277 static const raster_proc gRastProcs[] = {
278     r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
279 };
280 
281 static const struct {
282     SkColor fMul, fAdd;
283 } gLightingColors[] = {
284     { 0x808080, 0x800000 }, // general case
285     { 0x707070, 0x707070 }, // no-pin case
286     { 0xFFFFFF, 0x800000 }, // just-add case
287     { 0x808080, 0x000000 }, // just-mul case
288     { 0xFFFFFF, 0x000000 }  // identity case
289 };
290 
color_dist16(uint16_t a,uint16_t b)291 static unsigned color_dist16(uint16_t a, uint16_t b) {
292     unsigned dr = SkAbs32(SkPacked16ToR32(a) - SkPacked16ToR32(b));
293     unsigned dg = SkAbs32(SkPacked16ToG32(a) - SkPacked16ToG32(b));
294     unsigned db = SkAbs32(SkPacked16ToB32(a) - SkPacked16ToB32(b));
295 
296     return SkMax32(dr, SkMax32(dg, db));
297 }
298 
scale_dist(unsigned dist,unsigned scale)299 static unsigned scale_dist(unsigned dist, unsigned scale) {
300     dist >>= 6;
301     dist = (dist << 2) | dist;
302     dist = (dist << 4) | dist;
303     return dist;
304 
305 //    return SkAlphaMul(dist, scale);
306 }
307 
apply_shader(SkPaint * paint,int index)308 static void apply_shader(SkPaint* paint, int index) {
309     raster_proc proc = gRastProcs[index];
310     if (proc) {
311         SkPaint p;
312         SkLayerRasterizer*  rast = new SkLayerRasterizer;
313 
314         p.setAntiAlias(true);
315         proc(rast, p);
316         paint->setRasterizer(rast)->unref();
317     }
318 
319 #if 1
320     SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
321     paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(dir, SK_Scalar1/4, SkIntToScalar(4), SkIntToScalar(3)))->unref();
322     paint->setColor(SK_ColorBLUE);
323 #endif
324 }
325 
326 class DemoView : public SampleView {
327 public:
DemoView()328     DemoView() {}
329 
330 protected:
331     // overrides from SkEventSink
onQuery(SkEvent * evt)332     virtual bool onQuery(SkEvent* evt) {
333         if (SampleCode::TitleQ(*evt)) {
334             SampleCode::TitleR(evt, "Demo");
335             return true;
336         }
337         return this->INHERITED::onQuery(evt);
338     }
339 
onClick(Click * click)340     virtual bool onClick(Click* click) {
341         return this->INHERITED::onClick(click);
342     }
343 
makePath(SkPath & path)344     void makePath(SkPath& path) {
345         path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
346             SkPath::kCCW_Direction);
347         for (int index = 0; index < 10; index++) {
348             SkScalar x = SkFloatToScalar(cos(index / 10.0f * 2 * 3.1415925358f));
349             SkScalar y = SkFloatToScalar(sin(index / 10.0f * 2 * 3.1415925358f));
350             x *= index & 1 ? 7 : 14;
351             y *= index & 1 ? 7 : 14;
352             x += SkIntToScalar(20);
353             y += SkIntToScalar(20);
354             if (index == 0)
355                 path.moveTo(x, y);
356             else
357                 path.lineTo(x, y);
358         }
359         path.close();
360     }
361 
onDrawContent(SkCanvas * canvas)362     virtual void onDrawContent(SkCanvas* canvas) {
363         canvas->save();
364         drawPicture(canvas, 0);
365         canvas->restore();
366 
367         {
368             SkPicture picture;
369             SkCanvas* record = picture.beginRecording(320, 480);
370             drawPicture(record, 120);
371             canvas->translate(0, SkIntToScalar(120));
372 
373             SkRect clip;
374             clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
375             do {
376                 canvas->save();
377                 canvas->clipRect(clip);
378                 picture.draw(canvas);
379                 canvas->restore();
380                 if (clip.fRight < SkIntToScalar(320))
381                     clip.offset(SkIntToScalar(160), 0);
382                 else if (clip.fBottom < SkIntToScalar(480))
383                     clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
384                 else
385                     break;
386             } while (true);
387         }
388     }
389 
drawPicture(SkCanvas * canvas,int spriteOffset)390     void drawPicture(SkCanvas* canvas, int spriteOffset) {
391 	    SkMatrix matrix; matrix.reset();
392 		SkPaint paint;
393 		SkPath path;
394         SkPoint start = {0, 0};
395         SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
396 		SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
397 		SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
398 		SkScalar left = 0, top = 0, x = 0, y = 0;
399 		size_t index;
400 
401 		char ascii[] = "ascii...";
402 		size_t asciiLength = sizeof(ascii) - 1;
403 		char utf8[] = "utf8" "\xe2\x80\xa6";
404 		short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
405 		short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
406 
407         makePath(path);
408         SkTDArray<SkPoint>(pos);
409 		pos.setCount(asciiLength);
410 		for (index = 0;  index < asciiLength; index++)
411 			pos[index].set(SkIntToScalar(index * 10), SkIntToScalar(index * 2));
412         SkTDArray<SkPoint>(pos2);
413 		pos2.setCount(asciiLength);
414 		for (index = 0;  index < asciiLength; index++)
415 			pos2[index].set(SkIntToScalar(index * 10), SkIntToScalar(20));
416 
417         // shaders
418         SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
419         SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
420         SkScalar* linearPos = NULL;
421         int linearCount = 2;
422         SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
423         SkUnitMapper* linearMapper = new SkDiscreteMapper(3);
424         SkAutoUnref unmapLinearMapper(linearMapper);
425         SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
426             linearColors, linearPos, linearCount, linearMode, linearMapper);
427 
428         SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
429         SkScalar radialRadius = SkIntToScalar(25);
430         SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
431         SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
432         int radialCount = 3;
433         SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
434         SkUnitMapper* radialMapper = new SkCosineMapper();
435         SkAutoUnref unmapRadialMapper(radialMapper);
436         SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
437             radialRadius, radialColors, radialPos, radialCount,
438             radialMode, radialMapper);
439 
440         SkTransparentShader* transparentShader = new SkTransparentShader();
441         SkEmbossMaskFilter::Light light;
442         light.fDirection[0] = SK_Scalar1/2;
443         light.fDirection[1] = SK_Scalar1/2;
444         light.fDirection[2] = SK_Scalar1/3;
445         light.fAmbient		= 0x48;
446         light.fSpecular		= 0x80;
447         SkScalar radius = SkIntToScalar(12)/5;
448         SkEmbossMaskFilter* embossFilter = new SkEmbossMaskFilter(light,
449             radius);
450 
451         SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
452         SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
453             0xff89bc45, 0xff112233);
454 
455         canvas->save();
456 		canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
457 		paint.setFlags(SkPaint::kAntiAlias_Flag | SkPaint::kFilterBitmap_Flag);
458 		// !!! draw through a clip
459 		paint.setColor(SK_ColorLTGRAY);
460 		paint.setStyle(SkPaint::kFill_Style);
461         SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
462         canvas->clipRect(clip);
463         paint.setShader(SkShader::CreateBitmapShader(fTx,
464             SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
465 		canvas->drawPaint(paint);
466 		canvas->save();
467 
468         // line (exercises xfermode, colorShader, colorFilter, filterShader)
469 		paint.setColor(SK_ColorGREEN);
470 		paint.setStrokeWidth(SkIntToScalar(10));
471 		paint.setStyle(SkPaint::kStroke_Style);
472         paint.setXfermode(xfermode)->unref();
473         paint.setColorFilter(lightingFilter)->unref();
474 		canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
475 		paint.setXfermode(NULL);
476         paint.setColorFilter(NULL);
477 
478         // rectangle
479 		paint.setStyle(SkPaint::kFill_Style);
480 		canvas->translate(SkIntToScalar(50), 0);
481 		paint.setColor(SK_ColorYELLOW);
482         paint.setShader(linear)->unref();
483         paint.setPathEffect(pathEffectTest())->unref();
484 		canvas->drawRect(rect, paint);
485         paint.setPathEffect(NULL);
486 
487         // circle w/ emboss & transparent (exercises 3dshader)
488 		canvas->translate(SkIntToScalar(50), 0);
489         paint.setMaskFilter(embossFilter)->unref();
490         canvas->drawOval(rect, paint);
491 		canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
492         paint.setShader(transparentShader)->unref();
493         canvas->drawOval(rect, paint);
494 		canvas->translate(0, SkIntToScalar(-10));
495 
496         // path
497 		canvas->translate(SkIntToScalar(50), 0);
498 		paint.setColor(SK_ColorRED);
499 		paint.setStyle(SkPaint::kStroke_Style);
500 		paint.setStrokeWidth(SkIntToScalar(5));
501         paint.setShader(radial)->unref();
502         paint.setMaskFilter(NULL);
503 		canvas->drawPath(path, paint);
504 
505         paint.setShader(NULL);
506         // bitmap, sprite
507 		canvas->translate(SkIntToScalar(50), 0);
508 		paint.setStyle(SkPaint::kFill_Style);
509 		canvas->drawBitmap(fBug, left, top, &paint);
510 		canvas->translate(SkIntToScalar(30), 0);
511 		canvas->drawSprite(fTb,
512 			SkScalarRound(canvas->getTotalMatrix().getTranslateX()),
513             spriteOffset + 10, &paint);
514 
515 		canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
516         paint.setShader(shaderTest())->unref(); // test compose shader
517 		canvas->drawRect(rect2, paint);
518         paint.setShader(NULL);
519 
520         canvas->restore();
521         // text
522 		canvas->translate(0, SkIntToScalar(60));
523         canvas->save();
524 		paint.setColor(SK_ColorGRAY);
525 		canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
526 		canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
527 
528 		canvas->translate(SkIntToScalar(50), 0);
529 		paint.setColor(SK_ColorCYAN);
530 		canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
531 
532 		canvas->translate(SkIntToScalar(30), 0);
533 		paint.setColor(SK_ColorMAGENTA);
534 		paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
535         matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
536 		canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
537 		canvas->translate(0, SkIntToScalar(20));
538 		canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
539         canvas->restore();
540 
541         canvas->translate(0, SkIntToScalar(60));
542 		paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
543         canvas->restore();
544     }
545 
546     /*
547 ./SkColorFilter.h:25:class SkColorFilter : public SkFlattenable { -- abstract
548     static SkColorFilter* CreatXfermodeFilter() *** untested ***
549     static SkColorFilter* CreatePorterDuffFilter() *** untested ***
550     static SkColorFilter* CreateLightingFilter() -- tested
551 ./SkDrawLooper.h:9:class SkDrawLooper : public SkFlattenable { -- virtually abstract
552     ./SkBlurDrawLooper.h:9:class SkBlurDrawLooper : public SkDrawLooper { *** untested ***
553 ./SkMaskFilter.h:41:class SkMaskFilter : public SkFlattenable { -- abstract chmod +w .h
554     ./SkEmbossMaskFilter.h:27:class SkEmbossMaskFilter : public SkMaskFilter { -- tested
555 ./SkPathEffect.h:33:class SkPathEffect : public SkFlattenable { -- abstract
556     ./Sk1DPathEffect.h:27:class Sk1DPathEffect : public SkPathEffect { -- abstract
557         ./Sk1DPathEffect.h:48:class SkPath1DPathEffect : public Sk1DPathEffect { -- tested
558     ./Sk2DPathEffect.h:25:class Sk2DPathEffect : public SkPathEffect { *** untested ***
559     ./SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect { *** untested ***
560     ./SkDashPathEffect.h:27:class SkDashPathEffect : public SkPathEffect {
561     ./SkDiscretePathEffect.h:27:class SkDiscretePathEffect : public SkPathEffect {
562     ./SkPaint.h:760:class SkStrokePathEffect : public SkPathEffect {
563     ./SkPathEffect.h:58:class SkPairPathEffect : public SkPathEffect {
564         ./SkPathEffect.h:78:class SkComposePathEffect : public SkPairPathEffect {
565         ./SkPathEffect.h:114:class SkSumPathEffect : public SkPairPathEffect {
566 ./SkRasterizer.h:29:class SkRasterizer : public SkFlattenable {
567     ./SkLayerRasterizer.h:27:class SkLayerRasterizer : public SkRasterizer {
568 ./SkShader.h:36:class SkShader : public SkFlattenable {
569     ./SkColorFilter.h:59:class SkFilterShader : public SkShader {
570     ./SkColorShader.h:26:class SkColorShader : public SkShader {
571     ./SkShaderExtras.h:31:class SkComposeShader : public SkShader {
572     ./SkTransparentShader.h:23:class SkTransparentShader : public SkShader {
573 ./SkUnitMapper.h:24:class SkUnitMapper : public SkFlattenable {
574     ./SkUnitMapper.h:33:class SkDiscreteMapper : public SkUnitMapper {
575     ./SkUnitMapper.h:51:class SkFlipCosineMapper : public SkUnitMapper {
576 ./SkXfermode.h:32:class SkXfermode : public SkFlattenable {
577     ./SkAvoidXfermode.h:28:class SkAvoidXfermode : public SkXfermode { *** not done *** chmod +w .h .cpp
578     ./SkXfermode.h:54:class SkProcXfermode : public SkXfermode {
579     */
580 
581     /*
582 ./SkBlurMaskFilter.h:25:class SkBlurMaskFilter {
583     chmod +w SkBlurMaskFilter.cpp
584 ./SkGradientShader.h:30:class SkGradientShader {
585     */
586         // save layer, bounder, looper
587         // matrix
588         // clip /path/region
589         // bitmap proc shader ?
590 
591 /* untested:
592 SkCornerPathEffect.h:28:class SkCornerPathEffect : public SkPathEffect {
593 */
594 
onFindClickHandler(SkScalar x,SkScalar y)595     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
596         fClickPt.set(x, y);
597         this->inval(NULL);
598         return this->INHERITED::onFindClickHandler(x, y);
599     }
600 
pathEffectTest()601     SkPathEffect* pathEffectTest() {
602         static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
603         SkScalar gPhase = 0;
604         SkPath path;
605         path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
606         for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
607             path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
608         path.close();
609         path.offset(SkIntToScalar(-6), 0);
610         SkPathEffect* outer = new SkPath1DPathEffect(path, SkIntToScalar(12),
611             gPhase, SkPath1DPathEffect::kRotate_Style);
612         SkPathEffect* inner = new SkDiscretePathEffect(SkIntToScalar(2),
613             SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
614         SkPathEffect* result = new SkComposePathEffect(outer, inner);
615         outer->unref();
616         inner->unref();
617         return result;
618     }
619 
pathEffectTest2()620     SkPathEffect* pathEffectTest2() { // unsure this works (has no visible effect)
621         SkPathEffect* outer = new SkStrokePathEffect(SkIntToScalar(4),
622             SkPaint::kStroke_Style, SkPaint::kMiter_Join, SkPaint::kButt_Cap);
623         static const SkScalar intervals[] = {SkIntToScalar(1), SkIntToScalar(2),
624             SkIntToScalar(2), SkIntToScalar(1)};
625         SkPathEffect* inner = new SkDashPathEffect(intervals,
626             sizeof(intervals) / sizeof(intervals[0]), 0);
627         SkPathEffect* result = new SkSumPathEffect(outer, inner);
628         outer->unref();
629         inner->unref();
630         return result;
631     }
632 
shaderTest()633     SkShader* shaderTest() {
634         SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
635         SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
636         SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
637             2, SkShader::kClamp_TileMode);
638         pts[1].set(0, SkIntToScalar(100));
639         SkColor colors2[] = {SK_ColorBLACK,  SkColorSetARGB(0x80, 0, 0, 0)};
640         SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
641             2, SkShader::kClamp_TileMode);
642         SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
643         SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
644         shaderA->unref();
645         shaderB->unref();
646         mode->unref();
647         return result;
648     }
649 
startTest()650     virtual void startTest() {
651 		SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
652 		SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
653 		SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
654 	}
655 
drawRaster(SkCanvas * canvas)656     void drawRaster(SkCanvas* canvas)  {
657         for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
658             drawOneRaster(canvas);
659     }
660 
drawOneRaster(SkCanvas * canvas)661     void drawOneRaster(SkCanvas* canvas) {
662         canvas->save();
663 
664         SkScalar    x = SkIntToScalar(20);
665         SkScalar    y = SkIntToScalar(40);
666         SkPaint     paint;
667 
668         paint.setAntiAlias(true);
669         paint.setTextSize(SkIntToScalar(48));
670         paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
671                                                      SkTypeface::kBold));
672 
673         SkString str("GOOGLE");
674 
675         for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
676             apply_shader(&paint, i);
677 
678           //  paint.setMaskFilter(NULL);
679           //  paint.setColor(SK_ColorBLACK);
680 
681 #if 01
682             int index = i % SK_ARRAY_COUNT(gLightingColors);
683             paint.setColorFilter(SkColorFilter::CreateLightingFilter(
684                                     gLightingColors[index].fMul,
685                                     gLightingColors[index].fAdd))->unref();
686 #endif
687 
688             canvas->drawText(str.c_str(), str.size(), x, y, paint);
689             SkRect  oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
690             paint.setStyle(SkPaint::kStroke_Style);
691             canvas->drawOval(oval, paint);
692             paint.setStyle(SkPaint::kFill_Style);
693 
694             y += paint.getFontSpacing();
695         }
696 
697         canvas->restore();
698 
699         if (1) {
700             SkAvoidXfermode   mode(SK_ColorWHITE, 0xFF,
701                                    SkAvoidXfermode::kTargetColor_Mode);
702             SkPaint paint;
703             x += SkIntToScalar(20);
704             SkRect  r = { x, 0, x + SkIntToScalar(360), SkIntToScalar(700) };
705             paint.setXfermode(&mode);
706             paint.setColor(SK_ColorGREEN);
707             paint.setAntiAlias(true);
708             canvas->drawOval(r, paint);
709         }
710     }
711 
712 private:
713     SkPoint fClickPt;
714     SkBitmap fBug, fTb, fTx;
715     typedef SampleView INHERITED;
716 };
717 
718 //////////////////////////////////////////////////////////////////////////////
719 
MyFactory()720 static SkView* MyFactory() { return new DemoView; }
721 static SkViewRegister reg(MyFactory);
722 
723