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
10#include "SkPathOps.h"
11#include "SkTypes.h"
12#include <stdio.h>
13
14#ifdef SK_RELEASE
15#define FORCE_RELEASE 1
16#else
17#define FORCE_RELEASE 1  // set force release to 1 for multiple thread -- no debugging
18#endif
19
20#define ONE_OFF_DEBUG 0
21#define ONE_OFF_DEBUG_MATHEMATICA 0
22
23#if defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_ANDROID)
24    #define SK_RAND(seed) rand()
25#else
26    #define SK_RAND(seed) rand_r(&seed)
27#endif
28#ifdef SK_BUILD_FOR_WIN
29    #define SK_SNPRINTF _snprintf
30#else
31    #define SK_SNPRINTF snprintf
32#endif
33
34#define WIND_AS_STRING(x) char x##Str[12]; \
35        if (!SkPathOpsDebug::ValidWind(x)) strcpy(x##Str, "?"); \
36        else SK_SNPRINTF(x##Str, sizeof(x##Str), "%d", x)
37
38#if FORCE_RELEASE
39
40#define DEBUG_ACTIVE_OP 0
41#define DEBUG_ACTIVE_SPANS 0
42#define DEBUG_ACTIVE_SPANS_FIRST_ONLY 0
43#define DEBUG_ACTIVE_SPANS_SHORT_FORM 1
44#define DEBUG_ADD_INTERSECTING_TS 0
45#define DEBUG_ADD_T_PAIR 0
46#define DEBUG_ANGLE 0
47#define DEBUG_AS_C_CODE 1
48#define DEBUG_ASSEMBLE 0
49#define DEBUG_CHECK_ENDS 0
50#define DEBUG_CHECK_TINY 0
51#define DEBUG_CONCIDENT 0
52#define DEBUG_CROSS 0
53#define DEBUG_CUBIC_BINARY_SEARCH 0
54#define DEBUG_DUPLICATES 0
55#define DEBUG_FLAT_QUADS 0
56#define DEBUG_FLOW 0
57#define DEBUG_LIMIT_WIND_SUM 0
58#define DEBUG_MARK_DONE 0
59#define DEBUG_PATH_CONSTRUCTION 0
60#define DEBUG_SHOW_TEST_NAME 0
61#define DEBUG_SHOW_TEST_PROGRESS 0
62#define DEBUG_SHOW_WINDING 0
63#define DEBUG_SORT 0
64#define DEBUG_SORT_COMPACT 0
65#define DEBUG_SORT_RAW 0
66#define DEBUG_SORT_SINGLE 0
67#define DEBUG_SWAP_TOP 0
68#define DEBUG_UNSORTABLE 0
69#define DEBUG_VALIDATE 0
70#define DEBUG_WIND_BUMP 0
71#define DEBUG_WINDING 0
72#define DEBUG_WINDING_AT_T 0
73
74#else
75
76#define DEBUG_ACTIVE_OP 1
77#define DEBUG_ACTIVE_SPANS 1
78#define DEBUG_ACTIVE_SPANS_FIRST_ONLY 0
79#define DEBUG_ACTIVE_SPANS_SHORT_FORM 1
80#define DEBUG_ADD_INTERSECTING_TS 1
81#define DEBUG_ADD_T_PAIR 1
82#define DEBUG_ANGLE 1
83#define DEBUG_AS_C_CODE 1
84#define DEBUG_ASSEMBLE 1
85#define DEBUG_CHECK_ENDS 1
86#define DEBUG_CHECK_TINY 1
87#define DEBUG_CONCIDENT 1
88#define DEBUG_CROSS 01
89#define DEBUG_CUBIC_BINARY_SEARCH 1
90#define DEBUG_DUPLICATES 1
91#define DEBUG_FLAT_QUADS 0
92#define DEBUG_FLOW 1
93#define DEBUG_LIMIT_WIND_SUM 4
94#define DEBUG_MARK_DONE 1
95#define DEBUG_PATH_CONSTRUCTION 1
96#define DEBUG_SHOW_TEST_NAME 1
97#define DEBUG_SHOW_TEST_PROGRESS 1
98#define DEBUG_SHOW_WINDING 0
99#define DEBUG_SORT 1
100#define DEBUG_SORT_COMPACT 0
101#define DEBUG_SORT_RAW 0
102#define DEBUG_SORT_SINGLE 0
103#define DEBUG_SWAP_TOP 1
104#define DEBUG_UNSORTABLE 1
105#define DEBUG_VALIDATE 0
106#define DEBUG_WIND_BUMP 0
107#define DEBUG_WINDING 1
108#define DEBUG_WINDING_AT_T 1
109
110#endif
111
112#if DEBUG_AS_C_CODE
113#define CUBIC_DEBUG_STR "{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}"
114#define QUAD_DEBUG_STR  "{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}"
115#define LINE_DEBUG_STR  "{{%1.9g,%1.9g}, {%1.9g,%1.9g}}"
116#define PT_DEBUG_STR "{{%1.9g,%1.9g}}"
117#else
118#define CUBIC_DEBUG_STR "(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
119#define QUAD_DEBUG_STR  "(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)"
120#define LINE_DEBUG_STR  "(%1.9g,%1.9g %1.9g,%1.9g)"
121#define PT_DEBUG_STR "(%1.9g,%1.9g)"
122#endif
123#define T_DEBUG_STR(t, n) #t "[" #n "]=%1.9g"
124#define TX_DEBUG_STR(t) #t "[%d]=%1.9g"
125#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
126#define QUAD_DEBUG_DATA(q)  q[0].fX, q[0].fY, q[1].fX, q[1].fY, q[2].fX, q[2].fY
127#define LINE_DEBUG_DATA(l)  l[0].fX, l[0].fY, l[1].fX, l[1].fY
128#define PT_DEBUG_DATA(i, n) i.pt(n).asSkPoint().fX, i.pt(n).asSkPoint().fY
129
130#ifndef DEBUG_TEST
131#define DEBUG_TEST 0
132#endif
133
134#if DEBUG_SHOW_TEST_NAME
135#include "SkTLS.h"
136#endif
137
138#include "SkTArray.h"
139#include "SkTDArray.h"
140
141class SkPathOpsDebug {
142public:
143    static const char* kLVerbStr[];
144
145#if defined(SK_DEBUG) || !FORCE_RELEASE
146    static int gContourID;
147    static int gSegmentID;
148#endif
149
150#if DEBUG_SORT || DEBUG_SWAP_TOP
151    static int gSortCountDefault;
152    static int gSortCount;
153#endif
154
155#if DEBUG_ACTIVE_OP
156    static const char* kPathOpStr[];
157#endif
158
159    static bool ChaseContains(const SkTDArray<struct SkOpSpan *>& , const struct SkOpSpan * );
160    static void MathematicaIze(char* str, size_t bufferSize);
161    static bool ValidWind(int winding);
162    static void WindingPrintf(int winding);
163
164#if DEBUG_SHOW_TEST_NAME
165    static void* CreateNameStr();
166    static void DeleteNameStr(void* v);
167#define DEBUG_FILENAME_STRING_LENGTH 64
168#define DEBUG_FILENAME_STRING (reinterpret_cast<char* >(SkTLS::Get(SkPathOpsDebug::CreateNameStr, \
169        SkPathOpsDebug::DeleteNameStr)))
170    static void BumpTestName(char* );
171#endif
172    static void ShowPath(const SkPath& one, const SkPath& two, SkPathOp op, const char* name);
173    static void DumpCoincidence(const SkTArray<class SkOpContour, true>& contours);
174    static void DumpCoincidence(const SkTArray<class SkOpContour* , true>& contours);
175    static void DumpContours(const SkTArray<class SkOpContour, true>& contours);
176    static void DumpContours(const SkTArray<class SkOpContour* , true>& contours);
177    static void DumpContourAngles(const SkTArray<class SkOpContour, true>& contours);
178    static void DumpContourAngles(const SkTArray<class SkOpContour* , true>& contours);
179    static void DumpContourPt(const SkTArray<class SkOpContour, true>& contours, int id);
180    static void DumpContourPt(const SkTArray<class SkOpContour* , true>& contours, int id);
181    static void DumpContourPts(const SkTArray<class SkOpContour, true>& contours);
182    static void DumpContourPts(const SkTArray<class SkOpContour* , true>& contours);
183    static void DumpContourSpan(const SkTArray<class SkOpContour, true>& contours, int id);
184    static void DumpContourSpan(const SkTArray<class SkOpContour* , true>& contours, int id);
185    static void DumpContourSpans(const SkTArray<class SkOpContour, true>& contours);
186    static void DumpContourSpans(const SkTArray<class SkOpContour* , true>& contours);
187    static void DumpSpans(const SkTDArray<struct SkOpSpan *>& );
188    static void DumpSpans(const SkTDArray<struct SkOpSpan *>* );
189};
190
191// shorthand for calling from debugger
192void Dump(const SkTArray<class SkOpContour, true>& contours);
193void Dump(const SkTArray<class SkOpContour* , true>& contours);
194void Dump(const SkTArray<class SkOpContour, true>* contours);
195void Dump(const SkTArray<class SkOpContour* , true>* contours);
196
197void Dump(const SkTDArray<SkOpSpan* >& chase);
198void Dump(const SkTDArray<SkOpSpan* >* chase);
199
200void DumpAngles(const SkTArray<class SkOpContour, true>& contours);
201void DumpAngles(const SkTArray<class SkOpContour* , true>& contours);
202void DumpAngles(const SkTArray<class SkOpContour, true>* contours);
203void DumpAngles(const SkTArray<class SkOpContour* , true>* contours);
204
205void DumpCoin(const SkTArray<class SkOpContour, true>& contours);
206void DumpCoin(const SkTArray<class SkOpContour* , true>& contours);
207void DumpCoin(const SkTArray<class SkOpContour, true>* contours);
208void DumpCoin(const SkTArray<class SkOpContour* , true>* contours);
209
210void DumpPts(const SkTArray<class SkOpContour, true>& contours);
211void DumpPts(const SkTArray<class SkOpContour* , true>& contours);
212void DumpPts(const SkTArray<class SkOpContour, true>* contours);
213void DumpPts(const SkTArray<class SkOpContour* , true>* contours);
214
215void DumpPt(const SkTArray<class SkOpContour, true>& contours, int segmentID);
216void DumpPt(const SkTArray<class SkOpContour* , true>& contours, int segmentID);
217void DumpPt(const SkTArray<class SkOpContour, true>* contours, int segmentID);
218void DumpPt(const SkTArray<class SkOpContour* , true>* contours, int segmentID);
219
220void DumpSpans(const SkTArray<class SkOpContour, true>& contours);
221void DumpSpans(const SkTArray<class SkOpContour* , true>& contours);
222void DumpSpans(const SkTArray<class SkOpContour, true>* contours);
223void DumpSpans(const SkTArray<class SkOpContour* , true>* contours);
224
225void DumpSpan(const SkTArray<class SkOpContour, true>& contours, int segmentID);
226void DumpSpan(const SkTArray<class SkOpContour* , true>& contours, int segmentID);
227void DumpSpan(const SkTArray<class SkOpContour, true>* contours, int segmentID);
228void DumpSpan(const SkTArray<class SkOpContour* , true>* contours, int segmentID);
229
230// generates tools/path_sorter.htm and path_visualizer.htm compatible data
231void DumpQ(const struct SkDQuad& quad1, const struct SkDQuad& quad2, int testNo);
232
233void DumpT(const struct SkDQuad& quad, double t);
234
235#endif
236