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 SkPath_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPath_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#include "SkInstCnt.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMatrix.h" 15ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com#include "SkPathRef.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTDArray.h" 171dfe88e00aeddf20690fd2469fd17e43f670ee3absalomon@google.com#include "SkRefCnt.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 19739456585a0cc52b335cd1c0a9fc6b01782a7f89reed@google.comclass SkReader32; 20739456585a0cc52b335cd1c0a9fc6b01782a7f89reed@google.comclass SkWriter32; 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkAutoPathBoundsUpdate; 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkString; 234ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.comclass SkRRect; 2466a5d8bf13fe98baae268db0211e9c25e5ece7facaryclarkclass SkWStream; 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkPath 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The SkPath class encapsulates compound (multiple contour) geometric paths 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com consisting of straight line segments, quadratic curves, and cubic curves. 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 317ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkPath { 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com SK_DECLARE_INST_COUNT_ROOT(SkPath); 3465a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath(); 361ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org SkPath(const SkPath&); 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ~SkPath(); 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 391ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org SkPath& operator=(const SkPath&); 405e728450247c677343e072f37150967b36892573bsalomon@google.com friend SK_API bool operator==(const SkPath&, const SkPath&); 413abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com friend bool operator!=(const SkPath& a, const SkPath& b) { 423abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com return !(a == b); 433abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com } 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum FillType { 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Specifies that "inside" is computed by a non-zero sum of signed 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com edge crossings 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kWinding_FillType, 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Specifies that "inside" is computed by an odd number of edge 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com crossings 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kEvenOdd_FillType, 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Same as Winding, but draws outside of the path, rather than inside 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kInverseWinding_FillType, 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Same as EvenOdd, but draws outside of the path, rather than inside 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kInverseEvenOdd_FillType 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the path's fill type. This is used to define how "inside" is 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computed. The default value is kWinding_FillType. 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @return the path's fill type 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FillType getFillType() const { return (FillType)fFillType; } 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the path's fill type. This is used to define how "inside" is 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com computed. The default value is kWinding_FillType. 71b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param ft The new fill type for this path 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 74f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com void setFillType(FillType ft) { 75f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com fFillType = SkToU8(ft); 76f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the filltype is one of the Inverse variants */ 795f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com bool isInverseFillType() const { return IsInverseFillType((FillType)fFillType); } 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 81b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com /** 82b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * Toggle between inverse and normal filltypes. This reverse the return 83b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * value of isInverseFillType() 84b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com */ 85f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com void toggleInverseFillType() { 86f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com fFillType ^= 2; 876b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com } 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com enum Convexity { 9004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com kUnknown_Convexity, 9104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com kConvex_Convexity, 9204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com kConcave_Convexity 9304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com }; 9404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com 9504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com /** 9630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com * Return the path's convexity, as stored in the path. If it is currently unknown, 9730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com * then this function will attempt to compute the convexity (and cache the result). 98b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com */ 99b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com Convexity getConvexity() const { 10030c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com if (kUnknown_Convexity != fConvexity) { 10130c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com return static_cast<Convexity>(fConvexity); 10230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com } else { 10330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com return this->internalGetConvexity(); 104b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com } 105b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com } 106b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com 107b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com /** 108b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * Return the currently cached value for convexity, even if that is set to 109b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * kUnknown_Convexity. Note: getConvexity() will automatically call 110b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * ComputeConvexity and cache its return value if the current setting is 111b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * kUnknown. 11204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com */ 113b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; } 11404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com 11504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com /** 11604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com * Store a convexity setting in the path. There is no automatic check to 11730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com * see if this value actually agrees with the return value that would be 11830c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com * computed by getConvexity(). 119b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * 120b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * Note: even if this is set to a "known" value, if the path is later 121b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * changed (e.g. lineTo(), addRect(), etc.) then the cached value will be 122b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com * reset to kUnknown_Convexity. 12304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com */ 12404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com void setConvexity(Convexity); 12504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com 12604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com /** 12704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com * Returns true if the path is flagged as being convex. This is not a 12804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com * confirmed by any analysis, it is just the value set earlier. 12904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com */ 13004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com bool isConvex() const { 13104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com return kConvex_Convexity == this->getConvexity(); 13204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com } 13304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com 13404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com /** 13504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com * Set the isConvex flag to true or false. Convex paths may draw faster if 13604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com * this flag is set, though setting this to true on a path that is in fact 13704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com * not convex can give undefined results when drawn. Paths default to 13804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com * isConvex == false 1396b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com */ 1404469938e92d779dff05e745559e67907bbf21e78reed@google.com SK_ATTR_DEPRECATED("use setConvexity") 141f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com void setIsConvex(bool isConvex) { 14204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity); 143f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com } 1446b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com 1456aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com /** Returns true if the path is an oval. 1466aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * 1476aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * @param rect returns the bounding rect of this oval. It's a circle 1486aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * if the height and width are the same. 1496aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * 1506aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * @return true if this path is an oval. 1516aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * Tracking whether a path is an oval is considered an 1526aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * optimization for performance and so some paths that are in 1536aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com * fact ovals can report false. 1546aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com */ 155466310dbd3073add2ec934e336c30deaaf702eaerobertphillips@google.com bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); } 1566aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Clear any lines and curves from the path, making it empty. This frees up 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com internal storage associated with those segments. 159cb8b0eeacfc2ff79a2b9721e3ef21d1efb507dc8mtklein@google.com On Android, does not change fSourcePath. 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void reset(); 162fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Similar to reset(), in that all lines and curves are removed from the 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path. However, any internal storage for those lines/curves is retained, 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com making reuse of the path potentially faster. 166cb8b0eeacfc2ff79a2b9721e3ef21d1efb507dc8mtklein@google.com On Android, does not change fSourcePath. 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rewind(); 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the path is empty (contains no lines or curves) 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @return true if the path is empty (contains no lines or curves) 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 174ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com bool isEmpty() const { 175ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkDEBUGCODE(this->validate();) 176ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com return 0 == fPathRef->countVerbs(); 177ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com } 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1790bb18bb264b26afca45452910437c09445e23a3creed@google.com /** 1800bb18bb264b26afca45452910437c09445e23a3creed@google.com * Returns true if all of the points in this path are finite, meaning there 1810bb18bb264b26afca45452910437c09445e23a3creed@google.com * are no infinities and no NaNs. 1820bb18bb264b26afca45452910437c09445e23a3creed@google.com */ 1830bb18bb264b26afca45452910437c09445e23a3creed@google.com bool isFinite() const { 184ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkDEBUGCODE(this->validate();) 185ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com return fPathRef->isFinite(); 1860bb18bb264b26afca45452910437c09445e23a3creed@google.com } 1870bb18bb264b26afca45452910437c09445e23a3creed@google.com 1884da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org /** Test a line for zero length 1894da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org 1904da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org @return true if the line is of zero length; otherwise false. 1914da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org */ 1924da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2) { 19394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com return p1.equalsWithinTolerance(p2); 1944da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org } 1954da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org 1964da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org /** Test a quad for zero length 1974da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org 1984da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org @return true if the quad is of zero length; otherwise false. 1994da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org */ 2004da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2, 2014da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org const SkPoint& p3) { 20294fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com return p1.equalsWithinTolerance(p2) && 20394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com p2.equalsWithinTolerance(p3); 2044da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org } 2054da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org 2064da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org /** Test a cubic curve for zero length 2074da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org 2084da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org @return true if the cubic is of zero length; otherwise false. 2094da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org */ 2104da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2, 2114da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org const SkPoint& p3, const SkPoint& p4) { 21294fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com return p1.equalsWithinTolerance(p2) && 21394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com p2.equalsWithinTolerance(p3) && 21494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com p3.equalsWithinTolerance(p4); 2154da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org } 2164da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org 2177e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com /** 2187e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com * Returns true if the path specifies a single line (i.e. it contains just 2197e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com * a moveTo and a lineTo). If so, and line[] is not null, it sets the 2 2207e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com * points in line[] to the end-points of the line. If the path is not a 2217e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com * line, returns false and ignores line[]. 2227e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com */ 2237e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com bool isLine(SkPoint line[2]) const; 2247e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the path specifies a rectangle. If so, and if rect is 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com not null, set rect to the bounds of the path. If the path does not 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com specify a rectangle, return false and ignore rect. 228fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param rect If not null, returns the bounds of the path if it specifies 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a rectangle 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @return true if the path specifies a rectangle 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2338fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com bool isRect(SkRect* rect) const; 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 235d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com /** Return the number of points in the path 236d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com */ 2371dfe88e00aeddf20690fd2469fd17e43f670ee3absalomon@google.com int countPoints() const; 238d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com 239d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com /** Return the point at the specified index. If the index is out of range 240d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com (i.e. is not 0 <= index < countPoints()) then the returned coordinates 241d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com will be (0,0) 242d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com */ 243d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com SkPoint getPoint(int index) const; 244d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns the number of points in the path. Up to max points are copied. 246fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param points If not null, receives up to max points 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param max The maximum number of points to copy into points 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @return the actual number of points in the path 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int getPoints(SkPoint points[], int max) const; 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 253df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com /** Return the number of verbs in the path 254df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com */ 2551dfe88e00aeddf20690fd2469fd17e43f670ee3absalomon@google.com int countVerbs() const; 256df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com 257df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com /** Returns the number of verbs in the path. Up to max verbs are copied. The 258df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com verbs are copied as one byte per verb. 259fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 260df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com @param verbs If not null, receives up to max verbs 261df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com @param max The maximum number of verbs to copy into verbs 262df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com @return the actual number of verbs in the path 263df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com */ 264df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com int getVerbs(uint8_t verbs[], int max) const; 265df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //! Swap contents of this and other. Guaranteed not to throw 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void swap(SkPath& other); 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 269d252db03d9650013b545ef9781fe993c07f8f314reed@android.com /** Returns the bounds of the path's points. If the path contains 0 or 1 270d252db03d9650013b545ef9781fe993c07f8f314reed@android.com points, the bounds is set to (0,0,0,0), and isEmpty() will return true. 271d252db03d9650013b545ef9781fe993c07f8f314reed@android.com Note: this bounds may be larger than the actual shape, since curves 272d252db03d9650013b545ef9781fe993c07f8f314reed@android.com do not extend as far as their control points. 273d252db03d9650013b545ef9781fe993c07f8f314reed@android.com */ 274d252db03d9650013b545ef9781fe993c07f8f314reed@android.com const SkRect& getBounds() const { 275ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com return fPathRef->getBounds(); 276d252db03d9650013b545ef9781fe993c07f8f314reed@android.com } 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Calling this will, if the internal cache of the bounds is out of date, 2799bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com update it so that subsequent calls to getBounds will be instantaneous. 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com This also means that any copies or simple transformations of the path 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com will inherit the cached bounds. 282d252db03d9650013b545ef9781fe993c07f8f314reed@android.com */ 283d252db03d9650013b545ef9781fe993c07f8f314reed@android.com void updateBoundsCache() const { 284d252db03d9650013b545ef9781fe993c07f8f314reed@android.com // for now, just calling getBounds() is sufficient 285d252db03d9650013b545ef9781fe993c07f8f314reed@android.com this->getBounds(); 286d252db03d9650013b545ef9781fe993c07f8f314reed@android.com } 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2889bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com /** 2899bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com * Does a conservative test to see whether a rectangle is inside a path. Currently it only 2909bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com * will ever return true for single convex contour paths. The empty-status of the rect is not 2919bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com * considered (e.g. a rect that is a point can be inside a path). Points or line segments where 2929bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com * the rect edge touches the path border are not considered containment violations. 2939bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com */ 2949bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com bool conservativelyContainsRect(const SkRect& rect) const; 2959bee33afbeca29f531c8455513b925f6e93da633bsalomon@google.com 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // Construction methods 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Hint to the path to prepare for adding more points. This can allow the 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com path to more efficiently grow its storage. 300fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param extraPtCount The number of extra points the path should 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com preallocate for. 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void incReserve(unsigned extraPtCount); 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the beginning of the next contour to the point (x,y). 307fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x The x-coordinate of the start of a new contour 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y The y-coordinate of the start of a new contour 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void moveTo(SkScalar x, SkScalar y); 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the beginning of the next contour to the point 314fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p The start of a new contour 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void moveTo(const SkPoint& p) { 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->moveTo(p.fX, p.fY); 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the beginning of the next contour relative to the last point on the 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com previous contour. If there is no previous contour, this is treated the 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com same as moveTo(). 324fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx The amount to add to the x-coordinate of the end of the 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com previous contour, to specify the start of a new contour 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dy The amount to add to the y-coordinate of the end of the 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com previous contour, to specify the start of a new contour 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rMoveTo(SkScalar dx, SkScalar dy); 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a line from the last point to the specified point (x,y). If no 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com moveTo() call has been made for this contour, the first point is 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com automatically set to (0,0). 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x The x-coordinate of the end of a line 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y The y-coordinate of the end of a line 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void lineTo(SkScalar x, SkScalar y); 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a line from the last point to the specified point. If no moveTo() 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com call has been made for this contour, the first point is automatically 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com set to (0,0). 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p The end of a line 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void lineTo(const SkPoint& p) { 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->lineTo(p.fX, p.fY); 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Same as lineTo, but the coordinates are considered relative to the last 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com point on this contour. If there is no previous point, then a moveTo(0,0) 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com is inserted automatically. 354fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx The amount to add to the x-coordinate of the previous point 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com on this contour, to specify a line 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dy The amount to add to the y-coordinate of the previous point 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com on this contour, to specify a line 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rLineTo(SkScalar dx, SkScalar dy); 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a quadratic bezier from the last point, approaching control point 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, the first point is automatically set to (0,0). 365fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x1 The x-coordinate of the control point on a quadratic curve 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y1 The y-coordinate of the control point on a quadratic curve 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x2 The x-coordinate of the end point on a quadratic curve 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y2 The y-coordinate of the end point on a quadratic curve 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2); 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a quadratic bezier from the last point, approaching control point 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com p1, and ending at p2. If no moveTo() call has been made for this 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com contour, the first point is automatically set to (0,0). 376fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p1 The control point on a quadratic curve 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p2 The end point on a quadratic curve 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void quadTo(const SkPoint& p1, const SkPoint& p2) { 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY); 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Same as quadTo, but the coordinates are considered relative to the last 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com point on this contour. If there is no previous point, then a moveTo(0,0) 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com is inserted automatically. 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx1 The amount to add to the x-coordinate of the last point on 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the control point of a quadratic curve 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dy1 The amount to add to the y-coordinate of the last point on 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the control point of a quadratic curve 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx2 The amount to add to the x-coordinate of the last point on 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the end point of a quadratic curve 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dy2 The amount to add to the y-coordinate of the last point on 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the end point of a quadratic curve 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2); 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 399277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com void conicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, 400277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com SkScalar w); 401277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com void conicTo(const SkPoint& p1, const SkPoint& p2, SkScalar w) { 402277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com this->conicTo(p1.fX, p1.fY, p2.fX, p2.fY, w); 403277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com } 404277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com void rConicTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2, 405277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com SkScalar w); 40626da7f00aedba107d4b3e382283034e265db09b6skia.committer@gmail.com 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a cubic bezier from the last point, approaching control points 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com made for this contour, the first point is automatically set to (0,0). 410fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x1 The x-coordinate of the 1st control point on a cubic curve 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y1 The y-coordinate of the 1st control point on a cubic curve 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x2 The x-coordinate of the 2nd control point on a cubic curve 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y2 The y-coordinate of the 2nd control point on a cubic curve 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x3 The x-coordinate of the end point on a cubic curve 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y3 The y-coordinate of the end point on a cubic curve 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar x3, SkScalar y3); 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a cubic bezier from the last point, approaching control points p1 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com and p2, and ending at p3. If no moveTo() call has been made for this 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com contour, the first point is automatically set to (0,0). 424fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p1 The 1st control point on a cubic curve 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p2 The 2nd control point on a cubic curve 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p3 The end point on a cubic curve 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) { 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY); 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Same as cubicTo, but the coordinates are considered relative to the 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com current point on this contour. If there is no previous point, then a 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com moveTo(0,0) is inserted automatically. 436fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx1 The amount to add to the x-coordinate of the last point on 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the 1st control point of a cubic curve 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dy1 The amount to add to the y-coordinate of the last point on 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the 1st control point of a cubic curve 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx2 The amount to add to the x-coordinate of the last point on 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the 2nd control point of a cubic curve 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dy2 The amount to add to the y-coordinate of the last point on 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the 2nd control point of a cubic curve 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx3 The amount to add to the x-coordinate of the last point on 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the end point of a cubic curve 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dy3 The amount to add to the y-coordinate of the last point on 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this contour, to specify the end point of a cubic curve 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4506b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, 4516b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com SkScalar x3, SkScalar y3); 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Append the specified arc to the path as a new contour. If the start of 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the path is different from the path's current last point, then an 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com automatic lineTo() is added to connect the current contour to the start 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com of the arc. However, if the path is empty, then we call moveTo() with 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com the first point of the arc. The sweep angle is treated mod 360. 458fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param oval The bounding oval defining the shape and size of the arc 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param startAngle Starting angle (in degrees) where the arc begins 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param sweepAngle Sweep angle (in degrees) measured clockwise. This is 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com treated mod 360. 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param forceMoveTo If true, always begin a new contour with the arc 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4656b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, 4666b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com bool forceMoveTo); 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Append a line and arc to the current path. This is the same as the 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com PostScript call "arct". 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalar radius); 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Append a line and arc to the current path. This is the same as the 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com PostScript call "arct". 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) { 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius); 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Close the current contour. If the current point is not equal to the 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com first point of the contour, a line segment is automatically added. 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void close(); 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4868fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com enum Direction { 4878fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com /** Direction either has not been or could not be computed */ 4888fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com kUnknown_Direction, 4898fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com /** clockwise direction for adding closed contours */ 4908fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com kCW_Direction, 4918fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com /** counter-clockwise direction for adding closed contours */ 4928fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com kCCW_Direction, 4938fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com }; 4948fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com 495a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com /** 496a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * Return the opposite of the specified direction. kUnknown is its own 497a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * opposite. 498a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com */ 49930c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com static Direction OppositeDirection(Direction dir) { 500a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com static const Direction gOppositeDir[] = { 501a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com kUnknown_Direction, kCCW_Direction, kCW_Direction 502a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com }; 503a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com return gOppositeDir[dir]; 50430c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com } 50530c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com 50669a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com /** 50712b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com * Returns whether or not a fill type is inverted 5085f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * 5095f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kWinding_FillType -> false 5105f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kEvenOdd_FillType -> false 5115f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kInverseWinding_FillType -> true 5125f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kInverseEvenOdd_FillType -> true 51312b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com */ 5145f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com static bool IsInverseFillType(FillType fill) { 51512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); 51612b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); 51712b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); 51812b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch); 51912b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com return (fill & 2) != 0; 52012b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com } 52112b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com 52212b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com /** 52312b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com * Returns the equivalent non-inverted fill type to the given fill type 5245f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * 5255f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kWinding_FillType -> kWinding_FillType 5265f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kEvenOdd_FillType -> kEvenOdd_FillType 5275f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kInverseWinding_FillType -> kWinding_FillType 5285f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com * kInverseEvenOdd_FillType -> kEvenOdd_FillType 52912b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com */ 5305f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com static FillType ConvertToNonInverseFillType(FillType fill) { 53112b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); 53212b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); 53312b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); 53412b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch); 53512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com return (FillType)(fill & 1); 53612b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com } 53712b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com 53812b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com /** 53969a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com * Tries to quickly compute the direction of the first non-degenerate 54069a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com * contour. If it can be computed, return true and set dir to that 54169a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com * direction. If it cannot be (quickly) determined, return false and ignore 54230c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com * the dir parameter. If the direction was determined, it is cached to make 54330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com * subsequent calls return quickly. 54469a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com */ 54569a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com bool cheapComputeDirection(Direction* dir) const; 54669a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com 54769a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com /** 54869a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com * Returns true if the path's direction can be computed via 54969a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com * cheapComputDirection() and if that computed direction matches the 550a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * specified direction. If dir is kUnknown, returns true if the direction 551a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * cannot be computed. 55269a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com */ 55369a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com bool cheapIsDirection(Direction dir) const { 554a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com Direction computedDir = kUnknown_Direction; 555a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com (void)this->cheapComputeDirection(&computedDir); 556a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com return computedDir == dir; 55769a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com } 55869a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com 559c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org enum PathAsRect { 560c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org /** The path can not draw the same as its bounds. */ 561c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org kNone_PathAsRect, 562c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org /** The path draws the same as its bounds when filled. */ 563c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org kFill_PathAsRect, 5647e90e8dbb96f2084f7dd4a6a20cb4b880b362438commit-bot@chromium.org /** The path draws the same as its bounds when stroked or filled. */ 5657e90e8dbb96f2084f7dd4a6a20cb4b880b362438commit-bot@chromium.org kStroke_PathAsRect, 566c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org }; 567c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org 568c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org /** Returns kFill_PathAsRect or kStroke_PathAsRect if drawing the path (either filled or 569c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org stroked) will be equivalent to filling/stroking the path's bounding rect. If 570c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org either is true, and direction is not null, sets the direction of the contour. If the 571c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org path is not drawn equivalent to a rect, returns kNone_PathAsRect and ignores direction. 572c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org 573c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org @param direction If not null, set to the contour's direction when it is drawn as a rect 574c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org @return the path's PathAsRect type 575c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org */ 576c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org PathAsRect asRect(Direction* direction = NULL) const; 577c2abd54edadf94bb86e1635a3515089e4a6a8eeecommit-bot@chromium.org 5788fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com /** Returns true if the path specifies a rectangle. If so, and if isClosed is 5798fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com not null, set isClosed to true if the path is closed. Also, if returning true 5808fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com and direction is not null, return the rect direction. If the path does not 5818fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com specify a rectangle, return false and ignore isClosed and direction. 5828fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com 5838fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com @param isClosed If not null, set to true if the path is closed 5848fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com @param direction If not null, set to the rectangle's direction 5858fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com @return true if the path specifies a rectangle 5868fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com */ 5878fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com bool isRect(bool* isClosed, Direction* direction) const; 5888fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com 5898fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com /** Returns true if the path specifies a pair of nested rectangles. If so, and if 5908fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com rect is not null, set rect[0] to the outer rectangle and rect[1] to the inner 5918fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com rectangle. If so, and dirs is not null, set dirs[0] to the direction of 5928fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com the outer rectangle and dirs[1] to the direction of the inner rectangle. If 5938fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com the path does not specify a pair of nested rectangles, return 5948fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com false and ignore rect and dirs. 5958fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com 5968fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com @param rect If not null, returns the path as a pair of nested rectangles 5978fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com @param dirs If not null, returns the direction of the rects 5988fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com @return true if the path describes a pair of nested rectangles 5998fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com */ 6008fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com bool isNestedRects(SkRect rect[2], Direction dirs[2] = NULL) const; 6018fd160350ca5f57fbb1b2e03383c5778414a9b48robertphillips@google.com 602a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com /** 603a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * Add a closed rectangle contour to the path 604a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param rect The rectangle to add as a closed contour to the path 605a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param dir The direction to wind the rectangle's contour. Cannot be 606a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * kUnknown_Direction. 607a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com */ 608ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com void addRect(const SkRect& rect, Direction dir = kCW_Direction); 6098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 610a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com /** 611a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * Add a closed rectangle contour to the path 612a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * 613a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param left The left side of a rectangle to add as a closed contour 614a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * to the path 615a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param top The top of a rectangle to add as a closed contour to the 616a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * path 617a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param right The right side of a rectangle to add as a closed contour 618a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * to the path 619a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param bottom The bottom of a rectangle to add as a closed contour to 620a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * the path 621a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param dir The direction to wind the rectangle's contour. Cannot be 622a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * kUnknown_Direction. 623a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com */ 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom, 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Direction dir = kCW_Direction); 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 627a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com /** 628a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * Add a closed oval contour to the path 629a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * 630a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param oval The bounding oval to add as a closed contour to the path 631a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param dir The direction to wind the oval's contour. Cannot be 632a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * kUnknown_Direction. 633a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com */ 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void addOval(const SkRect& oval, Direction dir = kCW_Direction); 6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 636a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com /** 637a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * Add a closed circle contour to the path 638a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * 639a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param x The x-coordinate of the center of a circle to add as a 640a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * closed contour to the path 641a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param y The y-coordinate of the center of a circle to add as a 642a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * closed contour to the path 643a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param radius The radius of a circle to add as a closed contour to the 644a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * path 645a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param dir The direction to wind the circle's contour. Cannot be 646a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * kUnknown_Direction. 647a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com */ 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void addCircle(SkScalar x, SkScalar y, SkScalar radius, 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Direction dir = kCW_Direction); 6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add the specified arc to the path as a new contour. 652fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param oval The bounds of oval used to define the size of the arc 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param startAngle Starting angle (in degrees) where the arc begins 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param sweepAngle Sweep angle (in degrees) measured clockwise 6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle); 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 659a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com /** 660a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * Add a closed round-rectangle contour to the path 661a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param rect The bounds of a round-rectangle to add as a closed contour 662a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param rx The x-radius of the rounded corners on the round-rectangle 663a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param ry The y-radius of the rounded corners on the round-rectangle 664a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param dir The direction to wind the rectangle's contour. Cannot be 665a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * kUnknown_Direction. 666a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com */ 667ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, 668ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com Direction dir = kCW_Direction); 6698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 670a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com /** 671a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * Add a closed round-rectangle contour to the path. Each corner receives 672a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * two radius values [X, Y]. The corners are ordered top-left, top-right, 673a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * bottom-right, bottom-left. 674a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param rect The bounds of a round-rectangle to add as a closed contour 675a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner 676a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * @param dir The direction to wind the rectangle's contour. Cannot be 677a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com * kUnknown_Direction. 6784e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * Note: The radii here now go through the same constraint handling as the 6794e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * SkRRect radii (i.e., either radii at a corner being 0 implies a 6804e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * sqaure corner and oversized radii are proportionally scaled down). 681a8a3b3d9a027ad54ce20f8b4ed7c577a176b31careed@google.com */ 6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void addRoundRect(const SkRect& rect, const SkScalar radii[], 6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Direction dir = kCW_Direction); 6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 685744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com /** 6864e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * Add an SkRRect contour to the path 6874e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * @param rrect The rounded rect to add as a closed contour 6884e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * @param dir The winding direction for the new contour. Cannot be 6894e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com * kUnknown_Direction. 6904ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com */ 6914e18c7a9bbef6ac949d535aa61dfe1462ebb4452robertphillips@google.com void addRRect(const SkRRect& rrect, Direction dir = kCW_Direction); 6924ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com 6934ed0fb768409bf97b79899c3990d8c15f5e9d784reed@google.com /** 694744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * Add a new contour made of just lines. This is just a fast version of 695744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * the following: 696744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * this->moveTo(pts[0]); 697744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * for (int i = 1; i < count; ++i) { 698744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * this->lineTo(pts[i]); 699744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * } 700744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * if (close) { 701744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * this->close(); 702744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com * } 703744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com */ 704744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com void addPoly(const SkPoint pts[], int count, bool close); 705744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com 70614747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org enum AddPathMode { 70714747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org /** Source path contours are added as new contours. 70814747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org */ 70914747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org kAppend_AddPathMode, 71014747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org /** Path is added by extending the last contour of the destination path 71114747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org with the first contour of the source path. If the last contour of 712877c44956dceff038c0e315c8d311b0d581f2680skia.committer@gmail.com the destination path is closed, then it will not be extended. 71314747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org Instead, the start of source path will be extended by a straight 71414747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org line to the end point of the destination path. 71514747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org */ 716877c44956dceff038c0e315c8d311b0d581f2680skia.committer@gmail.com kExtend_AddPathMode 71714747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org }; 71814747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org 7198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a copy of src to the path, offset by (dx,dy) 7208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param src The path to add as a new contour 7218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx The amount to translate the path in X as it is added 7228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dx The amount to translate the path in Y as it is added 7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 72414747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org void addPath(const SkPath& src, SkScalar dx, SkScalar dy, 72514747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org AddPathMode mode = kAppend_AddPathMode); 7268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a copy of src to the path 7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 72914747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org void addPath(const SkPath& src, AddPathMode mode = kAppend_AddPathMode) { 7308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMatrix m; 7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com m.reset(); 73214747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org this->addPath(src, m, mode); 7338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Add a copy of src to the path, transformed by matrix 7368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param src The path to add as a new contour 73714747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org @param matrix Transform applied to src 73814747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org @param mode Determines how path is added 7398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 74014747e58f8127a6d6b3c748bf0642b0d6a3a79e8commit-bot@chromium.org void addPath(const SkPath& src, const SkMatrix& matrix, AddPathMode mode = kAppend_AddPathMode); 7418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 74263d73749fbe36491403ea521005fd298dc70a94creed@google.com /** 74363d73749fbe36491403ea521005fd298dc70a94creed@google.com * Same as addPath(), but reverses the src input 74463d73749fbe36491403ea521005fd298dc70a94creed@google.com */ 74563d73749fbe36491403ea521005fd298dc70a94creed@google.com void reverseAddPath(const SkPath& src); 74663d73749fbe36491403ea521005fd298dc70a94creed@google.com 7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Offset the path by (dx,dy), returning true on success 748fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 749fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com @param dx The amount in the X direction to offset the entire path 750fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com @param dy The amount in the Y direction to offset the entire path 7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dst The translated path is written here 7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void offset(SkScalar dx, SkScalar dy, SkPath* dst) const; 7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Offset the path by (dx,dy), returning true on success 756fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 757fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com @param dx The amount in the X direction to offset the entire path 758fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com @param dy The amount in the Y direction to offset the entire path 7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void offset(SkScalar dx, SkScalar dy) { 7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->offset(dx, dy, this); 7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Transform the points in this path by matrix, and write the answer into 7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dst. 766fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param matrix The matrix to apply to the path 7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param dst The transformed path is written here 7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 7708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void transform(const SkMatrix& matrix, SkPath* dst) const; 7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Transform the points in this path by matrix 7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param matrix The matrix to apply to the path 7758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void transform(const SkMatrix& matrix) { 7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->transform(matrix, this); 7788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 7798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the last point on the path. If no points have been added, (0,0) 781294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com is returned. If there are no points, this returns false, otherwise it 782294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com returns true. 783fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 7848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param lastPt The last point on the path is returned here 7858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 786294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com bool getLastPt(SkPoint* lastPt) const; 7878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the last point on the path. If no points have been added, 7898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com moveTo(x,y) is automatically called. 790fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 7918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param x The new x-coordinate for the last point 7928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param y The new y-coordinate for the last point 7938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 7948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setLastPt(SkScalar x, SkScalar y); 7958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Set the last point on the path. If no points have been added, moveTo(p) 7978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com is automatically called. 7988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param p The new location for the last point 8008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 8018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setLastPt(const SkPoint& p) { 8028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->setLastPt(p.fX, p.fY); 8038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 8048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 80510296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com enum SegmentMask { 80610296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com kLine_SegmentMask = 1 << 0, 80710296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com kQuad_SegmentMask = 1 << 1, 808277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com kConic_SegmentMask = 1 << 2, 809277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com kCubic_SegmentMask = 1 << 3, 81010296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com }; 81110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com 81210296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com /** 81310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com * Returns a mask, where each bit corresponding to a SegmentMask is 81410296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com * set if the path contains 1 or more segments of that type. 81510296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com * Returns 0 for an empty path (no segments). 81610296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com */ 8176b8dbb668f1f069270d35a47cfe98decd059c625robertphillips@google.com uint32_t getSegmentMasks() const { return fPathRef->getSegmentMasks(); } 81810296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com 8198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com enum Verb { 8208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kMove_Verb, //!< iter.next returns 1 point 8218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kLine_Verb, //!< iter.next returns 2 points 8228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kQuad_Verb, //!< iter.next returns 3 points 823277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com kConic_Verb, //!< iter.next returns 3 points + iter.conicWeight() 8248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com kCubic_Verb, //!< iter.next returns 4 points 825b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com kClose_Verb, //!< iter.next returns 1 point (contour's moveTo pt) 826277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com kDone_Verb, //!< iter.next returns 0 points 8278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 8288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Iterate through all of the segments (lines, quadratics, cubics) of 8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com each contours in a path. 83172785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org 83272785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org The iterator cleans up the segments along the way, removing degenerate 83372785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org segments and adding close verbs where necessary. When the forceClose 83472785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org argument is provided, each contour (as defined by a new starting 83572785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org move command) will be completed with a close verb regardless of the 83672785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org contour's contents. 8378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 8387ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org class SK_API Iter { 8398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com public: 84072785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org Iter(); 84172785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org Iter(const SkPath&, bool forceClose); 8428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void setPath(const SkPath&, bool forceClose); 8448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Return the next verb in this iteration of the path. When all 8468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com segments have been visited, return kDone_Verb. 847b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org 8488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @param pts The points representing the current verb and/or segment 8494a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com @param doConsumeDegerates If true, first scan for segments that are 8504a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com deemed degenerate (too short) and skip those. 8518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @return The verb for the current segment 8528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 8534a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com Verb next(SkPoint pts[4], bool doConsumeDegerates = true) { 8544a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com if (doConsumeDegerates) { 8554a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com this->consumeDegenerateSegments(); 8564a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com } 8574a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com return this->doNext(pts); 8584a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com } 8598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 860277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com /** 861277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com * Return the weight for the current conic. Only valid if the current 862277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com * segment return by next() was a conic. 863277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com */ 864277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com SkScalar conicWeight() const { return *fConicWeights; } 865277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com 8668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** If next() returns kLine_Verb, then this query returns true if the 8678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com line was the result of a close() command (i.e. the end point is the 8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com initial moveto for this contour). If next() returned a different 8698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com verb, this returns an undefined value. 870b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org 8718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @return If the last call to next() returned kLine_Verb, return true 8728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if it was the result of an explicit close command. 8738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 8748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool isCloseLine() const { return SkToBool(fCloseLine); } 875b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org 8768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /** Returns true if the current contour is closed (has a kClose_Verb) 8778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com @return true if the current contour is closed (has a kClose_Verb) 8788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 8798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool isClosedContour() const; 8808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com private: 8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPoint* fPts; 8838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* fVerbs; 8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const uint8_t* fVerbStop; 885277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com const SkScalar* fConicWeights; 8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint fMoveTo; 8878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint fLastPt; 8888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fForceClose; 8898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fNeedClose; 8908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkBool8 fCloseLine; 891b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org SkBool8 fSegmentState; 8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8939e25dbf589539dd44244bc2581590bd7591e17a2reed@google.com inline const SkPoint& cons_moveTo(); 8948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Verb autoClose(SkPoint pts[2]); 8954da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org void consumeDegenerateSegments(); 8964a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com Verb doNext(SkPoint pts[4]); 8978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 8988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8996630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org /** Iterate through the verbs in the path, providing the associated points. 9006630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org */ 9016630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org class SK_API RawIter { 9026630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org public: 9036630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org RawIter(); 9046630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org RawIter(const SkPath&); 9056630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org 9066630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org void setPath(const SkPath&); 9076630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org 9086630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org /** Return the next verb in this iteration of the path. When all 9096630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org segments have been visited, return kDone_Verb. 910fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 9116630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org @param pts The points representing the current verb and/or segment 912f6d3c5aa5f93e4c3cc7a7aebf014e960cf837783bsalomon@google.com This must not be NULL. 9136630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org @return The verb for the current segment 9146630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org */ 9156630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org Verb next(SkPoint pts[4]); 9166630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org 917277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com SkScalar conicWeight() const { return *fConicWeights; } 918277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com 9196630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org private: 9206630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org const SkPoint* fPts; 9216630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org const uint8_t* fVerbs; 9226630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org const uint8_t* fVerbStop; 923277c3f87656c44e0a651ed0dd56efa16c0ab07b4reed@google.com const SkScalar* fConicWeights; 9246630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org SkPoint fMoveTo; 9256630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org SkPoint fLastPt; 9266630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org }; 9276630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org 928bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org /** 929bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org * Returns true if the point { x, y } is contained by the path, taking into 930bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org * account the FillType. 931bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org */ 932bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org bool contains(SkScalar x, SkScalar y) const; 933bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org 934e956259c5a4f71768afb34ec032eaed49dcbe9f2caryclark void dump(SkWStream* , bool forceClose, bool dumpAsHex) const; 935e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com void dump() const; 936e956259c5a4f71768afb34ec032eaed49dcbe9f2caryclark void dumpHex() const; 9378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 93894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com /** 9394faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * Write the path to the buffer, and return the number of bytes written. 94094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com * If buffer is NULL, it still returns the number of bytes. 94194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com */ 9424faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t writeToMemory(void* buffer) const; 94394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com /** 9444faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * Initializes the path from the buffer 9454faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 9464faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param buffer Memory to read from 9474faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @param length Amount of memory available in the buffer 9484faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * @return number of bytes read (must be a multiple of 4) or 9494faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org * 0 if there was not enough memory available 95094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com */ 9514faa869cdabbdcf4867118b4a1272296baaeeb52commit-bot@chromium.org size_t readFromMemory(const void* buffer, size_t length); 9528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9531ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org /** Returns a non-zero, globally unique value corresponding to the set of verbs 9541ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org and points in the path (but not the fill type [except on Android skbug.com/1762]). 9557ed98df9ba14bdb58e381508eb0505c963a4b6dbskia.committer@gmail.com Each time the path is modified, a different generation ID will be returned. 9561ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org */ 9577101abe5b37d82ea222e971a42615a97a2419edbrobertphillips@google.com uint32_t getGenerationID() const; 9581ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org 9591ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org#ifdef SK_BUILD_FOR_ANDROID 9601ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org static const int kPathRefGenIDBitCnt = 30; // leave room for the fill type (skbug.com/1762) 961e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com const SkPath* getSourcePath() const; 962e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com void setSourcePath(const SkPath* path); 9631ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org#else 9641ab9f737f000e530f0c7713c8fad282f39e26efecommit-bot@chromium.org static const int kPathRefGenIDBitCnt = 32; 965f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 966f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com 9678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDEBUGCODE(void validate() const;) 9688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 97001ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com enum SerializationOffsets { 971fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // 1 free bit at 29 97211e055518a0cbe5329232a55fe2cd177e83836d8robertphillips@google.com kUnused1_SerializationShift = 28, // 1 free bit 97330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com kDirection_SerializationShift = 26, // requires 2 bits 97411e055518a0cbe5329232a55fe2cd177e83836d8robertphillips@google.com kUnused2_SerializationShift = 25, // 1 free bit 975fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // 1 free bit at 24 976ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com kConvexity_SerializationShift = 16, // requires 8 bits 977ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com kFillType_SerializationShift = 8, // requires 8 bits 978fed2ab648341ec153ad2af746a31d368963171e4commit-bot@chromium.org // 8 free bits at 0 97901ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com }; 98001ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com 981ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com SkAutoTUnref<SkPathRef> fPathRef; 982ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com 9835e1a7f2cc621d357da5c62a7bc4ef750d94b96f3commit-bot@chromium.org int fLastMoveToIndex; 9848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint8_t fFillType; 985b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com mutable uint8_t fConvexity; 98630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com mutable uint8_t fDirection; 98756c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID 988e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com const SkPath* fSourcePath; 989f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif 9908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 991a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com /** Resets all fields other than fPathRef to their initial 'empty' values. 992a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com * Assumes the caller has already emptied fPathRef. 993a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com * On Android increments fGenerationID without reseting it. 994a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com */ 995a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com void resetFields(); 996a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com 997a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com /** Sets all fields other than fPathRef to the values in 'that'. 998a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com * Assumes the caller has already set fPathRef. 9999c9d4a70028ef8dc33a46cfc0b22e254443effe3mtklein@google.com * Doesn't change fGenerationID or fSourcePath on Android. 1000a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com */ 1001a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com void copyFields(const SkPath& that); 1002a5809a3e4cb356387c5201ab9c0a10edf11a01bebungeman@google.com 10038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class Iter; 10048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class SkPathStroker; 10068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com /* Append, in reverse order, the first contour of path, ignoring path's 10088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com last point. If no moveTo() call has been made for this contour, the 10098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com first point is automatically set to (0,0). 10108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 10118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void reversePathTo(const SkPath&); 10128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1013d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com // called before we add points for lineTo, quadTo, cubicTo, checking to see 1014d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com // if we need to inject a leading moveTo first 1015d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com // 1016d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0) 1017d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo) 1018d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com // 10195e1a7f2cc621d357da5c62a7bc4ef750d94b96f3commit-bot@chromium.org inline void injectMoveToIfNeeded(); 1020d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com 10216aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com inline bool hasOnlyMoveTos() const; 10226aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com 102330c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com Convexity internalGetConvexity() const; 10243458716b52aa25dcd1b270141c7628c380696e35skia.committer@gmail.com 1025f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com bool isRectContour(bool allowPartial, int* currVerb, const SkPoint** pts, 1026f68154a3cf43eb22d45be11f3b09e25440c366a6caryclark@google.com bool* isClosed, Direction* direction) const; 102730c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com 1028ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com /** Returns if the path can return a bound at no cost (true) or will have to 1029ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com perform some computation (false). 1030ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com */ 1031ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com bool hasComputedBounds() const { 1032ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com SkDEBUGCODE(this->validate();) 1033ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com return fPathRef->hasComputedBounds(); 1034ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com } 1035ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 1036ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 1037ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com // 'rect' needs to be sorted 1038ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com void setBounds(const SkRect& rect) { 10390efb21bd1cd359b732a59753f3c1da096aab561arobertphillips@google.com SkPathRef::Editor ed(&fPathRef); 10400efb21bd1cd359b732a59753f3c1da096aab561arobertphillips@google.com 10410efb21bd1cd359b732a59753f3c1da096aab561arobertphillips@google.com ed.setBounds(rect); 1042ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com } 1043ca0c8389e2fd1c7f528869beb77a6c8587d59f29robertphillips@google.com 10448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com friend class SkAutoPathBoundsUpdate; 10456aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com friend class SkAutoDisableOvalCheck; 104630c174b9ce6b9777ee50ae0d0565a01b2a060f01bsalomon@google.com friend class SkAutoDisableDirectionCheck; 1047a1a097ee814d05a92487d85db8ad02e1d852fd6fcommit-bot@chromium.org friend class SkBench_AddPathTest; // perf test reversePathTo 1048a1a097ee814d05a92487d85db8ad02e1d852fd6fcommit-bot@chromium.org friend class PathTest_Private; // unit test reversePathTo 10498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 10508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 10518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1052