in src/pathops/SkPathOpsDebug.cpp [1732:1846]
void SkOpCoincidence::debugAddOrOverlap(SkPathOpsDebug::GlitchLog* log,
const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
double coinTs, double coinTe, double oppTs, double oppTe, bool* added) const {
SkTDArray<SkCoincidentSpans*> overlaps;
SkOPASSERT(!fTop); // this is (correctly) reversed in addifMissing()
if (fTop && !this->checkOverlap(fTop, coinSeg, oppSeg, coinTs, coinTe, oppTs, oppTe,
&overlaps)) {
return;
}
if (fHead && !this->checkOverlap(fHead, coinSeg, oppSeg, coinTs,
coinTe, oppTs, oppTe, &overlaps)) {
return;
}
const SkCoincidentSpans* overlap = overlaps.size() ? overlaps[0] : nullptr;
for (int index = 1; index < overlaps.size(); ++index) { // combine overlaps before continuing
const SkCoincidentSpans* test = overlaps[index];
if (overlap->coinPtTStart()->fT > test->coinPtTStart()->fT) {
log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->coinPtTStart());
}
if (overlap->coinPtTEnd()->fT < test->coinPtTEnd()->fT) {
log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->coinPtTEnd());
}
if (overlap->flipped()
? overlap->oppPtTStart()->fT < test->oppPtTStart()->fT
: overlap->oppPtTStart()->fT > test->oppPtTStart()->fT) {
log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->oppPtTStart());
}
if (overlap->flipped()
? overlap->oppPtTEnd()->fT > test->oppPtTEnd()->fT
: overlap->oppPtTEnd()->fT < test->oppPtTEnd()->fT) {
log->record(SkPathOpsDebug::kAddOrOverlap_Glitch, overlap, test->oppPtTEnd());
}
if (!fHead) { this->debugRelease(log, fHead, test);
this->debugRelease(log, fTop, test);
}
}
const SkOpPtT* cs = coinSeg->existing(coinTs, oppSeg);
const SkOpPtT* ce = coinSeg->existing(coinTe, oppSeg);
RETURN_FALSE_IF(overlap && cs && ce && overlap->contains(cs, ce), coinSeg);
RETURN_FALSE_IF(cs != ce || !cs, coinSeg);
const SkOpPtT* os = oppSeg->existing(oppTs, coinSeg);
const SkOpPtT* oe = oppSeg->existing(oppTe, coinSeg);
RETURN_FALSE_IF(overlap && os && oe && overlap->contains(os, oe), oppSeg);
SkASSERT(true || !cs || !cs->deleted());
SkASSERT(true || !os || !os->deleted());
SkASSERT(true || !ce || !ce->deleted());
SkASSERT(true || !oe || !oe->deleted());
const SkOpPtT* csExisting = !cs ? coinSeg->existing(coinTs, nullptr) : nullptr;
const SkOpPtT* ceExisting = !ce ? coinSeg->existing(coinTe, nullptr) : nullptr;
RETURN_FALSE_IF(csExisting && csExisting == ceExisting, coinSeg);
RETURN_FALSE_IF(csExisting && (csExisting == ce ||
csExisting->contains(ceExisting ? ceExisting : ce)), coinSeg);
RETURN_FALSE_IF(ceExisting && (ceExisting == cs ||
ceExisting->contains(csExisting ? csExisting : cs)), coinSeg);
const SkOpPtT* osExisting = !os ? oppSeg->existing(oppTs, nullptr) : nullptr;
const SkOpPtT* oeExisting = !oe ? oppSeg->existing(oppTe, nullptr) : nullptr;
RETURN_FALSE_IF(osExisting && osExisting == oeExisting, oppSeg);
RETURN_FALSE_IF(osExisting && (osExisting == oe ||
osExisting->contains(oeExisting ? oeExisting : oe)), oppSeg);
RETURN_FALSE_IF(oeExisting && (oeExisting == os ||
oeExisting->contains(osExisting ? osExisting : os)), oppSeg);
bool csDeleted = false, osDeleted = false, ceDeleted = false, oeDeleted = false;
this->debugValidate();
if (!cs || !os) {
if (!cs)
cs = coinSeg->debugAddT(coinTs, log);
if (!os)
os = oppSeg->debugAddT(oppTs, log);
// RETURN_FALSE_IF(callerAborts, !csWritable || !osWritable);
if (cs && os) cs->span()->debugAddOpp(log, os->span());
// cs = csWritable;
// os = osWritable->active();
RETURN_FALSE_IF((ce && ce->deleted()) || (oe && oe->deleted()), coinSeg);
}
if (!ce || !oe) {
if (!ce)
ce = coinSeg->debugAddT(coinTe, log);
if (!oe)
oe = oppSeg->debugAddT(oppTe, log);
if (ce && oe) ce->span()->debugAddOpp(log, oe->span());
// ce = ceWritable;
// oe = oeWritable;
}
this->debugValidate();
RETURN_FALSE_IF(csDeleted, coinSeg);
RETURN_FALSE_IF(osDeleted, oppSeg);
RETURN_FALSE_IF(ceDeleted, coinSeg);
RETURN_FALSE_IF(oeDeleted, oppSeg);
RETURN_FALSE_IF(!cs || !ce || cs == ce || cs->contains(ce) || !os || !oe || os == oe || os->contains(oe), coinSeg);
bool result = true;
if (overlap) {
if (overlap->coinPtTStart()->segment() == coinSeg) {
log->record(SkPathOpsDebug::kAddMissingExtend_Glitch, coinSeg, coinTs, coinTe, oppSeg, oppTs, oppTe);
} else {
if (oppTs > oppTe) {
using std::swap;
swap(coinTs, coinTe);
swap(oppTs, oppTe);
}
log->record(SkPathOpsDebug::kAddMissingExtend_Glitch, oppSeg, oppTs, oppTe, coinSeg, coinTs, coinTe);
}
#if 0 && DEBUG_COINCIDENCE_VERBOSE
if (result) {
overlap->debugShow();
}
#endif
} else {
log->record(SkPathOpsDebug::kAddMissingCoin_Glitch, coinSeg, coinTs, coinTe, oppSeg, oppTs, oppTe);
#if 0 && DEBUG_COINCIDENCE_VERBOSE
fHead->debugShow();
#endif
}
this->debugValidate();
return (void) result;
}