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 Dot2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { 176 fRadius = buffer.readScalar(); 177 } 178 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 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 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 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 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: 269 DemoView() {} 270 271 protected: 272 // overrides from SkEventSink 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 281 virtual bool onClick(Click* click) { 282 return this->INHERITED::onClick(click); 283 } 284 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 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 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 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 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 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 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 537 void drawRaster(SkCanvas* canvas) { 538 for (size_t index = 0; index < SK_ARRAY_COUNT(gRastProcs); index++) 539 drawOneRaster(canvas); 540 } 541 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 601 static SkView* MyFactory() { return new DemoView; } 602 static SkViewRegister reg(MyFactory); 603