blob: bd40fab6ccd93be97b3defa2b041df79b6920828 [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
Herb Derbyecc364c2017-04-19 15:09:48 -040010#include "SkArenaAlloc.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +000011#include "SkOpAngle.h"
caryclark@google.comcffbcc32013-06-04 17:59:42 +000012#include "SkOpSpan.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:
caryclark@google.com07393ca2013-04-08 11:47:37 +000026 bool operator<(const SkOpSegment& rh) const {
27 return fBounds.fTop < rh.fBounds.fTop;
28 }
29
caryclark54359292015-03-26 07:52:43 -070030 SkOpAngle* activeAngle(SkOpSpanBase* start, SkOpSpanBase** startPtr, SkOpSpanBase** endPtr,
caryclarkbca19f72015-05-13 08:23:48 -070031 bool* done);
caryclark54359292015-03-26 07:52:43 -070032 SkOpAngle* activeAngleInner(SkOpSpanBase* start, SkOpSpanBase** startPtr,
caryclarkbca19f72015-05-13 08:23:48 -070033 SkOpSpanBase** endPtr, bool* done);
caryclark54359292015-03-26 07:52:43 -070034 SkOpAngle* activeAngleOther(SkOpSpanBase* start, SkOpSpanBase** startPtr,
caryclarkbca19f72015-05-13 08:23:48 -070035 SkOpSpanBase** endPtr, bool* done);
caryclark54359292015-03-26 07:52:43 -070036 bool activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask, int xorSuMask,
37 SkPathOp op);
38 bool activeOp(int xorMiMask, int xorSuMask, SkOpSpanBase* start, SkOpSpanBase* end, SkPathOp op,
39 int* sumMiWinding, int* sumSuWinding);
40
caryclark54359292015-03-26 07:52:43 -070041 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end);
42 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* sumWinding);
43
caryclark03b03ca2015-04-23 09:13:37 -070044 SkOpSegment* addConic(SkPoint pts[3], SkScalar weight, SkOpContour* parent) {
caryclark1049f122015-04-20 08:31:59 -070045 init(pts, weight, parent, SkPath::kConic_Verb);
caryclarkaec25102015-04-29 08:28:30 -070046 SkDCurve curve;
47 curve.fConic.set(pts, weight);
48 curve.setConicBounds(pts, weight, 0, 1, &fBounds);
caryclark03b03ca2015-04-23 09:13:37 -070049 return this;
caryclark1049f122015-04-20 08:31:59 -070050 }
51
caryclark03b03ca2015-04-23 09:13:37 -070052 SkOpSegment* addCubic(SkPoint pts[4], SkOpContour* parent) {
caryclark1049f122015-04-20 08:31:59 -070053 init(pts, 1, parent, SkPath::kCubic_Verb);
caryclarkaec25102015-04-29 08:28:30 -070054 SkDCurve curve;
55 curve.fCubic.set(pts);
56 curve.setCubicBounds(pts, 1, 0, 1, &fBounds);
caryclark03b03ca2015-04-23 09:13:37 -070057 return this;
caryclark54359292015-03-26 07:52:43 -070058 }
59
caryclarkef784fb2015-10-30 12:03:06 -070060 bool addCurveTo(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPathWriter* path) const;
caryclark54359292015-03-26 07:52:43 -070061
caryclark55888e42016-07-18 10:01:36 -070062 SkOpAngle* addEndSpan() {
Herb Derbyecc364c2017-04-19 15:09:48 -040063 SkOpAngle* angle = this->globalState()->allocator()->make<SkOpAngle>();
caryclark54359292015-03-26 07:52:43 -070064 angle->set(&fTail, fTail.prev());
65 fTail.setFromAngle(angle);
66 return angle;
67 }
68
caryclark55888e42016-07-18 10:01:36 -070069 bool addExpanded(double newT, const SkOpSpanBase* test, bool* startOver);
70
caryclark03b03ca2015-04-23 09:13:37 -070071 SkOpSegment* addLine(SkPoint pts[2], SkOpContour* parent) {
caryclarkbb51f4a2016-08-23 07:38:48 -070072 SkASSERT(pts[0] != pts[1]);
caryclark1049f122015-04-20 08:31:59 -070073 init(pts, 1, parent, SkPath::kLine_Verb);
caryclark54359292015-03-26 07:52:43 -070074 fBounds.set(pts, 2);
caryclark03b03ca2015-04-23 09:13:37 -070075 return this;
caryclark54359292015-03-26 07:52:43 -070076 }
77
caryclark55888e42016-07-18 10:01:36 -070078 SkOpPtT* addMissing(double t, SkOpSegment* opp, bool* allExist);
caryclark54359292015-03-26 07:52:43 -070079
caryclark55888e42016-07-18 10:01:36 -070080 SkOpAngle* addStartSpan() {
Herb Derbyecc364c2017-04-19 15:09:48 -040081 SkOpAngle* angle = this->globalState()->allocator()->make<SkOpAngle>();
caryclark54359292015-03-26 07:52:43 -070082 angle->set(&fHead, fHead.next());
83 fHead.setToAngle(angle);
84 return angle;
85 }
86
caryclark03b03ca2015-04-23 09:13:37 -070087 SkOpSegment* addQuad(SkPoint pts[3], SkOpContour* parent) {
caryclark1049f122015-04-20 08:31:59 -070088 init(pts, 1, parent, SkPath::kQuad_Verb);
caryclarkaec25102015-04-29 08:28:30 -070089 SkDCurve curve;
90 curve.fQuad.set(pts);
91 curve.setQuadBounds(pts, 1, 0, 1, &fBounds);
caryclark03b03ca2015-04-23 09:13:37 -070092 return this;
caryclark54359292015-03-26 07:52:43 -070093 }
94
caryclark29b25632016-08-25 11:27:17 -070095 SkOpPtT* addT(double t);
Cary Clark73e597d2017-04-18 12:08:58 -040096 SkOpPtT* addT(double t, const SkPoint& pt);
caryclark54359292015-03-26 07:52:43 -070097
caryclark@google.com07393ca2013-04-08 11:47:37 +000098 const SkPathOpsBounds& bounds() const {
99 return fBounds;
100 }
101
caryclark54359292015-03-26 07:52:43 -0700102 void bumpCount() {
103 ++fCount;
104 }
105
caryclark55888e42016-07-18 10:01:36 -0700106 void calcAngles();
Cary Clarkba610292018-06-19 09:47:15 -0400107 SkOpSpanBase::Collapsed collapsed(double startT, double endT) const;
Cary Clark2587f412018-07-24 12:40:10 -0400108 static bool ComputeOneSum(const SkOpAngle* baseAngle, SkOpAngle* nextAngle,
caryclark54359292015-03-26 07:52:43 -0700109 SkOpAngle::IncludeType );
Cary Clark2587f412018-07-24 12:40:10 -0400110 static bool ComputeOneSumReverse(SkOpAngle* baseAngle, SkOpAngle* nextAngle,
caryclark54359292015-03-26 07:52:43 -0700111 SkOpAngle::IncludeType );
112 int computeSum(SkOpSpanBase* start, SkOpSpanBase* end, SkOpAngle::IncludeType includeType);
113
caryclark55888e42016-07-18 10:01:36 -0700114 void clearAll();
115 void clearOne(SkOpSpan* span);
116 static void ClearVisited(SkOpSpanBase* span);
117 bool contains(double t) const;
118
caryclark54359292015-03-26 07:52:43 -0700119 SkOpContour* contour() const {
120 return fContour;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000121 }
122
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000123 int count() const {
caryclark54359292015-03-26 07:52:43 -0700124 return fCount;
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000125 }
126
caryclark55888e42016-07-18 10:01:36 -0700127 void debugAddAngle(double startT, double endT);
Cary Clarkab87d7a2016-10-04 10:01:04 -0400128#if DEBUG_COIN
129 const SkOpPtT* debugAddT(double t, SkPathOpsDebug::GlitchLog* ) const;
caryclark30b9fdd2016-08-31 14:36:29 -0700130#endif
caryclark54359292015-03-26 07:52:43 -0700131 const SkOpAngle* debugAngle(int id) const;
caryclark26ad22a2015-10-16 09:03:38 -0700132#if DEBUG_ANGLE
133 void debugCheckAngleCoin() const;
134#endif
Cary Clarkab87d7a2016-10-04 10:01:04 -0400135#if DEBUG_COIN
136 void debugCheckHealth(SkPathOpsDebug::GlitchLog* ) const;
137 void debugClearAll(SkPathOpsDebug::GlitchLog* glitches) const;
138 void debugClearOne(const SkOpSpan* span, SkPathOpsDebug::GlitchLog* glitches) const;
caryclark55888e42016-07-18 10:01:36 -0700139#endif
140 const SkOpCoincidence* debugCoincidence() const;
caryclark30b9fdd2016-08-31 14:36:29 -0700141 SkOpContour* debugContour(int id) const;
caryclark54359292015-03-26 07:52:43 -0700142
143 int debugID() const {
caryclark1049f122015-04-20 08:31:59 -0700144 return SkDEBUGRELEASE(fID, -1);
caryclark54359292015-03-26 07:52:43 -0700145 }
146
caryclark54359292015-03-26 07:52:43 -0700147 SkOpAngle* debugLastAngle();
Cary Clarkab87d7a2016-10-04 10:01:04 -0400148#if DEBUG_COIN
149 void debugMissingCoincidence(SkPathOpsDebug::GlitchLog* glitches) const;
150 void debugMoveMultiples(SkPathOpsDebug::GlitchLog* glitches) const;
151 void debugMoveNearby(SkPathOpsDebug::GlitchLog* glitches) const;
caryclark55888e42016-07-18 10:01:36 -0700152#endif
caryclark54359292015-03-26 07:52:43 -0700153 const SkOpPtT* debugPtT(int id) const;
154 void debugReset();
155 const SkOpSegment* debugSegment(int id) const;
156
157#if DEBUG_ACTIVE_SPANS
Cary Clarkff114282016-12-14 11:56:16 -0500158 void debugShowActiveSpans(SkString* str) const;
caryclark54359292015-03-26 07:52:43 -0700159#endif
160#if DEBUG_MARK_DONE
161 void debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding);
162 void debugShowNewWinding(const char* fun, const SkOpSpan* span, int winding, int oppWinding);
163#endif
164
165 const SkOpSpanBase* debugSpan(int id) const;
166 void debugValidate() const;
caryclark55888e42016-07-18 10:01:36 -0700167
caryclark025b11e2016-08-25 05:21:14 -0700168#if DEBUG_COINCIDENCE_ORDER
Herb Derbyc3cc5fa2017-03-07 11:11:47 -0500169 void debugResetCoinT() const;
170 void debugSetCoinT(int, SkScalar ) const;
caryclark025b11e2016-08-25 05:21:14 -0700171#endif
172
Cary Clarkab87d7a2016-10-04 10:01:04 -0400173#if DEBUG_COIN
caryclark025b11e2016-08-25 05:21:14 -0700174 static void DebugClearVisited(const SkOpSpanBase* span);
caryclark55888e42016-07-18 10:01:36 -0700175
176 bool debugVisited() const {
177 if (!fDebugVisited) {
178 fDebugVisited = true;
179 return false;
180 }
181 return true;
182 }
183#endif
184
Cary Clarke47ae292016-10-05 08:51:39 -0400185#if DEBUG_ANGLE
caryclark26ad22a2015-10-16 09:03:38 -0700186 double distSq(double t, const SkOpAngle* opp) const;
Cary Clarke47ae292016-10-05 08:51:39 -0400187#endif
caryclark54359292015-03-26 07:52:43 -0700188
caryclark@google.com07393ca2013-04-08 11:47:37 +0000189 bool done() const {
caryclark15976282016-07-21 05:48:43 -0700190 SkOPASSERT(fDoneCount <= fCount);
caryclark54359292015-03-26 07:52:43 -0700191 return fDoneCount == fCount;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000192 }
193
194 bool done(const SkOpAngle* angle) const {
caryclark54359292015-03-26 07:52:43 -0700195 return angle->start()->starter(angle->end())->done();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000196 }
197
caryclark@google.com570863f2013-09-16 15:55:01 +0000198 SkDPoint dPtAtT(double mid) const {
caryclark1049f122015-04-20 08:31:59 -0700199 return (*CurveDPointAtT[fVerb])(fPts, fWeight, mid);
caryclark@google.com570863f2013-09-16 15:55:01 +0000200 }
201
caryclark54359292015-03-26 07:52:43 -0700202 SkDVector dSlopeAtT(double mid) const {
caryclark1049f122015-04-20 08:31:59 -0700203 return (*CurveDSlopeAtT[fVerb])(fPts, fWeight, mid);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000204 }
205
caryclark54359292015-03-26 07:52:43 -0700206 void dump() const;
207 void dumpAll() const;
208 void dumpAngles() const;
209 void dumpCoin() const;
caryclark26ad22a2015-10-16 09:03:38 -0700210 void dumpPts(const char* prefix = "seg") const;
211 void dumpPtsInner(const char* prefix = "seg") const;
caryclark54359292015-03-26 07:52:43 -0700212
caryclark55888e42016-07-18 10:01:36 -0700213 const SkOpPtT* existing(double t, const SkOpSegment* opp) const;
caryclark54359292015-03-26 07:52:43 -0700214 SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
Cary Clark1857ddb2018-07-11 11:01:43 -0400215 SkOpSpanBase** nextEnd, bool* unsortable, bool* simple,
216 SkPathOp op, int xorMiMask, int xorSuMask);
caryclark54359292015-03-26 07:52:43 -0700217 SkOpSegment* findNextWinding(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
218 SkOpSpanBase** nextEnd, bool* unsortable);
219 SkOpSegment* findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, bool* unsortable);
caryclark624637c2015-05-11 07:21:27 -0700220 SkOpSpan* findSortableTop(SkOpContour* );
caryclark54359292015-03-26 07:52:43 -0700221 SkOpGlobalState* globalState() const;
222
223 const SkOpSpan* head() const {
224 return &fHead;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000225 }
226
caryclark54359292015-03-26 07:52:43 -0700227 SkOpSpan* head() {
228 return &fHead;
caryclarkdac1d172014-06-17 05:15:38 -0700229 }
230
caryclark1049f122015-04-20 08:31:59 -0700231 void init(SkPoint pts[], SkScalar weight, SkOpContour* parent, SkPath::Verb verb);
caryclark54359292015-03-26 07:52:43 -0700232
caryclark55888e42016-07-18 10:01:36 -0700233 SkOpSpan* insert(SkOpSpan* prev) {
caryclark29b25632016-08-25 11:27:17 -0700234 SkOpGlobalState* globalState = this->globalState();
235 globalState->setAllocatedOpSpan();
Herb Derbyecc364c2017-04-19 15:09:48 -0400236 SkOpSpan* result = globalState->allocator()->make<SkOpSpan>();
caryclark54359292015-03-26 07:52:43 -0700237 SkOpSpanBase* next = prev->next();
238 result->setPrev(prev);
239 prev->setNext(result);
240 SkDEBUGCODE(result->ptT()->fT = 0);
241 result->setNext(next);
242 if (next) {
243 next->setPrev(result);
244 }
245 return result;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000246 }
247
caryclark54359292015-03-26 07:52:43 -0700248 bool isClose(double t, const SkOpSegment* opp) const;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000249
250 bool isHorizontal() const {
251 return fBounds.fTop == fBounds.fBottom;
252 }
253
Cary Clarkcadc5062018-08-06 17:24:04 -0400254 SkOpSegment* isSimple(SkOpSpanBase** end, int* step) const {
halcanary96fcdcc2015-08-27 07:41:13 -0700255 return nextChase(end, step, nullptr, nullptr);
caryclark54359292015-03-26 07:52:43 -0700256 }
257
caryclark@google.com07393ca2013-04-08 11:47:37 +0000258 bool isVertical() const {
259 return fBounds.fLeft == fBounds.fRight;
260 }
261
caryclark54359292015-03-26 07:52:43 -0700262 bool isVertical(SkOpSpanBase* start, SkOpSpanBase* end) const {
caryclark1049f122015-04-20 08:31:59 -0700263 return (*CurveIsVertical[fVerb])(fPts, fWeight, start->t(), end->t());
caryclark@google.com07393ca2013-04-08 11:47:37 +0000264 }
265
caryclark54359292015-03-26 07:52:43 -0700266 bool isXor() const;
267
caryclarkeed356d2016-09-14 07:18:20 -0700268 void joinEnds(SkOpSegment* start) {
269 fTail.ptT()->addOpp(start->fHead.ptT(), start->fHead.ptT());
270 }
271
caryclark54359292015-03-26 07:52:43 -0700272 const SkPoint& lastPt() const {
273 return fPts[SkPathOpsVerbToPoints(fVerb)];
caryclark@google.com07393ca2013-04-08 11:47:37 +0000274 }
275
caryclark5b5ddd72015-05-18 05:12:56 -0700276 void markAllDone();
Cary Clarkc050a1a2018-06-25 08:45:40 -0400277 bool markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end, SkOpSpanBase** found);
caryclark54359292015-03-26 07:52:43 -0700278 bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
279 SkOpSpanBase** lastPtr);
280 bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding,
281 int oppWinding, SkOpSpanBase** lastPtr);
Cary Clark2587f412018-07-24 12:40:10 -0400282 bool markAngle(int maxWinding, int sumWinding, const SkOpAngle* angle, SkOpSpanBase** result);
283 bool markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int oppSumWinding,
284 const SkOpAngle* angle, SkOpSpanBase** result);
caryclark54359292015-03-26 07:52:43 -0700285 void markDone(SkOpSpan* );
286 bool markWinding(SkOpSpan* , int winding);
287 bool markWinding(SkOpSpan* , int winding, int oppWinding);
caryclarkef4f32a2016-08-24 09:24:18 -0700288 bool match(const SkOpPtT* span, const SkOpSegment* parent, double t, const SkPoint& pt) const;
caryclark55888e42016-07-18 10:01:36 -0700289 bool missingCoincidence();
caryclarkd78c0882016-02-24 09:03:07 -0800290 bool moveMultiples();
Cary Clark28da2832017-03-21 10:30:50 -0400291 bool moveNearby();
caryclark54359292015-03-26 07:52:43 -0700292
293 SkOpSegment* next() const {
294 return fNext;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000295 }
296
caryclark54359292015-03-26 07:52:43 -0700297 SkOpSegment* nextChase(SkOpSpanBase** , int* step, SkOpSpan** , SkOpSpanBase** last) const;
298 bool operand() const;
299
300 static int OppSign(const SkOpSpanBase* start, const SkOpSpanBase* end) {
301 int result = start->t() < end->t() ? -start->upCast()->oppValue()
302 : end->upCast()->oppValue();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000303 return result;
304 }
305
caryclark54359292015-03-26 07:52:43 -0700306 bool oppXor() const;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000307
caryclark54359292015-03-26 07:52:43 -0700308 const SkOpSegment* prev() const {
309 return fPrev;
reed0dc4dd62015-03-24 13:55:33 -0700310 }
311
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000312 SkPoint ptAtT(double mid) const {
caryclark1049f122015-04-20 08:31:59 -0700313 return (*CurvePointAtT[fVerb])(fPts, fWeight, mid);
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000314 }
315
caryclark@google.com07393ca2013-04-08 11:47:37 +0000316 const SkPoint* pts() const {
317 return fPts;
318 }
319
caryclark54359292015-03-26 07:52:43 -0700320 bool ptsDisjoint(const SkOpPtT& span, const SkOpPtT& test) const {
caryclark55888e42016-07-18 10:01:36 -0700321 SkASSERT(this == span.segment());
322 SkASSERT(this == test.segment());
caryclark54359292015-03-26 07:52:43 -0700323 return ptsDisjoint(span.fT, span.fPt, test.fT, test.fPt);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000324 }
325
caryclark54359292015-03-26 07:52:43 -0700326 bool ptsDisjoint(const SkOpPtT& span, double t, const SkPoint& pt) const {
caryclark55888e42016-07-18 10:01:36 -0700327 SkASSERT(this == span.segment());
caryclark54359292015-03-26 07:52:43 -0700328 return ptsDisjoint(span.fT, span.fPt, t, pt);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000329 }
330
caryclark54359292015-03-26 07:52:43 -0700331 bool ptsDisjoint(double t1, const SkPoint& pt1, double t2, const SkPoint& pt2) const;
332
Herb Derbyc3cc5fa2017-03-07 11:11:47 -0500333 void rayCheck(const SkOpRayHit& base, SkOpRayDir dir, SkOpRayHit** hits, SkArenaAlloc*);
Cary Clarke47ae292016-10-05 08:51:39 -0400334 void release(const SkOpSpan* );
caryclark55888e42016-07-18 10:01:36 -0700335
Cary Clarkab87d7a2016-10-04 10:01:04 -0400336#if DEBUG_COIN
caryclark55888e42016-07-18 10:01:36 -0700337 void resetDebugVisited() const {
338 fDebugVisited = false;
339 }
340#endif
caryclark624637c2015-05-11 07:21:27 -0700341
caryclark54359292015-03-26 07:52:43 -0700342 void resetVisited() {
343 fVisited = false;
344 }
345
346 void setContour(SkOpContour* contour) {
347 fContour = contour;
348 }
349
350 void setNext(SkOpSegment* next) {
351 fNext = next;
352 }
353
354 void setPrev(SkOpSegment* prev) {
355 fPrev = prev;
356 }
357
caryclark54359292015-03-26 07:52:43 -0700358 void setUpWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* maxWinding, int* sumWinding) {
359 int deltaSum = SpanSign(start, end);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000360 *maxWinding = *sumWinding;
caryclark3cf2e202016-06-29 14:07:45 -0700361 if (*sumWinding == SK_MinS32) {
362 return;
363 }
caryclark@google.com07393ca2013-04-08 11:47:37 +0000364 *sumWinding -= deltaSum;
365 }
366
caryclark54359292015-03-26 07:52:43 -0700367 void setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding,
368 int* maxWinding, int* sumWinding);
369 void setUpWindings(SkOpSpanBase* start, SkOpSpanBase* end, int* sumMiWinding, int* sumSuWinding,
370 int* maxWinding, int* sumWinding, int* oppMaxWinding, int* oppSumWinding);
caryclarkb36a3cd2016-10-18 07:59:44 -0700371 bool sortAngles();
Cary Clark28da2832017-03-21 10:30:50 -0400372 bool spansNearby(const SkOpSpanBase* ref, const SkOpSpanBase* check, bool* found) const;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000373
caryclark54359292015-03-26 07:52:43 -0700374 static int SpanSign(const SkOpSpanBase* start, const SkOpSpanBase* end) {
375 int result = start->t() < end->t() ? -start->upCast()->windValue()
376 : end->upCast()->windValue();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000377 return result;
378 }
379
caryclark54359292015-03-26 07:52:43 -0700380 SkOpAngle* spanToAngle(SkOpSpanBase* start, SkOpSpanBase* end) {
381 SkASSERT(start != end);
382 return start->t() < end->t() ? start->upCast()->toAngle() : start->fromAngle();
caryclark@google.com07393ca2013-04-08 11:47:37 +0000383 }
384
caryclark1049f122015-04-20 08:31:59 -0700385 bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkDCurve* result) const;
caryclark54359292015-03-26 07:52:43 -0700386
387 const SkOpSpanBase* tail() const {
388 return &fTail;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000389 }
390
caryclark54359292015-03-26 07:52:43 -0700391 SkOpSpanBase* tail() {
392 return &fTail;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000393 }
skia.committer@gmail.com32840172013-04-09 07:01:27 +0000394
caryclark27c8eb82015-07-06 11:38:33 -0700395 bool testForCoincidence(const SkOpPtT* priorPtT, const SkOpPtT* ptT, const SkOpSpanBase* prior,
caryclark55888e42016-07-18 10:01:36 -0700396 const SkOpSpanBase* spanBase, const SkOpSegment* opp) const;
caryclark27c8eb82015-07-06 11:38:33 -0700397
Cary Clarkab2d73b2016-12-16 17:17:25 -0500398 SkOpSpan* undoneSpan();
caryclark54359292015-03-26 07:52:43 -0700399 int updateOppWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const;
400 int updateOppWinding(const SkOpAngle* angle) const;
401 int updateOppWindingReverse(const SkOpAngle* angle) const;
caryclark624637c2015-05-11 07:21:27 -0700402 int updateWinding(SkOpSpanBase* start, SkOpSpanBase* end);
403 int updateWinding(SkOpAngle* angle);
404 int updateWindingReverse(const SkOpAngle* angle);
caryclark54359292015-03-26 07:52:43 -0700405
406 static bool UseInnerWinding(int outerWinding, int innerWinding);
407
caryclark@google.com07393ca2013-04-08 11:47:37 +0000408 SkPath::Verb verb() const {
409 return fVerb;
410 }
411
caryclarkbca19f72015-05-13 08:23:48 -0700412 // look for two different spans that point to the same opposite segment
413 bool visited() {
414 if (!fVisited) {
415 fVisited = true;
416 return false;
417 }
418 return true;
419 }
420
caryclark1049f122015-04-20 08:31:59 -0700421 SkScalar weight() const {
422 return fWeight;
423 }
424
caryclark624637c2015-05-11 07:21:27 -0700425 SkOpSpan* windingSpanAtT(double tHit);
reed0dc4dd62015-03-24 13:55:33 -0700426 int windSum(const SkOpAngle* angle) const;
caryclark54359292015-03-26 07:52:43 -0700427
caryclark@google.com07393ca2013-04-08 11:47:37 +0000428private:
caryclark54359292015-03-26 07:52:43 -0700429 SkOpSpan fHead; // the head span always has its t set to zero
430 SkOpSpanBase fTail; // the tail span always has its t set to one
431 SkOpContour* fContour;
432 SkOpSegment* fNext; // forward-only linked list used by contour to walk the segments
433 const SkOpSegment* fPrev;
434 SkPoint* fPts; // pointer into array of points owned by edge builder that may be tweaked
435 SkPathOpsBounds fBounds; // tight bounds
caryclark1049f122015-04-20 08:31:59 -0700436 SkScalar fWeight;
caryclark54359292015-03-26 07:52:43 -0700437 int fCount; // number of spans (one for a non-intersecting segment)
438 int fDoneCount; // number of processed spans (zero initially)
caryclark@google.com07393ca2013-04-08 11:47:37 +0000439 SkPath::Verb fVerb;
caryclark54359292015-03-26 07:52:43 -0700440 bool fVisited; // used by missing coincidence check
Cary Clarkab87d7a2016-10-04 10:01:04 -0400441#if DEBUG_COIN
caryclark55888e42016-07-18 10:01:36 -0700442 mutable bool fDebugVisited; // used by debug missing coincidence check
443#endif
caryclark025b11e2016-08-25 05:21:14 -0700444#if DEBUG_COINCIDENCE_ORDER
445 mutable int fDebugBaseIndex;
446 mutable SkScalar fDebugBaseMin; // if > 0, the 1st t value in this seg vis-a-vis the ref seg
447 mutable SkScalar fDebugBaseMax;
448 mutable int fDebugLastIndex;
449 mutable SkScalar fDebugLastMin; // if > 0, the last t -- next t val - base has same sign
450 mutable SkScalar fDebugLastMax;
451#endif
caryclark1049f122015-04-20 08:31:59 -0700452 SkDEBUGCODE(int fID);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000453};
454
455#endif