SkPath.h revision 7cc7f494796afc681355b15e88c57ef2709a9220
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"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTDArray.h"
161dfe88e00aeddf20690fd2469fd17e43f670ee3absalomon@google.com#include "SkRefCnt.h"
178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1856c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
19f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC              fGenerationID++
20f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_PTR_INC(ptr)     ptr->fGenerationID++
21f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#else
22f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_INC
23f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#define GEN_ID_PTR_INC(ptr)
24f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif
25f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com
26739456585a0cc52b335cd1c0a9fc6b01782a7f89reed@google.comclass SkReader32;
27739456585a0cc52b335cd1c0a9fc6b01782a7f89reed@google.comclass SkWriter32;
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkAutoPathBoundsUpdate;
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass SkString;
301dfe88e00aeddf20690fd2469fd17e43f670ee3absalomon@google.comclass SkPathRef;
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
32ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com#ifndef SK_DEBUG_PATH_REF
33ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    #ifdef SK_DEBUG
34ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        #define SK_DEBUG_PATH_REF 1
35ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    #else
36ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        #define SK_DEBUG_PATH_REF 0
37ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    #endif
38ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com#endif
39ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkPath
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    The SkPath class encapsulates compound (multiple contour) geometric paths
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    consisting of straight line segments, quadratic curves, and cubic curves.
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
457ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgclass SK_API SkPath {
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
4765a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    SK_DECLARE_INST_COUNT_ROOT(SkPath);
4865a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath();
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath(const SkPath&);
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    ~SkPath();
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath& operator=(const SkPath&);
54b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org
555e728450247c677343e072f37150967b36892573bsalomon@google.com    friend  SK_API bool operator==(const SkPath&, const SkPath&);
563abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    friend bool operator!=(const SkPath& a, const SkPath& b) {
573abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com        return !(a == b);
583abec1d7c38e9bd786fc6057f9608f3eeec98c86reed@android.com    }
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum FillType {
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** Specifies that "inside" is computed by a non-zero sum of signed
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            edge crossings
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        */
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kWinding_FillType,
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** Specifies that "inside" is computed by an odd number of edge
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            crossings
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        */
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kEvenOdd_FillType,
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** Same as Winding, but draws outside of the path, rather than inside
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        */
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kInverseWinding_FillType,
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** Same as EvenOdd, but draws outside of the path, rather than inside
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com         */
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kInverseEvenOdd_FillType
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Return the path's fill type. This is used to define how "inside" is
788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        computed. The default value is kWinding_FillType.
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @return the path's fill type
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    FillType getFillType() const { return (FillType)fFillType; }
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the path's fill type. This is used to define how "inside" is
858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        computed. The default value is kWinding_FillType.
86b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org
878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param ft The new fill type for this path
888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
89f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    void setFillType(FillType ft) {
90f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com        fFillType = SkToU8(ft);
91f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com        GEN_ID_INC;
92f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    }
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns true if the filltype is one of the Inverse variants */
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool isInverseFillType() const { return (fFillType & 2) != 0; }
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
97b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    /**
98b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  Toggle between inverse and normal filltypes. This reverse the return
99b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  value of isInverseFillType()
100b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     */
101f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    void toggleInverseFillType() {
102f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com        fFillType ^= 2;
103f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com        GEN_ID_INC;
104f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com     }
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
10604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    enum Convexity {
10704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        kUnknown_Convexity,
10804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        kConvex_Convexity,
10904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        kConcave_Convexity
11004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    };
11104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
11204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    /**
113b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  Return the path's convexity, as stored in the path. If it is currently
114b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  unknown, and the computeIfUnknown bool is true, then this will first
115b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  call ComputeConvexity() and then return that (cached) value.
116b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     */
117b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    Convexity getConvexity() const {
118b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com        if (kUnknown_Convexity == fConvexity) {
119b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com            fConvexity = (uint8_t)ComputeConvexity(*this);
120b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com        }
121b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com        return (Convexity)fConvexity;
122b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    }
123b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com
124b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    /**
125b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  Return the currently cached value for convexity, even if that is set to
126b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  kUnknown_Convexity. Note: getConvexity() will automatically call
127b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  ComputeConvexity and cache its return value if the current setting is
128b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  kUnknown.
12904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     */
130b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    Convexity getConvexityOrUnknown() const { return (Convexity)fConvexity; }
13104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
13204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    /**
13304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  Store a convexity setting in the path. There is no automatic check to
13404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  see if this value actually agress with the return value from
13504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  ComputeConvexity().
136b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *
137b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  Note: even if this is set to a "known" value, if the path is later
138b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  changed (e.g. lineTo(), addRect(), etc.) then the cached value will be
139b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  reset to kUnknown_Convexity.
14004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     */
14104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    void setConvexity(Convexity);
14204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
14304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    /**
14404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  Compute the convexity of the specified path. This does not look at the
14504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  value stored in the path, but computes it directly from the path's data.
14604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *
147b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  This never returns kUnknown_Convexity.
148b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *
14904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  If there is more than one contour, this returns kConcave_Convexity.
150b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  If the contour is degenerate (e.g. there are fewer than 3 non-degenerate
151b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com     *  segments), then this returns kConvex_Convexity.
15204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  The contour is treated as if it were closed, even if there is no kClose
15304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  verb.
1546b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com     */
15504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    static Convexity ComputeConvexity(const SkPath&);
1566b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
15704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    /**
15804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  DEPRECATED: use getConvexity()
15904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  Returns true if the path is flagged as being convex. This is not a
16004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  confirmed by any analysis, it is just the value set earlier.
16104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     */
16204863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    bool isConvex() const {
16304863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        return kConvex_Convexity == this->getConvexity();
16404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    }
16504863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com
16604863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com    /**
16704863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  DEPRECATED: use setConvexity()
16804863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  Set the isConvex flag to true or false. Convex paths may draw faster if
16904863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  this flag is set, though setting this to true on a path that is in fact
17004863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  not convex can give undefined results when drawn. Paths default to
17104863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com     *  isConvex == false
1726b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com     */
173f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    void setIsConvex(bool isConvex) {
17404863fa14a44ddf85acbc6268690ebc3f0d1d6dbreed@google.com        this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity);
175f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    }
1766b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com
1776aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    /** Returns true if the path is an oval.
1786aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     *
1796aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     * @param rect      returns the bounding rect of this oval. It's a circle
1806aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     *                  if the height and width are the same.
1816aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     *
1826aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     * @return true if this path is an oval.
1836aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     *              Tracking whether a path is an oval is considered an
1846aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     *              optimization for performance and so some paths that are in
1856aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     *              fact ovals can report false.
1866aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com     */
1876aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    bool isOval(SkRect* rect) const;
1886aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Clear any lines and curves from the path, making it empty. This frees up
1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        internal storage associated with those segments.
1916b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        This does NOT change the fill-type setting nor isConvex
1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void reset();
194fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Similar to reset(), in that all lines and curves are removed from the
1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path. However, any internal storage for those lines/curves is retained,
1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        making reuse of the path potentially faster.
1986b82d1adc6a4726e36674e468ff1157e0b75373freed@android.com        This does NOT change the fill-type setting nor isConvex
1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rewind();
2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns true if the path is empty (contains no lines or curves)
2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @return true if the path is empty (contains no lines or curves)
2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool isEmpty() const;
2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2080bb18bb264b26afca45452910437c09445e23a3creed@google.com    /**
2090bb18bb264b26afca45452910437c09445e23a3creed@google.com     *  Returns true if all of the points in this path are finite, meaning there
2100bb18bb264b26afca45452910437c09445e23a3creed@google.com     *  are no infinities and no NaNs.
2110bb18bb264b26afca45452910437c09445e23a3creed@google.com     */
2120bb18bb264b26afca45452910437c09445e23a3creed@google.com    bool isFinite() const {
2130bb18bb264b26afca45452910437c09445e23a3creed@google.com        if (fBoundsIsDirty) {
2140bb18bb264b26afca45452910437c09445e23a3creed@google.com            this->computeBounds();
2150bb18bb264b26afca45452910437c09445e23a3creed@google.com        }
216fc91dc70042dcb6d2868e8822fbab15aa4402375robertphillips@google.com        return SkToBool(fIsFinite);
2170bb18bb264b26afca45452910437c09445e23a3creed@google.com    }
2180bb18bb264b26afca45452910437c09445e23a3creed@google.com
2194da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    /** Test a line for zero length
2204da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2214da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org        @return true if the line is of zero length; otherwise false.
2224da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    */
2234da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2) {
22494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com        return p1.equalsWithinTolerance(p2);
2254da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    }
2264da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2274da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    /** Test a quad for zero length
2284da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2294da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org        @return true if the quad is of zero length; otherwise false.
2304da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    */
2314da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2,
2324da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org                                 const SkPoint& p3) {
23394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com        return p1.equalsWithinTolerance(p2) &&
23494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com               p2.equalsWithinTolerance(p3);
2354da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    }
2364da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2374da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    /** Test a cubic curve for zero length
2384da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2394da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org        @return true if the cubic is of zero length; otherwise false.
2404da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    */
2414da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
2424da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org                                  const SkPoint& p3, const SkPoint& p4) {
24394fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com        return p1.equalsWithinTolerance(p2) &&
24494fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com               p2.equalsWithinTolerance(p3) &&
24594fa43c6255906660c2ff001fb462b6492cbdc07epoger@google.com               p3.equalsWithinTolerance(p4);
2464da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org    }
2474da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org
2487e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    /**
2497e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com     *  Returns true if the path specifies a single line (i.e. it contains just
2507e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com     *  a moveTo and a lineTo). If so, and line[] is not null, it sets the 2
2517e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com     *  points in line[] to the end-points of the line. If the path is not a
2527e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com     *  line, returns false and ignores line[].
2537e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com     */
2547e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com    bool isLine(SkPoint line[2]) const;
2557e6c4d16010550ee148f1c79cf088c0320fed5c1reed@google.com
2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns true if the path specifies a rectangle. If so, and if rect is
2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        not null, set rect to the bounds of the path. If the path does not
2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        specify a rectangle, return false and ignore rect.
259fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param rect If not null, returns the bounds of the path if it specifies
2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    a rectangle
2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @return true if the path specifies a rectangle
2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    bool isRect(SkRect* rect) const;
2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
266d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    /** Return the number of points in the path
267d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com     */
2681dfe88e00aeddf20690fd2469fd17e43f670ee3absalomon@google.com    int countPoints() const;
269d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com
270d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    /** Return the point at the specified index. If the index is out of range
271d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com         (i.e. is not 0 <= index < countPoints()) then the returned coordinates
272d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com         will be (0,0)
273d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com     */
274d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com    SkPoint getPoint(int index) const;
275d3aa4ff7a564953dff9a15ff03fd42eebf64569freed@android.com
2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Returns the number of points in the path. Up to max points are copied.
277fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param points If not null, receives up to max points
2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param max The maximum number of points to copy into points
2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @return the actual number of points in the path
2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    int getPoints(SkPoint points[], int max) const;
2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
284df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    /** Return the number of verbs in the path
285df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com     */
2861dfe88e00aeddf20690fd2469fd17e43f670ee3absalomon@google.com    int countVerbs() const;
287df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com
288df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    /** Returns the number of verbs in the path. Up to max verbs are copied. The
289df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com        verbs are copied as one byte per verb.
290fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
291df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com        @param verbs If not null, receives up to max verbs
292df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com        @param max The maximum number of verbs to copy into verbs
293df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com        @return the actual number of verbs in the path
294df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    */
295df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com    int getVerbs(uint8_t verbs[], int max) const;
296df9d656c352928f995abce0a62c4ec3255232a45bsalomon@google.com
2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    //! Swap contents of this and other. Guaranteed not to throw
2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void swap(SkPath& other);
2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
300d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    /** Returns the bounds of the path's points. If the path contains 0 or 1
301d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        points, the bounds is set to (0,0,0,0), and isEmpty() will return true.
302d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        Note: this bounds may be larger than the actual shape, since curves
303d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        do not extend as far as their control points.
304d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    */
305d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    const SkRect& getBounds() const {
306d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        if (fBoundsIsDirty) {
307d252db03d9650013b545ef9781fe993c07f8f314reed@android.com            this->computeBounds();
308d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        }
309d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        return fBounds;
310d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    }
3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Calling this will, if the internal cache of the bounds is out of date,
313d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        update it so that subsequent calls to getBounds will be instanteous.
3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        This also means that any copies or simple transformations of the path
3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        will inherit the cached bounds.
316d252db03d9650013b545ef9781fe993c07f8f314reed@android.com     */
317d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    void updateBoundsCache() const {
318d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        // for now, just calling getBounds() is sufficient
319d252db03d9650013b545ef9781fe993c07f8f314reed@android.com        this->getBounds();
320d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    }
3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    //  Construction methods
3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Hint to the path to prepare for adding more points. This can allow the
3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        path to more efficiently grow its storage.
326fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param extraPtCount The number of extra points the path should
3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                            preallocate for.
3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void incReserve(unsigned extraPtCount);
3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the beginning of the next contour to the point (x,y).
333fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x    The x-coordinate of the start of a new contour
3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y    The y-coordinate of the start of a new contour
3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void moveTo(SkScalar x, SkScalar y);
3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the beginning of the next contour to the point
340fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p    The start of a new contour
3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void moveTo(const SkPoint& p) {
3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->moveTo(p.fX, p.fY);
3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the beginning of the next contour relative to the last point on the
3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        previous contour. If there is no previous contour, this is treated the
3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        same as moveTo().
350fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx   The amount to add to the x-coordinate of the end of the
3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    previous contour, to specify the start of a new contour
3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dy   The amount to add to the y-coordinate of the end of the
3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    previous contour, to specify the start of a new contour
3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rMoveTo(SkScalar dx, SkScalar dy);
3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a line from the last point to the specified point (x,y). If no
3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        moveTo() call has been made for this contour, the first point is
3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        automatically set to (0,0).
3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x    The x-coordinate of the end of a line
3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y    The y-coordinate of the end of a line
3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void lineTo(SkScalar x, SkScalar y);
3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a line from the last point to the specified point. If no moveTo()
3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        call has been made for this contour, the first point is automatically
3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        set to (0,0).
3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p    The end of a line
3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void lineTo(const SkPoint& p) {
3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->lineTo(p.fX, p.fY);
3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Same as lineTo, but the coordinates are considered relative to the last
3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        point on this contour. If there is no previous point, then a moveTo(0,0)
3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        is inserted automatically.
380fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx   The amount to add to the x-coordinate of the previous point
3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    on this contour, to specify a line
3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dy   The amount to add to the y-coordinate of the previous point
3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    on this contour, to specify a line
3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rLineTo(SkScalar dx, SkScalar dy);
3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a quadratic bezier from the last point, approaching control point
3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for
3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this contour, the first point is automatically set to (0,0).
391fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x1   The x-coordinate of the control point on a quadratic curve
3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y1   The y-coordinate of the control point on a quadratic curve
3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x2   The x-coordinate of the end point on a quadratic curve
3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y2   The y-coordinate of the end point on a quadratic curve
3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2);
3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a quadratic bezier from the last point, approaching control point
4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        p1, and ending at p2. If no moveTo() call has been made for this
4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        contour, the first point is automatically set to (0,0).
402fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p1   The control point on a quadratic curve
4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p2   The end point on a quadratic curve
4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void quadTo(const SkPoint& p1, const SkPoint& p2) {
4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->quadTo(p1.fX, p1.fY, p2.fX, p2.fY);
4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Same as quadTo, but the coordinates are considered relative to the last
4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        point on this contour. If there is no previous point, then a moveTo(0,0)
4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        is inserted automatically.
4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx1   The amount to add to the x-coordinate of the last point on
4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this contour, to specify the control point of a quadratic curve
4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dy1   The amount to add to the y-coordinate of the last point on
4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this contour, to specify the control point of a quadratic curve
4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx2   The amount to add to the x-coordinate of the last point on
4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     this contour, to specify the end point of a quadratic curve
4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dy2   The amount to add to the y-coordinate of the last point on
4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     this contour, to specify the end point of a quadratic curve
4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void rQuadTo(SkScalar dx1, SkScalar dy1, SkScalar dx2, SkScalar dy2);
4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a cubic bezier from the last point, approaching control points
4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been
4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        made for this contour, the first point is automatically set to (0,0).
428fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x1   The x-coordinate of the 1st control point on a cubic curve
4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y1   The y-coordinate of the 1st control point on a cubic curve
4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x2   The x-coordinate of the 2nd control point on a cubic curve
4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y2   The y-coordinate of the 2nd control point on a cubic curve
4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x3   The x-coordinate of the end point on a cubic curve
4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y3   The y-coordinate of the end point on a cubic curve
4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 SkScalar x3, SkScalar y3);
4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a cubic bezier from the last point, approaching control points p1
4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        and p2, and ending at p3. If no moveTo() call has been made for this
4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        contour, the first point is automatically set to (0,0).
442fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p1   The 1st control point on a cubic curve
4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p2   The 2nd control point on a cubic curve
4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p3   The end point on a cubic curve
4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void cubicTo(const SkPoint& p1, const SkPoint& p2, const SkPoint& p3) {
4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->cubicTo(p1.fX, p1.fY, p2.fX, p2.fY, p3.fX, p3.fY);
4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Same as cubicTo, but the coordinates are considered relative to the
4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        current point on this contour. If there is no previous point, then a
4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        moveTo(0,0) is inserted automatically.
454fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx1   The amount to add to the x-coordinate of the last point on
4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this contour, to specify the 1st control point of a cubic curve
4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dy1   The amount to add to the y-coordinate of the last point on
4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this contour, to specify the 1st control point of a cubic curve
4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx2   The amount to add to the x-coordinate of the last point on
4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this contour, to specify the 2nd control point of a cubic curve
4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dy2   The amount to add to the y-coordinate of the last point on
4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                this contour, to specify the 2nd control point of a cubic curve
4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx3   The amount to add to the x-coordinate of the last point on
4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     this contour, to specify the end point of a cubic curve
4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dy3   The amount to add to the y-coordinate of the last point on
4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     this contour, to specify the end point of a cubic curve
4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void    rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                     SkScalar x3, SkScalar y3);
4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Append the specified arc to the path as a new contour. If the start of
4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        the path is different from the path's current last point, then an
4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        automatic lineTo() is added to connect the current contour to the start
4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        of the arc. However, if the path is empty, then we call moveTo() with
4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        the first point of the arc. The sweep angle is treated mod 360.
476fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param oval The bounding oval defining the shape and size of the arc
4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param startAngle Starting angle (in degrees) where the arc begins
4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param sweepAngle Sweep angle (in degrees) measured clockwise. This is
4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                          treated mod 360.
4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param forceMoveTo If true, always begin a new contour with the arc
4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void    arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                  bool forceMoveTo);
4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Append a line and arc to the current path. This is the same as the
4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        PostScript call "arct".
4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2,
4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com               SkScalar radius);
4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Append a line and arc to the current path. This is the same as the
4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        PostScript call "arct".
4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void arcTo(const SkPoint p1, const SkPoint p2, SkScalar radius) {
4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->arcTo(p1.fX, p1.fY, p2.fX, p2.fY, radius);
4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Close the current contour. If the current point is not equal to the
5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        first point of the contour, a line segment is automatically added.
5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void close();
5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum Direction {
5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** clockwise direction for adding closed contours */
5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kCW_Direction,
5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** counter-clockwise direction for adding closed contours */
5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kCCW_Direction
5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
51169a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    /**
51269a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     *  Tries to quickly compute the direction of the first non-degenerate
51369a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     *  contour. If it can be computed, return true and set dir to that
51469a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     *  direction. If it cannot be (quickly) determined, return false and ignore
51569a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     *  the dir parameter.
51669a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     */
51769a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    bool cheapComputeDirection(Direction* dir) const;
51869a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com
51969a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    /**
52069a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     *  Returns true if the path's direction can be computed via
52169a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     *  cheapComputDirection() and if that computed direction matches the
52269a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     *  specified direction.
52369a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com     */
52469a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    bool cheapIsDirection(Direction dir) const {
52569a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com        Direction computedDir;
52669a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com        return this->cheapComputeDirection(&computedDir) && computedDir == dir;
52769a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com    }
52869a9943b67cc52c24beac853c6f8865dcb197b85reed@google.com
5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a closed rectangle contour to the path
5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param rect The rectangle to add as a closed contour to the path
5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dir  The direction to wind the rectangle's contour
5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void    addRect(const SkRect& rect, Direction dir = kCW_Direction);
5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a closed rectangle contour to the path
5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param left     The left side of a rectangle to add as a closed contour
5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        to the path
5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param top      The top of a rectangle to add as a closed contour to the
5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        path
5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param right    The right side of a rectangle to add as a closed contour
5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        to the path
5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param bottom   The bottom of a rectangle to add as a closed contour to
5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        the path
5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dir      The direction to wind the rectangle's contour
5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                 Direction dir = kCW_Direction);
5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a closed oval contour to the path
5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param oval The bounding oval to add as a closed contour to the path
5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dir  The direction to wind the oval's contour
5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void addOval(const SkRect& oval, Direction dir = kCW_Direction);
5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a closed circle contour to the path
5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x        The x-coordinate of the center of a circle to add as a
5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        closed contour to the path
5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y        The y-coordinate of the center of a circle to add as a
5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        closed contour to the path
5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param radius   The radius of a circle to add as a closed contour to the
5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                        path
5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dir      The direction to wind the circle's contour
5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void addCircle(SkScalar x, SkScalar y, SkScalar radius,
5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                   Direction dir = kCW_Direction);
5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add the specified arc to the path as a new contour.
571fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param oval The bounds of oval used to define the size of the arc
5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param startAngle Starting angle (in degrees) where the arc begins
5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param sweepAngle Sweep angle (in degrees) measured clockwise
5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a closed round-rectangle contour to the path
5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param rect The bounds of a round-rectangle to add as a closed contour
5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param rx   The x-radius of the rounded corners on the round-rectangle
5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param ry   The y-radius of the rounded corners on the round-rectangle
5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dir  The direction to wind the round-rectangle's contour
5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void    addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                         Direction dir = kCW_Direction);
5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a closed round-rectangle contour to the path. Each corner receives
5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        two radius values [X, Y]. The corners are ordered top-left, top-right,
5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bottom-right, bottom-left.
5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param rect The bounds of a round-rectangle to add as a closed contour
5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner
5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dir  The direction to wind the round-rectangle's contour
5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        */
5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void addRoundRect(const SkRect& rect, const SkScalar radii[],
5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                      Direction dir = kCW_Direction);
5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
597744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    /**
598744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *  Add a new contour made of just lines. This is just a fast version of
599744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *  the following:
600744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *      this->moveTo(pts[0]);
601744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *      for (int i = 1; i < count; ++i) {
602744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *          this->lineTo(pts[i]);
603744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *      }
604744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *      if (close) {
605744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *          this->close();
606744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     *      }
607744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com     */
608744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com    void addPoly(const SkPoint pts[], int count, bool close);
609744fabad474e3e111e7cbd8609cf7e209df17f32reed@google.com
6108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a copy of src to the path, offset by (dx,dy)
6118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param src  The path to add as a new contour
6128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx   The amount to translate the path in X as it is added
6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dx   The amount to translate the path in Y as it is added
6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
61563d73749fbe36491403ea521005fd298dc70a94creed@google.com    void addPath(const SkPath& src, SkScalar dx, SkScalar dy);
6168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a copy of src to the path
6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void addPath(const SkPath& src) {
6208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkMatrix m;
6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        m.reset();
6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->addPath(src, m);
6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Add a copy of src to the path, transformed by matrix
6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param src  The path to add as a new contour
6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void addPath(const SkPath& src, const SkMatrix& matrix);
6298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
63063d73749fbe36491403ea521005fd298dc70a94creed@google.com    /**
63163d73749fbe36491403ea521005fd298dc70a94creed@google.com     *  Same as addPath(), but reverses the src input
63263d73749fbe36491403ea521005fd298dc70a94creed@google.com     */
63363d73749fbe36491403ea521005fd298dc70a94creed@google.com    void reverseAddPath(const SkPath& src);
63463d73749fbe36491403ea521005fd298dc70a94creed@google.com
6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Offset the path by (dx,dy), returning true on success
636fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
637fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        @param dx   The amount in the X direction to offset the entire path
638fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        @param dy   The amount in the Y direction to offset the entire path
6398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dst  The translated path is written here
6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void offset(SkScalar dx, SkScalar dy, SkPath* dst) const;
6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Offset the path by (dx,dy), returning true on success
644fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
645fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        @param dx   The amount in the X direction to offset the entire path
646fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com        @param dy   The amount in the Y direction to offset the entire path
6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void offset(SkScalar dx, SkScalar dy) {
6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->offset(dx, dy, this);
6508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Transform the points in this path by matrix, and write the answer into
6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        dst.
654fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param matrix   The matrix to apply to the path
6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param dst      The transformed path is written here
6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void transform(const SkMatrix& matrix, SkPath* dst) const;
6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Transform the points in this path by matrix
6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param matrix The matrix to apply to the path
6638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void transform(const SkMatrix& matrix) {
6658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->transform(matrix, this);
6668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Return the last point on the path. If no points have been added, (0,0)
669294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com        is returned. If there are no points, this returns false, otherwise it
670294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com        returns true.
671fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
6728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param lastPt   The last point on the path is returned here
6738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
674294dd7b3d7b55ba38881cd4cabb6636abda23eb9reed@google.com    bool getLastPt(SkPoint* lastPt) const;
6758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the last point on the path. If no points have been added,
6778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        moveTo(x,y) is automatically called.
678fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
6798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param x    The new x-coordinate for the last point
6808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param y    The new y-coordinate for the last point
6818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setLastPt(SkScalar x, SkScalar y);
6838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Set the last point on the path. If no points have been added, moveTo(p)
6858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        is automatically called.
6868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        @param p    The new location for the last point
6888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
6898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void setLastPt(const SkPoint& p) {
6908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->setLastPt(p.fX, p.fY);
6918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
6928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
69310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    enum SegmentMask {
69410296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com        kLine_SegmentMask   = 1 << 0,
69510296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com        kQuad_SegmentMask   = 1 << 1,
69610296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com        kCubic_SegmentMask  = 1 << 2
69710296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    };
69810296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
69910296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    /**
70010296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com     *  Returns a mask, where each bit corresponding to a SegmentMask is
70110296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com     *  set if the path contains 1 or more segments of that type.
70210296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com     *  Returns 0 for an empty path (no segments).
70310296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com     */
70410296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    uint32_t getSegmentMasks() const { return fSegmentMask; }
70510296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com
7068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    enum Verb {
7078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kMove_Verb,     //!< iter.next returns 1 point
7088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kLine_Verb,     //!< iter.next returns 2 points
7098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kQuad_Verb,     //!< iter.next returns 3 points
7108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kCubic_Verb,    //!< iter.next returns 4 points
711b3b8dfa31326c51dab8b5ed569e19ee715582d1bbsalomon@google.com        kClose_Verb,    //!< iter.next returns 1 point (contour's moveTo pt)
7128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        kDone_Verb      //!< iter.next returns 0 points
7138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
7148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /** Iterate through all of the segments (lines, quadratics, cubics) of
7168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        each contours in a path.
71772785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org
71872785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        The iterator cleans up the segments along the way, removing degenerate
71972785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        segments and adding close verbs where necessary. When the forceClose
72072785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        argument is provided, each contour (as defined by a new starting
72172785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        move command) will be completed with a close verb regardless of the
72272785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        contour's contents.
7238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
7247ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.org    class SK_API Iter {
7258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public:
72672785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        Iter();
72772785c4c8928a8b0fc5bbdb48929f9356554daceschenney@chromium.org        Iter(const SkPath&, bool forceClose);
7288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        void setPath(const SkPath&, bool forceClose);
7308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** Return the next verb in this iteration of the path. When all
7328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            segments have been visited, return kDone_Verb.
733b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org
7348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            @param  pts The points representing the current verb and/or segment
7354a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com            @param doConsumeDegerates If true, first scan for segments that are
7364a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com                   deemed degenerate (too short) and skip those.
7378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            @return The verb for the current segment
7388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        */
7394a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com        Verb next(SkPoint pts[4], bool doConsumeDegerates = true) {
7404a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com            if (doConsumeDegerates) {
7414a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com                this->consumeDegenerateSegments();
7424a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com            }
7434a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com            return this->doNext(pts);
7444a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com        }
7458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** If next() returns kLine_Verb, then this query returns true if the
7478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            line was the result of a close() command (i.e. the end point is the
7488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            initial moveto for this contour). If next() returned a different
7498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            verb, this returns an undefined value.
750b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org
7518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            @return If the last call to next() returned kLine_Verb, return true
7528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                    if it was the result of an explicit close command.
7538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        */
7548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bool isCloseLine() const { return SkToBool(fCloseLine); }
755b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org
7568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        /** Returns true if the current contour is closed (has a kClose_Verb)
7578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com            @return true if the current contour is closed (has a kClose_Verb)
7588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        */
7598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        bool isClosedContour() const;
7608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    private:
7628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const SkPoint*  fPts;
7638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const uint8_t*  fVerbs;
7648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const uint8_t*  fVerbStop;
7658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint         fMoveTo;
7668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkPoint         fLastPt;
7678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkBool8         fForceClose;
7688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkBool8         fNeedClose;
7698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkBool8         fCloseLine;
770b0af6dad94f3c51ea0d5d6426a9509354338c6b2schenney@chromium.org        SkBool8         fSegmentState;
7718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7729e25dbf589539dd44244bc2581590bd7591e17a2reed@google.com        inline const SkPoint& cons_moveTo();
7738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        Verb autoClose(SkPoint pts[2]);
7744da06ab3351f2a96f9216d96106db33a77b19644schenney@chromium.org        void consumeDegenerateSegments();
7754a3b714d73e585a3985d614600c6b79d5c8b1f1ereed@google.com        Verb doNext(SkPoint pts[4]);
7768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
7778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7786630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    /** Iterate through the verbs in the path, providing the associated points.
7796630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    */
7806630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    class SK_API RawIter {
7816630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    public:
7826630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        RawIter();
7836630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        RawIter(const SkPath&);
7846630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
7856630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        void setPath(const SkPath&);
7866630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
7876630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        /** Return the next verb in this iteration of the path. When all
7886630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            segments have been visited, return kDone_Verb.
789fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
7906630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            @param  pts The points representing the current verb and/or segment
791f6d3c5aa5f93e4c3cc7a7aebf014e960cf837783bsalomon@google.com                        This must not be NULL.
7926630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org            @return The verb for the current segment
7936630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        */
7946630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        Verb next(SkPoint pts[4]);
7956630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
7966630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    private:
7976630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        const SkPoint*  fPts;
7986630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        const uint8_t*  fVerbs;
7996630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        const uint8_t*  fVerbStop;
8006630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        SkPoint         fMoveTo;
8016630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org        SkPoint         fLastPt;
8026630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org    };
8036630d8d8ea7a897a18e3d950bab9fa40f065804aschenney@chromium.org
804bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org    /**
805bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org     *  Returns true if the point { x, y } is contained by the path, taking into
806bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org     *  account the FillType.
807bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org     */
808bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org    bool contains(SkScalar x, SkScalar y) const;
809bad1b2ff1d34ff86693b776f89d7b46995746127mike@reedtribe.org
8108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void dump(bool forceClose, const char title[] = NULL) const;
811e522ca5d5f249bd51a00cb68bb051f811d0a9e85reed@android.com    void dump() const;
8128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
81394e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    /**
81494e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com     *  Write the region to the buffer, and return the number of bytes written.
81594e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com     *  If buffer is NULL, it still returns the number of bytes.
81694e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com     */
81794e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t writeToMemory(void* buffer) const;
81894e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    /**
81994e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com     *  Initialized the region from the buffer, returning the number
82094e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com     *  of bytes actually read.
82194e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com     */
82294e75ee46a569cbcdf61fb7f04ee3a69d3ca0896djsollen@google.com    uint32_t readFromMemory(const void* buffer);
8238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
82456c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
825f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    uint32_t getGenerationID() const;
826e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com    const SkPath* getSourcePath() const;
827e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com    void setSourcePath(const SkPath* path);
828f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif
829f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com
8308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkDEBUGCODE(void validate() const;)
8318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
83301ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com    enum SerializationOffsets {
83401ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com        kIsFinite_SerializationShift = 25,
83501ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com        kIsOval_SerializationShift = 24,
836607d08b7db477ae11dbafff0bbebaa91f5c9fd7absalomon@google.com        kConvexity_SerializationShift = 16,
837607d08b7db477ae11dbafff0bbebaa91f5c9fd7absalomon@google.com        kFillType_SerializationShift = 8,
83801ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com        kSegmentMask_SerializationShift = 0
83901ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com    };
84001ec2eb42e9c64f8d06afd51f80c055710147141robertphillips@google.com
841ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com#if SK_DEBUG_PATH_REF
842ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.compublic:
843ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    /** Debugging wrapper for SkAutoTUnref<SkPathRef> used to track owners (SkPaths)
844ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        of SkPathRefs */
845ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    class PathRefDebugRef {
846ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    public:
847ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        PathRefDebugRef(SkPath* owner);
848ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        PathRefDebugRef(SkPathRef* pr, SkPath* owner);
849ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        ~PathRefDebugRef();
8507cc7f494796afc681355b15e88c57ef2709a9220skia.committer@gmail.com        void reset(SkPathRef* ref);
851ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        void swap(PathRefDebugRef* other);
852ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        SkPathRef* get() const;
853ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        SkAutoTUnref<SkPathRef>::BlockRefType *operator->() const;
854ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        operator SkPathRef*();
855ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    private:
856ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        SkAutoTUnref<SkPathRef>   fPathRef;
857ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com        SkPath*                   fOwner;
858ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    };
859ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com
860ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.comprivate:
861ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    PathRefDebugRef     fPathRef;
862ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com#else
863ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com    SkAutoTUnref<SkPathRef> fPathRef;
864ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com#endif
865ae09f2dc3fb1e8a8db99b214c8a71d0b9613a856bsalomon@google.com
866d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    mutable SkRect      fBounds;
867d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    int                 fLastMoveToIndex;
8688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    uint8_t             fFillType;
86910296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    uint8_t             fSegmentMask;
87010296ccb6a63c65b2e60733a929bf15d8bf94309reed@google.com    mutable uint8_t     fBoundsIsDirty;
871b54455e440e66e0b1c30954d226226f49aac26d6reed@google.com    mutable uint8_t     fConvexity;
8720bb18bb264b26afca45452910437c09445e23a3creed@google.com    mutable SkBool8     fIsFinite;    // only meaningful if bounds are valid
8736aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    mutable SkBool8     fIsOval;
87456c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
875f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com    uint32_t            fGenerationID;
876e63793a2c8d2871bf7d95195be7b93ff669688d7djsollen@google.com    const SkPath*       fSourcePath;
877f5dbe2f00f853c6a1719924bdd0c33335a53423adjsollen@google.com#endif
8788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
879d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    // called, if dirty, by getBounds()
880d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    void computeBounds() const;
881d252db03d9650013b545ef9781fe993c07f8f314reed@android.com
8828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend class Iter;
8838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend class SkPathStroker;
8858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /*  Append the first contour of path, ignoring path's initial point. If no
8868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        moveTo() call has been made for this contour, the first point is
8878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        automatically set to (0,0).
8888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
8898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void pathTo(const SkPath& path);
8908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    /*  Append, in reverse order, the first contour of path, ignoring path's
8928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        last point. If no moveTo() call has been made for this contour, the
8938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        first point is automatically set to (0,0).
8948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    */
8958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void reversePathTo(const SkPath&);
8968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
897d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    // called before we add points for lineTo, quadTo, cubicTo, checking to see
898d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    // if we need to inject a leading moveTo first
899d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    //
900d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    //  SkPath path; path.lineTo(...);   <--- need a leading moveTo(0, 0)
901d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo)
902d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    //
903d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com    inline void injectMoveToIfNeeded();
904d335d1d784167f8b9a4bf8a35e04d8e82d0a9507reed@google.com
9056aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    inline bool hasOnlyMoveTos() const;
9066aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com
9078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    friend class SkAutoPathBoundsUpdate;
9086aa2965ca814dd3329b65398b5c5af980e54b101bsalomon@google.com    friend class SkAutoDisableOvalCheck;
90930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    friend class SkBench_AddPathTest; // perf test pathTo/reversePathTo
9108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
9118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
913