SkPathOpsDebug.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*
  2. * Copyright 2013 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkPathOpsDebug_DEFINED
  8. #define SkPathOpsDebug_DEFINED
  9. #include "include/core/SkString.h"
  10. #include "include/core/SkTypes.h"
  11. #include "include/pathops/SkPathOps.h"
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. enum class SkOpPhase : char;
  15. struct SkDQuad;
  16. class SkOpAngle;
  17. class SkOpCoincidence;
  18. class SkOpContour;
  19. class SkOpContourHead;
  20. class SkOpPtT;
  21. class SkOpSegment;
  22. class SkOpSpan;
  23. class SkOpSpanBase;
  24. struct SkDPoint;
  25. struct SkDLine;
  26. struct SkDQuad;
  27. struct SkDConic;
  28. struct SkDCubic;
  29. class SkTSect;
  30. // define this when running fuzz
  31. // #define IS_FUZZING_WITH_LIBFUZZER
  32. // dummy classes to fool msvs Visual Studio 2018 Immediate Window
  33. #define DummyClasses(a, b) \
  34. class SkDebugTCoincident##a##b; \
  35. class SkDebugTSect##a##b; \
  36. class SkDebugTSpan##a##b
  37. DummyClasses(Quad, Quad);
  38. DummyClasses(Conic, Quad);
  39. DummyClasses(Conic, Conic);
  40. DummyClasses(Cubic, Quad);
  41. DummyClasses(Cubic, Conic);
  42. DummyClasses(Cubic, Cubic);
  43. #undef DummyClasses
  44. #ifdef SK_RELEASE
  45. #define FORCE_RELEASE 1
  46. #else
  47. #define FORCE_RELEASE 1 // set force release to 1 for multiple thread -- no debugging
  48. #endif
  49. #define DEBUG_UNDER_DEVELOPMENT 0
  50. #define ONE_OFF_DEBUG 0
  51. #define ONE_OFF_DEBUG_MATHEMATICA 0
  52. #if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_ANDROID)
  53. #define SK_RAND(seed) rand()
  54. #else
  55. #define SK_RAND(seed) rand_r(&seed)
  56. #endif
  57. #ifdef SK_BUILD_FOR_WIN
  58. #define SK_SNPRINTF _snprintf
  59. #else
  60. #define SK_SNPRINTF snprintf
  61. #endif
  62. #define WIND_AS_STRING(x) char x##Str[12]; \
  63. if (!SkPathOpsDebug::ValidWind(x)) strcpy(x##Str, "?"); \
  64. else SK_SNPRINTF(x##Str, sizeof(x##Str), "%d", x)
  65. #if FORCE_RELEASE
  66. #define DEBUG_ACTIVE_OP 0
  67. #define DEBUG_ACTIVE_SPANS 0
  68. #define DEBUG_ADD_INTERSECTING_TS 0
  69. #define DEBUG_ADD_T 0
  70. #define DEBUG_ALIGNMENT 0
  71. #define DEBUG_ANGLE 0
  72. #define DEBUG_ASSEMBLE 0
  73. #define DEBUG_COINCIDENCE 0 // sanity checking
  74. #define DEBUG_COINCIDENCE_DUMP 0 // accumulate and dump which algorithms fired
  75. #define DEBUG_COINCIDENCE_ORDER 0 // for well behaved curves, check if pairs match up in t-order
  76. #define DEBUG_COINCIDENCE_VERBOSE 0 // usually whether the next function generates coincidence
  77. #define DEBUG_CUBIC_BINARY_SEARCH 0
  78. #define DEBUG_CUBIC_SPLIT 0
  79. #define DEBUG_DUMP_SEGMENTS 0
  80. #define DEBUG_DUMP_VERIFY 0
  81. #define DEBUG_FLOW 0
  82. #define DEBUG_LIMIT_WIND_SUM 0
  83. #define DEBUG_MARK_DONE 0
  84. #define DEBUG_PATH_CONSTRUCTION 0
  85. #define DEBUG_PERP 0
  86. #define DEBUG_SHOW_TEST_NAME 0
  87. #define DEBUG_SORT 0
  88. #define DEBUG_T_SECT 0
  89. #define DEBUG_T_SECT_DUMP 0
  90. #define DEBUG_T_SECT_LOOP_COUNT 0
  91. #define DEBUG_VALIDATE 0
  92. #define DEBUG_WINDING 0
  93. #define DEBUG_WINDING_AT_T 0
  94. #else
  95. #define DEBUG_ACTIVE_OP 1
  96. #define DEBUG_ACTIVE_SPANS 1
  97. #define DEBUG_ADD_INTERSECTING_TS 1
  98. #define DEBUG_ADD_T 1
  99. #define DEBUG_ALIGNMENT 0
  100. #define DEBUG_ANGLE 1
  101. #define DEBUG_ASSEMBLE 1
  102. #define DEBUG_COINCIDENCE 1
  103. #define DEBUG_COINCIDENCE_DUMP 0
  104. #define DEBUG_COINCIDENCE_ORDER 0 // tight arc quads may generate out-of-order coincidence spans
  105. #define DEBUG_COINCIDENCE_VERBOSE 1
  106. #define DEBUG_CUBIC_BINARY_SEARCH 0
  107. #define DEBUG_CUBIC_SPLIT 1
  108. #define DEBUG_DUMP_VERIFY 0
  109. #define DEBUG_DUMP_SEGMENTS 1
  110. #define DEBUG_FLOW 1
  111. #define DEBUG_LIMIT_WIND_SUM 15
  112. #define DEBUG_MARK_DONE 1
  113. #define DEBUG_PATH_CONSTRUCTION 1
  114. #define DEBUG_PERP 1
  115. #define DEBUG_SHOW_TEST_NAME 1
  116. #define DEBUG_SORT 1
  117. #define DEBUG_T_SECT 0 // enabling may trigger validate asserts even though op does not fail
  118. #define DEBUG_T_SECT_DUMP 0 // Use 1 normally. Use 2 to number segments, 3 for script output
  119. #define DEBUG_T_SECT_LOOP_COUNT 0
  120. #define DEBUG_VALIDATE 1
  121. #define DEBUG_WINDING 1
  122. #define DEBUG_WINDING_AT_T 1
  123. #endif
  124. #ifdef SK_RELEASE
  125. #define SkDEBUGRELEASE(a, b) b
  126. #define SkDEBUGPARAMS(...)
  127. #else
  128. #define SkDEBUGRELEASE(a, b) a
  129. #define SkDEBUGPARAMS(...) , __VA_ARGS__
  130. #endif
  131. #if DEBUG_VALIDATE == 0
  132. #define PATH_OPS_DEBUG_VALIDATE_PARAMS(...)
  133. #else
  134. #define PATH_OPS_DEBUG_VALIDATE_PARAMS(...) , __VA_ARGS__
  135. #endif
  136. #if DEBUG_T_SECT == 0
  137. #define PATH_OPS_DEBUG_T_SECT_RELEASE(a, b) b
  138. #define PATH_OPS_DEBUG_T_SECT_PARAMS(...)
  139. #define PATH_OPS_DEBUG_T_SECT_CODE(...)
  140. #else
  141. #define PATH_OPS_DEBUG_T_SECT_RELEASE(a, b) a
  142. #define PATH_OPS_DEBUG_T_SECT_PARAMS(...) , __VA_ARGS__
  143. #define PATH_OPS_DEBUG_T_SECT_CODE(...) __VA_ARGS__
  144. #endif
  145. #if DEBUG_T_SECT_DUMP > 1
  146. extern int gDumpTSectNum;
  147. #endif
  148. #if DEBUG_COINCIDENCE || DEBUG_COINCIDENCE_DUMP
  149. #define DEBUG_COIN 1
  150. #else
  151. #define DEBUG_COIN 0
  152. #endif
  153. #if DEBUG_COIN
  154. #define DEBUG_COIN_DECLARE_ONLY_PARAMS() \
  155. int lineNo, SkOpPhase phase, int iteration
  156. #define DEBUG_COIN_DECLARE_PARAMS() \
  157. , DEBUG_COIN_DECLARE_ONLY_PARAMS()
  158. #define DEBUG_COIN_ONLY_PARAMS() \
  159. __LINE__, SkOpPhase::kNoChange, 0
  160. #define DEBUG_COIN_PARAMS() \
  161. , DEBUG_COIN_ONLY_PARAMS()
  162. #define DEBUG_ITER_ONLY_PARAMS(iteration) \
  163. __LINE__, SkOpPhase::kNoChange, iteration
  164. #define DEBUG_ITER_PARAMS(iteration) \
  165. , DEBUG_ITER_ONLY_PARAMS(iteration)
  166. #define DEBUG_PHASE_ONLY_PARAMS(phase) \
  167. __LINE__, SkOpPhase::phase, 0
  168. #define DEBUG_PHASE_PARAMS(phase) \
  169. , DEBUG_PHASE_ONLY_PARAMS(phase)
  170. #define DEBUG_SET_PHASE() \
  171. this->globalState()->debugSetPhase(__func__, lineNo, phase, iteration)
  172. #define DEBUG_STATIC_SET_PHASE(obj) \
  173. obj->globalState()->debugSetPhase(__func__, lineNo, phase, iteration)
  174. #elif DEBUG_VALIDATE
  175. #define DEBUG_COIN_DECLARE_ONLY_PARAMS() \
  176. SkOpPhase phase
  177. #define DEBUG_COIN_DECLARE_PARAMS() \
  178. , DEBUG_COIN_DECLARE_ONLY_PARAMS()
  179. #define DEBUG_COIN_ONLY_PARAMS() \
  180. SkOpPhase::kNoChange
  181. #define DEBUG_COIN_PARAMS() \
  182. , DEBUG_COIN_ONLY_PARAMS()
  183. #define DEBUG_ITER_ONLY_PARAMS(iteration) \
  184. SkOpPhase::kNoChange
  185. #define DEBUG_ITER_PARAMS(iteration) \
  186. , DEBUG_ITER_ONLY_PARAMS(iteration)
  187. #define DEBUG_PHASE_ONLY_PARAMS(phase) \
  188. SkOpPhase::phase
  189. #define DEBUG_PHASE_PARAMS(phase) \
  190. , DEBUG_PHASE_ONLY_PARAMS(phase)
  191. #define DEBUG_SET_PHASE() \
  192. this->globalState()->debugSetPhase(phase)
  193. #define DEBUG_STATIC_SET_PHASE(obj) \
  194. obj->globalState()->debugSetPhase(phase)
  195. #else
  196. #define DEBUG_COIN_DECLARE_ONLY_PARAMS()
  197. #define DEBUG_COIN_DECLARE_PARAMS()
  198. #define DEBUG_COIN_ONLY_PARAMS()
  199. #define DEBUG_COIN_PARAMS()
  200. #define DEBUG_ITER_ONLY_PARAMS(iteration)
  201. #define DEBUG_ITER_PARAMS(iteration)
  202. #define DEBUG_PHASE_ONLY_PARAMS(phase)
  203. #define DEBUG_PHASE_PARAMS(phase)
  204. #define DEBUG_SET_PHASE()
  205. #define DEBUG_STATIC_SET_PHASE(obj)
  206. #endif
  207. #define CUBIC_DEBUG_STR "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
  208. #define CONIC_DEBUG_STR "{{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}, %1.9g}"
  209. #define QUAD_DEBUG_STR "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
  210. #define LINE_DEBUG_STR "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
  211. #define PT_DEBUG_STR "{{%1.9g,%1.9g}}"
  212. #define T_DEBUG_STR(t, n) #t "[" #n "]=%1.9g"
  213. #define TX_DEBUG_STR(t) #t "[%d]=%1.9g"
  214. #define CUBIC_DEBUG_DATA(c) c[0].fX, c[0].fY, c[1].fX, c[1].fY, c[2].fX, c[2].fY, c[3].fX, c[3].fY
  215. #define CONIC_DEBUG_DATA(c, w) c[0].fX, c[0].fY, c[1].fX, c[1].fY, c[2].fX, c[2].fY, w
  216. #define QUAD_DEBUG_DATA(q) q[0].fX, q[0].fY, q[1].fX, q[1].fY, q[2].fX, q[2].fY
  217. #define LINE_DEBUG_DATA(l) l[0].fX, l[0].fY, l[1].fX, l[1].fY
  218. #define PT_DEBUG_DATA(i, n) i.pt(n).asSkPoint().fX, i.pt(n).asSkPoint().fY
  219. #ifndef DEBUG_TEST
  220. #define DEBUG_TEST 0
  221. #endif
  222. #if DEBUG_SHOW_TEST_NAME
  223. #include "src/core/SkTLS.h"
  224. #endif
  225. // Tests with extreme numbers may fail, but all other tests should never fail.
  226. #define FAIL_IF(cond) \
  227. do { bool fail = (cond); SkOPASSERT(!fail); if (fail) return false; } while (false)
  228. #define FAIL_WITH_NULL_IF(cond) \
  229. do { bool fail = (cond); SkOPASSERT(!fail); if (fail) return nullptr; } while (false)
  230. // Some functions serve two masters: one allows the function to fail, the other expects success
  231. // always. If abort is true, tests with normal numbers may not fail and assert if they do so.
  232. // If abort is false, both normal and extreme numbers may return false without asserting.
  233. #define RETURN_FALSE_IF(abort, cond) \
  234. do { bool fail = (cond); SkOPASSERT(!(abort) || !fail); if (fail) return false; \
  235. } while (false)
  236. class SkPathOpsDebug {
  237. public:
  238. #if DEBUG_COIN
  239. struct GlitchLog;
  240. enum GlitchType {
  241. kUninitialized_Glitch,
  242. kAddCorruptCoin_Glitch,
  243. kAddExpandedCoin_Glitch,
  244. kAddExpandedFail_Glitch,
  245. kAddIfCollapsed_Glitch,
  246. kAddIfMissingCoin_Glitch,
  247. kAddMissingCoin_Glitch,
  248. kAddMissingExtend_Glitch,
  249. kAddOrOverlap_Glitch,
  250. kCollapsedCoin_Glitch,
  251. kCollapsedDone_Glitch,
  252. kCollapsedOppValue_Glitch,
  253. kCollapsedSpan_Glitch,
  254. kCollapsedWindValue_Glitch,
  255. kCorrectEnd_Glitch,
  256. kDeletedCoin_Glitch,
  257. kExpandCoin_Glitch,
  258. kFail_Glitch,
  259. kMarkCoinEnd_Glitch,
  260. kMarkCoinInsert_Glitch,
  261. kMarkCoinMissing_Glitch,
  262. kMarkCoinStart_Glitch,
  263. kMergeMatches_Glitch,
  264. kMissingCoin_Glitch,
  265. kMissingDone_Glitch,
  266. kMissingIntersection_Glitch,
  267. kMoveMultiple_Glitch,
  268. kMoveNearbyClearAll_Glitch,
  269. kMoveNearbyClearAll2_Glitch,
  270. kMoveNearbyMerge_Glitch,
  271. kMoveNearbyMergeFinal_Glitch,
  272. kMoveNearbyRelease_Glitch,
  273. kMoveNearbyReleaseFinal_Glitch,
  274. kReleasedSpan_Glitch,
  275. kReturnFalse_Glitch,
  276. kUnaligned_Glitch,
  277. kUnalignedHead_Glitch,
  278. kUnalignedTail_Glitch,
  279. };
  280. struct CoinDictEntry {
  281. int fIteration;
  282. int fLineNumber;
  283. GlitchType fGlitchType;
  284. const char* fFunctionName;
  285. };
  286. struct CoinDict {
  287. void add(const CoinDictEntry& key);
  288. void add(const CoinDict& dict);
  289. void dump(const char* str, bool visitCheck) const;
  290. SkTDArray<CoinDictEntry> fDict;
  291. };
  292. static CoinDict gCoinSumChangedDict;
  293. static CoinDict gCoinSumVisitedDict;
  294. static CoinDict gCoinVistedDict;
  295. #endif
  296. #if defined(SK_DEBUG) || !FORCE_RELEASE
  297. static int gContourID;
  298. static int gSegmentID;
  299. #endif
  300. #if DEBUG_SORT
  301. static int gSortCountDefault;
  302. static int gSortCount;
  303. #endif
  304. #if DEBUG_ACTIVE_OP
  305. static const char* kPathOpStr[];
  306. #endif
  307. static bool gRunFail;
  308. static bool gVeryVerbose;
  309. #if DEBUG_ACTIVE_SPANS
  310. static SkString gActiveSpans;
  311. #endif
  312. #if DEBUG_DUMP_VERIFY
  313. static bool gDumpOp;
  314. static bool gVerifyOp;
  315. #endif
  316. static const char* OpStr(SkPathOp );
  317. static void MathematicaIze(char* str, size_t bufferSize);
  318. static bool ValidWind(int winding);
  319. static void WindingPrintf(int winding);
  320. #if DEBUG_SHOW_TEST_NAME
  321. static void* CreateNameStr();
  322. static void DeleteNameStr(void* v);
  323. #define DEBUG_FILENAME_STRING_LENGTH 64
  324. #define DEBUG_FILENAME_STRING (reinterpret_cast<char* >(SkTLS::Get(SkPathOpsDebug::CreateNameStr, \
  325. SkPathOpsDebug::DeleteNameStr)))
  326. static void BumpTestName(char* );
  327. #endif
  328. static void ShowActiveSpans(SkOpContourHead* contourList);
  329. static void ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration);
  330. static void ShowPath(const SkPath& one, const SkPath& two, SkPathOp op, const char* name);
  331. static bool ChaseContains(const SkTDArray<SkOpSpanBase*>& , const SkOpSpanBase* );
  332. static void CheckHealth(class SkOpContourHead* contourList);
  333. #if DEBUG_COIN
  334. static void DumpCoinDict();
  335. static void DumpGlitchType(GlitchType );
  336. #endif
  337. };
  338. // Visual Studio 2017 does not permit calling member functions from the Immediate Window.
  339. // Global functions work fine, however. Use globals rather than static members inside a class.
  340. const SkOpAngle* AngleAngle(const SkOpAngle*, int id);
  341. SkOpContour* AngleContour(SkOpAngle*, int id);
  342. const SkOpPtT* AnglePtT(const SkOpAngle*, int id);
  343. const SkOpSegment* AngleSegment(const SkOpAngle*, int id);
  344. const SkOpSpanBase* AngleSpan(const SkOpAngle*, int id);
  345. const SkOpAngle* ContourAngle(SkOpContour*, int id);
  346. SkOpContour* ContourContour(SkOpContour*, int id);
  347. const SkOpPtT* ContourPtT(SkOpContour*, int id);
  348. const SkOpSegment* ContourSegment(SkOpContour*, int id);
  349. const SkOpSpanBase* ContourSpan(SkOpContour*, int id);
  350. const SkOpAngle* CoincidenceAngle(SkOpCoincidence*, int id);
  351. SkOpContour* CoincidenceContour(SkOpCoincidence*, int id);
  352. const SkOpPtT* CoincidencePtT(SkOpCoincidence*, int id);
  353. const SkOpSegment* CoincidenceSegment(SkOpCoincidence*, int id);
  354. const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence*, int id);
  355. const SkOpAngle* PtTAngle(const SkOpPtT*, int id);
  356. SkOpContour* PtTContour(SkOpPtT*, int id);
  357. const SkOpPtT* PtTPtT(const SkOpPtT*, int id);
  358. const SkOpSegment* PtTSegment(const SkOpPtT*, int id);
  359. const SkOpSpanBase* PtTSpan(const SkOpPtT*, int id);
  360. const SkOpAngle* SegmentAngle(const SkOpSegment*, int id);
  361. SkOpContour* SegmentContour(SkOpSegment*, int id);
  362. const SkOpPtT* SegmentPtT(const SkOpSegment*, int id);
  363. const SkOpSegment* SegmentSegment(const SkOpSegment*, int id);
  364. const SkOpSpanBase* SegmentSpan(const SkOpSegment*, int id);
  365. const SkOpAngle* SpanAngle(const SkOpSpanBase*, int id);
  366. SkOpContour* SpanContour(SkOpSpanBase*, int id);
  367. const SkOpPtT* SpanPtT(const SkOpSpanBase*, int id);
  368. const SkOpSegment* SpanSegment(const SkOpSpanBase*, int id);
  369. const SkOpSpanBase* SpanSpan(const SkOpSpanBase*, int id);
  370. #if DEBUG_DUMP_VERIFY
  371. void DumpOp(const SkPath& one, const SkPath& two, SkPathOp op,
  372. const char* testName);
  373. void DumpOp(FILE* file, const SkPath& one, const SkPath& two, SkPathOp op,
  374. const char* testName);
  375. void DumpSimplify(const SkPath& path, const char* testName);
  376. void DumpSimplify(FILE* file, const SkPath& path, const char* testName);
  377. void ReportOpFail(const SkPath& one, const SkPath& two, SkPathOp op);
  378. void ReportSimplifyFail(const SkPath& path);
  379. void VerifyOp(const SkPath& one, const SkPath& two, SkPathOp op,
  380. const SkPath& result);
  381. void VerifySimplify(const SkPath& path, const SkPath& result);
  382. #endif
  383. // global path dumps for msvs Visual Studio 17 to use from Immediate Window
  384. void Dump(const SkOpContour& );
  385. void DumpAll(const SkOpContour& );
  386. void DumpAngles(const SkOpContour& );
  387. void DumpContours(const SkOpContour& );
  388. void DumpContoursAll(const SkOpContour& );
  389. void DumpContoursAngles(const SkOpContour& );
  390. void DumpContoursPts(const SkOpContour& );
  391. void DumpContoursPt(const SkOpContour& , int segmentID);
  392. void DumpContoursSegment(const SkOpContour& , int segmentID);
  393. void DumpContoursSpan(const SkOpContour& , int segmentID);
  394. void DumpContoursSpans(const SkOpContour& );
  395. void DumpPt(const SkOpContour& , int );
  396. void DumpPts(const SkOpContour& , const char* prefix = "seg");
  397. void DumpSegment(const SkOpContour& , int );
  398. void DumpSegments(const SkOpContour& , const char* prefix = "seg", SkPathOp op = (SkPathOp) -1);
  399. void DumpSpan(const SkOpContour& , int );
  400. void DumpSpans(const SkOpContour& );
  401. void Dump(const SkOpSegment& );
  402. void DumpAll(const SkOpSegment& );
  403. void DumpAngles(const SkOpSegment& );
  404. void DumpCoin(const SkOpSegment& );
  405. void DumpPts(const SkOpSegment& , const char* prefix = "seg");
  406. void Dump(const SkOpPtT& );
  407. void DumpAll(const SkOpPtT& );
  408. void Dump(const SkOpSpanBase& );
  409. void DumpCoin(const SkOpSpanBase& );
  410. void DumpAll(const SkOpSpanBase& );
  411. void DumpCoin(const SkOpSpan& );
  412. bool DumpSpan(const SkOpSpan& );
  413. void Dump(const SkDConic& );
  414. void DumpID(const SkDConic& , int id);
  415. void Dump(const SkDCubic& );
  416. void DumpID(const SkDCubic& , int id);
  417. void Dump(const SkDLine& );
  418. void DumpID(const SkDLine& , int id);
  419. void Dump(const SkDQuad& );
  420. void DumpID(const SkDQuad& , int id);
  421. void Dump(const SkDPoint& );
  422. void Dump(const SkOpAngle& );
  423. // generates tools/path_sorter.htm and path_visualizer.htm compatible data
  424. void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo);
  425. void DumpT(const SkDQuad& quad, double t);
  426. // global path dumps for msvs Visual Studio 17 to use from Immediate Window
  427. void Dump(const SkPath& path);
  428. void DumpHex(const SkPath& path);
  429. #endif