OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #ifndef SkOpContour_DEFINED | 7 #ifndef SkOpContour_DEFINED |
8 #define SkOpContour_DEFINED | 8 #define SkOpContour_DEFINED |
9 | 9 |
10 #include "SkOpSegment.h" | 10 #include "SkOpSegment.h" |
11 #include "SkTDArray.h" | 11 #include "SkTDArray.h" |
12 #include "SkTSort.h" | 12 #include "SkTSort.h" |
13 | 13 |
14 class SkChunkAlloc; | |
15 enum class SkOpRayDir; | 14 enum class SkOpRayDir; |
16 struct SkOpRayHit; | 15 struct SkOpRayHit; |
17 class SkPathWriter; | 16 class SkPathWriter; |
18 | 17 |
19 class SkOpContour { | 18 class SkOpContour { |
20 public: | 19 public: |
21 SkOpContour() { | 20 SkOpContour() { |
22 reset(); | 21 reset(); |
23 } | 22 } |
24 | 23 |
25 ~SkOpContour() { | 24 ~SkOpContour() { |
26 if (fNext) { | 25 if (fNext) { |
27 fNext->~SkOpContour(); | 26 fNext->~SkOpContour(); |
28 } | 27 } |
29 } | 28 } |
30 | 29 |
31 bool operator<(const SkOpContour& rh) const { | 30 bool operator<(const SkOpContour& rh) const { |
32 return fBounds.fTop == rh.fBounds.fTop | 31 return fBounds.fTop == rh.fBounds.fTop |
33 ? fBounds.fLeft < rh.fBounds.fLeft | 32 ? fBounds.fLeft < rh.fBounds.fLeft |
34 : fBounds.fTop < rh.fBounds.fTop; | 33 : fBounds.fTop < rh.fBounds.fTop; |
35 } | 34 } |
36 | 35 |
37 void addAlignIntersections(SkOpContourHead* contourList, SkChunkAlloc* alloc
ator) { | 36 void addConic(SkPoint pts[3], SkScalar weight) { |
38 SkASSERT(fCount > 0); | 37 appendSegment().addConic(pts, weight, this); |
39 SkOpSegment* segment = &fHead; | |
40 do { | |
41 segment->addAlignIntersections(contourList, allocator); | |
42 } while ((segment = segment->next())); | |
43 } | 38 } |
44 | 39 |
45 void addConic(SkPoint pts[3], SkScalar weight, SkChunkAlloc* allocator) { | 40 void addCubic(SkPoint pts[4]) { |
46 appendSegment(allocator).addConic(pts, weight, this); | 41 appendSegment().addCubic(pts, this); |
47 } | 42 } |
48 | 43 |
49 void addCubic(SkPoint pts[4], SkChunkAlloc* allocator) { | 44 SkOpSegment* addCurve(SkPath::Verb verb, const SkPoint pts[4]); |
50 appendSegment(allocator).addCubic(pts, this); | 45 |
| 46 SkOpSegment* addLine(SkPoint pts[2]) { |
| 47 return appendSegment().addLine(pts, this); |
51 } | 48 } |
52 | 49 |
53 SkOpSegment* addCurve(SkPath::Verb verb, const SkPoint pts[4], SkChunkAlloc*
allocator); | 50 void addQuad(SkPoint pts[3]) { |
54 | 51 appendSegment().addQuad(pts, this); |
55 void addLine(SkPoint pts[2], SkChunkAlloc* allocator) { | |
56 appendSegment(allocator).addLine(pts, this); | |
57 } | 52 } |
58 | 53 |
59 void addQuad(SkPoint pts[3], SkChunkAlloc* allocator) { | 54 SkOpSegment& appendSegment() { |
60 appendSegment(allocator).addQuad(pts, this); | |
61 } | |
62 | |
63 void align() { | |
64 SkASSERT(fCount > 0); | |
65 SkOpSegment* segment = &fHead; | |
66 do { | |
67 segment->align(); | |
68 } while ((segment = segment->next())); | |
69 } | |
70 | |
71 SkOpSegment& appendSegment(SkChunkAlloc* allocator) { | |
72 SkOpSegment* result = fCount++ | 55 SkOpSegment* result = fCount++ |
73 ? SkOpTAllocator<SkOpSegment>::Allocate(allocator) : &fHead; | 56 ? SkOpTAllocator<SkOpSegment>::Allocate(this->globalState()->allocat
or()) : &fHead; |
74 result->setPrev(fTail); | 57 result->setPrev(fTail); |
75 if (fTail) { | 58 if (fTail) { |
76 fTail->setNext(result); | 59 fTail->setNext(result); |
77 } | 60 } |
78 fTail = result; | 61 fTail = result; |
79 return *result; | 62 return *result; |
80 } | 63 } |
81 | 64 |
82 SkOpContour* appendContour(SkChunkAlloc* allocator) { | 65 SkOpContour* appendContour() { |
83 SkOpContour* contour = SkOpTAllocator<SkOpContour>::New(allocator); | 66 SkOpContour* contour = SkOpTAllocator<SkOpContour>::New(this->globalStat
e()->allocator()); |
84 contour->setNext(nullptr); | 67 contour->setNext(nullptr); |
85 SkOpContour* prev = this; | 68 SkOpContour* prev = this; |
86 SkOpContour* next; | 69 SkOpContour* next; |
87 while ((next = prev->next())) { | 70 while ((next = prev->next())) { |
88 prev = next; | 71 prev = next; |
89 } | 72 } |
90 prev->setNext(contour); | 73 prev->setNext(contour); |
91 return contour; | 74 return contour; |
92 } | 75 } |
93 | 76 |
94 const SkPathOpsBounds& bounds() const { | 77 const SkPathOpsBounds& bounds() const { |
95 return fBounds; | 78 return fBounds; |
96 } | 79 } |
97 | 80 |
98 void calcAngles(SkChunkAlloc* allocator) { | 81 void calcAngles() { |
99 SkASSERT(fCount > 0); | 82 SkASSERT(fCount > 0); |
100 SkOpSegment* segment = &fHead; | 83 SkOpSegment* segment = &fHead; |
101 do { | 84 do { |
102 segment->calcAngles(allocator); | 85 segment->calcAngles(); |
103 } while ((segment = segment->next())); | 86 } while ((segment = segment->next())); |
104 } | 87 } |
105 | 88 |
106 void complete() { | 89 void complete() { |
107 setBounds(); | 90 setBounds(); |
108 } | 91 } |
109 | 92 |
110 int count() const { | 93 int count() const { |
111 return fCount; | 94 return fCount; |
112 } | 95 } |
(...skipping 12 matching lines...) Expand all Loading... |
125 do { | 108 do { |
126 segment->debugShowActiveSpans(); | 109 segment->debugShowActiveSpans(); |
127 } while ((segment = segment->next())); | 110 } while ((segment = segment->next())); |
128 } | 111 } |
129 #endif | 112 #endif |
130 | 113 |
131 const SkOpAngle* debugAngle(int id) const { | 114 const SkOpAngle* debugAngle(int id) const { |
132 return SkDEBUGRELEASE(this->globalState()->debugAngle(id), nullptr); | 115 return SkDEBUGRELEASE(this->globalState()->debugAngle(id), nullptr); |
133 } | 116 } |
134 | 117 |
| 118 const SkOpCoincidence* debugCoincidence() const { |
| 119 return this->globalState()->coincidence(); |
| 120 } |
| 121 |
| 122 #if DEBUG_COINCIDENCE_VERBOSE |
135 void debugCheckHealth(const char* id, SkPathOpsDebug::GlitchLog* ) const; | 123 void debugCheckHealth(const char* id, SkPathOpsDebug::GlitchLog* ) const; |
| 124 #endif |
136 | 125 |
137 SkOpContour* debugContour(int id) { | 126 SkOpContour* debugContour(int id) { |
138 return SkDEBUGRELEASE(this->globalState()->debugContour(id), nullptr); | 127 return SkDEBUGRELEASE(this->globalState()->debugContour(id), nullptr); |
139 } | 128 } |
140 | 129 |
141 void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* log, | 130 #if DEBUG_COINCIDENCE_VERBOSE |
142 const SkOpCoincidence* coincidence) const; | 131 void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* log)
const; |
| 132 #endif |
143 | 133 |
144 const SkOpPtT* debugPtT(int id) const { | 134 const SkOpPtT* debugPtT(int id) const { |
145 return SkDEBUGRELEASE(this->globalState()->debugPtT(id), nullptr); | 135 return SkDEBUGRELEASE(this->globalState()->debugPtT(id), nullptr); |
146 } | 136 } |
147 | 137 |
148 const SkOpSegment* debugSegment(int id) const { | 138 const SkOpSegment* debugSegment(int id) const { |
149 return SkDEBUGRELEASE(this->globalState()->debugSegment(id), nullptr); | 139 return SkDEBUGRELEASE(this->globalState()->debugSegment(id), nullptr); |
150 } | 140 } |
151 | 141 |
152 const SkOpSpanBase* debugSpan(int id) const { | 142 const SkOpSpanBase* debugSpan(int id) const { |
153 return SkDEBUGRELEASE(this->globalState()->debugSpan(id), nullptr); | 143 return SkDEBUGRELEASE(this->globalState()->debugSpan(id), nullptr); |
154 } | 144 } |
155 | 145 |
156 SkOpGlobalState* globalState() const { | 146 SkOpGlobalState* globalState() const { |
157 return fState; | 147 return fState; |
158 } | 148 } |
159 | 149 |
160 void debugValidate() const { | 150 void debugValidate() const { |
161 #if DEBUG_VALIDATE | 151 #if DEBUG_VALIDATE |
162 const SkOpSegment* segment = &fHead; | 152 const SkOpSegment* segment = &fHead; |
163 const SkOpSegment* prior = nullptr; | 153 const SkOpSegment* prior = nullptr; |
164 do { | 154 do { |
165 segment->debugValidate(); | 155 segment->debugValidate(); |
166 SkASSERT(segment->prev() == prior); | 156 SkASSERT(segment->prev() == prior); |
167 prior = segment; | 157 prior = segment; |
(...skipping 22 matching lines...) Expand all Loading... |
190 void dumpPtsX(const char* prefix) const; | 180 void dumpPtsX(const char* prefix) const; |
191 void dumpSegment(int ) const; | 181 void dumpSegment(int ) const; |
192 void dumpSegments(const char* prefix = "seg", SkPathOp op = (SkPathOp) -1) c
onst; | 182 void dumpSegments(const char* prefix = "seg", SkPathOp op = (SkPathOp) -1) c
onst; |
193 void dumpSpan(int ) const; | 183 void dumpSpan(int ) const; |
194 void dumpSpans() const; | 184 void dumpSpans() const; |
195 | 185 |
196 const SkPoint& end() const { | 186 const SkPoint& end() const { |
197 return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())]; | 187 return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())]; |
198 } | 188 } |
199 | 189 |
200 bool findCollapsed() { | |
201 SkASSERT(fCount > 0); | |
202 SkOpSegment* segment = &fHead; | |
203 do { | |
204 segment->findCollapsed(); | |
205 } while ((segment = segment->next())); | |
206 return true; | |
207 } | |
208 | |
209 SkOpSpan* findSortableTop(SkOpContour* ); | 190 SkOpSpan* findSortableTop(SkOpContour* ); |
210 | 191 |
211 SkOpSegment* first() { | 192 SkOpSegment* first() { |
212 SkASSERT(fCount > 0); | 193 SkASSERT(fCount > 0); |
213 return &fHead; | 194 return &fHead; |
214 } | 195 } |
215 | 196 |
216 const SkOpSegment* first() const { | 197 const SkOpSegment* first() const { |
217 SkASSERT(fCount > 0); | 198 SkASSERT(fCount > 0); |
218 return &fHead; | 199 return &fHead; |
(...skipping 11 matching lines...) Expand all Loading... |
230 } | 211 } |
231 | 212 |
232 int isCcw() const { | 213 int isCcw() const { |
233 return fCcw; | 214 return fCcw; |
234 } | 215 } |
235 | 216 |
236 bool isXor() const { | 217 bool isXor() const { |
237 return fXor; | 218 return fXor; |
238 } | 219 } |
239 | 220 |
240 void markDone() { | 221 void markAllDone() { |
241 SkOpSegment* segment = &fHead; | 222 SkOpSegment* segment = &fHead; |
242 do { | 223 do { |
243 segment->markAllDone(); | 224 segment->markAllDone(); |
244 } while ((segment = segment->next())); | 225 } while ((segment = segment->next())); |
245 } | 226 } |
246 | 227 |
247 bool missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocat
or) { | 228 // Please keep this aligned with debugMissingCoincidence() |
| 229 bool missingCoincidence() { |
248 SkASSERT(fCount > 0); | 230 SkASSERT(fCount > 0); |
249 SkOpSegment* segment = &fHead; | 231 SkOpSegment* segment = &fHead; |
250 bool result = false; | 232 bool result = false; |
251 do { | 233 do { |
252 if (fState->angleCoincidence()) { | 234 if (fState->angleCoincidence()) { |
253 #if DEBUG_ANGLE | 235 #if DEBUG_ANGLE |
254 segment->debugCheckAngleCoin(); | 236 segment->debugCheckAngleCoin(); |
255 #endif | 237 #endif |
256 } else if (segment->missingCoincidence(coincidences, allocator)) { | 238 } else if (segment->missingCoincidence()) { |
257 result = true; | 239 result = true; |
258 // FIXME: trying again loops forever in issue3651_6 | 240 // FIXME: trying again loops forever in issue3651_6 |
259 // The continue below is speculative -- once there's an actual case that req
uires it, | 241 // The continue below is speculative -- once there's an actual case that req
uires it, |
260 // add the plumbing necessary to look for another missing coincidence in the
same segment | 242 // add the plumbing necessary to look for another missing coincidence in the
same segment |
261 // continue; // try again in case another missing coincidence is
further along | 243 // continue; // try again in case another missing coincidence is
further along |
262 } | 244 } |
263 segment = segment->next(); | 245 segment = segment->next(); |
264 } while (segment); | 246 } while (segment); |
265 return result; | 247 return result; |
266 } | 248 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 bool fXor; // set if original path had even-odd fill | 411 bool fXor; // set if original path had even-odd fill |
430 bool fOppXor; // set if opposite path had even-odd fill | 412 bool fOppXor; // set if opposite path had even-odd fill |
431 SkDEBUGCODE(int fID); | 413 SkDEBUGCODE(int fID); |
432 SkDEBUGCODE(mutable int fDebugIndent); | 414 SkDEBUGCODE(mutable int fDebugIndent); |
433 }; | 415 }; |
434 | 416 |
435 class SkOpContourHead : public SkOpContour { | 417 class SkOpContourHead : public SkOpContour { |
436 }; | 418 }; |
437 | 419 |
438 #endif | 420 #endif |
OLD | NEW |