OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 | 222 |
223 const SkOpPtT* SkOpSegment::existing(double t, const SkOpSegment* opp) const { | 223 const SkOpPtT* SkOpSegment::existing(double t, const SkOpSegment* opp) const { |
224 const SkOpSpanBase* test = &fHead; | 224 const SkOpSpanBase* test = &fHead; |
225 const SkOpPtT* testPtT; | 225 const SkOpPtT* testPtT; |
226 SkPoint pt = this->ptAtT(t); | 226 SkPoint pt = this->ptAtT(t); |
227 do { | 227 do { |
228 testPtT = test->ptT(); | 228 testPtT = test->ptT(); |
229 if (testPtT->fT == t) { | 229 if (testPtT->fT == t) { |
230 break; | 230 break; |
231 } | 231 } |
232 if (!this->match(testPtT, this, t, pt, opp ? kAllowAliasMatch : kNoAlias
Match)) { | 232 if (!this->match(testPtT, this, t, pt)) { |
233 if (t < testPtT->fT) { | 233 if (t < testPtT->fT) { |
234 return nullptr; | 234 return nullptr; |
235 } | 235 } |
236 continue; | 236 continue; |
237 } | 237 } |
238 if (!opp) { | 238 if (!opp) { |
239 return testPtT; | 239 return testPtT; |
240 } | 240 } |
241 const SkOpPtT* loop = testPtT->next(); | 241 const SkOpPtT* loop = testPtT->next(); |
242 while (loop != testPtT) { | 242 while (loop != testPtT) { |
243 if (loop->segment() == this && loop->fT == t && loop->fPt == pt) { | 243 if (loop->segment() == this && loop->fT == t && loop->fPt == pt) { |
244 goto foundMatch; | 244 goto foundMatch; |
245 } | 245 } |
246 loop = loop->next(); | 246 loop = loop->next(); |
247 } | 247 } |
248 return nullptr; | 248 return nullptr; |
249 } while ((test = test->upCast()->next())); | 249 } while ((test = test->upCast()->next())); |
250 foundMatch: | 250 foundMatch: |
251 return opp && !test->contains(opp) ? nullptr : testPtT; | 251 return opp && !test->contains(opp) ? nullptr : testPtT; |
252 } | 252 } |
253 | 253 |
254 // break the span so that the coincident part does not change the angle of the r
emainder | 254 // break the span so that the coincident part does not change the angle of the r
emainder |
255 bool SkOpSegment::addExpanded(double newT, const SkOpSpanBase* test, bool* start
Over) { | 255 bool SkOpSegment::addExpanded(double newT, const SkOpSpanBase* test, bool* start
Over) { |
256 if (this->contains(newT)) { | 256 if (this->contains(newT)) { |
257 return true; | 257 return true; |
258 } | 258 } |
259 SkOpPtT* newPtT = this->addT(newT, kAllowAliasMatch, startOver); | 259 SkOpPtT* newPtT = this->addT(newT, startOver); |
260 if (!newPtT) { | 260 if (!newPtT) { |
261 return false; | 261 return false; |
262 } | 262 } |
263 newPtT->fPt = this->ptAtT(newT); | 263 newPtT->fPt = this->ptAtT(newT); |
264 // const cast away to change linked list; pt/t values stays unchanged | 264 // const cast away to change linked list; pt/t values stays unchanged |
265 SkOpSpanBase* writableTest = const_cast<SkOpSpanBase*>(test); | 265 SkOpSpanBase* writableTest = const_cast<SkOpSpanBase*>(test); |
266 if (writableTest->ptT()->addOpp(newPtT)) { | 266 if (writableTest->ptT()->addOpp(newPtT)) { |
267 writableTest->checkForCollapsedCoincidence(); | 267 writableTest->checkForCollapsedCoincidence(); |
268 } | 268 } |
269 return true; | 269 return true; |
270 } | 270 } |
271 | 271 |
272 // Please keep this in sync with debugAddT() | 272 // Please keep this in sync with debugAddT() |
273 SkOpPtT* SkOpSegment::addT(double t, AliasMatch allowAlias, bool* allocated) { | 273 SkOpPtT* SkOpSegment::addT(double t, bool* allocated) { |
274 debugValidate(); | 274 debugValidate(); |
275 SkPoint pt = this->ptAtT(t); | 275 SkPoint pt = this->ptAtT(t); |
276 SkOpSpanBase* span = &fHead; | 276 SkOpSpanBase* span = &fHead; |
277 do { | 277 do { |
278 SkOpPtT* result = span->ptT(); | 278 SkOpPtT* result = span->ptT(); |
279 SkOpPtT* loop; | 279 SkOpPtT* loop; |
280 bool duplicatePt; | 280 bool duplicatePt; |
281 if (t == result->fT) { | 281 if (t == result->fT) { |
282 goto bumpSpan; | 282 goto bumpSpan; |
283 } | 283 } |
284 if (this->match(result, this, t, pt, allowAlias)) { | 284 if (this->match(result, this, t, pt)) { |
285 // see if any existing alias matches segment, pt, and t | 285 // see if any existing alias matches segment, pt, and t |
286 loop = result->next(); | 286 loop = result->next(); |
287 duplicatePt = false; | 287 duplicatePt = false; |
288 while (loop != result) { | 288 while (loop != result) { |
289 bool ptMatch = loop->fPt == pt; | 289 bool ptMatch = loop->fPt == pt; |
290 if (loop->segment() == this && loop->fT == t && ptMatch) { | 290 if (loop->segment() == this && loop->fT == t && ptMatch) { |
291 goto bumpSpan; | 291 goto bumpSpan; |
292 } | 292 } |
293 duplicatePt |= ptMatch; | 293 duplicatePt |= ptMatch; |
294 loop = loop->next(); | 294 loop = loop->next(); |
295 } | 295 } |
296 if (kNoAliasMatch == allowAlias) { | |
297 bumpSpan: | 296 bumpSpan: |
298 span->bumpSpanAdds(); | |
299 return result; | |
300 } | |
301 SkOpPtT* alias = SkOpTAllocator<SkOpPtT>::Allocate(this->globalState
()->allocator()); | |
302 alias->init(result->span(), t, pt, duplicatePt); | |
303 result->insert(alias); | |
304 result->span()->unaligned(); | |
305 this->debugValidate(); | |
306 #if DEBUG_ADD_T | |
307 SkDebugf("%s alias t=%1.9g segID=%d spanID=%d\n", __FUNCTION__, t, | |
308 alias->segment()->debugID(), alias->span()->debugID()); | |
309 #endif | |
310 span->bumpSpanAdds(); | 297 span->bumpSpanAdds(); |
311 if (allocated) { | 298 return result; |
312 *allocated = true; | |
313 } | |
314 return alias; | |
315 } | 299 } |
316 if (t < result->fT) { | 300 if (t < result->fT) { |
317 SkOpSpan* prev = result->span()->prev(); | 301 SkOpSpan* prev = result->span()->prev(); |
318 if (!prev) { | 302 if (!prev) { |
319 return nullptr; | 303 return nullptr; |
320 } | 304 } |
321 SkOpSpan* span = insert(prev); | 305 SkOpSpan* span = insert(prev); |
322 span->init(this, prev, t, pt); | 306 span->init(this, prev, t, pt); |
323 this->debugValidate(); | 307 this->debugValidate(); |
324 #if DEBUG_ADD_T | 308 #if DEBUG_ADD_T |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 #if DEBUG_MARK_DONE | 1028 #if DEBUG_MARK_DONE |
1045 debugShowNewWinding(__FUNCTION__, span, winding, oppWinding); | 1029 debugShowNewWinding(__FUNCTION__, span, winding, oppWinding); |
1046 #endif | 1030 #endif |
1047 span->setWindSum(winding); | 1031 span->setWindSum(winding); |
1048 span->setOppSum(oppWinding); | 1032 span->setOppSum(oppWinding); |
1049 debugValidate(); | 1033 debugValidate(); |
1050 return true; | 1034 return true; |
1051 } | 1035 } |
1052 | 1036 |
1053 bool SkOpSegment::match(const SkOpPtT* base, const SkOpSegment* testParent, doub
le testT, | 1037 bool SkOpSegment::match(const SkOpPtT* base, const SkOpSegment* testParent, doub
le testT, |
1054 const SkPoint& testPt, AliasMatch aliasMatch) const { | 1038 const SkPoint& testPt) const { |
1055 SkASSERT(this == base->segment()); | 1039 SkASSERT(this == base->segment()); |
1056 if (this == testParent) { | 1040 if (this == testParent) { |
1057 if (precisely_equal(base->fT, testT)) { | 1041 if (precisely_equal(base->fT, testT)) { |
1058 return true; | 1042 return true; |
1059 } | 1043 } |
1060 } | 1044 } |
1061 if (!SkDPoint::ApproximatelyEqual(testPt, base->fPt)) { | 1045 if (!SkDPoint::ApproximatelyEqual(testPt, base->fPt)) { |
1062 return false; | 1046 return false; |
1063 } | 1047 } |
1064 return this != testParent || !this->ptsDisjoint(base->fT, base->fPt, testT,
testPt); | 1048 return this != testParent || !this->ptsDisjoint(base->fT, base->fPt, testT,
testPt); |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 distSqBest = distSq; | 1398 distSqBest = distSq; |
1415 refBest = ref; | 1399 refBest = ref; |
1416 checkBest = check; | 1400 checkBest = check; |
1417 } | 1401 } |
1418 } while ((check = check->next()) != checkHead); | 1402 } while ((check = check->next()) != checkHead); |
1419 nextRef: | 1403 nextRef: |
1420 ; | 1404 ; |
1421 } while ((ref = ref->next()) != refHead); | 1405 } while ((ref = ref->next()) != refHead); |
1422 doneCheckingDistance: | 1406 doneCheckingDistance: |
1423 return checkBest && refBest->segment()->match(refBest, checkBest->segment(),
checkBest->fT, | 1407 return checkBest && refBest->segment()->match(refBest, checkBest->segment(),
checkBest->fT, |
1424 checkBest->fPt, kAllowAliasMatch); | 1408 checkBest->fPt); |
1425 } | 1409 } |
1426 | 1410 |
1427 // Please keep this function in sync with debugMoveNearby() | 1411 // Please keep this function in sync with debugMoveNearby() |
1428 // Move nearby t values and pts so they all hang off the same span. Alignment ha
ppens later. | 1412 // Move nearby t values and pts so they all hang off the same span. Alignment ha
ppens later. |
1429 void SkOpSegment::moveNearby() { | 1413 void SkOpSegment::moveNearby() { |
1430 debugValidate(); | 1414 debugValidate(); |
1431 // release undeleted spans pointing to this seg that are linked to the prima
ry span | 1415 // release undeleted spans pointing to this seg that are linked to the prima
ry span |
1432 SkOpSpanBase* spanBase = &fHead; | 1416 SkOpSpanBase* spanBase = &fHead; |
1433 do { | 1417 do { |
1434 SkOpPtT* ptT = spanBase->ptT(); | 1418 SkOpPtT* ptT = spanBase->ptT(); |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 int absOut = SkTAbs(outerWinding); | 1790 int absOut = SkTAbs(outerWinding); |
1807 int absIn = SkTAbs(innerWinding); | 1791 int absIn = SkTAbs(innerWinding); |
1808 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn; | 1792 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn; |
1809 return result; | 1793 return result; |
1810 } | 1794 } |
1811 | 1795 |
1812 int SkOpSegment::windSum(const SkOpAngle* angle) const { | 1796 int SkOpSegment::windSum(const SkOpAngle* angle) const { |
1813 const SkOpSpan* minSpan = angle->start()->starter(angle->end()); | 1797 const SkOpSpan* minSpan = angle->start()->starter(angle->end()); |
1814 return minSpan->windSum(); | 1798 return minSpan->windSum(); |
1815 } | 1799 } |
OLD | NEW |