aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2014-09-19 06:33:31 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-09-19 06:33:31 -0700
commit630240d18805faf81d8e75172496ad165c2226b2 (patch)
tree6d025f6779c443536192fd93a23ad2b74e4174c9
parent65b48952d7253faf44feb91dfe8953295b1600d0 (diff)
fail early if coincidence can't be resolved
Bail out if a very large value causes coincidence resolution to fail. TBR= BUG=415866 Author: caryclark@google.com Review URL: https://codereview.chromium.org/585913002
-rw-r--r--src/pathops/SkAddIntersections.cpp7
-rw-r--r--src/pathops/SkAddIntersections.h2
-rw-r--r--src/pathops/SkOpContour.cpp27
-rw-r--r--src/pathops/SkOpContour.h4
-rw-r--r--src/pathops/SkOpSegment.cpp18
-rw-r--r--src/pathops/SkOpSegment.h2
-rw-r--r--src/pathops/SkPathOpsCommon.cpp4
-rw-r--r--tests/PathOpsOpTest.cpp96
-rw-r--r--tools/pathops_visualizer.htm231
9 files changed, 300 insertions, 91 deletions
diff --git a/src/pathops/SkAddIntersections.cpp b/src/pathops/SkAddIntersections.cpp
index 52e751bd08..27422eda5f 100644
--- a/src/pathops/SkAddIntersections.cpp
+++ b/src/pathops/SkAddIntersections.cpp
@@ -434,7 +434,7 @@ void AddSelfIntersectTs(SkOpContour* test) {
// resolve any coincident pairs found while intersecting, and
// see if coincidence is formed by clipping non-concident segments
-void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
+bool CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
int contourCount = (*contourList).count();
for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
SkOpContour* contour = (*contourList)[cIndex];
@@ -446,10 +446,13 @@ void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) {
}
for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
SkOpContour* contour = (*contourList)[cIndex];
- contour->calcCoincidentWinding();
+ if (!contour->calcCoincidentWinding()) {
+ return false;
+ }
}
for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
SkOpContour* contour = (*contourList)[cIndex];
contour->calcPartialCoincidentWinding();
}
+ return true;
}
diff --git a/src/pathops/SkAddIntersections.h b/src/pathops/SkAddIntersections.h
index 94ea436b73..4c1947b635 100644
--- a/src/pathops/SkAddIntersections.h
+++ b/src/pathops/SkAddIntersections.h
@@ -13,6 +13,6 @@
bool AddIntersectTs(SkOpContour* test, SkOpContour* next);
void AddSelfIntersectTs(SkOpContour* test);
-void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total);
+bool CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total);
#endif
diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp
index 467fab31f5..6d6ad7926e 100644
--- a/src/pathops/SkOpContour.cpp
+++ b/src/pathops/SkOpContour.cpp
@@ -267,7 +267,7 @@ bool SkOpContour::calcAngles() {
return true;
}
-void SkOpContour::calcCoincidentWinding() {
+bool SkOpContour::calcCoincidentWinding() {
int count = fCoincidences.count();
#if DEBUG_CONCIDENT
if (count > 0) {
@@ -276,8 +276,11 @@ void SkOpContour::calcCoincidentWinding() {
#endif
for (int index = 0; index < count; ++index) {
SkCoincidence& coincidence = fCoincidences[index];
- calcCommonCoincidentWinding(coincidence);
+ if (!calcCommonCoincidentWinding(coincidence)) {
+ return false;
+ }
}
+ return true;
}
void SkOpContour::calcPartialCoincidentWinding() {
@@ -471,11 +474,11 @@ void SkOpContour::checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx,
addTo2->addTCancel(missingPt1, missingPt2, addOther2);
}
} else if (missingT1 >= 0) {
- addTo1->addTCoincident(missingPt1, missingPt2, addTo1 == addTo2 ? missingT2 : otherT2,
- addOther1);
+ SkAssertResult(addTo1->addTCoincident(missingPt1, missingPt2,
+ addTo1 == addTo2 ? missingT2 : otherT2, addOther1));
} else {
- addTo2->addTCoincident(missingPt2, missingPt1, addTo2 == addTo1 ? missingT1 : otherT1,
- addOther2);
+ SkAssertResult(addTo2->addTCoincident(missingPt2, missingPt1,
+ addTo2 == addTo1 ? missingT1 : otherT1, addOther2));
}
}
@@ -543,20 +546,20 @@ void SkOpContour::joinCoincidence(const SkTArray<SkCoincidence, true>& coinciden
}
}
-void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
+bool SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence) {
if (coincidence.fNearly[0] && coincidence.fNearly[1]) {
- return;
+ return true;
}
int thisIndex = coincidence.fSegments[0];
SkOpSegment& thisOne = fSegments[thisIndex];
if (thisOne.done()) {
- return;
+ return true;
}
SkOpContour* otherContour = coincidence.fOther;
int otherIndex = coincidence.fSegments[1];
SkOpSegment& other = otherContour->fSegments[otherIndex];
if (other.done()) {
- return;
+ return true;
}
double startT = coincidence.fTs[0][0];
double endT = coincidence.fTs[0][1];
@@ -577,15 +580,17 @@ void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence)
}
bump_out_close_span(&oStartT, &oEndT);
SkASSERT(!approximately_negative(oEndT - oStartT));
+ bool success = true;
if (cancelers) {
thisOne.addTCancel(*startPt, *endPt, &other);
} else {
- thisOne.addTCoincident(*startPt, *endPt, endT, &other);
+ success = thisOne.addTCoincident(*startPt, *endPt, endT, &other);
}
#if DEBUG_CONCIDENT
thisOne.debugShowTs("p");
other.debugShowTs("o");
#endif
+ return success;
}
void SkOpContour::resolveNearCoincidence() {
diff --git a/src/pathops/SkOpContour.h b/src/pathops/SkOpContour.h
index d1b3cd0179..899367ab0e 100644
--- a/src/pathops/SkOpContour.h
+++ b/src/pathops/SkOpContour.h
@@ -114,7 +114,7 @@ public:
}
bool calcAngles();
- void calcCoincidentWinding();
+ bool calcCoincidentWinding();
void calcPartialCoincidentWinding();
void checkDuplicates() {
@@ -325,7 +325,7 @@ public:
private:
void alignPt(int index, SkPoint* point, int zeroPt) const;
int alignT(bool swap, int tIndex, SkIntersections* ts) const;
- void calcCommonCoincidentWinding(const SkCoincidence& );
+ bool calcCommonCoincidentWinding(const SkCoincidence& );
void checkCoincidentPair(const SkCoincidence& oneCoin, int oneIdx,
const SkCoincidence& twoCoin, int twoIdx, bool partial);
void joinCoincidence(const SkTArray<SkCoincidence, true>& , bool partial);
diff --git a/src/pathops/SkOpSegment.cpp b/src/pathops/SkOpSegment.cpp
index 5208a38667..2dda11a383 100644
--- a/src/pathops/SkOpSegment.cpp
+++ b/src/pathops/SkOpSegment.cpp
@@ -1271,7 +1271,7 @@ void SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, int* oIndexPtr,
// set spans from start to end to increment the greater by one and decrement
// the lesser
-void SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
+bool SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
SkOpSegment* other) {
bool binary = fOperand != other->fOperand;
int index = 0;
@@ -1303,7 +1303,10 @@ void SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, d
// SkASSERT(AlmostEqualUlps(*testPt, *oTestPt));
do {
SkASSERT(test->fT < 1);
- SkASSERT(oTest->fT < 1);
+ if (oTest->fT == 1) {
+ // paths with extreme data may be so mismatched that we fail here
+ return false;
+ }
// consolidate the winding count even if done
if ((test->fWindValue == 0 && test->fOppValue == 0)
@@ -1409,6 +1412,7 @@ void SkOpSegment::addTCoincident(const SkPoint& startPt, const SkPoint& endPt, d
}
setCoincidentRange(startPt, endPt, other);
other->setCoincidentRange(startPt, endPt, this);
+ return true;
}
// FIXME: this doesn't prevent the same span from being added twice
@@ -2422,8 +2426,8 @@ nextSmallCheck:
do {
++nextSpan;
} while (nextSpan->fSmall);
- missing.fSegment->addTCoincident(missing.fPt, nextSpan->fPt, nextSpan->fT,
- missingOther);
+ SkAssertResult(missing.fSegment->addTCoincident(missing.fPt, nextSpan->fPt,
+ nextSpan->fT, missingOther));
} else if (otherSpan.fT > 0) {
const SkOpSpan* priorSpan = &otherSpan;
do {
@@ -2494,7 +2498,7 @@ void SkOpSegment::checkSmallCoincidence(const SkOpSpan& span,
}
// SkASSERT(oSpan.fSmall);
if (oStartIndex < oEndIndex) {
- addTCoincident(span.fPt, next->fPt, next->fT, other);
+ SkAssertResult(addTCoincident(span.fPt, next->fPt, next->fT, other));
} else {
addTCancel(span.fPt, next->fPt, other);
}
@@ -2539,7 +2543,7 @@ void SkOpSegment::checkSmallCoincidence(const SkOpSpan& span,
oTest->fOtherT, tTest->fT);
#endif
if (tTest->fT < oTest->fOtherT) {
- addTCoincident(span.fPt, next->fPt, next->fT, testOther);
+ SkAssertResult(addTCoincident(span.fPt, next->fPt, next->fT, testOther));
} else {
addTCancel(span.fPt, next->fPt, testOther);
}
@@ -3428,7 +3432,7 @@ bool SkOpSegment::joinCoincidence(SkOpSegment* other, double otherT, const SkPoi
if (cancel) {
match->addTCancel(startPt, endPt, other);
} else {
- match->addTCoincident(startPt, endPt, endT, other);
+ SkAssertResult(match->addTCoincident(startPt, endPt, endT, other));
}
return true;
}
diff --git a/src/pathops/SkOpSegment.h b/src/pathops/SkOpSegment.h
index df87d058b6..24d08bd814 100644
--- a/src/pathops/SkOpSegment.h
+++ b/src/pathops/SkOpSegment.h
@@ -284,7 +284,7 @@ public:
void addStartSpan(int endIndex);
int addT(SkOpSegment* other, const SkPoint& pt, double newT);
void addTCancel(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* other);
- void addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
+ bool addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double endT,
SkOpSegment* other);
const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool borrowWind,
const SkPoint& pt);
diff --git a/src/pathops/SkPathOpsCommon.cpp b/src/pathops/SkPathOpsCommon.cpp
index 9a8a2cf4e3..f7b7273a8d 100644
--- a/src/pathops/SkPathOpsCommon.cpp
+++ b/src/pathops/SkPathOpsCommon.cpp
@@ -699,7 +699,9 @@ bool HandleCoincidence(SkTArray<SkOpContour*, true>* contourList, int total) {
#if DEBUG_SHOW_WINDING
SkOpContour::debugShowWindingValues(contourList);
#endif
- CoincidenceCheck(contourList, total);
+ if (!CoincidenceCheck(contourList, total)) {
+ return false;
+ }
#if DEBUG_SHOW_WINDING
SkOpContour::debugShowWindingValues(contourList);
#endif
diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp
index 0b0e02438e..4977b28c30 100644
--- a/tests/PathOpsOpTest.cpp
+++ b/tests/PathOpsOpTest.cpp
@@ -3511,7 +3511,7 @@ static void issue2808(skiatest::Reporter* reporter, const char* filename) {
testPathOp(reporter, path1, path2, kUnion_PathOp, filename);
}
-static void (*firstTest)(skiatest::Reporter* , const char* filename) = cubicOp95u;
+static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0;
static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0;
static struct TestDesc tests[] = {
@@ -3807,7 +3807,101 @@ static void fuzz433b(skiatest::Reporter* reporter, const char* filename) {
testPathFailOp(reporter, path1, path2, kUnion_PathOp, filename);
}
+static void fuzz487a(skiatest::Reporter* reporter, const char* filename) {
+ SkPath path;
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x429a6666), SkBits2Float(0x42f9999a), SkBits2Float(0x4275999a), SkBits2Float(0x42d70001), SkBits2Float(0x42633333));
+path.lineTo(SkBits2Float(0x42e90001), SkBits2Float(0x41b8cccc));
+path.cubicTo(SkBits2Float(0x42dc6667), SkBits2Float(0x41ab3332), SkBits2Float(0x42cf3334), SkBits2Float(0x41a3ffff), SkBits2Float(0x42c20001), SkBits2Float(0x41a3ffff));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.cubicTo(SkBits2Float(0x429c6668), SkBits2Float(0x425d999a), SkBits2Float(0x4279999c), SkBits2Float(0x42886667), SkBits2Float(0x42673335), SkBits2Float(0x42ab0000));
+path.lineTo(SkBits2Float(0x41c0ccd0), SkBits2Float(0x42990000));
+path.cubicTo(SkBits2Float(0x41b33336), SkBits2Float(0x42a5999a), SkBits2Float(0x41ac0003), SkBits2Float(0x42b2cccd), SkBits2Float(0x41ac0003), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999c), SkBits2Float(0x434d3333), SkBits2Float(0x4364e667), SkBits2Float(0x4346b333), SkBits2Float(0x4364e667), SkBits2Float(0x43400000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+ SkPath path1(path);
+ path.reset();
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x42a20000), SkBits2Float(0x43016667), SkBits2Float(0x4287cccd), SkBits2Float(0x42ea999a), SkBits2Float(0x4273999a));
+path.lineTo(SkBits2Float(0x4306cccd), SkBits2Float(0x41f5999a));
+path.cubicTo(SkBits2Float(0x42f76667), SkBits2Float(0x41c26667), SkBits2Float(0x42dd999a), SkBits2Float(0x41a4cccd), SkBits2Float(0x42c23334), SkBits2Float(0x41a4cccd));
+path.lineTo(SkBits2Float(0x42c23334), SkBits2Float(0x425e0000));
+path.cubicTo(SkBits2Float(0x42a43334), SkBits2Float(0x425e0000), SkBits2Float(0x428a0001), SkBits2Float(0x427ecccd), SkBits2Float(0x42780002), SkBits2Float(0x4297999a));
+path.lineTo(SkBits2Float(0x41fccccd), SkBits2Float(0x42693333));
+path.cubicTo(SkBits2Float(0x41c9999a), SkBits2Float(0x428acccd), SkBits2Float(0x41ac0000), SkBits2Float(0x42a4999a), SkBits2Float(0x41ac0000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999a), SkBits2Float(0x42de0000), SkBits2Float(0x42813333), SkBits2Float(0x42f83333), SkBits2Float(0x42996666), SkBits2Float(0x4303199a));
+path.cubicTo(SkBits2Float(0x4272cccc), SkBits2Float(0x4303199a), SkBits2Float(0x423d3332), SkBits2Float(0x430de667), SkBits2Float(0x422d9999), SkBits2Float(0x431cb334));
+path.lineTo(SkBits2Float(0x7086a1dc), SkBits2Float(0x42eecccd));
+path.lineTo(SkBits2Float(0x41eb3333), SkBits2Float(0xc12ccccd));
+path.lineTo(SkBits2Float(0x42053333), SkBits2Float(0xc1cccccd));
+path.lineTo(SkBits2Float(0x42780000), SkBits2Float(0xc18f3334));
+path.cubicTo(SkBits2Float(0x43206666), SkBits2Float(0x43134ccd), SkBits2Float(0x43213333), SkBits2Float(0x430db333), SkBits2Float(0x43213333), SkBits2Float(0x43080000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+ SkPath path2(path);
+ testPathFailOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
+static void fuzz487b(skiatest::Reporter* reporter, const char* filename) {
+ SkPath path;
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x429a6666), SkBits2Float(0x42f9999a), SkBits2Float(0x4275999a), SkBits2Float(0x42d70001), SkBits2Float(0x42633333));
+path.lineTo(SkBits2Float(0x42e90001), SkBits2Float(0x41b8cccc));
+path.cubicTo(SkBits2Float(0x42dc6667), SkBits2Float(0x41ab3332), SkBits2Float(0x42cf3334), SkBits2Float(0x41a3ffff), SkBits2Float(0x42c20001), SkBits2Float(0x41a3ffff));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.lineTo(SkBits2Float(0x42c20001), SkBits2Float(0x425d999a));
+path.cubicTo(SkBits2Float(0x429c6668), SkBits2Float(0x425d999a), SkBits2Float(0x4279999c), SkBits2Float(0x42886667), SkBits2Float(0x42673335), SkBits2Float(0x42ab0000));
+path.lineTo(SkBits2Float(0x41c0ccd0), SkBits2Float(0x42990000));
+path.cubicTo(SkBits2Float(0x41b33336), SkBits2Float(0x42a5999a), SkBits2Float(0x41ac0003), SkBits2Float(0x42b2cccd), SkBits2Float(0x41ac0003), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999c), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999c), SkBits2Float(0x434d3333), SkBits2Float(0x4364e667), SkBits2Float(0x4346b333), SkBits2Float(0x4364e667), SkBits2Float(0x43400000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+ SkPath path1(path);
+ path.reset();
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4309999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4309999a), SkBits2Float(0x42a20000), SkBits2Float(0x43016667), SkBits2Float(0x4287cccd), SkBits2Float(0x42ea999a), SkBits2Float(0x4273999a));
+path.lineTo(SkBits2Float(0x4306cccd), SkBits2Float(0x41f5999a));
+path.cubicTo(SkBits2Float(0x42f76667), SkBits2Float(0x41c26667), SkBits2Float(0x42dd999a), SkBits2Float(0x41a4cccd), SkBits2Float(0x42c23334), SkBits2Float(0x41a4cccd));
+path.lineTo(SkBits2Float(0x42c23334), SkBits2Float(0x425e0000));
+path.cubicTo(SkBits2Float(0x42a43334), SkBits2Float(0x425e0000), SkBits2Float(0x428a0001), SkBits2Float(0x427ecccd), SkBits2Float(0x42780002), SkBits2Float(0x4297999a));
+path.lineTo(SkBits2Float(0x41fccccd), SkBits2Float(0x42693333));
+path.cubicTo(SkBits2Float(0x41c9999a), SkBits2Float(0x428acccd), SkBits2Float(0x41ac0000), SkBits2Float(0x42a4999a), SkBits2Float(0x41ac0000), SkBits2Float(0x42c00000));
+path.lineTo(SkBits2Float(0x4261999a), SkBits2Float(0x42c00000));
+path.cubicTo(SkBits2Float(0x4261999a), SkBits2Float(0x42de0000), SkBits2Float(0x42813333), SkBits2Float(0x42f83333), SkBits2Float(0x42996666), SkBits2Float(0x4303199a));
+path.cubicTo(SkBits2Float(0x4272cccc), SkBits2Float(0x4303199a), SkBits2Float(0x423d3332), SkBits2Float(0x430de667), SkBits2Float(0x422d9999), SkBits2Float(0x431cb334));
+path.lineTo(SkBits2Float(0x7086a1dc), SkBits2Float(0x42eecccd));
+path.lineTo(SkBits2Float(0x41eb3333), SkBits2Float(0xc12ccccd));
+path.lineTo(SkBits2Float(0x42053333), SkBits2Float(0xc1cccccd));
+path.lineTo(SkBits2Float(0x42780000), SkBits2Float(0xc18f3334));
+path.cubicTo(SkBits2Float(0x43206666), SkBits2Float(0x43134ccd), SkBits2Float(0x43213333), SkBits2Float(0x430db333), SkBits2Float(0x43213333), SkBits2Float(0x43080000));
+path.lineTo(SkBits2Float(0x432c8000), SkBits2Float(0x42c00000));
+path.close();
+
+ SkPath path2(path);
+ testPathFailOp(reporter, path1, path2, (SkPathOp) 2, filename);
+}
+
static struct TestDesc failTests[] = {
+ TEST(fuzz487a),
+ TEST(fuzz487b),
TEST(fuzz433b),
TEST(fuzz433),
TEST(bufferOverflow),
diff --git a/tools/pathops_visualizer.htm b/tools/pathops_visualizer.htm
index 825f5f67ab..eece69b73b 100644
--- a/tools/pathops_visualizer.htm
+++ b/tools/pathops_visualizer.htm
@@ -1,71 +1,172 @@
<html>
<head>
<div height="0" hidden="true">
-
-<div id="battleOp6001">
- RunTestSet [battleOp6001]
-
-{{0,-59.9999962}, {0,-83}},
-{{0,-83}, {0.0189378317,-83}, {0.0378723554,-82.9999924}, {0.0568068773,-82.9999771}},
-{{0.0568068773,-82.9999771}, {0.06248549,-82.9999771}},
-{{0.06248549,-82.9999771}, {0.0451734141,-59.9999847}},
-{{0.0451734141,-59.9999847}, {0.0438041016,-59.9999886}, {0.0424379632,-59.9999886}, {0.0410718247,-59.9999886}},
-{{0.0410718247,-59.9999886}, {0.0410667397,-59.9999847}},
-{{0.0410667397,-59.9999847}, {0.0273789354,-59.9999924}, {0.0136889406,-59.9999962}, {0,-59.9999962}},
+<div id="fuzz487a">
+ RunTestSet [fuzz487a]
+
+{{172.5,96}, {137.600006,96}},
+{{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}},
+{{107.500008,56.7999992}, {116.500008,23.0999985}},
+{{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}},
+{{97.0000076,20.4999981}, {97.0000076,55.4000015}},
+{{97.0000076,55.4000015}, {97.0000076,55.4000015}},
+{{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}},
+{{57.8000069,85.5}, {24.1000061,76.5}},
+{{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}},
+{{21.5000057,96}, {56.4000092,96}},
+{{56.4000092,96}, {56.4000092,96}},
+{{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}},
+{{228.900009,192}, {172.5,96}},
op union
-{{0.0624898896,-82.9999771}, {0.0931733027,-82.9999542}, {0.123859018,-82.9999084}, {0.154544711,-82.999855}},
-{{0.154544711,-82.999855}, {0.111722,-59.999897}},
-{{0.111722,-59.999897}, {0.0895366594,-59.999939}, {0.0673542097,-59.9999695}, {0.0451717526,-59.9999847}},
-{{0.0451717526,-59.9999847}, {0.0624898896,-82.9999771}},
-debugShowCubicIntersection no self intersect {{0,-83}, {0.0189378317,-83}, {0.0378723554,-82.9999924}, {0.0568068773,-82.9999771}}
-debugShowCubicIntersection no self intersect {{0.0451734141,-59.9999847}, {0.0438041016,-59.9999886}, {0.0424379632,-59.9999886}, {0.0410718247,-59.9999886}}
-debugShowCubicIntersection no self intersect {{0.0410667397,-59.9999847}, {0.0273789354,-59.9999924}, {0.0136889406,-59.9999962}, {0,-59.9999962}}
-debugShowCubicLineIntersection wtTs[0]=0 {{0,-83}, {0.0189378317,-83}, {0.0378723554,-82.9999924}, {0.0568068773,-82.9999771}} {{0,-83}} wnTs[0]=1 {{0,-59.9999962}, {0,-83}}
-debugShowCubicLineIntersection wtTs[0]=1 {{0.0410667397,-59.9999847}, {0.0273789354,-59.9999924}, {0.0136889406,-59.9999962}, {0,-59.9999962}} {{0,-59.9999962}} wnTs[0]=0 {{0,-59.9999962}, {0,-83}}
-debugShowCubicLineIntersection wtTs[0]=1 {{0,-83}, {0.0189378317,-83}, {0.0378723554,-82.9999924}, {0.0568068773,-82.9999771}} {{0.0568068773,-82.9999771}} wnTs[0]=0 {{0.0568068773,-82.9999771}, {0.06248549,-82.9999771}}
-debugShowCubicLineIntersection no intersect {{0,-83}, {0.0189378317,-83}, {0.0378723554,-82.9999924}, {0.0568068773,-82.9999771}} {{0.06248549,-82.9999771}, {0.0451734141,-59.9999847}}
-debugShowLineIntersection wtTs[0]=0 {{0.06248549,-82.9999771}, {0.0451734141,-59.9999847}} {{0.06248549,-82.9999771}} wnTs[0]=1 {{0.0568068773,-82.9999771}, {0.06248549,-82.9999771}}
-debugShowCubicLineIntersection wtTs[0]=0 {{0.0451734141,-59.9999847}, {0.0438041016,-59.9999886}, {0.0424379632,-59.9999886}, {0.0410718247,-59.9999886}} {{0.0451734141,-59.9999847}} wnTs[0]=1 {{0.06248549,-82.9999771}, {0.0451734141,-59.9999847}}
-debugShowCubicLineIntersection wtTs[0]=1 {{0.0451734141,-59.9999847}, {0.0438041016,-59.9999886}, {0.0424379632,-59.9999886}, {0.0410718247,-59.9999886}} {{0.0410718247,-59.9999886}} wnTs[0]=0 {{0.0410718247,-59.9999886}, {0.0410667397,-59.9999847}}
-debugShowCubicLineIntersection wtTs[0]=0 {{0.0410667397,-59.9999847}, {0.0273789354,-59.9999924}, {0.0136889406,-59.9999962}, {0,-59.9999962}} {{0.0410667397,-59.9999847}} wnTs[0]=1 {{0.0410718247,-59.9999886}, {0.0410667397,-59.9999847}}
-debugShowCubicLineIntersection no intersect {{0,-83}, {0.0189378317,-83}, {0.0378723554,-82.9999924}, {0.0568068773,-82.9999771}} {{0.0451717526,-59.9999847}, {0.0624898896,-82.9999771}}
-debugShowLineIntersection wtTs[0]=1 {{0.0451717526,-59.9999847}, {0.0624898896,-82.9999771}} {{0.06248549,-82.9999771}} wnTs[0]=1 {{0.0568068773,-82.9999771}, {0.06248549,-82.9999771}}
-debugShowCubicLineIntersection wtTs[0]=0.999975033 {{0.111722,-59.999897}, {0.0895366594,-59.999939}, {0.0673542097,-59.9999695}, {0.0451717526,-59.9999847}} {{0.0451734141,-59.9999847}} wnTs[0]=1 {{0.06248549,-82.9999771}, {0.0451734141,-59.9999847}}
-debugShowLineIntersection wtTs[0]=0 {{0.06248549,-82.9999771}, {0.0451734141,-59.9999847}} {{0.06248549,-82.9999771}} wtTs[1]=1 {{0.0451734141,-59.9999847}} wnTs[0]=1 {{0.0451717526,-59.9999847}, {0.0624898896,-82.9999771}} wnTs[1]=5.43926879e-011
-debugShowCubicIntersection wtTs[0]=0.000404455511 {{0.0451734141,-59.9999847}, {0.0438041016,-59.9999886}, {0.0424379632,-59.9999886}, {0.0410718247,-59.9999886}} {{0.0451717526,-59.9999847}} wnTs[0]=1 {{0.111722,-59.999897}, {0.0895366594,-59.999939}, {0.0673542097,-59.9999695}, {0.0451717526,-59.9999847}}
-debugShowCubicLineIntersection wtTs[0]=0 {{0.0451734141,-59.9999847}, {0.0438041016,-59.9999886}, {0.0424379632,-59.9999886}, {0.0410718247,-59.9999886}} {{0.0451734141,-59.9999847}} wtTs[1]=0.000404455438 {{0.0451717526,-59.9999847}} wnTs[0]=5.43927e-011 {{0.0451717526,-59.9999847}, {0.0624898896,-82.9999771}} wnTs[1]=0
-debugShowCubicIntersection no self intersect {{0.0624898896,-82.9999771}, {0.0931733027,-82.9999542}, {0.123859018,-82.9999084}, {0.154544711,-82.999855}}
-debugShowCubicIntersection no self intersect {{0.111722,-59.999897}, {0.0895366594,-59.999939}, {0.0673542097,-59.9999695}, {0.0451717526,-59.9999847}}
-debugShowCubicLineIntersection wtTs[0]=1 {{0.0624898896,-82.9999771}, {0.0931733027,-82.9999542}, {0.123859018,-82.9999084}, {0.154544711,-82.999855}} {{0.154544711,-82.999855}} wnTs[0]=0 {{0.154544711,-82.999855}, {0.111722,-59.999897}}
-debugShowCubicLineIntersection wtTs[0]=0 {{0.0624898896,-82.9999771}, {0.0931733027,-82.9999542}, {0.123859018,-82.9999084}, {0.154544711,-82.999855}} {{0.0624898896,-82.9999771}} wnTs[0]=1 {{0.0451717526,-59.9999847}, {0.0624898896,-82.9999771}}
-debugShowCubicLineIntersection wtTs[0]=0 {{0.111722,-59.999897}, {0.0895366594,-59.999939}, {0.0673542097,-59.9999695}, {0.0451717526,-59.9999847}} {{0.111722,-59.999897}} wnTs[0]=1 {{0.154544711,-82.999855}, {0.111722,-59.999897}}
-debugShowCubicLineIntersection wtTs[0]=1 {{0.111722,-59.999897}, {0.0895366594,-59.999939}, {0.0673542097,-59.9999695}, {0.0451717526,-59.9999847}} {{0.0451717526,-59.9999847}} wnTs[0]=0 {{0.0451717526,-59.9999847}, {0.0624898896,-82.9999771}}
-SkOpSegment::debugShowTs - id=3 [o=2 t=0 0.06248549,-82.9999771 w=1 o=0] [o=9,4 t=1 0.0451734141,-59.9999847 w=1 o=0]
-SkOpSegment::debugShowTs o id=10 [o=9,4 t=0 0.0451717526,-59.9999847 w=1 o=0] [o=4 t=5.44e-011 0.0451734141,-59.9999847 w=1 o=0] [o=2 t=1 0.06248549,-82.9999771 w=1 o=0] [o=7 t=1 0.0624898896,-82.9999771 w=1 o=0] operand
-SkOpSegment::addTPair addTPair this=3 0 other=10 1
-SkOpSegment::addTPair addTPair this=10 5.43926879e-011 other=3 1
-SkOpSegment::debugShowTs + id=3 [o=10,2 t=0 0.06248549,-82.9999771 w=1 o=0] [o=10,9,4 t=1 0.0451734141,-59.9999847 w=1 o=0]
-SkOpSegment::debugShowTs o id=10 [o=9,4 t=0 0.0451717526,-59.9999847 w=1 o=0] [o=3,4 t=5.44e-011 0.0451734141,-59.9999847 w=1 o=0] [o=3,2 t=1 0.06248549,-82.9999771 w=1 o=0] [o=7 t=1 0.0624898896,-82.9999771 w=1 o=0] operand
-SkOpContour::calcCoincidentWinding count=1
-SkOpSegment::debugShowTs p id=3 [o=10,2 t=0 0.06248549,-82.9999771 w=1 o=-1] [o=10,9,4 t=1 0.0451734141,-59.9999847 w=1 o=0]
-SkOpSegment::debugShowTs o id=10 [o=9,4 t=0 0.0451717526,-59.9999847 w=1 o=0] [o=3,4 t=5.44e-011 0.0451734141,-59.9999847 w=0 o=0] [o=3,2 t=1 0.06248549,-82.9999771 w=1 o=0] [o=7 t=1 0.0624898896,-82.9999771 w=1 o=0] operand
-SkOpContour::calcPartialCoincidentWinding count=1
-SkOpSegment::debugShowTs p id=4 [o=10,3 t=0 0.0451734141,-59.9999847 w=1 o=-1] [o=10 t=0.000404 0.0451717526,-59.9999847 w=1 o=0] [o=9 t=0.000404 0.0451717526,-59.9999847 w=1 o=0] [o=5 t=1 0.0410718247,-59.9999886 w=1 o=0]
-SkOpSegment::debugShowTs o id=10 [o=9,4 t=0 0.0451717526,-59.9999847 w=0 o=0] [o=3,4 t=5.44e-011 0.0451734141,-59.9999847 w=0 o=0] [o=3,2 t=1 0.06248549,-82.9999771 w=1 o=0] [o=7 t=1 0.0624898896,-82.9999771 w=1 o=0] operand
-SkOpSegment::checkEnds id=4 missing t=0 other=9 otherT=0.999975033 pt=(0.0451734141,-59.9999847)
-SkOpSegment::addTPair addTPair this=4 0 other=9 0.999975033
-SkOpSegment::checkEnds id=9 missing t=0.999975033 other=10 otherT=5.43926879e-011 pt=(0.0451734141,-59.9999847)
-SkOpSegment::addTPair addTPair other duplicate this=9 0.999975033 other=10 5.43926879e-011
-SkOpSegment::addTPair addTPair duplicate this=10 5.43926879e-011 other=9 0.999975033
-SkOpSegment::addTPair addTPair other duplicate this=9 0.999975033 other=10 5.43926879e-011
-SkOpSegment::addTPair addTPair other duplicate this=9 0.999975033 other=10 5.43926879e-011
-SkOpSegment::addTPair addTPair duplicate this=10 5.43926879e-011 other=9 0.999975033
-SkOpSegment::addTPair addTPair other duplicate this=9 0.999975033 other=10 5.43926879e-011
-SkOpSegment::addTPair addTPair other duplicate this=9 0.999975033 other=10 5.43926879e-011
-SkOpSegment::addTPair addTPair duplicate this=10 5.43926879e-011 other=9 0.999975033
-SkOpSegment::addTPair addTPair duplicate this=10 5.43926879e-011 other=9 0.999975033
-SkOpContour::joinCoincidence count=1
-SkOpContour::joinCoincidence count=1
+{{172.5,96}, {137.600006,96}},
+{{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}},
+{{117.300003,60.9000015}, {134.800003,30.7000008}},
+{{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}},
+{{97.1000061,20.6000004}, {97.1000061,55.5}},
+{{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}},
+{{62.0000076,75.8000031}, {31.6000004,58.2999992}},
+{{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}},
+{{21.5,96}, {56.4000015,96}},
+{{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}},
+{{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}},
+{{43.3999977,156.700012}, {3.33333338e+029,119.400002}},
+{{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}},
+{{29.3999996,-10.8000002}, {33.2999992,-25.6000004}},
+{{33.2999992,-25.6000004}, {62,-17.9000015}},
+{{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}},
+{{161.199997,136}, {172.5,96}},
+debugShowCubicIntersection no self intersect {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}}
+debugShowCubicIntersection no self intersect {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}}
+debugShowCubicIntersection no self intersect {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}}
+debugShowCubicIntersection no self intersect {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}}
+debugShowCubicIntersection no self intersect {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}}
+debugShowCubicIntersection no self intersect {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}}
+debugShowCubicIntersection no self intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{161.199997,136}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{117.300003,60.9000015}} wnTs[0]=0 {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wtTs[1]=1 {{117.300003,60.9000015}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicIntersection no intersect {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{134.800003,30.7000008}} wnTs[0]=1 {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowLineIntersection wtTs[0]=0 {{117.300003,60.9000015}, {134.800003,30.7000008}} {{117.300003,60.9000015}} wtTs[1]=1 {{134.800003,30.7000008}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowCubicLineIntersection wtTs[0]=1 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{97.1000061,20.6000004}} wnTs[0]=0 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicLineIntersection wtTs[0]=0 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{134.800003,30.7000008}} wtTs[1]=1 {{97.1000061,20.6000004}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicIntersection no intersect {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{97.1000061,55.5}} wnTs[0]=1 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{97.1000061,20.6000004}} wnTs[0]=0 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicLineIntersection wtTs[0]=0.13656589 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{97.1000061,40.6604424}} wnTs[0]=0.574798 {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicLineIntersection wtTs[0]=1 {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{62.0000076,75.8000031}} wnTs[0]=0 {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{97.1000061,55.5}} wtTs[1]=1 {{62.0000076,75.8000031}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicIntersection no intersect {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{31.6000004,58.2999992}} wnTs[0]=1 {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowLineIntersection wtTs[0]=0 {{62.0000076,75.8000031}, {31.6000004,58.2999992}} {{62.0000076,75.8000031}} wtTs[1]=1 {{31.6000004,58.2999992}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowCubicLineIntersection wtTs[0]=1 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{21.5,96}} wnTs[0]=0 {{21.5,96}, {56.4000015,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{31.6000004,58.2999992}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=1 {{21.5,96}, {56.4000015,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{56.4000015,96}} wnTs[0]=1 {{21.5,96}, {56.4000015,96}}
+debugShowCubicIntersection wtTs[0]=1 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{76.6999969,131.100006}} wnTs[0]=0 {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}}
+debugShowCubicLineIntersection wtTs[0]=1 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{76.6999969,131.100006}} wnTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowCubicIntersection no intersect {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowCubicLineIntersection wtTs[0]=0 {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}} {{76.6999969,131.100006}} wtTs[1]=1 {{43.3999977,156.700012}} wnTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} wnTs[1]=0
+debugShowCubicIntersection no intersect {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}} {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}}
+debugShowLineIntersection wtTs[0]=1 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} {{3.33333338e+029,119.400002}} wnTs[0]=0 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowCubicLineIntersection wtTs[0]=1 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{161.199997,136}} wnTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}}
+debugShowLineIntersection wtTs[0]=0 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} {{161.199997,136}} wnTs[0]=0 {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{29.3999996,-10.8000002}} wnTs[0]=0 {{29.3999996,-10.8000002}, {33.2999992,-25.6000004}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{172.5,96}} wnTs[0]=1 {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{29.3999996,-10.8000002}, {33.2999992,-25.6000004}} {{33.2999992,-25.6000004}} wnTs[0]=0 {{33.2999992,-25.6000004}, {62,-17.9000015}}
+debugShowCubicLineIntersection wtTs[0]=0 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{62,-17.9000015}} wnTs[0]=1 {{33.2999992,-25.6000004}, {62,-17.9000015}}
+debugShowCubicLineIntersection wtTs[0]=1 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{161.199997,136}} wnTs[0]=0 {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=0 {{172.5,96}, {137.600006,96}} {{172.5,96}} wtTs[1]=1 {{137.600006,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}} wnTs[1]=1
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{228.900009,192}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{137.600006,96}} wnTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}}
+debugShowCubicIntersection no intersect {{137.600006,96}, {137.600006,81}, {129.400009,67.9000015}, {117.300003,60.9000015}} {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection wtTs[0]=0.798977321 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{117.320122,60.8652802}} wnTs[0]=0.00114967 {{117.300003,60.9000015}, {134.800003,30.7000008}}
+debugShowCubicLineIntersection wtTs[0]=0.511418257 {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{116.491173,23.1330757}} wnTs[0]=0.999019 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicIntersection no intersect {{134.800003,30.7000008}, {123.700005,24.3000011}, {110.800003,20.6000004}, {97.1000061,20.6000004}} {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}}
+debugShowCubicLineIntersection no intersect {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{97.1000061,20.6000004}, {97.1000061,55.5}}
+debugShowCubicIntersection no intersect {{97.1000061,55.5}, {82.1000061,55.5}, {69.0000076,63.7000008}, {62.0000076,75.8000031}} {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}}
+debugShowCubicLineIntersection wtTs[0]=0.799679553 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{61.8468246,75.7118225}} wnTs[0]=0.00503891 {{62.0000076,75.8000031}, {31.6000004,58.2999992}}
+debugShowCubicLineIntersection no intersect {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowCubicIntersection wtTs[0]=1 {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{21.5,96}} wnTs[0]=1 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}}
+debugShowCubicLineIntersection no intersect {{31.6000004,58.2999992}, {25.2000008,69.4000015}, {21.5,82.3000031}, {21.5,96}} {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}} {{21.5000057,96}} wnTs[0]=1.63955e-007 {{21.5,96}, {56.4000015,96}}
+debugShowLineIntersection wtTs[0]=0 {{21.5000057,96}, {56.4000092,96}} {{21.5000057,96}} wtTs[1]=0.999999781 {{56.4000015,96}} wnTs[0]=1.63955e-007 {{21.5,96}, {56.4000015,96}} wnTs[1]=1
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{21.5,96}, {56.4000015,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=1 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicIntersection wtTs[0]=0 {{56.4000015,96}, {56.4000015,111}, {64.5999985,124.099998}, {76.6999969,131.100006}} {{56.4000015,96}} wnTs[0]=0 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicIntersection wtTs[0]=0.267722282 {{76.6999969,131.100006}, {60.6999969,131.100006}, {47.2999954,141.900009}, {43.3999977,156.700012}} {{64.540802,133.291794}} wnTs[0]=0.131302 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{43.3999977,156.700012}, {3.33333338e+029,119.400002}}
+debugShowLineIntersection wtTs[0]=4.94283788e-028 {{43.3999977,156.700012}, {3.33333338e+029,119.400002}} {{208.16127,156.700012}} wnTs[0]=0.367708 {{228.900009,192}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{137.600006,96}} wtTs[1]=1 {{107.500008,56.7999992}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{107.500008,56.7999992}} wnTs[0]=0 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicLineIntersection wtTs[0]=0 {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{116.500008,23.0999985}} wtTs[1]=1 {{97.0000076,20.4999981}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{97.0000076,20.4999981}} wnTs[0]=0 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{97.0000076,55.4000015}} wtTs[1]=1 {{57.8000069,85.5}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} wnTs[1]=1
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{57.8000069,85.5}} wnTs[0]=0 {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{56.4000092,96}} wnTs[0]=1 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{56.4000092,96}} wnTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}}
+debugShowLineIntersection wtTs[0]=1 {{3.33333338e+029,119.400002}, {29.3999996,-10.8000002}} {{172.5,96}} wnTs[0]=1 {{228.900009,192}, {172.5,96}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{172.5,96}, {137.600006,96}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}}
+debugShowCubicLineIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}}
+debugShowCubicLineIntersection wtTs[0]=0.136112912 {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{97.0000076,40.4949226}} wnTs[0]=0.57292 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}}
+debugShowCubicIntersection no intersect {{62,-17.9000015}, {160.399994,147.300003}, {161.199997,141.699997}, {161.199997,136}} {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowLineIntersection wtTs[0]=1 {{161.199997,136}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{161.199997,136}, {172.5,96}}
+debugShowLineIntersection wtTs[0]=1 {{161.199997,136}, {172.5,96}} {{172.5,96}} wnTs[0]=1 {{228.900009,192}, {172.5,96}}
+debugShowCubicIntersection no self intersect {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}}
+debugShowCubicIntersection no self intersect {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}}
+debugShowCubicIntersection no self intersect {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}}
+debugShowCubicIntersection no self intersect {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}}
+debugShowCubicIntersection no self intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection wtTs[0]=0 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{137.600006,96}} wnTs[0]=1 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection no intersect {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{172.5,96}, {137.600006,96}}
+debugShowLineIntersection wtTs[0]=1 {{228.900009,192}, {172.5,96}} {{172.5,96}} wnTs[0]=0 {{172.5,96}, {137.600006,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{107.500008,56.7999992}} wnTs[0]=0 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicIntersection no intersect {{137.600006,96}, {137.600006,77.1999969}, {124.800003,61.4000015}, {107.500008,56.7999992}} {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}}
+debugShowCubicLineIntersection wtTs[0]=0 {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{116.500008,23.0999985}} wnTs[0]=1 {{107.500008,56.7999992}, {116.500008,23.0999985}}
+debugShowCubicLineIntersection wtTs[0]=1 {{116.500008,23.0999985}, {110.200005,21.3999977}, {103.600006,20.4999981}, {97.0000076,20.4999981}} {{97.0000076,20.4999981}} wnTs[0]=0 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicLineIntersection wtTs[0]=0 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{97.0000076,55.4000015}} wnTs[0]=1 {{97.0000076,20.4999981}, {97.0000076,55.4000015}}
+debugShowCubicLineIntersection wtTs[0]=1 {{97.0000076,55.4000015}, {78.2000122,55.4000015}, {62.4000092,68.2000046}, {57.8000069,85.5}} {{57.8000069,85.5}} wnTs[0]=0 {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowCubicLineIntersection wtTs[0]=0 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}} {{24.1000061,76.5}} wnTs[0]=1 {{57.8000069,85.5}, {24.1000061,76.5}}
+debugShowCubicLineIntersection wtTs[0]=1 {{24.1000061,76.5}, {22.4000053,82.8000031}, {21.5000057,89.4000015}, {21.5000057,96}} {{21.5000057,96}} wnTs[0]=0 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=0 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{56.4000092,96}} wnTs[0]=1 {{21.5000057,96}, {56.4000092,96}}
+debugShowCubicLineIntersection wtTs[0]=1 {{56.4000092,96}, {56.4000092,205.199997}, {228.900009,198.699997}, {228.900009,192}} {{228.900009,192}} wnTs[0]=0 {{228.900009,192}, {172.5,96}}
+SkOpSegment::debugShowTs - id=13 [o=12 t=0 117.300003,60.9000015 w=1 o=0] [o=1 t=0.00115 117.320122,60.8652802 w=1 o=0] [o=14 t=1 134.800003,30.7000008 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::addTPair addTPair this=13 0 other=23 0.999999881
+SkOpSegment::debugShowTs + id=13 [o=23,12 t=0 117.300003,60.9000015 w=1 o=0] [o=1 t=0.00115 117.320122,60.8652802 w=1 o=0] [o=14 t=1 134.800003,30.7000008 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=13 t=1 117.300003,60.9000015 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::debugShowTs - id=17 [o=16 t=0 62.0000076,75.8000031 w=1 o=0] [o=5 t=0.00504 61.8468246,75.7118225 w=1 o=0] [o=18 t=1 31.6000004,58.2999992 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=13 t=1 117.300003,60.9000015 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::addTPair addTPair this=17 0 other=23 0.999999881
+SkOpSegment::debugShowTs + id=17 [o=23,16 t=0 62.0000076,75.8000031 w=1 o=0] [o=5 t=0.00504 61.8468246,75.7118225 w=1 o=0] [o=18 t=1 31.6000004,58.2999992 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=23 [o=22 t=0 3.33333338e+029,119.400002 w=1 o=0] [o=13,17 t=1 62.0000076,75.8000031 w=1 o=0] [o=1,0,12,11,12,14,15,14,16,16,18,20,19,10,27,2,1,3,4,3,5,6,5,9,8,24 t=1 29.3999996,-10.8000002 w=1 o=0] operand
+SkOpSegment::debugShowTs - id=11 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=0 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0]
+SkOpSegment::debugShowTs + id=11 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=0 [o=10,27 t=0 172.5,96 w=1 o=0] [o=1,23,12 t=1 137.600006,96 w=1 o=0]
+SkOpSegment::debugShowTs - id=19 [o=18 t=0 21.5,96 w=1 o=0] [o=7 t=1.64e-007 21.5000057,96 w=1 o=0] [o=23,20 t=1 56.4000015,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=8 [o=7 t=0 21.5000057,96 w=1 o=0] [o=20 t=1 56.4000015,96 w=1 o=0] [o=9,23 t=1 56.4000092,96 w=1 o=0]
+SkOpSegment::addTPair addTPair this=19 1.63955463e-007 other=8 0
+SkOpSegment::addTPair addTPair this=8 0.999999781 other=19 1
+SkOpSegment::debugShowTs + id=19 [o=18 t=0 21.5,96 w=1 o=0] [o=8,7 t=1.64e-007 21.5000057,96 w=1 o=0] [o=8,23,20 t=1 56.4000015,96 w=1 o=0] operand
+SkOpSegment::debugShowTs o id=8 [o=19,7 t=0 21.5000057,96 w=1 o=0] [o=19,20 t=1 56.4000015,96 w=1 o=0] [o=9,23 t=1 56.4000092,96 w=1 o=0]
+SkOpContour::calcCoincidentWinding count=4
+
</div>
</div>
@@ -73,7 +174,7 @@ SkOpContour::joinCoincidence count=1
<script type="text/javascript">
var testDivs = [
- battleOp6001,
+ fuzz487a,
];
var decimal_places = 3; // make this 3 to show more precision