39f772249199b5c6fb2ad0967642f558f9882d12
[platform/upstream/libSkiaSharp.git] / samplecode / SampleAll.cpp
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 "SkBlurMask.h"
10 #include "SkCanvas.h"
11 #include "SkView.h"
12 #include "Sk1DPathEffect.h"
13 #include "Sk2DPathEffect.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 "SkReadBuffer.h"
22 #include "SkWriteBuffer.h"
23 #include "SkGradientShader.h"
24 #include "SkImageDecoder.h"
25 #include "SkLayerRasterizer.h"
26 #include "SkMath.h"
27 #include "SkPath.h"
28 #include "SkPictureRecorder.h"
29 #include "SkRegion.h"
30 #include "SkShader.h"
31 #include "SkComposeShader.h"
32 #include "SkCornerPathEffect.h"
33 #include "SkPathMeasure.h"
34 #include "SkPicture.h"
35 #include "SkRandom.h"
36 #include "SkTransparentShader.h"
37 #include "SkTypeface.h"
38 #include "SkUtils.h"
39 #include "SkXfermode.h"
40
41 #include <math.h>
42
43 static inline SkPMColor rgb2gray(SkPMColor c) {
44     unsigned r = SkGetPackedR32(c);
45     unsigned g = SkGetPackedG32(c);
46     unsigned b = SkGetPackedB32(c);
47
48     unsigned x = (r * 5 + g * 7 + b * 4) >> 4;
49
50     return SkPackARGB32(0, x, x, x) | (c & (SK_A32_MASK << SK_A32_SHIFT));
51 }
52
53 class SkGrayScaleColorFilter : public SkColorFilter {
54 public:
55     virtual void filterSpan(const SkPMColor src[], int count,
56                             SkPMColor result[]) const SK_OVERRIDE {
57         for (int i = 0; i < count; i++)
58             result[i] = rgb2gray(src[i]);
59     }
60 };
61
62 class SkChannelMaskColorFilter : public SkColorFilter {
63 public:
64     SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) {
65         fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask);
66     }
67
68     virtual void filterSpan(const SkPMColor src[], int count,
69                             SkPMColor result[]) const SK_OVERRIDE {
70         SkPMColor mask = fMask;
71         for (int i = 0; i < count; i++) {
72             result[i] = src[i] & mask;
73         }
74     }
75
76 private:
77     SkPMColor   fMask;
78 };
79
80 ///////////////////////////////////////////////////////////
81
82 static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
83     p.setMaskFilter(SkBlurMaskFilter::Create(kNormal_SkBlurStyle,
84                                              SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)),
85                                              SkBlurMaskFilter::kNone_BlurFlag))->unref();
86     rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
87
88     p.setMaskFilter(NULL);
89     p.setStyle(SkPaint::kStroke_Style);
90     p.setStrokeWidth(SK_Scalar1);
91     rastBuilder->addLayer(p);
92
93     p.setAlpha(0x11);
94     p.setStyle(SkPaint::kFill_Style);
95     p.setXfermodeMode(SkXfermode::kSrc_Mode);
96     rastBuilder->addLayer(p);
97 }
98
99 static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
100     rastBuilder->addLayer(p);
101
102     p.setAlpha(0x40);
103     p.setXfermodeMode(SkXfermode::kSrc_Mode);
104     p.setStyle(SkPaint::kStroke_Style);
105     p.setStrokeWidth(SK_Scalar1*2);
106     rastBuilder->addLayer(p);
107 }
108
109 static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
110     p.setStyle(SkPaint::kStrokeAndFill_Style);
111     p.setStrokeWidth(SK_Scalar1*4);
112     rastBuilder->addLayer(p);
113
114     p.setStyle(SkPaint::kStroke_Style);
115     p.setStrokeWidth(SK_Scalar1*3/2);
116     p.setXfermodeMode(SkXfermode::kClear_Mode);
117     rastBuilder->addLayer(p);
118 }
119
120 static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
121     p.setStyle(SkPaint::kStroke_Style);
122     p.setStrokeWidth(SK_Scalar1*3);
123     rastBuilder->addLayer(p);
124
125     p.setAlpha(0x20);
126     p.setStyle(SkPaint::kFill_Style);
127     p.setXfermodeMode(SkXfermode::kSrc_Mode);
128     rastBuilder->addLayer(p);
129 }
130
131 static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
132     p.setAlpha(0x60);
133     rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3));
134
135     p.setAlpha(0xFF);
136     p.setXfermodeMode(SkXfermode::kClear_Mode);
137     rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2);
138
139     p.setXfermode(NULL);
140     rastBuilder->addLayer(p);
141 }
142
143 static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
144     rastBuilder->addLayer(p);
145
146     p.setPathEffect(SkDiscretePathEffect::Create(SK_Scalar1*4, SK_Scalar1*3))->unref();
147     p.setXfermodeMode(SkXfermode::kSrcOut_Mode);
148     rastBuilder->addLayer(p);
149 }
150
151 static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
152     rastBuilder->addLayer(p);
153
154     p.setAntiAlias(false);
155     SkLayerRasterizer::Builder rastBuilder2;
156     r5(&rastBuilder2, p);
157     p.setRasterizer(rastBuilder2.detachRasterizer())->unref();
158     p.setXfermodeMode(SkXfermode::kClear_Mode);
159     rastBuilder->addLayer(p);
160 }
161
162 class Dot2DPathEffect : public Sk2DPathEffect {
163 public:
164     Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix)
165         : Sk2DPathEffect(matrix), fRadius(radius) {}
166
167     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Dot2DPathEffect)
168
169 protected:
170     void next(const SkPoint& loc, int u, int v, SkPath* dst) const SK_OVERRIDE {
171         dst->addCircle(loc.fX, loc.fY, fRadius);
172     }
173
174     void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
175         this->INHERITED::flatten(buffer);
176         buffer.writeScalar(fRadius);
177     }
178
179 private:
180     SkScalar fRadius;
181
182     typedef Sk2DPathEffect INHERITED;
183 };
184
185 static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
186     SkMatrix    lattice;
187     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
188     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
189     p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*4, lattice))->unref();
190     rastBuilder->addLayer(p);
191 }
192
193 static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
194     rastBuilder->addLayer(p);
195
196     SkMatrix    lattice;
197     lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0);
198     lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
199     p.setPathEffect(new Dot2DPathEffect(SK_Scalar1*2, lattice))->unref();
200     p.setXfermodeMode(SkXfermode::kClear_Mode);
201     rastBuilder->addLayer(p);
202
203     p.setPathEffect(NULL);
204     p.setXfermode(NULL);
205     p.setStyle(SkPaint::kStroke_Style);
206     p.setStrokeWidth(SK_Scalar1);
207     rastBuilder->addLayer(p);
208 }
209
210 static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) {
211     rastBuilder->addLayer(p);
212
213     SkMatrix    lattice;
214     lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0);
215     lattice.postRotate(SkIntToScalar(30), 0, 0);
216     p.setPathEffect(SkLine2DPathEffect::Create(SK_Scalar1*2, lattice))->unref();
217     p.setXfermodeMode(SkXfermode::kClear_Mode);
218     rastBuilder->addLayer(p);
219
220     p.setPathEffect(NULL);
221     p.setXfermode(NULL);
222     p.setStyle(SkPaint::kStroke_Style);
223     p.setStrokeWidth(SK_Scalar1);
224     rastBuilder->addLayer(p);
225 }
226
227 typedef void (*raster_proc)(SkLayerRasterizer::Builder*, SkPaint&);
228
229 static const raster_proc gRastProcs[] = {
230     r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
231 };
232
233 static const struct {
234     SkColor fMul, fAdd;
235 } gLightingColors[] = {
236     { 0x808080, 0x800000 }, // general case
237     { 0x707070, 0x707070 }, // no-pin case
238     { 0xFFFFFF, 0x800000 }, // just-add case
239     { 0x808080, 0x000000 }, // just-mul case
240     { 0xFFFFFF, 0x000000 }  // identity case
241 };
242
243 static void apply_shader(SkPaint* paint, int index) {
244     raster_proc proc = gRastProcs[index];
245     if (proc) {
246         SkPaint p;
247         SkLayerRasterizer::Builder rastBuilder;
248
249         p.setAntiAlias(true);
250         proc(&rastBuilder, p);
251         paint->setRasterizer(rastBuilder.detachRasterizer())->unref();
252     }
253
254 #if 1
255     SkScalar dir[] = { SK_Scalar1, SK_Scalar1, SK_Scalar1 };
256     paint->setMaskFilter(SkBlurMaskFilter::CreateEmboss(
257                 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(3)), dir,
258                 SK_Scalar1/4, SkIntToScalar(4)))->unref();
259     paint->setColor(SK_ColorBLUE);
260 #endif
261 }
262
263 class DemoView : public SampleView {
264 public:
265     DemoView() {}
266
267 protected:
268     // overrides from SkEventSink
269     virtual bool onQuery(SkEvent* evt) {
270         if (SampleCode::TitleQ(*evt)) {
271             SampleCode::TitleR(evt, "Demo");
272             return true;
273         }
274         return this->INHERITED::onQuery(evt);
275     }
276
277     virtual bool onClick(Click* click) {
278         return this->INHERITED::onClick(click);
279     }
280
281     void makePath(SkPath& path) {
282         path.addCircle(SkIntToScalar(20), SkIntToScalar(20), SkIntToScalar(20),
283             SkPath::kCCW_Direction);
284         for (int index = 0; index < 10; index++) {
285             SkScalar x = (float) cos(index / 10.0f * 2 * 3.1415925358f);
286             SkScalar y = (float) sin(index / 10.0f * 2 * 3.1415925358f);
287             x *= index & 1 ? 7 : 14;
288             y *= index & 1 ? 7 : 14;
289             x += SkIntToScalar(20);
290             y += SkIntToScalar(20);
291             if (index == 0)
292                 path.moveTo(x, y);
293             else
294                 path.lineTo(x, y);
295         }
296         path.close();
297     }
298
299     virtual void onDrawContent(SkCanvas* canvas) {
300         canvas->save();
301         this->drawPicture(canvas, 0);
302         canvas->restore();
303
304         {
305             SkPictureRecorder recorder;
306             {
307                 SkCanvas* record = recorder.beginRecording(320, 480, NULL, 0);
308                 this->drawPicture(record, 120);
309             }
310             SkAutoTUnref<SkPicture> picture(recorder.endRecording());
311
312             canvas->translate(0, SkIntToScalar(120));
313
314             SkRect clip;
315             clip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
316             do {
317                 canvas->save();
318                 canvas->clipRect(clip);
319                 picture->playback(canvas);
320                 canvas->restore();
321                 if (clip.fRight < SkIntToScalar(320))
322                     clip.offset(SkIntToScalar(160), 0);
323                 else if (clip.fBottom < SkIntToScalar(480))
324                     clip.offset(-SkIntToScalar(320), SkIntToScalar(160));
325                 else
326                     break;
327             } while (true);
328         }
329     }
330
331     void drawPicture(SkCanvas* canvas, int spriteOffset) {
332         SkMatrix matrix; matrix.reset();
333         SkPaint paint;
334         SkPath path;
335         SkPoint start = {0, 0};
336         SkPoint stop = { SkIntToScalar(40), SkIntToScalar(40) };
337         SkRect rect = {0, 0, SkIntToScalar(40), SkIntToScalar(40) };
338         SkRect rect2 = {0, 0, SkIntToScalar(65), SkIntToScalar(20) };
339         SkScalar left = 0, top = 0, x = 0, y = 0;
340         int index;
341
342         char ascii[] = "ascii...";
343         int asciiLength = sizeof(ascii) - 1;
344         char utf8[] = "utf8" "\xe2\x80\xa6";
345         short utf16[] = {'u', 't', 'f', '1', '6', 0x2026 };
346         short utf16simple[] = {'u', 't', 'f', '1', '6', '!' };
347
348         makePath(path);
349         SkTDArray<SkPoint>(pos);
350         pos.setCount(asciiLength);
351         for (index = 0;  index < asciiLength; index++)
352             pos[index].set(SkIntToScalar((unsigned int)index * 10),
353                                        SkIntToScalar((unsigned int)index * 2));
354         SkTDArray<SkPoint>(pos2);
355         pos2.setCount(asciiLength);
356         for (index = 0;  index < asciiLength; index++)
357             pos2[index].set(SkIntToScalar((unsigned int)index * 10),
358                                         SkIntToScalar(20));
359
360         // shaders
361         SkPoint linearPoints[] = { { 0, 0, }, { SkIntToScalar(40), SkIntToScalar(40) } };
362         SkColor linearColors[] = { SK_ColorRED, SK_ColorBLUE };
363         SkScalar* linearPos = NULL;
364         int linearCount = 2;
365         SkShader::TileMode linearMode = SkShader::kMirror_TileMode;
366         SkShader* linear = SkGradientShader::CreateLinear(linearPoints,
367             linearColors, linearPos, linearCount, linearMode);
368
369         SkPoint radialCenter = { SkIntToScalar(25), SkIntToScalar(25) };
370         SkScalar radialRadius = SkIntToScalar(25);
371         SkColor radialColors[] = { SK_ColorGREEN, SK_ColorGRAY, SK_ColorRED };
372         SkScalar radialPos[] = { 0, SkIntToScalar(3) / 5, SkIntToScalar(1)};
373         int radialCount = 3;
374         SkShader::TileMode radialMode = SkShader::kRepeat_TileMode;
375         SkShader* radial = SkGradientShader::CreateRadial(radialCenter,
376             radialRadius, radialColors, radialPos, radialCount,
377             radialMode);
378
379         SkTransparentShader* transparentShader = new SkTransparentShader();
380         SkEmbossMaskFilter::Light light;
381         light.fDirection[0] = SK_Scalar1/2;
382         light.fDirection[1] = SK_Scalar1/2;
383         light.fDirection[2] = SK_Scalar1/3;
384         light.fAmbient        = 0x48;
385         light.fSpecular        = 0x80;
386         SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(12)/5);
387         SkEmbossMaskFilter* embossFilter = SkEmbossMaskFilter::Create(sigma, light);
388
389         SkXfermode* xfermode = SkXfermode::Create(SkXfermode::kXor_Mode);
390         SkColorFilter* lightingFilter = SkColorFilter::CreateLightingFilter(
391             0xff89bc45, 0xff112233);
392
393         canvas->save();
394         canvas->translate(SkIntToScalar(0), SkIntToScalar(5));
395         paint.setAntiAlias(true);
396         paint.setFilterQuality(kLow_SkFilterQuality);
397         // !!! draw through a clip
398         paint.setColor(SK_ColorLTGRAY);
399         paint.setStyle(SkPaint::kFill_Style);
400         SkRect clip = {0, 0, SkIntToScalar(320), SkIntToScalar(120)};
401         canvas->clipRect(clip);
402         paint.setShader(SkShader::CreateBitmapShader(fTx,
403             SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode))->unref();
404         canvas->drawPaint(paint);
405         canvas->save();
406
407         // line (exercises xfermode, colorShader, colorFilter, filterShader)
408         paint.setColor(SK_ColorGREEN);
409         paint.setStrokeWidth(SkIntToScalar(10));
410         paint.setStyle(SkPaint::kStroke_Style);
411         paint.setXfermode(xfermode)->unref();
412         paint.setColorFilter(lightingFilter)->unref();
413         canvas->drawLine(start.fX, start.fY, stop.fX, stop.fY, paint); // should not be green
414         paint.setXfermode(NULL);
415         paint.setColorFilter(NULL);
416
417         // rectangle
418         paint.setStyle(SkPaint::kFill_Style);
419         canvas->translate(SkIntToScalar(50), 0);
420         paint.setColor(SK_ColorYELLOW);
421         paint.setShader(linear)->unref();
422         paint.setPathEffect(pathEffectTest())->unref();
423         canvas->drawRect(rect, paint);
424         paint.setPathEffect(NULL);
425
426         // circle w/ emboss & transparent (exercises 3dshader)
427         canvas->translate(SkIntToScalar(50), 0);
428         paint.setMaskFilter(embossFilter)->unref();
429         canvas->drawOval(rect, paint);
430         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
431         paint.setShader(transparentShader)->unref();
432         canvas->drawOval(rect, paint);
433         canvas->translate(0, SkIntToScalar(-10));
434
435         // path
436         canvas->translate(SkIntToScalar(50), 0);
437         paint.setColor(SK_ColorRED);
438         paint.setStyle(SkPaint::kStroke_Style);
439         paint.setStrokeWidth(SkIntToScalar(5));
440         paint.setShader(radial)->unref();
441         paint.setMaskFilter(NULL);
442         canvas->drawPath(path, paint);
443
444         paint.setShader(NULL);
445         // bitmap, sprite
446         canvas->translate(SkIntToScalar(50), 0);
447         paint.setStyle(SkPaint::kFill_Style);
448         canvas->drawBitmap(fBug, left, top, &paint);
449         canvas->translate(SkIntToScalar(30), 0);
450         canvas->drawSprite(fTb,
451             SkScalarRoundToInt(canvas->getTotalMatrix().getTranslateX()),
452             spriteOffset + 10, &paint);
453
454         canvas->translate(-SkIntToScalar(30), SkIntToScalar(30));
455         paint.setShader(shaderTest())->unref(); // test compose shader
456         canvas->drawRect(rect2, paint);
457         paint.setShader(NULL);
458
459         canvas->restore();
460         // text
461         canvas->translate(0, SkIntToScalar(60));
462         canvas->save();
463         paint.setColor(SK_ColorGRAY);
464         canvas->drawPosText(ascii, asciiLength, pos.begin(), paint);
465         canvas->drawPosText(ascii, asciiLength, pos2.begin(), paint);
466
467         canvas->translate(SkIntToScalar(50), 0);
468         paint.setColor(SK_ColorCYAN);
469         canvas->drawText(utf8, sizeof(utf8) - 1, x, y, paint);
470
471         canvas->translate(SkIntToScalar(30), 0);
472         paint.setColor(SK_ColorMAGENTA);
473         paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
474         matrix.setTranslate(SkIntToScalar(10), SkIntToScalar(10));
475         canvas->drawTextOnPath((void*) utf16, sizeof(utf16), path, &matrix, paint);
476         canvas->translate(0, SkIntToScalar(20));
477         canvas->drawTextOnPath((void*) utf16simple, sizeof(utf16simple), path, &matrix, paint);
478         canvas->restore();
479
480         canvas->translate(0, SkIntToScalar(60));
481         paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
482         canvas->restore();
483     }
484
485     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) {
486         fClickPt.set(x, y);
487         this->inval(NULL);
488         return this->INHERITED::onFindClickHandler(x, y, modi);
489     }
490
491     SkPathEffect* pathEffectTest() {
492         static const int gXY[] = { 1, 0, 0, -1, 2, -1, 3, 0, 2, 1, 0, 1 };
493         SkScalar gPhase = 0;
494         SkPath path;
495         path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
496         for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
497             path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
498         path.close();
499         path.offset(SkIntToScalar(-6), 0);
500         SkPathEffect* outer = SkPath1DPathEffect::Create(path, SkIntToScalar(12),
501             gPhase, SkPath1DPathEffect::kRotate_Style);
502         SkPathEffect* inner = SkDiscretePathEffect::Create(SkIntToScalar(2),
503             SkIntToScalar(1)/10); // SkCornerPathEffect(SkIntToScalar(2));
504         SkPathEffect* result = SkComposePathEffect::Create(outer, inner);
505         outer->unref();
506         inner->unref();
507         return result;
508     }
509
510     SkShader* shaderTest() {
511         SkPoint pts[] = { { 0, 0, }, { SkIntToScalar(100), 0 } };
512         SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
513         SkShader* shaderA = SkGradientShader::CreateLinear(pts, colors, NULL,
514             2, SkShader::kClamp_TileMode);
515         pts[1].set(0, SkIntToScalar(100));
516         SkColor colors2[] = {SK_ColorBLACK,  SkColorSetARGB(0x80, 0, 0, 0)};
517         SkShader* shaderB = SkGradientShader::CreateLinear(pts, colors2, NULL,
518             2, SkShader::kClamp_TileMode);
519         SkXfermode* mode = SkXfermode::Create(SkXfermode::kDstIn_Mode);
520         SkShader* result = new SkComposeShader(shaderA, shaderB, mode);
521         shaderA->unref();
522         shaderB->unref();
523         mode->unref();
524         return result;
525     }
526
527     virtual void startTest() {
528         SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/bugcirc.gif", &fBug);
529         SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/tbcirc.gif", &fTb);
530         SkImageDecoder::DecodeFile("/Users/caryclark/Desktop/05psp04.gif", &fTx);
531     }
532
533     void drawRaster(SkCanvas* canvas)  {
534         for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++)
535             drawOneRaster(canvas);
536     }
537
538     void drawOneRaster(SkCanvas* canvas) {
539         canvas->save();
540
541         SkScalar    x = SkIntToScalar(20);
542         SkScalar    y = SkIntToScalar(40);
543         SkPaint     paint;
544
545         paint.setAntiAlias(true);
546         paint.setTextSize(SkIntToScalar(48));
547         paint.setTypeface(SkTypeface::CreateFromName("sans-serif",
548                                                      SkTypeface::kBold));
549
550         SkString str("GOOGLE");
551
552         for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) {
553             apply_shader(&paint, (int)i);
554
555           //  paint.setMaskFilter(NULL);
556           //  paint.setColor(SK_ColorBLACK);
557
558 #if 01
559             int index = i % SK_ARRAY_COUNT(gLightingColors);
560             paint.setColorFilter(SkColorFilter::CreateLightingFilter(
561                                     gLightingColors[index].fMul,
562                                     gLightingColors[index].fAdd))->unref();
563 #endif
564
565             canvas->drawText(str.c_str(), str.size(), x, y, paint);
566             SkRect  oval = { x, y - SkIntToScalar(40), x + SkIntToScalar(40), y };
567             paint.setStyle(SkPaint::kStroke_Style);
568             canvas->drawOval(oval, paint);
569             paint.setStyle(SkPaint::kFill_Style);
570
571             y += paint.getFontSpacing();
572         }
573
574         canvas->restore();
575     }
576
577 private:
578     SkPoint fClickPt;
579     SkBitmap fBug, fTb, fTx;
580     typedef SampleView INHERITED;
581 };
582
583 //////////////////////////////////////////////////////////////////////////////
584
585 static SkView* MyFactory() { return new DemoView; }
586 static SkViewRegister reg(MyFactory);