| 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 |