blob: 035ab14a053c532fabd821b75783a831b13a47a0 [file] [log] [blame]
caryclark@google.com07393ca2013-04-08 11:47:37 +00001/*
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
caryclark@google.coma5e55922013-05-07 18:51:31 +000010#include "SkPathOps.h"
Cary Clark1d314432018-07-10 10:57:54 -040011#include "SkString.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +000012#include "SkTypes.h"
bungeman60e0fee2015-08-26 05:15:46 -070013
14#include <stdlib.h>
bungeman@google.comfab44db2013-10-11 18:50:45 +000015#include <stdio.h>
caryclark@google.com07393ca2013-04-08 11:47:37 +000016
Cary Clarkab87d7a2016-10-04 10:01:04 -040017enum class SkOpPhase : char;
Cary Clarkb8421ed2018-03-14 15:55:02 -040018struct SkDQuad;
19class SkOpAngle;
20class SkOpCoincidence;
21class SkOpContour;
Cary Clarkab87d7a2016-10-04 10:01:04 -040022class SkOpContourHead;
Cary Clarkb8421ed2018-03-14 15:55:02 -040023class SkOpPtT;
24class SkOpSegment;
25class SkOpSpan;
26class SkOpSpanBase;
27struct SkDPoint;
28struct SkDLine;
29struct SkDQuad;
30struct SkDConic;
31struct SkDCubic;
32template<typename TCurve, typename OppCurve> class SkTSect;
33
34// dummy classes to fool msvs Visual Studio 2018 Immediate Window
35#define DummyClasses(a, b) \
36class SkDebugTCoincident##a##b; \
37class SkDebugTSect##a##b; \
38class SkDebugTSpan##a##b
39
40DummyClasses(Quad, Quad);
41DummyClasses(Conic, Quad);
42DummyClasses(Conic, Conic);
43DummyClasses(Cubic, Quad);
44DummyClasses(Cubic, Conic);
45DummyClasses(Cubic, Cubic);
46
47#undef DummyClasses
Cary Clarkab87d7a2016-10-04 10:01:04 -040048
caryclark@google.com07393ca2013-04-08 11:47:37 +000049#ifdef SK_RELEASE
50#define FORCE_RELEASE 1
51#else
caryclark@google.comb3f09212013-04-17 15:49:16 +000052#define FORCE_RELEASE 1 // set force release to 1 for multiple thread -- no debugging
caryclark@google.com07393ca2013-04-08 11:47:37 +000053#endif
54
caryclarkb36a3cd2016-10-18 07:59:44 -070055#define DEBUG_UNDER_DEVELOPMENT 0
caryclark27c015d2016-09-23 05:47:20 -070056
caryclark@google.com07393ca2013-04-08 11:47:37 +000057#define ONE_OFF_DEBUG 0
58#define ONE_OFF_DEBUG_MATHEMATICA 0
59
caryclark@google.comdb60de72013-04-11 12:33:23 +000060#if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_ANDROID)
caryclark@google.com07393ca2013-04-08 11:47:37 +000061 #define SK_RAND(seed) rand()
caryclark@google.com07393ca2013-04-08 11:47:37 +000062#else
63 #define SK_RAND(seed) rand_r(&seed)
caryclark@google.comdb60de72013-04-11 12:33:23 +000064#endif
65#ifdef SK_BUILD_FOR_WIN
66 #define SK_SNPRINTF _snprintf
67#else
skia.committer@gmail.com32840172013-04-09 07:01:27 +000068 #define SK_SNPRINTF snprintf
caryclark@google.com07393ca2013-04-08 11:47:37 +000069#endif
70
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000071#define WIND_AS_STRING(x) char x##Str[12]; \
72 if (!SkPathOpsDebug::ValidWind(x)) strcpy(x##Str, "?"); \
73 else SK_SNPRINTF(x##Str, sizeof(x##Str), "%d", x)
74
caryclark@google.com07393ca2013-04-08 11:47:37 +000075#if FORCE_RELEASE
76
77#define DEBUG_ACTIVE_OP 0
78#define DEBUG_ACTIVE_SPANS 0
caryclark@google.com07393ca2013-04-08 11:47:37 +000079#define DEBUG_ADD_INTERSECTING_TS 0
caryclark54359292015-03-26 07:52:43 -070080#define DEBUG_ADD_T 0
caryclark26ad22a2015-10-16 09:03:38 -070081#define DEBUG_ALIGNMENT 0
caryclark@google.com07393ca2013-04-08 11:47:37 +000082#define DEBUG_ANGLE 0
caryclark@google.com07393ca2013-04-08 11:47:37 +000083#define DEBUG_ASSEMBLE 0
Cary Clarkab87d7a2016-10-04 10:01:04 -040084#define DEBUG_COINCIDENCE 0 // sanity checking
85#define DEBUG_COINCIDENCE_DUMP 0 // accumulate and dump which algorithms fired
86#define DEBUG_COINCIDENCE_ORDER 0 // for well behaved curves, check if pairs match up in t-order
87#define DEBUG_COINCIDENCE_VERBOSE 0 // usually whether the next function generates coincidence
commit-bot@chromium.org2db7fe72014-05-07 15:31:40 +000088#define DEBUG_CUBIC_BINARY_SEARCH 0
caryclark03b03ca2015-04-23 09:13:37 -070089#define DEBUG_CUBIC_SPLIT 0
caryclark624637c2015-05-11 07:21:27 -070090#define DEBUG_DUMP_SEGMENTS 0
Cary Clark918fb1f2016-11-15 13:22:25 -050091#define DEBUG_DUMP_VERIFY 0
caryclark@google.com07393ca2013-04-08 11:47:37 +000092#define DEBUG_FLOW 0
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +000093#define DEBUG_LIMIT_WIND_SUM 0
caryclark@google.com07393ca2013-04-08 11:47:37 +000094#define DEBUG_MARK_DONE 0
95#define DEBUG_PATH_CONSTRUCTION 0
caryclark54359292015-03-26 07:52:43 -070096#define DEBUG_PERP 0
caryclark624637c2015-05-11 07:21:27 -070097#define DEBUG_SHOW_TEST_NAME 0
caryclark@google.com07393ca2013-04-08 11:47:37 +000098#define DEBUG_SORT 0
caryclark54359292015-03-26 07:52:43 -070099#define DEBUG_T_SECT 0
100#define DEBUG_T_SECT_DUMP 0
caryclark26ad22a2015-10-16 09:03:38 -0700101#define DEBUG_T_SECT_LOOP_COUNT 0
caryclark@google.com4fdbb222013-07-23 15:27:41 +0000102#define DEBUG_VALIDATE 0
caryclark@google.com07393ca2013-04-08 11:47:37 +0000103#define DEBUG_WINDING 0
104#define DEBUG_WINDING_AT_T 0
105
106#else
107
108#define DEBUG_ACTIVE_OP 1
109#define DEBUG_ACTIVE_SPANS 1
caryclark@google.com07393ca2013-04-08 11:47:37 +0000110#define DEBUG_ADD_INTERSECTING_TS 1
caryclark54359292015-03-26 07:52:43 -0700111#define DEBUG_ADD_T 1
caryclark26ad22a2015-10-16 09:03:38 -0700112#define DEBUG_ALIGNMENT 0
caryclark@google.com07393ca2013-04-08 11:47:37 +0000113#define DEBUG_ANGLE 1
caryclark@google.com07393ca2013-04-08 11:47:37 +0000114#define DEBUG_ASSEMBLE 1
Cary Clarkff114282016-12-14 11:56:16 -0500115#define DEBUG_COINCIDENCE 1
Cary Clarkab87d7a2016-10-04 10:01:04 -0400116#define DEBUG_COINCIDENCE_DUMP 0
caryclark81a478c2016-09-09 09:37:57 -0700117#define DEBUG_COINCIDENCE_ORDER 0 // tight arc quads may generate out-of-order coincdence spans
Cary Clarkff114282016-12-14 11:56:16 -0500118#define DEBUG_COINCIDENCE_VERBOSE 1
caryclark65b427c2014-09-18 10:32:57 -0700119#define DEBUG_CUBIC_BINARY_SEARCH 0
caryclark03b03ca2015-04-23 09:13:37 -0700120#define DEBUG_CUBIC_SPLIT 1
Cary Clark918fb1f2016-11-15 13:22:25 -0500121#define DEBUG_DUMP_VERIFY 0
caryclark03b03ca2015-04-23 09:13:37 -0700122#define DEBUG_DUMP_SEGMENTS 1
caryclark@google.com07393ca2013-04-08 11:47:37 +0000123#define DEBUG_FLOW 1
caryclark55888e42016-07-18 10:01:36 -0700124#define DEBUG_LIMIT_WIND_SUM 15
caryclark@google.com07393ca2013-04-08 11:47:37 +0000125#define DEBUG_MARK_DONE 1
126#define DEBUG_PATH_CONSTRUCTION 1
caryclark03b03ca2015-04-23 09:13:37 -0700127#define DEBUG_PERP 1
caryclark@google.com03610322013-04-18 15:58:21 +0000128#define DEBUG_SHOW_TEST_NAME 1
caryclark@google.com07393ca2013-04-08 11:47:37 +0000129#define DEBUG_SORT 1
Cary Clarkb8421ed2018-03-14 15:55:02 -0400130#define DEBUG_T_SECT 0 // enabling may trigger validate asserts even though op does not fail
caryclarke839e782016-09-15 07:48:18 -0700131#define DEBUG_T_SECT_DUMP 0 // Use 1 normally. Use 2 to number segments, 3 for script output
caryclarked0935a2015-10-22 07:23:52 -0700132#define DEBUG_T_SECT_LOOP_COUNT 0
caryclark54359292015-03-26 07:52:43 -0700133#define DEBUG_VALIDATE 1
caryclark@google.com07393ca2013-04-08 11:47:37 +0000134#define DEBUG_WINDING 1
135#define DEBUG_WINDING_AT_T 1
136
137#endif
138
caryclark54359292015-03-26 07:52:43 -0700139#ifdef SK_RELEASE
caryclark1049f122015-04-20 08:31:59 -0700140 #define SkDEBUGRELEASE(a, b) b
141 #define SkDEBUGPARAMS(...)
reed0dc4dd62015-03-24 13:55:33 -0700142#else
caryclark1049f122015-04-20 08:31:59 -0700143 #define SkDEBUGRELEASE(a, b) a
144 #define SkDEBUGPARAMS(...) , __VA_ARGS__
reed0dc4dd62015-03-24 13:55:33 -0700145#endif
caryclark54359292015-03-26 07:52:43 -0700146
caryclark27c8eb82015-07-06 11:38:33 -0700147#if DEBUG_VALIDATE == 0
148 #define PATH_OPS_DEBUG_VALIDATE_PARAMS(...)
149#else
150 #define PATH_OPS_DEBUG_VALIDATE_PARAMS(...) , __VA_ARGS__
151#endif
152
caryclark54359292015-03-26 07:52:43 -0700153#if DEBUG_T_SECT == 0
154 #define PATH_OPS_DEBUG_T_SECT_RELEASE(a, b) b
155 #define PATH_OPS_DEBUG_T_SECT_PARAMS(...)
156 #define PATH_OPS_DEBUG_T_SECT_CODE(...)
157#else
158 #define PATH_OPS_DEBUG_T_SECT_RELEASE(a, b) a
159 #define PATH_OPS_DEBUG_T_SECT_PARAMS(...) , __VA_ARGS__
160 #define PATH_OPS_DEBUG_T_SECT_CODE(...) __VA_ARGS__
161#endif
162
163#if DEBUG_T_SECT_DUMP > 1
164 extern int gDumpTSectNum;
165#endif
166
Ben Wagner63fd7602017-10-09 15:45:33 -0400167#if DEBUG_COINCIDENCE || DEBUG_COINCIDENCE_DUMP
Cary Clarkab87d7a2016-10-04 10:01:04 -0400168 #define DEBUG_COIN 1
caryclark26ad22a2015-10-16 09:03:38 -0700169#else
Cary Clarkab87d7a2016-10-04 10:01:04 -0400170 #define DEBUG_COIN 0
171#endif
172
173#if DEBUG_COIN
174 #define DEBUG_COIN_DECLARE_ONLY_PARAMS() \
175 int lineNo, SkOpPhase phase, int iteration
176 #define DEBUG_COIN_DECLARE_PARAMS() \
177 , DEBUG_COIN_DECLARE_ONLY_PARAMS()
178 #define DEBUG_COIN_ONLY_PARAMS() \
179 __LINE__, SkOpPhase::kNoChange, 0
180 #define DEBUG_COIN_PARAMS() \
181 , DEBUG_COIN_ONLY_PARAMS()
182 #define DEBUG_ITER_ONLY_PARAMS(iteration) \
183 __LINE__, SkOpPhase::kNoChange, iteration
184 #define DEBUG_ITER_PARAMS(iteration) \
185 , DEBUG_ITER_ONLY_PARAMS(iteration)
186 #define DEBUG_PHASE_ONLY_PARAMS(phase) \
187 __LINE__, SkOpPhase::phase, 0
188 #define DEBUG_PHASE_PARAMS(phase) \
189 , DEBUG_PHASE_ONLY_PARAMS(phase)
190 #define DEBUG_SET_PHASE() \
191 this->globalState()->debugSetPhase(__func__, lineNo, phase, iteration)
192 #define DEBUG_STATIC_SET_PHASE(obj) \
193 obj->globalState()->debugSetPhase(__func__, lineNo, phase, iteration)
194#elif DEBUG_VALIDATE
195 #define DEBUG_COIN_DECLARE_ONLY_PARAMS() \
196 SkOpPhase phase
197 #define DEBUG_COIN_DECLARE_PARAMS() \
198 , DEBUG_COIN_DECLARE_ONLY_PARAMS()
199 #define DEBUG_COIN_ONLY_PARAMS() \
200 SkOpPhase::kNoChange
201 #define DEBUG_COIN_PARAMS() \
202 , DEBUG_COIN_ONLY_PARAMS()
203 #define DEBUG_ITER_ONLY_PARAMS(iteration) \
204 SkOpPhase::kNoChange
205 #define DEBUG_ITER_PARAMS(iteration) \
206 , DEBUG_ITER_ONLY_PARAMS(iteration)
207 #define DEBUG_PHASE_ONLY_PARAMS(phase) \
208 SkOpPhase::phase
209 #define DEBUG_PHASE_PARAMS(phase) \
210 , DEBUG_PHASE_ONLY_PARAMS(phase)
211 #define DEBUG_SET_PHASE() \
212 this->globalState()->debugSetPhase(phase)
213 #define DEBUG_STATIC_SET_PHASE(obj) \
214 obj->globalState()->debugSetPhase(phase)
215#else
216 #define DEBUG_COIN_DECLARE_ONLY_PARAMS()
217 #define DEBUG_COIN_DECLARE_PARAMS()
218 #define DEBUG_COIN_ONLY_PARAMS()
219 #define DEBUG_COIN_PARAMS()
220 #define DEBUG_ITER_ONLY_PARAMS(iteration)
221 #define DEBUG_ITER_PARAMS(iteration)
222 #define DEBUG_PHASE_ONLY_PARAMS(phase)
223 #define DEBUG_PHASE_PARAMS(phase)
224 #define DEBUG_SET_PHASE()
225 #define DEBUG_STATIC_SET_PHASE(obj)
caryclark26ad22a2015-10-16 09:03:38 -0700226#endif
227
caryclark1049f122015-04-20 08:31:59 -0700228#define CUBIC_DEBUG_STR "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
229#define CONIC_DEBUG_STR "{{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}, %1.9g}"
230#define QUAD_DEBUG_STR "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
231#define LINE_DEBUG_STR "{{{%1.9g,%1.9g}, {%1.9g,%1.9g}}}"
caryclark54359292015-03-26 07:52:43 -0700232#define PT_DEBUG_STR "{{%1.9g,%1.9g}}"
233
caryclark@google.com07393ca2013-04-08 11:47:37 +0000234#define T_DEBUG_STR(t, n) #t "[" #n "]=%1.9g"
235#define TX_DEBUG_STR(t) #t "[%d]=%1.9g"
236#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
caryclark1049f122015-04-20 08:31:59 -0700237#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
caryclark@google.com07393ca2013-04-08 11:47:37 +0000238#define QUAD_DEBUG_DATA(q) q[0].fX, q[0].fY, q[1].fX, q[1].fY, q[2].fX, q[2].fY
239#define LINE_DEBUG_DATA(l) l[0].fX, l[0].fY, l[1].fX, l[1].fY
caryclarkdac1d172014-06-17 05:15:38 -0700240#define PT_DEBUG_DATA(i, n) i.pt(n).asSkPoint().fX, i.pt(n).asSkPoint().fY
caryclark@google.com07393ca2013-04-08 11:47:37 +0000241
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000242#ifndef DEBUG_TEST
243#define DEBUG_TEST 0
caryclark@google.coma5e55922013-05-07 18:51:31 +0000244#endif
245
caryclark@google.com570863f2013-09-16 15:55:01 +0000246#if DEBUG_SHOW_TEST_NAME
247#include "SkTLS.h"
248#endif
249
caryclark29b25632016-08-25 11:27:17 -0700250// Tests with extreme numbers may fail, but all other tests should never fail.
251#define FAIL_IF(cond) \
252 do { bool fail = (cond); SkOPASSERT(!fail); if (fail) return false; } while (false)
caryclark025b11e2016-08-25 05:21:14 -0700253
caryclark29b25632016-08-25 11:27:17 -0700254#define FAIL_WITH_NULL_IF(cond) \
255 do { bool fail = (cond); SkOPASSERT(!fail); if (fail) return nullptr; } while (false)
256
257// Some functions serve two masters: one allows the function to fail, the other expects success
258// always. If abort is true, tests with normal numbers may not fail and assert if they do so.
259// If abort is false, both normal and extreme numbers may return false without asserting.
caryclark025b11e2016-08-25 05:21:14 -0700260#define RETURN_FALSE_IF(abort, cond) \
caryclark29b25632016-08-25 11:27:17 -0700261 do { bool fail = (cond); SkOPASSERT(!(abort) || !fail); if (fail) return false; \
262 } while (false)
caryclark025b11e2016-08-25 05:21:14 -0700263
caryclark@google.com570863f2013-09-16 15:55:01 +0000264class SkPathOpsDebug {
265public:
Cary Clarkab87d7a2016-10-04 10:01:04 -0400266#if DEBUG_COIN
caryclark26ad22a2015-10-16 09:03:38 -0700267 struct GlitchLog;
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000268
Cary Clarkab87d7a2016-10-04 10:01:04 -0400269 enum GlitchType {
270 kUninitialized_Glitch,
271 kAddCorruptCoin_Glitch,
272 kAddExpandedCoin_Glitch,
273 kAddExpandedFail_Glitch,
274 kAddIfCollapsed_Glitch,
275 kAddIfMissingCoin_Glitch,
276 kAddMissingCoin_Glitch,
277 kAddMissingExtend_Glitch,
278 kAddOrOverlap_Glitch,
279 kCollapsedCoin_Glitch,
280 kCollapsedDone_Glitch,
281 kCollapsedOppValue_Glitch,
282 kCollapsedSpan_Glitch,
283 kCollapsedWindValue_Glitch,
284 kCorrectEnd_Glitch,
285 kDeletedCoin_Glitch,
286 kExpandCoin_Glitch,
287 kFail_Glitch,
288 kMarkCoinEnd_Glitch,
289 kMarkCoinInsert_Glitch,
290 kMarkCoinMissing_Glitch,
291 kMarkCoinStart_Glitch,
Cary Clarkab87d7a2016-10-04 10:01:04 -0400292 kMergeMatches_Glitch,
293 kMissingCoin_Glitch,
294 kMissingDone_Glitch,
295 kMissingIntersection_Glitch,
296 kMoveMultiple_Glitch,
297 kMoveNearbyClearAll_Glitch,
298 kMoveNearbyClearAll2_Glitch,
299 kMoveNearbyMerge_Glitch,
300 kMoveNearbyMergeFinal_Glitch,
301 kMoveNearbyRelease_Glitch,
302 kMoveNearbyReleaseFinal_Glitch,
303 kReleasedSpan_Glitch,
304 kReturnFalse_Glitch,
305 kUnaligned_Glitch,
306 kUnalignedHead_Glitch,
307 kUnalignedTail_Glitch,
308 };
309
310 struct CoinDictEntry {
311 int fIteration;
312 int fLineNumber;
313 GlitchType fGlitchType;
314 const char* fFunctionName;
315 };
316
317 struct CoinDict {
318 void add(const CoinDictEntry& key);
319 void add(const CoinDict& dict);
320 void dump(const char* str, bool visitCheck) const;
321 SkTDArray<CoinDictEntry> fDict;
322 };
323
324 static CoinDict gCoinSumChangedDict;
325 static CoinDict gCoinSumVisitedDict;
326 static CoinDict gCoinVistedDict;
327#endif
328
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000329#if defined(SK_DEBUG) || !FORCE_RELEASE
caryclark@google.com570863f2013-09-16 15:55:01 +0000330 static int gContourID;
331 static int gSegmentID;
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000332#endif
caryclark@google.com570863f2013-09-16 15:55:01 +0000333
caryclark624637c2015-05-11 07:21:27 -0700334#if DEBUG_SORT
caryclark@google.com570863f2013-09-16 15:55:01 +0000335 static int gSortCountDefault;
336 static int gSortCount;
337#endif
338
339#if DEBUG_ACTIVE_OP
340 static const char* kPathOpStr[];
341#endif
Cary Clarkb8421ed2018-03-14 15:55:02 -0400342 static bool gRunFail;
343 static bool gVeryVerbose;
caryclark@google.com570863f2013-09-16 15:55:01 +0000344
Cary Clarkb8421ed2018-03-14 15:55:02 -0400345#if DEBUG_ACTIVE_SPANS
346 static SkString gActiveSpans;
347#endif
348#if DEBUG_DUMP_VERIFY
349 static bool gDumpOp;
350 static bool gVerifyOp;
351#endif
352
353 static const char* OpStr(SkPathOp );
caryclark@google.com570863f2013-09-16 15:55:01 +0000354 static void MathematicaIze(char* str, size_t bufferSize);
355 static bool ValidWind(int winding);
356 static void WindingPrintf(int winding);
357
358#if DEBUG_SHOW_TEST_NAME
359 static void* CreateNameStr();
360 static void DeleteNameStr(void* v);
361#define DEBUG_FILENAME_STRING_LENGTH 64
362#define DEBUG_FILENAME_STRING (reinterpret_cast<char* >(SkTLS::Get(SkPathOpsDebug::CreateNameStr, \
363 SkPathOpsDebug::DeleteNameStr)))
364 static void BumpTestName(char* );
caryclark@google.com570863f2013-09-16 15:55:01 +0000365#endif
caryclark55888e42016-07-18 10:01:36 -0700366 static void ShowActiveSpans(SkOpContourHead* contourList);
caryclark19eb3b22014-07-18 05:08:14 -0700367 static void ShowOnePath(const SkPath& path, const char* name, bool includeDeclaration);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000368 static void ShowPath(const SkPath& one, const SkPath& two, SkPathOp op, const char* name);
caryclark54359292015-03-26 07:52:43 -0700369
Cary Clarkb8421ed2018-03-14 15:55:02 -0400370 static bool ChaseContains(const SkTDArray<SkOpSpanBase*>& , const SkOpSpanBase* );
caryclark54359292015-03-26 07:52:43 -0700371
Cary Clarkab87d7a2016-10-04 10:01:04 -0400372 static void CheckHealth(class SkOpContourHead* contourList);
caryclark26ad22a2015-10-16 09:03:38 -0700373
Cary Clarkab87d7a2016-10-04 10:01:04 -0400374#if DEBUG_COIN
Cary Clarkb8421ed2018-03-14 15:55:02 -0400375 static void DumpCoinDict();
376 static void DumpGlitchType(GlitchType );
Cary Clarkff114282016-12-14 11:56:16 -0500377#endif
378
caryclark@google.com570863f2013-09-16 15:55:01 +0000379};
380
Cary Clarkb8421ed2018-03-14 15:55:02 -0400381// Visual Studio 2017 does not permit calling member functions from the Immediate Window.
382// Global functions work fine, however. Use globals within a namespace rather than
383// static members inside a class.
384namespace SkOpDebug {
385 const SkOpAngle* AngleAngle(const SkOpAngle*, int id);
386 SkOpContour* AngleContour(SkOpAngle*, int id);
387 const SkOpPtT* AnglePtT(const SkOpAngle*, int id);
388 const SkOpSegment* AngleSegment(const SkOpAngle*, int id);
389 const SkOpSpanBase* AngleSpan(const SkOpAngle*, int id);
390
391 const SkOpAngle* ContourAngle(SkOpContour*, int id);
392 SkOpContour* ContourContour(SkOpContour*, int id);
393 const SkOpPtT* ContourPtT(SkOpContour*, int id);
394 const SkOpSegment* ContourSegment(SkOpContour*, int id);
395 const SkOpSpanBase* ContourSpan(SkOpContour*, int id);
396
397 const SkOpAngle* CoincidenceAngle(SkOpCoincidence*, int id);
398 SkOpContour* CoincidenceContour(SkOpCoincidence*, int id);
399 const SkOpPtT* CoincidencePtT(SkOpCoincidence*, int id);
400 const SkOpSegment* CoincidenceSegment(SkOpCoincidence*, int id);
401 const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence*, int id);
402
403 const SkOpAngle* PtTAngle(const SkOpPtT*, int id);
404 SkOpContour* PtTContour(SkOpPtT*, int id);
405 const SkOpPtT* PtTPtT(const SkOpPtT*, int id);
406 const SkOpSegment* PtTSegment(const SkOpPtT*, int id);
407 const SkOpSpanBase* PtTSpan(const SkOpPtT*, int id);
408
409 const SkOpAngle* SegmentAngle(const SkOpSegment*, int id);
410 SkOpContour* SegmentContour(SkOpSegment*, int id);
411 const SkOpPtT* SegmentPtT(const SkOpSegment*, int id);
412 const SkOpSegment* SegmentSegment(const SkOpSegment*, int id);
413 const SkOpSpanBase* SegmentSpan(const SkOpSegment*, int id);
414
415 const SkOpAngle* SpanAngle(const SkOpSpanBase*, int id);
416 SkOpContour* SpanContour(SkOpSpanBase*, int id);
417 const SkOpPtT* SpanPtT(const SkOpSpanBase*, int id);
418 const SkOpSegment* SpanSegment(const SkOpSpanBase*, int id);
419 const SkOpSpanBase* SpanSpan(const SkOpSpanBase*, int id);
420
421#if DEBUG_DUMP_VERIFY
422 void DumpOp(const SkPath& one, const SkPath& two, SkPathOp op,
423 const char* testName);
424 void DumpOp(FILE* file, const SkPath& one, const SkPath& two, SkPathOp op,
425 const char* testName);
426 void DumpSimplify(const SkPath& path, const char* testName);
427 void DumpSimplify(FILE* file, const SkPath& path, const char* testName);
428 void ReportOpFail(const SkPath& one, const SkPath& two, SkPathOp op);
429 void ReportSimplifyFail(const SkPath& path);
430 void VerifyOp(const SkPath& one, const SkPath& two, SkPathOp op,
431 const SkPath& result);
432 void VerifySimplify(const SkPath& path, const SkPath& result);
433#endif
434
435 // global path dumps for msvs Visual Studio 17 to use from Immediate Window
436 void Dump(const SkOpContour& );
437 void DumpAll(const SkOpContour& );
438 void DumpAngles(const SkOpContour& );
439 void DumpContours(const SkOpContour& );
440 void DumpContoursAll(const SkOpContour& );
441 void DumpContoursAngles(const SkOpContour& );
442 void DumpContoursPts(const SkOpContour& );
443 void DumpContoursPt(const SkOpContour& , int segmentID);
444 void DumpContoursSegment(const SkOpContour& , int segmentID);
445 void DumpContoursSpan(const SkOpContour& , int segmentID);
446 void DumpContoursSpans(const SkOpContour& );
447 void DumpPt(const SkOpContour& , int );
448 void DumpPts(const SkOpContour& , const char* prefix = "seg");
449 void DumpSegment(const SkOpContour& , int );
450 void DumpSegments(const SkOpContour& , const char* prefix = "seg", SkPathOp op = (SkPathOp) -1);
451 void DumpSpan(const SkOpContour& , int );
452 void DumpSpans(const SkOpContour& );
453
454 void Dump(const SkOpSegment& );
455 void DumpAll(const SkOpSegment& );
456 void DumpAngles(const SkOpSegment& );
457 void DumpCoin(const SkOpSegment& );
458 void DumpPts(const SkOpSegment& , const char* prefix = "seg");
459
460 void Dump(const SkOpPtT& );
461 void DumpAll(const SkOpPtT& );
462
463 void Dump(const SkOpSpanBase& );
464 void DumpCoin(const SkOpSpanBase& );
465 void DumpAll(const SkOpSpanBase& );
466
467 void DumpCoin(const SkOpSpan& );
468 bool DumpSpan(const SkOpSpan& );
469
470 void Dump(const SkDConic& );
471 void DumpID(const SkDConic& , int id);
472
473 void Dump(const SkDCubic& );
474 void DumpID(const SkDCubic& , int id);
475
476 void Dump(const SkDLine& );
477 void DumpID(const SkDLine& , int id);
478
479 void Dump(const SkDQuad& );
480 void DumpID(const SkDQuad& , int id);
481
482 void Dump(const SkDPoint& );
483
Cary Clark1857ddb2018-07-11 11:01:43 -0400484 void Dump(const SkOpAngle& );
485
Cary Clarkb8421ed2018-03-14 15:55:02 -0400486// dummy declarations to fool msvs Visual Studio 2018 Immediate Window
487#define DummyDeclarations(a, b) \
488 void Dump(const SkDebugTCoincident##a##b& ); \
489 \
490 void Dump(const SkDebugTSect##a##b& ); \
491 void DumpBoth(const SkDebugTSect##a##b& , SkDebugTSect##a##b* ); \
492 void DumpBounded(const SkDebugTSect##a##b& , int id); \
493 void DumpBounds(const SkDebugTSect##a##b& ); \
494 void DumpCoin(const SkDebugTSect##a##b& ); \
495 void DumpCoinCurves(const SkDebugTSect##a##b& ); \
496 void DumpCurves(const SkDebugTSect##a##b& ); \
497 \
498 void Dump(const SkDebugTSpan##a##b& ); \
499 void DumpAll(const SkDebugTSpan##a##b& ); \
500 void DumpBounded(const SkDebugTSpan##a##b& , int id); \
501 void DumpBounds(const SkDebugTSpan##a##b& ); \
502 void DumpCoin(const SkDebugTSpan##a##b& )
503
504 DummyDeclarations(Quad, Quad);
505 DummyDeclarations(Conic, Quad);
506 DummyDeclarations(Conic, Conic);
507 DummyDeclarations(Cubic, Quad);
508 DummyDeclarations(Cubic, Conic);
509 DummyDeclarations(Cubic, Cubic);
510#undef DummyDeclarations
511}
caryclarkdac1d172014-06-17 05:15:38 -0700512
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000513// generates tools/path_sorter.htm and path_visualizer.htm compatible data
caryclark54359292015-03-26 07:52:43 -0700514void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo);
515void DumpT(const SkDQuad& quad, double t);
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000516
Cary Clarkb8421ed2018-03-14 15:55:02 -0400517// global path dumps for msvs Visual Studio 17 to use from Immediate Window
518void Dump(const SkPath& path);
519void DumpHex(const SkPath& path);
520
caryclark@google.com07393ca2013-04-08 11:47:37 +0000521#endif