diff options
author | caryclark <caryclark@google.com> | 2014-09-19 06:33:31 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-19 06:33:31 -0700 |
commit | 630240d18805faf81d8e75172496ad165c2226b2 (patch) | |
tree | 6d025f6779c443536192fd93a23ad2b74e4174c9 | |
parent | 65b48952d7253faf44feb91dfe8953295b1600d0 (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.cpp | 7 | ||||
-rw-r--r-- | src/pathops/SkAddIntersections.h | 2 | ||||
-rw-r--r-- | src/pathops/SkOpContour.cpp | 27 | ||||
-rw-r--r-- | src/pathops/SkOpContour.h | 4 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.cpp | 18 | ||||
-rw-r--r-- | src/pathops/SkOpSegment.h | 2 | ||||
-rw-r--r-- | src/pathops/SkPathOpsCommon.cpp | 4 | ||||
-rw-r--r-- | tests/PathOpsOpTest.cpp | 96 | ||||
-rw-r--r-- | tools/pathops_visualizer.htm | 231 |
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 |