1f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.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 */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SampleCode.h" 10339cdbfb754ff0837ad4772b4837543e1092d62freed#include "SkAnimTimer.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkView.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGradientShader.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkGraphics.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkImageDecoder.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkUtils.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkXfermode.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorPriv.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColorFilter.h" 23d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com#include "SkParsePath.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTime.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTypeface.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 27a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com#include "SkGeometry.h" 28a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com 29a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com// http://code.google.com/p/skia/issues/detail?id=32 30a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.comstatic void test_cubic() { 31a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com SkPoint src[4] = { 32261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com { 556.25000f, 523.03003f }, 33261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com { 556.23999f, 522.96002f }, 34261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com { 556.21997f, 522.89001f }, 35261b8e2ca1cf22303ad95267f0bdc6e87e1bbe70reed@google.com { 556.21997f, 522.82001f } 36a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com }; 37a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com SkPoint dst[11]; 38a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com dst[10].set(42, -42); // one past the end, that we don't clobber these 39a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com SkScalar tval[] = { 0.33333334f, 0.99999994f }; 40a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com 41a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com SkChopCubicAt(src, dst, tval, 2); 42a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com 43a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com#if 0 44a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com for (int i = 0; i < 11; i++) { 45a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com SkDebugf("--- %d [%g %g]\n", i, dst[i].fX, dst[i].fY); 46a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com } 47a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com#endif 48a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com} 49a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com 50d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.comstatic void test_cubic2() { 51d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com const char* str = "M2242 -590088L-377758 9.94099e+07L-377758 9.94099e+07L2242 -590088Z"; 52d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com SkPath path; 53d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com SkParsePath::FromSVGString(str, &path); 54ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 55d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com { 56f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#ifdef SK_BUILD_FOR_WIN 57f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com // windows doesn't have strtof 58f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com float x = (float)strtod("9.94099e+07", NULL); 59f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#else 60d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com float x = strtof("9.94099e+07", NULL); 61f2b98d67dcb6fcb3120feede9c72016fc7b3ead8reed@android.com#endif 62d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com int ix = (int)x; 63d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com int fx = (int)(x * 65536); 64d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com int ffx = SkScalarToFixed(x); 65fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com SkDebugf("%g %x %x %x\n", x, ix, fx, ffx); 66ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 67d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com SkRect r = path.getBounds(); 68d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com SkIRect ir; 69d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com r.round(&ir); 70fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com SkDebugf("[%g %g %g %g] [%x %x %x %x]\n", 71fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com SkScalarToDouble(r.fLeft), SkScalarToDouble(r.fTop), 72fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com SkScalarToDouble(r.fRight), SkScalarToDouble(r.fBottom), 73fab44db294846ff05d837b9cf0bf97a073891da7bungeman@google.com ir.fLeft, ir.fTop, ir.fRight, ir.fBottom); 74d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com } 75ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 76d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com SkBitmap bitmap; 77a8c183125f2861067daf432cada06d431a795cd0commit-bot@chromium.org bitmap.allocN32Pixels(300, 200); 78d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com 79d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com SkCanvas canvas(bitmap); 80d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com SkPaint paint; 81d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com paint.setAntiAlias(true); 82d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com canvas.drawPath(path, paint); 83d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com} 84d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com 850faac1e8579088a39f38d02ff675f14d7deb608dreed@google.comclass PathView : public SampleView { 86339cdbfb754ff0837ad4772b4837543e1092d62freed SkScalar fPrevSecs; 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 88339cdbfb754ff0837ad4772b4837543e1092d62freed SkScalar fDStroke, fStroke, fMinStroke, fMaxStroke; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath fPath[6]; 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fShowHairline; 91c9fa63c869d9216869da64c1defb150655ade3afreed@google.com bool fOnce; 92ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 93ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com PathView() { 94339cdbfb754ff0837ad4772b4837543e1092d62freed fPrevSecs = 0; 95c9fa63c869d9216869da64c1defb150655ade3afreed@google.com fOnce = false; 96c9fa63c869d9216869da64c1defb150655ade3afreed@google.com } 97ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 98c9fa63c869d9216869da64c1defb150655ade3afreed@google.com void init() { 99c9fa63c869d9216869da64c1defb150655ade3afreed@google.com if (fOnce) { 100c9fa63c869d9216869da64c1defb150655ade3afreed@google.com return; 101c9fa63c869d9216869da64c1defb150655ade3afreed@google.com } 102c9fa63c869d9216869da64c1defb150655ade3afreed@google.com fOnce = true; 103c9fa63c869d9216869da64c1defb150655ade3afreed@google.com 104a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com test_cubic(); 105d0d0e65a6313f01dfd952e8cc214a7c193bec57areed@android.com test_cubic2(); 106a964028843ec3f69b3b2e556426ff881d1fcb4b2reed@android.com 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShowHairline = false; 108ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDStroke = 1; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStroke = 10; 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMinStroke = 10; 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMaxStroke = 180; 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 114339cdbfb754ff0837ad4772b4837543e1092d62freed const SkScalar V = 85; 115ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 116339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[0].moveTo(40, 70); 117339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[0].lineTo(70, 70 + SK_ScalarHalf); 118339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[0].lineTo(110, 70); 119ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 120339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[1].moveTo(40, 70); 121339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[1].lineTo(70, 70 - SK_ScalarHalf); 122339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[1].lineTo(110, 70); 123ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 124339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[2].moveTo(V, V); 125339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[2].lineTo(50, V); 126339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[2].lineTo(50, 50); 127ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 128339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[3].moveTo(50, 50); 129339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[3].lineTo(50, V); 130339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[3].lineTo(V, V); 131ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 132339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[4].moveTo(50, 50); 133339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[4].lineTo(50, V); 134339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[4].lineTo(52, 50); 135ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 136339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[5].moveTo(52, 50); 137339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[5].lineTo(50, V); 138339cdbfb754ff0837ad4772b4837543e1092d62freed fPath[5].lineTo(50, 50); 139ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1400faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com this->setBGColor(0xFFDDDDDD); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 142ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides from SkEventSink 1450faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com virtual bool onQuery(SkEvent* evt) { 1460faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com if (SampleCode::TitleQ(*evt)) { 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SampleCode::TitleR(evt, "Paths"); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return this->INHERITED::onQuery(evt); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 152ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1530faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com void drawPath(SkCanvas* canvas, const SkPath& path, SkPaint::Join j) { 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint paint; 155ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setAntiAlias(true); 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStyle(SkPaint::kStroke_Style); 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStrokeJoin(j); 159339cdbfb754ff0837ad4772b4837543e1092d62freed paint.setStrokeWidth(fStroke); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1610faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com if (fShowHairline) { 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath fill; 163ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 164ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com paint.getFillPath(path, &fill); 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStrokeWidth(0); 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(fill, paint); 1670faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com } else { 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(path, paint); 1690faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com } 170ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setColor(SK_ColorRED); 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com paint.setStrokeWidth(0); 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->drawPath(path, paint); 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 175ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 176c9fa63c869d9216869da64c1defb150655ade3afreed@google.com virtual void onDrawContent(SkCanvas* canvas) { 177c9fa63c869d9216869da64c1defb150655ade3afreed@google.com this->init(); 178339cdbfb754ff0837ad4772b4837543e1092d62freed canvas->translate(50, 50); 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const SkPaint::Join gJoins[] = { 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::kBevel_Join, 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::kMiter_Join, 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPaint::kRound_Join 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 18664cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org for (size_t i = 0; i < SK_ARRAY_COUNT(gJoins); i++) { 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->save(); 18864cc579efa7e416c7298ed159d76b074b283c0f9senorblanco@chromium.org for (size_t j = 0; j < SK_ARRAY_COUNT(fPath); j++) { 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->drawPath(canvas, fPath[j], gJoins[i]); 190339cdbfb754ff0837ad4772b4837543e1092d62freed canvas->translate(200, 0); 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas->restore(); 193ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 194339cdbfb754ff0837ad4772b4837543e1092d62freed canvas->translate(0, 200); 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 196339cdbfb754ff0837ad4772b4837543e1092d62freed } 197339cdbfb754ff0837ad4772b4837543e1092d62freed 19836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onAnimate(const SkAnimTimer& timer) override { 199339cdbfb754ff0837ad4772b4837543e1092d62freed SkScalar currSecs = timer.scaled(100); 200339cdbfb754ff0837ad4772b4837543e1092d62freed SkScalar delta = currSecs - fPrevSecs; 201339cdbfb754ff0837ad4772b4837543e1092d62freed fPrevSecs = currSecs; 202339cdbfb754ff0837ad4772b4837543e1092d62freed 203339cdbfb754ff0837ad4772b4837543e1092d62freed fStroke += fDStroke * delta; 204339cdbfb754ff0837ad4772b4837543e1092d62freed if (fStroke > fMaxStroke || fStroke < fMinStroke) { 205339cdbfb754ff0837ad4772b4837543e1092d62freed fDStroke = -fDStroke; 206339cdbfb754ff0837ad4772b4837543e1092d62freed } 207339cdbfb754ff0837ad4772b4837543e1092d62freed return true; 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 209ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 21036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fShowHairline = !fShowHairline; 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->inval(NULL); 2134d5c26de0a24f86c37c1da8b0e30d11a550ea67breed@google.com return this->INHERITED::onFindClickHandler(x, y, modi); 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 215ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2170faac1e8579088a39f38d02ff675f14d7deb608dreed@google.com typedef SampleView INHERITED; 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 219a7a8b10134f78d4ed55ff0370a54d8141daa7cacreedDEF_SAMPLE( return new PathView; ) 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2238b5752443f34680d26a73bb6e1e72a8d7cf0f320reed#include "SkArcToPathEffect.h" 224a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed#include "SkCornerPathEffect.h" 225a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed#include "SkRandom.h" 226a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 227a7a8b10134f78d4ed55ff0370a54d8141daa7cacreedclass ArcToView : public SampleView { 2288b5752443f34680d26a73bb6e1e72a8d7cf0f320reed bool fDoFrame, fDoArcTo, fDoCorner, fDoConic; 2298b5752443f34680d26a73bb6e1e72a8d7cf0f320reed SkPaint fPtsPaint, fArcToPaint, fSkeletonPaint, fCornerPaint; 230a7a8b10134f78d4ed55ff0370a54d8141daa7cacreedpublic: 231a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed enum { 232a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed N = 4 233a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed }; 234a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed SkPoint fPts[N]; 235a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 2368b5752443f34680d26a73bb6e1e72a8d7cf0f320reed ArcToView() 2378b5752443f34680d26a73bb6e1e72a8d7cf0f320reed : fDoFrame(false), fDoArcTo(false), fDoCorner(false), fDoConic(false) 2388b5752443f34680d26a73bb6e1e72a8d7cf0f320reed { 239a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed SkRandom rand; 240a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed for (int i = 0; i < N; ++i) { 241a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fPts[i].fX = 20 + rand.nextUScalar1() * 640; 242a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fPts[i].fY = 20 + rand.nextUScalar1() * 480; 243a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 2448b5752443f34680d26a73bb6e1e72a8d7cf0f320reed 2458b5752443f34680d26a73bb6e1e72a8d7cf0f320reed const SkScalar rad = 50; 246a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 247a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fPtsPaint.setAntiAlias(true); 248a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fPtsPaint.setStrokeWidth(15); 249a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fPtsPaint.setStrokeCap(SkPaint::kRound_Cap); 250a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 2518b5752443f34680d26a73bb6e1e72a8d7cf0f320reed fArcToPaint.setAntiAlias(true); 2528b5752443f34680d26a73bb6e1e72a8d7cf0f320reed fArcToPaint.setStyle(SkPaint::kStroke_Style); 2538b5752443f34680d26a73bb6e1e72a8d7cf0f320reed fArcToPaint.setStrokeWidth(9); 2548b5752443f34680d26a73bb6e1e72a8d7cf0f320reed fArcToPaint.setColor(0x800000FF); 2558b5752443f34680d26a73bb6e1e72a8d7cf0f320reed fArcToPaint.setPathEffect(SkArcToPathEffect::Create(rad))->unref(); 256a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 257a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fCornerPaint.setAntiAlias(true); 258a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fCornerPaint.setStyle(SkPaint::kStroke_Style); 259a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fCornerPaint.setStrokeWidth(13); 260a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fCornerPaint.setColor(SK_ColorGREEN); 2618b5752443f34680d26a73bb6e1e72a8d7cf0f320reed fCornerPaint.setPathEffect(SkCornerPathEffect::Create(rad*2))->unref(); 262a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 263a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fSkeletonPaint.setAntiAlias(true); 264a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fSkeletonPaint.setStyle(SkPaint::kStroke_Style); 265a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fSkeletonPaint.setColor(SK_ColorRED); 266a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 267a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 2688b5752443f34680d26a73bb6e1e72a8d7cf0f320reed void toggle(bool& value) { 2698b5752443f34680d26a73bb6e1e72a8d7cf0f320reed value = !value; 2708b5752443f34680d26a73bb6e1e72a8d7cf0f320reed this->inval(NULL); 2718b5752443f34680d26a73bb6e1e72a8d7cf0f320reed } 2728b5752443f34680d26a73bb6e1e72a8d7cf0f320reed 273a7a8b10134f78d4ed55ff0370a54d8141daa7cacreedprotected: 274a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed // overrides from SkEventSink 27536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onQuery(SkEvent* evt) override { 276a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed if (SampleCode::TitleQ(*evt)) { 277a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed SampleCode::TitleR(evt, "ArcTo"); 278a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed return true; 279a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 2808b5752443f34680d26a73bb6e1e72a8d7cf0f320reed SkUnichar uni; 2818b5752443f34680d26a73bb6e1e72a8d7cf0f320reed if (SampleCode::CharQ(*evt, &uni)) { 2828b5752443f34680d26a73bb6e1e72a8d7cf0f320reed switch (uni) { 2838b5752443f34680d26a73bb6e1e72a8d7cf0f320reed case '1': this->toggle(fDoFrame); return true; 2848b5752443f34680d26a73bb6e1e72a8d7cf0f320reed case '2': this->toggle(fDoArcTo); return true; 2858b5752443f34680d26a73bb6e1e72a8d7cf0f320reed case '3': this->toggle(fDoCorner); return true; 2868b5752443f34680d26a73bb6e1e72a8d7cf0f320reed case '4': this->toggle(fDoConic); return true; 2878b5752443f34680d26a73bb6e1e72a8d7cf0f320reed default: break; 2888b5752443f34680d26a73bb6e1e72a8d7cf0f320reed } 2898b5752443f34680d26a73bb6e1e72a8d7cf0f320reed } 290a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed return this->INHERITED::onQuery(evt); 291a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 2928b5752443f34680d26a73bb6e1e72a8d7cf0f320reed 2938b5752443f34680d26a73bb6e1e72a8d7cf0f320reed void makePath(SkPath* path) { 2948b5752443f34680d26a73bb6e1e72a8d7cf0f320reed path->moveTo(fPts[0]); 2958b5752443f34680d26a73bb6e1e72a8d7cf0f320reed for (int i = 1; i < N; ++i) { 2968b5752443f34680d26a73bb6e1e72a8d7cf0f320reed path->lineTo(fPts[i]); 2978b5752443f34680d26a73bb6e1e72a8d7cf0f320reed } 2988b5752443f34680d26a73bb6e1e72a8d7cf0f320reed if (!fDoFrame) { 2998b5752443f34680d26a73bb6e1e72a8d7cf0f320reed path->close(); 3008b5752443f34680d26a73bb6e1e72a8d7cf0f320reed } 3018b5752443f34680d26a73bb6e1e72a8d7cf0f320reed } 302a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 30336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onDrawContent(SkCanvas* canvas) override { 304a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed canvas->drawPoints(SkCanvas::kPoints_PointMode, N, fPts, fPtsPaint); 305a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 306a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed SkPath path; 3078b5752443f34680d26a73bb6e1e72a8d7cf0f320reed this->makePath(&path); 308a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 3098b5752443f34680d26a73bb6e1e72a8d7cf0f320reed if (fDoCorner) { 3108b5752443f34680d26a73bb6e1e72a8d7cf0f320reed canvas->drawPath(path, fCornerPaint); 311a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 3128b5752443f34680d26a73bb6e1e72a8d7cf0f320reed if (fDoArcTo) { 3138b5752443f34680d26a73bb6e1e72a8d7cf0f320reed canvas->drawPath(path, fArcToPaint); 314a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 315a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 3168b5752443f34680d26a73bb6e1e72a8d7cf0f320reed canvas->drawPath(path, fSkeletonPaint); 317a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 318a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 31936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onClick(Click* click) override { 320a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed int32_t index; 321a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed if (click->fMeta.findS32("index", &index)) { 322a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed SkASSERT((unsigned)index < N); 323a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed fPts[index] = click->fCurr; 324a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed this->inval(NULL); 325a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed return true; 326a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 327a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed return false; 328a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 329a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 33036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { 331a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed const SkScalar tol = 4; 332a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed const SkRect r = SkRect::MakeXYWH(x - tol, y - tol, tol * 2, tol * 2); 333a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed for (int i = 0; i < N; ++i) { 334a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed if (r.intersects(SkRect::MakeXYWH(fPts[i].fX, fPts[i].fY, 1, 1))) { 335a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed Click* click = new Click(this); 336a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed click->fMeta.setS32("index", i); 337a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed return click; 338a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 339a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 340a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed return this->INHERITED::onFindClickHandler(x, y, modi); 341a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed } 342a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 343a7a8b10134f78d4ed55ff0370a54d8141daa7cacreedprivate: 344a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed typedef SampleView INHERITED; 345a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed}; 346a7a8b10134f78d4ed55ff0370a54d8141daa7cacreedDEF_SAMPLE( return new ArcToView; ) 347a7a8b10134f78d4ed55ff0370a54d8141daa7cacreed 348