OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 #include "SkOpCoincidence.h" | 7 #include "SkOpCoincidence.h" |
8 #include "SkOpContour.h" | 8 #include "SkOpContour.h" |
9 #include "SkOpSegment.h" | 9 #include "SkOpSegment.h" |
10 #include "SkPathWriter.h" | 10 #include "SkPathWriter.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } | 79 } |
80 | 80 |
81 const SkOpSegment* SkOpPtT::segment() const { | 81 const SkOpSegment* SkOpPtT::segment() const { |
82 return span()->segment(); | 82 return span()->segment(); |
83 } | 83 } |
84 | 84 |
85 SkOpSegment* SkOpPtT::segment() { | 85 SkOpSegment* SkOpPtT::segment() { |
86 return span()->segment(); | 86 return span()->segment(); |
87 } | 87 } |
88 | 88 |
89 // find the starting or ending span with an existing loop of angles | |
90 // OPTIMIZE? remove the spans pointing to windValue==0 here or earlier? | |
91 // FIXME? assert that only one other span has a valid windValue or oppValue | |
92 bool SkOpSpanBase::addSimpleAngle(bool checkFrom, SkChunkAlloc* allocator) { | |
93 SkOpAngle* angle; | |
94 if (checkFrom) { | |
95 if (!this->final()) { | |
96 return false; | |
97 } | |
98 if (this->fromAngle()) { | |
99 SkASSERT(this->fromAngle()->loopCount() == 2); | |
100 return true; | |
101 } | |
102 angle = this->segment()->addEndSpan(allocator); | |
103 } else { | |
104 SkASSERT(this->t() == 0); | |
105 SkOpSpan* span = this->upCast(); | |
106 if (span->toAngle()) { | |
107 SkASSERT(span->toAngle()->loopCount() == 2); | |
108 SkASSERT(!span->fromAngle()); | |
109 span->setFromAngle(span->toAngle()->next()); | |
110 return true; | |
111 } | |
112 angle = this->segment()->addStartSpan(allocator); | |
113 } | |
114 SkOpPtT* ptT = this->ptT(); | |
115 SkOpSpanBase* oSpanBase; | |
116 SkOpSpan* oSpan; | |
117 SkOpSegment* other; | |
118 do { | |
119 ptT = ptT->next(); | |
120 oSpanBase = ptT->span(); | |
121 oSpan = oSpanBase->upCastable(); | |
122 other = oSpanBase->segment(); | |
123 if (oSpan && oSpan->windValue()) { | |
124 break; | |
125 } | |
126 if (oSpanBase->t() == 0) { | |
127 continue; | |
128 } | |
129 SkOpSpan* oFromSpan = oSpanBase->prev(); | |
130 SkASSERT(oFromSpan->t() < 1); | |
131 if (oFromSpan->windValue()) { | |
132 break; | |
133 } | |
134 } while (ptT != this->ptT()); | |
135 SkOpAngle* oAngle; | |
136 if (checkFrom) { | |
137 oAngle = other->addStartSpan(allocator); | |
138 SkASSERT(oSpan && !oSpan->final()); | |
139 SkASSERT(oAngle == oSpan->toAngle()); | |
140 } else { | |
141 oAngle = other->addEndSpan(allocator); | |
142 SkASSERT(oAngle == oSpanBase->fromAngle()); | |
143 } | |
144 angle->insert(oAngle); | |
145 return true; | |
146 } | |
147 | |
148 void SkOpSpanBase::align() { | 89 void SkOpSpanBase::align() { |
149 if (this->fAligned) { | 90 if (this->fAligned) { |
150 return; | 91 return; |
151 } | 92 } |
152 SkASSERT(!zero_or_one(this->fPtT.fT)); | 93 SkASSERT(!zero_or_one(this->fPtT.fT)); |
153 SkASSERT(this->fPtT.next()); | 94 SkASSERT(this->fPtT.next()); |
154 // if a linked pt/t pair has a t of zero or one, use it as the base for alig
nment | 95 // if a linked pt/t pair has a t of zero or one, use it as the base for alig
nment |
155 SkOpPtT* ptT = &this->fPtT, * stopPtT = ptT; | 96 SkOpPtT* ptT = &this->fPtT, * stopPtT = ptT; |
156 while ((ptT = ptT->next()) != stopPtT) { | 97 while ((ptT = ptT->next()) != stopPtT) { |
157 if (zero_or_one(ptT->fT)) { | 98 if (zero_or_one(ptT->fT)) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 } | 242 } |
302 compare = nextC; | 243 compare = nextC; |
303 } | 244 } |
304 spanPtT->insert(remainder); | 245 spanPtT->insert(remainder); |
305 tryNextRemainder: | 246 tryNextRemainder: |
306 remainder = next; | 247 remainder = next; |
307 } | 248 } |
308 fSpanAdds += span->fSpanAdds; | 249 fSpanAdds += span->fSpanAdds; |
309 } | 250 } |
310 | 251 |
311 void SkOpSpan::applyCoincidence(SkOpSpan* opp) { | |
312 SkASSERT(!final()); | |
313 SkASSERT(0); // incomplete | |
314 } | |
315 | |
316 bool SkOpSpan::containsCoincidence(const SkOpSegment* segment) const { | 252 bool SkOpSpan::containsCoincidence(const SkOpSegment* segment) const { |
317 SkASSERT(this->segment() != segment); | 253 SkASSERT(this->segment() != segment); |
318 const SkOpSpan* next = fCoincident; | 254 const SkOpSpan* next = fCoincident; |
319 do { | 255 do { |
320 if (next->segment() == segment) { | 256 if (next->segment() == segment) { |
321 return true; | 257 return true; |
322 } | 258 } |
323 } while ((next = next->fCoincident) != this); | 259 } while ((next = next->fCoincident) != this); |
324 return false; | 260 return false; |
325 } | 261 } |
(...skipping 12 matching lines...) Expand all Loading... |
338 } | 274 } |
339 | 275 |
340 void SkOpSpan::init(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoin
t& pt) { | 276 void SkOpSpan::init(SkOpSegment* segment, SkOpSpan* prev, double t, const SkPoin
t& pt) { |
341 SkASSERT(t != 1); | 277 SkASSERT(t != 1); |
342 initBase(segment, prev, t, pt); | 278 initBase(segment, prev, t, pt); |
343 fCoincident = this; | 279 fCoincident = this; |
344 fToAngle = NULL; | 280 fToAngle = NULL; |
345 fWindSum = fOppSum = SK_MinS32; | 281 fWindSum = fOppSum = SK_MinS32; |
346 fWindValue = 1; | 282 fWindValue = 1; |
347 fOppValue = 0; | 283 fOppValue = 0; |
| 284 fTopTTry = 0; |
348 fChased = fDone = false; | 285 fChased = fDone = false; |
349 segment->bumpCount(); | 286 segment->bumpCount(); |
350 } | 287 } |
351 | 288 |
352 void SkOpSpan::setOppSum(int oppSum) { | 289 void SkOpSpan::setOppSum(int oppSum) { |
353 SkASSERT(!final()); | 290 SkASSERT(!final()); |
354 if (fOppSum != SK_MinS32 && fOppSum != oppSum) { | 291 if (fOppSum != SK_MinS32 && fOppSum != oppSum) { |
355 this->globalState()->setWindingFailed(); | 292 this->globalState()->setWindingFailed(); |
356 return; | 293 return; |
357 } | 294 } |
358 SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(oppSum) <= DEBUG_LIMIT_WIND_SUM); | 295 SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(oppSum) <= DEBUG_LIMIT_WIND_SUM); |
359 fOppSum = oppSum; | 296 fOppSum = oppSum; |
360 } | 297 } |
| 298 |
| 299 void SkOpSpan::setWindSum(int windSum) { |
| 300 SkASSERT(!final()); |
| 301 if (fWindSum != SK_MinS32 && fWindSum != windSum) { |
| 302 this->globalState()->setWindingFailed(); |
| 303 return; |
| 304 } |
| 305 SkASSERT(!DEBUG_LIMIT_WIND_SUM || abs(windSum) <= DEBUG_LIMIT_WIND_SUM); |
| 306 fWindSum = windSum; |
| 307 } |
OLD | NEW |