/* * Copyright 2014 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file.
*/ #include"include/core/SkPoint.h" #include"include/core/SkTypes.h" #include"include/private/base/SkTemplates.h" #include"src/pathops/SkOpCoincidence.h" #include"src/pathops/SkOpContour.h" #include"src/pathops/SkOpSegment.h" #include"src/pathops/SkOpSpan.h" #include"src/pathops/SkPathOpsTypes.h"
// this pair of spans share a common t value or point; merge them and eliminate duplicates // this does not compute the best t or pt value; this merely moves all data into a single list void SkOpSpanBase::merge(SkOpSpan* span) {
SkOpPtT* spanPtT = span->ptT();
SkASSERT(this->t() != spanPtT->fT);
SkASSERT(!zero_or_one(spanPtT->fT));
span->release(this->ptT()); if (this->contains(span)) {
SkOPASSERT(0); // check to see if this ever happens -- should have been found earlier return; // merge is already in the ptT loop
}
SkOpPtT* remainder = spanPtT->next();
this->ptT()->insert(spanPtT); while (remainder != spanPtT) {
SkOpPtT* next = remainder->next();
SkOpPtT* compare = spanPtT->next(); while (compare != spanPtT) {
SkOpPtT* nextC = compare->next(); if (nextC->span() == remainder->span() && nextC->fT == remainder->fT) { goto tryNextRemainder;
}
compare = nextC;
}
spanPtT->insert(remainder);
tryNextRemainder:
remainder = next;
}
fSpanAdds += span->fSpanAdds;
}
// please keep in sync with debugCheckForCollapsedCoincidence() void SkOpSpanBase::checkForCollapsedCoincidence() {
SkOpCoincidence* coins = this->globalState()->coincidence(); if (coins->isEmpty()) { return;
} // the insert above may have put both ends of a coincident run in the same span // for each coincident ptT in loop; see if its opposite in is also in the loop // this implementation is the motivation for marking that a ptT is referenced by a coincident span
SkOpPtT* head = this->ptT();
SkOpPtT* test = head; do { if (!test->coincident()) { continue;
}
coins->markCollapsed(test);
} while ((test = test->next()) != head);
coins->releaseDeleted();
}
// please keep in sync with debugMergeMatches() // Look to see if pt-t linked list contains same segment more than once // if so, and if each pt-t is directly pointed to by spans in that segment, // merge them // keep the points, but remove spans so that the segment doesn't have 2 or more // spans pointing to the same pt-t loop at different loop elements bool SkOpSpanBase::mergeMatches(SkOpSpanBase* opp) {
SkOpPtT* test = &fPtT;
SkOpPtT* testNext; const SkOpPtT* stop = test; int safetyHatch = 1000000; do { if (!--safetyHatch) { returnfalse;
}
testNext = test->next(); if (test->deleted()) { continue;
}
SkOpSpanBase* testBase = test->span();
SkASSERT(testBase->ptT() == test);
SkOpSegment* segment = test->segment(); if (segment->done()) { continue;
}
SkOpPtT* inner = opp->ptT(); const SkOpPtT* innerStop = inner; do { if (inner->segment() != segment) { continue;
} if (inner->deleted()) { continue;
}
SkOpSpanBase* innerBase = inner->span();
SkASSERT(innerBase->ptT() == inner); // when the intersection is first detected, the span base is marked if there are // more than one point in the intersection. if (!zero_or_one(inner->fT)) {
innerBase->upCast()->release(test);
} else {
SkOPASSERT(inner->fT != test->fT); if (!zero_or_one(test->fT)) {
testBase->upCast()->release(inner);
} else {
segment->markAllDone(); // mark segment as collapsed
SkDEBUGCODE(testBase->debugSetDeleted());
test->setDeleted();
SkDEBUGCODE(innerBase->debugSetDeleted());
inner->setDeleted();
}
} #ifdef SK_DEBUG // assert if another undeleted entry points to segment const SkOpPtT* debugInner = inner; while ((debugInner = debugInner->next()) != innerStop) { if (debugInner->segment() != segment) { continue;
} if (debugInner->deleted()) { continue;
}
SkOPASSERT(0);
} #endif break;
} while ((inner = inner->next()) != innerStop);
} while ((test = testNext) != stop);
this->checkForCollapsedCoincidence(); returntrue;
}
int SkOpSpan::computeWindSum() {
SkOpGlobalState* globals = this->globalState();
SkOpContour* contourHead = globals->contourHead(); int windTry = 0; while (!this->sortableTop(contourHead) && ++windTry < SkOpGlobalState::kMaxWindingTries) {
} return this->windSum();
}
bool SkOpSpan::containsCoincidence(const SkOpSegment* segment) const {
SkASSERT(this->segment() != segment); const SkOpSpan* next = fCoincident; do { if (next->segment() == segment) { returntrue;
}
} while ((next = next->fCoincident) != this); returnfalse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.