1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h" 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCornerPathEffect.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCullPoints.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRandom.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 20961ddb04a0a7aba843032d829ab867518e52559ereed@google.comstatic void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump) { 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkVector tang; 22ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tang.setLength(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY, bump); 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path->lineTo(SkScalarHalf(pts[0].fX + pts[1].fX) - tang.fY, 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalarHalf(pts[0].fY + pts[1].fY) + tang.fX); 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path->lineTo(pts[1]); 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 30961ddb04a0a7aba843032d829ab867518e52559ereed@google.comstatic void subdivide(SkPath* path, SkScalar bump) { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath::Iter iter(*path, false); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[4]; 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath tmp; 34ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (iter.next(pts)) { 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kMove_Verb: 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tmp.moveTo(pts[0]); 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kLine_Verb: 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com addbump(&tmp, pts, bump); 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bump = -bump; 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kDone_Verb: 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com goto FINISH; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comFINISH: 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path->swap(tmp); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54961ddb04a0a7aba843032d829ab867518e52559ereed@google.comstatic SkIPoint* getpts(const SkPath& path, int* count) { 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint pts[4]; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int n = 1; 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIPoint* array; 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath::Iter iter(path, false); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (iter.next(pts)) { 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kLine_Verb: 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n += 1; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kDone_Verb: 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com goto FINISHED; 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comFINISHED: 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com array = new SkIPoint[n]; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com n = 0; 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath::Iter iter(path, false); 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (;;) 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (iter.next(pts)) { 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kMove_Verb: 82e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com array[n++].set(SkScalarRoundToInt(pts[0].fX), 83e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com SkScalarRoundToInt(pts[0].fY)); 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kLine_Verb: 86e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com array[n++].set(SkScalarRoundToInt(pts[1].fX), 87e1ca705cac4b946993f6cbf798e2a0ba27e739f3reed@google.com SkScalarRoundToInt(pts[1].fY)); 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SkPath::kDone_Verb: 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com goto FINISHED2; 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 95ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comFINISHED2: 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *count = n; 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return array; 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 101e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) { 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return min + SkScalarMul(rand.nextUScalar1(), max - min); 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 105961ddb04a0a7aba843032d829ab867518e52559ereed@google.comclass CullView : public SampleView { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 107ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com CullView() { 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160)); 109ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 110e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org SkRandom rand; 111ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 50; i++) { 113261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2); 114261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (i == 0) 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.moveTo(x, y); 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.lineTo(x, y); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 120ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar bump = fClip.width()/8; 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com subdivide(&fPath, bump); 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com subdivide(&fPath, bump); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com subdivide(&fPath, bump); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPoints = getpts(fPath, &fPtCount); 126ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 127961ddb04a0a7aba843032d829ab867518e52559ereed@google.com this->setBGColor(0xFFDDDDDD); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 129ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 130961ddb04a0a7aba843032d829ab867518e52559ereed@google.com virtual ~CullView() { 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete[] fPoints; 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides from SkEventSink 136961ddb04a0a7aba843032d829ab867518e52559ereed@google.com virtual bool onQuery(SkEvent* evt) { 137961ddb04a0a7aba843032d829ab867518e52559ereed@google.com if (SampleCode::TitleQ(*evt)) { 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SampleCode::TitleR(evt, "Culling"); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->INHERITED::onQuery(evt); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 143ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 144961ddb04a0a7aba843032d829ab867518e52559ereed@google.com virtual void onDrawContent(SkCanvas* canvas) { 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoCanvasRestore ar(canvas, true); 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->translate( SkScalarHalf(this->width() - fClip.width()), 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalarHalf(this->height() - fClip.height())); 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // canvas->scale(SK_Scalar1*3, SK_Scalar1*3, 0, 0); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 153ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // paint.setAntiAliasOn(true); 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStyle(SkPaint::kStroke_Style); 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawRect(fClip, paint); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 1 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(0xFF555555); 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStrokeWidth(SkIntToScalar(2)); 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// paint.setPathEffect(new SkCornerPathEffect(SkIntToScalar(30)))->unref(); 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(fPath, paint); 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// paint.setPathEffect(NULL); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath tmp; 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect iclip; 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fClip.round(&iclip); 170ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkCullPointsPath cpp(iclip, &tmp); 172ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com cpp.moveTo(fPoints[0].fX, fPoints[0].fY); 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < fPtCount; i++) 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com cpp.lineTo(fPoints[i].fX, fPoints[i].fY); 176ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(SK_ColorRED); 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStrokeWidth(SkIntToScalar(3)); 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStrokeJoin(SkPaint::kRound_Join); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(tmp, paint); 181ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->inval(NULL); 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 184ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRect fClip; 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIPoint* fPoints; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath fPath; 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int fPtCount; 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 191961ddb04a0a7aba843032d829ab867518e52559ereed@google.com typedef SampleView INHERITED; 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkView* MyFactory() { return new CullView; } 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkViewRegister reg(MyFactory); 198