1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 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 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDrawPath.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkAnimateMaker.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkCanvas.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMath.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrixParts.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPathParts.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comenum SkPath_Properties { 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PROPERTY(fillType), 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_PROPERTY(length) 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if SK_USE_CONDENSED_INFO == 0 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMemberInfo SkDrawPath::fInfo[] = { 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER(d, String), 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_PROPERTY(fillType, FillType), 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_PROPERTY(length, Float) 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comDEFINE_GET_MEMBER(SkDrawPath); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawPath::SkDrawPath() 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParent = NULL; 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLength = SK_ScalarNaN; 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fChildHasID = false; 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDirty = false; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDrawPath::~SkDrawPath() { 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete *part; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 481d3c411f5e4d2ad31bc92b3a85957004329ac00dtfarina@chromium.orgbool SkDrawPath::addChild(SkAnimateMaker& maker, SkDisplayable* child) { 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(child && child->isPathPart()); 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathPart* part = (SkPathPart*) child; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *fParts.append() = part; 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (part->add()) 53d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com maker.setErrorCode(SkDisplayXMLParserError::kErrorAddingToPath); 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDirty = false; 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 58d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.combool SkDrawPath::childrenNeedDisposing() const { 59d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return false; 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comvoid SkDrawPath::dirty() { 63d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com fDirty = true; 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLength = SK_ScalarNaN; 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fParent) 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParent->dirty(); 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDrawPath::draw(SkAnimateMaker& maker) { 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath& path = getPath(); 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBoundableAuto boundable(this, maker); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com maker.fCanvas->drawPath(path, *maker.fPaint); 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkDisplayable* SkDrawPath::getParent() const { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fParent; 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DUMP_ENABLED 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDrawPath::dump(SkAnimateMaker* maker) { 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpBase(maker); 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpAttrs(maker); 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool closedYet = false; 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayList::fIndent += 4; 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for(SkPathPart** part = fParts.begin(); part < fParts.end(); part++) { 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (closedYet == false) { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf(">\n"); 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com closedYet = true; 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (*part)->dump(maker); 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDisplayList::fIndent -= 4; 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (closedYet) 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dumpEnd(maker); 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("/>\n"); 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkPath& SkDrawPath::getPath() { 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fDirty == false) 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fPath; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (d.size() > 0) 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parseSVG(); 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com d.reset(); 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.reset(); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++) 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (*part)->add(); 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDirty = false; 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fPath; 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 118d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkDrawPath::onEndElement(SkAnimateMaker& ) { 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (d.size() > 0) { 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com parseSVG(); 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com d.reset(); 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDirty = false; 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (fChildHasID == false) { 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (SkPathPart** part = fParts.begin(); part < fParts.end(); part++) 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete *part; 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParts.reset(); 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fDirty = false; 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDrawPath::getProperty(int index, SkScriptValue* value) const { 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (index) { 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SK_PROPERTY(length): 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (SkScalarIsNaN(fLength)) { 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath& path = ((SkDrawPath*) this)->getPath(); 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathMeasure pathMeasure(path, false); 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fLength = pathMeasure.getLength(); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_Float; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fScalar = fLength; 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SK_PROPERTY(fillType): 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fType = SkType_FillType; 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value->fOperand.fS32 = (int) fPath.getFillType(); 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 156d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.comvoid SkDrawPath::setChildHasID() { 157d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com fChildHasID = true; 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDrawPath::setParent(SkDisplayable* parent) { 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fParent = parent; 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool SkDrawPath::setProperty(int index, SkScriptValue& value) 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com switch (index) { 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com case SK_PROPERTY(fillType): 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(value.fType == SkType_FillType); 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(value.fOperand.fS32 >= SkPath::kWinding_FillType && 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com value.fOperand.fS32 <= SkPath::kEvenOdd_FillType); 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.setFillType((SkPath::FillType) value.fOperand.fS32); 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com default: 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(0); 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if SK_USE_CONDENSED_INFO == 0 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMemberInfo SkPolyline::fInfo[] = { 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_ARRAY(points, Float) 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comDEFINE_GET_MEMBER(SkPolyline); 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1911d3c411f5e4d2ad31bc92b3a85957004329ac00dtfarina@chromium.orgbool SkPolyline::addChild(SkAnimateMaker& , SkDisplayable*) { 192d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com return false; 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPolyline::onEndElement(SkAnimateMaker& maker) { 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED::onEndElement(maker); 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (points.count() <= 0) 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.reset(); 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.moveTo(points[0], points[1]); 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = points.count(); 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int index = 2; index < count; index += 2) 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.lineTo(points[index], points[index+1]); 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if SK_USE_CONDENSED_INFO == 0 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comconst SkMemberInfo SkPolygon::fInfo[] = { 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SK_MEMBER_INHERITED 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comDEFINE_GET_MEMBER(SkPolygon); 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkPolygon::onEndElement(SkAnimateMaker& maker) { 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com INHERITED::onEndElement(maker); 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.close(); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 221