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