aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/pathops/SkOpCoincidence.cpp4
-rw-r--r--src/pathops/SkPathOpsDebug.cpp11
-rw-r--r--src/pathops/SkPathOpsDebug.h235
-rw-r--r--src/pathops/SkPathOpsTSect.h3
-rw-r--r--tests/PathOpsDebug.cpp288
-rw-r--r--tests/PathOpsSimplifyFailTest.cpp51
-rw-r--r--tests/PathOpsTSectDebug.h2
7 files changed, 487 insertions, 107 deletions
diff --git a/src/pathops/SkOpCoincidence.cpp b/src/pathops/SkOpCoincidence.cpp
index 8fa42a5c4e..3251ec4371 100644
--- a/src/pathops/SkOpCoincidence.cpp
+++ b/src/pathops/SkOpCoincidence.cpp
@@ -691,7 +691,7 @@ bool SkOpCoincidence::addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg,
if (overlap && os && oe && overlap->contains(os, oe)) {
return true;
}
- SkASSERT(!cs || !cs->deleted());
+ FAIL_IF(cs && cs->deleted());
FAIL_IF(os && os->deleted());
SkASSERT(!ce || !ce->deleted());
FAIL_IF(oe && oe->deleted());
@@ -1098,7 +1098,7 @@ bool SkOpCoincidence::apply(DEBUG_COIN_DECLARE_ONLY_PARAMS()) {
FAIL_IF(windValue == -1);
start->setWindValue(windValue);
start->setOppValue(oppValue);
- FAIL_IF(oWindValue == -1);
+ FAIL_IF(oWindValue <= -1);
oStart->setWindValue(oWindValue);
oStart->setOppValue(oOppValue);
if (!windValue && !oppValue) {
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index f13b958a84..346db4b340 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -47,8 +47,6 @@ const char* SkPathOpsDebug::kPathOpStr[] = {"diff", "sect", "union", "xor", "rdi
#if defined SK_DEBUG || !FORCE_RELEASE
-const char* SkPathOpsDebug::kLVerbStr[] = {"", "line", "quad", "cubic"};
-
int SkPathOpsDebug::gContourID = 0;
int SkPathOpsDebug::gSegmentID = 0;
@@ -3124,3 +3122,12 @@ void SkPathOpsDebug::VerifySimplify(const SkPath& path, const SkPath& result) {
}
#endif
+
+// global path dumps for msvs Visual Studio 17 to use from Immediate Window
+void Dump(const SkPath& path) {
+ path.dump();
+}
+
+void DumpHex(const SkPath& path) {
+ path.dumpHex();
+}
diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h
index afdfb32be1..9aec715de1 100644
--- a/src/pathops/SkPathOpsDebug.h
+++ b/src/pathops/SkPathOpsDebug.h
@@ -14,7 +14,36 @@
#include <stdio.h>
enum class SkOpPhase : char;
+struct SkDQuad;
+class SkOpAngle;
+class SkOpCoincidence;
+class SkOpContour;
class SkOpContourHead;
+class SkOpPtT;
+class SkOpSegment;
+class SkOpSpan;
+class SkOpSpanBase;
+struct SkDPoint;
+struct SkDLine;
+struct SkDQuad;
+struct SkDConic;
+struct SkDCubic;
+template<typename TCurve, typename OppCurve> class SkTSect;
+
+// dummy classes to fool msvs Visual Studio 2018 Immediate Window
+#define DummyClasses(a, b) \
+class SkDebugTCoincident##a##b; \
+class SkDebugTSect##a##b; \
+class SkDebugTSpan##a##b
+
+DummyClasses(Quad, Quad);
+DummyClasses(Conic, Quad);
+DummyClasses(Conic, Conic);
+DummyClasses(Cubic, Quad);
+DummyClasses(Cubic, Conic);
+DummyClasses(Cubic, Cubic);
+
+#undef DummyClasses
#ifdef SK_RELEASE
#define FORCE_RELEASE 1
@@ -97,7 +126,7 @@ class SkOpContourHead;
#define DEBUG_PERP 1
#define DEBUG_SHOW_TEST_NAME 1
#define DEBUG_SORT 1
-#define DEBUG_T_SECT 0
+#define DEBUG_T_SECT 0 // enabling may trigger validate asserts even though op does not fail
#define DEBUG_T_SECT_DUMP 0 // Use 1 normally. Use 2 to number segments, 3 for script output
#define DEBUG_T_SECT_LOOP_COUNT 0
#define DEBUG_VALIDATE 1
@@ -233,8 +262,6 @@ class SkOpContourHead;
class SkPathOpsDebug {
public:
- static const char* kLVerbStr[];
-
#if DEBUG_COIN
struct GlitchLog;
@@ -311,7 +338,18 @@ public:
#if DEBUG_ACTIVE_OP
static const char* kPathOpStr[];
#endif
+ static bool gRunFail;
+ static bool gVeryVerbose;
+
+#if DEBUG_ACTIVE_SPANS
+ static SkString gActiveSpans;
+#endif
+#if DEBUG_DUMP_VERIFY
+ static bool gDumpOp;
+ static bool gVerifyOp;
+#endif
+ static const char* OpStr(SkPathOp );
static void MathematicaIze(char* str, size_t bufferSize);
static bool ValidWind(int winding);
static void WindingPrintf(int winding);
@@ -324,86 +362,157 @@ public:
SkPathOpsDebug::DeleteNameStr)))
static void BumpTestName(char* );
#endif
- static const char* OpStr(SkPathOp );
static void ShowActiveSpans(SkOpContourHead* contourList);
static void ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration);
static void ShowPath(const SkPath& one, const SkPath& two, SkPathOp op, const char* name);
- static bool ChaseContains(const SkTDArray<class SkOpSpanBase*>& , const class SkOpSpanBase* );
+ static bool ChaseContains(const SkTDArray<SkOpSpanBase*>& , const SkOpSpanBase* );
static void CheckHealth(class SkOpContourHead* contourList);
- static const class SkOpAngle* DebugAngleAngle(const class SkOpAngle*, int id);
- static class SkOpContour* DebugAngleContour(class SkOpAngle*, int id);
- static const class SkOpPtT* DebugAnglePtT(const class SkOpAngle*, int id);
- static const class SkOpSegment* DebugAngleSegment(const class SkOpAngle*, int id);
- static const class SkOpSpanBase* DebugAngleSpan(const class SkOpAngle*, int id);
-
- static const class SkOpAngle* DebugContourAngle(class SkOpContour*, int id);
- static class SkOpContour* DebugContourContour(class SkOpContour*, int id);
- static const class SkOpPtT* DebugContourPtT(class SkOpContour*, int id);
- static const class SkOpSegment* DebugContourSegment(class SkOpContour*, int id);
- static const class SkOpSpanBase* DebugContourSpan(class SkOpContour*, int id);
-
- static const class SkOpAngle* DebugCoincidenceAngle(class SkOpCoincidence*, int id);
- static class SkOpContour* DebugCoincidenceContour(class SkOpCoincidence*, int id);
- static const class SkOpPtT* DebugCoincidencePtT(class SkOpCoincidence*, int id);
- static const class SkOpSegment* DebugCoincidenceSegment(class SkOpCoincidence*, int id);
- static const class SkOpSpanBase* DebugCoincidenceSpan(class SkOpCoincidence*, int id);
-
- static const class SkOpAngle* DebugPtTAngle(const class SkOpPtT*, int id);
- static class SkOpContour* DebugPtTContour(class SkOpPtT*, int id);
- static const class SkOpPtT* DebugPtTPtT(const class SkOpPtT*, int id);
- static const class SkOpSegment* DebugPtTSegment(const class SkOpPtT*, int id);
- static const class SkOpSpanBase* DebugPtTSpan(const class SkOpPtT*, int id);
-
- static const class SkOpAngle* DebugSegmentAngle(const class SkOpSegment*, int id);
- static class SkOpContour* DebugSegmentContour(class SkOpSegment*, int id);
- static const class SkOpPtT* DebugSegmentPtT(const class SkOpSegment*, int id);
- static const class SkOpSegment* DebugSegmentSegment(const class SkOpSegment*, int id);
- static const class SkOpSpanBase* DebugSegmentSpan(const class SkOpSegment*, int id);
-
- static const class SkOpAngle* DebugSpanAngle(const class SkOpSpanBase*, int id);
- static class SkOpContour* DebugSpanContour(class SkOpSpanBase*, int id);
- static const class SkOpPtT* DebugSpanPtT(const class SkOpSpanBase*, int id);
- static const class SkOpSegment* DebugSpanSegment(const class SkOpSpanBase*, int id);
- static const class SkOpSpanBase* DebugSpanSpan(const class SkOpSpanBase*, int id);
-
#if DEBUG_COIN
- static void DumpCoinDict();
- static void DumpGlitchType(GlitchType );
+ static void DumpCoinDict();
+ static void DumpGlitchType(GlitchType );
#endif
- static bool gRunFail;
- static bool gVeryVerbose;
+};
-#if DEBUG_DUMP_VERIFY
- static bool gDumpOp;
- static bool gVerifyOp;
+// Visual Studio 2017 does not permit calling member functions from the Immediate Window.
+// Global functions work fine, however. Use globals within a namespace rather than
+// static members inside a class.
+namespace SkOpDebug {
+ const SkOpAngle* AngleAngle(const SkOpAngle*, int id);
+ SkOpContour* AngleContour(SkOpAngle*, int id);
+ const SkOpPtT* AnglePtT(const SkOpAngle*, int id);
+ const SkOpSegment* AngleSegment(const SkOpAngle*, int id);
+ const SkOpSpanBase* AngleSpan(const SkOpAngle*, int id);
+
+ const SkOpAngle* ContourAngle(SkOpContour*, int id);
+ SkOpContour* ContourContour(SkOpContour*, int id);
+ const SkOpPtT* ContourPtT(SkOpContour*, int id);
+ const SkOpSegment* ContourSegment(SkOpContour*, int id);
+ const SkOpSpanBase* ContourSpan(SkOpContour*, int id);
+
+ const SkOpAngle* CoincidenceAngle(SkOpCoincidence*, int id);
+ SkOpContour* CoincidenceContour(SkOpCoincidence*, int id);
+ const SkOpPtT* CoincidencePtT(SkOpCoincidence*, int id);
+ const SkOpSegment* CoincidenceSegment(SkOpCoincidence*, int id);
+ const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence*, int id);
+
+ const SkOpAngle* PtTAngle(const SkOpPtT*, int id);
+ SkOpContour* PtTContour(SkOpPtT*, int id);
+ const SkOpPtT* PtTPtT(const SkOpPtT*, int id);
+ const SkOpSegment* PtTSegment(const SkOpPtT*, int id);
+ const SkOpSpanBase* PtTSpan(const SkOpPtT*, int id);
+
+ const SkOpAngle* SegmentAngle(const SkOpSegment*, int id);
+ SkOpContour* SegmentContour(SkOpSegment*, int id);
+ const SkOpPtT* SegmentPtT(const SkOpSegment*, int id);
+ const SkOpSegment* SegmentSegment(const SkOpSegment*, int id);
+ const SkOpSpanBase* SegmentSpan(const SkOpSegment*, int id);
+
+ const SkOpAngle* SpanAngle(const SkOpSpanBase*, int id);
+ SkOpContour* SpanContour(SkOpSpanBase*, int id);
+ const SkOpPtT* SpanPtT(const SkOpSpanBase*, int id);
+ const SkOpSegment* SpanSegment(const SkOpSpanBase*, int id);
+ const SkOpSpanBase* SpanSpan(const SkOpSpanBase*, int id);
- static void DumpOp(const SkPath& one, const SkPath& two, SkPathOp op,
+#if DEBUG_DUMP_VERIFY
+ void DumpOp(const SkPath& one, const SkPath& two, SkPathOp op,
const char* testName);
- static void DumpOp(FILE* file, const SkPath& one, const SkPath& two, SkPathOp op,
+ void DumpOp(FILE* file, const SkPath& one, const SkPath& two, SkPathOp op,
const char* testName);
- static void DumpSimplify(const SkPath& path, const char* testName);
- static void DumpSimplify(FILE* file, const SkPath& path, const char* testName);
- static void ReportOpFail(const SkPath& one, const SkPath& two, SkPathOp op);
- static void ReportSimplifyFail(const SkPath& path);
- static void VerifyOp(const SkPath& one, const SkPath& two, SkPathOp op,
+ void DumpSimplify(const SkPath& path, const char* testName);
+ void DumpSimplify(FILE* file, const SkPath& path, const char* testName);
+ void ReportOpFail(const SkPath& one, const SkPath& two, SkPathOp op);
+ void ReportSimplifyFail(const SkPath& path);
+ void VerifyOp(const SkPath& one, const SkPath& two, SkPathOp op,
const SkPath& result);
- static void VerifySimplify(const SkPath& path, const SkPath& result);
+ void VerifySimplify(const SkPath& path, const SkPath& result);
#endif
-#if DEBUG_ACTIVE_SPANS
- static SkString gActiveSpans;
-#endif
-
-};
-
-struct SkDQuad;
+ // global path dumps for msvs Visual Studio 17 to use from Immediate Window
+ void Dump(const SkOpContour& );
+ void DumpAll(const SkOpContour& );
+ void DumpAngles(const SkOpContour& );
+ void DumpContours(const SkOpContour& );
+ void DumpContoursAll(const SkOpContour& );
+ void DumpContoursAngles(const SkOpContour& );
+ void DumpContoursPts(const SkOpContour& );
+ void DumpContoursPt(const SkOpContour& , int segmentID);
+ void DumpContoursSegment(const SkOpContour& , int segmentID);
+ void DumpContoursSpan(const SkOpContour& , int segmentID);
+ void DumpContoursSpans(const SkOpContour& );
+ void DumpPt(const SkOpContour& , int );
+ void DumpPts(const SkOpContour& , const char* prefix = "seg");
+ void DumpSegment(const SkOpContour& , int );
+ void DumpSegments(const SkOpContour& , const char* prefix = "seg", SkPathOp op = (SkPathOp) -1);
+ void DumpSpan(const SkOpContour& , int );
+ void DumpSpans(const SkOpContour& );
+
+ void Dump(const SkOpSegment& );
+ void DumpAll(const SkOpSegment& );
+ void DumpAngles(const SkOpSegment& );
+ void DumpCoin(const SkOpSegment& );
+ void DumpPts(const SkOpSegment& , const char* prefix = "seg");
+
+ void Dump(const SkOpPtT& );
+ void DumpAll(const SkOpPtT& );
+
+ void Dump(const SkOpSpanBase& );
+ void DumpCoin(const SkOpSpanBase& );
+ void DumpAll(const SkOpSpanBase& );
+
+ void DumpCoin(const SkOpSpan& );
+ bool DumpSpan(const SkOpSpan& );
+
+ void Dump(const SkDConic& );
+ void DumpID(const SkDConic& , int id);
+
+ void Dump(const SkDCubic& );
+ void DumpID(const SkDCubic& , int id);
+
+ void Dump(const SkDLine& );
+ void DumpID(const SkDLine& , int id);
+
+ void Dump(const SkDQuad& );
+ void DumpID(const SkDQuad& , int id);
+
+ void Dump(const SkDPoint& );
+
+// dummy declarations to fool msvs Visual Studio 2018 Immediate Window
+#define DummyDeclarations(a, b) \
+ void Dump(const SkDebugTCoincident##a##b& ); \
+ \
+ void Dump(const SkDebugTSect##a##b& ); \
+ void DumpBoth(const SkDebugTSect##a##b& , SkDebugTSect##a##b* ); \
+ void DumpBounded(const SkDebugTSect##a##b& , int id); \
+ void DumpBounds(const SkDebugTSect##a##b& ); \
+ void DumpCoin(const SkDebugTSect##a##b& ); \
+ void DumpCoinCurves(const SkDebugTSect##a##b& ); \
+ void DumpCurves(const SkDebugTSect##a##b& ); \
+ \
+ void Dump(const SkDebugTSpan##a##b& ); \
+ void DumpAll(const SkDebugTSpan##a##b& ); \
+ void DumpBounded(const SkDebugTSpan##a##b& , int id); \
+ void DumpBounds(const SkDebugTSpan##a##b& ); \
+ void DumpCoin(const SkDebugTSpan##a##b& )
+
+ DummyDeclarations(Quad, Quad);
+ DummyDeclarations(Conic, Quad);
+ DummyDeclarations(Conic, Conic);
+ DummyDeclarations(Cubic, Quad);
+ DummyDeclarations(Cubic, Conic);
+ DummyDeclarations(Cubic, Cubic);
+#undef DummyDeclarations
+}
// generates tools/path_sorter.htm and path_visualizer.htm compatible data
void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo);
void DumpT(const SkDQuad& quad, double t);
+// global path dumps for msvs Visual Studio 17 to use from Immediate Window
+void Dump(const SkPath& path);
+void DumpHex(const SkPath& path);
+
#endif
diff --git a/src/pathops/SkPathOpsTSect.h b/src/pathops/SkPathOpsTSect.h
index 833e735da6..1e78f2a108 100644
--- a/src/pathops/SkPathOpsTSect.h
+++ b/src/pathops/SkPathOpsTSect.h
@@ -415,6 +415,7 @@ SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::addFollowing(
next->fPrev = result;
}
result->resetBounds(fCurve);
+ // world may not be consistent to call validate here
result->validate();
return result;
}
@@ -1797,6 +1798,7 @@ void SkTSect<TCurve, OppCurve>::removeSpanRange(SkTSpan<TCurve, OppCurve>* first
final->fPrev = first;
}
first->fNext = final;
+ // world may not be ready for validation here
first->validate();
}
@@ -1888,6 +1890,7 @@ bool SkTSect<TCurve, OppCurve>::unlinkSpan(SkTSpan<TCurve, OppCurve>* span) {
if (next->fStartT > next->fEndT) {
return false;
}
+ // world may not be ready for validate here
next->validate();
}
} else {
diff --git a/tests/PathOpsDebug.cpp b/tests/PathOpsDebug.cpp
index 8324f37dd4..942f99c7ae 100644
--- a/tests/PathOpsDebug.cpp
+++ b/tests/PathOpsDebug.cpp
@@ -208,130 +208,134 @@ void SkIntersections::dump() const {
SkDebugf("\n");
}
-const SkOpAngle* SkPathOpsDebug::DebugAngleAngle(const SkOpAngle* angle, int id) {
+namespace SkOpDebug {
+
+const ::SkOpAngle* AngleAngle(const ::SkOpAngle* angle, int id) {
return angle->debugAngle(id);
}
-SkOpContour* SkPathOpsDebug::DebugAngleContour(SkOpAngle* angle, int id) {
+::SkOpContour* AngleContour(::SkOpAngle* angle, int id) {
return angle->debugContour(id);
}
-const SkOpPtT* SkPathOpsDebug::DebugAnglePtT(const SkOpAngle* angle, int id) {
+const ::SkOpPtT* AnglePtT(const ::SkOpAngle* angle, int id) {
return angle->debugPtT(id);
}
-const SkOpSegment* SkPathOpsDebug::DebugAngleSegment(const SkOpAngle* angle, int id) {
+const ::SkOpSegment* AngleSegment(const ::SkOpAngle* angle, int id) {
return angle->debugSegment(id);
}
-const SkOpSpanBase* SkPathOpsDebug::DebugAngleSpan(const SkOpAngle* angle, int id) {
+const ::SkOpSpanBase* AngleSpan(const ::SkOpAngle* angle, int id) {
return angle->debugSpan(id);
}
-const SkOpAngle* SkPathOpsDebug::DebugContourAngle(SkOpContour* contour, int id) {
+const ::SkOpAngle* ContourAngle(::SkOpContour* contour, int id) {
return contour->debugAngle(id);
}
-SkOpContour* SkPathOpsDebug::DebugContourContour(SkOpContour* contour, int id) {
+::SkOpContour* ContourContour(::SkOpContour* contour, int id) {
return contour->debugContour(id);
}
-const SkOpPtT* SkPathOpsDebug::DebugContourPtT(SkOpContour* contour, int id) {
+const ::SkOpPtT* ContourPtT(::SkOpContour* contour, int id) {
return contour->debugPtT(id);
}
-const SkOpSegment* SkPathOpsDebug::DebugContourSegment(SkOpContour* contour, int id) {
+const ::SkOpSegment* ContourSegment(::SkOpContour* contour, int id) {
return contour->debugSegment(id);
}
-const SkOpSpanBase* SkPathOpsDebug::DebugContourSpan(SkOpContour* contour, int id) {
+const ::SkOpSpanBase* ContourSpan(::SkOpContour* contour, int id) {
return contour->debugSpan(id);
}
-const SkOpAngle* SkPathOpsDebug::DebugCoincidenceAngle(SkOpCoincidence* coin, int id) {
+const ::SkOpAngle* CoincidenceAngle(::SkOpCoincidence* coin, int id) {
return coin->debugAngle(id);
}
-SkOpContour* SkPathOpsDebug::DebugCoincidenceContour(SkOpCoincidence* coin, int id) {
+::SkOpContour* CoincidenceContour(::SkOpCoincidence* coin, int id) {
return coin->debugContour(id);
}
-const SkOpPtT* SkPathOpsDebug::DebugCoincidencePtT(SkOpCoincidence* coin, int id) {
+const ::SkOpPtT* CoincidencePtT(::SkOpCoincidence* coin, int id) {
return coin->debugPtT(id);
}
-const SkOpSegment* SkPathOpsDebug::DebugCoincidenceSegment(SkOpCoincidence* coin, int id) {
+const ::SkOpSegment* CoincidenceSegment(::SkOpCoincidence* coin, int id) {
return coin->debugSegment(id);
}
-const SkOpSpanBase* SkPathOpsDebug::DebugCoincidenceSpan(SkOpCoincidence* coin, int id) {
+const ::SkOpSpanBase* CoincidenceSpan(::SkOpCoincidence* coin, int id) {
return coin->debugSpan(id);
}
-const SkOpAngle* SkPathOpsDebug::DebugPtTAngle(const SkOpPtT* ptT, int id) {
+const ::SkOpAngle* PtTAngle(const ::SkOpPtT* ptT, int id) {
return ptT->debugAngle(id);
}
-SkOpContour* SkPathOpsDebug::DebugPtTContour(SkOpPtT* ptT, int id) {
+::SkOpContour* PtTContour(::SkOpPtT* ptT, int id) {
return ptT->debugContour(id);
}
-const SkOpPtT* SkPathOpsDebug::DebugPtTPtT(const SkOpPtT* ptT, int id) {
+const ::SkOpPtT* PtTPtT(const ::SkOpPtT* ptT, int id) {
return ptT->debugPtT(id);
}
-const SkOpSegment* SkPathOpsDebug::DebugPtTSegment(const SkOpPtT* ptT, int id) {
+const ::SkOpSegment* PtTSegment(const ::SkOpPtT* ptT, int id) {
return ptT->debugSegment(id);
}
-const SkOpSpanBase* SkPathOpsDebug::DebugPtTSpan(const SkOpPtT* ptT, int id) {
+const ::SkOpSpanBase* PtTSpan(const ::SkOpPtT* ptT, int id) {
return ptT->debugSpan(id);
}
-const SkOpAngle* SkPathOpsDebug::DebugSegmentAngle(const SkOpSegment* span, int id) {
+const ::SkOpAngle* SegmentAngle(const ::SkOpSegment* span, int id) {
return span->debugAngle(id);
}
-SkOpContour* SkPathOpsDebug::DebugSegmentContour(SkOpSegment* span, int id) {
+::SkOpContour* SegmentContour(::SkOpSegment* span, int id) {
return span->debugContour(id);
}
-const SkOpPtT* SkPathOpsDebug::DebugSegmentPtT(const SkOpSegment* span, int id) {
+const ::SkOpPtT* SegmentPtT(const ::SkOpSegment* span, int id) {
return span->debugPtT(id);
}
-const SkOpSegment* SkPathOpsDebug::DebugSegmentSegment(const SkOpSegment* span, int id) {
+const ::SkOpSegment* SegmentSegment(const ::SkOpSegment* span, int id) {
return span->debugSegment(id);
}
-const SkOpSpanBase* SkPathOpsDebug::DebugSegmentSpan(const SkOpSegment* span, int id) {
+const ::SkOpSpanBase* SegmentSpan(const ::SkOpSegment* span, int id) {
return span->debugSpan(id);
}
-const SkOpAngle* SkPathOpsDebug::DebugSpanAngle(const SkOpSpanBase* span, int id) {
+const ::SkOpAngle* SpanAngle(const ::SkOpSpanBase* span, int id) {
return span->debugAngle(id);
}
-SkOpContour* SkPathOpsDebug::DebugSpanContour(SkOpSpanBase* span, int id) {
+::SkOpContour* SpanContour(::SkOpSpanBase* span, int id) {
return span->debugContour(id);
}
-const SkOpPtT* SkPathOpsDebug::DebugSpanPtT(const SkOpSpanBase* span, int id) {
+const ::SkOpPtT* SpanPtT(const ::SkOpSpanBase* span, int id) {
return span->debugPtT(id);
}
-const SkOpSegment* SkPathOpsDebug::DebugSpanSegment(const SkOpSpanBase* span, int id) {
+const ::SkOpSegment* SpanSegment(const ::SkOpSpanBase* span, int id) {
return span->debugSegment(id);
}
-const SkOpSpanBase* SkPathOpsDebug::DebugSpanSpan(const SkOpSpanBase* span, int id) {
+const ::SkOpSpanBase* SpanSpan(const ::SkOpSpanBase* span, int id) {
return span->debugSpan(id);
}
+} // namespace SkPathOpsDebug
+
#if DEBUG_COIN
void SkPathOpsDebug::DumpCoinDict() {
- gCoinSumChangedDict.dump("unused coin algorithm", false);
- gCoinSumVisitedDict.dump("visited coin function", true);
+ SkPathOpsDebug::gCoinSumChangedDict.dump("unused coin algorithm", false);
+ SkPathOpsDebug::gCoinSumVisitedDict.dump("visited coin function", true);
}
void SkPathOpsDebug::CoinDict::dump(const char* str, bool visitCheck) const {
@@ -1479,3 +1483,223 @@ const SkOpSpanBase* SkOpGlobalState::debugSpan(int id) const {
#if DEBUG_T_SECT_DUMP > 1
int gDumpTSectNum;
#endif
+
+// global path dumps for msvs Visual Studio 17 to use from Immediate Window
+namespace SkOpDebug {
+
+ void Dump(const SkOpContour& contour) {
+ contour.dump();
+ }
+
+ void DumpAll(const SkOpContour& contour) {
+ contour.dumpAll();
+ }
+
+ void DumpAngles(const SkOpContour& contour) {
+ contour.dumpAngles();
+ }
+
+ void DumpContours(const SkOpContour& contour) {
+ contour.dumpContours();
+ }
+
+ void DumpContoursAll(const SkOpContour& contour) {
+ contour.dumpContoursAll();
+ }
+
+ void DumpContoursAngles(const SkOpContour& contour) {
+ contour.dumpContoursAngles();
+ }
+
+ void DumpContoursPts(const SkOpContour& contour) {
+ contour.dumpContoursPts();
+ }
+
+ void DumpContoursPt(const SkOpContour& contour, int segmentID) {
+ contour.dumpContoursPt(segmentID);
+ }
+
+ void DumpContoursSegment(const SkOpContour& contour, int segmentID) {
+ contour.dumpContoursSegment(segmentID);
+ }
+
+ void DumpContoursSpan(const SkOpContour& contour, int segmentID) {
+ contour.dumpContoursSpan(segmentID);
+ }
+
+ void DumpContoursSpans(const SkOpContour& contour) {
+ contour.dumpContoursSpans();
+ }
+
+ void DumpPt(const SkOpContour& contour, int pt) {
+ contour.dumpPt(pt);
+ }
+
+ void DumpPts(const SkOpContour& contour, const char* prefix) {
+ contour.dumpPts(prefix);
+ }
+
+ void DumpSegment(const SkOpContour& contour, int seg) {
+ contour.dumpSegment(seg);
+ }
+
+ void DumpSegments(const SkOpContour& contour, const char* prefix, SkPathOp op) {
+ contour.dumpSegments(prefix, op);
+ }
+
+ void DumpSpan(const SkOpContour& contour, int span) {
+ contour.dumpSpan(span);
+ }
+
+ void DumpSpans(const SkOpContour& contour ) {
+ contour.dumpSpans();
+ }
+
+ void Dump(const SkOpSegment& segment) {
+ segment.dump();
+ }
+
+ void DumpAll(const SkOpSegment& segment) {
+ segment.dumpAll();
+ }
+
+ void DumpAngles(const SkOpSegment& segment) {
+ segment.dumpAngles();
+ }
+
+ void DumpCoin(const SkOpSegment& segment) {
+ segment.dumpCoin();
+ }
+
+ void DumpPts(const SkOpSegment& segment, const char* prefix) {
+ segment.dumpPts(prefix);
+ }
+
+ void Dump(const SkOpPtT& ptT) {
+ ptT.dump();
+ }
+
+ void DumpAll(const SkOpPtT& ptT) {
+ ptT.dumpAll();
+ }
+
+ void Dump(const SkOpSpanBase& spanBase) {
+ spanBase.dump();
+ }
+
+ void DumpCoin(const SkOpSpanBase& spanBase) {
+ spanBase.dumpCoin();
+ }
+
+ void DumpAll(const SkOpSpanBase& spanBase) {
+ spanBase.dumpAll();
+ }
+
+ void DumpCoin(const SkOpSpan& span) {
+ span.dumpCoin();
+ }
+
+ bool DumpSpan(const SkOpSpan& span) {
+ return span.dumpSpan();
+ }
+
+ void Dump(const SkDConic& conic) {
+ conic.dump();
+ }
+
+ void DumpID(const SkDConic& conic, int id) {
+ conic.dumpID(id);
+ }
+
+ void Dump(const SkDCubic& cubic) {
+ cubic.dump();
+ }
+
+ void DumpID(const SkDCubic& cubic, int id) {
+ cubic.dumpID(id);
+ }
+
+ void Dump(const SkDLine& line) {
+ line.dump();
+ }
+
+ void DumpID(const SkDLine& line, int id) {
+ line.dumpID(id);
+ }
+
+ void Dump(const SkDQuad& quad) {
+ quad.dump();
+ }
+
+ void DumpID(const SkDQuad& quad, int id) {
+ quad.dumpID(id);
+ }
+
+ void Dump(const SkDPoint& point) {
+ point.dump();
+ }
+
+// dummy definitions to fool msvs Visual Studio 2018 Immediate Window
+#define DummyDefinitions(a, b) \
+ \
+ void Dump(const SkDebugTCoincident##a##b& curve) { \
+ ((const SkTCoincident<SkD##a, SkD##b>& ) curve).dump(); \
+ } \
+ \
+ void Dump(const SkDebugTSect##a##b& curve) { \
+ ((const SkTSect<SkD##a, SkD##b>& ) curve).dump(); \
+ } \
+ \
+ void DumpBoth(const SkDebugTSect##a##b& curve, SkDebugTSect##a##b* opp) { \
+ ((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBoth((SkTSect<SkD##b, SkD##a>* ) opp); \
+ } \
+ \
+ void DumpBounded(const SkDebugTSect##a##b& curve, int id) { \
+ ((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBounded(id); \
+ } \
+ \
+ void DumpBounds(const SkDebugTSect##a##b& curve) { \
+ ((const SkTSect<SkD##a, SkD##b>& ) curve).dumpBounds(); \
+ } \
+ \
+ void DumpCoin(const SkDebugTSect##a##b& curve) { \
+ ((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCoin(); \
+ } \
+ \
+ void DumpCoinCurves(const SkDebugTSect##a##b& curve) { \
+ ((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCoinCurves(); \
+ } \
+ \
+ void DumpCurves(const SkDebugTSect##a##b& curve) { \
+ ((const SkTSect<SkD##a, SkD##b>& ) curve).dumpCurves(); \
+ } \
+ \
+ void Dump(const SkDebugTSpan##a##b& curve) { \
+ ((const SkTSpan<SkD##a, SkD##b>& ) curve).dump(); \
+ } \
+ \
+ void DumpAll(const SkDebugTSpan##a##b& curve) { \
+ ((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpAll(); \
+ } \
+ \
+ void DumpBounded(const SkDebugTSpan##a##b& curve, int id) { \
+ ((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpBounded(id); \
+ } \
+ \
+ void DumpBounds(const SkDebugTSpan##a##b& curve) { \
+ ((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpBounds(); \
+ } \
+ \
+ void DumpCoin(const SkDebugTSpan##a##b& curve) { \
+ ((const SkTSpan<SkD##a, SkD##b>& ) curve).dumpCoin(); \
+ }
+
+ DummyDefinitions(Quad, Quad);
+ DummyDefinitions(Conic, Quad);
+ DummyDefinitions(Conic, Conic);
+ DummyDefinitions(Cubic, Quad);
+ DummyDefinitions(Cubic, Conic);
+ DummyDefinitions(Cubic, Cubic);
+
+#undef DummyDefinitions
+}
diff --git a/tests/PathOpsSimplifyFailTest.cpp b/tests/PathOpsSimplifyFailTest.cpp
index 58179a2175..eb43ae65ad 100644
--- a/tests/PathOpsSimplifyFailTest.cpp
+++ b/tests/PathOpsSimplifyFailTest.cpp
@@ -217,20 +217,57 @@ path.close();
static void fuzz_x3(skiatest::Reporter* reporter, const char* filename) {
SkPath path;
-path.setFillType(SkPath::kWinding_FillType);
-path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
-path.cubicTo(SkBits2Float(0x92743420), SkBits2Float(0x74747474), SkBits2Float(0x0f747c74), SkBits2Float(0xff538565), SkBits2Float(0x74744374), SkBits2Float(0x20437474)); // -7.70571e-28f, 7.74708e+31f, 1.20541e-29f, -2.8116e+38f, 7.74102e+31f, 1.65557e-19f
-path.conicTo(SkBits2Float(0x7474926d), SkBits2Float(0x7c747474), SkBits2Float(0x00170f74), SkBits2Float(0x3a7410d7), SkBits2Float(0x3a3a3a3a)); // 7.7508e+31f, 5.07713e+36f, 2.11776e-39f, 0.000931037f, 0.000710401f
-path.quadTo(SkBits2Float(0x203a3a3a), SkBits2Float(0x7459f43a), SkBits2Float(0x74747474), SkBits2Float(0x2043ad6e)); // 1.57741e-19f, 6.90724e+31f, 7.74708e+31f, 1.65745e-19f
-path.conicTo(SkBits2Float(0x7474b374), SkBits2Float(0x74747474), SkBits2Float(0x0f747c74), SkBits2Float(0xff537065), SkBits2Float(0x74744374)); // 7.75488e+31f, 7.74708e+31f, 1.20541e-29f, -2.81051e+38f, 7.74102e+31f
-path.cubicTo(SkBits2Float(0x3a3a3a3a), SkBits2Float(0x3a2c103a), SkBits2Float(0x7474263a), SkBits2Float(0x74976507), SkBits2Float(0x000000ff), SkBits2Float(0x00000000)); // 0.000710401f, 0.00065637f, 7.7374e+31f, 9.59578e+31f, 3.57331e-43f, 0
+path.setFillType(SkPath::kWinding_FillType);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.cubicTo(SkBits2Float(0x92743420), SkBits2Float(0x74747474), SkBits2Float(0x0f747c74), SkBits2Float(0xff538565), SkBits2Float(0x74744374), SkBits2Float(0x20437474)); // -7.70571e-28f, 7.74708e+31f, 1.20541e-29f, -2.8116e+38f, 7.74102e+31f, 1.65557e-19f
+path.conicTo(SkBits2Float(0x7474926d), SkBits2Float(0x7c747474), SkBits2Float(0x00170f74), SkBits2Float(0x3a7410d7), SkBits2Float(0x3a3a3a3a)); // 7.7508e+31f, 5.07713e+36f, 2.11776e-39f, 0.000931037f, 0.000710401f
+path.quadTo(SkBits2Float(0x203a3a3a), SkBits2Float(0x7459f43a), SkBits2Float(0x74747474), SkBits2Float(0x2043ad6e)); // 1.57741e-19f, 6.90724e+31f, 7.74708e+31f, 1.65745e-19f
+path.conicTo(SkBits2Float(0x7474b374), SkBits2Float(0x74747474), SkBits2Float(0x0f747c74), SkBits2Float(0xff537065), SkBits2Float(0x74744374)); // 7.75488e+31f, 7.74708e+31f, 1.20541e-29f, -2.81051e+38f, 7.74102e+31f
+path.cubicTo(SkBits2Float(0x3a3a3a3a), SkBits2Float(0x3a2c103a), SkBits2Float(0x7474263a), SkBits2Float(0x74976507), SkBits2Float(0x000000ff), SkBits2Float(0x00000000)); // 0.000710401f, 0.00065637f, 7.7374e+31f, 9.59578e+31f, 3.57331e-43f, 0
testSimplifyFuzz(reporter, path, filename);
}
+static void fuzz_k1(skiatest::Reporter* reporter, const char* filename) {
+ SkPath path;
+path.setFillType(SkPath::kWinding_FillType);
+path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000)); // 0, 0
+path.conicTo(SkBits2Float(0x2073732f), SkBits2Float(0x73f17f00), SkBits2Float(0x737b7b73), SkBits2Float(0x73916773), SkBits2Float(0x00738773)); // 2.0621e-19f, 3.82666e+31f, 1.99245e+31f, 2.30402e+31f, 1.06097e-38f
+path.lineTo(SkBits2Float(0x5803736d), SkBits2Float(0x807b5ba1)); // 5.78127e+14f, -1.13286e-38f
+path.cubicTo(SkBits2Float(0x7b7f7f7b), SkBits2Float(0x7373737b), SkBits2Float(0x1b617380), SkBits2Float(0x48541b10), SkBits2Float(0x73817373), SkBits2Float(0x00717373)); // 1.32662e+36f, 1.92882e+31f, 1.86489e-22f, 217196, 2.05123e+31f, 1.04188e-38f
+path.moveTo(SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.92882e+31f, 8.59425e+09f
+path.cubicTo(SkBits2Float(0x7b738364), SkBits2Float(0x73607380), SkBits2Float(0x7b738362), SkBits2Float(0x00007180), SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.26439e+36f, 1.77829e+31f, 1.26439e+36f, 4.07161e-41f, 1.92882e+31f, 8.59425e+09f
+path.cubicTo(SkBits2Float(0x7b737364), SkBits2Float(0x73607380), SkBits2Float(0x7b738366), SkBits2Float(0x73737380), SkBits2Float(0x73738873), SkBits2Float(0x96737353)); // 1.26407e+36f, 1.77829e+31f, 1.26439e+36f, 1.92882e+31f, 1.92947e+31f, -1.96658e-25f
+path.moveTo(SkBits2Float(0x00640000), SkBits2Float(0x73737373)); // 9.18355e-39f, 1.92882e+31f
+path.lineTo(SkBits2Float(0x40005d7b), SkBits2Float(0x58435460)); // 2.00571f, 8.59069e+14f
+path.cubicTo(SkBits2Float(0x7b7f7f7b), SkBits2Float(0x7373737b), SkBits2Float(0x1b617380), SkBits2Float(0x48400010), SkBits2Float(0x73817373), SkBits2Float(0x00717373)); // 1.32662e+36f, 1.92882e+31f, 1.86489e-22f, 196608, 2.05123e+31f, 1.04188e-38f
+path.moveTo(SkBits2Float(0x06737376), SkBits2Float(0x50001073)); // 4.5788e-35f, 8.59425e+09f
+path.cubicTo(SkBits2Float(0x7b737364), SkBits2Float(0x73737373), SkBits2Float(0x53737388), SkBits2Float(0x00967373), SkBits2Float(0x00640000), SkBits2Float(0x73737373)); // 1.26407e+36f, 1.92882e+31f, 1.04562e+12f, 1.38167e-38f, 9.18355e-39f, 1.92882e+31f
+path.lineTo(SkBits2Float(0x40005d7b), SkBits2Float(0x5843546d)); // 2.00571f, 8.59069e+14f
+path.cubicTo(SkBits2Float(0x7b7f7f7b), SkBits2Float(0x7373737b), SkBits2Float(0x1b617380), SkBits2Float(0x4840001e), SkBits2Float(0x73817373), SkBits2Float(0x007e7373)); // 1.32662e+36f, 1.92882e+31f, 1.86489e-22f, 196608, 2.05123e+31f, 1.16127e-38f
+path.moveTo(SkBits2Float(0x06737376), SkBits2Float(0x50001073)); // 4.5788e-35f, 8.59425e+09f
+path.cubicTo(SkBits2Float(0x7b737364), SkBits2Float(0x73607380), SkBits2Float(0x01008366), SkBits2Float(0x73737380), SkBits2Float(0x737d8873), SkBits2Float(0x7b4e7b53)); // 1.26407e+36f, 1.77829e+31f, 2.36042e-38f, 1.92882e+31f, 2.0087e+31f, 1.07211e+36f
+path.cubicTo(SkBits2Float(0x667b7b7b), SkBits2Float(0x73737b7b), SkBits2Float(0x73739167), SkBits2Float(0x40007387), SkBits2Float(0x5803736d), SkBits2Float(0x807b5ba1)); // 2.96898e+23f, 1.92907e+31f, 1.92974e+31f, 2.00705f, 5.78127e+14f, -1.13286e-38f
+path.cubicTo(SkBits2Float(0x7b7f7f7b), SkBits2Float(0x7373737b), SkBits2Float(0x1b617380), SkBits2Float(0x48401b10), SkBits2Float(0x73817373), SkBits2Float(0x00717373)); // 1.32662e+36f, 1.92882e+31f, 1.86489e-22f, 196716, 2.05123e+31f, 1.04188e-38f
+path.moveTo(SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.92882e+31f, 8.59425e+09f
+path.cubicTo(SkBits2Float(0x7b737364), SkBits2Float(0x73607380), SkBits2Float(0x7b738366), SkBits2Float(0x00007180), SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.26407e+36f, 1.77829e+31f, 1.26439e+36f, 4.07161e-41f, 1.92882e+31f, 8.59425e+09f
+path.cubicTo(SkBits2Float(0x7b737364), SkBits2Float(0x73607380), SkBits2Float(0x79738366), SkBits2Float(0x79797979), SkBits2Float(0xff000079), SkBits2Float(0xf2f2f2ff)); // 1.26407e+36f, 1.77829e+31f, 7.90246e+34f, 8.09591e+34f, -1.70144e+38f, -9.62421e+30f
+path.cubicTo(SkBits2Float(0x6579796a), SkBits2Float(0x79795979), SkBits2Float(0x4d4d7b57), SkBits2Float(0x4d574d66), SkBits2Float(0x7968ac4d), SkBits2Float(0x79797979)); // 7.36318e+22f, 8.09185e+34f, 2.15463e+08f, 2.25761e+08f, 7.55067e+34f, 8.09591e+34f
+path.quadTo(SkBits2Float(0xf2f27b79), SkBits2Float(0x867b9c7b), SkBits2Float(0xddf2f2f2), SkBits2Float(0x1379796a)); // -9.60571e+30f, -4.73228e-35f, -2.18829e+18f, 3.14881e-27f
+path.lineTo(SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.92882e+31f, 8.59425e+09f
+path.close();
+path.moveTo(SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.92882e+31f, 8.59425e+09f
+path.quadTo(SkBits2Float(0xe7797979), SkBits2Float(0xf2794d4d), SkBits2Float(0x79a8ddf2), SkBits2Float(0x13132513)); // -1.17811e+24f, -4.93793e+30f, 1.09601e+35f, 1.85723e-27f
+path.lineTo(SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.92882e+31f, 8.59425e+09f
+path.close();
+path.moveTo(SkBits2Float(0x7373739a), SkBits2Float(0x50001073)); // 1.92882e+31f, 8.59425e+09f
+path.quadTo(SkBits2Float(0x7b9c7b79), SkBits2Float(0xf4f2d886), SkBits2Float(0xf4f4f4f4), SkBits2Float(0xf4f4f4f4)); // 1.62501e+36f, -1.53922e+32f, -1.5526e+32f, -1.5526e+32f
+ testSimplifyFuzz(reporter, path, filename);
+}
#define TEST(test) test(reporter, #test)
DEF_TEST(PathOpsSimplifyFail, reporter) {
+ TEST(fuzz_k1);
TEST(fuzz_x3);
TEST(fuzz763_2);
TEST(fuzz763_1);
diff --git a/tests/PathOpsTSectDebug.h b/tests/PathOpsTSectDebug.h
index 209152104b..7b0f19d877 100644
--- a/tests/PathOpsTSectDebug.h
+++ b/tests/PathOpsTSectDebug.h
@@ -67,7 +67,7 @@ void SkTSect<TCurve, OppCurve>::dumpBoth(SkTSect<OppCurve, TCurve>* opp) const {
SkDebugf("%d ", ++gDumpTSectNum);
#endif
this->dump();
- SkDebugf(" ");
+ SkDebugf("\n");
opp->dump();
SkDebugf("\n");
#elif DEBUG_T_SECT_DUMP == 3