OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrAAConvexTessellator_DEFINED | 8 #ifndef GrAAConvexTessellator_DEFINED |
9 #define GrAAConvexTessellator_DEFINED | 9 #define GrAAConvexTessellator_DEFINED |
10 | 10 |
11 #include "SkColor.h" | 11 #include "SkColor.h" |
12 #include "SkPaint.h" | |
12 #include "SkPoint.h" | 13 #include "SkPoint.h" |
13 #include "SkScalar.h" | 14 #include "SkScalar.h" |
14 #include "SkTDArray.h" | 15 #include "SkTDArray.h" |
15 | 16 |
16 class SkCanvas; | 17 class SkCanvas; |
17 class SkMatrix; | 18 class SkMatrix; |
18 class SkPath; | 19 class SkPath; |
19 | 20 |
20 //#define GR_AA_CONVEX_TESSELLATOR_VIZ 1 | 21 //#define GR_AA_CONVEX_TESSELLATOR_VIZ 1 |
21 | 22 |
robertphillips
2015/06/16 13:13:02
// Add a comment ?
ethannicholas
2015/06/16 14:53:29
Done.
| |
23 static const SkScalar kAntialiasingRadius = 0.5f; | |
24 | |
22 class GrAAConvexTessellator; | 25 class GrAAConvexTessellator; |
23 | 26 |
24 // The AAConvexTessellator holds the global pool of points and the triangulation | 27 // The AAConvexTessellator holds the global pool of points and the triangulation |
25 // that connects them. It also drives the tessellation process. | 28 // that connects them. It also drives the tessellation process. |
26 // The outward facing normals of the original polygon are stored (in 'fNorms') t o service | 29 // The outward facing normals of the original polygon are stored (in 'fNorms') t o service |
27 // computeDepthFromEdge requests. | 30 // computeDepthFromEdge requests. |
28 class GrAAConvexTessellator { | 31 class GrAAConvexTessellator { |
29 public: | 32 public: |
30 GrAAConvexTessellator(SkScalar targetDepth = 0.5f) | 33 GrAAConvexTessellator(SkScalar strokeWidth = -1.0f, |
34 SkPaint::Join join = SkPaint::Join::kBevel_Join, | |
35 SkScalar miterLimit = 0.0f) | |
31 : fSide(SkPoint::kOn_Side) | 36 : fSide(SkPoint::kOn_Side) |
32 , fTargetDepth(targetDepth) { | 37 , fStrokeWidth(strokeWidth) |
38 , fJoin(join) | |
39 , fMiterLimit(miterLimit) { | |
33 } | 40 } |
34 | 41 |
35 void setTargetDepth(SkScalar targetDepth) { fTargetDepth = targetDepth; } | |
36 SkScalar targetDepth() const { return fTargetDepth; } | |
37 | |
38 SkPoint::Side side() const { return fSide; } | 42 SkPoint::Side side() const { return fSide; } |
39 | 43 |
40 bool tessellate(const SkMatrix& m, const SkPath& path); | 44 bool tessellate(const SkMatrix& m, const SkPath& path); |
41 | 45 |
42 // The next five should only be called after tessellate to extract the resul t | 46 // The next five should only be called after tessellate to extract the resul t |
43 int numPts() const { return fPts.count(); } | 47 int numPts() const { return fPts.count(); } |
44 int numIndices() const { return fIndices.count(); } | 48 int numIndices() const { return fIndices.count(); } |
45 | 49 |
46 const SkPoint& lastPoint() const { return fPts.top(); } | 50 const SkPoint& lastPoint() const { return fPts.top(); } |
47 const SkPoint& point(int index) const { return fPts[index]; } | 51 const SkPoint& point(int index) const { return fPts[index]; } |
48 int index(int index) const { return fIndices[index]; } | 52 int index(int index) const { return fIndices[index]; } |
49 SkScalar depth(int index) const {return fDepths[index]; } | 53 SkScalar coverage(int index) const { return fCoverages[index]; } |
50 | 54 |
51 #if GR_AA_CONVEX_TESSELLATOR_VIZ | 55 #if GR_AA_CONVEX_TESSELLATOR_VIZ |
52 void draw(SkCanvas* canvas) const; | 56 void draw(SkCanvas* canvas) const; |
53 #endif | 57 #endif |
54 | 58 |
55 // The tessellator can be reused for multiple paths by rewinding in between | 59 // The tessellator can be reused for multiple paths by rewinding in between |
56 void rewind(); | 60 void rewind(); |
57 | 61 |
58 private: | 62 private: |
59 // CandidateVerts holds the vertices for the next ring while they are | 63 // CandidateVerts holds the vertices for the next ring while they are |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
132 } | 136 } |
133 | 137 |
134 // init should be called after all the indices have been added (via addI dx) | 138 // init should be called after all the indices have been added (via addI dx) |
135 void init(const GrAAConvexTessellator& tess); | 139 void init(const GrAAConvexTessellator& tess); |
136 void init(const SkTDArray<SkVector>& norms, const SkTDArray<SkVector>& b isectors); | 140 void init(const SkTDArray<SkVector>& norms, const SkTDArray<SkVector>& b isectors); |
137 | 141 |
138 const SkPoint& norm(int index) const { return fPts[index].fNorm; } | 142 const SkPoint& norm(int index) const { return fPts[index].fNorm; } |
139 const SkPoint& bisector(int index) const { return fPts[index].fBisector; } | 143 const SkPoint& bisector(int index) const { return fPts[index].fBisector; } |
140 int index(int index) const { return fPts[index].fIndex; } | 144 int index(int index) const { return fPts[index].fIndex; } |
141 int origEdgeID(int index) const { return fPts[index].fOrigEdgeId; } | 145 int origEdgeID(int index) const { return fPts[index].fOrigEdgeId; } |
146 void setOrigEdgeId(int index, int id) { fPts[index].fOrigEdgeId = id; } | |
142 | 147 |
143 #if GR_AA_CONVEX_TESSELLATOR_VIZ | 148 #if GR_AA_CONVEX_TESSELLATOR_VIZ |
144 void draw(SkCanvas* canvas, const GrAAConvexTessellator& tess) const; | 149 void draw(SkCanvas* canvas, const GrAAConvexTessellator& tess) const; |
145 #endif | 150 #endif |
146 | 151 |
147 private: | 152 private: |
148 void computeNormals(const GrAAConvexTessellator& result); | 153 void computeNormals(const GrAAConvexTessellator& result); |
149 void computeBisectors(const GrAAConvexTessellator& tess); | 154 void computeBisectors(const GrAAConvexTessellator& tess); |
150 | 155 |
151 SkDEBUGCODE(bool isConvex(const GrAAConvexTessellator& tess) const;) | 156 SkDEBUGCODE(bool isConvex(const GrAAConvexTessellator& tess) const;) |
152 | 157 |
153 struct PointData { | 158 struct PointData { |
154 SkPoint fNorm; | 159 SkPoint fNorm; |
155 SkPoint fBisector; | 160 SkPoint fBisector; |
156 int fIndex; | 161 int fIndex; |
157 int fOrigEdgeId; | 162 int fOrigEdgeId; |
158 }; | 163 }; |
159 | 164 |
160 SkTDArray<PointData> fPts; | 165 SkTDArray<PointData> fPts; |
161 }; | 166 }; |
162 | 167 |
163 bool movable(int index) const { return fMovable[index]; } | 168 bool movable(int index) const { return fMovable[index]; } |
164 | 169 |
165 // Movable points are those that can be slid along their bisector. | 170 // Movable points are those that can be slid along their bisector. |
166 // Basically, a point is immovable if it is part of the original | 171 // Basically, a point is immovable if it is part of the original |
167 // polygon or it results from the fusing of two bisectors. | 172 // polygon or it results from the fusing of two bisectors. |
168 int addPt(const SkPoint& pt, SkScalar depth, bool movable, bool isCurve); | 173 int addPt(const SkPoint& pt, SkScalar depth, SkScalar coverage, bool movable , bool isCurve); |
169 void popLastPt(); | 174 void popLastPt(); |
170 void popFirstPtShuffle(); | 175 void popFirstPtShuffle(); |
171 | 176 |
172 void updatePt(int index, const SkPoint& pt, SkScalar depth); | 177 void updatePt(int index, const SkPoint& pt, SkScalar depth, SkScalar coverag e); |
173 | 178 |
174 void addTri(int i0, int i1, int i2); | 179 void addTri(int i0, int i1, int i2); |
175 | 180 |
176 void reservePts(int count) { | 181 void reservePts(int count) { |
177 fPts.setReserve(count); | 182 fPts.setReserve(count); |
178 fDepths.setReserve(count); | 183 fCoverages.setReserve(count); |
179 fMovable.setReserve(count); | 184 fMovable.setReserve(count); |
180 } | 185 } |
181 | 186 |
182 SkScalar computeDepthFromEdge(int edgeIdx, const SkPoint& p) const; | 187 SkScalar computeDepthFromEdge(int edgeIdx, const SkPoint& p) const; |
183 | 188 |
184 bool computePtAlongBisector(int startIdx, const SkPoint& bisector, | 189 bool computePtAlongBisector(int startIdx, const SkPoint& bisector, |
185 int edgeIdx, SkScalar desiredDepth, | 190 int edgeIdx, SkScalar desiredDepth, |
186 SkPoint* result) const; | 191 SkPoint* result) const; |
187 | 192 |
188 void lineTo(const SkMatrix& m, SkPoint p, bool isCurve); | 193 void lineTo(const SkMatrix& m, SkPoint p, bool isCurve); |
189 | 194 |
190 void quadTo(const SkMatrix& m, SkPoint pts[3]); | 195 void quadTo(const SkMatrix& m, SkPoint pts[3]); |
191 | 196 |
192 void cubicTo(const SkMatrix& m, SkPoint pts[4]); | 197 void cubicTo(const SkMatrix& m, SkPoint pts[4]); |
193 | 198 |
194 void conicTo(const SkMatrix& m, SkPoint pts[3], SkScalar w); | 199 void conicTo(const SkMatrix& m, SkPoint pts[3], SkScalar w); |
195 | 200 |
196 void terminate(const Ring& lastRing); | 201 void terminate(const Ring& lastRing); |
197 | 202 |
198 // return false on failure/degenerate path | 203 // return false on failure/degenerate path |
199 bool extractFromPath(const SkMatrix& m, const SkPath& path); | 204 bool extractFromPath(const SkMatrix& m, const SkPath& path); |
200 void computeBisectors(); | 205 void computeBisectors(); |
201 | 206 |
202 void fanRing(const Ring& ring); | 207 void fanRing(const Ring& ring); |
203 void createOuterRing(); | |
204 | 208 |
205 Ring* getNextRing(Ring* lastRing); | 209 Ring* getNextRing(Ring* lastRing); |
206 | 210 |
207 bool createInsetRing(const Ring& lastRing, Ring* nextRing); | 211 void createOuterRing(const Ring& previousRing, SkScalar outset, SkScalar cov erage, |
212 Ring* nextRing); | |
213 | |
214 bool createInsetRings(Ring& previousRing, SkScalar initialDepth, SkScalar in itialCoverage, | |
robertphillips
2015/06/16 13:13:02
tab this line over ?
| |
215 SkScalar targetDepth, SkScalar targetCoverage, Ring** finalRing); | |
216 | |
217 bool createInsetRing(const Ring& lastRing, Ring* nextRing, | |
218 SkScalar initialDepth, SkScalar initialCoverage, SkScal ar targetDepth, | |
219 SkScalar targetCoverage, bool forceNew); | |
208 | 220 |
209 void validate() const; | 221 void validate() const; |
210 | 222 |
211 | 223 |
212 #ifdef SK_DEBUG | 224 #ifdef SK_DEBUG |
213 SkScalar computeRealDepth(const SkPoint& p) const; | 225 SkScalar computeRealDepth(const SkPoint& p) const; |
214 void checkAllDepths() const; | 226 void checkAllDepths() const; |
215 #endif | 227 #endif |
216 | 228 |
217 // fPts, fWeights & fMovable should always have the same # of elements | 229 // fPts, fCoverages & fMovable should always have the same # of elements |
218 SkTDArray<SkPoint> fPts; | 230 SkTDArray<SkPoint> fPts; |
219 SkTDArray<SkScalar> fDepths; | 231 SkTDArray<SkScalar> fCoverages; |
220 // movable points are those that can be slid further along their bisector | 232 // movable points are those that can be slid further along their bisector |
221 SkTDArray<bool> fMovable; | 233 SkTDArray<bool> fMovable; |
222 | 234 |
223 // The outward facing normals for the original polygon | 235 // The outward facing normals for the original polygon |
224 SkTDArray<SkVector> fNorms; | 236 SkTDArray<SkVector> fNorms; |
225 // The inward facing bisector at each point in the original polygon. Only | 237 // The inward facing bisector at each point in the original polygon. Only |
226 // needed for exterior ring creation and then handed off to the initial ring . | 238 // needed for exterior ring creation and then handed off to the initial ring . |
227 SkTDArray<SkVector> fBisectors; | 239 SkTDArray<SkVector> fBisectors; |
228 | 240 |
229 // Tracks whether a given point is interior to a curve. Such points are | 241 // Tracks whether a given point is interior to a curve. Such points are |
230 // assumed to have shallow curvature. | 242 // assumed to have shallow curvature. |
231 SkTDArray<bool> fIsCurve; | 243 SkTDArray<bool> fIsCurve; |
232 | 244 |
233 SkPoint::Side fSide; // winding of the original polygon | 245 SkPoint::Side fSide; // winding of the original polygon |
234 | 246 |
235 // The triangulation of the points | 247 // The triangulation of the points |
236 SkTDArray<int> fIndices; | 248 SkTDArray<int> fIndices; |
237 | 249 |
238 Ring fInitialRing; | 250 Ring fInitialRing; |
239 #if GR_AA_CONVEX_TESSELLATOR_VIZ | 251 #if GR_AA_CONVEX_TESSELLATOR_VIZ |
240 // When visualizing save all the rings | 252 // When visualizing save all the rings |
241 SkTDArray<Ring*> fRings; | 253 SkTDArray<Ring*> fRings; |
242 #else | 254 #else |
243 Ring fRings[2]; | 255 Ring fRings[2]; |
244 #endif | 256 #endif |
245 CandidateVerts fCandidateVerts; | 257 CandidateVerts fCandidateVerts; |
246 | 258 |
247 SkScalar fTargetDepth; | 259 // < 0 means filling rather than stroking |
260 SkScalar fStrokeWidth; | |
261 | |
262 SkPaint::Join fJoin; | |
263 | |
264 SkScalar fMiterLimit; | |
248 | 265 |
249 SkTDArray<SkPoint> fPointBuffer; | 266 SkTDArray<SkPoint> fPointBuffer; |
250 | |
251 // If some goes wrong with the inset computation the tessellator will | |
252 // truncate the creation of the inset polygon. In this case the depth | |
253 // check will complain. | |
254 SkDEBUGCODE(bool fShouldCheckDepths;) | |
255 | |
256 SkDEBUGCODE(SkScalar fMinCross;) | |
257 | |
258 SkDEBUGCODE(SkScalar fMaxCross;) | |
259 }; | 267 }; |
260 | 268 |
261 | 269 |
262 #endif | 270 #endif |
263 | 271 |
OLD | NEW |