| 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 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 | 575 |
| 576 void SkDRect::debugInit() { | 576 void SkDRect::debugInit() { |
| 577 fLeft = fTop = fRight = fBottom = SK_ScalarNaN; | 577 fLeft = fTop = fRight = fBottom = SK_ScalarNaN; |
| 578 } | 578 } |
| 579 | 579 |
| 580 #include "SkOpAngle.h" | 580 #include "SkOpAngle.h" |
| 581 #include "SkOpSegment.h" | 581 #include "SkOpSegment.h" |
| 582 | 582 |
| 583 #if DEBUG_COINCIDENCE | 583 #if DEBUG_COINCIDENCE |
| 584 // commented-out lines keep this in sync with addT() | 584 // commented-out lines keep this in sync with addT() |
| 585 const SkOpPtT* SkOpSegment::debugAddT(double t, bool* allocated) const { | 585 const SkOpPtT* SkOpSegment::debugAddT(double t) const { |
| 586 debugValidate(); | 586 debugValidate(); |
| 587 SkPoint pt = this->ptAtT(t); | 587 SkPoint pt = this->ptAtT(t); |
| 588 const SkOpSpanBase* span = &fHead; | 588 const SkOpSpanBase* span = &fHead; |
| 589 do { | 589 do { |
| 590 const SkOpPtT* result = span->ptT(); | 590 const SkOpPtT* result = span->ptT(); |
| 591 const SkOpPtT* loop; | 591 if (t == result->fT || this->match(result, this, t, pt)) { |
| 592 bool duplicatePt; | |
| 593 if (t == result->fT) { | |
| 594 goto bumpSpan; | |
| 595 } | |
| 596 if (this->match(result, this, t, pt)) { | |
| 597 // see if any existing alias matches segment, pt, and t | |
| 598 loop = result->next(); | |
| 599 duplicatePt = false; | |
| 600 while (loop != result) { | |
| 601 bool ptMatch = loop->fPt == pt; | |
| 602 if (loop->segment() == this && loop->fT == t && ptMatch) { | |
| 603 goto bumpSpan; | |
| 604 } | |
| 605 duplicatePt |= ptMatch; | |
| 606 loop = loop->next(); | |
| 607 } | |
| 608 bumpSpan: | |
| 609 // span->bumpSpanAdds(); | 592 // span->bumpSpanAdds(); |
| 610 return result; | 593 return result; |
| 611 } | 594 } |
| 612 if (t < result->fT) { | 595 if (t < result->fT) { |
| 613 const SkOpSpan* prev = result->span()->prev(); | 596 const SkOpSpan* prev = result->span()->prev(); |
| 614 if (!prev) { | 597 FAIL_WITH_NULL_IF(!prev); |
| 615 return nullptr; // FIXME: this is a fail case; nullptr return e
lsewhere means result was allocated in non-const version | 598 // marks in global state that new op span has been allocated |
| 616 } | 599 this->globalState()->setAllocatedOpSpan(); |
| 617 // SkOpSpan* span = insert(prev, allocator); | |
| 618 // span->init(this, prev, t, pt); | 600 // span->init(this, prev, t, pt); |
| 619 this->debugValidate(); | 601 this->debugValidate(); |
| 620 // #if DEBUG_ADD_T | 602 // #if DEBUG_ADD_T |
| 621 // SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__,
t, | 603 // SkDebugf("%s insert t=%1.9g segID=%d spanID=%d\n", __FUNCTION__,
t, |
| 622 // span->segment()->debugID(), span->debugID()); | 604 // span->segment()->debugID(), span->debugID()); |
| 623 // #endif | 605 // #endif |
| 624 // span->bumpSpanAdds(); | 606 // span->bumpSpanAdds(); |
| 625 if (allocated) { | |
| 626 *allocated = true; | |
| 627 } | |
| 628 return nullptr; | 607 return nullptr; |
| 629 } | 608 } |
| 630 SkASSERT(span != &fTail); | 609 FAIL_WITH_NULL_IF(span != &fTail); |
| 631 } while ((span = span->upCast()->next())); | 610 } while ((span = span->upCast()->next())); |
| 632 SkASSERT(0); | 611 SkASSERT(0); |
| 633 return nullptr; | 612 return nullptr; // we never get here, but need this to satisfy compiler |
| 634 } | 613 } |
| 635 #endif | 614 #endif |
| 636 | 615 |
| 637 #if DEBUG_ANGLE | 616 #if DEBUG_ANGLE |
| 638 void SkOpSegment::debugCheckAngleCoin() const { | 617 void SkOpSegment::debugCheckAngleCoin() const { |
| 639 const SkOpSpanBase* base = &fHead; | 618 const SkOpSpanBase* base = &fHead; |
| 640 const SkOpSpan* span; | 619 const SkOpSpan* span; |
| 641 do { | 620 do { |
| 642 const SkOpAngle* angle = base->fromAngle(); | 621 const SkOpAngle* angle = base->fromAngle(); |
| 643 if (angle && angle->debugCheckCoincidence()) { | 622 if (angle && angle->debugCheckCoincidence()) { |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1486 if (osExisting && (osExisting == oe || osExisting->contains(oeExisting ? oeE
xisting : oe))) { | 1465 if (osExisting && (osExisting == oe || osExisting->contains(oeExisting ? oeE
xisting : oe))) { |
| 1487 return; | 1466 return; |
| 1488 } | 1467 } |
| 1489 if (oeExisting && (oeExisting == os || oeExisting->contains(osExisting ? osE
xisting : os))) { | 1468 if (oeExisting && (oeExisting == os || oeExisting->contains(osExisting ? osE
xisting : os))) { |
| 1490 return; | 1469 return; |
| 1491 } | 1470 } |
| 1492 bool csDeleted = false, osDeleted = false, ceDeleted = false, oeDeleted = f
alse; | 1471 bool csDeleted = false, osDeleted = false, ceDeleted = false, oeDeleted = f
alse; |
| 1493 this->debugValidate(); | 1472 this->debugValidate(); |
| 1494 if (!cs || !os) { | 1473 if (!cs || !os) { |
| 1495 if (!cs) | 1474 if (!cs) |
| 1496 cs = coinSeg->debugAddT(coinTs, nullptr); | 1475 cs = coinSeg->debugAddT(coinTs); |
| 1497 if (!os) | 1476 if (!os) |
| 1498 os = oppSeg->debugAddT(oppTs, nullptr); | 1477 os = oppSeg->debugAddT(oppTs); |
| 1499 if (cs && os) cs->span()->debugAddOppAndMerge(id, log, os->span(), &csDe
leted, &osDeleted); | 1478 if (cs && os) cs->span()->debugAddOppAndMerge(id, log, os->span(), &csDe
leted, &osDeleted); |
| 1500 // cs = csWritable; | 1479 // cs = csWritable; |
| 1501 // os = osWritable; | 1480 // os = osWritable; |
| 1502 if ((ce && ce->deleted()) || (oe && oe->deleted())) { | 1481 if ((ce && ce->deleted()) || (oe && oe->deleted())) { |
| 1503 return; | 1482 return; |
| 1504 } | 1483 } |
| 1505 } | 1484 } |
| 1506 if (!ce || !oe) { | 1485 if (!ce || !oe) { |
| 1507 if (!ce) | 1486 if (!ce) |
| 1508 ce = coinSeg->debugAddT(coinTe, nullptr); | 1487 ce = coinSeg->debugAddT(coinTe); |
| 1509 if (!oe) | 1488 if (!oe) |
| 1510 oe = oppSeg->debugAddT(oppTe, nullptr); | 1489 oe = oppSeg->debugAddT(oppTe); |
| 1511 if (ce && oe) ce->span()->debugAddOppAndMerge(id, log, oe->span(), &ceDe
leted, &oeDeleted); | 1490 if (ce && oe) ce->span()->debugAddOppAndMerge(id, log, oe->span(), &ceDe
leted, &oeDeleted); |
| 1512 // ce = ceWritable; | 1491 // ce = ceWritable; |
| 1513 // oe = oeWritable; | 1492 // oe = oeWritable; |
| 1514 } | 1493 } |
| 1515 this->debugValidate(); | 1494 this->debugValidate(); |
| 1516 if (csDeleted || osDeleted || ceDeleted || oeDeleted) { | 1495 if (csDeleted || osDeleted || ceDeleted || oeDeleted) { |
| 1517 return; | 1496 return; |
| 1518 } | 1497 } |
| 1519 if (!cs || !ce || cs->contains(ce) || !os || !oe || os->contains(oe)) { | 1498 if (!cs || !ce || cs->contains(ce) || !os || !oe || os->contains(oe)) { |
| 1520 return; | 1499 return; |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2052 SkASSERT(count >= fDoneCount); | 2031 SkASSERT(count >= fDoneCount); |
| 2053 SkASSERT(span->final()); | 2032 SkASSERT(span->final()); |
| 2054 span->debugValidate(); | 2033 span->debugValidate(); |
| 2055 #endif | 2034 #endif |
| 2056 } | 2035 } |
| 2057 | 2036 |
| 2058 #if DEBUG_COINCIDENCE_VERBOSE | 2037 #if DEBUG_COINCIDENCE_VERBOSE |
| 2059 // Commented-out lines keep this in sync with addOppAndMerge() | 2038 // Commented-out lines keep this in sync with addOppAndMerge() |
| 2060 // If the added points envelop adjacent spans, merge them in. | 2039 // If the added points envelop adjacent spans, merge them in. |
| 2061 void SkOpSpanBase::debugAddOppAndMerge(const char* id, SkPathOpsDebug::GlitchLog
* log, const SkOpSpanBase* opp, bool* spanDeleted, bool* oppDeleted) const { | 2040 void SkOpSpanBase::debugAddOppAndMerge(const char* id, SkPathOpsDebug::GlitchLog
* log, const SkOpSpanBase* opp, bool* spanDeleted, bool* oppDeleted) const { |
| 2062 if (this->ptT()->debugAddOpp(opp->ptT())) { | 2041 const SkOpPtT* oppPrev = this->ptT()->debugOppPrev(opp->ptT()); |
| 2042 if (oppPrev) { |
| 2043 this->ptT()->debugAddOpp(opp->ptT(), oppPrev); |
| 2063 this->debugCheckForCollapsedCoincidence(id, log); | 2044 this->debugCheckForCollapsedCoincidence(id, log); |
| 2064 } | 2045 } |
| 2065 // compute bounds of points in span | 2046 // compute bounds of points in span |
| 2066 SkPathOpsBounds bounds; | 2047 SkPathOpsBounds bounds; |
| 2067 bounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_ScalarMin); | 2048 bounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_ScalarMin); |
| 2068 const SkOpPtT* head = this->ptT(); | 2049 const SkOpPtT* head = this->ptT(); |
| 2069 const SkOpPtT* nextPt = head; | 2050 const SkOpPtT* nextPt = head; |
| 2070 do { | 2051 do { |
| 2071 bounds.add(nextPt->fPt); | 2052 bounds.add(nextPt->fPt); |
| 2072 } while ((nextPt = nextPt->next()) != head); | 2053 } while ((nextPt = nextPt->next()) != head); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2308 } | 2289 } |
| 2309 #endif | 2290 #endif |
| 2310 } | 2291 } |
| 2311 SkASSERT(count == count2); | 2292 SkASSERT(count == count2); |
| 2312 return count; | 2293 return count; |
| 2313 } | 2294 } |
| 2314 | 2295 |
| 2315 #include "SkOpContour.h" | 2296 #include "SkOpContour.h" |
| 2316 | 2297 |
| 2317 // Commented-out lines keep this in sync with addOpp() | 2298 // Commented-out lines keep this in sync with addOpp() |
| 2318 bool SkOpPtT::debugAddOpp(const SkOpPtT* opp) const { | 2299 void SkOpPtT::debugAddOpp(const SkOpPtT* opp, const SkOpPtT* oppPrev) const { |
| 2319 // find the fOpp ptr to opp | 2300 SkDEBUGCODE(const SkOpPtT* oldNext = this->fNext); |
| 2320 const SkOpPtT* oppPrev = opp->fNext; | |
| 2321 if (oppPrev == this) { | |
| 2322 return false; | |
| 2323 } | |
| 2324 while (oppPrev->fNext != opp) { | |
| 2325 oppPrev = oppPrev->fNext; | |
| 2326 if (oppPrev == this) { | |
| 2327 return false; | |
| 2328 } | |
| 2329 } | |
| 2330 // const SkOpPtT* oldNext = this->fNext; | |
| 2331 SkASSERT(this != opp); | 2301 SkASSERT(this != opp); |
| 2332 // this->fNext = opp; | 2302 // this->fNext = opp; |
| 2333 // SkASSERT(oppPrev != oldNext); | 2303 SkASSERT(oppPrev != oldNext); |
| 2334 // oppPrev->fNext = oldNext; | 2304 // oppPrev->fNext = oldNext; |
| 2335 return true; | |
| 2336 } | 2305 } |
| 2337 | 2306 |
| 2338 bool SkOpPtT::debugContains(const SkOpPtT* check) const { | 2307 bool SkOpPtT::debugContains(const SkOpPtT* check) const { |
| 2339 SkASSERT(this != check); | 2308 SkASSERT(this != check); |
| 2340 const SkOpPtT* ptT = this; | 2309 const SkOpPtT* ptT = this; |
| 2341 int links = 0; | 2310 int links = 0; |
| 2342 do { | 2311 do { |
| 2343 ptT = ptT->next(); | 2312 ptT = ptT->next(); |
| 2344 if (ptT == check) { | 2313 if (ptT == check) { |
| 2345 return true; | 2314 return true; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2396 // by taking a very long time to figure out that no loop entry is a dupl
icate | 2365 // by taking a very long time to figure out that no loop entry is a dupl
icate |
| 2397 // -- and it's likely that a large loop count is indicative of a bug som
ewhere | 2366 // -- and it's likely that a large loop count is indicative of a bug som
ewhere |
| 2398 if (++loop > 1000) { | 2367 if (++loop > 1000) { |
| 2399 SkDebugf("*** loop count exceeds 1000 ***\n"); | 2368 SkDebugf("*** loop count exceeds 1000 ***\n"); |
| 2400 return 1000; | 2369 return 1000; |
| 2401 } | 2370 } |
| 2402 } while ((next = next->fNext) && next != this); | 2371 } while ((next = next->fNext) && next != this); |
| 2403 return 0; | 2372 return 0; |
| 2404 } | 2373 } |
| 2405 | 2374 |
| 2375 const SkOpPtT* SkOpPtT::debugOppPrev(const SkOpPtT* opp) const { |
| 2376 return this->oppPrev(const_cast<SkOpPtT*>(opp)); |
| 2377 } |
| 2378 |
| 2406 void SkOpPtT::debugResetCoinT() const { | 2379 void SkOpPtT::debugResetCoinT() const { |
| 2407 #if DEBUG_COINCIDENCE_ORDER | 2380 #if DEBUG_COINCIDENCE_ORDER |
| 2408 this->segment()->debugResetCoinT(); | 2381 this->segment()->debugResetCoinT(); |
| 2409 #endif | 2382 #endif |
| 2410 } | 2383 } |
| 2411 | 2384 |
| 2412 void SkOpPtT::debugSetCoinT(int index) const { | 2385 void SkOpPtT::debugSetCoinT(int index) const { |
| 2413 #if DEBUG_COINCIDENCE_ORDER | 2386 #if DEBUG_COINCIDENCE_ORDER |
| 2414 this->segment()->debugSetCoinT(index, fT); | 2387 this->segment()->debugSetCoinT(index, fT); |
| 2415 #endif | 2388 #endif |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2530 #endif | 2503 #endif |
| 2531 SkPath::FillType fillType = path.getFillType(); | 2504 SkPath::FillType fillType = path.getFillType(); |
| 2532 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); | 2505 SkASSERT(fillType >= SkPath::kWinding_FillType && fillType <= SkPath::kInver
seEvenOdd_FillType); |
| 2533 if (includeDeclaration) { | 2506 if (includeDeclaration) { |
| 2534 SkDebugf(" SkPath %s;\n", name); | 2507 SkDebugf(" SkPath %s;\n", name); |
| 2535 } | 2508 } |
| 2536 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); | 2509 SkDebugf(" %s.setFillType(SkPath::%s);\n", name, gFillTypeStr[fillType]); |
| 2537 iter.setPath(path); | 2510 iter.setPath(path); |
| 2538 showPathContours(iter, name); | 2511 showPathContours(iter, name); |
| 2539 } | 2512 } |
| OLD | NEW |