fix path ops fuzz buster
Mark collapsed segments as done and remove collapsed segment references from the coincidence array. Also add test names to global debugging. R=fmalita@chromium.org BUG=512592 Review URL: https://codereview.chromium.org/1250293002
This commit is contained in:
parent
a0170f10aa
commit
d4349723fa
@ -44,7 +44,7 @@ void FixWinding(SkPath* path) {
|
||||
}
|
||||
SkChunkAlloc allocator(4096);
|
||||
SkOpContourHead contourHead;
|
||||
SkOpGlobalState globalState(NULL, &contourHead);
|
||||
SkOpGlobalState globalState(NULL, &contourHead SkDEBUGPARAMS(NULL));
|
||||
SkOpEdgeBuilder builder(*path, &contourHead, &allocator, &globalState);
|
||||
builder.finish(&allocator);
|
||||
SkASSERT(contourHead.next());
|
||||
|
@ -568,6 +568,16 @@ void SkOpCoincidence::fixAligned() {
|
||||
coin->fOppPtTEnd = coin->fOppPtTEnd->doppelganger();
|
||||
}
|
||||
} while ((coin = coin->fNext));
|
||||
coin = fHead;
|
||||
SkCoincidentSpans** priorPtr = &fHead;
|
||||
do {
|
||||
if (coin->fCoinPtTStart->collapsed(coin->fCoinPtTEnd)
|
||||
|| coin->fOppPtTStart->collapsed(coin->fOppPtTEnd)) {
|
||||
*priorPtr = coin->fNext;
|
||||
continue;
|
||||
}
|
||||
priorPtr = &coin->fNext;
|
||||
} while ((coin = coin->fNext));
|
||||
}
|
||||
|
||||
void SkOpCoincidence::fixUp(SkOpPtT* deleted, SkOpPtT* kept) {
|
||||
|
@ -192,6 +192,15 @@ public:
|
||||
return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())];
|
||||
}
|
||||
|
||||
bool findCollapsed() {
|
||||
SkASSERT(fCount > 0);
|
||||
SkOpSegment* segment = &fHead;
|
||||
do {
|
||||
segment->findCollapsed();
|
||||
} while ((segment = segment->next()));
|
||||
return true;
|
||||
}
|
||||
|
||||
SkOpSpan* findSortableTop(SkOpContour* );
|
||||
|
||||
SkOpSegment* first() {
|
||||
|
@ -615,6 +615,15 @@ double SkOpSegment::distSq(double t, SkOpAngle* oppAngle) {
|
||||
return closestDistSq;
|
||||
}
|
||||
|
||||
void SkOpSegment::findCollapsed() {
|
||||
if (fHead.contains(&fTail)) {
|
||||
markAllDone();
|
||||
// move start and end to the same point
|
||||
fHead.alignEnd(0, fHead.pt());
|
||||
fTail.setAligned();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The M and S variable name parts stand for the operators.
|
||||
Mi stands for Minuend (see wiki subtraction, analogous to difference)
|
||||
|
@ -182,6 +182,7 @@ public:
|
||||
void dumpPts() const;
|
||||
void dumpPtsInner() const;
|
||||
|
||||
void findCollapsed();
|
||||
SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** nextStart,
|
||||
SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp op,
|
||||
int xorMiMask, int xorSuMask);
|
||||
|
@ -13,6 +13,16 @@ bool SkOpPtT::alias() const {
|
||||
return this->span()->ptT() != this;
|
||||
}
|
||||
|
||||
bool SkOpPtT::collapsed(const SkOpPtT* check) const {
|
||||
if (fPt != check->fPt) {
|
||||
return false;
|
||||
}
|
||||
SkASSERT(this != check);
|
||||
const SkOpSegment* segment = this->segment();
|
||||
SkASSERT(segment == check->segment());
|
||||
return segment->collapsed();
|
||||
}
|
||||
|
||||
bool SkOpPtT::contains(const SkOpPtT* check) const {
|
||||
SkASSERT(this != check);
|
||||
const SkOpPtT* ptT = this;
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
}
|
||||
|
||||
bool alias() const;
|
||||
bool collapsed(const SkOpPtT* ) const;
|
||||
bool contains(const SkOpPtT* ) const;
|
||||
SkOpPtT* contains(const SkOpSegment* );
|
||||
SkOpContour* contour() const;
|
||||
@ -266,6 +267,10 @@ public:
|
||||
return fSegment;
|
||||
}
|
||||
|
||||
void setAligned() {
|
||||
fAligned = true;
|
||||
}
|
||||
|
||||
void setChased(bool chased) {
|
||||
fChased = chased;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ public:
|
||||
void Assemble(const SkPathWriter& path, SkPathWriter* simple) {
|
||||
SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
|
||||
SkOpContourHead contour;
|
||||
SkOpGlobalState globalState(NULL, &contour);
|
||||
SkOpGlobalState globalState(NULL, &contour SkDEBUGPARAMS(NULL));
|
||||
#if DEBUG_SHOW_TEST_NAME
|
||||
SkDebugf("</div>\n");
|
||||
#endif
|
||||
@ -408,6 +408,13 @@ static void calcAngles(SkOpContourHead* contourList, SkChunkAlloc* allocator) {
|
||||
} while ((contour = contour->next()));
|
||||
}
|
||||
|
||||
static void findCollapsed(SkOpContourHead* contourList) {
|
||||
SkOpContour* contour = contourList;
|
||||
do {
|
||||
contour->findCollapsed();
|
||||
} while ((contour = contour->next()));
|
||||
}
|
||||
|
||||
static bool missingCoincidence(SkOpContourHead* contourList,
|
||||
SkOpCoincidence* coincidence, SkChunkAlloc* allocator) {
|
||||
SkOpContour* contour = contourList;
|
||||
@ -444,6 +451,7 @@ bool HandleCoincidence(SkOpContourHead* contourList, SkOpCoincidence* coincidenc
|
||||
SkOpGlobalState* globalState = contourList->globalState();
|
||||
// combine t values when multiple intersections occur on some segments but not others
|
||||
moveMultiples(contourList);
|
||||
findCollapsed(contourList);
|
||||
// move t values and points together to eliminate small/tiny gaps
|
||||
moveNearby(contourList);
|
||||
align(contourList); // give all span members common values
|
||||
|
@ -25,7 +25,8 @@ SkOpSegment* FindUndone(SkOpContourHead* , SkOpSpanBase** startPtr,
|
||||
void FixWinding(SkPath* path);
|
||||
bool SortContourList(SkOpContourHead** , bool evenOdd, bool oppEvenOdd);
|
||||
bool HandleCoincidence(SkOpContourHead* , SkOpCoincidence* , SkChunkAlloc* );
|
||||
bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, bool expectSuccess);
|
||||
bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result,
|
||||
bool expectSuccess SkDEBUGPARAMS(const char* testName));
|
||||
#if DEBUG_ACTIVE_SPANS
|
||||
void DebugShowActiveSpans(SkOpContourHead* );
|
||||
#endif
|
||||
|
@ -223,12 +223,12 @@ static void dump_op(const SkPath& one, const SkPath& two, SkPathOp op) {
|
||||
#endif
|
||||
|
||||
bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result,
|
||||
bool expectSuccess) {
|
||||
bool expectSuccess SkDEBUGPARAMS(const char* testName)) {
|
||||
SkChunkAlloc allocator(4096); // FIXME: add a constant expression here, tune
|
||||
SkOpContour contour;
|
||||
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
|
||||
SkOpCoincidence coincidence;
|
||||
SkOpGlobalState globalState(&coincidence, contourList);
|
||||
SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(testName));
|
||||
#if DEBUGGING_PATHOPS_FROM_HOST
|
||||
dump_op(one, two, op);
|
||||
#endif
|
||||
@ -304,5 +304,5 @@ bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result,
|
||||
}
|
||||
|
||||
bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
|
||||
return OpDebug(one, two, op, result, true);
|
||||
return OpDebug(one, two, op, result, true SkDEBUGPARAMS(NULL));
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ bool Simplify(const SkPath& path, SkPath* result) {
|
||||
SkOpCoincidence coincidence;
|
||||
SkOpContour contour;
|
||||
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
|
||||
SkOpGlobalState globalState(&coincidence, contourList);
|
||||
SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(NULL));
|
||||
#if DEBUG_SORT
|
||||
SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
|
||||
#endif
|
||||
|
@ -11,7 +11,7 @@ bool TightBounds(const SkPath& path, SkRect* result) {
|
||||
SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
|
||||
SkOpContour contour;
|
||||
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
|
||||
SkOpGlobalState globalState(NULL, contourList);
|
||||
SkOpGlobalState globalState(NULL, contourList SkDEBUGPARAMS(NULL));
|
||||
// turn path into list of segments
|
||||
SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
|
||||
if (!builder.finish(&allocator)) {
|
||||
|
@ -200,13 +200,15 @@ double SkDCubeRoot(double x) {
|
||||
return result;
|
||||
}
|
||||
|
||||
SkOpGlobalState::SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head)
|
||||
SkOpGlobalState::SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head
|
||||
SkDEBUGPARAMS(const char* testName))
|
||||
: fCoincidence(coincidence)
|
||||
, fContourHead(head)
|
||||
, fNested(0)
|
||||
, fWindingFailed(false)
|
||||
, fAngleCoincidence(false)
|
||||
, fPhase(kIntersecting)
|
||||
SkDEBUGPARAMS(fDebugTestName(testName))
|
||||
SkDEBUGPARAMS(fAngleID(0))
|
||||
SkDEBUGPARAMS(fContourID(0))
|
||||
SkDEBUGPARAMS(fPtTID(0))
|
||||
|
@ -28,7 +28,8 @@ class SkOpContourHead;
|
||||
|
||||
class SkOpGlobalState {
|
||||
public:
|
||||
SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head);
|
||||
SkOpGlobalState(SkOpCoincidence* coincidence, SkOpContourHead* head
|
||||
SkDEBUGPARAMS(const char* testName));
|
||||
|
||||
enum Phase {
|
||||
kIntersecting,
|
||||
@ -67,6 +68,7 @@ public:
|
||||
bool debugRunFail() const;
|
||||
const class SkOpSegment* debugSegment(int id) const;
|
||||
const class SkOpSpanBase* debugSpan(int id) const;
|
||||
const char* debugTestName() const { return fDebugTestName; }
|
||||
#endif
|
||||
|
||||
int nested() const {
|
||||
@ -128,6 +130,7 @@ private:
|
||||
bool fAngleCoincidence;
|
||||
Phase fPhase;
|
||||
#ifdef SK_DEBUG
|
||||
const char* fDebugTestName;
|
||||
int fAngleID;
|
||||
int fContourID;
|
||||
int fPtTID;
|
||||
|
@ -419,7 +419,7 @@ static void testQuadAngles(skiatest::Reporter* reporter, const SkDQuad& quad1, c
|
||||
SkPoint shortQuads[2][3];
|
||||
|
||||
SkOpContourHead contour;
|
||||
SkOpGlobalState state(NULL, &contour);
|
||||
SkOpGlobalState state(NULL, &contour SkDEBUGPARAMS(NULL));
|
||||
contour.init(&state, false, false);
|
||||
makeSegment(&contour, quad1, shortQuads[0], allocator);
|
||||
makeSegment(&contour, quad1, shortQuads[1], allocator);
|
||||
|
@ -235,7 +235,7 @@ static const int circleDataSetSize = (int) SK_ARRAY_COUNT(circleDataSet);
|
||||
DEF_TEST(PathOpsAngleCircle, reporter) {
|
||||
SkChunkAlloc allocator(4096);
|
||||
SkOpContourHead contour;
|
||||
SkOpGlobalState state(NULL, &contour);
|
||||
SkOpGlobalState state(NULL, &contour SkDEBUGPARAMS(NULL));
|
||||
contour.init(&state, false, false);
|
||||
for (int index = 0; index < circleDataSetSize; ++index) {
|
||||
CircleData& data = circleDataSet[index];
|
||||
@ -427,7 +427,7 @@ struct FourPoints {
|
||||
DEF_TEST(PathOpsAngleAfter, reporter) {
|
||||
SkChunkAlloc allocator(4096);
|
||||
SkOpContourHead contour;
|
||||
SkOpGlobalState state(NULL, &contour);
|
||||
SkOpGlobalState state(NULL, &contour SkDEBUGPARAMS(NULL));
|
||||
contour.init(&state, false, false);
|
||||
for (int index = intersectDataSetsSize - 1; index >= 0; --index) {
|
||||
IntersectData* dataArray = intersectDataSets[index];
|
||||
|
@ -150,3 +150,124 @@ DEF_TEST(BuilderIssue502792_2, reporter) {
|
||||
SkPath result;
|
||||
builder.resolve(&result);
|
||||
}
|
||||
|
||||
DEF_TEST(Fuzz846, reporter) {
|
||||
/*
|
||||
<clipPath id="clip-circle">
|
||||
<circle id="circle" cx="60" cy="60" r="50" />
|
||||
</clipPath>
|
||||
<clipPath id="clip-rect">
|
||||
<clipPath id="clip-rect">
|
||||
<clipPath id="clip-rect">
|
||||
<clipPath id="clip-rect">
|
||||
<rect x="10" y="30" width="0" height="60" />
|
||||
<rect x="10" y="30" width="0" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="32668" />
|
||||
<rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
<rect x="10" y="255" width="100" height="60" />
|
||||
<rect width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="4294967236" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
</clipPath>
|
||||
<rect x="10" y="30" width="0" height="60" />
|
||||
<rect x="10" y="30" width="0" height="0.18093252719929986369568203" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="32668" height="60" />
|
||||
<rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
<rect x="10" y="255" width="100" height="60" />
|
||||
<rect x="2147483649" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
</clipPath>
|
||||
<rect x="10" y="30" width="0" height="60" />
|
||||
<rect x="10" y="30" width="0" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="32668" height="60" />
|
||||
<rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
<rect x="10" y="255" width="100" height="60" />
|
||||
<rect x="2147483649" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="2879753595" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
</clipPath>
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="0" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="32668" height="60" />
|
||||
<rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
<rect x="10" y="255" width="100" height="60" />
|
||||
<rect x="2147483649" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="10" y="30" width="100" height="4294967236" />
|
||||
<rect x="10" y="30" width="100" height="4294967236" />
|
||||
<rect x="10" y="30" width="100" height="4294967236" />
|
||||
<rect x="10" y="30" width="100" height="4294967236" />
|
||||
<rect x="10" y="30" width="100" height="60" />
|
||||
<rect x="757798030" y="30" width="100" height="60" />
|
||||
*/
|
||||
SkPath clipCircle, clipRect;
|
||||
SkPath inner;
|
||||
clipCircle.addCircle(60, 60, 50); // <circle id="circle" cx="60" cy="60" r="50" />
|
||||
|
||||
inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" />
|
||||
inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+32668, 30+0); // <rect x="10" y="30" width="32668" />
|
||||
inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" />
|
||||
inner.addRect(0, 0, 0+100, 0+60); // <rect width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
clipRect.addPath(inner);
|
||||
inner.reset();
|
||||
inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" />
|
||||
inner.addRect(10, 30, 10+0, 30+0.18093252719929986369568203f); // <rect x="10" y="30" width="0" height="0.18093252719929986369568203" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+32668, 30+60); // <rect x="10" y="30" width="32668" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" />
|
||||
inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
clipRect.addPath(inner);
|
||||
inner.reset();
|
||||
inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" />
|
||||
inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+32668, 30+60); // <rect x="10" y="30" width="32668" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" />
|
||||
inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 2879753595.f, 10+100, 30+2879753595.f); // <rect x="10" y="2879753595" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
clipRect.addPath(inner);
|
||||
inner.reset();
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+0, 30+60); // <rect x="10" y="30" width="0" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+32668, 30+60); // <rect x="10" y="30" width="32668" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+18446744073709551615.f); // <rect x="10" y="30" width="100" height="18446744073709551615" />
|
||||
inner.addRect(10, 255, 10+100, 255+60); // <rect x="10" y="255" width="100" height="60" />
|
||||
inner.addRect(2147483649.f, 30, 2147483649.f+100, 30+60); // <rect x="2147483649" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
|
||||
inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
|
||||
inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
|
||||
inner.addRect(10, 30, 10+100, 30+4294967236.f); // <rect x="10" y="30" width="100" height="4294967236" />
|
||||
inner.addRect(10, 30, 10+100, 30+60); // <rect x="10" y="30" width="100" height="60" />
|
||||
inner.addRect(757798030.f, 30, 757798030.f+100, 30+60); // <rect x="757798030" y="30" width="100" height="60" />
|
||||
clipRect.addPath(inner);
|
||||
|
||||
SkOpBuilder builder;
|
||||
builder.add(clipCircle, kUnion_SkPathOp);
|
||||
builder.add(clipRect, kDifference_SkPathOp);
|
||||
SkPath result;
|
||||
builder.resolve(&result);
|
||||
}
|
||||
|
||||
|
@ -488,7 +488,8 @@ static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) {
|
||||
}
|
||||
#endif
|
||||
|
||||
bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result, bool expectSuccess);
|
||||
bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result,
|
||||
bool expectSuccess SkDEBUGPARAMS(const char* testName));
|
||||
|
||||
static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
|
||||
const SkPathOp shapeOp, const char* testName, bool expectSuccess) {
|
||||
@ -496,7 +497,7 @@ static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
|
||||
showName(a, b, shapeOp);
|
||||
#endif
|
||||
SkPath out;
|
||||
if (!OpDebug(a, b, shapeOp, &out, expectSuccess)) {
|
||||
if (!OpDebug(a, b, shapeOp, &out, expectSuccess SkDEBUGPARAMS(testName))) {
|
||||
SkDebugf("%s did not expect failure\n", __FUNCTION__);
|
||||
REPORTER_ASSERT(reporter, 0);
|
||||
return false;
|
||||
|
@ -4810,11 +4810,76 @@ static void testQuads65(skiatest::Reporter* reporter,const char* filename) {
|
||||
testSimplify(reporter, path, filename);
|
||||
}
|
||||
|
||||
static void fuzz864a(skiatest::Reporter* reporter,const char* filename) {
|
||||
SkPath path;
|
||||
path.moveTo(10, 90);
|
||||
path.lineTo(10, 90);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 90);
|
||||
path.close();
|
||||
path.moveTo(10, 90);
|
||||
path.lineTo(10, 90);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 90);
|
||||
path.close();
|
||||
path.moveTo(10, 90);
|
||||
path.lineTo(110, 90);
|
||||
path.lineTo(110, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 90);
|
||||
path.close();
|
||||
path.moveTo(10, 30);
|
||||
path.lineTo(32678, 30);
|
||||
path.lineTo(32678, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.close();
|
||||
path.moveTo(10, 3.35545e+07f);
|
||||
path.lineTo(110, 3.35545e+07f);
|
||||
path.lineTo(110, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 3.35545e+07f);
|
||||
path.close();
|
||||
path.moveTo(10, 315);
|
||||
path.lineTo(110, 315);
|
||||
path.lineTo(110, 255);
|
||||
path.lineTo(10, 255);
|
||||
path.lineTo(10, 315);
|
||||
path.close();
|
||||
path.moveTo(0, 60);
|
||||
path.lineTo(100, 60);
|
||||
path.lineTo(100, 0);
|
||||
path.lineTo(0, 0);
|
||||
path.lineTo(0, 60);
|
||||
path.close();
|
||||
path.moveTo(10, 90);
|
||||
path.lineTo(110, 90);
|
||||
path.lineTo(110, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 90);
|
||||
path.close();
|
||||
path.moveTo(10, 3.35545e+07f);
|
||||
path.lineTo(110, 3.35545e+07f);
|
||||
path.lineTo(110, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 3.35545e+07f);
|
||||
path.close();
|
||||
path.moveTo(10, 90);
|
||||
path.lineTo(110, 90);
|
||||
path.lineTo(110, 30);
|
||||
path.lineTo(10, 30);
|
||||
path.lineTo(10, 90);
|
||||
path.close();
|
||||
testSimplify(reporter, path, filename);
|
||||
}
|
||||
|
||||
static void (*skipTest)(skiatest::Reporter* , const char* filename) = 0;
|
||||
static void (*firstTest)(skiatest::Reporter* , const char* filename) = 0;
|
||||
static void (*stopTest)(skiatest::Reporter* , const char* filename) = 0;
|
||||
|
||||
static TestDesc tests[] = {
|
||||
TEST(fuzz864a),
|
||||
TEST(testQuads65),
|
||||
TEST(testIssue3838_3),
|
||||
TEST(testIssue3838),
|
||||
|
Loading…
Reference in New Issue
Block a user