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