本文整理汇总了C++中SkOpSegment::done方法的典型用法代码示例。如果您正苦于以下问题:C++ SkOpSegment::done方法的具体用法?C++ SkOpSegment::done怎么用?C++ SkOpSegment::done使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkOpSegment
的用法示例。
在下文中一共展示了SkOpSegment::done方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: bridgeXor
// returns true if all edges were processed
static bool bridgeXor(SkTDArray<SkOpContour*>& contourList, SkPathWriter* simple) {
SkOpSegment* current;
int start, end;
bool unsortable = false;
bool closable = true;
while ((current = FindUndone(contourList, &start, &end))) {
do {
#if DEBUG_ACTIVE_SPANS
if (!unsortable && current->done()) {
DebugShowActiveSpans(contourList);
}
#endif
SkASSERT(unsortable || !current->done());
int nextStart = start;
int nextEnd = end;
SkOpSegment* next = current->findNextXor(&nextStart, &nextEnd, &unsortable);
if (!next) {
if (!unsortable && simple->hasMove()
&& current->verb() != SkPath::kLine_Verb
&& !simple->isClosed()) {
current->addCurveTo(start, end, simple, true);
SkASSERT(simple->isClosed());
}
break;
}
#if DEBUG_FLOW
SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
current->debugID(), current->xyAtT(start).fX, current->xyAtT(start).fY,
current->xyAtT(end).fX, current->xyAtT(end).fY);
#endif
current->addCurveTo(start, end, simple, true);
current = next;
start = nextStart;
end = nextEnd;
} while (!simple->isClosed() && (!unsortable || !current->done(SkMin32(start, end))));
if (!simple->isClosed()) {
SkASSERT(unsortable);
int min = SkMin32(start, end);
if (!current->done(min)) {
current->addCurveTo(start, end, simple, true);
current->markDone(min, 1);
}
closable = false;
}
simple->close();
#if DEBUG_ACTIVE_SPANS
DebugShowActiveSpans(contourList);
#endif
}
return closable;
}
示例2: topSortableSegment
void SkOpContour::topSortableSegment(const SkPoint& topLeft, SkPoint* bestXY,
SkOpSegment** topStart) {
int segmentCount = fSortedSegments.count();
SkASSERT(segmentCount > 0);
int sortedIndex = fFirstSorted;
fDone = true; // may be cleared below
for ( ; sortedIndex < segmentCount; ++sortedIndex) {
SkOpSegment* testSegment = fSortedSegments[sortedIndex];
if (testSegment->done()) {
if (sortedIndex == fFirstSorted) {
++fFirstSorted;
}
continue;
}
fDone = false;
SkPoint testXY = testSegment->activeLeftTop(true, NULL);
if (*topStart) {
if (testXY.fY < topLeft.fY) {
continue;
}
if (testXY.fY == topLeft.fY && testXY.fX < topLeft.fX) {
continue;
}
if (bestXY->fY < testXY.fY) {
continue;
}
if (bestXY->fY == testXY.fY && bestXY->fX < testXY.fX) {
continue;
}
}
*topStart = testSegment;
*bestXY = testXY;
}
}
示例3: mergeMatches
// 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
void SkOpSpanBase::mergeMatches(SkOpSpanBase* opp) {
SkOpPtT* test = &fPtT;
SkOpPtT* testNext;
const SkOpPtT* stop = test;
do {
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();
}
示例4: undoneSegment
SkOpSegment* SkOpContour::undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr) {
SkOpSegment* segment = &fHead;
do {
if (segment->done()) {
continue;
}
segment->undoneSpan(startPtr, endPtr);
return segment;
} while ((segment = segment->next()));
return nullptr;
}
示例5: undoneSpan
SkOpSpan* SkOpContour::undoneSpan() {
SkOpSegment* testSegment = &fHead;
do {
if (testSegment->done()) {
continue;
}
return testSegment->undoneSpan();
} while ((testSegment = testSegment->next()));
fDone = true;
return nullptr;
}
示例6: undoneSegment
SkOpSegment* SkOpContour::undoneSegment(int* start, int* end) {
int segmentCount = fSegments.count();
for (int test = 0; test < segmentCount; ++test) {
SkOpSegment* testSegment = &fSegments[test];
if (testSegment->done()) {
continue;
}
testSegment->undoneSpan(start, end);
return testSegment;
}
return NULL;
}
示例7: nonVerticalSegment
SkOpSegment* SkOpContour::nonVerticalSegment(int* start, int* end) {
int segmentCount = fSortedSegments.count();
SkASSERT(segmentCount > 0);
for (int sortedIndex = fFirstSorted; sortedIndex < segmentCount; ++sortedIndex) {
SkOpSegment* testSegment = fSortedSegments[sortedIndex];
if (testSegment->done()) {
continue;
}
*start = *end = 0;
while (testSegment->nextCandidate(start, end)) {
if (!testSegment->isVertical(*start, *end)) {
return testSegment;
}
}
}
return NULL;
}
示例8: nonVerticalSegment
SkOpSegment* SkOpContour::nonVerticalSegment(SkOpSpanBase** start, SkOpSpanBase** end) {
int segmentCount = fSortedSegments.count();
SkASSERT(segmentCount > 0);
for (int sortedIndex = fFirstSorted; sortedIndex < segmentCount; ++sortedIndex) {
SkOpSegment* testSegment = fSortedSegments[sortedIndex];
if (testSegment->done()) {
continue;
}
SkOpSpanBase* span = testSegment->head();
SkOpSpanBase* testS, * testE;
while (SkOpSegment::NextCandidate(span, &testS, &testE)) {
if (!testSegment->isVertical(testS, testE)) {
*start = testS;
*end = testE;
return testSegment;
}
span = span->upCast()->next();
}
}
return NULL;
}
示例9: FindSortableTop
SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList,
SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexPtr,
int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done, bool* onlyVertical,
bool firstPass) {
SkOpSegment* current = findTopSegment(contourList, indexPtr, endIndexPtr, topLeft, unsortable,
done, firstPass);
if (!current) {
return NULL;
}
const int startIndex = *indexPtr;
const int endIndex = *endIndexPtr;
if (*firstContour) {
current->initWinding(startIndex, endIndex, angleIncludeType);
*firstContour = false;
return current;
}
int minIndex = SkMin32(startIndex, endIndex);
int sumWinding = current->windSum(minIndex);
if (sumWinding == SK_MinS32) {
int index = endIndex;
int oIndex = startIndex;
do {
const SkOpSpan& span = current->span(index);
if ((oIndex < index ? span.fFromAngle : span.fToAngle) == NULL) {
current->addSimpleAngle(index);
}
sumWinding = current->computeSum(oIndex, index, angleIncludeType);
SkTSwap(index, oIndex);
} while (sumWinding == SK_MinS32 && index == startIndex);
}
if (sumWinding != SK_MinS32 && sumWinding != SK_NaN32) {
return current;
}
int contourWinding;
int oppContourWinding = 0;
// the simple upward projection of the unresolved points hit unsortable angles
// shoot rays at right angles to the segment to find its winding, ignoring angle cases
bool tryAgain;
double tHit;
SkScalar hitDx = 0;
SkScalar hitOppDx = 0;
do {
// if current is vertical, find another candidate which is not
// if only remaining candidates are vertical, then they can be marked done
SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
skipVertical(contourList, ¤t, indexPtr, endIndexPtr);
SkASSERT(current); // FIXME: if null, all remaining are vertical
SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
tryAgain = false;
contourWinding = rightAngleWinding(contourList, ¤t, indexPtr, endIndexPtr, &tHit,
&hitDx, &tryAgain, onlyVertical, false);
if (*onlyVertical) {
return current;
}
if (tryAgain) {
continue;
}
if (angleIncludeType < SkOpAngle::kBinarySingle) {
break;
}
oppContourWinding = rightAngleWinding(contourList, ¤t, indexPtr, endIndexPtr, &tHit,
&hitOppDx, &tryAgain, NULL, true);
} while (tryAgain);
current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx, oppContourWinding,
hitOppDx);
if (current->done()) {
return NULL;
}
return current;
}
示例10: findChaseOp
// FIXME: this and find chase should be merge together, along with
// other code that walks winding in angles
// OPTIMIZATION: Probably, the walked winding should be rolled into the angle structure
// so it isn't duplicated by walkers like this one
static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int& nextStart, int& nextEnd) {
while (chase.count()) {
SkOpSpan* span;
chase.pop(&span);
const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
SkOpSegment* segment = backPtr.fOther;
nextStart = backPtr.fOtherIndex;
SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles;
int done = 0;
if (segment->activeAngle(nextStart, &done, &angles)) {
SkOpAngle* last = angles.end() - 1;
nextStart = last->start();
nextEnd = last->end();
#if TRY_ROTATE
*chase.insert(0) = span;
#else
*chase.append() = span;
#endif
return last->segment();
}
if (done == angles.count()) {
continue;
}
SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted;
bool sortable = SkOpSegment::SortAngles(angles, &sorted,
SkOpSegment::kMayBeUnordered_SortAngleKind);
int angleCount = sorted.count();
#if DEBUG_SORT
sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0, sortable);
#endif
if (!sortable) {
continue;
}
// find first angle, initialize winding to computed fWindSum
int firstIndex = -1;
const SkOpAngle* angle;
bool foundAngle = true;
do {
++firstIndex;
if (firstIndex >= angleCount) {
foundAngle = false;
break;
}
angle = sorted[firstIndex];
segment = angle->segment();
} while (segment->windSum(angle) == SK_MinS32);
if (!foundAngle) {
continue;
}
#if DEBUG_SORT
segment->debugShowSort(__FUNCTION__, sorted, firstIndex, sortable);
#endif
int sumMiWinding = segment->updateWindingReverse(angle);
int sumSuWinding = segment->updateOppWindingReverse(angle);
if (segment->operand()) {
SkTSwap<int>(sumMiWinding, sumSuWinding);
}
int nextIndex = firstIndex + 1;
int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
SkOpSegment* first = NULL;
do {
SkASSERT(nextIndex != firstIndex);
if (nextIndex == angleCount) {
nextIndex = 0;
}
angle = sorted[nextIndex];
segment = angle->segment();
int start = angle->start();
int end = angle->end();
int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
segment->setUpWindings(start, end, &sumMiWinding, &sumSuWinding,
&maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
if (!segment->done(angle)) {
if (!first) {
first = segment;
nextStart = start;
nextEnd = end;
}
(void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
oppSumWinding, angle);
}
} while (++nextIndex != lastIndex);
if (first) {
#if TRY_ROTATE
*chase.insert(0) = span;
#else
*chase.append() = span;
#endif
return first;
}
}
return NULL;
}
示例11: bridgeOp
static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp op,
const int xorMask, const int xorOpMask, SkPathWriter* simple) {
bool firstContour = true;
bool unsortable = false;
bool topUnsortable = false;
SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin};
do {
int index, endIndex;
bool done;
SkOpSegment* current = FindSortableTop(contourList, SkOpAngle::kBinarySingle, &firstContour,
&index, &endIndex, &topLeft, &topUnsortable, &done);
if (!current) {
if (topUnsortable || !done) {
topUnsortable = false;
SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMin);
topLeft.fX = topLeft.fY = SK_ScalarMin;
continue;
}
break;
}
SkTDArray<SkOpSpan*> chaseArray;
do {
if (current->activeOp(index, endIndex, xorMask, xorOpMask, op)) {
do {
if (!unsortable && current->done()) {
#if DEBUG_ACTIVE_SPANS
DebugShowActiveSpans(contourList);
#endif
if (simple->isEmpty()) {
simple->init();
}
break;
}
SkASSERT(unsortable || !current->done());
int nextStart = index;
int nextEnd = endIndex;
SkOpSegment* next = current->findNextOp(&chaseArray, &nextStart, &nextEnd,
&unsortable, op, xorMask, xorOpMask);
if (!next) {
if (!unsortable && simple->hasMove()
&& current->verb() != SkPath::kLine_Verb
&& !simple->isClosed()) {
current->addCurveTo(index, endIndex, simple, true);
SkASSERT(simple->isClosed());
}
break;
}
#if DEBUG_FLOW
SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
current->debugID(), current->xyAtT(index).fX, current->xyAtT(index).fY,
current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY);
#endif
current->addCurveTo(index, endIndex, simple, true);
current = next;
index = nextStart;
endIndex = nextEnd;
} while (!simple->isClosed() && (!unsortable
|| !current->done(SkMin32(index, endIndex))));
if (current->activeWinding(index, endIndex) && !simple->isClosed()) {
// FIXME : add to simplify, xor cpaths
int min = SkMin32(index, endIndex);
if (!unsortable && !simple->isEmpty()) {
unsortable = current->checkSmall(min);
}
SkASSERT(unsortable || simple->isEmpty());
if (!current->done(min)) {
current->addCurveTo(index, endIndex, simple, true);
current->markDoneBinary(min);
}
}
simple->close();
} else {
SkOpSpan* last = current->markAndChaseDoneBinary(index, endIndex);
if (last && !last->fLoop) {
*chaseArray.append() = last;
}
}
current = findChaseOp(chaseArray, index, endIndex);
#if DEBUG_ACTIVE_SPANS
DebugShowActiveSpans(contourList);
#endif
if (!current) {
break;
}
} while (true);
} while (true);
return simple->someAssemblyRequired();
}
示例12: bridgeOp
static bool bridgeOp(SkTArray<SkOpContour*, true>& contourList, const SkPathOp op,
const int xorMask, const int xorOpMask, SkPathWriter* simple) {
bool firstContour = true;
bool unsortable = false;
bool topUnsortable = false;
bool firstPass = true;
SkPoint lastTopLeft;
SkPoint topLeft = {SK_ScalarMin, SK_ScalarMin};
do {
int index, endIndex;
bool topDone;
bool onlyVertical = false;
lastTopLeft = topLeft;
SkOpSegment* current = FindSortableTop(contourList, SkOpAngle::kBinarySingle, &firstContour,
&index, &endIndex, &topLeft, &topUnsortable, &topDone, &onlyVertical, firstPass);
if (!current) {
if ((!topUnsortable || firstPass) && !topDone) {
SkASSERT(topLeft.fX != SK_ScalarMin && topLeft.fY != SK_ScalarMin);
if (lastTopLeft.fX == SK_ScalarMin && lastTopLeft.fY == SK_ScalarMin) {
if (firstPass) {
firstPass = false;
} else {
break;
}
}
topLeft.fX = topLeft.fY = SK_ScalarMin;
continue;
}
break;
} else if (onlyVertical) {
break;
}
firstPass = !topUnsortable || lastTopLeft != topLeft;
SkTDArray<SkOpSpan*> chase;
do {
if (current->activeOp(index, endIndex, xorMask, xorOpMask, op)) {
do {
if (!unsortable && current->done()) {
break;
}
SkASSERT(unsortable || !current->done());
int nextStart = index;
int nextEnd = endIndex;
SkOpSegment* next = current->findNextOp(&chase, &nextStart, &nextEnd,
&unsortable, op, xorMask, xorOpMask);
if (!next) {
if (!unsortable && simple->hasMove()
&& current->verb() != SkPath::kLine_Verb
&& !simple->isClosed()) {
current->addCurveTo(index, endIndex, simple, true);
#if DEBUG_ACTIVE_SPANS
if (!simple->isClosed()) {
DebugShowActiveSpans(contourList);
}
#endif
// SkASSERT(simple->isClosed());
}
break;
}
#if DEBUG_FLOW
SkDebugf("%s current id=%d from=(%1.9g,%1.9g) to=(%1.9g,%1.9g)\n", __FUNCTION__,
current->debugID(), current->xyAtT(index).fX, current->xyAtT(index).fY,
current->xyAtT(endIndex).fX, current->xyAtT(endIndex).fY);
#endif
current->addCurveTo(index, endIndex, simple, true);
current = next;
index = nextStart;
endIndex = nextEnd;
} while (!simple->isClosed() && (!unsortable
|| !current->done(SkMin32(index, endIndex))));
if (current->activeWinding(index, endIndex) && !simple->isClosed()) {
// FIXME : add to simplify, xor cpaths
int min = SkMin32(index, endIndex);
if (!unsortable && !simple->isEmpty()) {
unsortable = current->checkSmall(min);
}
if (!current->done(min)) {
current->addCurveTo(index, endIndex, simple, true);
current->markDoneBinary(min);
}
}
simple->close();
} else {
SkOpSpan* last = current->markAndChaseDoneBinary(index, endIndex);
if (last && !last->fChased && !last->fLoop) {
last->fChased = true;
SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last));
*chase.append() = last;
#if DEBUG_WINDING
SkDebugf("%s chase.append id=%d windSum=%d small=%d\n", __FUNCTION__,
last->fOther->span(last->fOtherIndex).fOther->debugID(), last->fWindSum,
last->fSmall);
#endif
}
}
current = findChaseOp(chase, &index, &endIndex);
#if DEBUG_ACTIVE_SPANS
DebugShowActiveSpans(contourList);
#endif
if (!current) {
//.........这里部分代码省略.........
示例13: findChaseOp
static SkOpSegment* findChaseOp(SkTDArray<SkOpSpan*>& chase, int* tIndex, int* endIndex) {
while (chase.count()) {
SkOpSpan* span;
chase.pop(&span);
const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
SkOpSegment* segment = backPtr.fOther;
*tIndex = backPtr.fOtherIndex;
bool sortable = true;
bool done = true;
*endIndex = -1;
if (const SkOpAngle* last = segment->activeAngle(*tIndex, tIndex, endIndex, &done,
&sortable)) {
if (last->unorderable()) {
continue;
}
*tIndex = last->start();
*endIndex = last->end();
#if TRY_ROTATE
*chase.insert(0) = span;
#else
*chase.append() = span;
#endif
return last->segment();
}
if (done) {
continue;
}
if (!sortable) {
continue;
}
// find first angle, initialize winding to computed fWindSum
const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex);
if (!angle) {
continue;
}
const SkOpAngle* firstAngle = angle;
SkDEBUGCODE(bool loop = false);
int winding;
do {
angle = angle->next();
SkASSERT(angle != firstAngle || !loop);
SkDEBUGCODE(loop |= angle == firstAngle);
segment = angle->segment();
winding = segment->windSum(angle);
} while (winding == SK_MinS32);
int sumMiWinding = segment->updateWindingReverse(angle);
int sumSuWinding = segment->updateOppWindingReverse(angle);
if (segment->operand()) {
SkTSwap<int>(sumMiWinding, sumSuWinding);
}
SkOpSegment* first = NULL;
while ((angle = angle->next()) != firstAngle) {
segment = angle->segment();
int start = angle->start();
int end = angle->end();
int maxWinding, sumWinding, oppMaxWinding, oppSumWinding;
segment->setUpWindings(start, end, &sumMiWinding, &sumSuWinding,
&maxWinding, &sumWinding, &oppMaxWinding, &oppSumWinding);
if (!segment->done(angle)) {
if (!first) {
first = segment;
*tIndex = start;
*endIndex = end;
}
// OPTIMIZATION: should this also add to the chase?
(void) segment->markAngle(maxWinding, sumWinding, oppMaxWinding,
oppSumWinding, angle);
}
}
if (first) {
#if TRY_ROTATE
*chase.insert(0) = span;
#else
*chase.append() = span;
#endif
return first;
}
}
return NULL;
}
示例14: FindSortableTop
SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList,
SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexPtr,
int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done, bool* onlyVertical,
bool firstPass) {
SkOpSegment* current = findTopSegment(contourList, indexPtr, endIndexPtr, topLeft, unsortable,
done, firstPass);
if (!current) {
return NULL;
}
const int startIndex = *indexPtr;
const int endIndex = *endIndexPtr;
if (*firstContour) {
current->initWinding(startIndex, endIndex, angleIncludeType);
*firstContour = false;
return current;
}
int minIndex = SkMin32(startIndex, endIndex);
int sumWinding = current->windSum(minIndex);
if (sumWinding == SK_MinS32) {
int index = endIndex;
int oIndex = startIndex;
do {
const SkOpSpan& span = current->span(index);
if ((oIndex < index ? span.fFromAngle : span.fToAngle) == NULL) {
current->addSimpleAngle(index);
}
sumWinding = current->computeSum(oIndex, index, angleIncludeType);
SkTSwap(index, oIndex);
} while (sumWinding == SK_MinS32 && index == startIndex);
}
if (sumWinding != SK_MinS32 && sumWinding != SK_NaN32) {
return current;
}
int contourWinding;
int oppContourWinding = 0;
// the simple upward projection of the unresolved points hit unsortable angles
// shoot rays at right angles to the segment to find its winding, ignoring angle cases
bool tryAgain;
double tHit;
SkScalar hitDx = 0;
SkScalar hitOppDx = 0;
// keep track of subsequent returns to detect infinite loops
SkTDArray<SortableTop> sortableTops;
do {
// if current is vertical, find another candidate which is not
// if only remaining candidates are vertical, then they can be marked done
SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
skipVertical(contourList, ¤t, indexPtr, endIndexPtr);
SkASSERT(current); // FIXME: if null, all remaining are vertical
SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >= 0);
tryAgain = false;
contourWinding = rightAngleWinding(contourList, ¤t, indexPtr, endIndexPtr, &tHit,
&hitDx, &tryAgain, onlyVertical, false);
if (tryAgain) {
bool giveUp = false;
int count = sortableTops.count();
for (int index = 0; index < count; ++index) {
const SortableTop& prev = sortableTops[index];
if (giveUp) {
prev.fSegment->markDoneFinal(prev.fIndex);
} else if (prev.fSegment == current
&& (prev.fIndex == *indexPtr || prev.fEndIndex == *endIndexPtr)) {
// remaining edges are non-vertical and cannot have their winding computed
// mark them as done and return, and hope that assembly can fill the holes
giveUp = true;
index = -1;
}
}
if (giveUp) {
*done = true;
return NULL;
}
}
SortableTop* sortableTop = sortableTops.append();
sortableTop->fSegment = current;
sortableTop->fIndex = *indexPtr;
sortableTop->fEndIndex = *endIndexPtr;
#if DEBUG_SORT
SkDebugf("%s current=%d index=%d endIndex=%d tHit=%1.9g hitDx=%1.9g try=%d vert=%d\n",
__FUNCTION__, current->debugID(), *indexPtr, *endIndexPtr, tHit, hitDx, tryAgain,
*onlyVertical);
#endif
if (*onlyVertical) {
return current;
}
if (tryAgain) {
continue;
}
if (angleIncludeType < SkOpAngle::kBinarySingle) {
break;
}
oppContourWinding = rightAngleWinding(contourList, ¤t, indexPtr, endIndexPtr, &tHit,
&hitOppDx, &tryAgain, NULL, true);
} while (tryAgain);
bool success = current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx,
oppContourWinding, hitOppDx);
if (current->done()) {
return NULL;
} else if (!success) { // check if the span has a valid winding
int min = SkTMin(*indexPtr, *endIndexPtr);
//.........这里部分代码省略.........
示例15: FindChase
SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
SkOpSpanBase** endPtr) {
while (chase->count()) {
SkOpSpanBase* span;
chase->pop(&span);
SkOpSegment* segment = span->segment();
*startPtr = span->ptT()->next()->span();
bool done = true;
*endPtr = nullptr;
if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr, &done)) {
*startPtr = last->start();
*endPtr = last->end();
#if TRY_ROTATE
*chase->insert(0) = span;
#else
*chase->append() = span;
#endif
return last->segment();
}
if (done) {
continue;
}
// find first angle, initialize winding to computed wind sum
int winding;
bool sortable;
const SkOpAngle* angle = AngleWinding(*startPtr, *endPtr, &winding, &sortable);
if (winding == SK_MinS32) {
continue;
}
int sumWinding SK_INIT_TO_AVOID_WARNING;
if (sortable) {
segment = angle->segment();
sumWinding = segment->updateWindingReverse(angle);
}
SkOpSegment* first = nullptr;
const SkOpAngle* firstAngle = angle;
while ((angle = angle->next()) != firstAngle) {
segment = angle->segment();
SkOpSpanBase* start = angle->start();
SkOpSpanBase* end = angle->end();
int maxWinding;
if (sortable) {
segment->setUpWinding(start, end, &maxWinding, &sumWinding);
}
if (!segment->done(angle)) {
if (!first && (sortable || start->starter(end)->windSum() != SK_MinS32)) {
first = segment;
*startPtr = start;
*endPtr = end;
}
// OPTIMIZATION: should this also add to the chase?
if (sortable) {
(void) segment->markAngle(maxWinding, sumWinding, angle);
}
}
}
if (first) {
#if TRY_ROTATE
*chase->insert(0) = span;
#else
*chase->append() = span;
#endif
return first;
}
}
return nullptr;
}