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