OLD | NEW |
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 "SkPathOpsBounds.h" | 8 #include "SkPathOpsBounds.h" |
9 | 9 |
10 #if DEBUG_ADD_INTERSECTING_TS | 10 #if DEBUG_ADD_INTERSECTING_TS |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 const SkIntersectionHelper& , const SkIntersections& ) { | 169 const SkIntersectionHelper& , const SkIntersections& ) { |
170 } | 170 } |
171 | 171 |
172 static void debugShowCubicIntersection(int , const SkIntersectionHelper& , | 172 static void debugShowCubicIntersection(int , const SkIntersectionHelper& , |
173 const SkIntersections& ) { | 173 const SkIntersections& ) { |
174 } | 174 } |
175 #endif | 175 #endif |
176 | 176 |
177 bool AddIntersectTs(SkOpContour* test, SkOpContour* next) { | 177 bool AddIntersectTs(SkOpContour* test, SkOpContour* next) { |
178 if (test != next) { | 178 if (test != next) { |
179 if (test->bounds().fBottom < next->bounds().fTop) { | 179 if (AlmostLessUlps(test->bounds().fBottom, next->bounds().fTop)) { |
180 return false; | 180 return false; |
181 } | 181 } |
| 182 // OPTIMIZATION: outset contour bounds a smidgen instead? |
182 if (!SkPathOpsBounds::Intersects(test->bounds(), next->bounds())) { | 183 if (!SkPathOpsBounds::Intersects(test->bounds(), next->bounds())) { |
183 return true; | 184 return true; |
184 } | 185 } |
185 } | 186 } |
186 SkIntersectionHelper wt; | 187 SkIntersectionHelper wt; |
187 wt.init(test); | 188 wt.init(test); |
188 bool foundCommonContour = test == next; | 189 bool foundCommonContour = test == next; |
189 do { | 190 do { |
190 SkIntersectionHelper wn; | 191 SkIntersectionHelper wn; |
191 wn.init(next); | 192 wn.init(next); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 continue; | 367 continue; |
367 } | 368 } |
368 if (wn.segmentType() >= SkIntersectionHelper::kQuad_Segment | 369 if (wn.segmentType() >= SkIntersectionHelper::kQuad_Segment |
369 && wt.segmentType() >= SkIntersectionHelper::kQuad_Segme
nt | 370 && wt.segmentType() >= SkIntersectionHelper::kQuad_Segme
nt |
370 && ts.isCoincident(0)) { | 371 && ts.isCoincident(0)) { |
371 SkASSERT(ts.coincidentUsed() == 2); | 372 SkASSERT(ts.coincidentUsed() == 2); |
372 wt.addCoincident(wn, ts, swap); | 373 wt.addCoincident(wn, ts, swap); |
373 continue; | 374 continue; |
374 } | 375 } |
375 } | 376 } |
| 377 if (pts >= 2) { |
| 378 for (int pt = 0; pt < pts - 1; ++pt) { |
| 379 const SkDPoint& point = ts.pt(pt); |
| 380 const SkDPoint& next = ts.pt(pt + 1); |
| 381 if (wt.isNear(ts[swap][pt], ts[swap][pt + 1], point, next) |
| 382 && wn.isNear(ts[!swap][pt], ts[!swap][pt + 1], point
, next)) { |
| 383 wt.addPartialCoincident(wn, ts, pt, swap); |
| 384 } |
| 385 } |
| 386 } |
376 for (int pt = 0; pt < pts; ++pt) { | 387 for (int pt = 0; pt < pts; ++pt) { |
377 SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1); | 388 SkASSERT(ts[0][pt] >= 0 && ts[0][pt] <= 1); |
378 SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1); | 389 SkASSERT(ts[1][pt] >= 0 && ts[1][pt] <= 1); |
379 SkPoint point = ts.pt(pt).asSkPoint(); | 390 SkPoint point = ts.pt(pt).asSkPoint(); |
380 int testTAt = wt.addT(wn, point, ts[swap][pt]); | 391 int testTAt = wt.addT(wn, point, ts[swap][pt], swap && ts.isNear
(pt)); |
381 int nextTAt = wn.addT(wt, point, ts[!swap][pt]); | 392 int nextTAt = wn.addT(wt, point, ts[!swap][pt], !swap && ts.isNe
ar(pt)); |
382 wt.addOtherT(testTAt, ts[!swap][pt], nextTAt); | 393 wt.addOtherT(testTAt, ts[!swap][pt], nextTAt); |
383 wn.addOtherT(nextTAt, ts[swap][pt], testTAt); | 394 wn.addOtherT(nextTAt, ts[swap][pt], testTAt); |
384 } | 395 } |
385 } while (wn.advance()); | 396 } while (wn.advance()); |
386 } while (wt.advance()); | 397 } while (wt.advance()); |
387 return true; | 398 return true; |
388 } | 399 } |
389 | 400 |
390 void AddSelfIntersectTs(SkOpContour* test) { | 401 void AddSelfIntersectTs(SkOpContour* test) { |
391 SkIntersectionHelper wt; | 402 SkIntersectionHelper wt; |
392 wt.init(test); | 403 wt.init(test); |
393 do { | 404 do { |
394 if (wt.segmentType() != SkIntersectionHelper::kCubic_Segment) { | 405 if (wt.segmentType() != SkIntersectionHelper::kCubic_Segment) { |
395 continue; | 406 continue; |
396 } | 407 } |
397 SkIntersections ts; | 408 SkIntersections ts; |
398 int pts = ts.cubic(wt.pts()); | 409 int pts = ts.cubic(wt.pts()); |
399 debugShowCubicIntersection(pts, wt, ts); | 410 debugShowCubicIntersection(pts, wt, ts); |
400 if (!pts) { | 411 if (!pts) { |
401 continue; | 412 continue; |
402 } | 413 } |
403 SkASSERT(pts == 1); | 414 SkASSERT(pts == 1); |
404 SkASSERT(ts[0][0] >= 0 && ts[0][0] <= 1); | 415 SkASSERT(ts[0][0] >= 0 && ts[0][0] <= 1); |
405 SkASSERT(ts[1][0] >= 0 && ts[1][0] <= 1); | 416 SkASSERT(ts[1][0] >= 0 && ts[1][0] <= 1); |
406 SkPoint point = ts.pt(0).asSkPoint(); | 417 SkPoint point = ts.pt(0).asSkPoint(); |
407 int testTAt = wt.addSelfT(wt, point, ts[0][0]); | 418 int testTAt = wt.addSelfT(wt, point, ts[0][0]); |
408 int nextTAt = wt.addT(wt, point, ts[1][0]); | 419 int nextTAt = wt.addT(wt, point, ts[1][0], ts.isNear(0)); |
409 wt.addOtherT(testTAt, ts[1][0], nextTAt); | 420 wt.addOtherT(testTAt, ts[1][0], nextTAt); |
410 wt.addOtherT(nextTAt, ts[0][0], testTAt); | 421 wt.addOtherT(nextTAt, ts[0][0], testTAt); |
411 } while (wt.advance()); | 422 } while (wt.advance()); |
412 } | 423 } |
413 | 424 |
414 // resolve any coincident pairs found while intersecting, and | 425 // resolve any coincident pairs found while intersecting, and |
415 // see if coincidence is formed by clipping non-concident segments | 426 // see if coincidence is formed by clipping non-concident segments |
416 void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) { | 427 void CoincidenceCheck(SkTArray<SkOpContour*, true>* contourList, int total) { |
417 int contourCount = (*contourList).count(); | 428 int contourCount = (*contourList).count(); |
418 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { | 429 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { |
419 SkOpContour* contour = (*contourList)[cIndex]; | 430 SkOpContour* contour = (*contourList)[cIndex]; |
420 contour->addCoincidentPoints(); | 431 contour->addCoincidentPoints(); |
421 } | 432 } |
422 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { | 433 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { |
423 SkOpContour* contour = (*contourList)[cIndex]; | 434 SkOpContour* contour = (*contourList)[cIndex]; |
424 contour->calcCoincidentWinding(); | 435 contour->calcCoincidentWinding(); |
425 } | 436 } |
426 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { | 437 for (int cIndex = 0; cIndex < contourCount; ++cIndex) { |
427 SkOpContour* contour = (*contourList)[cIndex]; | 438 SkOpContour* contour = (*contourList)[cIndex]; |
428 contour->findTooCloseToCall(); | 439 contour->calcPartialCoincidentWinding(); |
429 } | 440 } |
430 } | 441 } |
OLD | NEW |