Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(258)

Side by Side Diff: src/pathops/SkPathOpsCommon.cpp

Issue 131103009: update pathops to circle sort (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: disable old test that still fails on linux 32 release Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/pathops/SkPathOpsCommon.h ('k') | src/pathops/SkPathOpsCubic.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 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 #include "SkAddIntersections.h" 7 #include "SkAddIntersections.h"
8 #include "SkOpEdgeBuilder.h" 8 #include "SkOpEdgeBuilder.h"
9 #include "SkPathOpsCommon.h" 9 #include "SkPathOpsCommon.h"
10 #include "SkPathWriter.h" 10 #include "SkPathWriter.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { 104 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
105 SkOpContour* contour = contourList[cIndex]; 105 SkOpContour* contour = contourList[cIndex];
106 result = contour->undoneSegment(start, end); 106 result = contour->undoneSegment(start, end);
107 if (result) { 107 if (result) {
108 return result; 108 return result;
109 } 109 }
110 } 110 }
111 return NULL; 111 return NULL;
112 } 112 }
113 113
114 SkOpSegment* FindChase(SkTDArray<SkOpSpan*>& chase, int& tIndex, int& endIndex) { 114 SkOpSegment* FindChase(SkTDArray<SkOpSpan*>* chase, int* tIndex, int* endIndex) {
115 while (chase.count()) { 115 while (chase->count()) {
116 SkOpSpan* span; 116 SkOpSpan* span;
117 chase.pop(&span); 117 chase->pop(&span);
118 const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex); 118 const SkOpSpan& backPtr = span->fOther->span(span->fOtherIndex);
119 SkOpSegment* segment = backPtr.fOther; 119 SkOpSegment* segment = backPtr.fOther;
120 tIndex = backPtr.fOtherIndex; 120 *tIndex = backPtr.fOtherIndex;
121 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; 121 bool sortable = true;
122 int done = 0; 122 bool done = true;
123 if (segment->activeAngle(tIndex, &done, &angles)) { 123 *endIndex = -1;
124 SkOpAngle* last = angles.end() - 1; 124 if (const SkOpAngle* last = segment->activeAngle(*tIndex, tIndex, endInd ex, &done,
125 tIndex = last->start(); 125 &sortable)) {
126 endIndex = last->end(); 126 *tIndex = last->start();
127 #if TRY_ROTATE 127 *endIndex = last->end();
128 *chase.insert(0) = span; 128 #if TRY_ROTATE
129 #else 129 *chase->insert(0) = span;
130 *chase.append() = span; 130 #else
131 #endif 131 *chase->append() = span;
132 #endif
132 return last->segment(); 133 return last->segment();
133 } 134 }
134 if (done == angles.count()) { 135 if (done) {
135 continue; 136 continue;
136 } 137 }
137 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted;
138 bool sortable = SkOpSegment::SortAngles(angles, &sorted,
139 SkOpSegment::kMayBeUnordered_SortAngleKind);
140 int angleCount = sorted.count();
141 #if DEBUG_SORT
142 sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0, 0, 0, sorta ble);
143 #endif
144 if (!sortable) { 138 if (!sortable) {
145 continue; 139 continue;
146 } 140 }
147 // find first angle, initialize winding to computed fWindSum 141 // find first angle, initialize winding to computed fWindSum
148 int firstIndex = -1; 142 const SkOpAngle* angle = segment->spanToAngle(*tIndex, *endIndex);
149 const SkOpAngle* angle; 143 const SkOpAngle* firstAngle;
144 SkDEBUGCODE(firstAngle = angle);
145 SkDEBUGCODE(bool loop = false);
150 int winding; 146 int winding;
151 do { 147 do {
152 angle = sorted[++firstIndex]; 148 angle = angle->next();
149 SkASSERT(angle != firstAngle || !loop);
150 SkDEBUGCODE(loop |= angle == firstAngle);
153 segment = angle->segment(); 151 segment = angle->segment();
154 winding = segment->windSum(angle); 152 winding = segment->windSum(angle);
155 } while (winding == SK_MinS32); 153 } while (winding == SK_MinS32);
156 int spanWinding = segment->spanSign(angle->start(), angle->end()); 154 int spanWinding = segment->spanSign(angle->start(), angle->end());
157 #if DEBUG_WINDING 155 #if DEBUG_WINDING
158 SkDebugf("%s winding=%d spanWinding=%d\n", 156 SkDebugf("%s winding=%d spanWinding=%d\n", __FUNCTION__, winding, spanWi nding);
159 __FUNCTION__, winding, spanWinding);
160 #endif 157 #endif
161 // turn span winding into contour winding 158 // turn span winding into contour winding
162 if (spanWinding * winding < 0) { 159 if (spanWinding * winding < 0) {
163 winding += spanWinding; 160 winding += spanWinding;
164 } 161 }
165 #if DEBUG_SORT
166 segment->debugShowSort(__FUNCTION__, sorted, firstIndex, winding, 0, sor table);
167 #endif
168 // we care about first sign and whether wind sum indicates this 162 // we care about first sign and whether wind sum indicates this
169 // edge is inside or outside. Maybe need to pass span winding 163 // edge is inside or outside. Maybe need to pass span winding
170 // or first winding or something into this function? 164 // or first winding or something into this function?
171 // advance to first undone angle, then return it and winding 165 // advance to first undone angle, then return it and winding
172 // (to set whether edges are active or not) 166 // (to set whether edges are active or not)
173 int nextIndex = firstIndex + 1; 167 firstAngle = angle;
174 int lastIndex = firstIndex != 0 ? firstIndex : angleCount; 168 winding -= firstAngle->segment()->spanSign(firstAngle);
175 angle = sorted[firstIndex]; 169 while ((angle = angle->next()) != firstAngle) {
176 winding -= angle->segment()->spanSign(angle);
177 do {
178 SkASSERT(nextIndex != firstIndex);
179 if (nextIndex == angleCount) {
180 nextIndex = 0;
181 }
182 angle = sorted[nextIndex];
183 segment = angle->segment(); 170 segment = angle->segment();
184 int maxWinding = winding; 171 int maxWinding = winding;
185 winding -= segment->spanSign(angle); 172 winding -= segment->spanSign(angle);
186 #if DEBUG_SORT 173 #if DEBUG_SORT
187 SkDebugf("%s id=%d maxWinding=%d winding=%d sign=%d\n", __FUNCTION__ , 174 SkDebugf("%s id=%d maxWinding=%d winding=%d sign=%d\n", __FUNCTION__ ,
188 segment->debugID(), maxWinding, winding, angle->sign()); 175 segment->debugID(), maxWinding, winding, angle->sign());
189 #endif 176 #endif
190 tIndex = angle->start(); 177 *tIndex = angle->start();
191 endIndex = angle->end(); 178 *endIndex = angle->end();
192 int lesser = SkMin32(tIndex, endIndex); 179 int lesser = SkMin32(*tIndex, *endIndex);
193 const SkOpSpan& nextSpan = segment->span(lesser); 180 const SkOpSpan& nextSpan = segment->span(lesser);
194 if (!nextSpan.fDone) { 181 if (!nextSpan.fDone) {
195 // FIXME: this be wrong? assign startWinding if edge is in 182 // FIXME: this be wrong? assign startWinding if edge is in
196 // same direction. If the direction is opposite, winding to 183 // same direction. If the direction is opposite, winding to
197 // assign is flipped sign or +/- 1? 184 // assign is flipped sign or +/- 1?
198 if (SkOpSegment::UseInnerWinding(maxWinding, winding)) { 185 if (SkOpSegment::UseInnerWinding(maxWinding, winding)) {
199 maxWinding = winding; 186 maxWinding = winding;
200 } 187 }
201 segment->markAndChaseWinding(angle, maxWinding, 0); 188 segment->markAndChaseWinding(angle, maxWinding, 0);
202 break; 189 break;
203 } 190 }
204 } while (++nextIndex != lastIndex); 191 }
205 *chase.insert(0) = span; 192 *chase->insert(0) = span;
206 return segment; 193 return segment;
207 } 194 }
208 return NULL; 195 return NULL;
209 } 196 }
210 197
211 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY 198 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
212 void DebugShowActiveSpans(SkTArray<SkOpContour*, true>& contourList) { 199 void DebugShowActiveSpans(SkTArray<SkOpContour*, true>& contourList) {
213 int index; 200 int index;
214 for (index = 0; index < contourList.count(); ++ index) { 201 for (index = 0; index < contourList.count(); ++ index) {
215 contourList[index]->debugShowActiveSpans(); 202 contourList[index]->debugShowActiveSpans();
216 } 203 }
217 } 204 }
218 #endif 205 #endif
219 206
220 static SkOpSegment* findSortableTop(const SkTArray<SkOpContour*, true>& contourL ist, 207 static SkOpSegment* findSortableTop(const SkTArray<SkOpContour*, true>& contourL ist,
221 int* index, int* endIndex, SkPoint* topLeft, bool* unsortable, 208 int* index, int* endIndex, SkPoint* topLeft, bool* unsortable,
222 bool* done, bool onlySortable) { 209 bool* done, bool onlySortable) {
223 SkOpSegment* result; 210 SkOpSegment* result;
211 const SkOpSegment* lastTopStart = NULL;
212 int lastIndex = -1, lastEndIndex = -1;
224 do { 213 do {
225 SkPoint bestXY = {SK_ScalarMax, SK_ScalarMax}; 214 SkPoint bestXY = {SK_ScalarMax, SK_ScalarMax};
226 int contourCount = contourList.count(); 215 int contourCount = contourList.count();
227 SkOpSegment* topStart = NULL; 216 SkOpSegment* topStart = NULL;
228 *done = true; 217 *done = true;
229 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { 218 for (int cIndex = 0; cIndex < contourCount; ++cIndex) {
230 SkOpContour* contour = contourList[cIndex]; 219 SkOpContour* contour = contourList[cIndex];
231 if (contour->done()) { 220 if (contour->done()) {
232 continue; 221 continue;
233 } 222 }
234 const SkPathOpsBounds& bounds = contour->bounds(); 223 const SkPathOpsBounds& bounds = contour->bounds();
235 if (bounds.fBottom < topLeft->fY) { 224 if (bounds.fBottom < topLeft->fY) {
236 *done = false; 225 *done = false;
237 continue; 226 continue;
238 } 227 }
239 if (bounds.fBottom == topLeft->fY && bounds.fRight < topLeft->fX) { 228 if (bounds.fBottom == topLeft->fY && bounds.fRight < topLeft->fX) {
240 *done = false; 229 *done = false;
241 continue; 230 continue;
242 } 231 }
243 contour->topSortableSegment(*topLeft, &bestXY, &topStart); 232 contour->topSortableSegment(*topLeft, &bestXY, &topStart);
244 if (!contour->done()) { 233 if (!contour->done()) {
245 *done = false; 234 *done = false;
246 } 235 }
247 } 236 }
248 if (!topStart) { 237 if (!topStart) {
249 return NULL; 238 return NULL;
250 } 239 }
251 *topLeft = bestXY; 240 *topLeft = bestXY;
252 result = topStart->findTop(index, endIndex, unsortable, onlySortable); 241 result = topStart->findTop(index, endIndex, unsortable);
242 if (!result) {
243 if (lastTopStart == topStart && lastIndex == *index && lastEndIndex == *endIndex) {
244 *done = true;
245 return NULL;
246 }
247 lastTopStart = topStart;
248 lastIndex = *index;
249 lastEndIndex = *endIndex;
250 }
253 } while (!result); 251 } while (!result);
254 if (result) { 252 if (result) {
255 *unsortable = false; 253 *unsortable = false;
256 } 254 }
257 return result; 255 return result;
258 } 256 }
259 257
260 static int rightAngleWinding(const SkTArray<SkOpContour*, true>& contourList, 258 static int rightAngleWinding(const SkTArray<SkOpContour*, true>& contourList,
261 SkOpSegment** current, int* index, int* endIndex, d ouble* tHit, 259 SkOpSegment** current, int* index, int* endIndex, d ouble* tHit,
262 SkScalar* hitDx, bool* tryAgain, bool opp) { 260 SkScalar* hitDx, bool* tryAgain, bool opp) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexP tr, 294 SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexP tr,
297 int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done) { 295 int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done) {
298 SkOpSegment* current = findSortableTop(contourList, indexPtr, endIndexPtr, t opLeft, unsortable, 296 SkOpSegment* current = findSortableTop(contourList, indexPtr, endIndexPtr, t opLeft, unsortable,
299 done, true); 297 done, true);
300 if (!current) { 298 if (!current) {
301 return NULL; 299 return NULL;
302 } 300 }
303 const int index = *indexPtr; 301 const int index = *indexPtr;
304 const int endIndex = *endIndexPtr; 302 const int endIndex = *endIndexPtr;
305 if (*firstContour) { 303 if (*firstContour) {
306 current->initWinding(index, endIndex); 304 current->initWinding(index, endIndex, angleIncludeType);
307 *firstContour = false; 305 *firstContour = false;
308 return current; 306 return current;
309 } 307 }
310 int minIndex = SkMin32(index, endIndex); 308 int minIndex = SkMin32(index, endIndex);
311 int sumWinding = current->windSum(minIndex); 309 int sumWinding = current->windSum(minIndex);
312 if (sumWinding != SK_MinS32) { 310 if (sumWinding != SK_MinS32) {
313 return current; 311 return current;
314 } 312 }
315 SkASSERT(current->windSum(SkMin32(index, endIndex)) == SK_MinS32); 313 SkASSERT(current->windSum(SkMin32(index, endIndex)) == SK_MinS32);
316 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; 314 const SkOpSpan& span = current->span(endIndex);
317 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; 315 if ((index < endIndex ? span.fFromAngleIndex : span.fToAngleIndex) < 0) {
318 sumWinding = current->computeSum(index, endIndex, angleIncludeType, &angles, &sorted); 316 current->addSimpleAngle(endIndex);
317 }
318 sumWinding = current->computeSum(index, endIndex, angleIncludeType);
319 if (sumWinding != SK_MinS32 && sumWinding != SK_NaN32) { 319 if (sumWinding != SK_MinS32 && sumWinding != SK_NaN32) {
320 return current; 320 return current;
321 } 321 }
322 int contourWinding; 322 int contourWinding;
323 int oppContourWinding = 0; 323 int oppContourWinding = 0;
324 // the simple upward projection of the unresolved points hit unsortable angl es 324 // the simple upward projection of the unresolved points hit unsortable angl es
325 // shoot rays at right angles to the segment to find its winding, ignoring a ngle cases 325 // shoot rays at right angles to the segment to find its winding, ignoring a ngle cases
326 bool tryAgain; 326 bool tryAgain;
327 double tHit; 327 double tHit;
328 SkScalar hitDx = 0; 328 SkScalar hitDx = 0;
(...skipping 15 matching lines...) Expand all
344 break; 344 break;
345 } 345 }
346 oppContourWinding = rightAngleWinding(contourList, &current, indexPtr, e ndIndexPtr, &tHit, 346 oppContourWinding = rightAngleWinding(contourList, &current, indexPtr, e ndIndexPtr, &tHit,
347 &hitOppDx, &tryAgain, true); 347 &hitOppDx, &tryAgain, true);
348 } while (tryAgain); 348 } while (tryAgain);
349 current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx, o ppContourWinding, 349 current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx, o ppContourWinding,
350 hitOppDx); 350 hitOppDx);
351 return current; 351 return current;
352 } 352 }
353 353
354 static bool calcAngles(SkTArray<SkOpContour*, true>* contourList) {
355 int contourCount = (*contourList).count();
356 for (int cTest = 0; cTest < contourCount; ++cTest) {
357 SkOpContour* contour = (*contourList)[cTest];
358 if (!contour->calcAngles()) {
359 return false;
360 }
361 }
362 return true;
363 }
364
365 static void checkDuplicates(SkTArray<SkOpContour*, true>* contourList) {
366 int contourCount = (*contourList).count();
367 for (int cTest = 0; cTest < contourCount; ++cTest) {
368 SkOpContour* contour = (*contourList)[cTest];
369 contour->checkDuplicates();
370 }
371 }
372
354 static void checkEnds(SkTArray<SkOpContour*, true>* contourList) { 373 static void checkEnds(SkTArray<SkOpContour*, true>* contourList) {
355 // it's hard to determine if the end of a cubic or conic nearly intersects a nother curve. 374 // it's hard to determine if the end of a cubic or conic nearly intersects a nother curve.
356 // instead, look to see if the connecting curve intersected at that same end . 375 // instead, look to see if the connecting curve intersected at that same end .
357 int contourCount = (*contourList).count(); 376 int contourCount = (*contourList).count();
358 for (int cTest = 0; cTest < contourCount; ++cTest) { 377 for (int cTest = 0; cTest < contourCount; ++cTest) {
359 SkOpContour* contour = (*contourList)[cTest]; 378 SkOpContour* contour = (*contourList)[cTest];
360 contour->checkEnds(); 379 contour->checkEnds();
361 } 380 }
362 } 381 }
363 382
383 static void checkMultiples(SkTArray<SkOpContour*, true>* contourList) {
384 // it's hard to determine if the end of a cubic or conic nearly intersects a nother curve.
385 // instead, look to see if the connecting curve intersected at that same end .
386 int contourCount = (*contourList).count();
387 for (int cTest = 0; cTest < contourCount; ++cTest) {
388 SkOpContour* contour = (*contourList)[cTest];
389 contour->checkMultiples();
390 }
391 }
392
393 // A small interval of a pair of curves may collapse to lines for each, triggeri ng coincidence
394 static void checkSmall(SkTArray<SkOpContour*, true>* contourList) {
395 int contourCount = (*contourList).count();
396 for (int cTest = 0; cTest < contourCount; ++cTest) {
397 SkOpContour* contour = (*contourList)[cTest];
398 contour->checkSmall();
399 }
400 }
401
364 // A tiny interval may indicate an undiscovered coincidence. Find and fix. 402 // A tiny interval may indicate an undiscovered coincidence. Find and fix.
365 static void checkTiny(SkTArray<SkOpContour*, true>* contourList) { 403 static void checkTiny(SkTArray<SkOpContour*, true>* contourList) {
366 int contourCount = (*contourList).count(); 404 int contourCount = (*contourList).count();
367 for (int cTest = 0; cTest < contourCount; ++cTest) { 405 for (int cTest = 0; cTest < contourCount; ++cTest) {
368 SkOpContour* contour = (*contourList)[cTest]; 406 SkOpContour* contour = (*contourList)[cTest];
369 contour->checkTiny(); 407 contour->checkTiny();
370 } 408 }
371 } 409 }
372 410
373 static void fixOtherTIndex(SkTArray<SkOpContour*, true>* contourList) { 411 static void fixOtherTIndex(SkTArray<SkOpContour*, true>* contourList) {
374 int contourCount = (*contourList).count(); 412 int contourCount = (*contourList).count();
375 for (int cTest = 0; cTest < contourCount; ++cTest) { 413 for (int cTest = 0; cTest < contourCount; ++cTest) {
376 SkOpContour* contour = (*contourList)[cTest]; 414 SkOpContour* contour = (*contourList)[cTest];
377 contour->fixOtherTIndex(); 415 contour->fixOtherTIndex();
378 } 416 }
379 } 417 }
380 418
381 static void joinCoincidence(SkTArray<SkOpContour*, true>* contourList) { 419 static void joinCoincidence(SkTArray<SkOpContour*, true>* contourList) {
382 int contourCount = (*contourList).count(); 420 int contourCount = (*contourList).count();
383 for (int cTest = 0; cTest < contourCount; ++cTest) { 421 for (int cTest = 0; cTest < contourCount; ++cTest) {
384 SkOpContour* contour = (*contourList)[cTest]; 422 SkOpContour* contour = (*contourList)[cTest];
385 contour->joinCoincidence(); 423 contour->joinCoincidence();
386 } 424 }
387 } 425 }
388 426
427 static void sortAngles(SkTArray<SkOpContour*, true>* contourList) {
428 int contourCount = (*contourList).count();
429 for (int cTest = 0; cTest < contourCount; ++cTest) {
430 SkOpContour* contour = (*contourList)[cTest];
431 contour->sortAngles();
432 }
433 }
434
389 static void sortSegments(SkTArray<SkOpContour*, true>* contourList) { 435 static void sortSegments(SkTArray<SkOpContour*, true>* contourList) {
390 int contourCount = (*contourList).count(); 436 int contourCount = (*contourList).count();
391 for (int cTest = 0; cTest < contourCount; ++cTest) { 437 for (int cTest = 0; cTest < contourCount; ++cTest) {
392 SkOpContour* contour = (*contourList)[cTest]; 438 SkOpContour* contour = (*contourList)[cTest];
393 contour->sortSegments(); 439 contour->sortSegments();
394 } 440 }
395 } 441 }
396 442
397 void MakeContourList(SkTArray<SkOpContour>& contours, SkTArray<SkOpContour*, tru e>& list, 443 void MakeContourList(SkTArray<SkOpContour>& contours, SkTArray<SkOpContour*, tru e>& list,
398 bool evenOdd, bool oppEvenOdd) { 444 bool evenOdd, bool oppEvenOdd) {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 } 652 }
607 } while (rIndex < count); 653 } while (rIndex < count);
608 #if DEBUG_ASSEMBLE 654 #if DEBUG_ASSEMBLE
609 for (rIndex = 0; rIndex < count; ++rIndex) { 655 for (rIndex = 0; rIndex < count; ++rIndex) {
610 SkASSERT(sLink[rIndex] == SK_MaxS32); 656 SkASSERT(sLink[rIndex] == SK_MaxS32);
611 SkASSERT(eLink[rIndex] == SK_MaxS32); 657 SkASSERT(eLink[rIndex] == SK_MaxS32);
612 } 658 }
613 #endif 659 #endif
614 } 660 }
615 661
616 void HandleCoincidence(SkTArray<SkOpContour*, true>* contourList, int total) { 662 bool HandleCoincidence(SkTArray<SkOpContour*, true>* contourList, int total) {
617 #if DEBUG_SHOW_WINDING 663 #if DEBUG_SHOW_WINDING
618 SkOpContour::debugShowWindingValues(contourList); 664 SkOpContour::debugShowWindingValues(contourList);
619 #endif 665 #endif
620 CoincidenceCheck(contourList, total); 666 CoincidenceCheck(contourList, total);
621 #if DEBUG_SHOW_WINDING 667 #if DEBUG_SHOW_WINDING
622 SkOpContour::debugShowWindingValues(contourList); 668 SkOpContour::debugShowWindingValues(contourList);
623 #endif 669 #endif
624 fixOtherTIndex(contourList); 670 fixOtherTIndex(contourList);
625 checkEnds(contourList); 671 checkEnds(contourList);
672 checkMultiples(contourList);
673 checkDuplicates(contourList);
626 checkTiny(contourList); 674 checkTiny(contourList);
675 checkSmall(contourList);
627 joinCoincidence(contourList); 676 joinCoincidence(contourList);
628 sortSegments(contourList); 677 sortSegments(contourList);
678 if (!calcAngles(contourList)) {
679 return false;
680 }
681 sortAngles(contourList);
629 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY 682 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY
630 DebugShowActiveSpans(*contourList); 683 DebugShowActiveSpans(*contourList);
631 #endif 684 #endif
685 return true;
632 } 686 }
OLDNEW
« no previous file with comments | « src/pathops/SkPathOpsCommon.h ('k') | src/pathops/SkPathOpsCubic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698