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 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: 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: 61 SkChannelMaskColorFilter(U8CPU redMask, U8CPU greenMask, U8CPU blueMask) { 62 fMask = SkPackARGB32(0xFF, redMask, greenMask, blueMask); 63 } 64 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 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 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 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 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 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 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 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: 159 Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix) 160 : Sk2DPathEffect(matrix), fRadius(radius) {} 161 162 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 163 this->INHERITED::flatten(buffer); 164 165 buffer.writeScalar(fRadius); 166 } 167 virtual Factory getFactory() { return CreateProc; } 168 169 protected: 170 virtual void next(const SkPoint& loc, int u, int v, SkPath* dst) { 171 dst->addCircle(loc.fX, loc.fY, fRadius); 172 } 173 174 Dot2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) { 175 fRadius = buffer.readScalar(); 176 } 177 private: 178 SkScalar fRadius; 179 180 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 181 return new Dot2DPathEffect(buffer); 182 } 183 184 typedef Sk2DPathEffect INHERITED; 185 }; 186 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 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: 214 Line2DPathEffect(SkScalar width, const SkMatrix& matrix) 215 : Sk2DPathEffect(matrix), fWidth(width) {} 216 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 225 virtual Factory getFactory() { return CreateProc; } 226 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 227 this->INHERITED::flatten(buffer); 228 buffer.writeScalar(fWidth); 229 } 230 protected: 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 246 Line2DPathEffect(SkFlattenableReadBuffer& buffer) : Sk2DPathEffect(buffer) { 247 fWidth = buffer.readScalar(); 248 } 249 250 private: 251 SkScalar fWidth; 252 253 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { return new Line2DPathEffect(buffer); } 254 255 typedef Sk2DPathEffect INHERITED; 256 }; 257 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 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 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 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: 328 DemoView() {} 329 330 protected: 331 // overrides from SkEventSink 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 340 virtual bool onClick(Click* click) { 341 return this->INHERITED::onClick(click); 342 } 343 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 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 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 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 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 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 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 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 656 void drawRaster(SkCanvas* canvas) { 657 for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++) 658 drawOneRaster(canvas); 659 } 660 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 720 static SkView* MyFactory() { return new DemoView; } 721 static SkViewRegister reg(MyFactory); 722 723