1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 776113a9b7716748c70ea0ecf7aacbabe4cce5009reed 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h" 976113a9b7716748c70ea0ecf7aacbabe4cce5009reed#include "SkAnimTimer.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "Sk1DPathEffect.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCornerPathEffect.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathMeasure.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPixelXorXfermode.h" 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define CORNER_RADIUS 12 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic const int gXY[] = { 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30d9adfe6a223955bc69c8c7661ab8e0a078afbc32reedstatic SkPathEffect* make_pe(int flags, SkScalar phase) { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags == 1) 320a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org return SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.offset(SkIntToScalar(-6), 0); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 41d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed SkPathEffect* outer = SkPath1DPathEffect::Create(path, 12, phase, 42d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed SkPath1DPathEffect::kRotate_Style); 43ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (flags == 2) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return outer; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 470a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 490a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkPathEffect* pe = SkComposePathEffect::Create(outer, inner); 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com outer->unref(); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inner->unref(); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return pe; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 55d9adfe6a223955bc69c8c7661ab8e0a078afbc32reedstatic SkPathEffect* make_warp_pe(SkScalar phase) { 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath path; 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.close(); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path.offset(SkIntToScalar(-6), 0); 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 630a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkPathEffect* outer = SkPath1DPathEffect::Create( 64d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed path, 12, phase, SkPath1DPathEffect::kMorph_Style); 650a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 670a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org SkPathEffect* pe = SkComposePathEffect::Create(outer, inner); 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com outer->unref(); 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com inner->unref(); 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return pe; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////// 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkLayerRasterizer.h" 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 78f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.orgclass TestRastBuilder : public SkLayerRasterizer::Builder { 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 80f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.org TestRastBuilder() { 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setAntiAlias(true); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setAlpha(0x66); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->addLayer(paint, SkIntToScalar(4), SkIntToScalar(4)); 86ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setAlpha(0xFF); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->addLayer(paint); 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 92e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.comclass PathEffectView : public SampleView { 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath fPath; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint fClickPt; 95d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed SkScalar fPhase; 96d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 98d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed PathEffectView() : fPhase(0) { 9963c684a8a609d39da11b4a656223cebf52ca85dccaryclark } 10063c684a8a609d39da11b4a656223cebf52ca85dccaryclark 10163c684a8a609d39da11b4a656223cebf52ca85dccaryclarkprotected: 10236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onOnceBeforeDraw() override { 103e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom rand; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int steps = 20; 10592a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com SkScalar dist = SkIntToScalar(400); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x = SkIntToScalar(20); 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar y = SkIntToScalar(50); 108ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.moveTo(x, y); 110f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com for (int i = 0; i < steps; i++) { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x += dist/steps; 11292a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25); 11392a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com if (i == steps/2) { 11492a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com fPath.moveTo(x, tmpY); 11592a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com } else { 11692a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com fPath.lineTo(x, tmpY); 11792a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com } 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12092a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com { 12192a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com SkRect oval; 12292a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com oval.set(SkIntToScalar(20), SkIntToScalar(30), 12392a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com SkIntToScalar(100), SkIntToScalar(60)); 12492a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com oval.offset(x, 0); 12592a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8)); 12692a50eaab977543031f12a1b0b1d4ce07f80ba75reed@android.com } 127ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClickPt.set(SkIntToScalar(200), SkIntToScalar(200)); 129ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 130e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com this->setBGColor(0xFFDDDDDD); 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 132ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 13336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onQuery(SkEvent* evt) override { 134f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com if (SampleCode::TitleQ(*evt)) { 135f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com SampleCode::TitleR(evt, "PathEffects"); 136f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return true; 137f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com } 138f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com return this->INHERITED::onQuery(evt); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 140ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 14136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDrawContent(SkCanvas* canvas) override { 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 143ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 144d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed canvas->translate(0, 50); 145ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(SK_ColorBLUE); 147d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed paint.setPathEffect(make_pe(2, fPhase))->unref(); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(fPath, paint); 149ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 150d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed canvas->translate(0, 50); 151ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(0xFF, 0, 0xBB, 0); 153d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed paint.setPathEffect(make_pe(3, fPhase))->unref(); 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(fPath, paint); 155ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 156d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed canvas->translate(0, 50); 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setARGB(0xFF, 0, 0, 0); 159d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed paint.setPathEffect(make_warp_pe(fPhase))->unref(); 160f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.org TestRastBuilder testRastBuilder; 161f792a1b20747f769b28906a4b00fd67691ce8d0bcommit-bot@chromium.org paint.setRasterizer(testRastBuilder.detachRasterizer())->unref(); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(fPath, paint); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 164ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 16536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onAnimate(const SkAnimTimer& timer) override { 16676113a9b7716748c70ea0ecf7aacbabe4cce5009reed fPhase = timer.scaled(40); 167d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed return true; 168d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed } 169d9adfe6a223955bc69c8c7661ab8e0a078afbc32reed 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 171e5ff43906603dff33e14086cf1e5d73c157d2e8ereed@google.com typedef SampleView INHERITED; 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new PathEffectView; } 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory); 178