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