Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(489)

Unified Diff: src/pathops/SkPathOpsCommon.cpp

Issue 1140813002: deal more consistently with unsortable edges (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix linux warning Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/pathops/SkPathOpsCommon.h ('k') | src/pathops/SkPathOpsOp.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pathops/SkPathOpsCommon.cpp
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
index 734b5f0819edf601a38f66f5acd2dd4a2585e1ee..98cce15fb29554df3bc5622ac84d53bea331f2e3 100644
--- a/src/pathops/SkPathOpsCommon.cpp
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -11,6 +11,55 @@
#include "SkPathWriter.h"
#include "SkTSort.h"
+const SkOpAngle* AngleWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* windingPtr,
+ bool* sortablePtr) {
+ // find first angle, initialize winding to computed fWindSum
+ SkOpSegment* segment = start->segment();
+ const SkOpAngle* angle = segment->spanToAngle(start, end);
+ if (!angle) {
+ *windingPtr = SK_MinS32;
+ return NULL;
+ }
+ bool computeWinding = false;
+ const SkOpAngle* firstAngle = angle;
+ bool loop = false;
+ bool unorderable = false;
+ int winding = SK_MinS32;
+ do {
+ angle = angle->next();
+ unorderable |= angle->unorderable();
+ if ((computeWinding = unorderable || (angle == firstAngle && loop))) {
+ break; // if we get here, there's no winding, loop is unorderable
+ }
+ loop |= angle == firstAngle;
+ segment = angle->segment();
+ winding = segment->windSum(angle);
+ } while (winding == SK_MinS32);
+ // if the angle loop contains an unorderable span, the angle order may be useless
+ // directly compute the winding in this case for each span
+ if (computeWinding) {
+ firstAngle = angle;
+ winding = SK_MinS32;
+ do {
+ SkOpSpanBase* startSpan = angle->start();
+ SkOpSpanBase* endSpan = angle->end();
+ SkOpSpan* lesser = startSpan->starter(endSpan);
+ int testWinding = lesser->windSum();
+ if (testWinding == SK_MinS32) {
+ testWinding = lesser->computeWindSum();
+ }
+ if (testWinding != SK_MinS32) {
+ segment = angle->segment();
+ winding = testWinding;
+ }
+ angle = angle->next();
+ } while (angle != firstAngle);
+ }
+ *sortablePtr = !unorderable;
+ *windingPtr = winding;
+ return angle;
+}
+
SkOpSegment* FindUndone(SkOpContourHead* contourList, SkOpSpanBase** startPtr,
SkOpSpanBase** endPtr) {
SkOpSegment* result;
@@ -31,14 +80,9 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
chase->pop(&span);
SkOpSegment* segment = span->segment();
*startPtr = span->ptT()->next()->span();
- bool sortable = true;
bool done = true;
*endPtr = NULL;
- if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr, &done,
- &sortable)) {
- if (last->unorderable()) {
- continue;
- }
+ if (SkOpAngle* last = segment->activeAngle(*startPtr, startPtr, endPtr, &done)) {
*startPtr = last->start();
*endPtr = last->end();
#if TRY_ROTATE
@@ -51,46 +95,38 @@ SkOpSegment* FindChase(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** startPtr,
if (done) {
continue;
}
- if (!sortable) {
- continue;
- }
// find first angle, initialize winding to computed wind sum
- const SkOpAngle* angle = segment->spanToAngle(*startPtr, *endPtr);
- if (!angle) {
+ int winding;
+ bool sortable;
+ const SkOpAngle* angle = AngleWinding(*startPtr, *endPtr, &winding, &sortable);
+ if (winding == SK_MinS32) {
continue;
}
- const SkOpAngle* firstAngle = angle;
- bool loop = false;
- int winding = SK_MinS32;
- do {
- angle = angle->next();
- if (angle == firstAngle && loop) {
- break; // if we get here, there's no winding, loop is unorderable
- }
- loop |= angle == firstAngle;
+ int sumWinding SK_INIT_TO_AVOID_WARNING;
+ if (sortable) {
segment = angle->segment();
- winding = segment->windSum(angle);
- } while (winding == SK_MinS32);
- if (winding == SK_MinS32) {
- continue;
+ sumWinding = segment->updateWindingReverse(angle);
}
- int sumWinding = segment->updateWindingReverse(angle);
SkOpSegment* first = NULL;
- firstAngle = angle;
+ const SkOpAngle* firstAngle = angle;
while ((angle = angle->next()) != firstAngle) {
segment = angle->segment();
SkOpSpanBase* start = angle->start();
SkOpSpanBase* end = angle->end();
int maxWinding;
- segment->setUpWinding(start, end, &maxWinding, &sumWinding);
+ if (sortable) {
+ segment->setUpWinding(start, end, &maxWinding, &sumWinding);
+ }
if (!segment->done(angle)) {
- if (!first) {
+ if (!first && (sortable || start->starter(end)->windSum() != SK_MinS32)) {
first = segment;
*startPtr = start;
*endPtr = end;
}
// OPTIMIZATION: should this also add to the chase?
- (void) segment->markAngle(maxWinding, sumWinding, angle);
+ if (sortable) {
+ (void) segment->markAngle(maxWinding, sumWinding, angle);
+ }
}
}
if (first) {
« no previous file with comments | « src/pathops/SkPathOpsCommon.h ('k') | src/pathops/SkPathOpsOp.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698