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; | 14 class SkChunkAlloc; |
| 15 enum class SkOpRayDir; |
| 16 struct SkOpRayHit; |
15 class SkPathWriter; | 17 class SkPathWriter; |
16 | 18 |
17 class SkOpContour { | 19 class SkOpContour { |
18 public: | 20 public: |
19 SkOpContour() { | 21 SkOpContour() { |
20 reset(); | 22 reset(); |
21 } | 23 } |
22 | 24 |
23 ~SkOpContour() { | 25 ~SkOpContour() { |
24 if (fNext) { | 26 if (fNext) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 | 101 |
100 int count() const { | 102 int count() const { |
101 return fCount; | 103 return fCount; |
102 } | 104 } |
103 | 105 |
104 int debugID() const { | 106 int debugID() const { |
105 return SkDEBUGRELEASE(fID, -1); | 107 return SkDEBUGRELEASE(fID, -1); |
106 } | 108 } |
107 | 109 |
108 int debugIndent() const { | 110 int debugIndent() const { |
109 return SkDEBUGRELEASE(fIndent, 0); | 111 return SkDEBUGRELEASE(fDebugIndent, 0); |
110 } | 112 } |
111 | 113 |
112 #if DEBUG_ACTIVE_SPANS | 114 #if DEBUG_ACTIVE_SPANS |
113 void debugShowActiveSpans() { | 115 void debugShowActiveSpans() { |
114 SkOpSegment* segment = &fHead; | 116 SkOpSegment* segment = &fHead; |
115 do { | 117 do { |
116 segment->debugShowActiveSpans(); | 118 segment->debugShowActiveSpans(); |
117 } while ((segment = segment->next())); | 119 } while ((segment = segment->next())); |
118 } | 120 } |
119 #endif | 121 #endif |
120 | 122 |
121 const SkOpAngle* debugAngle(int id) const { | 123 const SkOpAngle* debugAngle(int id) const { |
122 return SkDEBUGRELEASE(globalState()->debugAngle(id), NULL); | 124 return SkDEBUGRELEASE(this->globalState()->debugAngle(id), NULL); |
123 } | 125 } |
124 | 126 |
125 SkOpContour* debugContour(int id) { | 127 SkOpContour* debugContour(int id) { |
126 return SkDEBUGRELEASE(globalState()->debugContour(id), NULL); | 128 return SkDEBUGRELEASE(this->globalState()->debugContour(id), NULL); |
127 } | 129 } |
128 | 130 |
129 const SkOpPtT* debugPtT(int id) const { | 131 const SkOpPtT* debugPtT(int id) const { |
130 return SkDEBUGRELEASE(globalState()->debugPtT(id), NULL); | 132 return SkDEBUGRELEASE(this->globalState()->debugPtT(id), NULL); |
131 } | 133 } |
132 | 134 |
133 const SkOpSegment* debugSegment(int id) const { | 135 const SkOpSegment* debugSegment(int id) const { |
134 return SkDEBUGRELEASE(globalState()->debugSegment(id), NULL); | 136 return SkDEBUGRELEASE(this->globalState()->debugSegment(id), NULL); |
135 } | 137 } |
136 | 138 |
137 const SkOpSpanBase* debugSpan(int id) const { | 139 const SkOpSpanBase* debugSpan(int id) const { |
138 return SkDEBUGRELEASE(globalState()->debugSpan(id), NULL); | 140 return SkDEBUGRELEASE(this->globalState()->debugSpan(id), NULL); |
139 } | 141 } |
140 | 142 |
141 SkOpGlobalState* globalState() const { | 143 SkOpGlobalState* globalState() const { |
142 return fState; | 144 return fState; |
143 } | 145 } |
144 | 146 |
145 void debugValidate() const { | 147 void debugValidate() const { |
146 #if DEBUG_VALIDATE | 148 #if DEBUG_VALIDATE |
147 const SkOpSegment* segment = &fHead; | 149 const SkOpSegment* segment = &fHead; |
148 const SkOpSegment* prior = NULL; | 150 const SkOpSegment* prior = NULL; |
149 do { | 151 do { |
150 segment->debugValidate(); | 152 segment->debugValidate(); |
151 SkASSERT(segment->prev() == prior); | 153 SkASSERT(segment->prev() == prior); |
152 prior = segment; | 154 prior = segment; |
153 } while ((segment = segment->next())); | 155 } while ((segment = segment->next())); |
154 SkASSERT(prior == fTail); | 156 SkASSERT(prior == fTail); |
155 #endif | 157 #endif |
156 } | 158 } |
157 | 159 |
158 bool done() const { | 160 bool done() const { |
159 return fDone; | 161 return fDone; |
160 } | 162 } |
161 | 163 |
162 void dump(); | 164 void dump() const; |
163 void dumpAll(); | 165 void dumpAll() const; |
164 void dumpAngles() const; | 166 void dumpAngles() const; |
| 167 void dumpContours() const; |
| 168 void dumpContoursAll() const; |
| 169 void dumpContoursAngles() const; |
| 170 void dumpContoursPts() const; |
| 171 void dumpContoursPt(int segmentID) const; |
| 172 void dumpContoursSegment(int segmentID) const; |
| 173 void dumpContoursSpan(int segmentID) const; |
| 174 void dumpContoursSpans() const; |
165 void dumpPt(int ) const; | 175 void dumpPt(int ) const; |
166 void dumpPts() const; | 176 void dumpPts() const; |
167 void dumpPtsX() const; | 177 void dumpPtsX() const; |
168 void dumpSegment(int ) const; | 178 void dumpSegment(int ) const; |
169 void dumpSegments(SkPathOp op) const; | 179 void dumpSegments(SkPathOp op) const; |
170 void dumpSpan(int ) const; | 180 void dumpSpan(int ) const; |
171 void dumpSpans() const; | 181 void dumpSpans() const; |
172 | 182 |
173 const SkPoint& end() const { | 183 const SkPoint& end() const { |
174 return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())]; | 184 return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())]; |
175 } | 185 } |
176 | 186 |
| 187 SkOpSpan* findSortableTop(SkOpContour* ); |
| 188 |
177 SkOpSegment* first() { | 189 SkOpSegment* first() { |
178 SkASSERT(fCount > 0); | 190 SkASSERT(fCount > 0); |
179 return &fHead; | 191 return &fHead; |
180 } | 192 } |
181 | 193 |
182 const SkOpSegment* first() const { | 194 const SkOpSegment* first() const { |
183 SkASSERT(fCount > 0); | 195 SkASSERT(fCount > 0); |
184 return &fHead; | 196 return &fHead; |
185 } | 197 } |
186 | 198 |
187 void indentDump() { | 199 void indentDump() const { |
188 SkDEBUGCODE(fIndent += 2); | 200 SkDEBUGCODE(fDebugIndent += 2); |
189 } | 201 } |
190 | 202 |
191 void init(SkOpGlobalState* globalState, bool operand, bool isXor) { | 203 void init(SkOpGlobalState* globalState, bool operand, bool isXor) { |
192 fState = globalState; | 204 fState = globalState; |
193 fOperand = operand; | 205 fOperand = operand; |
194 fXor = isXor; | 206 fXor = isXor; |
195 SkDEBUGCODE(fID = globalState->nextContourID()); | 207 SkDEBUGCODE(fID = globalState->nextContourID()); |
196 } | 208 } |
197 | 209 |
198 bool isXor() const { | 210 bool isXor() const { |
(...skipping 30 matching lines...) Expand all Loading... |
229 } | 241 } |
230 | 242 |
231 SkOpContour* next() { | 243 SkOpContour* next() { |
232 return fNext; | 244 return fNext; |
233 } | 245 } |
234 | 246 |
235 const SkOpContour* next() const { | 247 const SkOpContour* next() const { |
236 return fNext; | 248 return fNext; |
237 } | 249 } |
238 | 250 |
239 SkOpSegment* nonVerticalSegment(SkOpSpanBase** start, SkOpSpanBase** end); | |
240 | |
241 bool operand() const { | 251 bool operand() const { |
242 return fOperand; | 252 return fOperand; |
243 } | 253 } |
244 | 254 |
245 bool oppXor() const { | 255 bool oppXor() const { |
246 return fOppXor; | 256 return fOppXor; |
247 } | 257 } |
248 | 258 |
249 void outdentDump() { | 259 void outdentDump() const { |
250 SkDEBUGCODE(fIndent -= 2); | 260 SkDEBUGCODE(fDebugIndent -= 2); |
251 } | 261 } |
252 | 262 |
| 263 void rayCheck(const SkOpRayHit& base, SkOpRayDir dir, SkOpRayHit** hits, SkC
hunkAlloc* ); |
| 264 |
253 void remove(SkOpContour* contour) { | 265 void remove(SkOpContour* contour) { |
254 if (contour == this) { | 266 if (contour == this) { |
255 SkASSERT(fCount == 0); | 267 SkASSERT(fCount == 0); |
256 return; | 268 return; |
257 } | 269 } |
258 SkASSERT(contour->fNext == NULL); | 270 SkASSERT(contour->fNext == NULL); |
259 SkOpContour* prev = this; | 271 SkOpContour* prev = this; |
260 SkOpContour* next; | 272 SkOpContour* next; |
261 while ((next = prev->next()) != contour) { | 273 while ((next = prev->next()) != contour) { |
262 SkASSERT(next); | 274 SkASSERT(next); |
263 prev = next; | 275 prev = next; |
264 } | 276 } |
265 SkASSERT(prev); | 277 SkASSERT(prev); |
266 prev->setNext(NULL); | 278 prev->setNext(NULL); |
267 } | 279 } |
268 | 280 |
269 void reset() { | 281 void reset() { |
270 fTail = NULL; | 282 fTail = NULL; |
271 fNext = NULL; | 283 fNext = NULL; |
272 fCount = 0; | 284 fCount = 0; |
273 fDone = false; | 285 fDone = false; |
| 286 fTopsFound = false; |
274 SkDEBUGCODE(fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_Sca
larMin)); | 287 SkDEBUGCODE(fBounds.set(SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_Sca
larMin)); |
275 SkDEBUGCODE(fFirstSorted = -1); | 288 SkDEBUGCODE(fFirstSorted = -1); |
276 SkDEBUGCODE(fIndent = 0); | 289 SkDEBUGCODE(fDebugIndent = 0); |
277 } | 290 } |
278 | 291 |
279 void setBounds() { | 292 void setBounds() { |
280 SkASSERT(fCount > 0); | 293 SkASSERT(fCount > 0); |
281 const SkOpSegment* segment = &fHead; | 294 const SkOpSegment* segment = &fHead; |
282 fBounds = segment->bounds(); | 295 fBounds = segment->bounds(); |
283 while ((segment = segment->next())) { | 296 while ((segment = segment->next())) { |
284 fBounds.add(segment->bounds()); | 297 fBounds.add(segment->bounds()); |
285 } | 298 } |
286 } | 299 } |
(...skipping 22 matching lines...) Expand all Loading... |
309 SkPath::Verb simplifyCubic(SkPoint pts[4]); | 322 SkPath::Verb simplifyCubic(SkPoint pts[4]); |
310 | 323 |
311 void sortAngles() { | 324 void sortAngles() { |
312 SkASSERT(fCount > 0); | 325 SkASSERT(fCount > 0); |
313 SkOpSegment* segment = &fHead; | 326 SkOpSegment* segment = &fHead; |
314 do { | 327 do { |
315 segment->sortAngles(); | 328 segment->sortAngles(); |
316 } while ((segment = segment->next())); | 329 } while ((segment = segment->next())); |
317 } | 330 } |
318 | 331 |
319 void sortSegments() { | |
320 SkOpSegment* segment = &fHead; | |
321 do { | |
322 *fSortedSegments.append() = segment; | |
323 } while ((segment = segment->next())); | |
324 SkTQSort<SkOpSegment>(fSortedSegments.begin(), fSortedSegments.end() - 1
); | |
325 fFirstSorted = 0; | |
326 } | |
327 | |
328 const SkPoint& start() const { | 332 const SkPoint& start() const { |
329 return fHead.pts()[0]; | 333 return fHead.pts()[0]; |
330 } | 334 } |
331 | 335 |
332 void toPartialBackward(SkPathWriter* path) const { | 336 void toPartialBackward(SkPathWriter* path) const { |
333 const SkOpSegment* segment = fTail; | 337 const SkOpSegment* segment = fTail; |
334 do { | 338 do { |
335 segment->addCurveTo(segment->tail(), segment->head(), path, true); | 339 segment->addCurveTo(segment->tail(), segment->head(), path, true); |
336 } while ((segment = segment->prev())); | 340 } while ((segment = segment->prev())); |
337 } | 341 } |
338 | 342 |
339 void toPartialForward(SkPathWriter* path) const { | 343 void toPartialForward(SkPathWriter* path) const { |
340 const SkOpSegment* segment = &fHead; | 344 const SkOpSegment* segment = &fHead; |
341 do { | 345 do { |
342 segment->addCurveTo(segment->head(), segment->tail(), path, true); | 346 segment->addCurveTo(segment->head(), segment->tail(), path, true); |
343 } while ((segment = segment->next())); | 347 } while ((segment = segment->next())); |
344 } | 348 } |
345 | 349 |
346 void toPath(SkPathWriter* path) const; | 350 void toPath(SkPathWriter* path) const; |
347 void topSortableSegment(const SkDPoint& topLeft, SkDPoint* bestXY, SkOpSegme
nt** topStart); | |
348 SkOpSegment* undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr); | 351 SkOpSegment* undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr); |
349 | 352 |
350 private: | 353 private: |
351 SkOpGlobalState* fState; | 354 SkOpGlobalState* fState; |
352 SkOpSegment fHead; | 355 SkOpSegment fHead; |
353 SkOpSegment* fTail; | 356 SkOpSegment* fTail; |
354 SkOpContour* fNext; | 357 SkOpContour* fNext; |
355 SkTDArray<SkOpSegment*> fSortedSegments; // set by find top segment | |
356 SkPathOpsBounds fBounds; | 358 SkPathOpsBounds fBounds; |
357 int fCount; | 359 int fCount; |
358 int fFirstSorted; | 360 int fFirstSorted; |
359 bool fDone; // set by find top segment | 361 bool fDone; // set by find top segment |
| 362 bool fTopsFound; |
360 bool fOperand; // true for the second argument to a binary operator | 363 bool fOperand; // true for the second argument to a binary operator |
361 bool fXor; // set if original path had even-odd fill | 364 bool fXor; // set if original path had even-odd fill |
362 bool fOppXor; // set if opposite path had even-odd fill | 365 bool fOppXor; // set if opposite path had even-odd fill |
363 SkDEBUGCODE(int fID); | 366 SkDEBUGCODE(int fID); |
364 SkDEBUGCODE(int fIndent); | 367 SkDEBUGCODE(mutable int fDebugIndent); |
| 368 }; |
| 369 |
| 370 class SkOpContourHead : public SkOpContour { |
365 }; | 371 }; |
366 | 372 |
367 #endif | 373 #endif |
OLD | NEW |