184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips/*
284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips * Copyright 2015 Google Inc.
384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips *
484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips * Use of this source code is governed by a BSD-style license that can be
584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips * found in the LICENSE file.
684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips */
784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#ifndef GrAAConvexTessellator_DEFINED
984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#define GrAAConvexTessellator_DEFINED
1084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
1184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#include "SkColor.h"
12bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita#include "SkPaint.h"
1384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#include "SkPoint.h"
1484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#include "SkScalar.h"
158c170971f182d47bc9af71fc88a607740d03dfd5robertphillips#include "SkStrokeRec.h"
1684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#include "SkTDArray.h"
1784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
1884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillipsclass SkCanvas;
1984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillipsclass SkMatrix;
2084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillipsclass SkPath;
2184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips//#define GR_AA_CONVEX_TESSELLATOR_VIZ 1
2384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
24bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita// device space distance which we inset / outset points in order to create the soft antialiased edge
25bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalitastatic const SkScalar kAntialiasingRadius = 0.5f;
26bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita
2784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillipsclass GrAAConvexTessellator;
2884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips// The AAConvexTessellator holds the global pool of points and the triangulation
3084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips// that connects them. It also drives the tessellation process.
3184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips// The outward facing normals of the original polygon are stored (in 'fNorms') to service
3284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips// computeDepthFromEdge requests.
3384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillipsclass GrAAConvexTessellator {
3484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillipspublic:
358c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    GrAAConvexTessellator(SkStrokeRec::Style style = SkStrokeRec::kFill_Style,
368c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                          SkScalar strokeWidth = -1.0f,
379d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary                          SkPaint::Join join = SkPaint::Join::kBevel_Join,
38bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita                          SkScalar miterLimit = 0.0f)
3984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        : fSide(SkPoint::kOn_Side)
40bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        , fStrokeWidth(strokeWidth)
418c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        , fStyle(style)
42bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        , fJoin(join)
43bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        , fMiterLimit(miterLimit) {
4484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    }
4584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
4684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    SkPoint::Side side() const { return fSide; }
4784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
4884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    bool tessellate(const SkMatrix& m, const SkPath& path);
4984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
5084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // The next five should only be called after tessellate to extract the result
5184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    int numPts() const { return fPts.count(); }
5284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    int numIndices() const { return fIndices.count(); }
5384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
5484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    const SkPoint& lastPoint() const { return fPts.top(); }
5584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    const SkPoint& point(int index) const { return fPts[index]; }
5684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    int index(int index) const { return fIndices[index]; }
57bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita    SkScalar coverage(int index) const { return fCoverages[index]; }
5884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
5984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#if GR_AA_CONVEX_TESSELLATOR_VIZ
6084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void draw(SkCanvas* canvas) const;
6184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#endif
6284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
6384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // The tessellator can be reused for multiple paths by rewinding in between
6484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void rewind();
6584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
6684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillipsprivate:
679d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    // CandidateVerts holds the vertices for the next ring while they are
6884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // being generated. Its main function is to de-dup the points.
6984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    class CandidateVerts {
7084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    public:
7184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void setReserve(int numPts) { fPts.setReserve(numPts); }
7284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void rewind() { fPts.rewind(); }
7384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
7484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int numPts() const { return fPts.count(); }
7584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
7684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        const SkPoint& lastPoint() const { return fPts.top().fPt; }
7784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        const SkPoint& firstPoint() const { return fPts[0].fPt; }
7884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        const SkPoint& point(int index) const { return fPts[index].fPt; }
7984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
8084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int originatingIdx(int index) const { return fPts[index].fOriginatingIdx; }
8184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int origEdge(int index) const { return fPts[index].fOrigEdgeId; }
8284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        bool needsToBeNew(int index) const { return fPts[index].fNeedsToBeNew; }
8384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
8484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int addNewPt(const SkPoint& newPt, int originatingIdx, int origEdge, bool needsToBeNew) {
8584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            struct PointData* pt = fPts.push();
8684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            pt->fPt = newPt;
8784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            pt->fOrigEdgeId = origEdge;
8884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            pt->fOriginatingIdx = originatingIdx;
8984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            pt->fNeedsToBeNew = needsToBeNew;
9084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            return fPts.count() - 1;
9184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        }
9284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
9384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int fuseWithPrior(int origEdgeId) {
9484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            fPts.top().fOrigEdgeId = origEdgeId;
9584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            fPts.top().fOriginatingIdx = -1;
9684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            fPts.top().fNeedsToBeNew = true;
9784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            return fPts.count() - 1;
9884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        }
9984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
10084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int fuseWithNext() {
10184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            fPts[0].fOriginatingIdx = -1;
10284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            fPts[0].fNeedsToBeNew = true;
10384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            return 0;
10484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        }
10584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
10684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int fuseWithBoth() {
10784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            if (fPts.count() > 1) {
10884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips                fPts.pop();
10984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            }
11084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
11184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            fPts[0].fOriginatingIdx = -1;
11284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            fPts[0].fNeedsToBeNew = true;
11384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            return 0;
11484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        }
11584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
11684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    private:
11784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        struct PointData {
11884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            SkPoint fPt;
11984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            int     fOriginatingIdx;
12084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            int     fOrigEdgeId;
12184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            bool    fNeedsToBeNew;
12284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        };
12384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
12484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        SkTDArray<struct PointData> fPts;
12584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    };
12684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
12784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // The Ring holds a set of indices into the global pool that together define
12884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // a single polygon inset.
12984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    class Ring {
13084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    public:
13184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void setReserve(int numPts) { fPts.setReserve(numPts); }
13284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void rewind() { fPts.rewind(); }
13384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
13484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int numPts() const { return fPts.count(); }
13584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
13684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void addIdx(int index, int origEdgeId) {
13784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            struct PointData* pt = fPts.push();
13884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            pt->fIndex = index;
13984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            pt->fOrigEdgeId = origEdgeId;
14084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        }
14184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
1428c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        // Upgrade this ring so that it can behave like an originating ring
1438c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        void makeOriginalRing() {
1448c170971f182d47bc9af71fc88a607740d03dfd5robertphillips            for (int i = 0; i < fPts.count(); ++i) {
1458c170971f182d47bc9af71fc88a607740d03dfd5robertphillips                fPts[i].fOrigEdgeId = fPts[i].fIndex;
1468c170971f182d47bc9af71fc88a607740d03dfd5robertphillips            }
1478c170971f182d47bc9af71fc88a607740d03dfd5robertphillips        }
1488c170971f182d47bc9af71fc88a607740d03dfd5robertphillips
14984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        // init should be called after all the indices have been added (via addIdx)
15084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void init(const GrAAConvexTessellator& tess);
15184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void init(const SkTDArray<SkVector>& norms, const SkTDArray<SkVector>& bisectors);
15284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
15384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        const SkPoint& norm(int index) const { return fPts[index].fNorm; }
15484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        const SkPoint& bisector(int index) const { return fPts[index].fBisector; }
15584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int index(int index) const { return fPts[index].fIndex; }
15684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        int origEdgeID(int index) const { return fPts[index].fOrigEdgeId; }
157bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        void setOrigEdgeId(int index, int id) { fPts[index].fOrigEdgeId = id; }
15884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
15984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    #if GR_AA_CONVEX_TESSELLATOR_VIZ
16084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void draw(SkCanvas* canvas, const GrAAConvexTessellator& tess) const;
16184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    #endif
16284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
16384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    private:
16484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        void computeNormals(const GrAAConvexTessellator& result);
165364ad00446923d1cbc963c7358cd9b01efc53d3erobertphillips        void computeBisectors(const GrAAConvexTessellator& tess);
16684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
16784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        SkDEBUGCODE(bool isConvex(const GrAAConvexTessellator& tess) const;)
16884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
16984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        struct PointData {
17084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            SkPoint fNorm;
17184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            SkPoint fBisector;
17284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            int     fIndex;
17384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips            int     fOrigEdgeId;
17484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        };
17584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
17684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        SkTDArray<PointData> fPts;
17784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    };
17884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
179fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    // Represents whether a given point is within a curve. A point is inside a curve only if it is
180fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    // an interior point within a quad, cubic, or conic, or if it is the endpoint of a quad, cubic,
181fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    // or conic with another curve meeting it at (more or less) the same angle.
182fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    enum CurveState {
183fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas        // point is a sharp vertex
184fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas        kSharp_CurveState,
185fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas        // endpoint of a curve with the other side's curvature not yet determined
186fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas        kIndeterminate_CurveState,
187fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas        // point is in the interior of a curve
188fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas        kCurve_CurveState
189fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    };
190fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas
19184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    bool movable(int index) const { return fMovable[index]; }
19284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
19384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // Movable points are those that can be slid along their bisector.
19484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // Basically, a point is immovable if it is part of the original
19584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // polygon or it results from the fusing of two bisectors.
196fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    int addPt(const SkPoint& pt, SkScalar depth, SkScalar coverage, bool movable, CurveState curve);
19784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void popLastPt();
19884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void popFirstPtShuffle();
19984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
200bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita    void updatePt(int index, const SkPoint& pt, SkScalar depth, SkScalar coverage);
20184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
20284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void addTri(int i0, int i1, int i2);
20384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
20484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void reservePts(int count) {
20584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        fPts.setReserve(count);
206bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita        fCoverages.setReserve(count);
20784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips        fMovable.setReserve(count);
20884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    }
20984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
21084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    SkScalar computeDepthFromEdge(int edgeIdx, const SkPoint& p) const;
21184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
21284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    bool computePtAlongBisector(int startIdx, const SkPoint& bisector,
21384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips                                int edgeIdx, SkScalar desiredDepth,
21484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips                                SkPoint* result) const;
21584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2161d08998e4fb81755978f3d1c11744a6c77ddab2eRobert Phillips    void lineTo(const SkPoint& p, CurveState curve);
217bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita
218fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    void lineTo(const SkMatrix& m, SkPoint p, CurveState curve);
2191a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2201d08998e4fb81755978f3d1c11744a6c77ddab2eRobert Phillips    void quadTo(const SkPoint pts[3]);
221bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita
2221a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    void quadTo(const SkMatrix& m, SkPoint pts[3]);
2231a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2241a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    void cubicTo(const SkMatrix& m, SkPoint pts[4]);
2251a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
2261a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas    void conicTo(const SkMatrix& m, SkPoint pts[3], SkScalar w);
2271a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
22884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void terminate(const Ring& lastRing);
22984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
23084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // return false on failure/degenerate path
23184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    bool extractFromPath(const SkMatrix& m, const SkPath& path);
23284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void computeBisectors();
23384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
23484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    void fanRing(const Ring& ring);
23584b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
23684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    Ring* getNextRing(Ring* lastRing);
23784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2389d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    void createOuterRing(const Ring& previousRing, SkScalar outset, SkScalar coverage,
239bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita                         Ring* nextRing);
24084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2419d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    bool createInsetRings(Ring& previousRing, SkScalar initialDepth, SkScalar initialCoverage,
242bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita                          SkScalar targetDepth, SkScalar targetCoverage, Ring** finalRing);
24384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2449d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary    bool createInsetRing(const Ring& lastRing, Ring* nextRing,
2459d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary                         SkScalar initialDepth, SkScalar initialCoverage, SkScalar targetDepth,
246bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita                         SkScalar targetCoverage, bool forceNew);
24784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
248bd5d7e75c1ef08816bfd8eed52150cd716e15d5bfmalita    void validate() const;
24984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2501d08998e4fb81755978f3d1c11744a6c77ddab2eRobert Phillips    // fPts, fCoverages, fMovable & fCurveState should always have the same # of elements
251fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<SkPoint>    fPts;
252fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<SkScalar>   fCoverages;
25384b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // movable points are those that can be slid further along their bisector
254fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<bool>       fMovable;
2551d08998e4fb81755978f3d1c11744a6c77ddab2eRobert Phillips    // Tracks whether a given point is interior to a curve. Such points are
2561d08998e4fb81755978f3d1c11744a6c77ddab2eRobert Phillips    // assumed to have shallow curvature.
2571d08998e4fb81755978f3d1c11744a6c77ddab2eRobert Phillips    SkTDArray<CurveState> fCurveState;
25884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
25984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // The outward facing normals for the original polygon
260fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<SkVector>   fNorms;
26184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // The inward facing bisector at each point in the original polygon. Only
26284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // needed for exterior ring creation and then handed off to the initial ring.
263fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<SkVector>   fBisectors;
2641a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
265fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkPoint::Side         fSide;    // winding of the original polygon
26684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
26784b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // The triangulation of the points
268fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<int>        fIndices;
26984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
270fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    Ring                  fInitialRing;
27184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#if GR_AA_CONVEX_TESSELLATOR_VIZ
27284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips    // When visualizing save all the rings
273fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<Ring*>      fRings;
27484b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#else
275fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    Ring                  fRings[2];
27684b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#endif
277fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    CandidateVerts        fCandidateVerts;
27884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
2798c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    // the stroke width is only used for stroke or stroke-and-fill styles
280fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkScalar              fStrokeWidth;
2818c170971f182d47bc9af71fc88a607740d03dfd5robertphillips    SkStrokeRec::Style    fStyle;
28284b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
283fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkPaint::Join         fJoin;
2841a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
285fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkScalar              fMiterLimit;
2861a1b3ac0d4feecb0fefa8a07c7abf3471c96f545ethannicholas
287fab4a9b9882bfd1c2d8c3fd5eeaf691caeba0f31ethannicholas    SkTDArray<SkPoint>    fPointBuffer;
28884b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips};
28984b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
29084b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips
29184b008873b5bdf35eba9185038fb3b5580a8b9a8robertphillips#endif
292