SkPathEffect.h revision 548a1f321011292359ef163f78c8a1d4871b3b7f
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.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. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkPathEffect_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPathEffect_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFlattenable.h" 14629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com#include "SkPath.h" 15629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com#include "SkPoint.h" 16629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com#include "SkRect.h" 175f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h" 18629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com#include "SkTDArray.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkPath; 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkPathEffect 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect is the base class for objects in the SkPaint that affect 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the geometry of a drawing primitive before it is transformed by the 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com canvas' matrix and drawn. 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Dashing is implemented as a subclass of SkPathEffect. 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 307ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkPathEffect : public SkFlattenable { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 320456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com SK_DECLARE_INST_COUNT(SkPathEffect) 330456e0b7b85060e9b9597ce414c4c2b19aff4f58robertphillips@google.com 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect() {} 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 36fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com /** 37fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * Given a src path (input) and a stroke-rec (input and output), apply 38fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * this effect to the src path, returning the new path in dst, and return 39fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * true. If this effect cannot be applied, return false and ignore dst 40fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * and stroke-rec. 41fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * 42fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * The stroke-rec specifies the initial request for stroking (if any). 43fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * The effect can treat this as input only, or it can choose to change 44fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * the rec as well. For example, the effect can decide to change the 45fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * stroke's width or join, or the effect can change the rec from stroke 46fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * to fill (or fill to stroke) in addition to returning a new (dst) path. 47fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * 48fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * If this method returns true, the caller will apply (as needed) the 49fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com * resulting stroke-rec to dst and then draw. 50fd4be26c4202ae91f0f7cf2c03e44b5169d885ebreed@google.com */ 51548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com virtual bool filterPath(SkPath* dst, const SkPath& src, 52548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com SkStrokeRec*) const = 0; 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com /** 55e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com * Compute a conservative bounds for its effect, given the src bounds. 56e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com * The baseline implementation just assigns src to dst. 57e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com */ 58548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com virtual void computeFastBounds(SkRect* dst, const SkRect& src) const; 59e4f10a70807166484e5a6303a5cd0034e5e87abareed@google.com 60629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com /** \class PointData 61629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 62629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com PointData aggregates all the information needed to draw the point 63687c57c7d5a17549f63e0b15208db18b220e2a91skia.committer@gmail.com primitives returned by an 'asPoints' call. 64629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com */ 65629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com class PointData { 66629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com public: 67629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com PointData() 68935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com : fFlags(0) 69935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com , fPoints(NULL) 70935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com , fNumPoints(0) { 71629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com fSize.set(SK_Scalar1, SK_Scalar1); 72687c57c7d5a17549f63e0b15208db18b220e2a91skia.committer@gmail.com // 'asPoints' needs to initialize/fill-in 'fClipRect' if it sets 73629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com // the kUseClip flag 74629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com }; 75935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com ~PointData() { 76935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com delete [] fPoints; 77935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com } 78629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 79629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com // TODO: consider using passed-in flags to limit the work asPoints does. 80629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com // For example, a kNoPath flag could indicate don't bother generating 81629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com // stamped solutions. 82629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 83629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com // Currently none of these flags are supported. 84629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com enum PointFlags { 85629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com kCircles_PointFlag = 0x01, // draw points as circles (instead of rects) 86629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com kUsePath_PointFlag = 0x02, // draw points as stamps of the returned path 87629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com kUseClip_PointFlag = 0x04, // apply 'fClipRect' before drawing the points 88629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com }; 89629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 90629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com uint32_t fFlags; // flags that impact the drawing of the points 91935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com SkPoint* fPoints; // the center point of each generated point 92935ad026826fb7d31d562ff7326b84ec3a827456robertphillips@google.com int fNumPoints; // number of points in fPoints 93629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com SkVector fSize; // the size to draw the points 94629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com SkRect fClipRect; // clip required to draw the points (if kUseClip is set) 95629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com SkPath fPath; // 'stamp' to be used at each point (if kUsePath is set) 966d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com 976d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkPath fFirst; // If not empty, contains geometry for first point 986d87557278052c131957e5d6e093d3a675162d22robertphillips@google.com SkPath fLast; // If not empty, contains geometry for last point 99629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com }; 100629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 101629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com /** 102629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com * Does applying this path effect to 'src' yield a set of points? If so, 103629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com * optionally return the points in 'results'. 104629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com */ 105687c57c7d5a17549f63e0b15208db18b220e2a91skia.committer@gmail.com virtual bool asPoints(PointData* results, const SkPath& src, 106629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com const SkStrokeRec&, const SkMatrix&) const; 107629ab540667422d3edcb97c51e9628b7051e1ba4robertphillips@google.com 108ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.comprotected: 109ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SkPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 110ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // illegal 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect(const SkPathEffect&); 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect& operator=(const SkPathEffect&); 115ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com 116ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com typedef SkFlattenable INHERITED; 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkPairPathEffect 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Common baseclass for Compose and Sum. This subclass manages two pathEffects, 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com including flattening them. It does nothing in filterPath, and is only useful 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for managing the lifetimes of its two arguments. 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkPairPathEffect : public SkPathEffect { 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual ~SkPairPathEffect(); 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprotected: 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPairPathEffect(SkFlattenableReadBuffer&); 13254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; 13354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // these are visible to our subclasses 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPathEffect* fPE0, *fPE1; 136fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkPathEffect INHERITED; 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkComposePathEffect 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This subclass of SkPathEffect composes its two arguments, to create 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a compound pathEffect. 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkComposePathEffect : public SkPairPathEffect { 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Construct a pathEffect whose effect is to apply first the inner pathEffect 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and the the outer pathEffect (e.g. outer(inner(path))) 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The reference counts for outer and inner are both incremented in the constructor, 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and decremented in the destructor. 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner) 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(outer, inner) {} 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 156548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com virtual bool filterPath(SkPath* dst, const SkPath& src, 157548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com SkStrokeRec*) const SK_OVERRIDE; 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 159ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect) 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16154924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comprotected: 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkComposePathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 16454924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comprivate: 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // illegal 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkComposePathEffect(const SkComposePathEffect&); 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkComposePathEffect& operator=(const SkComposePathEffect&); 168fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkPairPathEffect INHERITED; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkSumPathEffect 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This subclass of SkPathEffect applies two pathEffects, one after the other. 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Its filterPath() returns true if either of the effects succeeded. 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkSumPathEffect : public SkPairPathEffect { 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Construct a pathEffect whose effect is to apply two effects, in sequence. 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (e.g. first(path) + second(path)) 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The reference counts for first and second are both incremented in the constructor, 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and decremented in the destructor. 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSumPathEffect(SkPathEffect* first, SkPathEffect* second) 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(first, second) {} 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 187548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com virtual bool filterPath(SkPath* dst, const SkPath& src, 188548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com SkStrokeRec*) const SK_OVERRIDE; 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 190ba28d03e94dc221d6a803bf2a84a420b9159255cdjsollen@google.com SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect) 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comprotected: 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSumPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19554924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comprivate: 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // illegal 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSumPathEffect(const SkSumPathEffect&); 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkSumPathEffect& operator=(const SkSumPathEffect&); 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkPairPathEffect INHERITED; 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 205