OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 | 7 |
8 #include "SkMutex.h" | 8 #include "SkMutex.h" |
9 #include "SkOpCoincidence.h" | 9 #include "SkOpCoincidence.h" |
10 #include "SkOpContour.h" | 10 #include "SkOpContour.h" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 } | 56 } |
57 return false; | 57 return false; |
58 } | 58 } |
59 #endif | 59 #endif |
60 | 60 |
61 #if DEBUG_COINCIDENCE_VERBOSE | 61 #if DEBUG_COINCIDENCE_VERBOSE |
62 enum GlitchType { | 62 enum GlitchType { |
63 kAddCorruptCoin_Glitch, | 63 kAddCorruptCoin_Glitch, |
64 kAddExpandedCoin_Glitch, | 64 kAddExpandedCoin_Glitch, |
65 kAddExpandedFail_Glitch, | 65 kAddExpandedFail_Glitch, |
| 66 kAddIfCollapsed_Glitch, |
66 kAddIfMissingCoin_Glitch, | 67 kAddIfMissingCoin_Glitch, |
67 kAddMissingCoin_Glitch, | 68 kAddMissingCoin_Glitch, |
68 kAddMissingExtend_Glitch, | 69 kAddMissingExtend_Glitch, |
69 kAddOrOverlap_Glitch, | 70 kAddOrOverlap_Glitch, |
70 kCollapsedCoin_Glitch, | 71 kCollapsedCoin_Glitch, |
71 kCollapsedDone_Glitch, | 72 kCollapsedDone_Glitch, |
72 kCollapsedOppValue_Glitch, | 73 kCollapsedOppValue_Glitch, |
73 kCollapsedSpan_Glitch, | 74 kCollapsedSpan_Glitch, |
74 kCollapsedWindValue_Glitch, | 75 kCollapsedWindValue_Glitch, |
75 kDeletedCoin_Glitch, | 76 kDeletedCoin_Glitch, |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 mask |= 1 << glitch.fType; | 280 mask |= 1 << glitch.fType; |
280 } | 281 } |
281 for (int index = 0; index < kGlitchType_Count; ++index) { | 282 for (int index = 0; index < kGlitchType_Count; ++index) { |
282 SkDebugf(mask & (1 << index) ? "x" : "-"); | 283 SkDebugf(mask & (1 << index) ? "x" : "-"); |
283 } | 284 } |
284 SkDebugf(" %s\n", id); | 285 SkDebugf(" %s\n", id); |
285 for (int index = 0; index < glitches.fGlitches.count(); ++index) { | 286 for (int index = 0; index < glitches.fGlitches.count(); ++index) { |
286 const SpanGlitch& glitch = glitches.fGlitches[index]; | 287 const SpanGlitch& glitch = glitches.fGlitches[index]; |
287 SkDebugf("%02d: ", index); | 288 SkDebugf("%02d: ", index); |
288 if (glitch.fBase) { | 289 if (glitch.fBase) { |
289 SkDebugf(" base=%d", glitch.fBase->debugID()); | 290 SkDebugf(" seg/base=%d/%d", glitch.fBase->segment()->debugID(), |
| 291 glitch.fBase->debugID()); |
290 } | 292 } |
291 if (glitch.fSuspect) { | 293 if (glitch.fSuspect) { |
292 SkDebugf(" base=%d", glitch.fSuspect->debugID()); | 294 SkDebugf(" seg/base=%d/%d", glitch.fSuspect->segment()->debugID(), |
| 295 glitch.fSuspect->debugID()); |
293 } | 296 } |
294 if (glitch.fSegment) { | 297 if (glitch.fSegment) { |
295 SkDebugf(" segment=%d", glitch.fSegment->debugID()); | 298 SkDebugf(" segment=%d", glitch.fSegment->debugID()); |
296 } | 299 } |
297 if (glitch.fCoinSpan) { | 300 if (glitch.fCoinSpan) { |
298 SkDebugf(" coinSpan=%d", glitch.fCoinSpan->debugID()); | 301 SkDebugf(" coinSeg/Span/PtT=%d/%d/%d", glitch.fCoinSpan->segment()->
debugID(), |
| 302 glitch.fCoinSpan->span()->debugID(), glitch.fCoinSpan->debug
ID()); |
299 } | 303 } |
300 if (glitch.fEndSpan) { | 304 if (glitch.fEndSpan) { |
301 SkDebugf(" endSpan=%d", glitch.fEndSpan->debugID()); | 305 SkDebugf(" endSpan=%d", glitch.fEndSpan->debugID()); |
302 } | 306 } |
303 if (glitch.fOppSpan) { | 307 if (glitch.fOppSpan) { |
304 SkDebugf(" oppSpan=%d", glitch.fOppSpan->debugID()); | 308 SkDebugf(" oppSeg/Span/PtT=%d/%d/%d", glitch.fOppSpan->segment()->de
bugID(), |
| 309 glitch.fOppSpan->span()->debugID(), glitch.fOppSpan->debugID
()); |
305 } | 310 } |
306 if (glitch.fOppEndSpan) { | 311 if (glitch.fOppEndSpan) { |
307 SkDebugf(" oppEndSpan=%d", glitch.fOppEndSpan->debugID()); | 312 SkDebugf(" oppEndSpan=%d", glitch.fOppEndSpan->debugID()); |
308 } | 313 } |
309 if (!SkScalarIsNaN(glitch.fStartT)) { | 314 if (!SkScalarIsNaN(glitch.fStartT)) { |
310 SkDebugf(" startT=%g", glitch.fStartT); | 315 SkDebugf(" startT=%g", glitch.fStartT); |
311 } | 316 } |
312 if (!SkScalarIsNaN(glitch.fEndT)) { | 317 if (!SkScalarIsNaN(glitch.fEndT)) { |
313 SkDebugf(" endT=%g", glitch.fEndT); | 318 SkDebugf(" endT=%g", glitch.fEndT); |
314 } | 319 } |
315 if (glitch.fOppSegment) { | 320 if (glitch.fOppSegment) { |
316 SkDebugf(" segment=%d", glitch.fOppSegment->debugID()); | 321 SkDebugf(" segment=%d", glitch.fOppSegment->debugID()); |
317 } | 322 } |
318 if (!SkScalarIsNaN(glitch.fOppStartT)) { | 323 if (!SkScalarIsNaN(glitch.fOppStartT)) { |
319 SkDebugf(" oppStartT=%g", glitch.fOppStartT); | 324 SkDebugf(" oppStartT=%g", glitch.fOppStartT); |
320 } | 325 } |
321 if (!SkScalarIsNaN(glitch.fOppEndT)) { | 326 if (!SkScalarIsNaN(glitch.fOppEndT)) { |
322 SkDebugf(" oppEndT=%g", glitch.fOppEndT); | 327 SkDebugf(" oppEndT=%g", glitch.fOppEndT); |
323 } | 328 } |
324 if (!SkScalarIsNaN(glitch.fPt.fX) || !SkScalarIsNaN(glitch.fPt.fY)) { | 329 if (!SkScalarIsNaN(glitch.fPt.fX) || !SkScalarIsNaN(glitch.fPt.fY)) { |
325 SkDebugf(" pt=%g,%g", glitch.fPt.fX, glitch.fPt.fY); | 330 SkDebugf(" pt=%g,%g", glitch.fPt.fX, glitch.fPt.fY); |
326 } | 331 } |
327 switch (glitch.fType) { | 332 switch (glitch.fType) { |
328 case kAddCorruptCoin_Glitch: SkDebugf(" AddCorruptCoin"); break; | 333 case kAddCorruptCoin_Glitch: SkDebugf(" AddCorruptCoin"); break; |
329 case kAddExpandedCoin_Glitch: SkDebugf(" AddExpandedCoin"); break; | 334 case kAddExpandedCoin_Glitch: SkDebugf(" AddExpandedCoin"); break; |
330 case kAddExpandedFail_Glitch: SkDebugf(" AddExpandedFail"); break; | 335 case kAddExpandedFail_Glitch: SkDebugf(" AddExpandedFail"); break; |
| 336 case kAddIfCollapsed_Glitch: SkDebugf(" AddIfCollapsed"); break;; br
eak; |
331 case kAddIfMissingCoin_Glitch: SkDebugf(" AddIfMissingCoin"); break; | 337 case kAddIfMissingCoin_Glitch: SkDebugf(" AddIfMissingCoin"); break; |
332 case kAddMissingCoin_Glitch: SkDebugf(" AddMissingCoin"); break; | 338 case kAddMissingCoin_Glitch: SkDebugf(" AddMissingCoin"); break; |
333 case kAddMissingExtend_Glitch: SkDebugf(" AddMissingExtend"); break; | 339 case kAddMissingExtend_Glitch: SkDebugf(" AddMissingExtend"); break; |
334 case kAddOrOverlap_Glitch: SkDebugf(" AAddOrOverlap"); break; | 340 case kAddOrOverlap_Glitch: SkDebugf(" AAddOrOverlap"); break; |
335 case kCollapsedCoin_Glitch: SkDebugf(" CollapsedCoin"); break; | 341 case kCollapsedCoin_Glitch: SkDebugf(" CollapsedCoin"); break; |
336 case kCollapsedDone_Glitch: SkDebugf(" CollapsedDone"); break; | 342 case kCollapsedDone_Glitch: SkDebugf(" CollapsedDone"); break; |
337 case kCollapsedOppValue_Glitch: SkDebugf(" CollapsedOppValue"); brea
k; | 343 case kCollapsedOppValue_Glitch: SkDebugf(" CollapsedOppValue"); brea
k; |
338 case kCollapsedSpan_Glitch: SkDebugf(" CollapsedSpan"); break; | 344 case kCollapsedSpan_Glitch: SkDebugf(" CollapsedSpan"); break; |
339 case kCollapsedWindValue_Glitch: SkDebugf(" CollapsedWindValue"); br
eak; | 345 case kCollapsedWindValue_Glitch: SkDebugf(" CollapsedWindValue"); br
eak; |
340 case kDeletedCoin_Glitch: SkDebugf(" DeletedCoin"); break; | 346 case kDeletedCoin_Glitch: SkDebugf(" DeletedCoin"); break; |
(...skipping 16 matching lines...) Expand all Loading... |
357 case kMoveNearbyReleaseFinal_Glitch: SkDebugf(" MoveNearbyReleaseFin
al"); break; | 363 case kMoveNearbyReleaseFinal_Glitch: SkDebugf(" MoveNearbyReleaseFin
al"); break; |
358 case kReleasedSpan_Glitch: SkDebugf(" ReleasedSpan"); break; | 364 case kReleasedSpan_Glitch: SkDebugf(" ReleasedSpan"); break; |
359 case kUnaligned_Glitch: SkDebugf(" Unaligned"); break; | 365 case kUnaligned_Glitch: SkDebugf(" Unaligned"); break; |
360 case kUnalignedHead_Glitch: SkDebugf(" UnalignedHead"); break; | 366 case kUnalignedHead_Glitch: SkDebugf(" UnalignedHead"); break; |
361 case kUnalignedTail_Glitch: SkDebugf(" UnalignedTail"); break; | 367 case kUnalignedTail_Glitch: SkDebugf(" UnalignedTail"); break; |
362 default: SkASSERT(0); | 368 default: SkASSERT(0); |
363 } | 369 } |
364 SkDebugf("\n"); | 370 SkDebugf("\n"); |
365 } | 371 } |
366 contourList->globalState()->debugSetCheckHealth(false); | 372 contourList->globalState()->debugSetCheckHealth(false); |
367 #if DEBUG_ACTIVE_SPANS | 373 #if 0 && DEBUG_ACTIVE_SPANS |
368 SkDebugf("active after %s:\n", id); | 374 SkDebugf("active after %s:\n", id); |
369 ShowActiveSpans(contourList); | 375 ShowActiveSpans(contourList); |
370 #endif | 376 #endif |
371 #endif | 377 #endif |
372 } | 378 } |
373 #endif | 379 #endif |
374 | 380 |
375 #if defined SK_DEBUG || !FORCE_RELEASE | 381 #if defined SK_DEBUG || !FORCE_RELEASE |
376 void SkPathOpsDebug::MathematicaIze(char* str, size_t bufferLen) { | 382 void SkPathOpsDebug::MathematicaIze(char* str, size_t bufferLen) { |
377 size_t len = strlen(str); | 383 size_t len = strlen(str); |
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 if (!oTest) { | 1369 if (!oTest) { |
1364 return; | 1370 return; |
1365 } | 1371 } |
1366 } | 1372 } |
1367 } | 1373 } |
1368 } while ((coin = coin->next())); | 1374 } while ((coin = coin->next())); |
1369 return; | 1375 return; |
1370 } | 1376 } |
1371 | 1377 |
1372 /* Commented-out lines keep this in sync with addIfMissing() */ | 1378 /* Commented-out lines keep this in sync with addIfMissing() */ |
1373 void SkOpCoincidence::debugAddIfMissing(const SkCoincidentSpans* outer, const Sk
OpPtT* over1s, | 1379 void SkOpCoincidence::debugAddIfMissing(const char* id, SkPathOpsDebug::GlitchLo
g* log, const SkCoincidentSpans* outer, const SkOpPtT* over1s, |
1374 const SkOpPtT* over1e, const char* id, SkPathOpsDebug::GlitchLog* lo
g) const { | 1380 const SkOpPtT* over1e) const { |
1375 // SkASSERT(fTop); | 1381 // SkASSERT(fTop); |
1376 if (fTop && alreadyAdded(fTop, outer, over1s, over1e)) { // in debug, fTop
may be null | 1382 if (fTop && alreadyAdded(fTop, outer, over1s, over1e)) { // in debug, fTop
may be null |
1377 return; | 1383 return; |
1378 } | 1384 } |
1379 if (fHead && alreadyAdded(fHead, outer, over1s, over1e)) { | 1385 if (fHead && alreadyAdded(fHead, outer, over1s, over1e)) { |
1380 return; | 1386 return; |
1381 } | 1387 } |
1382 log->record(kAddIfMissingCoin_Glitch, id, outer->coinPtTStart(), outer->coin
PtTEnd(), over1s, over1e); | 1388 log->record(kAddIfMissingCoin_Glitch, id, outer->coinPtTStart(), outer->coin
PtTEnd(), over1s, over1e); |
1383 this->debugValidate(); | 1389 this->debugValidate(); |
1384 return; | 1390 return; |
1385 } | 1391 } |
1386 | 1392 |
1387 /* Commented-out lines keep this in sync addIfMissing() */ | 1393 /* Commented-out lines keep this in sync addIfMissing() */ |
1388 void SkOpCoincidence::debugAddIfMissing(const SkOpPtT* over1s, const SkOpPtT* ov
er1e, | 1394 // note that over1s, over1e, over2s, over2e are ordered |
1389 const SkOpPtT* over2s, const SkOpPtT* over2e, double tStart, double tEnd
, | 1395 void SkOpCoincidence::debugAddIfMissing(const char* id, SkPathOpsDebug::GlitchLo
g* log, const SkOpPtT* over1s, const SkOpPtT* over2s, |
1390 const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, | 1396 double tStart, double tEnd, const SkOpSegment* coinSeg, const SkOpSegmen
t* oppSeg, |
1391 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, const char* id, Sk
PathOpsDebug::GlitchLog* log) const { | 1397 const SkOpPtT* over1e, const SkOpPtT* over2e) const { |
| 1398 SkASSERT(tStart < tEnd); |
| 1399 SkASSERT(over1s->fT < over1e->fT); |
| 1400 SkASSERT(between(over1s->fT, tStart, over1e->fT)); |
| 1401 SkASSERT(between(over1s->fT, tEnd, over1e->fT)); |
| 1402 SkASSERT(over2s->fT < over2e->fT); |
| 1403 SkASSERT(between(over2s->fT, tStart, over2e->fT)); |
| 1404 SkASSERT(between(over2s->fT, tEnd, over2e->fT)); |
| 1405 SkASSERT(over1s->segment() == over1e->segment()); |
| 1406 SkASSERT(over2s->segment() == over2e->segment()); |
| 1407 SkASSERT(over1s->segment() == over2s->segment()); |
| 1408 SkASSERT(over1s->segment() != coinSeg); |
| 1409 SkASSERT(over1s->segment() != oppSeg); |
| 1410 SkASSERT(coinSeg != oppSeg); |
1392 double coinTs, coinTe, oppTs, oppTe; | 1411 double coinTs, coinTe, oppTs, oppTe; |
1393 TRange(over1s, over1e, tStart, tEnd, coinPtTStart, coinPtTEnd, &coinTs, &coi
nTe); | 1412 coinTs = TRange(over1s, tStart, coinSeg SkDEBUGPARAMS(over1e)); |
1394 TRange(over2s, over2e, tStart, tEnd, oppPtTStart, oppPtTEnd, &oppTs, &oppTe)
; | 1413 coinTe = TRange(over1s, tEnd, coinSeg SkDEBUGPARAMS(over1e)); |
1395 bool swap = coinTs > coinTe; | 1414 if (coinSeg->collapsed(coinTs, coinTe)) { |
1396 if (swap) { | 1415 return log->record(kAddIfCollapsed_Glitch, id, coinSeg); |
| 1416 } |
| 1417 oppTs = TRange(over2s, tStart, oppSeg SkDEBUGPARAMS(over2e)); |
| 1418 oppTe = TRange(over2s, tEnd, oppSeg SkDEBUGPARAMS(over2e)); |
| 1419 if (oppSeg->collapsed(oppTs, oppTe)) { |
| 1420 return log->record(kAddIfCollapsed_Glitch, id, oppSeg); |
| 1421 } |
| 1422 if (coinTs > coinTe) { |
1397 SkTSwap(coinTs, coinTe); | 1423 SkTSwap(coinTs, coinTe); |
1398 } | |
1399 if ((over1s->fT < over1e->fT) != (over2s->fT < over2e->fT)) { | |
1400 SkTSwap(oppTs, oppTe); | 1424 SkTSwap(oppTs, oppTe); |
1401 } | 1425 } |
1402 if (swap) { | 1426 return this->debugAddOrOverlap(id, log, coinSeg, oppSeg, coinTs, coinTe, opp
Ts, oppTe |
1403 SkTSwap(oppTs, oppTe); | 1427 ); |
1404 } | |
1405 const SkOpSegment* coinSeg = coinPtTStart->segment(); | |
1406 const SkOpSegment* oppSeg = oppPtTStart->segment(); | |
1407 if (coinSeg == oppSeg) { | |
1408 return; | |
1409 } | |
1410 return this->debugAddOrOverlap(id, log, coinSeg, oppSeg, coinTs, coinTe, opp
Ts, oppTe); | |
1411 } | 1428 } |
1412 | 1429 |
1413 /* Commented-out lines keep this in sync addOrOverlap() */ | 1430 /* Commented-out lines keep this in sync addOrOverlap() */ |
1414 // If this is called by addEndMovedSpans(), a returned false propogates out to a
n abort. | 1431 // If this is called by addEndMovedSpans(), a returned false propogates out to a
n abort. |
1415 // If this is called by AddIfMissing(), a returned false indicates there was not
hing to add | 1432 // If this is called by AddIfMissing(), a returned false indicates there was not
hing to add |
1416 void SkOpCoincidence::debugAddOrOverlap(const char* id, SkPathOpsDebug::GlitchLo
g* log, | 1433 void SkOpCoincidence::debugAddOrOverlap(const char* id, SkPathOpsDebug::GlitchLo
g* log, |
1417 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, | 1434 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg, |
1418 double coinTs, double coinTe, double oppTs, double oppTe) const { | 1435 double coinTs, double coinTe, double oppTs, double oppTe) const { |
1419 SkTDArray<SkCoincidentSpans*> overlaps; | 1436 SkTDArray<SkCoincidentSpans*> overlaps; |
1420 SkASSERT(!fTop); // this is (correctly) reversed in addifMissing() | 1437 SkASSERT(!fTop); // this is (correctly) reversed in addifMissing() |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1493 oe = oppSeg->debugAddT(oppTe, id, log); | 1510 oe = oppSeg->debugAddT(oppTe, id, log); |
1494 if (ce && oe) ce->span()->debugAddOpp(id, log, oe->span()); | 1511 if (ce && oe) ce->span()->debugAddOpp(id, log, oe->span()); |
1495 // ce = ceWritable; | 1512 // ce = ceWritable; |
1496 // oe = oeWritable; | 1513 // oe = oeWritable; |
1497 } | 1514 } |
1498 this->debugValidate(); | 1515 this->debugValidate(); |
1499 RETURN_FALSE_IF(csDeleted, coinSeg); | 1516 RETURN_FALSE_IF(csDeleted, coinSeg); |
1500 RETURN_FALSE_IF(osDeleted, oppSeg); | 1517 RETURN_FALSE_IF(osDeleted, oppSeg); |
1501 RETURN_FALSE_IF(ceDeleted, coinSeg); | 1518 RETURN_FALSE_IF(ceDeleted, coinSeg); |
1502 RETURN_FALSE_IF(oeDeleted, oppSeg); | 1519 RETURN_FALSE_IF(oeDeleted, oppSeg); |
1503 RETURN_FALSE_IF(!cs || !ce || cs->contains(ce) || !os || !oe || os->contains
(oe), coinSeg); | 1520 RETURN_FALSE_IF(!cs || !ce || cs == ce || cs->contains(ce) || !os || !oe ||
os == oe || os->contains(oe), coinSeg); |
1504 // bool result = true; | 1521 bool result = true; |
1505 if (overlap) { | 1522 if (overlap) { |
1506 if (overlap->coinPtTStart()->segment() == coinSeg) { | 1523 if (overlap->coinPtTStart()->segment() == coinSeg) { |
1507 log->record(kAddMissingExtend_Glitch, id, coinSeg, coinTs, coinT
e, oppSeg, oppTs, oppTe); | 1524 log->record(kAddMissingExtend_Glitch, id, coinSeg, coinTs, coinT
e, oppSeg, oppTs, oppTe); |
1508 } else { | 1525 } else { |
1509 if (oppTs > oppTe) { | 1526 if (oppTs > oppTe) { |
1510 SkTSwap(coinTs, coinTe); | 1527 SkTSwap(coinTs, coinTe); |
1511 SkTSwap(oppTs, oppTe); | 1528 SkTSwap(oppTs, oppTe); |
1512 } | 1529 } |
1513 log->record(kAddMissingExtend_Glitch, id, oppSeg, oppTs, oppTe, coin
Seg, coinTs, coinTe); | 1530 log->record(kAddMissingExtend_Glitch, id, oppSeg, oppTs, oppTe, coin
Seg, coinTs, coinTe); |
1514 } | 1531 } |
1515 #if DEBUG_COINCIDENCE_VERBOSE | 1532 #if 0 && DEBUG_COINCIDENCE_VERBOSE |
1516 // if (result) { | 1533 if (result) { |
1517 // overlap->debugShow(); | 1534 overlap->debugShow(); |
1518 // } | 1535 } |
1519 #endif | 1536 #endif |
1520 } else { | 1537 } else { |
1521 log->record(kAddMissingCoin_Glitch, id, coinSeg, coinTs, coinTe, oppSeg,
oppTs, oppTe); | 1538 log->record(kAddMissingCoin_Glitch, id, coinSeg, coinTs, coinTe, oppSeg,
oppTs, oppTe); |
1522 #if DEBUG_COINCIDENCE_VERBOSE | 1539 #if 0 && DEBUG_COINCIDENCE_VERBOSE |
1523 // fHead->debugShow(); | 1540 fHead->debugShow(); |
1524 #endif | 1541 #endif |
1525 } | 1542 } |
1526 this->debugValidate(); | 1543 this->debugValidate(); |
1527 return; | 1544 return (void) result; |
1528 } | 1545 } |
1529 | 1546 |
1530 // Extra commented-out lines keep this in sync with addMissing() | 1547 // Extra commented-out lines keep this in sync with addMissing() |
1531 /* detects overlaps of different coincident runs on same segment */ | 1548 /* detects overlaps of different coincident runs on same segment */ |
1532 /* does not detect overlaps for pairs without any segments in common */ | 1549 /* does not detect overlaps for pairs without any segments in common */ |
1533 // returns true if caller should loop again | 1550 // returns true if caller should loop again |
1534 void SkOpCoincidence::debugAddMissing(const char* id, SkPathOpsDebug::GlitchLog*
log) const { | 1551 void SkOpCoincidence::debugAddMissing(const char* id, SkPathOpsDebug::GlitchLog*
log) const { |
1535 const SkCoincidentSpans* outer = fHead; | 1552 const SkCoincidentSpans* outer = fHead; |
1536 if (!outer) { | 1553 if (!outer) { |
1537 return; | 1554 return; |
1538 } | 1555 } |
1539 // bool added = false; | 1556 // bool added = false; |
1540 // fTop = outer; | 1557 // fTop = outer; |
1541 // fHead = nullptr; | 1558 // fHead = nullptr; |
1542 do { | 1559 do { |
1543 // addifmissing can modify the list that this is walking | 1560 // addifmissing can modify the list that this is walking |
1544 // save head so that walker can iterate over old data unperturbed | 1561 // save head so that walker can iterate over old data unperturbed |
1545 // addifmissing adds to head freely then add saved head in the end | 1562 // addifmissing adds to head freely then add saved head in the end |
1546 const SkOpSegment* outerCoin = outer->coinPtTStart()->segment(); | 1563 const SkOpPtT* ocs = outer->coinPtTStart(); |
1547 const SkOpSegment* outerOpp = outer->oppPtTStart()->segment(); | 1564 SkASSERT(!ocs->deleted()); |
1548 if (outerCoin->done() || outerOpp->done()) { | 1565 const SkOpSegment* outerCoin = ocs->segment(); |
1549 continue; | 1566 SkASSERT(!outerCoin->done()); // if it's done, should have already been
removed from list |
1550 } | 1567 const SkOpPtT* oos = outer->oppPtTStart(); |
| 1568 SkASSERT(!oos->deleted()); |
| 1569 const SkOpSegment* outerOpp = oos->segment(); |
| 1570 SkASSERT(!outerOpp->done()); |
| 1571 // SkOpSegment* outerCoinWritable = const_cast<SkOpSegment*>(outerCoin); |
| 1572 // SkOpSegment* outerOppWritable = const_cast<SkOpSegment*>(outerOpp); |
1551 const SkCoincidentSpans* inner = outer; | 1573 const SkCoincidentSpans* inner = outer; |
1552 while ((inner = inner->next())) { | 1574 while ((inner = inner->next())) { |
1553 this->debugValidate(); | 1575 this->debugValidate(); |
1554 double overS, overE; | 1576 double overS, overE; |
1555 const SkOpSegment* innerCoin = inner->coinPtTStart()->segment(); | 1577 const SkOpPtT* ics = inner->coinPtTStart(); |
1556 const SkOpSegment* innerOpp = inner->oppPtTStart()->segment(); | 1578 SkASSERT(!ics->deleted()); |
1557 if (innerCoin->done() || innerOpp->done()) { | 1579 const SkOpSegment* innerCoin = ics->segment(); |
1558 continue; | 1580 SkASSERT(!innerCoin->done()); |
1559 } | 1581 const SkOpPtT* ios = inner->oppPtTStart(); |
| 1582 SkASSERT(!ios->deleted()); |
| 1583 const SkOpSegment* innerOpp = ios->segment(); |
| 1584 SkASSERT(!innerOpp->done()); |
| 1585 // SkOpSegment* innerCoinWritable = const_cast<SkOpSegment*>(innerCoi
n); |
| 1586 // SkOpSegment* innerOppWritable = const_cast<SkOpSegment*>(innerOpp)
; |
1560 if (outerCoin == innerCoin) { | 1587 if (outerCoin == innerCoin) { |
1561 if (outerOpp != innerOpp | 1588 const SkOpPtT* oce = outer->coinPtTEnd(); |
1562 && this->overlap(outer->coinPtTStart(), outer->coinPtTEn
d(), | 1589 SkASSERT(!oce->deleted()); |
1563 inner->coinPtTStart(), inner->coinPtTEnd(), &overS, &ove
rE)) { | 1590 const SkOpPtT* ice = inner->coinPtTEnd(); |
1564 this->debugAddIfMissing(outer->coinPtTStart(), outer->coinPt
TEnd(), | 1591 SkASSERT(!ice->deleted()); |
1565 inner->coinPtTStart(), inner->coinPtTEnd(), overS, o
verE, | 1592 if (outerOpp != innerOpp && this->overlap(ocs, oce, ics, ice, &o
verS, &overE)) { |
1566 outer->oppPtTStart(), outer->oppPtTEnd(), | 1593 this->debugAddIfMissing(id, log, ocs->starter(oce), ics->sta
rter(ice), |
1567 inner->oppPtTStart(), inner->oppPtTEnd(), id, log); | 1594 overS, overE, outerOpp, innerOpp, |
| 1595 ocs->debugEnder(oce), |
| 1596 ics->debugEnder(ice)); |
1568 } | 1597 } |
1569 } else if (outerCoin == innerOpp) { | 1598 } else if (outerCoin == innerOpp) { |
1570 if (outerOpp != innerCoin | 1599 const SkOpPtT* oce = outer->coinPtTEnd(); |
1571 && this->overlap(outer->coinPtTStart(), outer->coinPtTEn
d(), | 1600 SkASSERT(!oce->deleted()); |
1572 inner->oppPtTStart(), inner->oppPtTEnd(), &overS, &overE
)) { | 1601 const SkOpPtT* ioe = inner->oppPtTEnd(); |
1573 this->debugAddIfMissing(outer->coinPtTStart(), outer->coinPt
TEnd(), | 1602 SkASSERT(!ioe->deleted()); |
1574 inner->oppPtTStart(), inner->oppPtTEnd(), overS, ove
rE, | 1603 if (outerOpp != innerCoin && this->overlap(ocs, oce, ios, ioe, &
overS, &overE)) { |
1575 outer->oppPtTStart(), outer->oppPtTEnd(), | 1604 this->debugAddIfMissing(id, log, ocs->starter(oce), ios->sta
rter(ioe), |
1576 inner->coinPtTStart(), inner->coinPtTEnd(), id, log)
; | 1605 overS, overE, outerOpp, innerCoin, |
| 1606 ocs->debugEnder(oce), |
| 1607 ios->debugEnder(ioe)); |
1577 } | 1608 } |
1578 } else if (outerOpp == innerCoin) { | 1609 } else if (outerOpp == innerCoin) { |
| 1610 const SkOpPtT* ooe = outer->oppPtTEnd(); |
| 1611 SkASSERT(!ooe->deleted()); |
| 1612 const SkOpPtT* ice = inner->coinPtTEnd(); |
| 1613 SkASSERT(!ice->deleted()); |
1579 SkASSERT(outerCoin != innerOpp); | 1614 SkASSERT(outerCoin != innerOpp); |
1580 if (this->overlap(outer->oppPtTStart(), outer->oppPtTEnd(), | 1615 if (this->overlap(oos, ooe, ics, ice, &overS, &overE)) { |
1581 inner->coinPtTStart(), inner->coinPtTEnd(), &overS, &ove
rE)) { | 1616 this->debugAddIfMissing(id, log, oos->starter(ooe), ics->sta
rter(ice), |
1582 this->debugAddIfMissing(outer->oppPtTStart(), outer->oppPtTE
nd(), | 1617 overS, overE, outerCoin, innerOpp, |
1583 inner->coinPtTStart(), inner->coinPtTEnd(), overS, o
verE, | 1618 oos->debugEnder(ooe), |
1584 outer->coinPtTStart(), outer->coinPtTEnd(), | 1619 ics->debugEnder(ice)); |
1585 inner->oppPtTStart(), inner->oppPtTEnd(), id, log); | |
1586 } | 1620 } |
1587 } else if (outerOpp == innerOpp) { | 1621 } else if (outerOpp == innerOpp) { |
| 1622 const SkOpPtT* ooe = outer->oppPtTEnd(); |
| 1623 SkASSERT(!ooe->deleted()); |
| 1624 const SkOpPtT* ioe = inner->oppPtTEnd(); |
| 1625 SkASSERT(!ioe->deleted()); |
1588 SkASSERT(outerCoin != innerCoin); | 1626 SkASSERT(outerCoin != innerCoin); |
1589 if (this->overlap(outer->oppPtTStart(), outer->oppPtTEnd(), | 1627 if (this->overlap(oos, ooe, ios, ioe, &overS, &overE)) { |
1590 inner->oppPtTStart(), inner->oppPtTEnd(), &overS, &overE
)) { | 1628 this->debugAddIfMissing(id, log, oos->starter(ooe), ios->sta
rter(ioe), |
1591 this->debugAddIfMissing(outer->oppPtTStart(), outer->oppPtTE
nd(), | 1629 overS, overE, outerCoin, innerCoin, |
1592 inner->oppPtTStart(), inner->oppPtTEnd(), overS, ove
rE, | 1630 oos->debugEnder(ooe), |
1593 outer->coinPtTStart(), outer->coinPtTEnd(), | 1631 ios->debugEnder(ioe)); |
1594 inner->coinPtTStart(), inner->coinPtTEnd(), id, log)
; | |
1595 } | 1632 } |
1596 } | 1633 } |
1597 this->debugValidate(); | 1634 this->debugValidate(); |
1598 } | 1635 } |
1599 } while ((outer = outer->next())); | 1636 } while ((outer = outer->next())); |
1600 // this->restoreHead(); | 1637 // this->restoreHead(); |
1601 return; | 1638 return; |
1602 } | 1639 } |
1603 | 1640 |
1604 // Commented-out lines keep this in sync with release() | 1641 // Commented-out lines keep this in sync with release() |
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2435 const SkOpPtT* test = this; | 2472 const SkOpPtT* test = this; |
2436 for (int index = 0; index < links; ++index) { | 2473 for (int index = 0; index < links; ++index) { |
2437 if (ptT == test) { | 2474 if (ptT == test) { |
2438 return nullptr; | 2475 return nullptr; |
2439 } | 2476 } |
2440 test = test->next(); | 2477 test = test->next(); |
2441 } | 2478 } |
2442 } while (true); | 2479 } while (true); |
2443 } | 2480 } |
2444 | 2481 |
| 2482 const SkOpPtT* SkOpPtT::debugEnder(const SkOpPtT* end) const { |
| 2483 return fT < end->fT ? end : this; |
| 2484 } |
| 2485 |
2445 int SkOpPtT::debugLoopLimit(bool report) const { | 2486 int SkOpPtT::debugLoopLimit(bool report) const { |
2446 int loop = 0; | 2487 int loop = 0; |
2447 const SkOpPtT* next = this; | 2488 const SkOpPtT* next = this; |
2448 do { | 2489 do { |
2449 for (int check = 1; check < loop - 1; ++check) { | 2490 for (int check = 1; check < loop - 1; ++check) { |
2450 const SkOpPtT* checkPtT = this->fNext; | 2491 const SkOpPtT* checkPtT = this->fNext; |
2451 const SkOpPtT* innerPtT = checkPtT; | 2492 const SkOpPtT* innerPtT = checkPtT; |
2452 for (int inner = check + 1; inner < loop; ++inner) { | 2493 for (int inner = check + 1; inner < loop; ++inner) { |
2453 innerPtT = innerPtT->fNext; | 2494 innerPtT = innerPtT->fNext; |
2454 if (checkPtT == innerPtT) { | 2495 if (checkPtT == innerPtT) { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2601 #endif | 2642 #endif |
2602 SkPath::FillType fillType = path.getFillType(); | 2643 SkPath::FillType fillType = path.getFillType(); |
2603 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); | 2644 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); |
2604 if (includeDeclaration) { | 2645 if (includeDeclaration) { |
2605 SkDebugf(" SkPath %s;\n", name); | 2646 SkDebugf(" SkPath %s;\n", name); |
2606 } | 2647 } |
2607 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); | 2648 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); |
2608 iter.setPath(path); | 2649 iter.setPath(path); |
2609 showPathContours(iter, name); | 2650 showPathContours(iter, name); |
2610 } | 2651 } |
OLD | NEW |