// winding -1 means ccw, 1 means cw
// firstFind allows coincident edges to be treated differently
Segment* findNext(SkTDArray<Span*>& chase, int winding,
- const int startIndex, const int endIndex,
- int& nextStart, int& nextEnd, int& flipped, bool firstFind
- ,bool active /* active param is debugging only */ ) {
+ const int startIndex, const int endIndex, int& nextStart,
+ int& nextEnd, int& flipped, bool firstFind, bool active) {
SkASSERT(startIndex != endIndex);
int count = fTs.count();
SkASSERT(startIndex < endIndex ? startIndex < count - 1
sortAngles(angles, sorted);
int angleCount = angles.count();
int firstIndex = findStartingEdge(sorted, startIndex, end);
-
SkASSERT(firstIndex >= 0);
+ #if DEBUG_WINDING
+ SkDebugf("%s (first) winding=%d sign=%d\n", __FUNCTION__,
+ winding, sorted[firstIndex]->sign());
+ #endif
+ bool innerSwap = false;
int startWinding = winding;
+ if (winding * sorted[firstIndex]->sign() > 0 && active) {
+ // FIXME: this means winding was computed wrong by caller ?
+ winding = 0;
+ innerSwap = true;
+ }
int nextIndex = firstIndex + 1;
int lastIndex = firstIndex != 0 ? firstIndex : angleCount;
const Angle* foundAngle = NULL;
SkASSERT(windValue > 0);
winding -= nextAngle->sign() * windValue;
#if DEBUG_WINDING
- SkDebugf("%s maxWinding=%d winding=%d\n", __FUNCTION__, maxWinding,
- winding);
+ SkDebugf("%s maxWinding=%d winding=%d sign=%d\n", __FUNCTION__,
+ maxWinding, winding, nextAngle->sign());
#endif
if (maxWinding * winding < 0) {
flipped = -flipped;
SkASSERT(nextAngle->segment() == this);
markWinding(SkMin32(nextAngle->start(), nextAngle->end()),
maxWinding);
+ #if DEBUG_WINDING
SkDebugf("%s inactive\n", __FUNCTION__);
+ #endif
return NULL;
}
if (!foundAngle) {
}
continue;
}
+ if (!maxWinding && innerSwap && !foundAngle) {
+ foundAngle = nextAngle;
+ }
if (nextSegment->done()) {
continue;
}
maxWinding = winding;
}
Span* last;
- if (foundAngle) {
+ if (foundAngle || innerSwap) {
last = nextSegment->markAndChaseWinding(nextAngle, maxWinding);
} else {
last = nextSegment->markAndChaseDone(nextAngle, maxWinding);
int otherEnd = other->nextSpan(index, step);
int min = SkMin32(index, otherEnd);
if (other->fTs[min].fWindSum != SK_MinS32) {
- SkASSERT(other->fTs[index].fWindSum == winding);
+ SkASSERT(other->fTs[min].fWindSum == winding);
return NULL;
}
Span* last = other->innerChaseWinding(index, step, winding);
SkTDArray<Span*> chaseArray;
do {
bool active = winding * spanWinding <= 0;
+ #if DEBUG_WINDING
+ if (!active) {
+ SkDebugf("%s !active winding=%d spanWinding=%d\n",
+ __FUNCTION__, winding, spanWinding);
+ }
+ #endif
const SkPoint* firstPt = NULL;
do {
SkASSERT(!current->done());
int nextStart, nextEnd, flipped = 1;
Segment* next = current->findNext(chaseArray,
- winding + spanWinding, index,
- endIndex, nextStart, nextEnd, flipped, firstTime
- , active /* active is debugging only */ );
+ winding + spanWinding, index, endIndex,
+ nextStart, nextEnd, flipped, firstTime, active);
if (!next) {
break;
}
simple.close();
}
current = findChase(chaseArray, index, endIndex);
-#if DEBUG_ACTIVE_SPANS
+ #if DEBUG_ACTIVE_SPANS
debugShowActiveSpans(contourList);
-#endif
+ #endif
if (!current) {
break;
}
// SkTSwap<int>(index, endIndex);
}
if (abs(spanWinding) > spanValue) {
- #if DEBUG_WINDING
- SkDebugf("%s abs(spanWinding) > spanValue\n", __FUNCTION__);
- #endif
winding = spanWinding;
spanWinding = spanValue * SkSign32(spanWinding);
winding -= spanWinding;
+ #if DEBUG_WINDING
+ SkDebugf("%s spanWinding=%d winding=%d\n", __FUNCTION__,
+ spanWinding, winding);
+ #endif
+ } else {
+ #if DEBUG_WINDING
+ SkDebugf("%s ->0 contourWinding=%d winding=%d\n", __FUNCTION__,
+ contourWinding, winding);
+ #endif
+ winding = 0;
}
} while (true);
} while (true);
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
</div>
+<div id="testLine36">
+ path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
+ path.addRect(6, 12, 18, 18, (SkPath::Direction) 0);
+ path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
+</div>
+
</div>
<script type="text/javascript">
var testDivs = [
+ testLine36,
testLine35,
testLine34,
testLine33,
var at_y = 13 + 0.5;
var tests = [];
+var testTitles = [];
var testIndex = 0;
var ctx;
-function parse(test) {
+function parse(test, title) {
var contours = [];
var contourStrs = test.split("path.close();");
var pattern = /-?\d+\.*\d*/g;
contours.push(verbs);
}
}
- if (contours.length > 0)
+ if (contours.length > 0) {
tests.push(contours);
+ testTitles.push(title);
+ }
}
-function parseRect(test) {
+function parseRect(test, title) {
var contours = [];
var rectStrs = test.split("path.addRect");
var pattern = /-?\d+\.*\d*/g;
verbs.push(topLeft);
contours.push(verbs);
}
- if (contours.length > 0)
+ if (contours.length > 0) {
tests.push(contours);
+ testTitles.push(title);
+ }
}
function init(test) {
ctx.fillText(label, _px + 5, _py);
}
-function draw(test, _at_x, _at_y, scale) {
+function draw(test, title, _at_x, _at_y, scale) {
+ ctx.fillStyle = "rgba(0,0,0, 0.1)";
+ ctx.font = "normal 50px Arial";
+ ctx.fillText(title, 50, 50);
+ ctx.font = "normal 10px Arial";
+
var unit = scale * ticks;
ctx.lineWidth = 1;
var i;
ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle="white";
ctx.fill();
- draw(tests[testIndex], at_x, at_y, scale);
+ draw(tests[testIndex], testTitles[testIndex], at_x, at_y, scale);
// if (insetScale != scale && mouseX != Infinity)
// drawInset();
}
function start() {
for (i = 0; i < testDivs.length; ++i) {
+ var title = testDivs[i].id.toString();
var str = testDivs[i].firstChild.data;
if (str.split("addRect").length > 1) {
- parseRect(str);
+ parseRect(str, title);
} else {
- parse(str);
+ parse(str, title);
}
}
drawTop();