1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7#include "SampleCode.h" 8#include "SkBlurMask.h" 9#include "SkBlurMaskFilter.h" 10#include "SkCanvas.h" 11#include "SkReadBuffer.h" 12#include "SkWriteBuffer.h" 13#include "SkGradientShader.h" 14#include "SkLayerRasterizer.h" 15#include "SkPaint.h" 16#include "SkVertices.h" 17#include "SkView.h" 18 19#include "sk_tool_utils.h" 20 21#define BG_COLOR 0xFFDDDDDD 22 23typedef void (*SlideProc)(SkCanvas*); 24 25/////////////////////////////////////////////////////////////////////////////// 26 27#include "Sk1DPathEffect.h" 28#include "Sk2DPathEffect.h" 29#include "SkCornerPathEffect.h" 30#include "SkDashPathEffect.h" 31#include "SkDiscretePathEffect.h" 32 33static void compose_pe(SkPaint* paint) { 34 SkPathEffect* pe = paint->getPathEffect(); 35 sk_sp<SkPathEffect> corner = SkCornerPathEffect::Make(25); 36 sk_sp<SkPathEffect> compose; 37 if (pe) { 38 compose = SkPathEffect::MakeCompose(sk_ref_sp(pe), corner); 39 } else { 40 compose = corner; 41 } 42 paint->setPathEffect(compose); 43} 44 45static void hair_pe(SkPaint* paint) { 46 paint->setStrokeWidth(0); 47} 48 49static void hair2_pe(SkPaint* paint) { 50 paint->setStrokeWidth(0); 51 compose_pe(paint); 52} 53 54static void stroke_pe(SkPaint* paint) { 55 paint->setStrokeWidth(12); 56 compose_pe(paint); 57} 58 59static void dash_pe(SkPaint* paint) { 60 SkScalar inter[] = { 20, 10, 10, 10 }; 61 paint->setStrokeWidth(12); 62 paint->setPathEffect(SkDashPathEffect::Make(inter, SK_ARRAY_COUNT(inter), 0)); 63 compose_pe(paint); 64} 65 66static const int gXY[] = { 674, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4 68}; 69 70static void scale(SkPath* path, SkScalar scale) { 71 SkMatrix m; 72 m.setScale(scale, scale); 73 path->transform(m); 74} 75 76static void one_d_pe(SkPaint* paint) { 77 SkPath path; 78 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 79 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 80 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 81 path.close(); 82 path.offset(SkIntToScalar(-6), 0); 83 scale(&path, 1.5f); 84 85 paint->setPathEffect(SkPath1DPathEffect::Make(path, SkIntToScalar(21), 0, 86 SkPath1DPathEffect::kRotate_Style)); 87 compose_pe(paint); 88} 89 90typedef void (*PE_Proc)(SkPaint*); 91static const PE_Proc gPE[] = { hair_pe, hair2_pe, stroke_pe, dash_pe, one_d_pe }; 92 93static void fill_pe(SkPaint* paint) { 94 paint->setStyle(SkPaint::kFill_Style); 95 paint->setPathEffect(nullptr); 96} 97 98static void discrete_pe(SkPaint* paint) { 99 paint->setPathEffect(SkDiscretePathEffect::Make(10, 4)); 100} 101 102static sk_sp<SkPathEffect> MakeTileEffect() { 103 SkMatrix m; 104 m.setScale(SkIntToScalar(12), SkIntToScalar(12)); 105 106 SkPath path; 107 path.addCircle(0, 0, SkIntToScalar(5)); 108 109 return SkPath2DPathEffect::Make(m, path); 110} 111 112static void tile_pe(SkPaint* paint) { 113 paint->setPathEffect(MakeTileEffect()); 114} 115 116static const PE_Proc gPE2[] = { fill_pe, discrete_pe, tile_pe }; 117 118static void patheffect_slide(SkCanvas* canvas) { 119 SkPaint paint; 120 paint.setAntiAlias(true); 121 paint.setStyle(SkPaint::kStroke_Style); 122 123 SkPath path; 124 path.moveTo(20, 20); 125 path.lineTo(70, 120); 126 path.lineTo(120, 30); 127 path.lineTo(170, 80); 128 path.lineTo(240, 50); 129 130 size_t i; 131 canvas->save(); 132 for (i = 0; i < SK_ARRAY_COUNT(gPE); i++) { 133 gPE[i](&paint); 134 canvas->drawPath(path, paint); 135 canvas->translate(0, 75); 136 } 137 canvas->restore(); 138 139 path.reset(); 140 SkRect r = { 0, 0, 250, 120 }; 141 path.addOval(r, SkPath::kCW_Direction); 142 r.inset(50, 50); 143 path.addRect(r, SkPath::kCCW_Direction); 144 145 canvas->translate(320, 20); 146 for (i = 0; i < SK_ARRAY_COUNT(gPE2); i++) { 147 gPE2[i](&paint); 148 canvas->drawPath(path, paint); 149 canvas->translate(0, 160); 150 } 151} 152 153/////////////////////////////////////////////////////////////////////////////// 154 155#include "SkGradientShader.h" 156 157struct GradData { 158 int fCount; 159 const SkColor* fColors; 160 const SkScalar* fPos; 161}; 162 163static const SkColor gColors[] = { 164SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK 165}; 166static const SkScalar gPos0[] = { 0, SK_Scalar1 }; 167static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 }; 168static const SkScalar gPos2[] = { 1690, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1 170}; 171 172static const GradData gGradData[] = { 173{ 2, gColors, nullptr }, 174{ 2, gColors, gPos0 }, 175{ 2, gColors, gPos1 }, 176{ 5, gColors, nullptr }, 177{ 5, gColors, gPos2 } 178}; 179 180static sk_sp<SkShader> MakeLinear(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) { 181 return SkGradientShader::MakeLinear(pts, data.fColors, data.fPos, data.fCount, tm); 182} 183 184static sk_sp<SkShader> MakeRadial(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) { 185 SkPoint center; 186 center.set(SkScalarAve(pts[0].fX, pts[1].fX), 187 SkScalarAve(pts[0].fY, pts[1].fY)); 188 return SkGradientShader::MakeRadial(center, center.fX, data.fColors, 189 data.fPos, data.fCount, tm); 190} 191 192static sk_sp<SkShader> MakeSweep(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) { 193 SkPoint center; 194 center.set(SkScalarAve(pts[0].fX, pts[1].fX), 195 SkScalarAve(pts[0].fY, pts[1].fY)); 196 return SkGradientShader::MakeSweep(center.fX, center.fY, data.fColors, data.fPos, data.fCount); 197} 198 199static sk_sp<SkShader> Make2Conical(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm) { 200 SkPoint center0, center1; 201 center0.set(SkScalarAve(pts[0].fX, pts[1].fX), 202 SkScalarAve(pts[0].fY, pts[1].fY)); 203 center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), 204 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); 205 return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7, 206 center0, (pts[1].fX - pts[0].fX) / 2, 207 data.fColors, data.fPos, data.fCount, tm); 208} 209 210typedef sk_sp<SkShader> (*GradMaker)(const SkPoint pts[2], const GradData&, SkShader::TileMode); 211static const GradMaker gGradMakers[] = { 212 MakeLinear, MakeRadial, MakeSweep, Make2Conical 213}; 214 215static void gradient_slide(SkCanvas* canvas) { 216 SkPoint pts[2] = { 217 { 0, 0 }, 218 { SkIntToScalar(100), SkIntToScalar(100) } 219 }; 220 SkShader::TileMode tm = SkShader::kClamp_TileMode; 221 SkRect r = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) }; 222 SkPaint paint; 223 paint.setAntiAlias(true); 224 paint.setDither(true); 225 226 canvas->translate(SkIntToScalar(20), SkIntToScalar(10)); 227 for (size_t i = 0; i < SK_ARRAY_COUNT(gGradData); i++) { 228 canvas->save(); 229 for (size_t j = 0; j < SK_ARRAY_COUNT(gGradMakers); j++) { 230 paint.setShader(gGradMakers[j](pts, gGradData[i], tm)); 231 canvas->drawRect(r, paint); 232 canvas->translate(0, SkIntToScalar(120)); 233 } 234 canvas->restore(); 235 canvas->translate(SkIntToScalar(120), 0); 236 } 237} 238 239/////////////////////////////////////////////////////////////////////////////// 240 241#include "SkPathMeasure.h" 242 243static SkScalar getpathlen(const SkPath& path) { 244 SkPathMeasure meas(path, false); 245 return meas.getLength(); 246} 247 248static void textonpath_slide(SkCanvas* canvas) { 249 const char* text = "Displacement"; 250 size_t len =strlen(text); 251 SkPath path; 252 path.moveTo(100, 300); 253 path.quadTo(300, 100, 500, 300); 254 path.offset(0, -100); 255 256 SkPaint paint; 257 paint.setAntiAlias(true); 258 paint.setTextSize(40); 259 260 paint.setStyle(SkPaint::kStroke_Style); 261 canvas->drawPath(path, paint); 262 paint.setStyle(SkPaint::kFill_Style); 263 264 SkScalar x = 50; 265 paint.setColor(0xFF008800); 266 canvas->drawTextOnPathHV(text, len, path, 267 x, paint.getTextSize()*2/3, paint); 268 paint.setColor(SK_ColorRED); 269 canvas->drawTextOnPathHV(text, len, path, 270 x + 60, 0, paint); 271 paint.setColor(SK_ColorBLUE); 272 canvas->drawTextOnPathHV(text, len, path, 273 x + 120, -paint.getTextSize()*2/3, paint); 274 275 path.offset(0, 200); 276 paint.setTextAlign(SkPaint::kRight_Align); 277 278 text = "Matrices"; 279 len = strlen(text); 280 SkScalar pathLen = getpathlen(path); 281 SkMatrix matrix; 282 283 paint.setColor(SK_ColorBLACK); 284 paint.setStyle(SkPaint::kStroke_Style); 285 canvas->drawPath(path, paint); 286 paint.setStyle(SkPaint::kFill_Style); 287 288 paint.setTextSize(50); 289 canvas->drawTextOnPath(text, len, path, nullptr, paint); 290 291 paint.setColor(SK_ColorRED); 292 matrix.setScale(-SK_Scalar1, SK_Scalar1); 293 matrix.postTranslate(pathLen, 0); 294 canvas->drawTextOnPath(text, len, path, &matrix, paint); 295 296 paint.setColor(SK_ColorBLUE); 297 matrix.setScale(SK_Scalar1, -SK_Scalar1); 298 canvas->drawTextOnPath(text, len, path, &matrix, paint); 299 300 paint.setColor(0xFF008800); 301 matrix.setScale(-SK_Scalar1, -SK_Scalar1); 302 matrix.postTranslate(pathLen, 0); 303 canvas->drawTextOnPath(text, len, path, &matrix, paint); 304} 305 306/////////////////////////////////////////////////////////////////////////////// 307 308#include "DecodeFile.h" 309#include "SkOSFile.h" 310#include "SkRandom.h" 311#include "SkStream.h" 312 313static sk_sp<SkShader> make_shader0(SkIPoint* size) { 314 SkBitmap bm; 315 316 decode_file("/skimages/logo.gif", &bm); 317 size->set(bm.width(), bm.height()); 318 return SkShader::MakeBitmapShader(bm, SkShader::kClamp_TileMode, 319 SkShader::kClamp_TileMode); 320} 321 322static sk_sp<SkShader> make_shader1(const SkIPoint& size) { 323 SkPoint pts[] = { { 0, 0 }, 324 { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } }; 325 SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED }; 326 return SkGradientShader::MakeLinear(pts, colors, nullptr, 327 SK_ARRAY_COUNT(colors), SkShader::kMirror_TileMode); 328} 329 330class Rec { 331public: 332 SkVertices::VertexMode fMode; 333 int fCount; 334 SkPoint* fVerts; 335 SkPoint* fTexs; 336 337 Rec() : fCount(0), fVerts(nullptr), fTexs(nullptr) {} 338 ~Rec() { delete[] fVerts; delete[] fTexs; } 339}; 340 341static void make_tris(Rec* rec) { 342 int n = 10; 343 SkRandom rand; 344 345 rec->fMode = SkVertices::kTriangles_VertexMode; 346 rec->fCount = n * 3; 347 rec->fVerts = new SkPoint[rec->fCount]; 348 349 for (int i = 0; i < n; i++) { 350 SkPoint* v = &rec->fVerts[i*3]; 351 for (int j = 0; j < 3; j++) { 352 v[j].set(rand.nextUScalar1() * 250, rand.nextUScalar1() * 250); 353 } 354 } 355} 356 357static void make_fan(Rec* rec, int texWidth, int texHeight) { 358 const SkScalar tx = SkIntToScalar(texWidth); 359 const SkScalar ty = SkIntToScalar(texHeight); 360 const int n = 24; 361 362 rec->fMode = SkVertices::kTriangleFan_VertexMode; 363 rec->fCount = n + 2; 364 rec->fVerts = new SkPoint[rec->fCount]; 365 rec->fTexs = new SkPoint[rec->fCount]; 366 367 SkPoint* v = rec->fVerts; 368 SkPoint* t = rec->fTexs; 369 370 v[0].set(0, 0); 371 t[0].set(0, 0); 372 for (int i = 0; i < n; i++) { 373 SkScalar cos; 374 SkScalar sin = SkScalarSinCos(SK_ScalarPI * 2 * i / n, &cos); 375 v[i+1].set(cos, sin); 376 t[i+1].set(i*tx/n, ty); 377 } 378 v[n+1] = v[1]; 379 t[n+1].set(tx, ty); 380 381 SkMatrix m; 382 m.setScale(SkIntToScalar(100), SkIntToScalar(100)); 383 m.postTranslate(SkIntToScalar(110), SkIntToScalar(110)); 384 m.mapPoints(v, rec->fCount); 385} 386 387static void make_strip(Rec* rec, int texWidth, int texHeight) { 388 const SkScalar tx = SkIntToScalar(texWidth); 389 const SkScalar ty = SkIntToScalar(texHeight); 390 const int n = 24; 391 392 rec->fMode = SkVertices::kTriangleStrip_VertexMode; 393 rec->fCount = 2 * (n + 1); 394 rec->fVerts = new SkPoint[rec->fCount]; 395 rec->fTexs = new SkPoint[rec->fCount]; 396 397 SkPoint* v = rec->fVerts; 398 SkPoint* t = rec->fTexs; 399 400 for (int i = 0; i < n; i++) { 401 SkScalar cos; 402 SkScalar sin = SkScalarSinCos(SK_ScalarPI * 2 * i / n, &cos); 403 v[i*2 + 0].set(cos/2, sin/2); 404 v[i*2 + 1].set(cos, sin); 405 406 t[i*2 + 0].set(tx * i / n, ty); 407 t[i*2 + 1].set(tx * i / n, 0); 408 } 409 v[2*n + 0] = v[0]; 410 v[2*n + 1] = v[1]; 411 412 t[2*n + 0].set(tx, ty); 413 t[2*n + 1].set(tx, 0); 414 415 SkMatrix m; 416 m.setScale(SkIntToScalar(100), SkIntToScalar(100)); 417 m.postTranslate(SkIntToScalar(110), SkIntToScalar(110)); 418 m.mapPoints(v, rec->fCount); 419} 420 421static void mesh_slide(SkCanvas* canvas) { 422 Rec fRecs[3]; 423 SkIPoint size; 424 425 auto fShader0 = make_shader0(&size); 426 auto fShader1 = make_shader1(size); 427 428 make_strip(&fRecs[0], size.fX, size.fY); 429 make_fan(&fRecs[1], size.fX, size.fY); 430 make_tris(&fRecs[2]); 431 432 SkPaint paint; 433 paint.setDither(true); 434 paint.setFilterQuality(kLow_SkFilterQuality); 435 436 for (size_t i = 0; i < SK_ARRAY_COUNT(fRecs); i++) { 437 auto verts = SkVertices::MakeCopy(fRecs[i].fMode, fRecs[i].fCount, 438 fRecs[i].fVerts, fRecs[i].fTexs, nullptr); 439 canvas->save(); 440 441 paint.setShader(nullptr); 442 canvas->drawVertices(verts, SkBlendMode::kModulate, paint); 443 444 canvas->translate(SkIntToScalar(210), 0); 445 446 paint.setShader(fShader0); 447 canvas->drawVertices(verts, SkBlendMode::kModulate, paint); 448 449 canvas->translate(SkIntToScalar(210), 0); 450 451 paint.setShader(fShader1); 452 canvas->drawVertices(verts, SkBlendMode::kModulate, paint); 453 canvas->restore(); 454 455 canvas->translate(0, SkIntToScalar(250)); 456 } 457} 458 459/////////////////////////////////////////////////////////////////////////////// 460 461static void r0(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 462{ 463 p.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, 464 SkBlurMask::ConvertRadiusToSigma(3))); 465 rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3)); 466 467 p.setMaskFilter(nullptr); 468 p.setStyle(SkPaint::kStroke_Style); 469 p.setStrokeWidth(SK_Scalar1); 470 rastBuilder->addLayer(p); 471 472 p.setAlpha(0x11); 473 p.setStyle(SkPaint::kFill_Style); 474 p.setBlendMode(SkBlendMode::kSrc); 475 rastBuilder->addLayer(p); 476} 477 478static void r1(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 479{ 480 rastBuilder->addLayer(p); 481 482 p.setAlpha(0x40); 483 p.setBlendMode(SkBlendMode::kSrc); 484 p.setStyle(SkPaint::kStroke_Style); 485 p.setStrokeWidth(SK_Scalar1*2); 486 rastBuilder->addLayer(p); 487} 488 489static void r2(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 490{ 491 p.setStyle(SkPaint::kStrokeAndFill_Style); 492 p.setStrokeWidth(SK_Scalar1*4); 493 rastBuilder->addLayer(p); 494 495 p.setStyle(SkPaint::kStroke_Style); 496 p.setStrokeWidth(SK_Scalar1*3/2); 497 p.setBlendMode(SkBlendMode::kClear); 498 rastBuilder->addLayer(p); 499} 500 501static void r3(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 502{ 503 p.setStyle(SkPaint::kStroke_Style); 504 p.setStrokeWidth(SK_Scalar1*3); 505 rastBuilder->addLayer(p); 506 507 p.setAlpha(0x20); 508 p.setStyle(SkPaint::kFill_Style); 509 p.setBlendMode(SkBlendMode::kSrc); 510 rastBuilder->addLayer(p); 511} 512 513static void r4(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 514{ 515 p.setAlpha(0x60); 516 rastBuilder->addLayer(p, SkIntToScalar(3), SkIntToScalar(3)); 517 518 p.setAlpha(0xFF); 519 p.setBlendMode(SkBlendMode::kClear); 520 rastBuilder->addLayer(p, SK_Scalar1*3/2, SK_Scalar1*3/2); 521 522 p.setBlendMode(SkBlendMode::kSrcOver); 523 rastBuilder->addLayer(p); 524} 525 526#include "SkDiscretePathEffect.h" 527 528static void r5(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 529{ 530 rastBuilder->addLayer(p); 531 532 p.setPathEffect(SkDiscretePathEffect::Make(SK_Scalar1*4, SK_Scalar1*3)); 533 p.setBlendMode(SkBlendMode::kSrcOut); 534 rastBuilder->addLayer(p); 535} 536 537static void r6(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 538{ 539 rastBuilder->addLayer(p); 540 541 p.setAntiAlias(false); 542 SkLayerRasterizer::Builder rastBuilder2; 543 r5(&rastBuilder2, p); 544 p.setRasterizer(rastBuilder2.detach()); 545 p.setBlendMode(SkBlendMode::kClear); 546 rastBuilder->addLayer(p); 547} 548 549#include "Sk2DPathEffect.h" 550 551static sk_sp<SkPathEffect> MakeDotEffect(SkScalar radius, const SkMatrix& matrix) { 552 SkPath path; 553 path.addCircle(0, 0, radius); 554 return SkPath2DPathEffect::Make(matrix, path); 555} 556 557static void r7(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 558{ 559 SkMatrix lattice; 560 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); 561 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 562 p.setPathEffect(MakeDotEffect(SK_Scalar1*4, lattice)); 563 rastBuilder->addLayer(p); 564} 565 566static void r8(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 567{ 568 rastBuilder->addLayer(p); 569 570 SkMatrix lattice; 571 lattice.setScale(SK_Scalar1*6, SK_Scalar1*6, 0, 0); 572 lattice.postSkew(SK_Scalar1/3, 0, 0, 0); 573 p.setPathEffect(MakeDotEffect(SK_Scalar1*2, lattice)); 574 p.setBlendMode(SkBlendMode::kClear); 575 rastBuilder->addLayer(p); 576 577 p.setPathEffect(nullptr); 578 p.setBlendMode(SkBlendMode::kSrcOver); 579 p.setStyle(SkPaint::kStroke_Style); 580 p.setStrokeWidth(SK_Scalar1); 581 rastBuilder->addLayer(p); 582} 583 584static void r9(SkLayerRasterizer::Builder* rastBuilder, SkPaint& p) 585{ 586 rastBuilder->addLayer(p); 587 588 SkMatrix lattice; 589 lattice.setScale(SK_Scalar1, SK_Scalar1*6, 0, 0); 590 lattice.postRotate(SkIntToScalar(30), 0, 0); 591 p.setPathEffect(SkLine2DPathEffect::Make(SK_Scalar1*2, lattice)); 592 p.setBlendMode(SkBlendMode::kClear); 593 rastBuilder->addLayer(p); 594 595 p.setPathEffect(nullptr); 596 p.setBlendMode(SkBlendMode::kSrcOver); 597 p.setStyle(SkPaint::kStroke_Style); 598 p.setStrokeWidth(SK_Scalar1); 599 rastBuilder->addLayer(p); 600} 601 602typedef void (*raster_proc)(SkLayerRasterizer::Builder*, SkPaint&); 603 604static const raster_proc gRastProcs[] = { 605 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9 606}; 607 608static void apply_shader(SkPaint* paint, int index) { 609 raster_proc proc = gRastProcs[index]; 610 SkPaint p; 611 SkLayerRasterizer::Builder rastBuilder; 612 613 p.setAntiAlias(true); 614 proc(&rastBuilder, p); 615 paint->setRasterizer(rastBuilder.detach()); 616 paint->setColor(SK_ColorBLUE); 617} 618 619#include "SkTypeface.h" 620 621static void texteffect_slide(SkCanvas* canvas) { 622 const char* str = "Google"; 623 size_t len = strlen(str); 624 SkScalar x = 20; 625 SkScalar y = 80; 626 SkPaint paint; 627 paint.setTypeface(SkTypeface::MakeFromName("Georgia", 628 SkFontStyle::FromOldStyle(SkTypeface::kItalic))); 629 paint.setTextSize(75); 630 paint.setAntiAlias(true); 631 paint.setColor(SK_ColorBLUE); 632 for (size_t i = 0; i < SK_ARRAY_COUNT(gRastProcs); i++) { 633 apply_shader(&paint, (int)i); 634 canvas->drawText(str, len, x, y, paint); 635 y += 80; 636 if (i == 4) { 637 x += 320; 638 y = 80; 639 } 640 } 641} 642 643/////////////////////////////////////////////////////////////////////////////// 644 645#include "SkImageEncoder.h" 646 647static const SlideProc gProc[] = { 648 patheffect_slide, 649 gradient_slide, 650 textonpath_slide, 651 mesh_slide, 652 texteffect_slide 653}; 654 655class SlideView : public SampleView { 656 int fIndex; 657 bool fOnce; 658public: 659 SlideView() { 660 fOnce = false; 661 } 662 663 void init() { 664 if (fOnce) { 665 return; 666 } 667 fOnce = true; 668 669 fIndex = 0; 670 671 SkBitmap bm; 672 bm.allocN32Pixels(1024, 768); 673 SkCanvas canvas(bm); 674 SkScalar s = SkIntToScalar(1024) / 640; 675 canvas.scale(s, s); 676 for (size_t i = 0; i < SK_ARRAY_COUNT(gProc); i++) { 677 canvas.save(); 678 canvas.drawColor(BG_COLOR); 679 gProc[i](&canvas); 680 canvas.restore(); 681 SkString str; 682 str.printf("/skimages/slide_" SK_SIZE_T_SPECIFIER ".png", i); 683 sk_tool_utils::EncodeImageToFile(str.c_str(), bm, SkEncodedImageFormat::kPNG, 100); 684 } 685 this->setBGColor(BG_COLOR); 686 } 687 688protected: 689 // overrides from SkEventSink 690 bool onQuery(SkEvent* evt) override { 691 if (SampleCode::TitleQ(*evt)) { 692 SampleCode::TitleR(evt, "Slides"); 693 return true; 694 } 695 return this->INHERITED::onQuery(evt); 696 } 697 698 void onDrawContent(SkCanvas* canvas) override { 699 this->init(); 700 gProc[fIndex](canvas); 701 } 702 703 SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned) override { 704 this->init(); 705 fIndex = (fIndex + 1) % SK_ARRAY_COUNT(gProc); 706 this->inval(nullptr); 707 return nullptr; 708 } 709 710private: 711 typedef SampleView INHERITED; 712}; 713 714////////////////////////////////////////////////////////////////////////////// 715 716static SkView* MyFactory() { return new SlideView; } 717static SkViewRegister reg(MyFactory); 718