aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pathops/SkPathOpsTSect.h16
-rw-r--r--src/pathops/SkPathOpsTypes.h5
-rw-r--r--tests/PathOpsOpTest.cpp45
3 files changed, 61 insertions, 5 deletions
diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h
index 9032af83eb..db2e865a12 100644
--- a/src/pathops/SkPathOpsTSect.h
+++ b/src/pathops/SkPathOpsTSect.h
@@ -882,6 +882,7 @@ bool SkTSect<TCurve, OppCurve>::binarySearchCoin(SkTSect<OppCurve, TCurve>* sect
SkDPoint last = fCurve.ptAtT(tStart);
SkDPoint oppPt;
bool flip = false;
+ bool contained = false;
SkDEBUGCODE(bool down = tStep < 0);
const OppCurve& opp = sect2->fCurve;
do {
@@ -908,6 +909,7 @@ bool SkTSect<TCurve, OppCurve>::binarySearchCoin(SkTSect<OppCurve, TCurve>* sect
if (sect2->fHead->contains(oppTTest)) {
*oppT = oppTTest;
oppPt = work.fCoinStart.perpPt();
+ contained = true;
SkASSERT(down ? result > work.fStartT : result < work.fStartT);
result = work.fStartT;
continue;
@@ -916,6 +918,9 @@ bool SkTSect<TCurve, OppCurve>::binarySearchCoin(SkTSect<OppCurve, TCurve>* sect
tStep = -tStep;
flip = true;
} while (true);
+ if (!contained) {
+ return false;
+ }
if (last.approximatelyEqual(fCurve[0])) {
result = 0;
} else if (last.approximatelyEqual(fCurve[TCurve::kPointLast])) {
@@ -1923,10 +1928,10 @@ struct SkClosestRecord {
fClosest = dist;
}
- bool matesWith(const SkClosestRecord& mate) const {
+ bool matesWith(const SkClosestRecord& mate SkDEBUGPARAMS(SkIntersections* i)) const {
SkASSERT(fC1Span == mate.fC1Span || fC1Span->endT() <= mate.fC1Span->startT()
|| mate.fC1Span->endT() <= fC1Span->startT());
- SkASSERT(fC2Span == mate.fC2Span || fC2Span->endT() <= mate.fC2Span->startT()
+ SkOPOBJASSERT(i, fC2Span == mate.fC2Span || fC2Span->endT() <= mate.fC2Span->startT()
|| mate.fC2Span->endT() <= fC2Span->startT());
return fC1Span == mate.fC1Span || fC1Span->endT() == mate.fC1Span->startT()
|| fC1Span->startT() == mate.fC1Span->endT()
@@ -1975,7 +1980,8 @@ struct SkClosestSect {
fClosest.push_back().reset();
}
- bool find(const SkTSpan<TCurve, OppCurve>* span1, const SkTSpan<OppCurve, TCurve>* span2) {
+ bool find(const SkTSpan<TCurve, OppCurve>* span1, const SkTSpan<OppCurve, TCurve>* span2
+ SkDEBUGPARAMS(SkIntersections* i)) {
SkClosestRecord<TCurve, OppCurve>* record = &fClosest[fUsed];
record->findEnd(span1, span2, 0, 0);
record->findEnd(span1, span2, 0, OppCurve::kPointLast);
@@ -1986,7 +1992,7 @@ struct SkClosestSect {
}
for (int index = 0; index < fUsed; ++index) {
SkClosestRecord<TCurve, OppCurve>* test = &fClosest[index];
- if (test->matesWith(*record)) {
+ if (test->matesWith(*record SkDEBUGPARAMS(i))) {
if (test->fClosest > record->fClosest) {
test->merge(*record);
}
@@ -2212,7 +2218,7 @@ void SkTSect<TCurve, OppCurve>::BinarySearch(SkTSect<TCurve, OppCurve>* sect1,
SkTSpan<OppCurve, TCurve>* result2 = sect2->fHead;
bool found = false;
while (result2) {
- found |= closest.find(result1, result2);
+ found |= closest.find(result1, result2 SkDEBUGPARAMS(intersections));
result2 = result2->fNext;
}
} while ((result1 = result1->fNext));
diff --git a/src/pathops/SkPathOpsTypes.h b/src/pathops/SkPathOpsTypes.h
index ad9c931795..3b98c7b3af 100644
--- a/src/pathops/SkPathOpsTypes.h
+++ b/src/pathops/SkPathOpsTypes.h
@@ -183,9 +183,14 @@ private:
#endif
};
+#ifdef SK_DEBUG
#define SkOPASSERT(cond) SkASSERT(this->globalState()->debugSkipAssert() || cond)
#define SkOPOBJASSERT(obj, cond) SkASSERT((obj->debugGlobalState() && \
obj->debugGlobalState()->debugSkipAssert()) || cond)
+#else
+#define SkOPASSERT(cond)
+#define SkOPOBJASSERT(obj, cond)
+#endif
// Use Almost Equal when comparing coordinates. Use epsilon to compare T values.
bool AlmostEqualUlps(float a, float b);
diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp
index dff26434fd..b217fa3dd9 100644
--- a/tests/PathOpsOpTest.cpp
+++ b/tests/PathOpsOpTest.cpp
@@ -6533,7 +6533,52 @@ SkPath path2(path);
testPathOpFail(reporter, path1, path2, kXOR_SkPathOp, filename);
}
+static void fuzz763_10(skiatest::Reporter* reporter, const char* filename) {
+ SkPath path;
+ path.setFillType((SkPath::FillType) 1);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x68556829)); // 0, 4.03114e+24f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.quadTo(SkBits2Float(0x6a4b7bc0), SkBits2Float(0x00000000), SkBits2Float(0x00000000), SkBits2Float(0x6a4b7bc4)); // 6.14991e+25f, 0, 0, 6.14991e+25f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x68556829)); // 0, 4.03114e+24f
+path.close();
+
+ SkPath path1(path);
+ path.reset();
+ path.setFillType((SkPath::FillType) 0);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.lineTo(SkBits2Float(0x5b2d2968), SkBits2Float(0x2a8c8f55)); // 4.87407e+16f, 2.49685e-13f
+path.lineTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.close();
+path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.conicTo(SkBits2Float(0x682d2fed), SkBits2Float(0x755b6829), SkBits2Float(0x5b292d2b), SkBits2Float(0xc92a8c55), SkBits2Float(0x081f2a21)); // 3.27141e+24f, 2.78131e+32f, 4.76189e+16f, -698565, 4.78968e-34f
+path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.close();
+path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.conicTo(SkBits2Float(0x6a4b7bc0), SkBits2Float(0x2a8ced7a), SkBits2Float(0x21081f21), SkBits2Float(0x3a7bc003), SkBits2Float(0x47ed7a29)); // 6.14991e+25f, 2.50338e-13f, 4.61198e-19f, 0.00096035f, 121588
+path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.close();
+path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.quadTo(SkBits2Float(0x6829682d), SkBits2Float(0x292d555b), SkBits2Float(0x2a8c555b), SkBits2Float(0x081f2a29)); // 3.20001e+24f, 3.84878e-14f, 2.49282e-13f, 4.78969e-34f
+path.conicTo(SkBits2Float(0x6a497b19), SkBits2Float(0x218ced7a), SkBits2Float(0x0321081f), SkBits2Float(0x6a3a7bc0), SkBits2Float(0x47ed3a7a)); // 6.08939e+25f, 9.54963e-19f, 4.7323e-37f, 5.63611e+25f, 121461
+path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.close();
+path.moveTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.quadTo(SkBits2Float(0x282a282a), SkBits2Float(0x8a3a21df), SkBits2Float(0x2728282a), SkBits2Float(0x8a3a2129)); // 9.4456e-15f, -8.96194e-33f, 2.33365e-15f, -8.96181e-33f
+path.quadTo(SkBits2Float(0x8a284f9a), SkBits2Float(0x3a3ac2b3), SkBits2Float(0x2a292827), SkBits2Float(0x962be61d)); // -8.10388e-33f, 0.000712435f, 1.50241e-13f, -1.38859e-25f
+path.lineTo(SkBits2Float(0x272a802a), SkBits2Float(0x2a8c2d29)); // 2.36617e-15f, 2.49003e-13f
+path.lineTo(SkBits2Float(0xc021211f), SkBits2Float(0x6a4b7b03)); // -2.51765f, 6.14982e+25f
+path.close();
+path.moveTo(SkBits2Float(0x4f9a3a29), SkBits2Float(0x3ab38a28)); // 5.17501e+09f, 0.00136978f
+path.quadTo(SkBits2Float(0xc368305b), SkBits2Float(0x5b296855), SkBits2Float(0x2d8c5568), SkBits2Float(0x1f2a2172)); // -232.189f, 4.7684e+16f, 1.59541e-11f, 3.60266e-20f
+path.lineTo(SkBits2Float(0x29c00321), SkBits2Float(0x5b4b7b13)); // 8.52706e-14f, 5.72747e+16f
+
+ SkPath path2(path);
+ testPathOpSkipAssert(reporter, path1, path2, (SkPathOp) 4, filename);
+}
+
+
static struct TestDesc failTests[] = {
+ TEST(fuzz763_10),
TEST(kfuzz2),
TEST(fuzz763_7),
TEST(fuzz763_6),