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