blob: 40a50c5fe098f0341be74d51827a66450a30ceab [file] [log] [blame]
caryclark@google.com07393ca2013-04-08 11:47:37 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#ifndef SkOpSegment_DEFINE
8#define SkOpSegment_DEFINE
9
10#include "SkOpAngle.h"
caryclark@google.comcffbcc32013-06-04 17:59:42 +000011#include "SkOpSpan.h"
caryclark54359292015-03-26 07:52:43 -070012#include "SkOpTAllocator.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +000013#include "SkPathOpsBounds.h"
caryclark03b03ca2015-04-23 09:13:37 -070014#include "SkPathOpsCubic.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +000015#include "SkPathOpsCurve.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +000016
caryclark1049f122015-04-20 08:31:59 -070017struct SkDCurve;
caryclark54359292015-03-26 07:52:43 -070018class SkOpCoincidence;
19class SkOpContour;
caryclark624637c2015-05-11 07:21:27 -070020enum class SkOpRayDir;
21struct SkOpRayHit;
caryclark@google.com07393ca2013-04-08 11:47:37 +000022class SkPathWriter;
23
24class SkOpSegment {
25public:
caryclark54359292015-03-26 07:52:43 -070026 enum AllowAlias {
27 kAllowAlias,
28 kNoAlias
29 };
caryclark@google.com07393ca2013-04-08 11:47:37 +000030
31 bool operator<(const SkOpSegment& rh) const {
32 return fBounds.fTop < rh.fBounds.fTop;
33 }
34
caryclark54359292015-03-26 07:52:43 -070035 SkOpAngle* activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr, SkOpSpanBase** endPtr,
caryclarkbca19f72015-05-13 08:23:48 -070036 bool* done);
caryclark54359292015-03-26 07:52:43 -070037 SkOpAngle* activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** startPtr,
caryclarkbca19f72015-05-13 08:23:48 -070038 SkOpSpanBase** endPtr, bool* done);
caryclark54359292015-03-26 07:52:43 -070039 SkOpAngle* activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** startPtr,
caryclarkbca19f72015-05-13 08:23:48 -070040 SkOpSpanBase** endPtr, bool* done);
caryclark54359292015-03-26 07:52:43 -070041 bool activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask, int xorSuMask,
42 SkPathOp op);
43 bool activeOp(int xorMiMask, int xorSuMask, SkOpSpanBase* start, SkOpSpanBase* end, SkPathOp op,
44 int* sumMiWinding, int* sumSuWinding);
45
caryclark54359292015-03-26 07:52:43 -070046 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end);
47 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* sumWinding);
caryclark27c8eb82015-07-06 11:38:33 -070048 void addAlignIntersection(SkOpPtT& endPtT, SkPoint& oldPt,
49 SkOpContourHead* contourList, SkChunkAlloc* allocator);
50
51 void addAlignIntersections(SkOpContourHead* contourList, SkChunkAlloc* allocator) {
52 this->addAlignIntersection(*fHead.ptT(), fOriginal[0], contourList, allocator);
53 this->addAlignIntersection(*fTail.ptT(), fOriginal[1], contourList, allocator);
54 }
caryclark54359292015-03-26 07:52:43 -070055
caryclark03b03ca2015-04-23 09:13:37 -070056 SkOpSegment* addConic(SkPoint pts[3], SkScalar weight, SkOpContour* parent) {
caryclark1049f122015-04-20 08:31:59 -070057 init(pts, weight, parent, SkPath::kConic_Verb);
caryclarkaec25102015-04-29 08:28:30 -070058 SkDCurve curve;
59 curve.fConic.set(pts, weight);
60 curve.setConicBounds(pts, weight, 0, 1, &fBounds);
caryclark03b03ca2015-04-23 09:13:37 -070061 return this;
caryclark1049f122015-04-20 08:31:59 -070062 }
63
caryclark03b03ca2015-04-23 09:13:37 -070064 SkOpSegment* addCubic(SkPoint pts[4], SkOpContour* parent) {
caryclark1049f122015-04-20 08:31:59 -070065 init(pts, 1, parent, SkPath::kCubic_Verb);
caryclarkaec25102015-04-29 08:28:30 -070066 SkDCurve curve;
67 curve.fCubic.set(pts);
68 curve.setCubicBounds(pts, 1, 0, 1, &fBounds);
caryclark03b03ca2015-04-23 09:13:37 -070069 return this;
caryclark54359292015-03-26 07:52:43 -070070 }
71
caryclarkef784fb2015-10-30 12:03:06 -070072 bool addCurveTo(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPathWriter* path) const;
caryclark54359292015-03-26 07:52:43 -070073
74 SkOpAngle* addEndSpan(SkChunkAlloc* allocator) {
75 SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
76 angle->set(&fTail, fTail.prev());
77 fTail.setFromAngle(angle);
78 return angle;
79 }
80
caryclark03b03ca2015-04-23 09:13:37 -070081 SkOpSegment* addLine(SkPoint pts[2], SkOpContour* parent) {
caryclark1049f122015-04-20 08:31:59 -070082 init(pts, 1, parent, SkPath::kLine_Verb);
caryclark54359292015-03-26 07:52:43 -070083 fBounds.set(pts, 2);
caryclark03b03ca2015-04-23 09:13:37 -070084 return this;
caryclark54359292015-03-26 07:52:43 -070085 }
86
87 SkOpPtT* addMissing(double t, SkOpSegment* opp, SkChunkAlloc* );
caryclark54359292015-03-26 07:52:43 -070088
89 SkOpAngle* addStartSpan(SkChunkAlloc* allocator) {
90 SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator);
91 angle->set(&fHead, fHead.next());
92 fHead.setToAngle(angle);
93 return angle;
94 }
95
caryclark03b03ca2015-04-23 09:13:37 -070096 SkOpSegment* addQuad(SkPoint pts[3], SkOpContour* parent) {
caryclark1049f122015-04-20 08:31:59 -070097 init(pts, 1, parent, SkPath::kQuad_Verb);
caryclarkaec25102015-04-29 08:28:30 -070098 SkDCurve curve;
99 curve.fQuad.set(pts);
100 curve.setQuadBounds(pts, 1, 0, 1, &fBounds);
caryclark03b03ca2015-04-23 09:13:37 -0700101 return this;
caryclark54359292015-03-26 07:52:43 -0700102 }
103
104 SkOpPtT* addT(double t, AllowAlias , SkChunkAlloc* );
105
106 void align();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000107
caryclark@google.com07393ca2013-04-08 11:47:37 +0000108 const SkPathOpsBounds& bounds() const {
109 return fBounds;
110 }
111
caryclark54359292015-03-26 07:52:43 -0700112 void bumpCount() {
113 ++fCount;
114 }
115
116 void calcAngles(SkChunkAlloc*);
caryclarkbca19f72015-05-13 08:23:48 -0700117 bool collapsed() const;
caryclark54359292015-03-26 07:52:43 -0700118 static void ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
119 SkOpAngle::IncludeType );
caryclark624637c2015-05-11 07:21:27 -0700120 static void ComputeOneSumReverse(SkOpAngle* baseAngle, SkOpAngle* nextAngle,
caryclark54359292015-03-26 07:52:43 -0700121 SkOpAngle::IncludeType );
122 int computeSum(SkOpSpanBase* start, SkOpSpanBase* end, SkOpAngle::IncludeType includeType);
123
124 SkOpContour* contour() const {
125 return fContour;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000126 }
127
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000128 int count() const {
caryclark54359292015-03-26 07:52:43 -0700129 return fCount;
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000130 }
131
caryclark54359292015-03-26 07:52:43 -0700132 void debugAddAngle(double startT, double endT, SkChunkAlloc*);
caryclark26ad22a2015-10-16 09:03:38 -0700133 void debugAddAlignIntersection(const char* id, SkPathOpsDebug::GlitchLog* glitches,
134 const SkOpPtT& endPtT, const SkPoint& oldPt,
135 const SkOpContourHead* ) const;
136
137 void debugAddAlignIntersections(const char* id, SkPathOpsDebug::GlitchLog* glitches,
138 SkOpContourHead* contourList) const {
139 this->debugAddAlignIntersection(id, glitches, *fHead.ptT(), fOriginal[0], contourList);
140 this->debugAddAlignIntersection(id, glitches, *fTail.ptT(), fOriginal[1], contourList);
141 }
142
143 bool debugAddMissing(double t, const SkOpSegment* opp) const;
144 void debugAlign(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
caryclark54359292015-03-26 07:52:43 -0700145 const SkOpAngle* debugAngle(int id) const;
caryclark26ad22a2015-10-16 09:03:38 -0700146#if DEBUG_ANGLE
147 void debugCheckAngleCoin() const;
148#endif
149 void debugCheckHealth(const char* id, SkPathOpsDebug::GlitchLog* ) const;
caryclark54359292015-03-26 07:52:43 -0700150 SkOpContour* debugContour(int id);
caryclark26ad22a2015-10-16 09:03:38 -0700151 void debugFindCollapsed(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
caryclark54359292015-03-26 07:52:43 -0700152
153 int debugID() const {
caryclark1049f122015-04-20 08:31:59 -0700154 return SkDEBUGRELEASE(fID, -1);
caryclark54359292015-03-26 07:52:43 -0700155 }
156
caryclark54359292015-03-26 07:52:43 -0700157 SkOpAngle* debugLastAngle();
caryclark26ad22a2015-10-16 09:03:38 -0700158 void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* glitches,
159 const SkOpCoincidence* coincidences) const;
160 void debugMoveMultiples(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
161 void debugMoveNearby(const char* id, SkPathOpsDebug::GlitchLog* glitches) const;
caryclark54359292015-03-26 07:52:43 -0700162 const SkOpPtT* debugPtT(int id) const;
163 void debugReset();
164 const SkOpSegment* debugSegment(int id) const;
165
166#if DEBUG_ACTIVE_SPANS
167 void debugShowActiveSpans() const;
168#endif
169#if DEBUG_MARK_DONE
170 void debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding);
171 void debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding, int oppWinding);
172#endif
173
174 const SkOpSpanBase* debugSpan(int id) const;
175 void debugValidate() const;
176 void detach(const SkOpSpan* );
caryclark26ad22a2015-10-16 09:03:38 -0700177 double distSq(double t, const SkOpAngle* opp) const;
caryclark54359292015-03-26 07:52:43 -0700178
caryclark@google.com07393ca2013-04-08 11:47:37 +0000179 bool done() const {
caryclark54359292015-03-26 07:52:43 -0700180 SkASSERT(fDoneCount <= fCount);
181 return fDoneCount == fCount;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000182 }
183
184 bool done(const SkOpAngle* angle) const {
caryclark54359292015-03-26 07:52:43 -0700185 return angle->start()->starter(angle->end())->done();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000186 }
187
caryclark@google.com570863f2013-09-16 15:55:01 +0000188 SkDPoint dPtAtT(double mid) const {
caryclark1049f122015-04-20 08:31:59 -0700189 return (*CurveDPointAtT[fVerb])(fPts, fWeight, mid);
caryclark@google.com570863f2013-09-16 15:55:01 +0000190 }
191
caryclark54359292015-03-26 07:52:43 -0700192 SkDVector dSlopeAtT(double mid) const {
caryclark1049f122015-04-20 08:31:59 -0700193 return (*CurveDSlopeAtT[fVerb])(fPts, fWeight, mid);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000194 }
195
caryclark54359292015-03-26 07:52:43 -0700196 void dump() const;
197 void dumpAll() const;
198 void dumpAngles() const;
199 void dumpCoin() const;
caryclark26ad22a2015-10-16 09:03:38 -0700200 void dumpPts(const char* prefix = "seg") const;
201 void dumpPtsInner(const char* prefix = "seg") const;
caryclark54359292015-03-26 07:52:43 -0700202
caryclarkd4349722015-07-23 12:40:22 -0700203 void findCollapsed();
caryclark54359292015-03-26 07:52:43 -0700204 SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
205 SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op,
206 int xorMiMask, int xorSuMask);
207 SkOpSegment* findNextWinding(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
208 SkOpSpanBase** nextEnd, bool* unsortable);
209 SkOpSegment* findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable);
caryclark624637c2015-05-11 07:21:27 -0700210 SkOpSpan* findSortableTop(SkOpContour* );
caryclark54359292015-03-26 07:52:43 -0700211 SkOpGlobalState* globalState() const;
212
213 const SkOpSpan* head() const {
214 return &fHead;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000215 }
216
caryclark54359292015-03-26 07:52:43 -0700217 SkOpSpan* head() {
218 return &fHead;
caryclarkdac1d172014-06-17 05:15:38 -0700219 }
220
caryclark1049f122015-04-20 08:31:59 -0700221 void init(SkPoint pts[], SkScalar weight, SkOpContour* parent, SkPath::Verb verb);
caryclark54359292015-03-26 07:52:43 -0700222
223 SkOpSpan* insert(SkOpSpan* prev, SkChunkAlloc* allocator) {
224 SkOpSpan* result = SkOpTAllocator<SkOpSpan>::Allocate(allocator);
225 SkOpSpanBase* next = prev->next();
226 result->setPrev(prev);
227 prev->setNext(result);
228 SkDEBUGCODE(result->ptT()->fT = 0);
229 result->setNext(next);
230 if (next) {
231 next->setPrev(result);
232 }
233 return result;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000234 }
235
caryclark54359292015-03-26 07:52:43 -0700236 bool isClose(double t, const SkOpSegment* opp) const;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000237
238 bool isHorizontal() const {
239 return fBounds.fTop == fBounds.fBottom;
240 }
241
caryclark54359292015-03-26 07:52:43 -0700242 SkOpSegment* isSimple(SkOpSpanBase** end, int* step) {
halcanary96fcdcc2015-08-27 07:41:13 -0700243 return nextChase(end, step, nullptr, nullptr);
caryclark54359292015-03-26 07:52:43 -0700244 }
245
caryclark@google.com07393ca2013-04-08 11:47:37 +0000246 bool isVertical() const {
247 return fBounds.fLeft == fBounds.fRight;
248 }
249
caryclark54359292015-03-26 07:52:43 -0700250 bool isVertical(SkOpSpanBase* start, SkOpSpanBase* end) const {
caryclark1049f122015-04-20 08:31:59 -0700251 return (*CurveIsVertical[fVerb])(fPts, fWeight, start->t(), end->t());
caryclark@google.com07393ca2013-04-08 11:47:37 +0000252 }
253
caryclark54359292015-03-26 07:52:43 -0700254 bool isXor() const;
255
256 const SkPoint& lastPt() const {
257 return fPts[SkPathOpsVerbToPoints(fVerb)];
caryclark@google.com07393ca2013-04-08 11:47:37 +0000258 }
259
caryclark5b5ddd72015-05-18 05:12:56 -0700260 void markAllDone();
caryclark54359292015-03-26 07:52:43 -0700261 SkOpSpanBase* markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end);
262 bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
263 SkOpSpanBase** lastPtr);
264 bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
265 int oppWinding, SkOpSpanBase** lastPtr);
266 SkOpSpanBase* markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle);
267 SkOpSpanBase* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
268 const SkOpAngle* angle);
269 void markDone(SkOpSpan* );
270 bool markWinding(SkOpSpan* , int winding);
271 bool markWinding(SkOpSpan* , int winding, int oppWinding);
272 bool match(const SkOpPtT* span, const SkOpSegment* parent, double t, const SkPoint& pt) const;
caryclark27c8eb82015-07-06 11:38:33 -0700273 bool missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocator);
caryclarkd78c0882016-02-24 09:03:07 -0800274 bool moveMultiples();
caryclark08bc8482015-04-24 09:08:57 -0700275 void moveNearby();
caryclark54359292015-03-26 07:52:43 -0700276
277 SkOpSegment* next() const {
278 return fNext;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000279 }
280
caryclark54359292015-03-26 07:52:43 -0700281 SkOpSegment* nextChase(SkOpSpanBase** , int* step, SkOpSpan** , SkOpSpanBase** last) const;
282 bool operand() const;
283
284 static int OppSign(const SkOpSpanBase* start, const SkOpSpanBase* end) {
285 int result = start->t() < end->t() ? -start->upCast()->oppValue()
286 : end->upCast()->oppValue();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000287 return result;
288 }
289
caryclark54359292015-03-26 07:52:43 -0700290 bool oppXor() const;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000291
caryclark54359292015-03-26 07:52:43 -0700292 const SkOpSegment* prev() const {
293 return fPrev;
reed0dc4dd62015-03-24 13:55:33 -0700294 }
295
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000296 SkPoint ptAtT(double mid) const {
caryclark1049f122015-04-20 08:31:59 -0700297 return (*CurvePointAtT[fVerb])(fPts, fWeight, mid);
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000298 }
299
caryclark@google.com07393ca2013-04-08 11:47:37 +0000300 const SkPoint* pts() const {
301 return fPts;
302 }
303
caryclark54359292015-03-26 07:52:43 -0700304 bool ptsDisjoint(const SkOpPtT& span, const SkOpPtT& test) const {
305 return ptsDisjoint(span.fT, span.fPt, test.fT, test.fPt);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000306 }
307
caryclark54359292015-03-26 07:52:43 -0700308 bool ptsDisjoint(const SkOpPtT& span, double t, const SkPoint& pt) const {
309 return ptsDisjoint(span.fT, span.fPt, t, pt);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000310 }
311
caryclark54359292015-03-26 07:52:43 -0700312 bool ptsDisjoint(double t1, const SkPoint& pt1, double t2, const SkPoint& pt2) const;
313
caryclark624637c2015-05-11 07:21:27 -0700314 void rayCheck(const SkOpRayHit& base, SkOpRayDir dir, SkOpRayHit** hits,
315 SkChunkAlloc* allocator);
316
caryclark54359292015-03-26 07:52:43 -0700317 void resetVisited() {
318 fVisited = false;
319 }
320
321 void setContour(SkOpContour* contour) {
322 fContour = contour;
323 }
324
325 void setNext(SkOpSegment* next) {
326 fNext = next;
327 }
328
329 void setPrev(SkOpSegment* prev) {
330 fPrev = prev;
331 }
332
caryclarkbca19f72015-05-13 08:23:48 -0700333 void setVisited() {
334 fVisited = true;
caryclark54359292015-03-26 07:52:43 -0700335 }
336
337 void setUpWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* maxWinding, int* sumWinding) {
338 int deltaSum = SpanSign(start, end);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000339 *maxWinding = *sumWinding;
340 *sumWinding -= deltaSum;
341 }
342
caryclark54359292015-03-26 07:52:43 -0700343 void setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding,
344 int* maxWinding, int* sumWinding);
345 void setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding, int* sumSuWinding,
346 int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
347 void sortAngles();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000348
caryclark54359292015-03-26 07:52:43 -0700349 static int SpanSign(const SkOpSpanBase* start, const SkOpSpanBase* end) {
350 int result = start->t() < end->t() ? -start->upCast()->windValue()
351 : end->upCast()->windValue();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000352 return result;
353 }
354
caryclark54359292015-03-26 07:52:43 -0700355 SkOpAngle* spanToAngle(SkOpSpanBase* start, SkOpSpanBase* end) {
356 SkASSERT(start != end);
357 return start->t() < end->t() ? start->upCast()->toAngle() : start->fromAngle();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000358 }
359
caryclark1049f122015-04-20 08:31:59 -0700360 bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkDCurve* result) const;
361 bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkOpCurve* result) const;
caryclark54359292015-03-26 07:52:43 -0700362
363 const SkOpSpanBase* tail() const {
364 return &fTail;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000365 }
366
caryclark54359292015-03-26 07:52:43 -0700367 SkOpSpanBase* tail() {
368 return &fTail;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000369 }
skia.committer@gmail.com32840172013-04-09 07:01:27 +0000370
caryclark27c8eb82015-07-06 11:38:33 -0700371 bool testForCoincidence(const SkOpPtT* priorPtT, const SkOpPtT* ptT, const SkOpSpanBase* prior,
372 const SkOpSpanBase* spanBase, const SkOpSegment* opp, SkScalar flatnessLimit) const;
373
caryclark54359292015-03-26 07:52:43 -0700374 void undoneSpan(SkOpSpanBase** start, SkOpSpanBase** end);
375 int updateOppWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const;
376 int updateOppWinding(const SkOpAngle* angle) const;
377 int updateOppWindingReverse(const SkOpAngle* angle) const;
caryclark624637c2015-05-11 07:21:27 -0700378 int updateWinding(SkOpSpanBase* start, SkOpSpanBase* end);
379 int updateWinding(SkOpAngle* angle);
380 int updateWindingReverse(const SkOpAngle* angle);
caryclark54359292015-03-26 07:52:43 -0700381
382 static bool UseInnerWinding(int outerWinding, int innerWinding);
383
caryclark@google.com07393ca2013-04-08 11:47:37 +0000384 SkPath::Verb verb() const {
385 return fVerb;
386 }
387
caryclarkbca19f72015-05-13 08:23:48 -0700388 // look for two different spans that point to the same opposite segment
389 bool visited() {
390 if (!fVisited) {
391 fVisited = true;
392 return false;
393 }
394 return true;
395 }
396
caryclark1049f122015-04-20 08:31:59 -0700397 SkScalar weight() const {
398 return fWeight;
399 }
400
caryclark624637c2015-05-11 07:21:27 -0700401 SkOpSpan* windingSpanAtT(double tHit);
reed0dc4dd62015-03-24 13:55:33 -0700402 int windSum(const SkOpAngle* angle) const;
caryclark54359292015-03-26 07:52:43 -0700403
404 SkPoint* writablePt(bool end) {
405 return &fPts[end ? SkPathOpsVerbToPoints(fVerb) : 0];
reed0dc4dd62015-03-24 13:55:33 -0700406 }
reed0dc4dd62015-03-24 13:55:33 -0700407
caryclark@google.com07393ca2013-04-08 11:47:37 +0000408private:
caryclark54359292015-03-26 07:52:43 -0700409 SkOpSpan fHead; // the head span always has its t set to zero
410 SkOpSpanBase fTail; // the tail span always has its t set to one
411 SkOpContour* fContour;
412 SkOpSegment* fNext; // forward-only linked list used by contour to walk the segments
413 const SkOpSegment* fPrev;
caryclark27c8eb82015-07-06 11:38:33 -0700414 SkPoint fOriginal[2]; // if aligned, the original unaligned points are here
caryclark54359292015-03-26 07:52:43 -0700415 SkPoint* fPts; // pointer into array of points owned by edge builder that may be tweaked
416 SkPathOpsBounds fBounds; // tight bounds
caryclark1049f122015-04-20 08:31:59 -0700417 SkScalar fWeight;
caryclark54359292015-03-26 07:52:43 -0700418 int fCount; // number of spans (one for a non-intersecting segment)
419 int fDoneCount; // number of processed spans (zero initially)
caryclark@google.com07393ca2013-04-08 11:47:37 +0000420 SkPath::Verb fVerb;
caryclark54359292015-03-26 07:52:43 -0700421 bool fVisited; // used by missing coincidence check
caryclark1049f122015-04-20 08:31:59 -0700422 SkDEBUGCODE(int fID);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000423};
424
425#endif