aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@google.com>2017-01-23 14:38:52 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-01-23 15:31:25 +0000
commit59d5a0e3f560da40e0ae7036a01d7d58ce3718d8 (patch)
tree55a3467bdbbda58dc30eca902d20130a2a20346d
parentb07a01e6b9bd552bab12aabd48dc77a7562f4f97 (diff)
Revert "offset angle check edge in common"
This reverts commit d2eb581ebc8f8009e80cccccd74d5b341ef5bd5b. Reason for revert: broke Google3 MSAN run of dm Original change's description: > offset angle check edge in common > > When curves cross, their intersection points may be nearby, but not exactly the same. > Sort the angles formed by the crossing curves when all angles don't have the same > origin. > > This sets up the framework to solve test case that currently fail (e.g., joel6) but > does not fix all related test cases (e.g., joel9). > > All older existing test cases, including extended tests, pass. > > Rework the test framework to better report when tests expected to produce failing > results now pass. > > Add new point and vector operations to support offset angles. > > TBR=reed@google.com > BUG=skia:6041 > > Change-Id: I67c651ded0a25e99ad93d55d6a35109b3ee3698e > Reviewed-on: https://skia-review.googlesource.com/6624 > Commit-Queue: Cary Clark <caryclark@google.com> > Reviewed-by: Cary Clark <caryclark@google.com> > TBR=caryclark@google.com,reviews@skia.org # Not skipping CQ checks because original CL landed > 1 day ago. BUG=skia:6041 Change-Id: I43db0808522ac44aceeb4f70e296167ea84a3663 Reviewed-on: https://skia-review.googlesource.com/7373 Commit-Queue: Cary Clark <caryclark@google.com> Reviewed-by: Cary Clark <caryclark@google.com>
-rw-r--r--src/pathops/SkOpAngle.cpp356
-rw-r--r--src/pathops/SkOpAngle.h20
-rw-r--r--src/pathops/SkPathOpsDebug.cpp24
-rw-r--r--src/pathops/SkPathOpsDebug.h1
-rw-r--r--src/pathops/SkPathOpsPoint.h30
-rw-r--r--src/pathops/SkPathOpsTypes.h2
-rw-r--r--tests/PathOpsAngleTest.cpp61
-rw-r--r--tests/PathOpsChalkboardTest.cpp3
-rw-r--r--tests/PathOpsExtendedTest.cpp52
-rw-r--r--tests/PathOpsExtendedTest.h7
-rw-r--r--tests/PathOpsFuzz763Test.cpp3
-rw-r--r--tests/PathOpsIssue3651.cpp8
-rw-r--r--tests/PathOpsSimplifyFailTest.cpp269
-rw-r--r--tests/PathOpsSimplifyTest.cpp21
-rw-r--r--tests/skia_test.cpp7
-rw-r--r--tools/pathops_sorter.htm20
-rw-r--r--tools/pathops_visualizer.htm1545
17 files changed, 1475 insertions, 954 deletions
diff --git a/src/pathops/SkOpAngle.cpp b/src/pathops/SkOpAngle.cpp
index f41ef234d4..c07e8cc73f 100644
--- a/src/pathops/SkOpAngle.cpp
+++ b/src/pathops/SkOpAngle.cpp
@@ -62,15 +62,23 @@ bool SkOpAngle::after(SkOpAngle* test) {
SkOpAngle* lh = test;
SkOpAngle* rh = lh->fNext;
SkASSERT(lh != rh);
+ fPart.fCurve = fOriginalCurvePart;
+ lh->fPart.fCurve = lh->fOriginalCurvePart;
+ lh->fPart.fCurve.offset(lh->segment()->verb(), fPart.fCurve[0] - lh->fPart.fCurve[0]);
+ rh->fPart.fCurve = rh->fOriginalCurvePart;
+ rh->fPart.fCurve.offset(rh->segment()->verb(), fPart.fCurve[0] - rh->fPart.fCurve[0]);
+
#if DEBUG_ANGLE
SkString bugOut;
- this->debugAfter(lh, rh, &bugOut);
+ bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
+ " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
+ " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__,
+ lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd,
+ lh->fStart->t(), lh->fEnd->t(),
+ segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(),
+ rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd,
+ rh->fStart->t(), rh->fEnd->t());
SkString bugPart[3] = { lh->debugPart(), this->debugPart(), rh->debugPart() };
-#if 0 // convenient place to set a breakpoint to trace through a specific angle compare
- if (lh->debugID() == 4 && this->debugID() == 16 && rh->debugID() == 5) {
- SkDebugf("");
- }
-#endif
#endif
if (lh->fComputeSector && !lh->computeSector()) {
return COMPARE_RESULT(1, true);
@@ -82,106 +90,23 @@ bool SkOpAngle::after(SkOpAngle* test) {
return COMPARE_RESULT(3, true);
}
#if DEBUG_ANGLE // reset bugOut with computed sectors
- this->debugAfter(lh, rh, &bugOut);
+ bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
+ " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
+ " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__,
+ lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd,
+ lh->fStart->t(), lh->fEnd->t(),
+ segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(),
+ rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd,
+ rh->fStart->t(), rh->fEnd->t());
#endif
- /* If the curve pairs share a point, the computed sector is valid. Otherwise, the sectors must
- be sufficiently different that translating them won't change the sort order. For instance,
- curves with different origins may mis-sort if the computed sectors are 1 and 5.
-
- Curves with different origins have more information though -- there are more ways for their
- convex hulls not to overlap. Try to resolve different origins directly before translating
- one curve to share the opposite's origin.
- */
- bool lrOverlap, ltrOverlap;
- SkDVector lhOffset = fOriginalCurvePart[0] - lh->fOriginalCurvePart[0];
- bool lhHasOffset = lhOffset.fX || lhOffset.fY;
- SkDVector rhOffset = fOriginalCurvePart[0] - rh->fOriginalCurvePart[0];
- bool rhHasOffset = rhOffset.fX || rhOffset.fY;
- int lhStart, lhEnd, thStart, thEnd, rhStart, rhEnd;
- bool lhX0, thX0, rhX0;
- if (lhHasOffset | rhHasOffset) {
- lhX0 = lh->sectorRange(&lhStart, &lhEnd, lhHasOffset);
- thX0 = this->sectorRange(&thStart, &thEnd, false);
- rhX0 = rh->sectorRange(&rhStart, &rhEnd, rhHasOffset);
- lrOverlap = lhX0 + rhX0 + (lhStart <= rhEnd) + (rhStart <= lhEnd) >= 2;
- ltrOverlap = thX0 + lhX0 + (lhStart <= thEnd) + (thStart <= lhEnd) >= 2
- || rhX0 + thX0 + (thStart <= rhEnd) + (rhStart <= thEnd) >= 2;
- } else {
- lrOverlap = lh->fSectorMask & rh->fSectorMask;
- ltrOverlap = (lh->fSectorMask | rh->fSectorMask) & fSectorMask;
- }
- if (!lrOverlap & !ltrOverlap) { // no lh/this/rh sector overlap
- return COMPARE_RESULT(4, (lh->fSectorEnd > rh->fSectorStart)
- ^ (fSectorStart > lh->fSectorEnd) ^ (fSectorStart > rh->fSectorStart));
- }
+ bool ltrOverlap = (lh->fSectorMask | rh->fSectorMask) & fSectorMask;
+ bool lrOverlap = lh->fSectorMask & rh->fSectorMask;
int lrOrder; // set to -1 if either order works
- fPart.fCurve = fOriginalCurvePart;
- lh->fPart.fCurve = lh->fOriginalCurvePart;
- rh->fPart.fCurve = rh->fOriginalCurvePart;
- if (lhHasOffset | rhHasOffset) {
- bool lhSweepsCCW = lh->sweepsCCW();
- bool thSweepsCCW = this->sweepsCCW();
- bool rhSweepsCCW = rh->sweepsCCW();
- Turn thStartFromLhEnd = this->ccwOf(lh, lhSweepsCCW, !thSweepsCCW);
- Turn thEndFromRhStart = this->ccwOf(rh, !rhSweepsCCW, thSweepsCCW);
- if (!lrOverlap && Turn::kCcw == thStartFromLhEnd && Turn::kCw == thEndFromRhStart) {
- if (!this->sweepContains(lh) && !this->sweepContains(rh)) {
- return COMPARE_RESULT(5, true);
- }
- }
- Turn lhStartFromRhStart = lh->ccwOf(rh, !rhSweepsCCW, !lhSweepsCCW);
- Turn lhEndFromRhStart = lh->fPart.isCurve()
- ? lh->ccwOf(rh, !rhSweepsCCW, lhSweepsCCW) : lhStartFromRhStart;
- bool lhOrRhIsCurve = lh->fPart.isCurve() || rh->fPart.isCurve();
- Turn lhStartFromRhEnd;
- if (lhOrRhIsCurve) {
- if (rh->fPart.isCurve()) {
- lhStartFromRhEnd = lh->ccwOf(rh, rhSweepsCCW, !lhSweepsCCW);
- } else {
- lhStartFromRhEnd = lhStartFromRhStart;
- }
- // cancel overlap only if sweep doesn't contain other curve's sweep pts
- if (!lh->sweepContains(rh)) {
- // clear overlap if both turn in the same direction
- lrOverlap &= (int) lhStartFromRhEnd * (int) lhEndFromRhStart < 0;
- }
- } else {
- lrOverlap = false;
- }
- Turn thStartFromRhEnd SkDEBUGCODE(= Turn::kDebugUninitialized);
- Turn thEndFromLhStart SkDEBUGCODE(= Turn::kDebugUninitialized);
- if (lhOrRhIsCurve || fPart.isCurve()) {
- thStartFromRhEnd = rh->fPart.isCurve() || fPart.isCurve()
- ? this->ccwOf(rh, rhSweepsCCW, !thSweepsCCW) : thEndFromRhStart;
- thEndFromLhStart = lh->fPart.isCurve() || fPart.isCurve()
- ? this->ccwOf(lh, !lhSweepsCCW, thSweepsCCW) : thStartFromLhEnd;
- // clear overlap if both pairs turn in the same direction
- if (!this->sweepContains(lh) && !this->sweepContains(rh)) {
- ltrOverlap &= (int) thStartFromRhEnd * (int) thEndFromRhStart <= 0
- || (int) thStartFromLhEnd * (int) thEndFromLhStart <= 0;
- }
- } else {
- ltrOverlap = false;
+ if (!lrOverlap) { // no lh/rh sector overlap
+ if (!ltrOverlap) { // no lh/this/rh sector overlap
+ return COMPARE_RESULT(4, (lh->fSectorEnd > rh->fSectorStart)
+ ^ (fSectorStart > lh->fSectorEnd) ^ (fSectorStart > rh->fSectorStart));
}
- if (!lrOverlap & !ltrOverlap) {
- Turn lhFromRh = (Turn) ((int) lhEndFromRhStart | (int) lhStartFromRhStart);
- Turn thFromLh = (Turn) ((int) thEndFromLhStart | (int) thStartFromLhEnd);
- Turn thFromRh = (Turn) ((int) thEndFromRhStart | (int) thStartFromRhEnd);
- bool result = Turn::kCw == lhFromRh ?
- Turn::kCcw == thFromLh && Turn::kCw == thFromRh :
- Turn::kCcw == thFromLh || Turn::kCw == thFromRh;
- return COMPARE_RESULT(6, result);
- }
- if (lhHasOffset) {
- lh->fPart.fCurve.offset(lh->segment()->verb(), lhOffset);
- }
- if (rhHasOffset) {
- rh->fPart.fCurve.offset(rh->segment()->verb(), rhOffset);
- }
- lrOverlap = lh->fSectorMask & rh->fSectorMask;
- ltrOverlap = (lh->fSectorMask | rh->fSectorMask) & fSectorMask;
- }
- if (!lrOverlap) { // no lh/rh sector overlap, no offsets
int lrGap = (rh->fSectorStart - lh->fSectorStart + 32) & 0x1f;
/* A tiny change can move the start +/- 4. The order can only be determined if
lr gap is not 12 to 20 or -12 to -20.
@@ -197,13 +122,11 @@ bool SkOpAngle::after(SkOpAngle* test) {
} else {
lrOrder = (int) lh->orderable(rh);
if (!ltrOverlap) {
- return COMPARE_RESULT(7, !lrOrder);
+ return COMPARE_RESULT(5, !lrOrder);
}
}
int ltOrder;
- SkDEBUGCODE(bool ltOverlap = lhHasOffset || lh->fSectorMask & fSectorMask);
- SkDEBUGCODE(bool trOverlap = rhHasOffset || rh->fSectorMask & fSectorMask);
- SkASSERT(ltOverlap || trOverlap);
+ SkASSERT((lh->fSectorMask & fSectorMask) || (rh->fSectorMask & fSectorMask));
if (lh->fSectorMask & fSectorMask) {
ltOrder = (int) lh->orderable(this);
} else {
@@ -220,7 +143,7 @@ bool SkOpAngle::after(SkOpAngle* test) {
this->alignmentSameSide(lh, &ltOrder);
this->alignmentSameSide(rh, &trOrder);
if (lrOrder >= 0 && ltOrder >= 0 && trOrder >= 0) {
- return COMPARE_RESULT(8, lrOrder ? (ltOrder & trOrder) : (ltOrder | trOrder));
+ return COMPARE_RESULT(7, lrOrder ? (ltOrder & trOrder) : (ltOrder | trOrder));
}
SkASSERT(lrOrder >= 0 || ltOrder >= 0 || trOrder >= 0);
// There's not enough information to sort. Get the pairs of angles in opposite planes.
@@ -232,25 +155,25 @@ bool SkOpAngle::after(SkOpAngle* test) {
SkDEBUGCODE(bool lrOpposite = lh->oppositePlanes(rh));
bool ltOpposite = lh->oppositePlanes(this);
SkOPASSERT(lrOpposite != ltOpposite);
- return COMPARE_RESULT(9, ltOpposite);
+ return COMPARE_RESULT(8, ltOpposite);
} else if (ltOrder == 1 && trOrder == 0) {
SkASSERT(lrOrder < 0);
bool trOpposite = oppositePlanes(rh);
- return COMPARE_RESULT(10, trOpposite);
+ return COMPARE_RESULT(9, trOpposite);
} else if (lrOrder == 1 && trOrder == 1) {
SkASSERT(ltOrder < 0);
// SkDEBUGCODE(bool trOpposite = oppositePlanes(rh));
bool lrOpposite = lh->oppositePlanes(rh);
// SkASSERT(lrOpposite != trOpposite);
- return COMPARE_RESULT(11, lrOpposite);
+ return COMPARE_RESULT(10, lrOpposite);
}
if (lrOrder < 0) {
if (ltOrder < 0) {
- return COMPARE_RESULT(12, trOrder);
+ return COMPARE_RESULT(11, trOrder);
}
- return COMPARE_RESULT(13, ltOrder);
+ return COMPARE_RESULT(12, ltOrder);
}
- return COMPARE_RESULT(14, !lrOrder);
+ return COMPARE_RESULT(13, !lrOrder);
}
// given a line, see if the opposite curve's convex hull is all on one side
@@ -325,101 +248,10 @@ void SkOpAngle::alignmentSameSide(const SkOpAngle* test, int* order) const {
}
}
-static bool same_side(double cross1, double cross2) {
- return cross1 * cross2 > 0 && !roughly_zero_when_compared_to(cross1, cross2)
- && !roughly_zero_when_compared_to(cross2, cross1);
-}
-
-static double same_side_candidate(double cross1, double cross2) {
- return same_side(cross1, cross2) ? SkTAbs(cross1) > SkTAbs(cross2) ? cross1 : cross2 : 0;
-}
-
-SkOpAngle::Turn SkOpAngle::ccwOf(const SkOpAngle* rh, bool rhCW, bool thisCCW, bool recursed)
- const {
- const SkDPoint& startPt = fPart.fCurve[0];
- const SkDPoint& rhStartPt = rh->fPart.fCurve[0];
- SkDVector startOffset = rhStartPt - startPt;
- bool commonPt = 0 == startOffset.fX && 0 == startOffset.fY;
- const SkDVector& sweep = fPart.fSweep[(int) thisCCW];
- const SkDVector& rhSweep = rh->fPart.fSweep[(int) rhCW];
- const SkDVector* testV;
- SkDVector rhEndV;
- if (commonPt) {
- testV = &rhSweep;
- } else {
- rhEndV = rhSweep + startOffset;
- testV = &rhEndV;
- }
- double endCheck = sweep.crossCheck(*testV);
-#if 0 && DEBUG_ANGLE // too verbose to show on all the time
- SkDebugf("%s {{{%1.9g,%1.9g}, {%1.9g,%1.9g}}} id=1\n", __func__, rhStartPt.fX, rhStartPt.fY,
- rhStartPt.fX + rhSweep.fX, rhStartPt.fY + rhSweep.fY);
- SkDebugf("%s {{{%1.9g,%1.9g}, {%1.9g,%1.9g}}} id=2\n", __func__, startPt.fX, startPt.fY,
- startPt.fX + sweep.fX, startPt.fY + sweep.fY);
-#endif
- if (0 == endCheck) {
- if (sweep.dot(*testV) < 0) {
- return Turn::kNone; // neither clockwise nor counterclockwise
- }
- // if the pair of angles share an edge, use its other sweep to check the turn value
- if ((fPart.isCurve() || rh->fPart.isCurve())) {
- if (recursed) {
- return Turn::kNone;
- }
- return this->ccwOf(rh, !rhCW, !thisCCW, true);
- }
- }
- if (commonPt) {
- return toTurn(endCheck > 0);
- }
- double startCheck = sweep.crossCheck(startOffset);
- if ((startCheck == 0 || startOffset.lengthSquared() < FLT_EPSILON_SQUARED * 2049) &&
- (endCheck == 0 || testV->lengthSquared() < FLT_EPSILON_SQUARED * 2049)) {
- double cross = sweep.cross(rhSweep);
- if (cross != 0)
- return toTurn(cross > 0);
- }
- if (same_side(startCheck, endCheck)) {
- return toTurn(startCheck > 0);
- }
- SkDVector reverseSweep = -sweep;
- SkDVector rhReverseStartV = startOffset - sweep;
- double reverseStartCheck = reverseSweep.crossCheck(rhReverseStartV);
- SkDVector rhReverseEndV = rhReverseStartV + rhSweep;
- double reverseEndCheck = reverseSweep.crossCheck(rhReverseEndV);
- if (same_side(reverseStartCheck, reverseEndCheck)) {
- return toTurn(reverseStartCheck < 0);
- }
- double rhEndCheck = rhSweep.crossCheck(rhReverseEndV);
- double rhStartCheck = rhSweep.crossCheck(*testV);
- double endSide = same_side_candidate(rhEndCheck, rhStartCheck);
- SkDVector rhReverseSweep = -rhSweep;
- double rhReverseEndCheck = rhReverseSweep.crossCheck(rhReverseStartV);
- double rhReverseStartCheck = rhReverseSweep.crossCheck(startOffset);
- double startSide = -same_side_candidate(rhReverseEndCheck, rhReverseStartCheck);
- if (startSide || endSide) {
- return toTurn((SkTAbs(startSide) > SkTAbs(endSide) ? startSide : endSide) > 0);
- }
- // if a pair crosses only slightly, no two ends will be on the same side
- // look for the smaller ratio to guess which segment only crosses the other slightly
- double crosses[] = { endCheck, reverseStartCheck, reverseEndCheck,
- rhStartCheck, rhEndCheck, rhReverseStartCheck, rhReverseEndCheck };
- int smallest = -1;
- double smallCross = SkTAbs(startCheck);
- for (int index = 0; index < (int) SK_ARRAY_COUNT(crosses); ++index) {
- double testCross = SkTAbs(crosses[index]);
- if (smallCross > testCross) {
- smallCross = testCross;
- smallest = index;
- }
- }
- return toTurn((smallest <= 2 ? endCheck : -rhReverseEndCheck) > 0);
-}
-
-bool SkOpAngle::checkCrossesZero(int* start, int* end) const {
- *start = SkTMin(fSectorStart, fSectorEnd);
- *end = SkTMax(fSectorStart, fSectorEnd);
- bool crossesZero = *end - *start > 16;
+bool SkOpAngle::checkCrossesZero() const {
+ int start = SkTMin(fSectorStart, fSectorEnd);
+ int end = SkTMax(fSectorStart, fSectorEnd);
+ bool crossesZero = end - start > 16;
return crossesZero;
}
@@ -794,6 +626,7 @@ SkOpGlobalState* SkOpAngle::globalState() const {
return this->segment()->globalState();
}
+
// OPTIMIZE: if this loops to only one other angle, after first compare fails, insert on other side
// OPTIMIZE: return where insertion succeeded. Then, start next insertion on opposite side
bool SkOpAngle::insert(SkOpAngle* angle) {
@@ -1016,19 +849,6 @@ SkOpAngle* SkOpAngle::previous() const {
} while (true);
}
-// returns true if rounded sector range crosses zero
-bool SkOpAngle::sectorRange(int* start, int* end, bool roundOut) const {
- if (checkCrossesZero(start, end)) {
- SkTSwap(*start, *end);
- }
- // round away since the offset curves may swap order
- if (roundOut) {
- *start = (((*start + 1) & ~0x03) - 1) & 0x1f;
- *end |= 0x03;
- }
- return *end < *start;
-}
-
SkOpSegment* SkOpAngle::segment() const {
return fStart->segment();
}
@@ -1165,25 +985,23 @@ deferTilLater:
fSectorMask = 1 << fSectorStart;
return;
}
- int start, end;
- bool crossesZero = this->checkCrossesZero(&start, &end);
- bool bumpStart = (fSectorStart & 3) == 3;
- bool bumpEnd = (fSectorEnd & 3) == 3;
- if (bumpStart | bumpEnd) {
- bool curveBendsCCW = (fSectorStart == start) ^ crossesZero;
- // bump the start and end of the sector span if they are on exact compass points
- if (bumpStart) {
- fSectorStart = (fSectorStart + (curveBendsCCW ? 1 : 31)) & 0x1f;
- }
- if (bumpEnd) {
- fSectorEnd = (fSectorEnd + (curveBendsCCW ? 31 : 1)) & 0x1f;
- }
- crossesZero = this->checkCrossesZero(&start, &end);
+ bool crossesZero = this->checkCrossesZero();
+ int start = SkTMin(fSectorStart, fSectorEnd);
+ bool curveBendsCCW = (fSectorStart == start) ^ crossesZero;
+ // bump the start and end of the sector span if they are on exact compass points
+ if ((fSectorStart & 3) == 3) {
+ fSectorStart = (fSectorStart + (curveBendsCCW ? 1 : 31)) & 0x1f;
}
+ if ((fSectorEnd & 3) == 3) {
+ fSectorEnd = (fSectorEnd + (curveBendsCCW ? 31 : 1)) & 0x1f;
+ }
+ crossesZero = this->checkCrossesZero();
+ start = SkTMin(fSectorStart, fSectorEnd);
+ int end = SkTMax(fSectorStart, fSectorEnd);
if (!crossesZero) {
fSectorMask = (unsigned) -1 >> (31 - end + start) << start;
} else {
- fSectorMask = (unsigned) -1 >> (31 - start) | (unsigned) -1 << end;
+ fSectorMask = (unsigned) -1 >> (31 - start) | ((unsigned) -1 << end);
}
}
@@ -1191,70 +1009,6 @@ SkOpSpan* SkOpAngle::starter() {
return fStart->starter(fEnd);
}
-bool SkOpAngle::sweepsCCW() const {
- if (!fPart.isCurve()) {
- return false; // lines have no sweep
- }
-#if 0 && DEBUG_ANGLE // too verbose to show all the time
- SkDebugf("%s {{{0,0}, {%g,%g}}} id=1\n", __func__, fPart.fSweep[0].fX, fPart.fSweep[0].fY);
- SkDebugf("%s {{{0,0}, {%g,%g}}} id=2\n", __func__, fPart.fSweep[1].fX, fPart.fSweep[1].fY);
-#endif
- return fPart.fSweep[0].crossCheck(fPart.fSweep[1]) < 0;
-}
-
-static bool sweep_edge_contains(const SkDVector& edge, const SkDVector& v, double* direction) {
- double cross = edge.crossCheck(v);
- if (cross) {
- if (cross * *direction < 0) {
- return true;
- }
- *direction = cross;
- }
- return false;
-}
-
-static bool sweep_contains(const SkDVector sweep[2], const SkDVector& v, double* direction) {
- if (sweep_edge_contains(sweep[0], v, direction)) {
- return true;
- }
- return sweep_edge_contains(sweep[1], v, direction);
-}
-
-bool SkOpAngle::sweepContains(const SkOpAngle* rh) const {
- if (!fPart.isCurve()) {
- return false;
- }
- if (!rh->fPart.isCurve()) {
- return false;
- }
- const SkDPoint& startPt = fPart.fCurve[0];
- const SkDVector* sweep = fPart.fSweep;
- const SkDPoint& rhStartPt = rh->fPart.fCurve[0];
- double direction = 0;
- if (startPt != rhStartPt) {
- SkDVector vTest = rhStartPt - startPt;
- if (sweep_contains(sweep, vTest, &direction)) {
- return true;
- }
- for (int index = 0; index < (int) SK_ARRAY_COUNT(rh->fPart.fSweep); ++index) {
- SkDPoint sweepEnd = rhStartPt;
- sweepEnd += rh->fPart.fSweep[index];
- SkDVector vTest = sweepEnd - startPt;
- if (sweep_contains(sweep, vTest, &direction)) {
- return true;
- }
- }
- } else {
- for (int index = 0; index < (int) SK_ARRAY_COUNT(rh->fPart.fSweep); ++index) {
- const SkDVector& vTest = rh->fPart.fSweep[index];
- if (sweep_contains(sweep, vTest, &direction)) {
- return true;
- }
- }
- }
- return false;
-}
-
bool SkOpAngle::tangentsDiverge(const SkOpAngle* rh, double s0xt0) {
if (s0xt0 == 0) {
return false;
diff --git a/src/pathops/SkOpAngle.h b/src/pathops/SkOpAngle.h
index d11a1c1ee5..d8615c3229 100644
--- a/src/pathops/SkOpAngle.h
+++ b/src/pathops/SkOpAngle.h
@@ -41,12 +41,8 @@ public:
#endif
#if DEBUG_ANGLE
- void debugAfter(const SkOpAngle* lh, const SkOpAngle* rh, SkString* bugOut) const;
bool debugCheckCoincidence() const { return fCheckCoincidence; }
void debugCheckNearCoincidence() const;
-#endif
- SkDPoint* debugFirstPt() { return &fOriginalCurvePart.fLine.fPts[0]; }
-#if DEBUG_ANGLE
SkString debugPart() const;
#endif
const SkOpPtT* debugPtT(int id) const;
@@ -100,20 +96,10 @@ public:
}
private:
- enum class Turn {
-#ifdef SK_DEBUG
- kDebugUninitialized = -2,
-#endif
- kCcw = -1,
- kNone,
- kCw
- };
-
bool after(SkOpAngle* test);
void alignmentSameSide(const SkOpAngle* test, int* order) const;
int allOnOneSide(const SkOpAngle* test);
- Turn ccwOf(const SkOpAngle* rh, bool rhCW, bool thisCCW, bool recursed = false) const;
- bool checkCrossesZero(int* start, int* end) const;
+ bool checkCrossesZero() const;
bool checkParallel(SkOpAngle* );
bool computeSector();
int convexHullOverlaps(const SkOpAngle* );
@@ -126,13 +112,9 @@ private:
bool midToSide(const SkOpAngle* rh, bool* inside) const;
bool oppositePlanes(const SkOpAngle* rh) const;
bool orderable(SkOpAngle* rh); // false == this < rh ; true == this > rh
- bool sectorRange(int* start, int* end, bool roundOut) const;
void setSector();
void setSpans();
- bool sweepContains(const SkOpAngle* rh) const;
- bool sweepsCCW() const;
bool tangentsDiverge(const SkOpAngle* rh, double s0xt0);
- Turn toTurn(bool ccw) const { return ccw ? Turn::kCcw : Turn::kCw; }
SkDCurve fOriginalCurvePart; // the curve from start to end
SkDCurveSweep fPart; // the curve from start to end offset as needed
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index 6ed37dc133..45a1138488 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -18,6 +18,7 @@ bool SkPathOpsDebug::gDumpOp; // set to true to write op to file before a crash
bool SkPathOpsDebug::gVerifyOp; // set to true to compare result against regions
#endif
+bool SkPathOpsDebug::gRunFail; // set to true to check for success on tests known to fail
bool SkPathOpsDebug::gVeryVerbose; // set to true to run extensive checking tests
#undef FAIL_IF
@@ -666,6 +667,10 @@ void SkOpGlobalState::debugResetLoopCounts() {
}
#endif
+bool SkOpGlobalState::DebugRunFail() {
+ return SkPathOpsDebug::gRunFail;
+}
+
// this is const so it can be called by const methods that overwise don't alter state
#if DEBUG_VALIDATE || DEBUG_COIN
void SkOpGlobalState::debugSetPhase(const char* funcName DEBUG_COIN_DECLARE_PARAMS()) const {
@@ -1244,17 +1249,6 @@ void SkOpSegment::debugShowNewWinding(const char* fun, const SkOpSpan* span, int
This checks the distance between start points; the distance between
*/
#if DEBUG_ANGLE
-void SkOpAngle::debugAfter(const SkOpAngle* lh, const SkOpAngle* rh, SkString* bugOut) const {
- bugOut->printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
- " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g"
- " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__,
- lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSectorEnd,
- lh->fStart->t(), lh->fEnd->t(),
- segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t(), fEnd->t(),
- rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSectorEnd,
- rh->fStart->t(), rh->fEnd->t());
-}
-
void SkOpAngle::debugCheckNearCoincidence() const {
const SkOpAngle* test = this;
do {
@@ -1382,8 +1376,8 @@ void SkOpAngle::debugValidate() const {
}
next = next->fNext;
} while (next && next != first);
- SkASSERT(wind == 0);
- SkASSERT(opp == 0);
+ SkASSERT(wind == 0 || !SkPathOpsDebug::gRunFail);
+ SkASSERT(opp == 0 || !SkPathOpsDebug::gRunFail);
#endif
}
@@ -1410,8 +1404,8 @@ void SkOpAngle::debugValidateNext() const {
#ifdef SK_DEBUG
void SkCoincidentSpans::debugStartCheck(const SkOpSpanBase* outer, const SkOpSpanBase* over,
const SkOpGlobalState* debugState) const {
- SkASSERT(coinPtTEnd()->span() == over);
- SkASSERT(oppPtTEnd()->span() == outer);
+ SkASSERT(coinPtTEnd()->span() == over || !SkOpGlobalState::DebugRunFail());
+ SkASSERT(oppPtTEnd()->span() == outer || !SkOpGlobalState::DebugRunFail());
}
#endif
diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h
index 0f3fadaf14..97fa534a2a 100644
--- a/src/pathops/SkPathOpsDebug.h
+++ b/src/pathops/SkPathOpsDebug.h
@@ -374,6 +374,7 @@ public:
static void DumpGlitchType(GlitchType );
#endif
+ static bool gRunFail;
static bool gVeryVerbose;
#if DEBUG_DUMP_VERIFY
diff --git a/src/pathops/SkPathOpsPoint.h b/src/pathops/SkPathOpsPoint.h
index deadbc2aa0..f314f69d0e 100644
--- a/src/pathops/SkPathOpsPoint.h
+++ b/src/pathops/SkPathOpsPoint.h
@@ -29,29 +29,13 @@ struct SkDVector {
fY += v.fY;
}
- SkDVector operator+(const SkDVector& v) const {
- SkDVector result = *this;
- result += v;
- return result;
- }
-
// only called by nearestT, which is currently only used by testing
void operator-=(const SkDVector& v) {
fX -= v.fX;
fY -= v.fY;
}
- SkDVector operator-(const SkDVector& v) const {
- SkDVector result = *this;
- result -= v;
- return result;
- }
-
- SkDVector operator-() const {
- SkDVector result = { -fX, -fY };
- return result;
- }
-
+ // only used by testing
void operator/=(const double s) {
fX /= s;
fY /= s;
@@ -105,13 +89,6 @@ struct SkDVector {
fX *= inverseLength;
fY *= inverseLength;
}
-
- void setLengthSquared(double lenSquared) {
- double inverseLength = lenSquared / this->lengthSquared();
- fX *= inverseLength;
- fY *= inverseLength;
- }
-
};
struct SkDPoint {
@@ -150,14 +127,15 @@ struct SkDPoint {
fY -= v.fY;
}
- SkDPoint operator+(const SkDVector& v) const {
+ // only used by testing
+ SkDPoint operator+(const SkDVector& v) {
SkDPoint result = *this;
result += v;
return result;
}
// only used by testing
- SkDPoint operator-(const SkDVector& v) const {
+ SkDPoint operator-(const SkDVector& v) {
SkDPoint result = *this;
result -= v;
return result;
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
index 4e9fbe9ac5..f525ea49db 100644
--- a/src/pathops/SkPathOpsTypes.h
+++ b/src/pathops/SkPathOpsTypes.h
@@ -77,6 +77,8 @@ public:
const class SkOpPtT* debugPtT(int id) const;
#endif
+ static bool DebugRunFail();
+
#ifdef SK_DEBUG
const class SkOpSegment* debugSegment(int id) const;
bool debugSkipAssert() const { return fDebugSkipAssert; }
diff --git a/tests/PathOpsAngleTest.cpp b/tests/PathOpsAngleTest.cpp
index a598aea949..d5285c8fbc 100644
--- a/tests/PathOpsAngleTest.cpp
+++ b/tests/PathOpsAngleTest.cpp
@@ -478,67 +478,6 @@ DEF_TEST(PathOpsAngleAfter, reporter) {
}
}
-static void offset_start(SkOpAngle* angle, const SkPoint* line, bool offsetStart) {
- SkDPoint* pt = angle->debugFirstPt();
- if (!offsetStart) {
- pt->fX = pt->fY = 0;
- return;
- }
- pt->fX = line[1].fX * 0.001f;
- pt->fY = line[1].fY * 0.001f;
-}
-
-// test if offset line edges return the same results as edges without offsets
-DEF_TEST(PathOpsOffsetLineAngle, reporter) {
- static SkPoint radialLines[][2] = {
- { {0, 0}, { 2, -1} }, { {0, 0}, { 2, -2} }, { {0, 0}, { 1, -2} }, { {0, 0}, { 0, -2} },
- { {0, 0}, {-1, -2} }, { {0, 0}, {-2, -2} }, { {0, 0}, {-2, -1} }, { {0, 0}, {-2, 0} },
- { {0, 0}, {-2, 1} }, { {0, 0}, {-2, 2} }, { {0, 0}, {-1, 2} }, { {0, 0}, { 0, 2} },
- { {0, 0}, { 1, 2} }, { {0, 0}, { 2, 2} }, { {0, 0}, { 2, 1} }, { {0, 0}, { 2, 0} },
- };
- SkChunkAlloc allocator(4096);
- SkOpContourHead contour;
- SkOpGlobalState state(&contour, &allocator SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
- contour.init(&state, false, false);
- for (int lh = 0; lh < 16; ++lh) {
- for (int mid = 0; mid < 16; ++mid) {
- if (lh == mid) {
- continue;
- }
- for (int rh = 0; rh < 16; ++rh) {
- if (lh == rh || mid == rh) {
- continue;
- }
- allocator.reset();
- contour.reset();
- contour.addLine(radialLines[lh]);
- contour.addLine(radialLines[mid]);
- contour.addLine(radialLines[rh]);
- SkOpSegment* seg1 = contour.first();
- seg1->debugAddAngle(0, 1);
- SkOpSegment* seg2 = seg1->next();
- seg2->debugAddAngle(0, 1);
- SkOpSegment* seg3 = seg2->next();
- seg3->debugAddAngle(0, 1);
- SkOpAngle* angle1 = seg1->debugLastAngle();
- SkOpAngle* angle2 = seg2->debugLastAngle();
- SkOpAngle* angle3 = seg3->debugLastAngle();
- PathOpsAngleTester::SetNext(*angle1, *angle3);
- /* int expected = */ PathOpsAngleTester::After(*angle2, *angle1);
- for (int test = 1; test <= 8; ++test) {
- offset_start(angle1, radialLines[lh], test & 1);
- offset_start(angle2, radialLines[mid], test & 2);
- offset_start(angle3, radialLines[rh], test & 4);
- /* int found = */ PathOpsAngleTester::After(*angle2, *angle1);
-#if 0 // this test fails; haven't explored if this is a real bug or not
- REPORTER_ASSERT(reporter, expected == found);
-#endif
- }
- }
- }
- }
-}
-
void SkOpSegment::debugAddAngle(double startT, double endT) {
SkOpPtT* startPtT = startT == 0 ? fHead.ptT() : startT == 1 ? fTail.ptT()
: this->addT(startT);
diff --git a/tests/PathOpsChalkboardTest.cpp b/tests/PathOpsChalkboardTest.cpp
index acfa46f39b..8c74e7f98d 100644
--- a/tests/PathOpsChalkboardTest.cpp
+++ b/tests/PathOpsChalkboardTest.cpp
@@ -91,6 +91,9 @@ static void testChalkboard(PathOpsThreadState* data) {
}
static void chalkboard_threaded(skiatest::Reporter* reporter, const char* filename) {
+#if DEBUG_UNDER_DEVELOPMENT
+ return;
+#endif
initializeTests(reporter, "chalkboard");
PathOpsThreadedTestRunner testRunner(reporter);
SkRandom r;
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp
index 06fee80f5d..d70deb30fc 100644
--- a/tests/PathOpsExtendedTest.cpp
+++ b/tests/PathOpsExtendedTest.cpp
@@ -320,26 +320,21 @@ int comparePaths(skiatest::Reporter* reporter, const char* filename, const SkPat
static SkTDArray<SkPathOp> gTestOp;
-static void dumpPathOpFunction(const char* testName, const SkPath& a, const SkPath& b,
- const SkPathOp shapeOp) {
+static void showPathOpPath(const char* testName, const SkPath& one, const SkPath& two,
+ const SkPath& a, const SkPath& b, const SkPath& scaledOne, const SkPath& scaledTwo,
+ const SkPathOp shapeOp, const SkMatrix& scale) {
+ SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs));
if (!testName) {
testName = "xOp";
}
SkDebugf("static void %s_%s(skiatest::Reporter* reporter, const char* filename) {\n",
testName, opSuffixes[shapeOp]);
+ *gTestOp.append() = shapeOp;
SkDebugf(" SkPath path, pathB;\n");
SkPathOpsDebug::ShowOnePath(a, "path", false);
SkPathOpsDebug::ShowOnePath(b, "pathB", false);
SkDebugf(" testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[shapeOp]);
SkDebugf("}\n");
-}
-
-static void showPathOpPath(const char* testName, const SkPath& one, const SkPath& two,
- const SkPath& a, const SkPath& b, const SkPath& scaledOne, const SkPath& scaledTwo,
- const SkPathOp shapeOp, const SkMatrix& scale) {
- SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs));
- *gTestOp.append() = shapeOp;
- dumpPathOpFunction(testName, a, b, shapeOp);
drawAsciiPaths(scaledOne, scaledTwo, true);
}
@@ -349,15 +344,11 @@ static int comparePaths(skiatest::Reporter* reporter, const char* testName, cons
const SkPath& scaledOne, const SkPath& two, const SkPath& scaledTwo, SkBitmap& bitmap,
const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const SkMatrix& scale,
ExpectMatch expectMatch) {
- if (ExpectMatch::kFlaky == expectMatch) {
- return 0; // fuzz data may cause asserts in region generating code, so don't try
- }
int errors2x2;
const int MAX_ERRORS = 8;
(void) pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2);
if (ExpectMatch::kNo == expectMatch) {
if (errors2x2 < MAX_ERRORS) {
- SkDebugf("%s failing test %s now succeeds\n", __FUNCTION__, testName);
REPORTER_ASSERT(reporter, 0);
}
return 0;
@@ -514,11 +505,6 @@ bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path, const c
ExpectSuccess::kYes : ExpectSuccess::kNo, SkipAssert::kNo, ExpectMatch::kNo);
}
-bool testSimplifyTry(skiatest::Reporter* reporter, const SkPath& path, const char* filename) {
- return inner_simplify(reporter, path, filename, ExpectSuccess::kYes, SkipAssert::kNo,
- ExpectMatch::kNo);
-}
-
#if DEBUG_SHOW_TEST_NAME
static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) {
SkDebugf("\n");
@@ -539,23 +525,18 @@ static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
SkDEBUGPARAMS(testName))) {
if (ExpectSuccess::kYes == expectSuccess) {
SkDebugf("%s %s did not expect failure\n", __FUNCTION__, testName);
- dumpPathOpFunction(testName, a, b, shapeOp);
REPORTER_ASSERT(reporter, 0);
}
return false;
} else {
if (ExpectSuccess::kNo == expectSuccess) {
SkDebugf("%s %s unexpected success\n", __FUNCTION__, testName);
- dumpPathOpFunction(testName, a, b, shapeOp);
REPORTER_ASSERT(reporter, 0);
}
}
if (!reporter->verbose()) {
return true;
}
- if (ExpectMatch::kFlaky == expectMatch) {
- return true; // fuzzy data may assert in region construction: see bug.skia.org/6129
- }
SkPath pathOut, scaledPathOut;
SkRegion rgnA, rgnB, openClip, rgnOut;
openClip.setRect(-16000, -16000, 16000, 16000);
@@ -598,18 +579,29 @@ bool testPathOpCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath
ExpectSuccess::kYes : ExpectSuccess::kNo, SkipAssert::kNo, ExpectMatch::kNo);
}
-bool testPathOpTry(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
- const SkPathOp shapeOp, const char* testName) {
- return innerPathOp(reporter, a, b, shapeOp, testName,
- ExpectSuccess::kYes, SkipAssert::kNo, ExpectMatch::kNo);
-}
-
bool testPathOpFuzz(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
const SkPathOp shapeOp, const char* testName) {
return innerPathOp(reporter, a, b, shapeOp, testName, ExpectSuccess::kFlaky, SkipAssert::kYes,
ExpectMatch::kFlaky);
}
+bool testPathOpFail(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
+ const SkPathOp shapeOp, const char* testName) {
+#if DEBUG_SHOW_TEST_NAME
+ showName(a, b, shapeOp);
+#endif
+ SkPath orig;
+ orig.lineTo(54, 43);
+ SkPath out = orig;
+ if (Op(a, b, shapeOp, &out) ) {
+ SkDebugf("%s test is expected to fail\n", __FUNCTION__);
+ REPORTER_ASSERT(reporter, 0);
+ return false;
+ }
+ SkASSERT(out == orig);
+ return true;
+}
+
SK_DECLARE_STATIC_MUTEX(gMutex);
void initializeTests(skiatest::Reporter* reporter, const char* test) {
diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h
index 7c8ceb1529..9f8b0aeaac 100644
--- a/tests/PathOpsExtendedTest.h
+++ b/tests/PathOpsExtendedTest.h
@@ -36,18 +36,17 @@ extern bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPa
const SkPathOp , const char* testName);
extern bool testPathOpCheck(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
const SkPathOp , const char* testName, bool checkFail);
+extern bool testPathOpFail(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
+ const SkPathOp, const char* testName);
extern bool testPathOpFuzz(skiatest::Reporter* reporter, const SkPath& a,
const SkPath& b, const SkPathOp , const char* testName);
-extern bool testPathOpTry(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
- const SkPathOp , const char* testName);
extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
const char* pathStr);
extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char* filename);
extern bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path,
const char* filename, bool checkFail);
extern bool testSimplifyFuzz(skiatest::Reporter* reporter, const SkPath& path,
- const char* filename);
-extern bool testSimplifyTry(skiatest::Reporter* reporter, const SkPath& path, const char* filename);
+ const char* filename);
void initializeTests(skiatest::Reporter* reporter, const char* testName);
diff --git a/tests/PathOpsFuzz763Test.cpp b/tests/PathOpsFuzz763Test.cpp
index 996f4e70e7..90d5723774 100644
--- a/tests/PathOpsFuzz763Test.cpp
+++ b/tests/PathOpsFuzz763Test.cpp
@@ -2092,7 +2092,8 @@ path.quadTo(SkBits2Float(0x42240000), SkBits2Float(0x41ed7d86), SkBits2Float(0x4
path.close();
SkPath path2(path);
- testPathOpTry(reporter, path1, path2, (SkPathOp) 2, filename);
+ // DEBUG_UNDER_DEVELOPMENT fuzz763_1026368 disable expectation check for now
+ testPathOpCheck(reporter, path1, path2, (SkPathOp) 2, filename, !SkOpGlobalState::DebugRunFail());
}
static void fuzz763_5485218(skiatest::Reporter* reporter, const char* filename) {
diff --git a/tests/PathOpsIssue3651.cpp b/tests/PathOpsIssue3651.cpp
index dc93657d08..bd4ed2d9ab 100644
--- a/tests/PathOpsIssue3651.cpp
+++ b/tests/PathOpsIssue3651.cpp
@@ -472,7 +472,9 @@ path.close();
static void issue3651_1a(skiatest::Reporter* reporter, const char* filename) {
SkPath path = path1_a();
SkPath pathB = path2_a();
- testPathOpTry(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename);
+ // DEBUG_UNDER_DEVELOPMENT issue3651_1a disable expectation check for now
+ testPathOpCheck(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename,
+ !SkOpGlobalState::DebugRunFail());
}
static SkPath path3() {
@@ -1202,7 +1204,9 @@ path.close();
static void issue3651_1(skiatest::Reporter* reporter, const char* filename) {
SkPath path = path1();
SkPath pathB = path2();
- testPathOpTry(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename);
+ // DEBUG_UNDER_DEVELOPMENT issue3651_1 disable expectation check for now
+ testPathOpCheck(reporter, path, pathB, SkPathOp::kUnion_SkPathOp, filename,
+ !SkOpGlobalState::DebugRunFail());
}
static void issue3651_2(skiatest::Reporter* reporter, const char* filename) {
diff --git a/tests/PathOpsSimplifyFailTest.cpp b/tests/PathOpsSimplifyFailTest.cpp
index 44bb50ce94..b6f210e8ea 100644
--- a/tests/PathOpsSimplifyFailTest.cpp
+++ b/tests/PathOpsSimplifyFailTest.cpp
@@ -215,278 +215,9 @@ path.close();
testSimplifyFuzz(reporter, path, filename);
}
-static void fuzz_twister(skiatest::Reporter* reporter, const char* filename) {
- SkPath path;
- path.setFillType((SkPath::FillType) 0);
-path.moveTo(0, 600);
-path.lineTo(3.35544e+07f, 600);
-path.lineTo(3.35544e+07f, 0);
-path.lineTo(0, 0);
-path.lineTo(0, 600);
-path.close();
-path.moveTo(63, 600);
-path.lineTo(3.35545e+07f, 600);
-path.lineTo(3.35545e+07f, 0);
-path.lineTo(63, 0);
-path.lineTo(63, 600);
-path.close();
-path.moveTo(93, 600);
-path.lineTo(3.35545e+07f, 600);
-path.lineTo(3.35545e+07f, 0);
-path.lineTo(93, 0);
-path.lineTo(93, 600);
-path.close();
-path.moveTo(123, 600);
-path.lineTo(3.35546e+07f, 600);
-path.lineTo(3.35546e+07f, 0);
-path.lineTo(123, 0);
-path.lineTo(123, 600);
-path.close();
- testSimplifyFuzz(reporter, path, filename);
-}
-
-static void fuzz_twister2(skiatest::Reporter* reporter, const char* filename) {
- SkPath path;
-
-path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x44160000)); // 0, 600
-path.lineTo(SkBits2Float(0x4bfffffe), SkBits2Float(0x44160000)); // 3.35544e+07f, 600
-path.lineTo(SkBits2Float(0x4bfffffe), SkBits2Float(0x00000000)); // 3.35544e+07f, 0
-path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
-path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x44160000)); // 0, 600
-path.close();
-
-path.moveTo(SkBits2Float(0x427c0000), SkBits2Float(0x00000000)); // 63, 0
-path.lineTo(SkBits2Float(0x4c00000f), SkBits2Float(0x00000000)); // 3.35545e+07f, 0
-path.lineTo(SkBits2Float(0x4c00000f), SkBits2Float(0x00000000)); // 3.35545e+07f, 0
-path.lineTo(SkBits2Float(0x427c0000), SkBits2Float(0x00000000)); // 63, 0
-path.close();
-
-path.moveTo(SkBits2Float(0x42ba0000), SkBits2Float(0x00000000)); // 93, 0
-path.lineTo(SkBits2Float(0x4c000016), SkBits2Float(0x00000000)); // 3.35545e+07f, 0
-path.lineTo(SkBits2Float(0x4c000016), SkBits2Float(0x00000000)); // 3.35545e+07f, 0
-path.lineTo(SkBits2Float(0x42ba0000), SkBits2Float(0x00000000)); // 93, 0
-path.close();
-
-path.moveTo(SkBits2Float(0x42f60000), SkBits2Float(0x00000000)); // 123, 0
-path.lineTo(SkBits2Float(0x4c00001e), SkBits2Float(0x00000000)); // 3.35546e+07f, 0
-path.lineTo(SkBits2Float(0x4c00001e), SkBits2Float(0x00000000)); // 3.35546e+07f, 0
-path.lineTo(SkBits2Float(0x42f60000), SkBits2Float(0x00000000)); // 123, 0
-path.close();
-
- testSimplifyFuzz(reporter, path, filename);
-}
-
-static void fuzz994s_11(skiatest::Reporter* reporter, const char* filename) {
- SkPath path;
- path.setFillType((SkPath::FillType) 0);
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x42b40000)); // 110, 90
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x46ff4c00), SkBits2Float(0x41f00000)); // 32678, 30
-path.lineTo(SkBits2Float(0x46ff4c00), SkBits2Float(0x41f00000)); // 32678, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x4c000006)); // 110, 3.35545e+07f
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x439d8000)); // 10, 315
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x439d8000)); // 110, 315
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x437f0000)); // 110, 255
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x437f0000)); // 10, 255
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x439d8000)); // 10, 315
-path.close();
-path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x42700000)); // 0, 60
-path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x42700000)); // 100, 60
-path.lineTo(SkBits2Float(0x42c80000), SkBits2Float(0x00000000)); // 100, 0
-path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
-path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x42700000)); // 0, 60
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x42b40000)); // 110, 90
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x4c000006)); // 110, 3.35545e+07f
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x4c000006)); // 10, 3.35545e+07f
-path.close();
-path.moveTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x42b40000)); // 110, 90
-path.lineTo(SkBits2Float(0x42dc0000), SkBits2Float(0x41f00000)); // 110, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
-path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
-path.close();
-
- testSimplifyFuzz(reporter, path, filename);
-}
-
-static void fuzz994s_3414(skiatest::Reporter* reporter, const char* filename) {
- SkPath path;
- path.setFillType((SkPath::FillType) 0);
-path.moveTo(SkBits2Float(0x42c80000), SkBits2Float(0x42480000)); // 100, 50
-path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100, 0, 50, 0, 0.707107f
-path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0, 0, 0, 50, 0.707107f
-path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0, 100, 50, 100, 0.707107f
-path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100, 100, 100, 50, 0.707107f
-path.close();
-path.moveTo(SkBits2Float(0x42c84964), SkBits2Float(0x42480000)); // 100.143f, 50
-path.conicTo(SkBits2Float(0x42c84964), SkBits2Float(0x00000000), SkBits2Float(0x424892c8), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100.143f, 0, 50.1433f, 0, 0.707107f
-path.conicTo(SkBits2Float(0x3e12c788), SkBits2Float(0x00000000), SkBits2Float(0x3e12c788), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0.143339f, 0, 0.143339f, 50, 0.707107f
-path.conicTo(SkBits2Float(0x3e12c788), SkBits2Float(0x42c80000), SkBits2Float(0x424892c8), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0.143339f, 100, 50.1433f, 100, 0.707107f
-path.conicTo(SkBits2Float(0x42c84964), SkBits2Float(0x42c80000), SkBits2Float(0x42c84964), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100.143f, 100, 100.143f, 50, 0.707107f
-path.close();
-path.moveTo(SkBits2Float(0x42c80000), SkBits2Float(0x42480000)); // 100, 50
-path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 100, 0, 50, 0, 0.707107f
-path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 0, 0, 0, 50, 0.707107f
-path.conicTo(SkBits2Float(0x00000000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 0, 100, 50, 100, 0.707107f
-path.conicTo(SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42c80000), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 100, 100, 100, 50, 0.707107f
-path.close();
-path.moveTo(SkBits2Float(0x4c00006b), SkBits2Float(0x424c0000)); // 3.35549e+07f, 51
-path.conicTo(SkBits2Float(0x4c00006b), SkBits2Float(0xcbffffe5), SkBits2Float(0x43d6e720), SkBits2Float(0xcbffffe5), SkBits2Float(0x3f3504f3)); // 3.35549e+07f, -3.35544e+07f, 429.806f, -3.35544e+07f, 0.707107f
-path.conicTo(SkBits2Float(0xcbffff28), SkBits2Float(0xcbffffe5), SkBits2Float(0xcbffff28), SkBits2Float(0x424c0000), SkBits2Float(0x3f3504f3)); // -3.3554e+07f, -3.35544e+07f, -3.3554e+07f, 51, 0.707107f
-path.conicTo(SkBits2Float(0xcbffff28), SkBits2Float(0x4c00000c), SkBits2Float(0x43d6e720), SkBits2Float(0x4c00000c), SkBits2Float(0x3f3504f3)); // -3.3554e+07f, 3.35545e+07f, 429.806f, 3.35545e+07f, 0.707107f
-path.conicTo(SkBits2Float(0x4c00006b), SkBits2Float(0x4c00000c), SkBits2Float(0x4c00006b), SkBits2Float(0x424c0000), SkBits2Float(0x3f3504f3)); // 3.35549e+07f, 3.35545e+07f, 3.35549e+07f, 51, 0.707107f
-path.close();
-path.moveTo(SkBits2Float(0x43ef6720), SkBits2Float(0x42480000)); // 478.806f, 50
-path.conicTo(SkBits2Float(0x43ef6720), SkBits2Float(0x00000000), SkBits2Float(0x43d66720), SkBits2Float(0x00000000), SkBits2Float(0x3f3504f3)); // 478.806f, 0, 428.806f, 0, 0.707107f
-path.conicTo(SkBits2Float(0x43bd6720), SkBits2Float(0x00000000), SkBits2Float(0x43bd6720), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 378.806f, 0, 378.806f, 50, 0.707107f
-path.conicTo(SkBits2Float(0x43bd6720), SkBits2Float(0x42c80000), SkBits2Float(0x43d66720), SkBits2Float(0x42c80000), SkBits2Float(0x3f3504f3)); // 378.806f, 100, 428.806f, 100, 0.707107f
-path.conicTo(SkBits2Float(0x43ef6720), SkBits2Float(0x42c80000), SkBits2Float(0x43ef6720), SkBits2Float(0x42480000), SkBits2Float(0x3f3504f3)); // 478.806f, 100, 478.806f, 50, 0.707107f
-path.close();
-
- testSimplify(reporter, path, filename);
-}
-
-static void fuzz763_4713_b(skiatest::Reporter* reporter, const char* filename) {
- SkPath path;
- path.setFillType((SkPath::FillType) 0);
-path.moveTo(SkBits2Float(0x42240000), SkBits2Float(0x42040000));
-path.quadTo(SkBits2Float(0x42240000), SkBits2Float(0x4211413d), SkBits2Float(0x421aa09e), SkBits2Float(0x421aa09e));
-path.quadTo(SkBits2Float(0x4211413d), SkBits2Float(0x42240000), SkBits2Float(0x42040000), SkBits2Float(0x42240000));
-path.quadTo(SkBits2Float(0x41ed7d86), SkBits2Float(0x42240000), SkBits2Float(0x41dabec3), SkBits2Float(0x421aa09e));
-path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x4211413d), SkBits2Float(0x41c80000), SkBits2Float(0x42040000));
-path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x41ed7d86), SkBits2Float(0x41dabec3), SkBits2Float(0x41dabec3));
-path.quadTo(SkBits2Float(0x41ed7d86), SkBits2Float(0x41c80000), SkBits2Float(0x42040000), SkBits2Float(0x41c80000));
-path.quadTo(SkBits2Float(0x4211413d), SkBits2Float(0x41c80000), SkBits2Float(0x421aa09e), SkBits2Float(0x41dabec3));
-path.quadTo(SkBits2Float(0x42240000), SkBits2Float(0x41ed7d86), SkBits2Float(0x42240000), SkBits2Float(0x42040000));
-path.close();
-
-path.moveTo(SkBits2Float(0x4204f72e), SkBits2Float(0x41c56cd2));
-path.quadTo(SkBits2Float(0x42123842), SkBits2Float(0x41c52adf), SkBits2Float(0x421baed7), SkBits2Float(0x41d7bac6));
-path.quadTo(SkBits2Float(0x4225256d), SkBits2Float(0x41ea4aad), SkBits2Float(0x42254667), SkBits2Float(0x4202666b));
-path.quadTo(SkBits2Float(0x42256760), SkBits2Float(0x420fa77f), SkBits2Float(0x421c1f6c), SkBits2Float(0x42191e14));
-path.quadTo(SkBits2Float(0x421bff97), SkBits2Float(0x42193e89), SkBits2Float(0x421bdf6b), SkBits2Float(0x42195eb8));
-path.quadTo(SkBits2Float(0x421bbff6), SkBits2Float(0x42197f32), SkBits2Float(0x421ba03b), SkBits2Float(0x42199f57));
-path.quadTo(SkBits2Float(0x421b605e), SkBits2Float(0x4219e00a), SkBits2Float(0x421b1fa8), SkBits2Float(0x421a1f22));
-path.quadTo(SkBits2Float(0x421ae0f1), SkBits2Float(0x421a604b), SkBits2Float(0x421aa09e), SkBits2Float(0x421aa09e));
-path.quadTo(SkBits2Float(0x4211413d), SkBits2Float(0x42240000), SkBits2Float(0x42040000), SkBits2Float(0x42240000));
-path.quadTo(SkBits2Float(0x41ed7d86), SkBits2Float(0x42240000), SkBits2Float(0x41dabec3), SkBits2Float(0x421aa09e));
-path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x4211413d), SkBits2Float(0x41c80000), SkBits2Float(0x42040000));
-path.quadTo(SkBits2Float(0x41c80000), SkBits2Float(0x41ed7d86), SkBits2Float(0x41dabec3), SkBits2Float(0x41dabec3));
-path.quadTo(SkBits2Float(0x41db19b1), SkBits2Float(0x41da63d5), SkBits2Float(0x41db755b), SkBits2Float(0x41da0a9b));
-path.quadTo(SkBits2Float(0x41dbce01), SkBits2Float(0x41d9ae59), SkBits2Float(0x41dc285e), SkBits2Float(0x41d952ce));
-path.quadTo(SkBits2Float(0x41dc55b6), SkBits2Float(0x41d924df), SkBits2Float(0x41dc82cd), SkBits2Float(0x41d8f7cd));
-path.quadTo(SkBits2Float(0x41dcaf1e), SkBits2Float(0x41d8ca01), SkBits2Float(0x41dcdc4c), SkBits2Float(0x41d89bf0));
-path.quadTo(SkBits2Float(0x41ef6c33), SkBits2Float(0x41c5aec5), SkBits2Float(0x4204f72e), SkBits2Float(0x41c56cd2));
-path.close();
-testSimplify(reporter, path, filename);
-}
-
-static void fuzz864a(skiatest::Reporter* reporter,const char* filename) {
- SkPath path;
- path.moveTo(10, 90);
- path.lineTo(10, 90);
- path.lineTo(10, 30);
- path.lineTo(10, 30);
- path.lineTo(10, 90);
- path.close();
- path.moveTo(10, 90);
- path.lineTo(10, 90);
- path.lineTo(10, 30);
- path.lineTo(10, 30);
- path.lineTo(10, 90);
- path.close();
- path.moveTo(10, 90);
- path.lineTo(110, 90);
- path.lineTo(110, 30);
- path.lineTo(10, 30);
- path.lineTo(10, 90);
- path.close();
- path.moveTo(10, 30);
- path.lineTo(32678, 30);
- path.lineTo(32678, 30);
- path.lineTo(10, 30);
- path.close();
- path.moveTo(10, 3.35545e+07f);
- path.lineTo(110, 3.35545e+07f);
- path.lineTo(110, 30);
- path.lineTo(10, 30);
- path.lineTo(10, 3.35545e+07f);
- path.close();
- path.moveTo(10, 315);
- path.lineTo(110, 315);
- path.lineTo(110, 255);
- path.lineTo(10, 255);
- path.lineTo(10, 315);
- path.close();
- path.moveTo(0, 60);
- path.lineTo(100, 60);
- path.lineTo(100, 0);
- path.lineTo(0, 0);
- path.lineTo(0, 60);
- path.close();
- path.moveTo(10, 90);
- path.lineTo(110, 90);
- path.lineTo(110, 30);
- path.lineTo(10, 30);
- path.lineTo(10, 90);
- path.close();
- path.moveTo(10, 3.35545e+07f);
- path.lineTo(110, 3.35545e+07f);
- path.lineTo(110, 30);
- path.lineTo(10, 30);
- path.lineTo(10, 3.35545e+07f);
- path.close();
- path.moveTo(10, 90);
- path.lineTo(110, 90);
- path.lineTo(110, 30);
- path.lineTo(10, 30);
- path.lineTo(10, 90);
- path.close();
- testSimplifyFuzz(reporter, path, filename);
-}
-
#define TEST(test) test(reporter, #test)
DEF_TEST(PathOpsSimplifyFail, reporter) {
- TEST(fuzz864a);
- TEST(fuzz763_4713_b);
- TEST(fuzz994s_3414);
- TEST(fuzz994s_11);
- TEST(fuzz_twister2);
- TEST(fuzz_twister);
TEST(fuzz763_2);
TEST(fuzz763_1);
TEST(fuzz_x2);
diff --git a/tests/PathOpsSimplifyTest.cpp b/tests/PathOpsSimplifyTest.cpp
index 7daa5e0d5f..2de67ff22f 100644
--- a/tests/PathOpsSimplifyTest.cpp
+++ b/tests/PathOpsSimplifyTest.cpp
@@ -4871,7 +4871,7 @@ static void fuzz864a(skiatest::Reporter* reporter,const char* filename) {
path.lineTo(10, 30);
path.lineTo(10, 90);
path.close();
- testSimplifyFuzz(reporter, path, filename);
+ testSimplify(reporter, path, filename);
}
static void cr514118(skiatest::Reporter* reporter,const char* filename) {
@@ -4954,7 +4954,7 @@ path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x41f00000)); // 10, 30
path.lineTo(SkBits2Float(0x41200000), SkBits2Float(0x42b40000)); // 10, 90
path.close();
- testSimplifyFuzz(reporter, path, filename);
+ testSimplify(reporter, path, filename);
}
static void fuzz994s_3414(skiatest::Reporter* reporter, const char* filename) {
@@ -5021,7 +5021,7 @@ path.lineTo(3.35546e+07f, 0);
path.lineTo(123, 0);
path.lineTo(123, 600);
path.close();
- testSimplifyFuzz(reporter, path, filename);
+ testSimplify(reporter, path, filename);
}
static void fuzz_twister2(skiatest::Reporter* reporter, const char* filename) {
@@ -6919,6 +6919,8 @@ testSimplify(reporter, path, filename);
}
static void joel_9(skiatest::Reporter* reporter, const char* filename) {
+#if DEBUG_UNDER_DEVELOPMENT
+// fails with image mismatch
SkPath path;
path.moveTo(SkBits2Float(0x4310dbe7), SkBits2Float(0x438e9604)); // 144.859f, 285.172f
path.lineTo(SkBits2Float(0x4310dbe7), SkBits2Float(0x438e9604)); // 144.859f, 285.172f
@@ -6971,10 +6973,13 @@ path.lineTo(SkBits2Float(0x430bbdf4), SkBits2Float(0x43898f1a)); // 139.742f, 2
path.cubicTo(SkBits2Float(0x430fefe0), SkBits2Float(0x438a3f1a), SkBits2Float(0x43123811), SkBits2Float(0x438c7d0e), SkBits2Float(0x4310dbe8), SkBits2Float(0x438e9624)); // 143.937f, 276.493f, 146.219f, 280.977f, 144.859f, 285.173f
path.lineTo(SkBits2Float(0x430d67f0), SkBits2Float(0x438e070a)); // 141.406f, 284.055f
path.close();
-testSimplifyTry(reporter, path, filename);
+testSimplify(reporter, path, filename);
+#endif
}
static void joel_10(skiatest::Reporter* reporter, const char* filename) {
+#if DEBUG_UNDER_DEVELOPMENT
+// fails with image mismatch
SkPath path;
path.moveTo(SkBits2Float(0x440fc979), SkBits2Float(0x43d88000)); // 575.148f, 433
path.lineTo(SkBits2Float(0x440fc979), SkBits2Float(0x43d88000)); // 575.148f, 433
@@ -7027,11 +7032,12 @@ path.lineTo(SkBits2Float(0x44111106), SkBits2Float(0x43dd86ea)); // 580.266f, 4
path.cubicTo(SkBits2Float(0x4410048b), SkBits2Float(0x43dcd7f0), SkBits2Float(0x440f720c), SkBits2Float(0x43da99dc), SkBits2Float(0x440fc989), SkBits2Float(0x43d87fe0)); // 576.071f, 441.687f, 573.782f, 437.202f, 575.149f, 432.999f
path.lineTo(SkBits2Float(0x4410a687), SkBits2Float(0x43d91000)); // 578.602f, 434.125f
path.close();
-// DEBUG_UNDER_DEVELOPMENT fails with angle instability
-testSimplifyFuzz(reporter, path, filename);
+testSimplify(reporter, path, filename);
+#endif
}
static void joel_11(skiatest::Reporter* reporter, const char* filename) {
+#if DEBUG_UNDER_DEVELOPMENT
// fails with image mismatch
SkPath path;
path.moveTo(SkBits2Float(0x43c9d000), SkBits2Float(0x4411977d)); // 403.625f, 582.367f
@@ -7086,7 +7092,8 @@ path.lineTo(SkBits2Float(0x43c6bd0e), SkBits2Float(0x4413f591)); // 397.477f, 5
path.cubicTo(SkBits2Float(0x43c64810), SkBits2Float(0x4412e116), SkBits2Float(0x43c7a70a), SkBits2Float(0x4411d28f), SkBits2Float(0x43c9d000), SkBits2Float(0x4411978d)); // 396.563f, 587.517f, 399.305f, 583.29f, 403.625f, 582.368f
path.lineTo(SkBits2Float(0x43ca3106), SkBits2Float(0x44127b02)); // 404.383f, 585.922f
path.close();
-testSimplifyFuzz(reporter, path, filename);
+testSimplify(reporter, path, filename);
+#endif
}
static void make_joel_12(SkPath& path) {
diff --git a/tests/skia_test.cpp b/tests/skia_test.cpp
index 969c1ff54a..4cb55d0853 100644
--- a/tests/skia_test.cpp
+++ b/tests/skia_test.cpp
@@ -29,6 +29,7 @@ using namespace sk_gpu_test;
DEFINE_bool2(dumpOp, d, false, "dump the pathOps to a file to recover mid-crash.");
DEFINE_bool2(extendedTest, x, false, "run extended tests for pathOps.");
+DEFINE_bool2(runFail, f, false, "check for success on tests known to fail.");
DEFINE_bool2(verifyOp, y, false, "compare the pathOps result against a region.");
#if DEBUG_COIN
@@ -140,6 +141,7 @@ int test_main() {
SkPathOpsDebug::gDumpOp = FLAGS_dumpOp;
SkPathOpsDebug::gVerifyOp = FLAGS_verifyOp;
#endif
+ SkPathOpsDebug::gRunFail = FLAGS_runFail;
SkPathOpsDebug::gVeryVerbose = FLAGS_veryVerbose;
SetupCrashHandler();
@@ -169,6 +171,11 @@ int test_main() {
if (FLAGS_dumpOp) {
header.appendf(" -d");
}
+#ifdef SK_DEBUG
+ if (FLAGS_runFail) {
+ header.appendf(" -f");
+ }
+#endif
if (FLAGS_verbose) {
header.appendf(" -v");
}
diff --git a/tools/pathops_sorter.htm b/tools/pathops_sorter.htm
index e31a196975..967ac316eb 100644
--- a/tools/pathops_sorter.htm
+++ b/tools/pathops_sorter.htm
@@ -6,16 +6,28 @@
<title></title>
<div style="height:0">
-<div id="halfplane">
-ccwOf {{{380.294464,140.44487}, {379.597463,140.82048}}} id=1
-ccwOf {{{380.294495,140.444855}, {378.965302,141.103577}}} id=2
+<div id="cubics">
+{{{403.28299,497.196991}, {403.424011,497.243988}, {391.110992,495.556}, {391.110992,495.556}}}
+{{{398.375,501.976013}, {403.28299,497.196991}}}
+{{{403.42401123046875, 497.243988037109375}, {378.7979736328125, 493.868011474609375}}}, id=0
+{{{415.5605946972181641, 498.8838844379989155}, {378.8318672594865006, 493.8897667505245295}}}, id=1
+{{{403.2954048004600622, 497.117149457477467}, {403.2729768294798873, 497.2781265045034615}}}, id=2
+{{{403.42401123046875, 497.243988037109375}, {378.7979736328125, 493.868011474609375}}}, id=3
+
+</div>
+
+<div id="c1">
+{{{403.28299f, 497.196991f}, {403.284241f, 497.197388f}, {403.28418f, 497.197632f}}}
+{{{403.28418f, 497.197632f}, {403.280487f, 497.224304f}, {391.110992f, 495.556f}, {391.110992f, 495.556f}}}
+
</div>
</div>
<script type="text/javascript">
var testDivs = [
- halfplane,
+ c1,
+ cubics,
];
var decimal_places = 3;
diff --git a/tools/pathops_visualizer.htm b/tools/pathops_visualizer.htm
index 5acbeb136e..1844dfd3ad 100644
--- a/tools/pathops_visualizer.htm
+++ b/tools/pathops_visualizer.htm
@@ -1,9 +1,779 @@
<html>
<head>
-<div height="0" hidden="true">
-
-Skia UnitTests: --match Simplify$ --resourcePath resources\ -v -V SK_DEBUG
+<div height="0" hidden="true">
+<div id="joel_11">
+SkDCubic::ComplexBreak
+{{{407.66400146484375, 586.52301025390625}, {406.718994140625, 585.91400146484375}, {405.56201171875, 585.6710205078125}, {404.38299560546875, 585.9210205078125}}},
+maxCurvature[0]=0.210691815 {{{410.1179280337341311, 587.5354084049533867}, {403.9625372513739308, 584.8405979797089458}}},
+SkDCubic::ComplexBreak
+{{{403.625, 582.36602783203125}, {407.9530029296875, 581.4520263671875}, {412.17999267578125, 584.2020263671875}, {413.10198974609375, 588.5140380859375}}},
+maxCurvature[0]=0.505742375 {{{399.4806060513494685, 576.7555289603596975}, {419.9185900147107304, 590.2821868178559725}}},
+SkDCubic::ComplexBreak
+{{{408.92901611328125, 592.5469970703125}, {409.53802490234375, 591.60198974609375}, {409.78802490234375, 590.4530029296875}, {409.53802490234375, 589.27398681640625}}},
+maxCurvature[0]=0.2464997 {{{408.0414711863251682, 594.9185862710903621}, {410.5821756824746558, 588.7085892000006879}}},
+SkDCubic::ComplexBreak
+{{{413.10003662109375, 588.5159912109375}, {414.00604248046875, 592.83599853515625}, {411.27203369140625, 597.06298828125}, {406.94403076171875, 597.9849853515625}}},
+maxCurvature[0]=0.50027635 {{{418.6547935965468241, 584.2584103487866969}, {405.3110940414140941, 604.7967504597730795}}},
+SkDCubic::ComplexBreak
+{{{402.91400146484375, 593.82000732421875}, {403.8590087890625, 594.42901611328125}, {405.0159912109375, 594.67901611328125}, {406.19500732421875, 594.42901611328125}}},
+maxCurvature[0]=0.20172566 {{{400.4418179242405245, 592.7682938621098856}, {406.5786156780874876, 595.518866839962584}}},
+SkDCubic::ComplexBreak
+{{{406.94500732421875, 597.9840087890625}, {402.625, 598.89801025390625}, {398.39801025390625, 596.156005859375}, {397.47601318359375, 591.83599853515625}}},
+maxCurvature[0]=0.500281451 {{{411.2024837739085115, 603.5428096059653171}, {390.6642477196397749, 590.1989499052259589}}},
+SkDCubic::ComplexBreak
+{{{401.6409912109375, 587.81298828125}, {401.031982421875, 588.7509765625}, {400.781982421875, 589.89898681640625}, {401.031982421875, 591.0789794921875}}},
+maxCurvature[0]=0.208772223 {{{402.6666692341399312, 585.3725424991555428}, {399.9489005783761968, 591.4800732145131406}}},
+SkDCubic::ComplexBreak
+{{{397.47698974609375, 591.83697509765625}, {396.56298828125, 587.5169677734375}, {399.30499267578125, 583.28997802734375}, {403.625, 582.36798095703125}}},
+maxCurvature[0]=0.500281451 {{{391.9181889291909329, 596.0944515473461252}, {405.2620486299302911, 575.5562154930773886}}},
+<empty>
+<empty>
+seg=1 {{{409.539001f, 589.27301f}, {409.296997f, 588.085022f}, {408.593994f, 587.140015f}, {407.664001f, 586.52301f}}}
+seg=2 {{{407.664001f, 586.52301f}, {406.718994f, 585.914001f}, {405.562012f, 585.671021f}, {404.382996f, 585.921021f}}}
+seg=3 {{{404.382996f, 585.921021f}, {403.625f, 582.366028f}}}
+seg=4 {{{403.625f, 582.366028f}, {407.953003f, 581.452026f}, {412.179993f, 584.202026f}, {413.10199f, 588.514038f}}}
+seg=5 {{{413.10199f, 588.514038f}, {409.539001f, 589.27301f}}}
+<empty>
+seg=6 {{{406.195007f, 594.429993f}, {407.375f, 594.179993f}, {408.320007f, 593.484985f}, {408.929016f, 592.546997f}}}
+seg=7 {{{408.929016f, 592.546997f}, {409.538025f, 591.60199f}, {409.788025f, 590.453003f}, {409.538025f, 589.273987f}}}
+seg=8 {{{409.538025f, 589.273987f}, {413.100037f, 588.515991f}}}
+seg=9 {{{413.100037f, 588.515991f}, {414.006042f, 592.835999f}, {411.272034f, 597.062988f}, {406.944031f, 597.984985f}}}
+seg=10 {{{406.944031f, 597.984985f}, {406.195007f, 594.429993f}}}
+<empty>
+seg=11 {{{401.031006f, 591.078003f}, {401.289001f, 592.257996f}, {401.984009f, 593.210999f}, {402.914001f, 593.820007f}}}
+seg=12 {{{402.914001f, 593.820007f}, {403.859009f, 594.429016f}, {405.015991f, 594.679016f}, {406.195007f, 594.429016f}}}
+seg=13 {{{406.195007f, 594.429016f}, {406.945007f, 597.984009f}}}
+seg=14 {{{406.945007f, 597.984009f}, {402.625f, 598.89801f}, {398.39801f, 596.156006f}, {397.476013f, 591.835999f}}}
+seg=15 {{{397.476013f, 591.835999f}, {401.031006f, 591.078003f}}}
+seg=16 {{{404.382996f, 585.921997f}, {403.203003f, 586.171997f}, {402.25f, 586.867004f}, {401.640991f, 587.812988f}}}
+seg=17 {{{401.640991f, 587.812988f}, {401.031982f, 588.750977f}, {400.781982f, 589.898987f}, {401.031982f, 591.078979f}}}
+seg=18 {{{401.031982f, 591.078979f}, {397.47699f, 591.836975f}}}
+seg=19 {{{397.47699f, 591.836975f}, {396.562988f, 587.516968f}, {399.304993f, 583.289978f}, {403.625f, 582.367981f}}}
+seg=20 {{{403.625f, 582.367981f}, {404.382996f, 585.921997f}}}
+debugShowCubicIntersection wtTs[0]=1 {{{409.539001,589.27301}, {409.296997,588.085022}, {408.593994,587.140015}, {407.664001,586.52301}}} {{407.664001,586.52301}} wnTs[0]=0 {{{407.664001,586.52301}, {406.718994,585.914001}, {405.562012,585.671021}, {404.382996,585.921021}}}
+debugShowCubicIntersection no intersect {{{409.539001,589.27301}, {409.296997,588.085022}, {408.593994,587.140015}, {407.664001,586.52301}}} {{{403.625,582.366028}, {407.953003,581.452026}, {412.179993,584.202026}, {413.10199,588.514038}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{409.539001,589.27301}, {409.296997,588.085022}, {408.593994,587.140015}, {407.664001,586.52301}}} {{409.539001,589.27301}} wnTs[0]=1 {{{413.10199,588.514038}, {409.539001,589.27301}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{407.664001,586.52301}, {406.718994,585.914001}, {405.562012,585.671021}, {404.382996,585.921021}}} {{404.382996,585.921021}} wnTs[0]=0 {{{404.382996,585.921021}, {403.625,582.366028}}}
+debugShowCubicIntersection no intersect {{{407.664001,586.52301}, {406.718994,585.914001}, {405.562012,585.671021}, {404.382996,585.921021}}} {{{403.625,582.366028}, {407.953003,581.452026}, {412.179993,584.202026}, {413.10199,588.514038}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{403.625,582.366028}, {407.953003,581.452026}, {412.179993,584.202026}, {413.10199,588.514038}}} {{403.625,582.366028}} wnTs[0]=1 {{{404.382996,585.921021}, {403.625,582.366028}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{403.625,582.366028}, {407.953003,581.452026}, {412.179993,584.202026}, {413.10199,588.514038}}} {{413.10199,588.514038}} wnTs[0]=0 {{{413.10199,588.514038}, {409.539001,589.27301}}}
+debugShowCubicIntersection no intersect {{{407.664001,586.52301}, {406.718994,585.914001}, {405.562012,585.671021}, {404.382996,585.921021}}} {{{404.382996,585.921997}, {403.203003,586.171997}, {402.25,586.867004}, {401.640991,587.812988}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{407.664001,586.52301}, {406.718994,585.914001}, {405.562012,585.671021}, {404.382996,585.921021}}} {{404.382996,585.921021}} wnTs[0]=0.999737 {{{403.625,582.367981}, {404.382996,585.921997}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}} {{403.625,582.367981}} wnTs[0]=0.999474 {{{404.382996,585.921021}, {403.625,582.366028}}}
+SkOpSegment::addT insert t=0.999474488 segID=3 spanID=41
+debugShowLineIntersection wtTs[0]=0 {{{404.382996,585.921021}, {403.625,582.366028}}} {{404.382996,585.921021}} wtTs[1]=0.999474488 {{403.625,582.367981}} wnTs[0]=0.999737 {{{403.625,582.367981}, {404.382996,585.921997}}} wnTs[1]=0
+debugShowCubicIntersection no intersect {{{403.625,582.366028}, {407.953003,581.452026}, {412.179993,584.202026}, {413.10199,588.514038}}} {{{404.382996,585.921997}, {403.203003,586.171997}, {402.25,586.867004}, {401.640991,587.812988}}}
+debugShowCubicIntersection no intersect {{{403.625,582.366028}, {407.953003,581.452026}, {412.179993,584.202026}, {413.10199,588.514038}}} {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}}
+debugShowCubicLineIntersection no intersect {{{403.625,582.366028}, {407.953003,581.452026}, {412.179993,584.202026}, {413.10199,588.514038}}} {{{403.625,582.367981}, {404.382996,585.921997}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{409.539001,589.27301}, {409.296997,588.085022}, {408.593994,587.140015}, {407.664001,586.52301}}} {{409.539001,589.27301}} wnTs[0]=0.000318097 {{{409.538025,589.273987}, {413.100037,588.515991}}}
+SkOpSegment::addT insert t=0.000318097039 segID=8 spanID=42
+debugShowCubicIntersection no intersect {{{409.539001,589.27301}, {409.296997,588.085022}, {408.593994,587.140015}, {407.664001,586.52301}}} {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}}
+debugShowLineIntersection wtTs[0]=1 {{{413.10199,588.514038}, {409.539001,589.27301}}} {{409.539001,589.27301}} wnTs[0]=0.000318097 {{{409.538025,589.273987}, {413.100037,588.515991}}}
+debugShowCubicLineIntersection no intersect {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}} {{{413.10199,588.514038}, {409.539001,589.27301}}}
+debugShowCubicIntersection wtTs[0]=1 {{{404.382996,585.921997}, {403.203003,586.171997}, {402.25,586.867004}, {401.640991,587.812988}}} {{401.640991,587.812988}} wnTs[0]=0 {{{401.640991,587.812988}, {401.031982,588.750977}, {400.781982,589.898987}, {401.031982,591.078979}}}
+debugShowCubicIntersection no intersect {{{404.382996,585.921997}, {403.203003,586.171997}, {402.25,586.867004}, {401.640991,587.812988}}} {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{404.382996,585.921997}, {403.203003,586.171997}, {402.25,586.867004}, {401.640991,587.812988}}} {{404.382996,585.921997}} wnTs[0]=1 {{{403.625,582.367981}, {404.382996,585.921997}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{401.640991,587.812988}, {401.031982,588.750977}, {400.781982,589.898987}, {401.031982,591.078979}}} {{401.031982,591.078979}} wnTs[0]=0 {{{401.031982,591.078979}, {397.47699,591.836975}}}
+debugShowCubicIntersection no intersect {{{401.640991,587.812988}, {401.031982,588.750977}, {400.781982,589.898987}, {401.031982,591.078979}}} {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}} {{397.47699,591.836975}} wnTs[0]=1 {{{401.031982,591.078979}, {397.47699,591.836975}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}} {{403.625,582.367981}} wnTs[0]=0 {{{403.625,582.367981}, {404.382996,585.921997}}}
+debugShowCubicIntersection no intersect {{{401.640991,587.812988}, {401.031982,588.750977}, {400.781982,589.898987}, {401.031982,591.078979}}} {{{401.031006,591.078003}, {401.289001,592.257996}, {401.984009,593.210999}, {402.914001,593.820007}}}
+debugShowCubicLineIntersection no intersect {{{401.640991,587.812988}, {401.031982,588.750977}, {400.781982,589.898987}, {401.031982,591.078979}}} {{{397.476013,591.835999}, {401.031006,591.078003}}}
+debugShowCubicLineIntersection wtTs[0]=0.000319790508 {{{401.031006,591.078003}, {401.289001,592.257996}, {401.984009,593.210999}, {402.914001,593.820007}}} {{401.03125,591.079163}} wnTs[0]=0.00020504 {{{401.031982,591.078979}, {397.47699,591.836975}}}
+SkOpSegment::addT insert t=0.000319790508 segID=11 spanID=43
+debugShowCubicLineIntersection no intersect {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}} {{{401.031982,591.078979}, {397.47699,591.836975}}}
+debugShowLineIntersection no intersect {{{401.031982,591.078979}, {397.47699,591.836975}}} {{{397.476013,591.835999}, {401.031006,591.078003}}}
+debugShowCubicIntersection no intersect {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}} {{{401.031006,591.078003}, {401.289001,592.257996}, {401.984009,593.210999}, {402.914001,593.820007}}}
+debugShowCubicIntersection no intersect {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}} {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}}
+debugShowCubicLineIntersection wtTs[0]=8.74738929e-05 {{{397.47699,591.836975}, {396.562988,587.516968}, {399.304993,583.289978}, {403.625,582.367981}}} {{397.476746,591.835815}} wnTs[0]=0.000207256 {{{397.476013,591.835999}, {401.031006,591.078003}}}
+SkOpSegment::addT insert t=8.74738929e-05 segID=19 spanID=44
+debugShowCubicIntersection wtTs[0]=1 {{{406.195007,594.429993}, {407.375,594.179993}, {408.320007,593.484985}, {408.929016,592.546997}}} {{408.929016,592.546997}} wnTs[0]=0 {{{408.929016,592.546997}, {409.538025,591.60199}, {409.788025,590.453003}, {409.538025,589.273987}}}
+debugShowCubicIntersection no intersect {{{406.195007,594.429993}, {407.375,594.179993}, {408.320007,593.484985}, {408.929016,592.546997}}} {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{406.195007,594.429993}, {407.375,594.179993}, {408.320007,593.484985}, {408.929016,592.546997}}} {{406.195007,594.429993}} wnTs[0]=1 {{{406.944031,597.984985}, {406.195007,594.429993}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{408.929016,592.546997}, {409.538025,591.60199}, {409.788025,590.453003}, {409.538025,589.273987}}} {{409.538025,589.273987}} wnTs[0]=0 {{{409.538025,589.273987}, {413.100037,588.515991}}}
+debugShowCubicIntersection no intersect {{{408.929016,592.546997}, {409.538025,591.60199}, {409.788025,590.453003}, {409.538025,589.273987}}} {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}} {{413.100037,588.515991}} wnTs[0]=1 {{{409.538025,589.273987}, {413.100037,588.515991}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}} {{406.944031,597.984985}} wnTs[0]=0 {{{406.944031,597.984985}, {406.195007,594.429993}}}
+debugShowCubicIntersection no intersect {{{406.195007,594.429993}, {407.375,594.179993}, {408.320007,593.484985}, {408.929016,592.546997}}} {{{402.914001,593.820007}, {403.859009,594.429016}, {405.015991,594.679016}, {406.195007,594.429016}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{406.195007,594.429993}, {407.375,594.179993}, {408.320007,593.484985}, {408.929016,592.546997}}} {{406.195007,594.429993}} wtTs[1]=5.57101392e-05 {{406.19519,594.429932}} wnTs[0]=0.000262996 {{{406.195007,594.429016}, {406.945007,597.984009}}} wnTs[1]=0.000262947308
+debugShowCubicIntersection no intersect {{{406.195007,594.429993}, {407.375,594.179993}, {408.320007,593.484985}, {408.929016,592.546997}}} {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}}
+debugShowCubicLineIntersection no intersect {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}} {{{406.195007,594.429016}, {406.945007,597.984009}}}
+debugShowCubicIntersection no intersect {{{413.100037,588.515991}, {414.006042,592.835999}, {411.272034,597.062988}, {406.944031,597.984985}}} {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}}
+debugShowCubicLineIntersection no intersect {{{402.914001,593.820007}, {403.859009,594.429016}, {405.015991,594.679016}, {406.195007,594.429016}}} {{{406.944031,597.984985}, {406.195007,594.429993}}}
+debugShowLineIntersection wtTs[0]=1 {{{406.944031,597.984985}, {406.195007,594.429993}}} {{406.195007,594.429993}} wnTs[0]=0.000262996 {{{406.195007,594.429016}, {406.945007,597.984009}}}
+debugShowCubicLineIntersection wtTs[0]=8.73365293e-05 {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}} {{406.943878,597.984253}} wnTs[0]=0.000207362 {{{406.944031,597.984985}, {406.195007,594.429993}}}
+SkOpSegment::addT insert t=8.73365293e-05 segID=14 spanID=45
+debugShowCubicIntersection wtTs[0]=1 {{{401.031006,591.078003}, {401.289001,592.257996}, {401.984009,593.210999}, {402.914001,593.820007}}} {{402.914001,593.820007}} wnTs[0]=0 {{{402.914001,593.820007}, {403.859009,594.429016}, {405.015991,594.679016}, {406.195007,594.429016}}}
+debugShowCubicIntersection no intersect {{{401.031006,591.078003}, {401.289001,592.257996}, {401.984009,593.210999}, {402.914001,593.820007}}} {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{401.031006,591.078003}, {401.289001,592.257996}, {401.984009,593.210999}, {402.914001,593.820007}}} {{401.031006,591.078003}} wnTs[0]=1 {{{397.476013,591.835999}, {401.031006,591.078003}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{402.914001,593.820007}, {403.859009,594.429016}, {405.015991,594.679016}, {406.195007,594.429016}}} {{406.195007,594.429016}} wnTs[0]=0 {{{406.195007,594.429016}, {406.945007,597.984009}}}
+debugShowCubicIntersection no intersect {{{402.914001,593.820007}, {403.859009,594.429016}, {405.015991,594.679016}, {406.195007,594.429016}}} {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}} {{406.945007,597.984009}} wnTs[0]=1 {{{406.195007,594.429016}, {406.945007,597.984009}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{406.945007,597.984009}, {402.625,598.89801}, {398.39801,596.156006}, {397.476013,591.835999}}} {{397.476013,591.835999}} wnTs[0]=0 {{{397.476013,591.835999}, {401.031006,591.078003}}}
+------------------x--x---------------- addExpanded
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+SkOpSegment::debugShowActiveSpans id=1 (409.539001,589.27301 409.296997,588.085022 408.593994,587.140015 407.664001,586.52301) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (407.664001,586.52301 406.718994,585.914001 405.562012,585.671021 404.382996,585.921021) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (404.382996,585.921021 403.625397,582.36792) t=0 tEnd=0.999474488 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (403.625397,582.36792 403.625,582.366028) t=0.999474488 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=4 (403.625,582.366028 407.953003,581.452026 412.179993,584.202026 413.10199,588.514038) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (413.10199,588.514038 409.539001,589.27301) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=16 (404.382996,585.921997 403.203003,586.171997 402.25,586.867004 401.640991,587.812988) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=17 (401.640991,587.812988 401.031982,588.750977 400.781982,589.898987 401.031982,591.078979) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=18 (401.031982,591.078979 397.47699,591.836975) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (397.47699,591.836975 397.47691,591.836597 397.476826,591.836193 397.476746,591.835815) t=0 tEnd=8.74738929e-05 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (397.476746,591.835815 396.563464,587.516202 399.305371,583.289897 403.625,582.367981) t=8.74738929e-05 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=20 (403.625,582.367981 404.382996,585.921997) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=6 (406.195007,594.429993 407.375,594.179993 408.320007,593.484985 408.929016,592.546997) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (408.929016,592.546997 409.538025,591.60199 409.788025,590.453003 409.538025,589.273987) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=8 (409.538025,589.273987 409.539154,589.273743) t=0 tEnd=0.000318097039 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=8 (409.539154,589.273743 413.100037,588.515991) t=0.000318097039 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=9 (413.100037,588.515991 414.006042,592.835999 411.272034,597.062988 406.944031,597.984985) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (406.944031,597.984985 406.195007,594.429993) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=11 (401.031006,591.078003 401.031088,591.07838 401.031167,591.078785 401.03125,591.079163) t=0 tEnd=0.000319790508 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=11 (401.03125,591.079163 401.289442,592.258633 401.984306,593.211193 402.914001,593.820007) t=0.000319790508 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=12 (402.914001,593.820007 403.859009,594.429016 405.015991,594.679016 406.195007,594.429016) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=13 (406.195007,594.429016 406.945007,597.984009) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=14 (406.945007,597.984009 406.94463,597.984009 406.944255,597.984253 406.943878,597.984253) t=0 tEnd=8.73365293e-05 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=14 (406.943878,597.984253 402.624264,598.897536 398.39793,596.155629 397.476013,591.835999) t=8.73365293e-05 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=15 (397.476013,591.835999 401.031006,591.078003) t=0 tEnd=1 windSum=? windValue=1
+------------------x--x---------------- move_multiples
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+------------------x--x---------------- move_nearby
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+------------------x--x---------------- correctEnds
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+------------------x--x---------------- addEndMovedSpans
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+------------------x--x---------------- expand
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+------------------x--x---------------- addExpanded
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+------------------x--x---------------- mark
+00: seg/base=20/39 seg/base=3/5 MarkCoinStart
+01: seg/base=20/40 seg/base=3/41 MarkCoinEnd
+-------------------------------------- missing_coincidence
+-------------------------------------- expand
+-------------------------------------- expand
+-------------------------------------- apply
+SkOpSegment::markDone id=20 (403.625,582.367981 404.382996,585.921997) t=0 [39] (403.625,582.367981) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
+SkOpSegment::markDone id=3 (404.382996,585.921021 403.625,582.366028) t=0 [5] (404.382996,585.921021) tEnd=0.999474488 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
+-------------------------------------- findOverlaps
+SkOpSegment::debugShowActiveSpans id=1 (409.539001,589.27301 409.296997,588.085022 408.593994,587.140015 407.664001,586.52301) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (407.664001,586.52301 406.718994,585.914001 405.562012,585.671021 404.382996,585.921021) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (403.625397,582.36792 403.625,582.366028) t=0.999474488 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=4 (403.625,582.366028 407.953003,581.452026 412.179993,584.202026 413.10199,588.514038) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (413.10199,588.514038 409.539001,589.27301) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=16 (404.382996,585.921997 403.203003,586.171997 402.25,586.867004 401.640991,587.812988) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=17 (401.640991,587.812988 401.031982,588.750977 400.781982,589.898987 401.031982,591.078979) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=18 (401.031982,591.078979 397.47699,591.836975) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (397.47699,591.836975 397.47691,591.836597 397.476826,591.836193 397.476746,591.835815) t=0 tEnd=8.74738929e-05 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (397.476746,591.835815 396.563464,587.516202 399.305371,583.289897 403.625,582.367981) t=8.74738929e-05 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=6 (406.195007,594.429993 407.375,594.179993 408.320007,593.484985 408.929016,592.546997) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (408.929016,592.546997 409.538025,591.60199 409.788025,590.453003 409.538025,589.273987) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=8 (409.538025,589.273987 409.539154,589.273743) t=0 tEnd=0.000318097039 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=8 (409.539154,589.273743 413.100037,588.515991) t=0.000318097039 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=9 (413.100037,588.515991 414.006042,592.835999 411.272034,597.062988 406.944031,597.984985) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (406.944031,597.984985 406.195007,594.429993) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=11 (401.031006,591.078003 401.031088,591.07838 401.031167,591.078785 401.03125,591.079163) t=0 tEnd=0.000319790508 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=11 (401.03125,591.079163 401.289442,592.258633 401.984306,593.211193 402.914001,593.820007) t=0.000319790508 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=12 (402.914001,593.820007 403.859009,594.429016 405.015991,594.679016 406.195007,594.429016) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=13 (406.195007,594.429016 406.945007,597.984009) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=14 (406.945007,597.984009 406.94463,597.984009 406.944255,597.984253 406.943878,597.984253) t=0 tEnd=8.73365293e-05 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=14 (406.943878,597.984253 402.624264,598.897536 398.39793,596.155629 397.476013,591.835999) t=8.73365293e-05 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=15 (397.476013,591.835999 401.031006,591.078003) t=0 tEnd=1 windSum=? windValue=1
+-------------------------------------- calc_angles
+SkOpSegment::sortAngles [1] tStart=0 [1]
+SkOpAngle::after [1/1] 9/9 tStart=0 tEnd=1 < [8/13] 1/1 tStart=0.000318097039 tEnd=1 < [8/12] 17/17 tStart=0.000318097039 tEnd=0 F 4
+SkOpAngle::afterPart {{{409.539154,589.273743}, {409.29715,588.085754}, {408.594147,587.140747}, {407.664154,586.523743}}} id=1
+SkOpAngle::afterPart {{{409.539154,589.273743}, {413.100037,588.515991}}} id=8
+SkOpAngle::afterPart {{{409.539154,589.273743}, {409.538025,589.273987}}} id=8
+SkOpAngle::after [1/1] 9/9 tStart=0 tEnd=1 < [5/4] 1/1 tStart=1 tEnd=0 < [8/12] 17/17 tStart=0.000318097039 tEnd=0 F 4
+SkOpAngle::afterPart {{{409.539001,589.27301}, {409.296997,588.085022}, {408.593994,587.140015}, {407.664001,586.52301}}} id=1
+SkOpAngle::afterPart {{{409.539001,589.27301}, {413.10199,588.514038}}} id=5
+SkOpAngle::afterPart {{{409.539001,589.27301}, {409.537872,589.273254}}} id=8
+SkOpAngle::after [8/12] 17/17 tStart=0.000318097039 tEnd=0 < [5/4] 1/1 tStart=1 tEnd=0 < [8/13] 1/1 tStart=0.000318097039 tEnd=1 F 11
+SkOpAngle::afterPart {{{409.539001,589.27301}, {409.537872,589.273254}}} id=8
+SkOpAngle::afterPart {{{409.539001,589.27301}, {413.10199,588.514038}}} id=5
+SkOpAngle::afterPart {{{409.539001,589.27301}, {413.099884,588.515259}}} id=8
+SkOpAngle::after [8/13] 1/1 tStart=0.000318097039 tEnd=1 < [5/4] 1/1 tStart=1 tEnd=0 < [1/1] 9/9 tStart=0 tEnd=1 T 7
+SkOpAngle::afterPart {{{409.539001,589.27301}, {413.099884,588.515259}}} id=8
+SkOpAngle::afterPart {{{409.539001,589.27301}, {413.10199,588.514038}}} id=5
+SkOpAngle::afterPart {{{409.539001,589.27301}, {409.296997,588.085022}, {408.593994,587.140015}, {407.664001,586.52301}}} id=1
+SkOpSegment::sortAngles [2] tStart=1 [4]
+SkOpSegment::sortAngles [3] tStart=0.999474488 [41]
+SkOpSegment::sortAngles [5] tStart=1 [10]
+SkOpSegment::sortAngles [16] tStart=0 [31]
+SkOpSegment::sortAngles [17] tStart=1 [34]
+SkOpAngle::after [17/6] 9/5 tStart=1 tEnd=0 < [11/17] 9/9 tStart=0.000319790508 tEnd=0 < [18/7] 17/17 tStart=0 tEnd=1 T 7
+SkOpAngle::afterPart {{{401.03125,591.079163}, {400.78125,589.89917}, {401.03125,588.75116}, {401.640259,587.813171}}} id=17
+SkOpAngle::afterPart {{{401.03125,591.079163}, {401.031006,591.078003}, {401.031088,591.07838}, {401.031006,591.078003}}} id=11
+SkOpAngle::afterPart {{{401.03125,591.079163}, {397.476257,591.837158}}} id=18
+SkOpAngle::after [17/6] 9/5 tStart=1 tEnd=0 < [11/18] 25/25 tStart=0.000319790508 tEnd=1 < [11/17] 9/9 tStart=0.000319790508 tEnd=0 F 5
+SkOpAngle::afterPart {{{401.03125,591.079163}, {400.78125,589.89917}, {401.03125,588.75116}, {401.640259,587.813171}}} id=17
+SkOpAngle::afterPart {{{401.03125,591.079163}, {401.289442,592.258633}, {401.984306,593.211193}, {402.914001,593.820007}}} id=11
+SkOpAngle::afterPart {{{401.03125,591.079163}, {401.031006,591.078003}, {401.031088,591.07838}, {401.031006,591.078003}}} id=11
+SkOpAngle::after [11/17] 9/9 tStart=0.000319790508 tEnd=0 < [11/18] 25/25 tStart=0.000319790508 tEnd=1 < [18/7] 17/17 tStart=0 tEnd=1 F 4
+SkOpAngle::afterPart {{{401.03125,591.079163}, {401.031006,591.078003}, {401.031088,591.07838}, {401.031006,591.078003}}} id=11
+SkOpAngle::afterPart {{{401.03125,591.079163}, {401.289442,592.258633}, {401.984306,593.211193}, {402.914001,593.820007}}} id=11
+SkOpAngle::afterPart {{{401.03125,591.079163}, {397.476257,591.837158}}} id=18
+SkOpAngle::after [18/7] 17/17 tStart=0 tEnd=1 < [11/18] 25/25 tStart=0.000319790508 tEnd=1 < [17/6] 9/5 tStart=1 tEnd=0 T 4
+SkOpAngle::afterPart {{{401.03125,591.079163}, {397.476257,591.837158}}} id=18
+SkOpAngle::afterPart {{{401.03125,591.079163}, {401.289442,592.258633}, {401.984306,593.211193}, {402.914001,593.820007}}} id=11
+SkOpAngle::afterPart {{{401.03125,591.079163}, {400.78125,589.89917}, {401.03125,588.75116}, {401.640259,587.813171}}} id=17
+SkOpSegment::sortAngles [18] tStart=0 [35]
+SkOpSegment::sortAngles [19] tStart=8.74738929e-05 [44]
+SkOpAngle::after [19/8] 25/25 tStart=8.74738929e-05 tEnd=0 < [14/23] 25/29 tStart=1 tEnd=8.73365293e-05 < [19/9] 9/5 tStart=8.74738929e-05 tEnd=1 T 12
+SkOpAngle::afterPart {{{397.476013,591.835999}, {397.476257,591.837158}, {397.476177,591.83678}, {397.476257,591.837158}}} id=19
+SkOpAngle::afterPart {{{397.476013,591.835999}, {398.39793,596.155629}, {402.624264,598.897536}, {406.943878,597.984253}}} id=14
+SkOpAngle::afterPart {{{397.476013,591.835999}, {396.562731,587.516385}, {399.304638,583.29008}, {403.624268,582.368164}}} id=19
+SkOpAngle::after [19/8] 25/25 tStart=8.74738929e-05 tEnd=0 < [15/24] 1/1 tStart=0 tEnd=1 < [14/23] 25/29 tStart=1 tEnd=8.73365293e-05 F 5
+SkOpAngle::afterPart {{{397.476013,591.835999}, {397.476257,591.837158}, {397.476177,591.83678}, {397.476257,591.837158}}} id=19
+SkOpAngle::afterPart {{{397.476013,591.835999}, {401.031006,591.078003}}} id=15
+SkOpAngle::afterPart {{{397.476013,591.835999}, {398.39793,596.155629}, {402.624264,598.897536}, {406.943878,597.984253}}} id=14
+SkOpAngle::after [14/23] 25/29 tStart=1 tEnd=8.73365293e-05 < [15/24] 1/1 tStart=0 tEnd=1 < [19/9] 9/5 tStart=8.74738929e-05 tEnd=1 T 4
+SkOpAngle::afterPart {{{397.476013,591.835999}, {398.39793,596.155629}, {402.624264,598.897536}, {406.943878,597.984253}}} id=14
+SkOpAngle::afterPart {{{397.476013,591.835999}, {401.031006,591.078003}}} id=15
+SkOpAngle::afterPart {{{397.476013,591.835999}, {396.562731,587.516385}, {399.304638,583.29008}, {403.624268,582.368164}}} id=19
+SkOpSegment::sortAngles [19] tStart=1 [38]
+SkOpSegment::sortAngles [6] tStart=0 [11]
+SkOpAngle::after [6/11] 1/1 tStart=0 tEnd=1 < [13/20] 25/25 tStart=0 tEnd=1 < [12/19] 17/13 tStart=1 tEnd=0 F 4
+SkOpAngle::afterPart {{{406.195007,594.429016}, {407.375,594.179016}, {408.320007,593.484009}, {408.929016,592.546021}}} id=6
+SkOpAngle::afterPart {{{406.195007,594.429016}, {406.945007,597.984009}}} id=13
+SkOpAngle::afterPart {{{406.195007,594.429016}, {405.015991,594.679016}, {403.859009,594.429016}, {402.914001,593.820007}}} id=12
+SkOpAngle::after [6/11] 1/1 tStart=0 tEnd=1 < [10/16] 25/25 tStart=1 tEnd=0 < [12/19] 17/13 tStart=1 tEnd=0 F 4
+SkOpAngle::afterPart {{{406.195007,594.429993}, {407.375,594.179993}, {408.320007,593.484985}, {408.929016,592.546997}}} id=6
+SkOpAngle::afterPart {{{406.195007,594.429993}, {406.944031,597.984985}}} id=10
+SkOpAngle::afterPart {{{406.195007,594.429993}, {405.015991,594.679993}, {403.859009,594.429993}, {402.914001,593.820984}}} id=12
+SkOpAngle::after [12/19] 17/13 tStart=1 tEnd=0 < [10/16] 25/25 tStart=1 tEnd=0 < [13/20] 25/25 tStart=0 tEnd=1 T 7
+SkOpAngle::afterPart {{{406.195007,594.429993}, {405.015991,594.679993}, {403.859009,594.429993}, {402.914001,593.820984}}} id=12
+SkOpAngle::afterPart {{{406.195007,594.429993}, {406.944031,597.984985}}} id=10
+SkOpAngle::afterPart {{{406.195007,594.429993}, {406.945007,597.984985}}} id=13
+SkOpSegment::sortAngles [8] tStart=0.000318097039 [42]
+SkOpSegment::sortAngles [9] tStart=1 [18]
+SkOpAngle::after [9/14] 1/5 tStart=1 tEnd=0 < [14/21] 31/31 tStart=8.73365293e-05 tEnd=0 < [10/15] 9/9 tStart=0 tEnd=1 F 4
+SkOpAngle::afterPart {{{406.943878,597.984253}, {411.271881,597.062256}, {414.00589,592.835266}, {413.099884,588.515259}}} id=9
+SkOpAngle::afterPart {{{406.943878,597.984253}, {406.945007,597.984009}, {406.94463,597.984009}, {406.945007,597.984009}}} id=14
+SkOpAngle::afterPart {{{406.943878,597.984253}, {406.194855,594.42926}}} id=10
+SkOpAngle::after [9/14] 1/5 tStart=1 tEnd=0 < [14/22] 17/13 tStart=8.73365293e-05 tEnd=1 < [10/15] 9/9 tStart=0 tEnd=1 F 4
+SkOpAngle::afterPart {{{406.943878,597.984253}, {411.271881,597.062256}, {414.00589,592.835266}, {413.099884,588.515259}}} id=9
+SkOpAngle::afterPart {{{406.943878,597.984253}, {402.624264,598.897536}, {398.39793,596.155629}, {397.476013,591.835999}}} id=14
+SkOpAngle::afterPart {{{406.943878,597.984253}, {406.194855,594.42926}}} id=10
+SkOpAngle::after [10/15] 9/9 tStart=0 tEnd=1 < [14/22] 17/13 tStart=8.73365293e-05 tEnd=1 < [14/21] 31/31 tStart=8.73365293e-05 tEnd=0 T 4
+SkOpAngle::afterPart {{{406.943878,597.984253}, {406.194855,594.42926}}} id=10
+SkOpAngle::afterPart {{{406.943878,597.984253}, {402.624264,598.897536}, {398.39793,596.155629}, {397.476013,591.835999}}} id=14
+SkOpAngle::afterPart {{{406.943878,597.984253}, {406.945007,597.984009}, {406.94463,597.984009}, {406.945007,597.984009}}} id=14
+SkOpSegment::sortAngles [10] tStart=0 [19]
+SkOpSegment::sortAngles [10] tStart=1 [20]
+SkOpSegment::sortAngles [11] tStart=0.000319790508 [43]
+SkOpSegment::sortAngles [12] tStart=1 [24]
+SkOpSegment::sortAngles [13] tStart=0 [25]
+SkOpSegment::sortAngles [14] tStart=8.73365293e-05 [45]
+SkOpSegment::sortAngles [14] tStart=1 [28]
+SkOpSegment::sortAngles [15] tStart=0 [29]
+coinSpan - id=20 t=0 tEnd=1
+coinSpan + id=3 t=0.999474488 tEnd=0
+SkOpSpan::sortableTop dir=kLeft seg=1 t=0.5 pt=(408.859497,587.683899)
+SkOpSpan::sortableTop [0] valid=1 operand=0 span=44 ccw=1 seg=19 {{{397.47699f, 591.836975f}, {396.562988f, 587.516968f}, {399.304993f, 583.289978f}, {403.625f, 582.367981f}}} t=0.33188452 pt=(397.699097,587.683899) slope=(3.85156666,-11.7134239)
+SkOpSpan::sortableTop [1] valid=1 operand=0 span=31 ccw=0 seg=16 {{{404.382996f, 585.921997f}, {403.203003f, 586.171997f}, {402.25f, 586.867004f}, {401.640991f, 587.812988f}}} t=0.953943751 pt=(401.727325,587.683899) slope=(-1.92134028,2.7673627)
+SkOpSpan::sortableTop [2] valid=1 operand=0 span=1 ccw=1 seg=1 {{{409.539001f, 589.27301f}, {409.296997f, 588.085022f}, {408.593994f, 587.140015f}, {407.664001f, 586.52301f}}} t=0.5 pt=(408.859497,587.683899) slope=(-1.9335022,-2.77125549)
+SkOpSegment::markWinding id=19 (397.47699,591.836975 396.562988,587.516968 399.304993,583.289978 403.625,582.367981) t=8.74738929e-05 [44] (397.476746,591.835815) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markWinding id=3 (404.382996,585.921021 403.625,582.366028) t=0.999474488 [41] (403.625397,582.36792) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=4 (403.625,582.366028 407.953003,581.452026 412.179993,584.202026 413.10199,588.514038) t=0 [7] (403.625,582.366028) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=5 (413.10199,588.514038 409.539001,589.27301) t=0 [9] (413.10199,588.514038) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=19 (397.47699,591.836975 396.562988,587.516968 399.304993,583.289978 403.625,582.367981) t=8.74738929e-05 [44] (397.476746,591.835815) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::markWinding id=16 (404.382996,585.921997 403.203003,586.171997 402.25,586.867004 401.640991,587.812988) t=0 [31] (404.382996,585.921997) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::markWinding id=17 (401.640991,587.812988 401.031982,588.750977 400.781982,589.898987 401.031982,591.078979) t=0 [33] (401.640991,587.812988) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=16 (404.382996,585.921997 403.203003,586.171997 402.25,586.867004 401.640991,587.812988) t=0 [31] (404.382996,585.921997) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markWinding id=2 (407.664001,586.52301 406.718994,585.914001 405.562012,585.671021 404.382996,585.921021) t=0 [3] (407.664001,586.52301) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=1 (409.539001,589.27301 409.296997,588.085022 408.593994,587.140015 407.664001,586.52301) t=0 [1] (409.539001,589.27301) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=8 (409.538025,589.273987 413.100037,588.515991) t=0 [15] (409.538025,589.273987) tEnd=0.000318097039 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=7 (408.929016,592.546997 409.538025,591.60199 409.788025,590.453003 409.538025,589.273987) t=0 [13] (408.929016,592.546997) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=6 (406.195007,594.429993 407.375,594.179993 408.320007,593.484985 408.929016,592.546997) t=0 [11] (406.195007,594.429993) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=6 span=11 windSum=-1
+SkOpSegment::markWinding id=8 (409.538025,589.273987 413.100037,588.515991) t=0.000318097039 [42] (409.539154,589.273743) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=9 (413.100037,588.515991 414.006042,592.835999 411.272034,597.062988 406.944031,597.984985) t=0 [17] (413.100037,588.515991) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=9 span=18
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [1/1] next=8/12 sect=9/9 s=0 [1] e=1 [2] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpAngle::dumpOne [8/12] next=8/13 sect=17/17 s=0.000318097039 [42] e=0 [15] sgn=1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [8/13] next=5/4 sect=1/1 s=0.000318097039 [42] e=1 [16] sgn=-1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [5/4] next=1/1 sect=1/1 s=1 [10] e=0 [9] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpSegment::findNextWinding chase.append segment=6 span=11 windSum=-1
+SkOpSegment::findNextWinding chase.append segment=9 span=18
+SkOpSegment::markDone id=1 (409.539001,589.27301 409.296997,588.085022 408.593994,587.140015 407.664001,586.52301) t=0 [1] (409.539001,589.27301) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[1] to:[8] start=4291816 end=4286928
+bridgeWinding current id=1 from=(407.664001,586.52301) to=(409.539001,589.27301)
+path.moveTo(407.664001,586.52301);
+path.cubicTo(408.593994,587.140015, 409.296997,588.085022, 409.539001,589.27301);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=8 (409.538025,589.273987 413.100037,588.515991) t=0 [15] (409.538025,589.273987) tEnd=0.000318097039 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=8 from=(409.539154,589.273743) to=(409.538025,589.273987)
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=7 (408.929016,592.546997 409.538025,591.60199 409.788025,590.453003 409.538025,589.273987) t=0 [13] (408.929016,592.546997) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=7 from=(409.538025,589.273987) to=(408.929016,592.546997)
+path.lineTo(409.538025,589.273987);
+path.cubicTo(409.788025,590.453003, 409.538025,591.60199, 408.929016,592.546997);
+SkOpSegment::markWinding id=12 (402.914001,593.820007 403.859009,594.429016 405.015991,594.679016 406.195007,594.429016) t=0 [23] (402.914001,593.820007) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=11 (401.031006,591.078003 401.289001,592.257996 401.984009,593.210999 402.914001,593.820007) t=0.000319790508 [43] (401.03125,591.079163) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=11 span=43 windSum=-1
+SkOpSegment::markWinding id=10 (406.944031,597.984985 406.195007,594.429993) t=0 [19] (406.944031,597.984985) tEnd=1 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=10 span=19 windSum=-2
+SkOpSegment::markWinding id=13 (406.195007,594.429016 406.945007,597.984009) t=0 [25] (406.195007,594.429016) tEnd=1 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markWinding id=14 (406.945007,597.984009 402.625,598.89801 398.39801,596.156006 397.476013,591.835999) t=0 [27] (406.945007,597.984009) tEnd=8.73365293e-05 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=14 span=45 windSum=?
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [6/11] next=12/19 sect=1/1 s=0 [11] e=1 [12] sgn=-1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [12/19] next=10/16 sect=17/13 s=1 [24] e=0 [23] sgn=1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [10/16] next=13/20 sect=25/25 s=1 [20] e=0 [19] sgn=1 windVal=1 windSum=-2
+SkOpAngle::dumpOne [13/20] next=6/11 sect=25/25 s=0 [25] e=1 [26] sgn=-1 windVal=1 windSum=-2
+SkOpSegment::findNextWinding chase.append segment=11 span=43 windSum=-1
+SkOpSegment::markDone id=10 (406.944031,597.984985 406.195007,594.429993) t=0 [19] (406.944031,597.984985) tEnd=1 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=10 span=19 windSum=-2
+SkOpSegment::markDone id=13 (406.195007,594.429016 406.945007,597.984009) t=0 [25] (406.195007,594.429016) tEnd=1 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::markDone id=14 (406.945007,597.984009 402.625,598.89801 398.39801,596.156006 397.476013,591.835999) t=0 [27] (406.945007,597.984009) tEnd=8.73365293e-05 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=14 span=45 windSum=-2147483647
+SkOpSegment::markDone id=6 (406.195007,594.429993 407.375,594.179993 408.320007,593.484985 408.929016,592.546997) t=0 [11] (406.195007,594.429993) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[6] to:[12] start=4288824 end=4288680
+bridgeWinding current id=6 from=(408.929016,592.546997) to=(406.195007,594.429993)
+path.cubicTo(408.320007,593.484985, 407.375,594.179993, 406.195007,594.429993);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=12 (402.914001,593.820007 403.859009,594.429016 405.015991,594.679016 406.195007,594.429016) t=0 [23] (402.914001,593.820007) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=12 from=(406.195007,594.429016) to=(402.914001,593.820007)
+path.cubicTo(405.015991,594.679016, 403.859009,594.429016, 402.914001,593.820007);
+SkOpSegment::markWinding id=11 (401.031006,591.078003 401.289001,592.257996 401.984009,593.210999 402.914001,593.820007) t=0 [21] (401.031006,591.078003) tEnd=0.000319790508 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markWinding id=15 (397.476013,591.835999 401.031006,591.078003) t=0 [29] (397.476013,591.835999) tEnd=1 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=15 span=29 windSum=-2
+SkOpSegment::markWinding id=18 (401.031982,591.078979 397.47699,591.836975) t=0 [35] (401.031982,591.078979) tEnd=1 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markWinding id=19 (397.47699,591.836975 396.562988,587.516968 399.304993,583.289978 403.625,582.367981) t=0 [37] (397.47699,591.836975) tEnd=8.74738929e-05 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=19 span=44 windSum=-1
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [11/18] next=17/6 sect=25/25 s=0.000319790508 [43] e=1 [22] sgn=-1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [17/6] next=11/17 sect=9/5 s=1 [34] e=0 [33] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpAngle::dumpOne [11/17] next=18/7 sect=9/9 s=0.000319790508 [43] e=0 [21] sgn=1 windVal=1 windSum=-2
+SkOpAngle::dumpOne [18/7] next=11/18 sect=17/17 s=0 [35] e=1 [36] sgn=-1 windVal=1 windSum=-2
+SkOpSegment::markDone id=11 (401.031006,591.078003 401.289001,592.257996 401.984009,593.210999 402.914001,593.820007) t=0 [21] (401.031006,591.078003) tEnd=0.000319790508 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::markDone id=15 (397.476013,591.835999 401.031006,591.078003) t=0 [29] (397.476013,591.835999) tEnd=1 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=15 span=29 windSum=-2
+SkOpSegment::markDone id=18 (401.031982,591.078979 397.47699,591.836975) t=0 [35] (401.031982,591.078979) tEnd=1 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::markDone id=19 (397.47699,591.836975 396.562988,587.516968 399.304993,583.289978 403.625,582.367981) t=0 [37] (397.47699,591.836975) tEnd=8.74738929e-05 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=19 span=44 windSum=-1
+SkOpSegment::markDone id=11 (401.031006,591.078003 401.289001,592.257996 401.984009,593.210999 402.914001,593.820007) t=0.000319790508 [43] (401.03125,591.079163) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[11] to:[17] start=4290488 end=4290344
+bridgeWinding current id=11 from=(402.914001,593.820007) to=(401.03125,591.079163)
+path.cubicTo(401.984314,593.211182, 401.289429,592.258606, 401.03125,591.079163);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=17 (401.640991,587.812988 401.031982,588.750977 400.781982,589.898987 401.031982,591.078979) t=0 [33] (401.640991,587.812988) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=17 from=(401.031982,591.078979) to=(401.640991,587.812988)
+path.cubicTo(400.781982,589.898987, 401.031982,588.750977, 401.640991,587.812988);
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=16 (404.382996,585.921997 403.203003,586.171997 402.25,586.867004 401.640991,587.812988) t=0 [31] (404.382996,585.921997) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=16 from=(401.640991,587.812988) to=(404.382996,585.921997)
+path.cubicTo(402.25,586.867004, 403.203003,586.171997, 404.382996,585.921997);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=2 (407.664001,586.52301 406.718994,585.914001 405.562012,585.671021 404.382996,585.921021) t=0 [3] (407.664001,586.52301) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=2 from=(404.382996,585.921021) to=(407.664001,586.52301)
+path.cubicTo(405.562012,585.671021, 406.718994,585.914001, 407.664001,586.52301);
+path.close();
+SkOpSegment::markWinding id=19 (397.47699,591.836975 396.562988,587.516968 399.304993,583.289978 403.625,582.367981) t=8.74738929e-05 [44] (397.476746,591.835815) tEnd=1 newWindSum=-1 windSum=-1 windValue=1
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markWinding id=14 (406.945007,597.984009 402.625,598.89801 398.39801,596.156006 397.476013,591.835999) t=8.73365293e-05 [45] (406.943878,597.984253) tEnd=1 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=14 span=45 windSum=-2
+SkOpSegment::debugShowActiveSpans id=3 (403.625397,582.36792 403.625,582.366028) t=0.999474488 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
+SkOpSegment::debugShowActiveSpans id=4 (403.625,582.366028 407.953003,581.452026 412.179993,584.202026 413.10199,588.514038) t=0 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
+SkOpSegment::debugShowActiveSpans id=5 (413.10199,588.514038 409.539001,589.27301) t=0 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
+SkOpSegment::debugShowActiveSpans id=19 (397.476746,591.835815 396.563464,587.516202 399.305371,583.289897 403.625,582.367981) t=8.74738929e-05 tEnd=1 windSum=-1 oppSum=0 windValue=1 oppValue=0
+SkOpSegment::debugShowActiveSpans id=8 (409.539154,589.273743 413.100037,588.515991) t=0.000318097039 tEnd=1 windSum=-1 windValue=1
+SkOpSegment::debugShowActiveSpans id=9 (413.100037,588.515991 414.006042,592.835999 411.272034,597.062988 406.944031,597.984985) t=0 tEnd=1 windSum=-1 windValue=1
+SkOpSegment::debugShowActiveSpans id=14 (406.943878,597.984253 402.624264,598.897536 398.39793,596.155629 397.476013,591.835999) t=8.73365293e-05 tEnd=1 windSum=-2 windValue=1
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=19 (397.47699,591.836975 396.562988,587.516968 399.304993,583.289978 403.625,582.367981) t=8.74738929e-05 [44] (397.476746,591.835815) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=19 from=(397.476746,591.835815) to=(403.625,582.367981)
+path.moveTo(397.476746,591.835815);
+path.cubicTo(396.563477,587.516174, 399.305359,583.289917, 403.625,582.367981);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=3 (404.382996,585.921021 403.625,582.366028) t=0.999474488 [41] (403.625397,582.36792) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=3 from=(403.625397,582.36792) to=(403.625,582.366028)
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=4 (403.625,582.366028 407.953003,581.452026 412.179993,584.202026 413.10199,588.514038) t=0 [7] (403.625,582.366028) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=4 from=(403.625,582.366028) to=(413.10199,588.514038)
+path.lineTo(403.625,582.366028);
+path.cubicTo(407.953003,581.452026, 412.179993,584.202026, 413.10199,588.514038);
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [5/4] next=1/1 sect=1/1 s=1 [10] e=0 [9] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpAngle::dumpOne [1/1] next=8/12 sect=9/9 s=0 [1] e=1 [2] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0 done
+SkOpAngle::dumpOne [8/12] next=8/13 sect=17/17 s=0.000318097039 [42] e=0 [15] sgn=1 windVal=1 windSum=-1 done
+SkOpAngle::dumpOne [8/13] next=5/4 sect=1/1 s=0.000318097039 [42] e=1 [16] sgn=-1 windVal=1 windSum=-1
+SkOpSegment::markDone id=5 (413.10199,588.514038 409.539001,589.27301) t=0 [9] (413.10199,588.514038) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[5] to:[8] start=4291816 end=4287072
+bridgeWinding current id=5 from=(413.10199,588.514038) to=(409.539001,589.27301)
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=8 (409.538025,589.273987 413.100037,588.515991) t=0.000318097039 [42] (409.539154,589.273743) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=8 from=(409.539154,589.273743) to=(413.100037,588.515991)
+path.lineTo(409.539001,589.27301);
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [9/14] next=10/15 sect=1/5 s=1 [18] e=0 [17] sgn=1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [10/15] next=14/22 sect=9/9 s=0 [19] e=1 [20] sgn=-1 windVal=1 windSum=-2 done
+SkOpAngle::dumpOne [14/22] next=14/21 sect=17/13 s=8.73365293e-05 [45] e=1 [28] sgn=-1 windVal=1 windSum=-2
+SkOpAngle::dumpOne [14/21] next=9/14 sect=31/31 s=8.73365293e-05 [45] e=0 [27] sgn=1 windVal=1 windSum=-2 done
+SkOpSegment::markDone id=9 (413.100037,588.515991 414.006042,592.835999 411.272034,597.062988 406.944031,597.984985) t=0 [17] (413.100037,588.515991) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[9] to:[14] start=4292248 end=4289320
+bridgeWinding current id=9 from=(413.100037,588.515991) to=(406.944031,597.984985)
+path.lineTo(413.100037,588.515991);
+path.cubicTo(414.006042,592.835999, 411.272034,597.062988, 406.944031,597.984985);
+SkOpSegment::findNextWinding simple
+SkOpSegment::debugShowActiveSpans id=14 (406.943878,597.984253 402.624264,598.897536 398.39793,596.155629 397.476013,591.835999) t=8.73365293e-05 tEnd=1 windSum=-2 windValue=1
+SkOpSegment::markDone id=14 (406.945007,597.984009 402.625,598.89801 398.39801,596.156006 397.476013,591.835999) t=8.73365293e-05 [45] (406.943878,597.984253) tEnd=1 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+</div>
+
+<div id="joel_10">
+SkDCubic::ComplexBreak
+{{{584.08599853515625, 431.33599853515625}, {582.93798828125, 430.96099853515625}, {581.75799560546875, 431.08599853515625}, {580.7659912109375, 431.593994140625}}},
+maxCurvature[0]=0.908113421 {{{584.1181209116214177, 430.1538818130687787}, {577.969954809597084, 432.7736222667205084}}},
+SkDCubic::ComplexBreak
+{{{575.14801025390625, 433}, {576.5150146484375, 428.7969970703125}, {581.0150146484375, 426.5159912109375}, {585.21002197265625, 427.875}}},
+maxCurvature[0]=0.50036075 {{{568.1978874470240726, 433.8982271481503972}, {590.0470235470908165, 422.8012586633995511}}},
+SkDCubic::ComplexBreak
+{{{586.875, 436.81201171875}, {587.25, 435.66400146484375}, {587.125, 434.5}, {586.61700439453125, 433.49200439453125}}},
+maxCurvature[0]=0.709758914 {{{587.7871278617965345, 437.6571056882418702}, {586.1322255770696756, 431.1527144185091061}}},
+SkDCubic::ComplexBreak
+{{{585.21099853515625, 427.875}, {589.406005859375, 429.24200439453125}, {591.69500732421875, 433.7340087890625}, {590.3280029296875, 437.93701171875}}},
+maxCurvature[0]=0.49729326 {{{584.2405287567108871, 420.9205840752692325}, {595.4397901231312744, 442.7054003127302053}}},
+SkDCubic::ComplexBreak
+{{{581.39801025390625, 439.60198974609375}, {582.53900146484375, 439.968994140625}, {583.71002197265625, 439.85198974609375}, {584.71002197265625, 439.343994140625}}},
+maxCurvature[0]=0.769822111 {{{580.7905223461929154, 440.6007184045780036}, {587.1989920634028977, 438.6622846164399903}}},
+SkDCubic::ComplexBreak
+{{{590.3270263671875, 437.93798828125}, {588.9520263671875, 442.13299560546875}, {584.468017578125, 444.4219970703125}, {580.2650146484375, 443.05499267578125}}},
+maxCurvature[0]=0.50179849 {{{597.2616281410381589, 437.0677298509480124}, {575.4121463613508922, 448.1166853435209987}}},
+SkDCubic::ComplexBreak
+{{{578.60198974609375, 434.125}, {578.2349853515625, 435.27301025390625}, {578.35198974609375, 436.43701171875}, {578.8599853515625, 437.44500732421875}}},
+maxCurvature[0]=0.714831074 {{{577.6906339162001132, 433.299635239093675}, {579.3552391524597169, 439.7975429835167347}}},
+SkDCubic::ComplexBreak
+{{{580.2659912109375, 443.05401611328125}, {576.07098388671875, 441.68701171875}, {573.781982421875, 437.2020263671875}, {575.14898681640625, 432.9990234375}}},
+maxCurvature[0]=0.498616268 {{{581.2070198879381451, 449.9982918524905813}, {570.0518531862154532, 428.2119094507434625}}},
+<empty>
+<empty>
+seg=1 {{{584.085999f, 431.335999f}, {582.937988f, 430.960999f}, {581.757996f, 431.085999f}, {580.765991f, 431.593994f}}}
+seg=2 {{{580.765991f, 431.593994f}, {579.773987f, 432.10199f}, {578.97699f, 432.97699f}, {578.60199f, 434.125f}}}
+seg=3 {{{578.60199f, 434.125f}, {575.14801f, 433}}}
+seg=4 {{{575.14801f, 433}, {576.515015f, 428.796997f}, {581.015015f, 426.515991f}, {585.210022f, 427.875f}}}
+seg=5 {{{585.210022f, 427.875f}, {584.085999f, 431.335999f}}}
+<empty>
+seg=6 {{{586.875f, 436.812012f}, {587.25f, 435.664001f}, {587.125f, 434.5f}, {586.617004f, 433.492004f}}}
+seg=7 {{{586.617004f, 433.492004f}, {586.101013f, 432.5f}, {585.234009f, 431.703003f}, {584.085999f, 431.335999f}}}
+seg=8 {{{584.085999f, 431.335999f}, {585.210999f, 427.875f}}}
+seg=9 {{{585.210999f, 427.875f}, {589.406006f, 429.242004f}, {591.695007f, 433.734009f}, {590.328003f, 437.937012f}}}
+seg=10 {{{590.328003f, 437.937012f}, {586.875f, 436.812012f}}}
+<empty>
+seg=11 {{{581.39801f, 439.60199f}, {582.539001f, 439.968994f}, {583.710022f, 439.85199f}, {584.710022f, 439.343994f}}}
+seg=12 {{{584.710022f, 439.343994f}, {585.702026f, 438.835999f}, {586.499023f, 437.960999f}, {586.874023f, 436.812988f}}}
+seg=13 {{{586.874023f, 436.812988f}, {590.327026f, 437.937988f}}}
+seg=14 {{{590.327026f, 437.937988f}, {588.952026f, 442.132996f}, {584.468018f, 444.421997f}, {580.265015f, 443.054993f}}}
+seg=15 {{{580.265015f, 443.054993f}, {581.39801f, 439.60199f}}}
+seg=16 {{{578.60199f, 434.125f}, {578.234985f, 435.27301f}, {578.35199f, 436.437012f}, {578.859985f, 437.445007f}}}
+seg=17 {{{578.859985f, 437.445007f}, {579.367981f, 438.437012f}, {580.250977f, 439.226013f}, {581.398987f, 439.601013f}}}
+seg=18 {{{581.398987f, 439.601013f}, {580.265991f, 443.054016f}}}
+seg=19 {{{580.265991f, 443.054016f}, {576.070984f, 441.687012f}, {573.781982f, 437.202026f}, {575.148987f, 432.999023f}}}
+seg=20 {{{575.148987f, 432.999023f}, {578.60199f, 434.125f}}}
+debugShowCubicIntersection wtTs[0]=1 {{{584.085999,431.335999}, {582.937988,430.960999}, {581.757996,431.085999}, {580.765991,431.593994}}} {{580.765991,431.593994}} wnTs[0]=0 {{{580.765991,431.593994}, {579.773987,432.10199}, {578.97699,432.97699}, {578.60199,434.125}}}
+debugShowCubicIntersection no intersect {{{584.085999,431.335999}, {582.937988,430.960999}, {581.757996,431.085999}, {580.765991,431.593994}}} {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{584.085999,431.335999}, {582.937988,430.960999}, {581.757996,431.085999}, {580.765991,431.593994}}} {{584.085999,431.335999}} wnTs[0]=1 {{{585.210022,427.875}, {584.085999,431.335999}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{580.765991,431.593994}, {579.773987,432.10199}, {578.97699,432.97699}, {578.60199,434.125}}} {{578.60199,434.125}} wnTs[0]=0 {{{578.60199,434.125}, {575.14801,433}}}
+debugShowCubicIntersection no intersect {{{580.765991,431.593994}, {579.773987,432.10199}, {578.97699,432.97699}, {578.60199,434.125}}} {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}} {{575.14801,433}} wnTs[0]=1 {{{578.60199,434.125}, {575.14801,433}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}} {{585.210022,427.875}} wnTs[0]=0 {{{585.210022,427.875}, {584.085999,431.335999}}}
+debugShowCubicIntersection wtTs[0]=0 {{{584.085999,431.335999}, {582.937988,430.960999}, {581.757996,431.085999}, {580.765991,431.593994}}} {{584.085999,431.335999}} wnTs[0]=1 {{{586.617004,433.492004}, {586.101013,432.5}, {585.234009,431.703003}, {584.085999,431.335999}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{584.085999,431.335999}, {582.937988,430.960999}, {581.757996,431.085999}, {580.765991,431.593994}}} {{584.085999,431.335999}} wnTs[0]=0 {{{584.085999,431.335999}, {585.210999,427.875}}}
+debugShowCubicIntersection no intersect {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}} {{{586.617004,433.492004}, {586.101013,432.5}, {585.234009,431.703003}, {584.085999,431.335999}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}} {{585.210022,427.875}} wnTs[0]=0.999917 {{{584.085999,431.335999}, {585.210999,427.875}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{586.617004,433.492004}, {586.101013,432.5}, {585.234009,431.703003}, {584.085999,431.335999}}} {{584.085999,431.335999}} wnTs[0]=1 {{{585.210022,427.875}, {584.085999,431.335999}}}
+debugShowLineIntersection wtTs[0]=0 {{{585.210022,427.875}, {584.085999,431.335999}}} {{585.210022,427.875}} wtTs[1]=1 {{584.085999,431.335999}} wnTs[0]=0.999917 {{{584.085999,431.335999}, {585.210999,427.875}}} wnTs[1]=0
+debugShowCubicIntersection wtTs[0]=1 {{{580.765991,431.593994}, {579.773987,432.10199}, {578.97699,432.97699}, {578.60199,434.125}}} {{578.60199,434.125}} wnTs[0]=0 {{{578.60199,434.125}, {578.234985,435.27301}, {578.35199,436.437012}, {578.859985,437.445007}}}
+debugShowCubicIntersection no intersect {{{580.765991,431.593994}, {579.773987,432.10199}, {578.97699,432.97699}, {578.60199,434.125}}} {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{580.765991,431.593994}, {579.773987,432.10199}, {578.97699,432.97699}, {578.60199,434.125}}} {{578.60199,434.125}} wnTs[0]=1 {{{575.148987,432.999023}, {578.60199,434.125}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{578.60199,434.125}, {578.234985,435.27301}, {578.35199,436.437012}, {578.859985,437.445007}}} {{578.60199,434.125}} wnTs[0]=0 {{{578.60199,434.125}, {575.14801,433}}}
+debugShowCubicLineIntersection wtTs[0]=0.999907158 {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}} {{575.148621,433.000183}} wnTs[0]=0.999827 {{{578.60199,434.125}, {575.14801,433}}}
+SkOpSegment::addT insert t=0.999907158 segID=19 spanID=41
+debugShowLineIntersection wtTs[0]=0 {{{578.60199,434.125}, {575.14801,433}}} {{578.60199,434.125}} wnTs[0]=1 {{{575.148987,432.999023}, {578.60199,434.125}}}
+debugShowCubicIntersection no intersect {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}} {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}}
+debugShowCubicLineIntersection no intersect {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}} {{{575.148987,432.999023}, {578.60199,434.125}}}
+debugShowCubicIntersection wtTs[0]=1 {{{586.875,436.812012}, {587.25,435.664001}, {587.125,434.5}, {586.617004,433.492004}}} {{586.617004,433.492004}} wnTs[0]=0 {{{586.617004,433.492004}, {586.101013,432.5}, {585.234009,431.703003}, {584.085999,431.335999}}}
+debugShowCubicIntersection no intersect {{{586.875,436.812012}, {587.25,435.664001}, {587.125,434.5}, {586.617004,433.492004}}} {{{585.210999,427.875}, {589.406006,429.242004}, {591.695007,433.734009}, {590.328003,437.937012}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{586.875,436.812012}, {587.25,435.664001}, {587.125,434.5}, {586.617004,433.492004}}} {{586.875,436.812012}} wnTs[0]=1 {{{590.328003,437.937012}, {586.875,436.812012}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{586.617004,433.492004}, {586.101013,432.5}, {585.234009,431.703003}, {584.085999,431.335999}}} {{584.085999,431.335999}} wnTs[0]=0 {{{584.085999,431.335999}, {585.210999,427.875}}}
+debugShowCubicIntersection no intersect {{{586.617004,433.492004}, {586.101013,432.5}, {585.234009,431.703003}, {584.085999,431.335999}}} {{{585.210999,427.875}, {589.406006,429.242004}, {591.695007,433.734009}, {590.328003,437.937012}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{585.210999,427.875}, {589.406006,429.242004}, {591.695007,433.734009}, {590.328003,437.937012}}} {{585.210999,427.875}} wnTs[0]=1 {{{584.085999,431.335999}, {585.210999,427.875}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{585.210999,427.875}, {589.406006,429.242004}, {591.695007,433.734009}, {590.328003,437.937012}}} {{590.328003,437.937012}} wnTs[0]=0 {{{590.328003,437.937012}, {586.875,436.812012}}}
+debugShowCubicIntersection no intersect {{{585.210999,427.875}, {589.406006,429.242004}, {591.695007,433.734009}, {590.328003,437.937012}}} {{{584.710022,439.343994}, {585.702026,438.835999}, {586.499023,437.960999}, {586.874023,436.812988}}}
+debugShowCubicLineIntersection no intersect {{{585.210999,427.875}, {589.406006,429.242004}, {591.695007,433.734009}, {590.328003,437.937012}}} {{{586.874023,436.812988}, {590.327026,437.937988}}}
+debugShowLineIntersection no intersect {{{590.328003,437.937012}, {586.875,436.812012}}} {{{586.874023,436.812988}, {590.327026,437.937988}}}
+debugShowCubicIntersection wtTs[0]=1 {{{578.60199,434.125}, {578.234985,435.27301}, {578.35199,436.437012}, {578.859985,437.445007}}} {{578.859985,437.445007}} wnTs[0]=0 {{{578.859985,437.445007}, {579.367981,438.437012}, {580.250977,439.226013}, {581.398987,439.601013}}}
+debugShowCubicIntersection no intersect {{{578.60199,434.125}, {578.234985,435.27301}, {578.35199,436.437012}, {578.859985,437.445007}}} {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{578.60199,434.125}, {578.234985,435.27301}, {578.35199,436.437012}, {578.859985,437.445007}}} {{578.60199,434.125}} wnTs[0]=1 {{{575.148987,432.999023}, {578.60199,434.125}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{578.859985,437.445007}, {579.367981,438.437012}, {580.250977,439.226013}, {581.398987,439.601013}}} {{581.398987,439.601013}} wnTs[0]=0 {{{581.398987,439.601013}, {580.265991,443.054016}}}
+debugShowCubicIntersection no intersect {{{578.859985,437.445007}, {579.367981,438.437012}, {580.250977,439.226013}, {581.398987,439.601013}}} {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}} {{580.265991,443.054016}} wnTs[0]=1 {{{581.398987,439.601013}, {580.265991,443.054016}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}} {{575.148987,432.999023}} wnTs[0]=0 {{{575.148987,432.999023}, {578.60199,434.125}}}
+debugShowCubicIntersection no intersect {{{578.859985,437.445007}, {579.367981,438.437012}, {580.250977,439.226013}, {581.398987,439.601013}}} {{{581.39801,439.60199}, {582.539001,439.968994}, {583.710022,439.85199}, {584.710022,439.343994}}}
+debugShowCubicIntersection no intersect {{{578.859985,437.445007}, {579.367981,438.437012}, {580.250977,439.226013}, {581.398987,439.601013}}} {{{590.327026,437.937988}, {588.952026,442.132996}, {584.468018,444.421997}, {580.265015,443.054993}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{581.39801,439.60199}, {582.539001,439.968994}, {583.710022,439.85199}, {584.710022,439.343994}}} {{581.39801,439.60199}} wtTs[1]=0.000173389113 {{581.398621,439.602173}} wnTs[0]=0.000339104 {{{581.398987,439.601013}, {580.265991,443.054016}}} wnTs[1]=0.000338089069
+SkOpSegment::addT insert t=0.000339103907 segID=18 spanID=42
+debugShowCubicLineIntersection no intersect {{{590.327026,437.937988}, {588.952026,442.132996}, {584.468018,444.421997}, {580.265015,443.054993}}} {{{581.398987,439.601013}, {580.265991,443.054016}}}
+debugShowLineIntersection wtTs[0]=0.000339103907 {{{581.398987,439.601013}, {580.265991,443.054016}}} {{581.39801,439.60199}} wtTs[1]=1 {{580.265991,443.054016}} wnTs[0]=1 {{{580.265015,443.054993}, {581.39801,439.60199}}} wnTs[1]=0.000339103907
+SkOpSegment::addT insert t=0.000339103907 segID=15 spanID=43
+debugShowCubicIntersection no intersect {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}} {{{590.327026,437.937988}, {588.952026,442.132996}, {584.468018,444.421997}, {580.265015,443.054993}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{580.265991,443.054016}, {576.070984,441.687012}, {573.781982,437.202026}, {575.148987,432.999023}}} {{580.265991,443.054016}} wtTs[1]=4.71004667e-05 {{580.265381,443.053833}} wnTs[0]=0.000339104 {{{580.265015,443.054993}, {581.39801,439.60199}}} wnTs[1]=0.000338761046
+debugShowCubicIntersection wtTs[0]=1 {{{581.39801,439.60199}, {582.539001,439.968994}, {583.710022,439.85199}, {584.710022,439.343994}}} {{584.710022,439.343994}} wnTs[0]=0 {{{584.710022,439.343994}, {585.702026,438.835999}, {586.499023,437.960999}, {586.874023,436.812988}}}
+debugShowCubicIntersection no intersect {{{581.39801,439.60199}, {582.539001,439.968994}, {583.710022,439.85199}, {584.710022,439.343994}}} {{{590.327026,437.937988}, {588.952026,442.132996}, {584.468018,444.421997}, {580.265015,443.054993}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{581.39801,439.60199}, {582.539001,439.968994}, {583.710022,439.85199}, {584.710022,439.343994}}} {{581.39801,439.60199}} wnTs[0]=1 {{{580.265015,443.054993}, {581.39801,439.60199}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{584.710022,439.343994}, {585.702026,438.835999}, {586.499023,437.960999}, {586.874023,436.812988}}} {{586.874023,436.812988}} wnTs[0]=0 {{{586.874023,436.812988}, {590.327026,437.937988}}}
+debugShowCubicIntersection no intersect {{{584.710022,439.343994}, {585.702026,438.835999}, {586.499023,437.960999}, {586.874023,436.812988}}} {{{590.327026,437.937988}, {588.952026,442.132996}, {584.468018,444.421997}, {580.265015,443.054993}}}
+debugShowCubicLineIntersection wtTs[0]=0 {{{590.327026,437.937988}, {588.952026,442.132996}, {584.468018,444.421997}, {580.265015,443.054993}}} {{590.327026,437.937988}} wnTs[0]=1 {{{586.874023,436.812988}, {590.327026,437.937988}}}
+debugShowCubicLineIntersection wtTs[0]=1 {{{590.327026,437.937988}, {588.952026,442.132996}, {584.468018,444.421997}, {580.265015,443.054993}}} {{580.265015,443.054993}} wnTs[0]=0 {{{580.265015,443.054993}, {581.39801,439.60199}}}
+------------------x--x---------------- addExpanded
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+SkOpSegment::debugShowActiveSpans id=1 (584.085999,431.335999 582.937988,430.960999 581.757996,431.085999 580.765991,431.593994) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (580.765991,431.593994 579.773987,432.10199 578.97699,432.97699 578.60199,434.125) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (578.60199,434.125 575.14801,433) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=4 (575.14801,433 576.515015,428.796997 581.015015,426.515991 585.210022,427.875) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (585.210022,427.875 584.085999,431.335999) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=6 (586.875,436.812012 587.25,435.664001 587.125,434.5 586.617004,433.492004) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (586.617004,433.492004 586.101013,432.5 585.234009,431.703003 584.085999,431.335999) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=8 (584.085999,431.335999 585.210999,427.875) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=9 (585.210999,427.875 589.406006,429.242004 591.695007,433.734009 590.328003,437.937012) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (590.328003,437.937012 586.875,436.812012) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=16 (578.60199,434.125 578.234985,435.27301 578.35199,436.437012 578.859985,437.445007) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=17 (578.859985,437.445007 579.367981,438.437012 580.250977,439.226013 581.398987,439.601013) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=18 (581.398987,439.601013 581.398621,439.602173) t=0 tEnd=0.000339103907 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=18 (581.398621,439.602173 580.265991,443.054016) t=0.000339103907 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (580.265991,443.054016 576.071373,441.687139 573.782422,437.202848 575.148621,433.000183) t=0 tEnd=0.999907158 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (575.148621,433.000183 575.148747,432.999793 575.14886,432.999414 575.148987,432.999023) t=0.999907158 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=20 (575.148987,432.999023 578.60199,434.125) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=11 (581.39801,439.60199 582.539001,439.968994 583.710022,439.85199 584.710022,439.343994) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=12 (584.710022,439.343994 585.702026,438.835999 586.499023,437.960999 586.874023,436.812988) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=13 (586.874023,436.812988 590.327026,437.937988) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=14 (590.327026,437.937988 588.952026,442.132996 584.468018,444.421997 580.265015,443.054993) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=15 (580.265015,443.054993 580.265381,443.053833) t=0 tEnd=0.000339103907 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=15 (580.265381,443.053833 581.39801,439.60199) t=0.000339103907 tEnd=1 windSum=? windValue=1
+------------------x--x---------------- move_multiples
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+------------------x--x---------------- move_nearby
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+------------------x--x---------------- correctEnds
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+------------------x--x---------------- addEndMovedSpans
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+------------------x--x---------------- expand
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+------------------x--x---------------- addExpanded
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+------------------x--x---------------- mark
+00: seg/base=15/43 seg/base=18/42 MarkCoinStart
+01: seg/base=15/30 seg/base=18/36 MarkCoinEnd
+02: seg/base=8/15 seg/base=5/9 MarkCoinStart
+03: seg/base=8/16 seg/base=5/10 MarkCoinEnd
+-------------------------------------- missing_coincidence
+-------------------------------------- expand
+-------------------------------------- expand
+-------------------------------------- apply
+SkOpSegment::markDone id=15 (580.265015,443.054993 581.39801,439.60199) t=0.000339103907 [43] (580.265381,443.053833) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
+SkOpSegment::markDone id=18 (581.398987,439.601013 580.265991,443.054016) t=0.000339103907 [42] (581.398621,439.602173) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
+SkOpSegment::markDone id=8 (584.085999,431.335999 585.210999,427.875) t=0 [15] (584.085999,431.335999) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
+SkOpSegment::markDone id=5 (585.210022,427.875 584.085999,431.335999) t=0 [9] (585.210022,427.875) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=0 oppValue=0
+-------------------------------------- findOverlaps
+SkOpSegment::debugShowActiveSpans id=1 (584.085999,431.335999 582.937988,430.960999 581.757996,431.085999 580.765991,431.593994) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (580.765991,431.593994 579.773987,432.10199 578.97699,432.97699 578.60199,434.125) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (578.60199,434.125 575.14801,433) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=4 (575.14801,433 576.515015,428.796997 581.015015,426.515991 585.210022,427.875) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=6 (586.875,436.812012 587.25,435.664001 587.125,434.5 586.617004,433.492004) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (586.617004,433.492004 586.101013,432.5 585.234009,431.703003 584.085999,431.335999) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=9 (585.210999,427.875 589.406006,429.242004 591.695007,433.734009 590.328003,437.937012) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (590.328003,437.937012 586.875,436.812012) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=16 (578.60199,434.125 578.234985,435.27301 578.35199,436.437012 578.859985,437.445007) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=17 (578.859985,437.445007 579.367981,438.437012 580.250977,439.226013 581.398987,439.601013) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=18 (581.398987,439.601013 581.398621,439.602173) t=0 tEnd=0.000339103907 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (580.265991,443.054016 576.071373,441.687139 573.782422,437.202848 575.148621,433.000183) t=0 tEnd=0.999907158 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=19 (575.148621,433.000183 575.148747,432.999793 575.14886,432.999414 575.148987,432.999023) t=0.999907158 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=20 (575.148987,432.999023 578.60199,434.125) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=11 (581.39801,439.60199 582.539001,439.968994 583.710022,439.85199 584.710022,439.343994) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=12 (584.710022,439.343994 585.702026,438.835999 586.499023,437.960999 586.874023,436.812988) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=13 (586.874023,436.812988 590.327026,437.937988) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=14 (590.327026,437.937988 588.952026,442.132996 584.468018,444.421997 580.265015,443.054993) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=15 (580.265015,443.054993 580.265381,443.053833) t=0 tEnd=0.000339103907 windSum=? windValue=1
+-------------------------------------- calc_angles
+SkOpSegment::sortAngles [1] tStart=0 [1]
+SkOpSegment::sortAngles [2] tStart=1 [4]
+SkOpAngle::after [2/2] 5/5 tStart=1 tEnd=0 < [16/9] 21/25 tStart=0 tEnd=1 < [20/14] 13/13 tStart=1 tEnd=0 F 4
+SkOpAngle::afterPart {{{578.60199,434.125}, {578.97699,432.97699}, {579.773987,432.10199}, {580.765991,431.593994}}} id=2
+SkOpAngle::afterPart {{{578.60199,434.125}, {578.234985,435.27301}, {578.35199,436.437012}, {578.859985,437.445007}}} id=16
+SkOpAngle::afterPart {{{578.60199,434.125}, {575.148987,432.999023}}} id=20
+SkOpAngle::after [2/2] 5/5 tStart=1 tEnd=0 < [3/3] 13/13 tStart=0 tEnd=1 < [20/14] 13/13 tStart=1 tEnd=0 F 7
+SkOpAngle::afterPart {{{578.60199,434.125}, {578.97699,432.97699}, {579.773987,432.10199}, {580.765991,431.593994}}} id=2
+SkOpAngle::afterPart {{{578.60199,434.125}, {575.14801,433}}} id=3
+SkOpAngle::afterPart {{{578.60199,434.125}, {575.148987,432.999023}}} id=20
+SkOpAngle::after [20/14] 13/13 tStart=1 tEnd=0 < [3/3] 13/13 tStart=0 tEnd=1 < [16/9] 21/25 tStart=0 tEnd=1 T 7
+SkOpAngle::afterPart {{{578.60199,434.125}, {575.148987,432.999023}}} id=20
+SkOpAngle::afterPart {{{578.60199,434.125}, {575.14801,433}}} id=3
+SkOpAngle::afterPart {{{578.60199,434.125}, {578.234985,435.27301}, {578.35199,436.437012}, {578.859985,437.445007}}} id=16
+SkOpSegment::sortAngles [3] tStart=0 [5]
+SkOpSegment::sortAngles [3] tStart=1 [6]
+SkOpAngle::after [3/4] 29/29 tStart=1 tEnd=0 < [19/13] 5/5 tStart=0.999907158 tEnd=1 < [19/12] 21/25 tStart=0.999907158 tEnd=0 T 4
+SkOpAngle::afterPart {{{575.148621,433.000183}, {578.6026,434.125183}}} id=3
+SkOpAngle::afterPart {{{575.148621,433.000183}, {575.148987,432.999023}, {575.14886,432.999414}, {575.148987,432.999023}}} id=19
+SkOpAngle::afterPart {{{575.148621,433.000183}, {573.782422,437.202848}, {576.071373,441.687139}, {580.265991,443.054016}}} id=19
+SkOpAngle::after [3/4] 29/29 tStart=1 tEnd=0 < [4/5] 5/1 tStart=0 tEnd=1 < [19/13] 5/5 tStart=0.999907158 tEnd=1 T 7
+SkOpAngle::afterPart {{{575.14801,433}, {578.60199,434.125}}} id=3
+SkOpAngle::afterPart {{{575.14801,433}, {576.515015,428.796997}, {581.015015,426.515991}, {585.210022,427.875}}} id=4
+SkOpAngle::afterPart {{{575.14801,433}, {575.148376,432.99884}, {575.14825,432.999231}, {575.148376,432.99884}}} id=19
+SkOpSegment::sortAngles [4] tStart=0 [7]
+SkOpSegment::sortAngles [4] tStart=1 [8]
+SkOpSegment::sortAngles [7] tStart=1 [14]
+SkOpSegment::sortAngles [9] tStart=0 [17]
+SkOpSegment::sortAngles [16] tStart=0 [31]
+SkOpSegment::sortAngles [18] tStart=0.000339103907 [42]
+SkOpSegment::sortAngles [19] tStart=0 [37]
+SkOpSegment::sortAngles [19] tStart=0.999907158 [41]
+SkOpSegment::sortAngles [20] tStart=1 [40]
+SkOpSegment::sortAngles [11] tStart=0 [21]
+SkOpSegment::sortAngles [15] tStart=0.000339103907 [43]
+coinSpan - id=15 t=0.000339103907 tEnd=1
+coinSpan + id=18 t=1 tEnd=0.000339103907
+coinSpan - id=8 t=0 tEnd=1
+coinSpan + id=5 t=1 tEnd=0
+SkOpSpan::sortableTop dir=kTop seg=1 t=0.5 pt=(582.367493,431.133881)
+SkOpSpan::sortableTop [0] valid=1 operand=0 span=7 ccw=1 seg=4 {{{575.14801f, 433}, {576.515015f, 428.796997f}, {581.015015f, 426.515991f}, {585.210022f, 427.875f}}} t=0.774700227 pt=(582.367493,427.491089) slope=(12.4737739,-0.581920821)
+SkOpSpan::sortableTop [1] valid=1 operand=0 span=1 ccw=0 seg=1 {{{584.085999f, 431.335999f}, {582.937988f, 430.960999f}, {581.757996f, 431.085999f}, {580.765991f, 431.593994f}}} t=0.5 pt=(582.367493,431.133881) slope=(-3.375,0.287246704)
+SkOpSegment::markWinding id=4 (575.14801,433 576.515015,428.796997 581.015015,426.515991 585.210022,427.875) t=0 [7] (575.14801,433) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markWinding id=9 (585.210999,427.875 589.406006,429.242004 591.695007,433.734009 590.328003,437.937012) t=0 [17] (585.210999,427.875) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=10 (590.328003,437.937012 586.875,436.812012) t=0 [19] (590.328003,437.937012) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=6 (586.875,436.812012 587.25,435.664001 587.125,434.5 586.617004,433.492004) t=0 [11] (586.875,436.812012) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=7 (586.617004,433.492004 586.101013,432.5 585.234009,431.703003 584.085999,431.335999) t=0 [13] (586.617004,433.492004) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markWinding id=1 (584.085999,431.335999 582.937988,430.960999 581.757996,431.085999 580.765991,431.593994) t=0 [1] (584.085999,431.335999) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=2 (580.765991,431.593994 579.773987,432.10199 578.97699,432.97699 578.60199,434.125) t=0 [3] (580.765991,431.593994) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=4 (575.14801,433 576.515015,428.796997 581.015015,426.515991 585.210022,427.875) t=0 [7] (575.14801,433) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=1 (584.085999,431.335999 582.937988,430.960999 581.757996,431.085999 580.765991,431.593994) t=0 [1] (584.085999,431.335999) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=1 from=(580.765991,431.593994) to=(584.085999,431.335999)
+path.moveTo(580.765991,431.593994);
+path.cubicTo(581.757996,431.085999, 582.937988,430.960999, 584.085999,431.335999);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=7 (586.617004,433.492004 586.101013,432.5 585.234009,431.703003 584.085999,431.335999) t=0 [13] (586.617004,433.492004) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=7 from=(584.085999,431.335999) to=(586.617004,433.492004)
+path.cubicTo(585.234009,431.703003, 586.101013,432.5, 586.617004,433.492004);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=6 (586.875,436.812012 587.25,435.664001 587.125,434.5 586.617004,433.492004) t=0 [11] (586.875,436.812012) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=6 from=(586.617004,433.492004) to=(586.875,436.812012)
+path.cubicTo(587.125,434.5, 587.25,435.664001, 586.875,436.812012);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=10 (590.328003,437.937012 586.875,436.812012) t=0 [19] (590.328003,437.937012) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=10 from=(586.875,436.812012) to=(590.328003,437.937012)
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=9 (585.210999,427.875 589.406006,429.242004 591.695007,433.734009 590.328003,437.937012) t=0 [17] (585.210999,427.875) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=9 from=(590.328003,437.937012) to=(585.210999,427.875)
+path.lineTo(590.328003,437.937012);
+path.cubicTo(591.695007,433.734009, 589.406006,429.242004, 585.210999,427.875);
+SkOpSegment::markWinding id=19 (580.265991,443.054016 576.070984,441.687012 573.781982,437.202026 575.148987,432.999023) t=0.999907158 [41] (575.148621,433.000183) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markWinding id=20 (575.148987,432.999023 578.60199,434.125) t=0 [39] (575.148987,432.999023) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=20 span=40
+SkOpSegment::markWinding id=19 (580.265991,443.054016 576.070984,441.687012 573.781982,437.202026 575.148987,432.999023) t=0 [37] (580.265991,443.054016) tEnd=0.999907158 newWindSum=1 windSum=? windValue=1
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markWinding id=15 (580.265015,443.054993 581.39801,439.60199) t=0 [29] (580.265015,443.054993) tEnd=0.000339103907 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markWinding id=14 (590.327026,437.937988 588.952026,442.132996 584.468018,444.421997 580.265015,443.054993) t=0 [27] (590.327026,437.937988) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markWinding id=13 (586.874023,436.812988 590.327026,437.937988) t=0 [25] (586.874023,436.812988) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markWinding id=12 (584.710022,439.343994 585.702026,438.835999 586.499023,437.960999 586.874023,436.812988) t=0 [23] (584.710022,439.343994) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markWinding id=11 (581.39801,439.60199 582.539001,439.968994 583.710022,439.85199 584.710022,439.343994) t=0 [21] (581.39801,439.60199) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markWinding id=18 (581.398987,439.601013 580.265991,443.054016) t=0 [35] (581.398987,439.601013) tEnd=0.000339103907 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markWinding id=17 (578.859985,437.445007 579.367981,438.437012 580.250977,439.226013 581.398987,439.601013) t=0 [33] (578.859985,437.445007) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markWinding id=16 (578.60199,434.125 578.234985,435.27301 578.35199,436.437012 578.859985,437.445007) t=0 [31] (578.60199,434.125) tEnd=1 newWindSum=1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=16 span=31 windSum=1
+SkOpSegment::markWinding id=3 (578.60199,434.125 575.14801,433) t=0 [5] (578.60199,434.125) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=3 span=5 windSum=-1
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [4/5] next=19/13 sect=5/1 s=0 [7] e=1 [8] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpAngle::dumpOne [19/13] next=19/12 sect=5/5 s=0.999907158 [41] e=1 [38] sgn=-1 windVal=1 windSum=1
+SkOpAngle::dumpOne [19/12] next=3/4 sect=21/25 s=0.999907158 [41] e=0 [37] sgn=1 windVal=1 windSum=1
+SkOpAngle::dumpOne [3/4] next=4/5 sect=29/29 s=1 [6] e=0 [5] sgn=1 windVal=1 windSum=-1
+SkOpSegment::findNextWinding chase.append segment=20 span=40
+SkOpSegment::findNextWinding chase.append segment=16 span=31 windSum=1
+SkOpSegment::findNextWinding chase.append segment=3 span=5 windSum=-1
+SkOpSegment::markDone id=4 (575.14801,433 576.515015,428.796997 581.015015,426.515991 585.210022,427.875) t=0 [7] (575.14801,433) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[4] to:[19] start=107589448 end=107588904
+bridgeWinding current id=4 from=(585.210022,427.875) to=(575.14801,433)
+path.cubicTo(581.015015,426.515991, 576.515015,428.796997, 575.14801,433);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=19 (580.265991,443.054016 576.070984,441.687012 573.781982,437.202026 575.148987,432.999023) t=0.999907158 [41] (575.148621,433.000183) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+bridgeWinding current id=19 from=(575.148621,433.000183) to=(575.148987,432.999023)
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [20/14] next=3/3 sect=13/13 s=1 [40] e=0 [39] sgn=1 windVal=1 windSum=1
+SkOpAngle::dumpOne [3/3] next=16/9 sect=13/13 s=0 [5] e=1 [6] sgn=-1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [16/9] next=2/2 sect=21/25 s=0 [31] e=1 [32] sgn=-1 windVal=1 windSum=1
+SkOpAngle::dumpOne [2/2] next=20/14 sect=5/5 s=1 [4] e=0 [3] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpSegment::markDone id=16 (578.60199,434.125 578.234985,435.27301 578.35199,436.437012 578.859985,437.445007) t=0 [31] (578.60199,434.125) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=17 (578.859985,437.445007 579.367981,438.437012 580.250977,439.226013 581.398987,439.601013) t=0 [33] (578.859985,437.445007) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=18 (581.398987,439.601013 580.265991,443.054016) t=0 [35] (581.398987,439.601013) tEnd=0.000339103907 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markDone id=11 (581.39801,439.60199 582.539001,439.968994 583.710022,439.85199 584.710022,439.343994) t=0 [21] (581.39801,439.60199) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=12 (584.710022,439.343994 585.702026,438.835999 586.499023,437.960999 586.874023,436.812988) t=0 [23] (584.710022,439.343994) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=13 (586.874023,436.812988 590.327026,437.937988) t=0 [25] (586.874023,436.812988) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=14 (590.327026,437.937988 588.952026,442.132996 584.468018,444.421997 580.265015,443.054993) t=0 [27] (590.327026,437.937988) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=15 (580.265015,443.054993 581.39801,439.60199) t=0 [29] (580.265015,443.054993) tEnd=0.000339103907 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::nextChase mismatched signs
+SkOpSegment::markDone id=19 (580.265991,443.054016 576.070984,441.687012 573.781982,437.202026 575.148987,432.999023) t=0 [37] (580.265991,443.054016) tEnd=0.999907158 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=2 (580.765991,431.593994 579.773987,432.10199 578.97699,432.97699 578.60199,434.125) t=0 [3] (580.765991,431.593994) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::markDone id=20 (575.148987,432.999023 578.60199,434.125) t=0 [39] (575.148987,432.999023) tEnd=1 newWindSum=1 newOppSum=? oppSum=? windSum=1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[20] to:[3] start=84323264 end=84323408
+bridgeWinding current id=20 from=(575.148987,432.999023) to=(578.60199,434.125)
+path.lineTo(575.148987,432.999023);
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [3/4] next=4/5 sect=29/29 s=1 [6] e=0 [5] sgn=1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [4/5] next=19/13 sect=5/1 s=0 [7] e=1 [8] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0 done
+SkOpAngle::dumpOne [19/13] next=19/12 sect=5/5 s=0.999907158 [41] e=1 [38] sgn=-1 windVal=1 windSum=1 done
+SkOpAngle::dumpOne [19/12] next=3/4 sect=21/25 s=0.999907158 [41] e=0 [37] sgn=1 windVal=1 windSum=1 done
+SkOpSegment::markDone id=3 (578.60199,434.125 575.14801,433) t=0 [5] (578.60199,434.125) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[3] to:[19] start=107589448 end=107588760
+bridgeWinding current id=3 from=(578.60199,434.125) to=(575.14801,433)
+path.lineTo(578.60199,434.125);
+path.lineTo(575.14801,433);
+</div>
+
<div id="joel_9">
SkDCubic::ComplexBreak
{{{135.9219970703125, 286.843994140625}, {137.0699920654296875, 287.218994140625}, {138.24200439453125, 287.08599853515625}, {139.24200439453125, 286.5780029296875}}},
@@ -217,103 +987,59 @@ SkOpSegment::debugShowActiveSpans id=5 (134.797012,290.296997 134.797302,290.296
-------------------------------------- calc_angles
SkOpSegment::sortAngles [11] tStart=0 [21]
SkOpSegment::sortAngles [12] tStart=1 [24]
-SkOpAngle::debugAfter [12/2] 5/5 tStart=1 tEnd=0 < [6/13] 21/25 tStart=0 tEnd=1 < [10/18] 13/13 tStart=1 tEnd=0 F 4
+SkOpAngle::after [12/2] 5/5 tStart=1 tEnd=0 < [6/13] 21/25 tStart=0 tEnd=1 < [10/18] 13/13 tStart=1 tEnd=0 F 4
SkOpAngle::afterPart {{{133.132996,281.367004}, {133.507996,280.218994}, {134.296997,279.343994}, {135.296997,278.835999}}} id=12
SkOpAngle::afterPart {{{133.132996,281.367004}, {132.757996,282.507996}, {132.882996,283.687012}, {133.390991,284.679016}}} id=6
SkOpAngle::afterPart {{{133.132996,281.367004}, {129.679993,280.241028}}} id=10
-SkOpAngle::debugAfter [12/2] 5/5 tStart=1 tEnd=0 < [13/3] 13/13 tStart=0 tEnd=1 < [10/18] 13/13 tStart=1 tEnd=0 F 9
+SkOpAngle::after [12/2] 5/5 tStart=1 tEnd=0 < [13/3] 13/13 tStart=0 tEnd=1 < [10/18] 13/13 tStart=1 tEnd=0 F 7
SkOpAngle::afterPart {{{133.132996,281.367004}, {133.507996,280.218994}, {134.296997,279.343994}, {135.296997,278.835999}}} id=12
SkOpAngle::afterPart {{{133.132996,281.367004}, {129.679993,280.242004}}} id=13
SkOpAngle::afterPart {{{133.132996,281.367004}, {129.679993,280.241028}}} id=10
-SkOpAngle::debugAfter [10/18] 13/13 tStart=1 tEnd=0 < [13/3] 13/13 tStart=0 tEnd=1 < [6/13] 21/25 tStart=0 tEnd=1 T 9
+SkOpAngle::after [10/18] 13/13 tStart=1 tEnd=0 < [13/3] 13/13 tStart=0 tEnd=1 < [6/13] 21/25 tStart=0 tEnd=1 T 7
SkOpAngle::afterPart {{{133.132996,281.367004}, {129.679993,280.241028}}} id=10
SkOpAngle::afterPart {{{133.132996,281.367004}, {129.679993,280.242004}}} id=13
SkOpAngle::afterPart {{{133.132996,281.367004}, {132.757996,282.507996}, {132.882996,283.687012}, {133.390991,284.679016}}} id=6
SkOpSegment::sortAngles [13] tStart=0 [25]
SkOpSegment::sortAngles [14] tStart=7.00240426e-05 [43]
-ccwOf {{{129.680283,280.241119}, {129.680187,280.241414}}} id=1
-ccwOf {{{129.679993,280.241028}, {128.313004,284.437012}}} id=2
-ccwOf {{{129.680283,280.241119}, {139.741989,275.117004}}} id=1
-ccwOf {{{129.679993,280.241028}, {134.796997,290.296021}}} id=2
-ccwOf {{{129.680283,280.241119}, {139.741989,275.117004}}} id=1
-ccwOf {{{129.680283,280.241119}, {129.680088,280.24171}}} id=2
-ccwOf {{{129.680283,280.241119}, {131.047629,276.03868}}} id=1
-ccwOf {{{129.680283,280.241119}, {129.680088,280.24171}}} id=2
-ccwOf {{{129.680283,280.241119}, {131.047629,276.03868}}} id=1
-ccwOf {{{129.679993,280.241028}, {128.313004,284.437012}}} id=2
-ccwOf {{{129.680283,280.241119}, {129.680088,280.24171}}} id=1
-ccwOf {{{129.679993,280.241028}, {134.796997,290.296021}}} id=2
-SkOpAngle::debugAfter [14/4] 21/21 tStart=7.00240426e-05 tEnd=0 < [9/16] 21/25 tStart=1 tEnd=0 < [14/5] 5/1 tStart=7.00240426e-05 tEnd=1 T 14
-SkOpAngle::afterPart {{{129.680283,280.241119}, {129.679993,280.242004}, {129.680088,280.24171}, {129.679993,280.242004}}} id=14
+SkOpAngle::after [14/4] 21/21 tStart=7.00240426e-05 tEnd=0 < [9/16] 21/25 tStart=1 tEnd=0 < [14/5] 5/1 tStart=7.00240426e-05 tEnd=1 T 12
+SkOpAngle::afterPart {{{129.679993,280.241028}, {129.679703,280.241913}, {129.679798,280.241619}, {129.679703,280.241913}}} id=14
SkOpAngle::afterPart {{{129.679993,280.241028}, {128.313004,284.437012}, {130.60199,288.929016}, {134.796997,290.296021}}} id=9
-SkOpAngle::afterPart {{{129.680283,280.241119}, {131.047629,276.03868}, {135.539281,273.758091}, {139.741989,275.117004}}} id=14
-ccwOf {{{129.680283,280.241119}, {129.680187,280.241414}}} id=1
-ccwOf {{{129.679993,280.241028}, {133.132996,281.367004}}} id=2
-ccwOf {{{129.679993,280.241028}, {128.313004,284.437012}}} id=1
-ccwOf {{{129.679993,280.241028}, {133.132996,281.367004}}} id=2
-ccwOf {{{129.679993,280.241028}, {128.313004,284.437012}}} id=1
-ccwOf {{{129.680283,280.241119}, {129.680088,280.24171}}} id=2
-ccwOf {{{129.679993,280.241028}, {134.796997,290.296021}}} id=1
-ccwOf {{{129.680283,280.241119}, {129.680088,280.24171}}} id=2
-ccwOf {{{129.679993,280.241028}, {134.796997,290.296021}}} id=1
-ccwOf {{{129.679993,280.241028}, {133.132996,281.367004}}} id=2
-SkOpAngle::debugAfter [14/4] 21/21 tStart=7.00240426e-05 tEnd=0 < [10/17] 29/29 tStart=0 tEnd=1 < [9/16] 21/25 tStart=1 tEnd=0 F 8
+SkOpAngle::afterPart {{{129.679993,280.241028}, {131.047339,276.038588}, {135.538991,273.757999}, {139.741699,275.116913}}} id=14
+SkOpAngle::after [14/4] 21/21 tStart=7.00240426e-05 tEnd=0 < [10/17] 29/29 tStart=0 tEnd=1 < [9/16] 21/25 tStart=1 tEnd=0 F 5
SkOpAngle::afterPart {{{129.679993,280.241028}, {129.679703,280.241913}, {129.679798,280.241619}, {129.679703,280.241913}}} id=14
SkOpAngle::afterPart {{{129.679993,280.241028}, {133.132996,281.367004}}} id=10
SkOpAngle::afterPart {{{129.679993,280.241028}, {128.313004,284.437012}, {130.60199,288.929016}, {134.796997,290.296021}}} id=9
-SkOpAngle::debugAfter [9/16] 21/25 tStart=1 tEnd=0 < [10/17] 29/29 tStart=0 tEnd=1 < [14/5] 5/1 tStart=7.00240426e-05 tEnd=1 T 4
+SkOpAngle::after [9/16] 21/25 tStart=1 tEnd=0 < [10/17] 29/29 tStart=0 tEnd=1 < [14/5] 5/1 tStart=7.00240426e-05 tEnd=1 T 4
SkOpAngle::afterPart {{{129.679993,280.241028}, {128.313004,284.437012}, {130.60199,288.929016}, {134.796997,290.296021}}} id=9
SkOpAngle::afterPart {{{129.679993,280.241028}, {133.132996,281.367004}}} id=10
SkOpAngle::afterPart {{{129.679993,280.241028}, {131.047339,276.038588}, {135.538991,273.757999}, {139.741699,275.116913}}} id=14
SkOpSegment::sortAngles [15] tStart=0.00025401744 [42]
SkOpSegment::sortAngles [16] tStart=0 [31]
-SkOpAngle::debugAfter [16/7] 5/9 tStart=0 tEnd=1 < [2/20] 21/21 tStart=1 tEnd=0 < [3/21] 29/29 tStart=0 tEnd=1 T 4
+SkOpAngle::after [16/7] 5/9 tStart=0 tEnd=1 < [2/20] 21/21 tStart=1 tEnd=0 < [3/21] 29/29 tStart=0 tEnd=1 T 4
SkOpAngle::afterPart {{{141.406006,284.054993}, {141.77301,282.906982}, {141.64801,281.734985}, {141.14801,280.734985}}} id=16
SkOpAngle::afterPart {{{141.406006,284.054993}, {141.031006,285.203003}, {140.234009,286.078003}, {139.242004,286.578003}}} id=2
SkOpAngle::afterPart {{{141.406006,284.054993}, {144.859009,285.171997}}} id=3
-SkOpAngle::debugAfter [16/7] 5/9 tStart=0 tEnd=1 < [20/12] 29/29 tStart=1 tEnd=0 < [2/20] 21/21 tStart=1 tEnd=0 F 4
+SkOpAngle::after [16/7] 5/9 tStart=0 tEnd=1 < [20/12] 29/29 tStart=1 tEnd=0 < [2/20] 21/21 tStart=1 tEnd=0 F 4
SkOpAngle::afterPart {{{141.406006,284.054993}, {141.77301,282.906982}, {141.64801,281.734985}, {141.14801,280.734985}}} id=16
SkOpAngle::afterPart {{{141.406006,284.054993}, {144.859009,285.172974}}} id=20
SkOpAngle::afterPart {{{141.406006,284.054993}, {141.031006,285.203003}, {140.234009,286.078003}, {139.242004,286.578003}}} id=2
-SkOpAngle::debugAfter [2/20] 21/21 tStart=1 tEnd=0 < [20/12] 29/29 tStart=1 tEnd=0 < [3/21] 29/29 tStart=0 tEnd=1 T 9
+SkOpAngle::after [2/20] 21/21 tStart=1 tEnd=0 < [20/12] 29/29 tStart=1 tEnd=0 < [3/21] 29/29 tStart=0 tEnd=1 T 7
SkOpAngle::afterPart {{{141.406006,284.054993}, {141.031006,285.203003}, {140.234009,286.078003}, {139.242004,286.578003}}} id=2
SkOpAngle::afterPart {{{141.406006,284.054993}, {144.859009,285.172974}}} id=20
SkOpAngle::afterPart {{{141.406006,284.054993}, {144.859009,285.171997}}} id=3
SkOpSegment::sortAngles [18] tStart=0.00025401744 [41]
SkOpSegment::sortAngles [19] tStart=0 [37]
SkOpSegment::sortAngles [19] tStart=1 [38]
-ccwOf {{{144.859009,285.172974}, {139.742004,275.117981}}} id=1
-ccwOf {{{144.858719,285.172882}, {144.858913,285.172292}}} id=2
-ccwOf {{{144.859009,285.172974}, {141.406006,284.054993}}} id=1
-ccwOf {{{144.858719,285.172882}, {144.858815,285.172588}}} id=2
-ccwOf {{{144.859009,285.172974}, {141.406006,284.054993}}} id=1
-ccwOf {{{144.859009,285.172974}, {146.219009,280.97699}}} id=2
-ccwOf {{{144.859009,285.172974}, {141.406006,284.054993}}} id=1
-ccwOf {{{144.859009,285.172974}, {139.742004,275.117981}}} id=2
-ccwOf {{{144.859009,285.172974}, {146.219009,280.97699}}} id=1
-ccwOf {{{144.858719,285.172882}, {144.858815,285.172588}}} id=2
-SkOpAngle::debugAfter [19/10] 5/9 tStart=1 tEnd=0 < [4/22] 5/5 tStart=7.00717611e-05 tEnd=0 < [20/11] 13/13 tStart=0 tEnd=1 F 9
-SkOpAngle::afterPart {{{144.859009,285.172974}, {146.219009,280.97699}, {143.937012,276.492981}, {139.742004,275.117981}}} id=19
+SkOpAngle::after [19/10] 5/9 tStart=1 tEnd=0 < [4/22] 5/5 tStart=7.00717611e-05 tEnd=0 < [20/11] 13/13 tStart=0 tEnd=1 F 7
+SkOpAngle::afterPart {{{144.858719,285.172882}, {146.218719,280.976898}, {143.936722,276.492889}, {139.741714,275.117889}}} id=19
SkOpAngle::afterPart {{{144.858719,285.172882}, {144.859009,285.171997}, {144.858913,285.172292}, {144.859009,285.171997}}} id=4
-SkOpAngle::afterPart {{{144.859009,285.172974}, {141.406006,284.054993}}} id=20
-ccwOf {{{144.859009,285.172974}, {139.742004,275.117981}}} id=1
-ccwOf {{{144.858719,285.172882}, {134.797012,290.296997}}} id=2
-ccwOf {{{144.859009,285.172974}, {141.406006,284.054993}}} id=1
-ccwOf {{{144.858719,285.172882}, {143.491371,289.375321}}} id=2
-ccwOf {{{144.859009,285.172974}, {141.406006,284.054993}}} id=1
-ccwOf {{{144.859009,285.172974}, {146.219009,280.97699}}} id=2
-ccwOf {{{144.859009,285.172974}, {141.406006,284.054993}}} id=1
-ccwOf {{{144.859009,285.172974}, {139.742004,275.117981}}} id=2
-ccwOf {{{144.859009,285.172974}, {141.406006,284.054993}}} id=1
-ccwOf {{{144.858719,285.172882}, {134.797012,290.296997}}} id=2
-ccwOf {{{144.859009,285.172974}, {146.219009,280.97699}}} id=1
-ccwOf {{{144.858719,285.172882}, {143.491371,289.375321}}} id=2
-SkOpAngle::debugAfter [19/10] 5/9 tStart=1 tEnd=0 < [4/23] 21/17 tStart=7.00717611e-05 tEnd=1 < [20/11] 13/13 tStart=0 tEnd=1 F 7
+SkOpAngle::afterPart {{{144.858719,285.172882}, {141.405716,284.054901}}} id=20
+SkOpAngle::after [19/10] 5/9 tStart=1 tEnd=0 < [4/23] 21/17 tStart=7.00717611e-05 tEnd=1 < [20/11] 13/13 tStart=0 tEnd=1 F 4
SkOpAngle::afterPart {{{144.858719,285.172882}, {146.218719,280.976898}, {143.936722,276.492889}, {139.741714,275.117889}}} id=19
SkOpAngle::afterPart {{{144.858719,285.172882}, {143.491371,289.375321}, {138.99171,291.655911}, {134.797012,290.296997}}} id=4
SkOpAngle::afterPart {{{144.858719,285.172882}, {141.405716,284.054901}}} id=20
-SkOpAngle::debugAfter [20/11] 13/13 tStart=0 tEnd=1 < [4/23] 21/17 tStart=7.00717611e-05 tEnd=1 < [4/22] 5/5 tStart=7.00717611e-05 tEnd=0 T 4
-SkOpAngle::afterPart {{{144.859009,285.172974}, {141.406006,284.054993}}} id=20
+SkOpAngle::after [20/11] 13/13 tStart=0 tEnd=1 < [4/23] 21/17 tStart=7.00717611e-05 tEnd=1 < [4/22] 5/5 tStart=7.00717611e-05 tEnd=0 T 4
+SkOpAngle::afterPart {{{144.858719,285.172882}, {141.405716,284.054901}}} id=20
SkOpAngle::afterPart {{{144.858719,285.172882}, {143.491371,289.375321}, {138.99171,291.655911}, {134.797012,290.296997}}} id=4
SkOpAngle::afterPart {{{144.858719,285.172882}, {144.859009,285.171997}, {144.858913,285.172292}, {144.859009,285.171997}}} id=4
SkOpSegment::sortAngles [20] tStart=0 [39]
@@ -386,7 +1112,7 @@ SkOpSegment::markDone id=3 (141.406006,284.054993 144.859009,285.171997) t=0 [5]
SkOpSegment::markDone id=4 (144.859009,285.171997 143.492004,289.375 138.992004,291.656006 134.797012,290.296997) t=0 [7] (144.859009,285.171997) tEnd=7.00717611e-05 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
SkOpSegment::findNextWinding chase.append segment=4 span=44 windSum=-2147483647
SkOpSegment::markDone id=16 (141.406006,284.054993 141.77301,282.906982 141.64801,281.734985 141.14801,280.734985) t=0 [31] (141.406006,284.054993) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
-SkOpSegment::findNextWinding from:[16] to:[2] start=4746648 end=4746504
+SkOpSegment::findNextWinding from:[16] to:[2] start=84323080 end=84322936
bridgeWinding current id=16 from=(141.14801,280.734985) to=(141.406006,284.054993)
path.cubicTo(141.64801,281.734985, 141.77301,282.906982, 141.406006,284.054993);
SkOpSegment::findNextWinding simple
@@ -422,7 +1148,7 @@ SkOpSegment::markDone id=13 (133.132996,281.367004 129.679993,280.242004) t=0 [2
SkOpSegment::markDone id=14 (129.679993,280.242004 131.046997,276.039001 135.538986,273.757996 139.741989,275.117004) t=0 [27] (129.679993,280.242004) tEnd=7.00240426e-05 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
SkOpSegment::findNextWinding chase.append segment=14 span=43 windSum=-1
SkOpSegment::markDone id=6 (133.132996,281.367004 132.757996,282.507996 132.882996,283.687012 133.390991,284.679016) t=0 [11] (133.132996,281.367004) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
-SkOpSegment::findNextWinding from:[6] to:[12] start=4750776 end=4750632
+SkOpSegment::findNextWinding from:[6] to:[12] start=107586600 end=107586456
bridgeWinding current id=6 from=(133.390991,284.679016) to=(133.132996,281.367004)
path.cubicTo(132.882996,283.687012, 132.757996,282.507996, 133.132996,281.367004);
SkOpSegment::findNextWinding simple
@@ -457,7 +1183,7 @@ SkOpAngle::dumpOne [20/11] next=4/23 sect=13/13 s=0 [39] e=1 [40] sgn=-1 windVa
SkOpAngle::dumpOne [4/23] next=4/22 sect=21/17 s=7.00717611e-05 [44] e=1 [8] sgn=-1 windVal=1 windSum=-2
SkOpAngle::dumpOne [4/22] next=19/10 sect=5/5 s=7.00717611e-05 [44] e=0 [7] sgn=1 windVal=1 windSum=-2 done
SkOpSegment::markDone id=19 (139.742004,275.117981 143.937012,276.492981 146.219009,280.97699 144.859009,285.172974) t=0 [37] (139.742004,275.117981) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
-SkOpSegment::findNextWinding from:[19] to:[4] start=4754056 end=4747144
+SkOpSegment::findNextWinding from:[19] to:[4] start=107589880 end=84323576
bridgeWinding current id=19 from=(139.742004,275.117981) to=(144.859009,285.172974)
path.lineTo(139.741699,275.117889);
path.cubicTo(143.937012,276.492981, 146.219009,280.97699, 144.859009,285.172974);
@@ -471,11 +1197,400 @@ SkOpSegment::markDone id=5 (134.797012,290.296997 135.921997,286.843994) t=0 [9]
SkOpSegment::markDone id=4 (144.859009,285.171997 143.492004,289.375 138.992004,291.656006 134.797012,290.296997) t=7.00717611e-05 [44] (144.858719,285.172882) tEnd=1 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
</div>
+<div id="issue3838">
+seg=1 {{{200, 170}, {220, 170}}}
+seg=2 {{{220, 170}, {220, 230}}}
+seg=3 {{{220, 230}, {240, 230}}}
+seg=4 {{{240, 230}, {240, 210}}}
+seg=5 {{{240, 210}, {180, 210}}}
+seg=6 {{{180, 210}, {180, 190}}}
+seg=7 {{{180, 190}, {260, 190}}}
+seg=8 {{{260, 190}, {260, 250}}}
+seg=9 {{{260, 250}, {200, 250}}}
+seg=10 {{{200, 250}, {200, 170}}}
+debugShowLineIntersection wtTs[0]=0 {{{220,170}, {220,230}}} {{220,170}} wnTs[0]=1 {{{200,170}, {220,170}}}
+debugShowLineIntersection wtTs[0]=1 {{{200,250}, {200,170}}} {{200,170}} wnTs[0]=0 {{{200,170}, {220,170}}}
+debugShowLineIntersection wtTs[0]=0 {{{220,230}, {240,230}}} {{220,230}} wnTs[0]=1 {{{220,170}, {220,230}}}
+debugShowLineIntersection wtTs[0]=0.333333333 {{{240,210}, {180,210}}} {{220,210}} wnTs[0]=0.666667 {{{220,170}, {220,230}}}
+SkOpSegment::addT insert t=0.666666667 segID=2 spanID=21
+SkOpSegment::addT insert t=0.333333333 segID=5 spanID=22
+debugShowLineIntersection wtTs[0]=0.5 {{{180,190}, {260,190}}} {{220,190}} wnTs[0]=0.333333 {{{220,170}, {220,230}}}
+SkOpSegment::addT insert t=0.333333333 segID=2 spanID=23
+SkOpSegment::addT insert t=0.5 segID=7 spanID=24
+debugShowLineIntersection wtTs[0]=0 {{{240,230}, {240,210}}} {{240,230}} wnTs[0]=1 {{{220,230}, {240,230}}}
+debugShowLineIntersection wtTs[0]=0 {{{240,210}, {180,210}}} {{240,210}} wnTs[0]=1 {{{240,230}, {240,210}}}
+debugShowLineIntersection wtTs[0]=0 {{{180,210}, {180,190}}} {{180,210}} wnTs[0]=1 {{{240,210}, {180,210}}}
+debugShowLineIntersection wtTs[0]=0.5 {{{200,250}, {200,170}}} {{200,210}} wnTs[0]=0.666667 {{{240,210}, {180,210}}}
+SkOpSegment::addT insert t=0.666666667 segID=5 spanID=25
+SkOpSegment::addT insert t=0.5 segID=10 spanID=26
+debugShowLineIntersection wtTs[0]=0 {{{180,190}, {260,190}}} {{180,190}} wnTs[0]=1 {{{180,210}, {180,190}}}
+debugShowLineIntersection wtTs[0]=0 {{{260,190}, {260,250}}} {{260,190}} wnTs[0]=1 {{{180,190}, {260,190}}}
+debugShowLineIntersection wtTs[0]=0.75 {{{200,250}, {200,170}}} {{200,190}} wnTs[0]=0.25 {{{180,190}, {260,190}}}
+SkOpSegment::addT insert t=0.25 segID=7 spanID=27
+SkOpSegment::addT insert t=0.75 segID=10 spanID=28
+debugShowLineIntersection wtTs[0]=0 {{{260,250}, {200,250}}} {{260,250}} wnTs[0]=1 {{{260,190}, {260,250}}}
+debugShowLineIntersection wtTs[0]=0 {{{200,250}, {200,170}}} {{200,250}} wnTs[0]=1 {{{260,250}, {200,250}}}
+-------------------------------------- addExpanded
+SkOpSegment::debugShowActiveSpans id=1 (200,170 220,170) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (220,170 220,190) t=0 tEnd=0.333333333 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (220,190 220,210) t=0.333333333 tEnd=0.666666667 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (220,210 220,230) t=0.666666667 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (220,230 240,230) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=4 (240,230 240,210) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (240,210 220,210) t=0 tEnd=0.333333333 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (220,210 200,210) t=0.333333333 tEnd=0.666666667 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (200,210 180,210) t=0.666666667 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=6 (180,210 180,190) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (180,190 200,190) t=0 tEnd=0.25 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (200,190 220,190) t=0.25 tEnd=0.5 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (220,190 260,190) t=0.5 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=8 (260,190 260,250) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=9 (260,250 200,250) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (200,250 200,210) t=0 tEnd=0.5 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (200,210 200,190) t=0.5 tEnd=0.75 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (200,190 200,170) t=0.75 tEnd=1 windSum=? windValue=1
+-------------------------------------- move_multiples
+-------------------------------------- move_nearby
+-------------------------------------- correctEnds
+-------------------------------------- addEndMovedSpans
+-------------------------------------- expand
+-------------------------------------- addExpanded
+-------------------------------------- mark
+-------------------------------------- missing_coincidence
+-------------------------------------- expand
+-------------------------------------- expand
+-------------------------------------- apply
+-------------------------------------- findOverlaps
+-------------------------------------- calc_angles
+SkOpSegment::sortAngles [2] tStart=0.333333333 [23]
+SkOpAngle::after [2/1] 7/7 tStart=0.333333333 tEnd=0 < [7/11] 15/15 tStart=0.5 tEnd=0.25 < [2/2] 23/23 tStart=0.333333333 tEnd=0.666666667 T 4
+SkOpAngle::afterPart {{{220,190}, {220,170}}} id=2
+SkOpAngle::afterPart {{{220,190}, {200,190}}} id=7
+SkOpAngle::afterPart {{{220,190}, {220,210}}} id=2
+SkOpAngle::after [2/1] 7/7 tStart=0.333333333 tEnd=0 < [7/12] 31/31 tStart=0.5 tEnd=1 < [7/11] 15/15 tStart=0.5 tEnd=0.25 F 4
+SkOpAngle::afterPart {{{220,190}, {220,170}}} id=2
+SkOpAngle::afterPart {{{220,190}, {260,190}}} id=7
+SkOpAngle::afterPart {{{220,190}, {200,190}}} id=7
+SkOpAngle::after [7/11] 15/15 tStart=0.5 tEnd=0.25 < [7/12] 31/31 tStart=0.5 tEnd=1 < [2/2] 23/23 tStart=0.333333333 tEnd=0.666666667 F 4
+SkOpAngle::afterPart {{{220,190}, {200,190}}} id=7
+SkOpAngle::afterPart {{{220,190}, {260,190}}} id=7
+SkOpAngle::afterPart {{{220,190}, {220,210}}} id=2
+SkOpAngle::after [2/2] 23/23 tStart=0.333333333 tEnd=0.666666667 < [7/12] 31/31 tStart=0.5 tEnd=1 < [2/1] 7/7 tStart=0.333333333 tEnd=0 T 4
+SkOpAngle::afterPart {{{220,190}, {220,210}}} id=2
+SkOpAngle::afterPart {{{220,190}, {260,190}}} id=7
+SkOpAngle::afterPart {{{220,190}, {220,170}}} id=2
+SkOpSegment::sortAngles [2] tStart=0.666666667 [21]
+SkOpAngle::after [2/3] 7/7 tStart=0.666666667 tEnd=0.333333333 < [5/5] 31/31 tStart=0.333333333 tEnd=0 < [2/4] 23/23 tStart=0.666666667 tEnd=1 F 4
+SkOpAngle::afterPart {{{220,210}, {220,190}}} id=2
+SkOpAngle::afterPart {{{220,210}, {240,210}}} id=5
+SkOpAngle::afterPart {{{220,210}, {220,230}}} id=2
+SkOpAngle::after [2/3] 7/7 tStart=0.666666667 tEnd=0.333333333 < [5/6] 15/15 tStart=0.333333333 tEnd=0.666666667 < [2/4] 23/23 tStart=0.666666667 tEnd=1 T 4
+SkOpAngle::afterPart {{{220,210}, {220,190}}} id=2
+SkOpAngle::afterPart {{{220,210}, {200,210}}} id=5
+SkOpAngle::afterPart {{{220,210}, {220,230}}} id=2
+SkOpSegment::sortAngles [5] tStart=0.333333333 [22]
+SkOpSegment::sortAngles [5] tStart=0.666666667 [25]
+SkOpAngle::after [5/7] 31/31 tStart=0.666666667 tEnd=0.333333333 < [10/13] 23/23 tStart=0.5 tEnd=0 < [5/8] 15/15 tStart=0.666666667 tEnd=1 F 4
+SkOpAngle::afterPart {{{200,210}, {220,210}}} id=5
+SkOpAngle::afterPart {{{200,210}, {200,250}}} id=10
+SkOpAngle::afterPart {{{200,210}, {180,210}}} id=5
+SkOpAngle::after [5/7] 31/31 tStart=0.666666667 tEnd=0.333333333 < [10/14] 7/7 tStart=0.5 tEnd=0.75 < [5/8] 15/15 tStart=0.666666667 tEnd=1 T 4
+SkOpAngle::afterPart {{{200,210}, {220,210}}} id=5
+SkOpAngle::afterPart {{{200,210}, {200,190}}} id=10
+SkOpAngle::afterPart {{{200,210}, {180,210}}} id=5
+SkOpSegment::sortAngles [7] tStart=0.25 [27]
+SkOpAngle::after [7/9] 15/15 tStart=0.25 tEnd=0 < [10/15] 23/23 tStart=0.75 tEnd=0.5 < [7/10] 31/31 tStart=0.25 tEnd=0.5 T 4
+SkOpAngle::afterPart {{{200,190}, {180,190}}} id=7
+SkOpAngle::afterPart {{{200,190}, {200,210}}} id=10
+SkOpAngle::afterPart {{{200,190}, {220,190}}} id=7
+SkOpAngle::after [7/9] 15/15 tStart=0.25 tEnd=0 < [10/16] 7/7 tStart=0.75 tEnd=1 < [10/15] 23/23 tStart=0.75 tEnd=0.5 F 4
+SkOpAngle::afterPart {{{200,190}, {180,190}}} id=7
+SkOpAngle::afterPart {{{200,190}, {200,170}}} id=10
+SkOpAngle::afterPart {{{200,190}, {200,210}}} id=10
+SkOpAngle::after [10/15] 23/23 tStart=0.75 tEnd=0.5 < [10/16] 7/7 tStart=0.75 tEnd=1 < [7/10] 31/31 tStart=0.25 tEnd=0.5 F 4
+SkOpAngle::afterPart {{{200,190}, {200,210}}} id=10
+SkOpAngle::afterPart {{{200,190}, {200,170}}} id=10
+SkOpAngle::afterPart {{{200,190}, {220,190}}} id=7
+SkOpAngle::after [7/10] 31/31 tStart=0.25 tEnd=0.5 < [10/16] 7/7 tStart=0.75 tEnd=1 < [7/9] 15/15 tStart=0.25 tEnd=0 T 4
+SkOpAngle::afterPart {{{200,190}, {220,190}}} id=7
+SkOpAngle::afterPart {{{200,190}, {200,170}}} id=10
+SkOpAngle::afterPart {{{200,190}, {180,190}}} id=7
+SkOpSegment::sortAngles [7] tStart=0.5 [24]
+SkOpSegment::sortAngles [10] tStart=0.5 [26]
+SkOpSegment::sortAngles [10] tStart=0.75 [28]
+SkOpSpan::sortableTop dir=kTop seg=1 t=0.5 pt=(210,170)
+SkOpSpan::sortableTop [0] valid=1 operand=0 span=1 ccw=1 seg=1 {{{200, 170}, {220, 170}}} t=0.5 pt=(210,170) slope=(20,0)
+SkOpSegment::markWinding id=1 (200,170 220,170) t=0 [1] (200,170) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::markWinding id=2 (220,170 220,230) t=0 [3] (220,170) tEnd=0.333333333 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=1 (200,170 220,170) t=0 [1] (200,170) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::markWinding id=10 (200,250 200,170) t=0.75 [28] (200,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=1 (200,170 220,170) t=0 [1] (200,170) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=1 from=(220,170) to=(200,170)
+SkOpSegment::markWinding id=7 (180,190 260,190) t=0 [13] (180,190) tEnd=0.25 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=6 (180,210 180,190) t=0 [11] (180,210) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=5 (240,210 180,210) t=0.666666667 [25] (200,210) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=5 span=25 windSum=-1
+SkOpSegment::markWinding id=10 (200,250 200,170) t=0.5 [26] (200,210) tEnd=0.75 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=10 span=26 windSum=-2
+SkOpSegment::markWinding id=7 (180,190 260,190) t=0.25 [27] (200,190) tEnd=0.5 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=7 span=24 windSum=?
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [10/16] next=7/9 sect=7/7 s=0.75 [28] e=1 [20] sgn=-1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpAngle::dumpOne [7/9] next=10/15 sect=15/15 s=0.25 [27] e=0 [13] sgn=1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [10/15] next=7/10 sect=23/23 s=0.75 [28] e=0.5 [26] sgn=1 windVal=1 windSum=-2
+SkOpAngle::dumpOne [7/10] next=10/16 sect=31/31 s=0.25 [27] e=0.5 [24] sgn=-1 windVal=1 windSum=-2
+SkOpSegment::findNextWinding chase.append segment=5 span=25 windSum=-1
+SkOpSegment::markDone id=10 (200,250 200,170) t=0.5 [26] (200,210) tEnd=0.75 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=10 span=26 windSum=-2
+SkOpSegment::markDone id=7 (180,190 260,190) t=0.25 [27] (200,190) tEnd=0.5 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=7 span=24 windSum=-2147483647
+SkOpSegment::markDone id=10 (200,250 200,170) t=0.75 [28] (200,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[10] to:[7] start=5333632 end=5331472
+bridgeWinding current id=10 from=(200,170) to=(200,190)
+path.moveTo(220,170);
+path.lineTo(200,170);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=7 (180,190 260,190) t=0 [13] (180,190) tEnd=0.25 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=7 from=(200,190) to=(180,190)
+path.lineTo(200,190);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=6 (180,210 180,190) t=0 [11] (180,210) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=6 from=(180,190) to=(180,210)
+path.lineTo(180,190);
+SkOpSegment::markWinding id=10 (200,250 200,170) t=0 [19] (200,250) tEnd=0.5 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=9 (260,250 200,250) t=0 [17] (260,250) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=8 (260,190 260,250) t=0 [15] (260,190) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=7 (180,190 260,190) t=0.5 [24] (220,190) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=7 span=24 windSum=-1
+SkOpSegment::markWinding id=5 (240,210 180,210) t=0.333333333 [22] (220,210) tEnd=0.666666667 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=5 span=22 windSum=-2
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [5/8] next=10/13 sect=15/15 s=0.666666667 [25] e=1 [10] sgn=-1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [10/13] next=5/7 sect=23/23 s=0.5 [26] e=0 [19] sgn=1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [5/7] next=10/14 sect=31/31 s=0.666666667 [25] e=0.333333333 [22] sgn=1 windVal=1 windSum=-2
+SkOpAngle::dumpOne [10/14] next=5/8 sect=7/7 s=0.5 [26] e=0.75 [28] sgn=-1 windVal=1 windSum=-2 done
+SkOpSegment::markDone id=5 (240,210 180,210) t=0.333333333 [22] (220,210) tEnd=0.666666667 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=5 span=22 windSum=-2
+SkOpSegment::markDone id=5 (240,210 180,210) t=0.666666667 [25] (200,210) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[5] to:[10] start=5333488 end=5332456
+bridgeWinding current id=5 from=(180,210) to=(200,210)
+path.lineTo(180,210);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=10 (200,250 200,170) t=0 [19] (200,250) tEnd=0.5 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=10 from=(200,210) to=(200,250)
+path.lineTo(200,210);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=9 (260,250 200,250) t=0 [17] (260,250) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=9 from=(200,250) to=(260,250)
+path.lineTo(200,250);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=8 (260,190 260,250) t=0 [15] (260,190) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=8 from=(260,250) to=(260,190)
+path.lineTo(260,250);
+SkOpSegment::markWinding id=2 (220,170 220,230) t=0.333333333 [23] (220,190) tEnd=0.666666667 newWindSum=-2 windSum=? windValue=1
+SkOpSegment::markAngle last seg=2 span=21 windSum=?
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [7/12] next=2/1 sect=31/31 s=0.5 [24] e=1 [14] sgn=-1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [2/1] next=7/11 sect=7/7 s=0.333333333 [23] e=0 [3] sgn=1 windVal=1 windSum=-1 oppVal=0 oppSum=0
+SkOpAngle::dumpOne [7/11] next=2/2 sect=15/15 s=0.5 [24] e=0.25 [27] sgn=1 windVal=1 windSum=-2 done
+SkOpAngle::dumpOne [2/2] next=7/12 sect=23/23 s=0.333333333 [23] e=0.666666667 [21] sgn=-1 windVal=1 windSum=-2
+SkOpSegment::markDone id=2 (220,170 220,230) t=0.333333333 [23] (220,190) tEnd=0.666666667 newWindSum=-2 newOppSum=? oppSum=? windSum=-2 windValue=1 oppValue=0
+SkOpSegment::findNextWinding chase.append segment=2 span=21 windSum=-2147483647
+SkOpSegment::markDone id=7 (180,190 260,190) t=0.5 [24] (220,190) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[7] to:[2] start=5333056 end=5329832
+bridgeWinding current id=7 from=(260,190) to=(220,190)
+path.lineTo(260,190);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=2 (220,170 220,230) t=0 [3] (220,170) tEnd=0.333333333 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=2 from=(220,190) to=(220,170)
+path.lineTo(220,190);
+path.lineTo(220,170);
+path.close();
+SkOpSegment::markWinding id=2 (220,170 220,230) t=0.666666667 [21] (220,210) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=3 (220,230 240,230) t=0 [5] (220,230) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=4 (240,230 240,210) t=0 [7] (240,230) tEnd=1 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markWinding id=5 (240,210 180,210) t=0 [9] (240,210) tEnd=0.333333333 newWindSum=-1 windSum=? windValue=1
+SkOpSegment::markAngle last seg=5 span=22 windSum=-2
+SkOpSegment::markWinding id=5 (240,210 180,210) t=0 [9] (240,210) tEnd=0.333333333 newWindSum=-1 windSum=-1 windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (220,210 220,230) t=0.666666667 tEnd=1 windSum=-1 windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (220,230 240,230) t=0 tEnd=1 windSum=-1 windValue=1
+SkOpSegment::debugShowActiveSpans id=4 (240,230 240,210) t=0 tEnd=1 windSum=-1 windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (240,210 220,210) t=0 tEnd=0.333333333 windSum=-1 windValue=1
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=2 (220,170 220,230) t=0.666666667 [21] (220,210) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=2 from=(220,210) to=(220,230)
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=3 (220,230 240,230) t=0 [5] (220,230) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=3 from=(220,230) to=(240,230)
+path.moveTo(220,210);
+path.lineTo(220,230);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=4 (240,230 240,210) t=0 [7] (240,230) tEnd=1 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=4 from=(240,230) to=(240,210)
+path.lineTo(240,230);
+SkOpSegment::findNextWinding
+SkOpAngle::dumpOne [5/5] next=2/3 sect=31/31 s=0.333333333 [22] e=0 [9] sgn=1 windVal=1 windSum=-1
+SkOpAngle::dumpOne [2/3] next=5/6 sect=7/7 s=0.666666667 [21] e=0.333333333 [23] sgn=1 windVal=1 windSum=-2 done
+SkOpAngle::dumpOne [5/6] next=2/4 sect=15/15 s=0.333333333 [22] e=0.666666667 [25] sgn=-1 windVal=1 windSum=-2 done
+SkOpAngle::dumpOne [2/4] next=5/5 sect=23/23 s=0.666666667 [21] e=1 [4] sgn=-1 windVal=1 windSum=-1 done
+SkOpSegment::markDone id=5 (240,210 180,210) t=0 [9] (240,210) tEnd=0.333333333 newWindSum=-1 newOppSum=? oppSum=? windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding from:[5] to:[2] start=5332768 end=5329976
+bridgeWinding current id=5 from=(240,210) to=(220,210)
+path.lineTo(240,210);
+path.lineTo(220,210);
+path.close();
+</div>
+
+<div id="issue3838_a">
+SkOpSpan::sortableTop dir=kTop seg=1 t=0.5 pt=(210,170)
+SkOpSpan::sortableTop [0] valid=1 operand=0 span=1 ccw=0 seg=1 {{{220, 170}, {200, 170}}} t=0.5 pt=(210,170) slope=(-20,0)
+SkOpBuilder::FixWinding id=1 nested=1 ccw=0
+SkOpSegment::markDone id=1 (220,170 200,170) t=0 [1] (220,170) tEnd=1 newWindSum=1 newOppSum=0 oppSum=0 windSum=1 windValue=1 oppValue=0
+SkOpSegment::markDone id=2 (200,170 200,190) t=0 [3] (200,170) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=3 (200,190 180,190) t=0 [5] (200,190) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=4 (180,190 180,210) t=0 [7] (180,190) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=5 (180,210 200,210) t=0 [9] (180,210) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=6 (200,210 200,250) t=0 [11] (200,210) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=7 (200,250 260,250) t=0 [13] (200,250) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=8 (260,250 260,190) t=0 [15] (260,250) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=9 (260,190 220,190) t=0 [17] (260,190) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=10 (220,190 220,170) t=0 [19] (220,190) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSpan::sortableTop dir=kLeft seg=11 t=0.5 pt=(220,220)
+SkOpSpan::sortableTop [0] valid=1 operand=0 span=11 ccw=0 seg=6 {{{200, 210}, {200, 250}}} t=0.25 pt=(200,220) slope=(0,40)
+SkOpSpan::sortableTop [1] valid=1 operand=0 span=21 ccw=0 seg=11 {{{220, 210}, {220, 230}}} t=0.5 pt=(220,220) slope=(0,20)
+SkOpBuilder::FixWinding id=11 nested=2 ccw=0
+SkOpSegment::markDone id=11 (220,210 220,230) t=0 [21] (220,210) tEnd=1 newWindSum=2 newOppSum=0 oppSum=0 windSum=2 windValue=1 oppValue=0
+SkOpSegment::markDone id=12 (220,230 240,230) t=0 [23] (220,230) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=13 (240,230 240,210) t=0 [25] (240,230) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markDone id=14 (240,210 220,210) t=0 [27] (240,210) tEnd=1 newWindSum=? newOppSum=? oppSum=? windSum=? windValue=1 oppValue=0
+path.moveTo(220,170);
+path.lineTo(220,190);
+path.lineTo(260,190);
+path.lineTo(260,250);
+path.lineTo(200,250);
+path.lineTo(200,210);
+path.lineTo(180,210);
+path.lineTo(180,190);
+path.lineTo(200,190);
+path.lineTo(200,170);
+path.lineTo(220,170);
+path.close();
+</div>
+
+<div id="issue3838_b">
+seg=1 {{{220, 170}, {220, 190}}}
+seg=2 {{{220, 190}, {260, 190}}}
+seg=3 {{{260, 190}, {260, 250}}}
+seg=4 {{{260, 250}, {200, 250}}}
+seg=5 {{{200, 250}, {200, 210}}}
+seg=6 {{{200, 210}, {180, 210}}}
+seg=7 {{{180, 210}, {180, 190}}}
+seg=8 {{{180, 190}, {200, 190}}}
+seg=9 {{{200, 190}, {200, 170}}}
+seg=10 {{{200, 170}, {220, 170}}}
+debugShowLineIntersection wtTs[0]=0 {{{220,190}, {260,190}}} {{220,190}} wnTs[0]=1 {{{220,170}, {220,190}}}
+debugShowLineIntersection wtTs[0]=1 {{{200,170}, {220,170}}} {{220,170}} wnTs[0]=0 {{{220,170}, {220,190}}}
+debugShowLineIntersection wtTs[0]=0 {{{260,190}, {260,250}}} {{260,190}} wnTs[0]=1 {{{220,190}, {260,190}}}
+debugShowLineIntersection wtTs[0]=0 {{{260,250}, {200,250}}} {{260,250}} wnTs[0]=1 {{{260,190}, {260,250}}}
+debugShowLineIntersection wtTs[0]=0 {{{200,250}, {200,210}}} {{200,250}} wnTs[0]=1 {{{260,250}, {200,250}}}
+debugShowLineIntersection wtTs[0]=0 {{{200,210}, {180,210}}} {{200,210}} wnTs[0]=1 {{{200,250}, {200,210}}}
+debugShowLineIntersection wtTs[0]=0 {{{180,210}, {180,190}}} {{180,210}} wnTs[0]=1 {{{200,210}, {180,210}}}
+debugShowLineIntersection wtTs[0]=0 {{{180,190}, {200,190}}} {{180,190}} wnTs[0]=1 {{{180,210}, {180,190}}}
+debugShowLineIntersection wtTs[0]=0 {{{200,190}, {200,170}}} {{200,190}} wnTs[0]=1 {{{180,190}, {200,190}}}
+debugShowLineIntersection wtTs[0]=0 {{{200,170}, {220,170}}} {{200,170}} wnTs[0]=1 {{{200,190}, {200,170}}}
+-------------------------------------- addExpanded
+SkOpSegment::debugShowActiveSpans id=1 (220,170 220,190) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=2 (220,190 260,190) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=3 (260,190 260,250) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=4 (260,250 200,250) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=5 (200,250 200,210) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=6 (200,210 180,210) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=7 (180,210 180,190) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=8 (180,190 200,190) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=9 (200,190 200,170) t=0 tEnd=1 windSum=? windValue=1
+SkOpSegment::debugShowActiveSpans id=10 (200,170 220,170) t=0 tEnd=1 windSum=? windValue=1
+-------------------------------------- move_multiples
+-------------------------------------- move_nearby
+-------------------------------------- correctEnds
+-------------------------------------- addEndMovedSpans
+-------------------------------------- expand
+-------------------------------------- addExpanded
+-------------------------------------- mark
+-------------------------------------- missing_coincidence
+-------------------------------------- expand
+-------------------------------------- expand
+-------------------------------------- apply
+-------------------------------------- findOverlaps
+-------------------------------------- calc_angles
+SkOpSpan::sortableTop dir=kLeft seg=1 t=0.5 pt=(220,180)
+SkOpSpan::sortableTop [0] valid=1 operand=0 span=17 ccw=1 seg=9 {{{200, 190}, {200, 170}}} t=0.5 pt=(200,180) slope=(0,-20)
+SkOpSpan::sortableTop [1] valid=1 operand=0 span=1 ccw=0 seg=1 {{{220, 170}, {220, 190}}} t=0.5 pt=(220,180) slope=(0,20)
+SkOpSegment::markWinding id=9 (200,190 200,170) t=0 [17] (200,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::markWinding id=10 (200,170 220,170) t=0 [19] (200,170) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=1 (220,170 220,190) t=0 [1] (220,170) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=2 (220,190 260,190) t=0 [3] (220,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=3 (260,190 260,250) t=0 [5] (260,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=4 (260,250 200,250) t=0 [7] (260,250) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=5 (200,250 200,210) t=0 [9] (200,250) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=6 (200,210 180,210) t=0 [11] (200,210) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=7 (180,210 180,190) t=0 [13] (180,210) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=8 (180,190 200,190) t=0 [15] (180,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=? windSum=? windValue=1 oppValue=0
+SkOpSegment::markWinding id=9 (200,190 200,170) t=0 [17] (200,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=1 (220,170 220,190) t=0 [1] (220,170) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=1 from=(220,190) to=(220,170)
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=10 (200,170 220,170) t=0 [19] (200,170) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=10 from=(220,170) to=(200,170)
+path.moveTo(220,190);
+path.lineTo(220,170);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=9 (200,190 200,170) t=0 [17] (200,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=9 from=(200,170) to=(200,190)
+path.lineTo(200,170);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=8 (180,190 200,190) t=0 [15] (180,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=8 from=(200,190) to=(180,190)
+path.lineTo(200,190);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=7 (180,210 180,190) t=0 [13] (180,210) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=7 from=(180,190) to=(180,210)
+path.lineTo(180,190);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=6 (200,210 180,210) t=0 [11] (200,210) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=6 from=(180,210) to=(200,210)
+path.lineTo(180,210);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=5 (200,250 200,210) t=0 [9] (200,250) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=5 from=(200,210) to=(200,250)
+path.lineTo(200,210);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=4 (260,250 200,250) t=0 [7] (260,250) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=4 from=(200,250) to=(260,250)
+path.lineTo(200,250);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=3 (260,190 260,250) t=0 [5] (260,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=3 from=(260,250) to=(260,190)
+path.lineTo(260,250);
+SkOpSegment::findNextWinding simple
+SkOpSegment::markDone id=2 (220,190 260,190) t=0 [3] (220,190) tEnd=1 newWindSum=-1 newOppSum=0 oppSum=0 windSum=-1 windValue=1 oppValue=0
+bridgeWinding current id=2 from=(260,190) to=(220,190)
+path.lineTo(260,190);
+path.lineTo(220,190);
+path.close();
+</div>
+
</div>
<script type="text/javascript">
var testDivs = [
+ issue3838,
+ issue3838_a,
+ issue3838_b,
+ joel_11,
+ joel_10,
joel_9,
];
@@ -836,7 +1951,6 @@ function parse_all(test) {
: line.lastIndexOf("debugShowCoincidence", 0) === 0 ? REC_TYPE_COINCIDENCE
: line.lastIndexOf("((SkOpSegment*)", 0) === 0 ? REC_TYPE_PATH2
: line.lastIndexOf("debugShowTs", 0) === 0 ? REC_TYPE_COIN
- : line.lastIndexOf("debugAfter", 0) === 0 ? REC_TYPE_ANGLE
: line.lastIndexOf("afterPart", 0) === 0 ? REC_TYPE_AFTERPART
: line.lastIndexOf("debugShow", 0) === 0 ? REC_TYPE_SECT
: line.lastIndexOf("activeOp", 0) === 0 ? REC_TYPE_ACTIVE_OP
@@ -847,6 +1961,7 @@ function parse_all(test) {
: line.lastIndexOf("findTop", 0) === 0 ? REC_TYPE_TOP
: line.lastIndexOf("pathB.", 0) === 0 ? REC_TYPE_ADD
: line.lastIndexOf("path.", 0) === 0 ? REC_TYPE_ADD
+ : line.lastIndexOf("after", 0) === 0 ? REC_TYPE_ANGLE
: line.lastIndexOf("mark", 0) === 0 ? REC_TYPE_MARK
: line.lastIndexOf(" {{", 0) === 0 ? REC_TYPE_COMPUTED
: line.lastIndexOf("seg=", 0) === 0 ? REC_TYPE_PATH
@@ -939,7 +2054,7 @@ function parse_all(test) {
);
break;
case REC_TYPE_ANGLE:
- found = match_regexp(line, lineNo, record, ANGLE_AFTER, "debugAfter " +
+ found = match_regexp(line, lineNo, record, ANGLE_AFTER, "after " +
"[IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL < [IDX/IDX] NUM/NUM tStart=T_VAL tEnd=T_VAL T_F IDX");
break;
case REC_TYPE_COIN:
@@ -2485,9 +3600,9 @@ function dxy_at_t(curve, type, t) {
return dxy;
}
-function dpt_at_t(curve, t) {
+function dpt_at_t(curve, t) {
var type = PATH_LINE + (curve.length / 2 - 2);
- return dxy_at_t(curve, type, t);
+ return dxy_at_t(curve, type, t);
}
function drawLabel(num, px, py) {
@@ -2605,11 +3720,11 @@ function y_at_t(curve, t) {
return a * curve[1] + b * curve[3] + c * curve[5] + d * curve[7];
}
-function pt_at_t(curve, t) {
- var pt = {};
- pt.x = x_at_t(curve, t);
- pt.y = y_at_t(curve, t);
- return pt;
+function pt_at_t(curve, t) {
+ var pt = {};
+ pt.x = x_at_t(curve, t);
+ pt.y = y_at_t(curve, t);
+ return pt;
}
function drawOrder(curve, t, label) {
@@ -2636,59 +3751,59 @@ function drawOrder(curve, t, label) {
ctx.font = "normal 10px Arial";
}
-function drawVisibleOrder(curve, label) {
- var s = pt_at_t(curve, 0);
- var e = pt_at_t(curve, 1);
- var sOn = ptOnScreen(s);
- var eOn = ptOnScreen(e);
- var defaultT = 0.85;
- if (sOn && eOn)
- return drawOrder(curve, defaultT, label);
- if (sOn || eOn) {
- if (eOn) {
- defaultT = 1 - defaultT;
- }
- var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
- var t = defaultT;
- var tries = 16;
- do {
- var mid = pt_at_t(curve, t);
- if (ptOnScreen(mid))
- return drawOrder(curve, t, label);
- t += step;
- step /= 2;
- } while (--tries > 0);
- drawOrder(curve, defaultT, label);
- }
- // scattershot until we find a visible point
- var denom = 2; // visit odd number num / denom to hit unique pts
- var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
- do {
- for (var numer = 1; numer < denom; numer += 2) {
- var t = numer / denom + 0.1;
- if (t >= 1) {
- break;
- }
- var mid = pt_at_t(curve, t);
- if (ptOnScreen(mid))
- return drawOrder(curve, t, label);
- }
- denom *= 2;
- } while (--tries > 0);
- drawOrder(curve, defaultT, label);
+function drawVisibleOrder(curve, label) {
+ var s = pt_at_t(curve, 0);
+ var e = pt_at_t(curve, 1);
+ var sOn = ptOnScreen(s);
+ var eOn = ptOnScreen(e);
+ var defaultT = 0.85;
+ if (sOn && eOn)
+ return drawOrder(curve, defaultT, label);
+ if (sOn || eOn) {
+ if (eOn) {
+ defaultT = 1 - defaultT;
+ }
+ var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
+ var t = defaultT;
+ var tries = 16;
+ do {
+ var mid = pt_at_t(curve, t);
+ if (ptOnScreen(mid))
+ return drawOrder(curve, t, label);
+ t += step;
+ step /= 2;
+ } while (--tries > 0);
+ drawOrder(curve, defaultT, label);
+ }
+ // scattershot until we find a visible point
+ var denom = 2; // visit odd number num / denom to hit unique pts
+ var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
+ do {
+ for (var numer = 1; numer < denom; numer += 2) {
+ var t = numer / denom + 0.1;
+ if (t >= 1) {
+ break;
+ }
+ var mid = pt_at_t(curve, t);
+ if (ptOnScreen(mid))
+ return drawOrder(curve, t, label);
+ }
+ denom *= 2;
+ } while (--tries > 0);
+ drawOrder(curve, defaultT, label);
}
-function set_length(pt, newLen) {
- var len = Math.sqrt(pt.x * pt.x + pt.y * pt.y);
- var scale = newLen / len;
- var newPt = { x: pt.x * scale, y: pt.y * scale };
- return newPt;
+function set_length(pt, newLen) {
+ var len = Math.sqrt(pt.x * pt.x + pt.y * pt.y);
+ var scale = newLen / len;
+ var newPt = { x: pt.x * scale, y: pt.y * scale };
+ return newPt;
}
-function drawDirection(curve, t) {
+function drawDirection(curve, t) {
var d = dpt_at_t(curve, t);
d = set_length(d, 16);
- var pt = localToGlobal(pt_at_t(curve, t));
+ var pt = localToGlobal(pt_at_t(curve, t));
ctx.beginPath();
ctx.moveTo(pt.x - d.y, pt.y + d.x);
ctx.lineTo(pt.x + d.x, pt.y + d.y);
@@ -2697,47 +3812,47 @@ function drawDirection(curve, t) {
ctx.stroke();
}
-function drawVisibleDirection(curve) {
- var s = pt_at_t(curve, 0);
- var e = pt_at_t(curve, 1);
- var sOn = ptOnScreen(s);
- var eOn = ptOnScreen(e);
- var defaultT = 0.65;
- if (sOn && eOn) {
- return drawDirection(curve, defaultT);
- }
- if (sOn || eOn) {
- if (eOn) {
- defaultT = 1 - defaultT;
- }
- var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
- var t = defaultT;
- var tries = 16;
- do {
- var mid = pt_at_t(curve, t);
- if (ptOnScreen(mid))
- return drawDirection(curve, t);
- t += step;
- step /= 2;
- } while (--tries > 0);
- drawDirection(curve, defaultT);
- }
- // scattershot until we find a visible point
- var denom = 2; // visit odd number num / denom to hit unique pts
- var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
- do {
- for (var numer = 1; numer < denom; numer += 2) {
- var t = numer / denom + 0.1;
- if (t >= 1) {
- break;
- }
- var mid = pt_at_t(curve, t);
- if (ptOnScreen(mid))
- return drawDirection(curve, t);
- }
- denom *= 2;
- } while (--tries > 0);
- drawDirection(curve, defaultT);
+function drawVisibleDirection(curve) {
+ var s = pt_at_t(curve, 0);
+ var e = pt_at_t(curve, 1);
+ var sOn = ptOnScreen(s);
+ var eOn = ptOnScreen(e);
+ var defaultT = 0.65;
+ if (sOn && eOn) {
+ return drawDirection(curve, defaultT);
+ }
+ if (sOn || eOn) {
+ if (eOn) {
+ defaultT = 1 - defaultT;
+ }
+ var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
+ var t = defaultT;
+ var tries = 16;
+ do {
+ var mid = pt_at_t(curve, t);
+ if (ptOnScreen(mid))
+ return drawDirection(curve, t);
+ t += step;
+ step /= 2;
+ } while (--tries > 0);
+ drawDirection(curve, defaultT);
+ }
+ // scattershot until we find a visible point
+ var denom = 2; // visit odd number num / denom to hit unique pts
+ var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
+ do {
+ for (var numer = 1; numer < denom; numer += 2) {
+ var t = numer / denom + 0.1;
+ if (t >= 1) {
+ break;
+ }
+ var mid = pt_at_t(curve, t);
+ if (ptOnScreen(mid))
+ return drawDirection(curve, t);
+ }
+ denom *= 2;
+ } while (--tries > 0);
+ drawDirection(curve, defaultT);
}
function drawID(curve, t, id) {
@@ -2748,53 +3863,53 @@ function drawID(curve, t, id) {
draw_id_at(id, _px, _py);
}
-function localToGlobal(local) {
- var global = {};
- global.x = (local.x - srcLeft) * scale;
- global.y = (local.y - srcTop) * scale;
- return global;
+function localToGlobal(local) {
+ var global = {};
+ global.x = (local.x - srcLeft) * scale;
+ global.y = (local.y - srcTop) * scale;
+ return global;
}
-function ptOnScreen(local) {
- var pt = localToGlobal(local);
- return 10 <= pt.x && pt.x <= screenWidth - 10
- && 10 <= pt.y && pt.y <= screenHeight - 10;
+function ptOnScreen(local) {
+ var pt = localToGlobal(local);
+ return 10 <= pt.x && pt.x <= screenWidth - 10
+ && 10 <= pt.y && pt.y <= screenHeight - 10;
}
-function drawVisibleID(curve, defaultT, id) {
- // determine if either or both ends are visible
- var s = pt_at_t(curve, 0);
- var e = pt_at_t(curve, 1);
- var sOn = ptOnScreen(s);
- var eOn = ptOnScreen(e);
- if (sOn && eOn)
- return drawID(curve, defaultT, id);
- if (sOn || eOn) {
- var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
- var t = defaultT;
- var tries = 16;
- do {
- var mid = pt_at_t(curve, t);
- if (ptOnScreen(mid))
- return drawID(curve, t, id);
- t += step;
- step /= 2;
- } while (--tries > 0);
- drawID(curve, defaultT, id);
- }
- // scattershot until we find a visible point
- var denom = 2; // visit odd number num / denom to hit unique pts
- var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
- do {
- for (var numer = 1; numer < denom; numer += 2) {
- var t = numer / denom;
- var mid = pt_at_t(curve, t);
- if (ptOnScreen(mid))
- return drawID(curve, t, id);
- }
- denom *= 2;
- } while (--tries > 0);
- drawID(curve, defaultT, id);
+function drawVisibleID(curve, defaultT, id) {
+ // determine if either or both ends are visible
+ var s = pt_at_t(curve, 0);
+ var e = pt_at_t(curve, 1);
+ var sOn = ptOnScreen(s);
+ var eOn = ptOnScreen(e);
+ if (sOn && eOn)
+ return drawID(curve, defaultT, id);
+ if (sOn || eOn) {
+ var step = sOn ? -defaultT / 2 : (1 - defaultT) / 2;
+ var t = defaultT;
+ var tries = 16;
+ do {
+ var mid = pt_at_t(curve, t);
+ if (ptOnScreen(mid))
+ return drawID(curve, t, id);
+ t += step;
+ step /= 2;
+ } while (--tries > 0);
+ drawID(curve, defaultT, id);
+ }
+ // scattershot until we find a visible point
+ var denom = 2; // visit odd number num / denom to hit unique pts
+ var tries = 6; // tries 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16 ...
+ do {
+ for (var numer = 1; numer < denom; numer += 2) {
+ var t = numer / denom;
+ var mid = pt_at_t(curve, t);
+ if (ptOnScreen(mid))
+ return drawID(curve, t, id);
+ }
+ denom *= 2;
+ } while (--tries > 0);
+ drawID(curve, defaultT, id);
}
function draw_id_at(id, _px, _py) {
@@ -2872,8 +3987,8 @@ function drawCurveSpecials(test, curve, type) {
drawVisibleID(curve, 0.5, id);
}
}
- if (draw_direction) {
- drawVisibleDirection(curve);
+ if (draw_direction) {
+ drawVisibleDirection(curve);
}
if (type == PATH_LINE) {
return;
@@ -3464,10 +4579,10 @@ function draw(test, lines, title) {
drawVisibleOrder(leftCurve, 'L');
drawVisibleOrder(rightCurve, 'R');
}
- if (draw_id) {
- drawVisibleID(leftCurve, 0.5, frags[0]);
- drawVisibleID(midCurve, 0.5, frags[6]);
- drawVisibleID(rightCurve, 0.5, frags[12]);
+ if (draw_id) {
+ drawVisibleID(leftCurve, 0.5, frags[0]);
+ drawVisibleID(midCurve, 0.5, frags[6]);
+ drawVisibleID(rightCurve, 0.5, frags[12]);
}
break;
case REC_TYPE_AFTERPART:
@@ -3504,8 +4619,8 @@ function draw(test, lines, title) {
throw "stop execution";
}
drawCurve(curve);
- if (draw_id) {
- drawVisibleID(curve, 0.5, id);
+ if (draw_id) {
+ drawVisibleID(curve, 0.5, id);
}
++afterIndex;
break;