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 | 7 |
8 #include "SkIntersections.h" | 8 #include "SkIntersections.h" |
9 #include "SkPathOpsCubic.h" | 9 #include "SkPathOpsCubic.h" |
10 #include "SkPathOpsLine.h" | 10 #include "SkPathOpsLine.h" |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 } | 419 } |
420 SkDPoint pt[2]; | 420 SkDPoint pt[2]; |
421 if (closeStart(c1, 0, *this, pt[0]) && closeStart(c2, 1, *this, pt[1]) | 421 if (closeStart(c1, 0, *this, pt[0]) && closeStart(c2, 1, *this, pt[1]) |
422 && pt[0].approximatelyEqual(pt[1])) { | 422 && pt[0].approximatelyEqual(pt[1])) { |
423 removeOne(1); | 423 removeOne(1); |
424 } | 424 } |
425 if (closeEnd(c1, 0, *this, pt[0]) && closeEnd(c2, 1, *this, pt[1]) | 425 if (closeEnd(c1, 0, *this, pt[0]) && closeEnd(c2, 1, *this, pt[1]) |
426 && pt[0].approximatelyEqual(pt[1])) { | 426 && pt[0].approximatelyEqual(pt[1])) { |
427 removeOne(used() - 2); | 427 removeOne(used() - 2); |
428 } | 428 } |
| 429 // vet the pairs of t values to see if the mid value is also on the curve. I
f so, mark |
| 430 // the span as coincident |
| 431 if (fUsed >= 2 && !coincidentUsed()) { |
| 432 int last = fUsed - 1; |
| 433 int match = 0; |
| 434 for (int index = 0; index < last; ++index) { |
| 435 double mid1 = (fT[0][index] + fT[0][index + 1]) / 2; |
| 436 double mid2 = (fT[1][index] + fT[1][index + 1]) / 2; |
| 437 pt[0] = c1.xyAtT(mid1); |
| 438 pt[1] = c2.xyAtT(mid2); |
| 439 if (pt[0].approximatelyEqual(pt[1])) { |
| 440 match |= 1 << index; |
| 441 } |
| 442 } |
| 443 if (match) { |
| 444 if (((match + 1) & match) != 0) { |
| 445 SkDebugf("%s coincident hole\n", __FUNCTION__); |
| 446 } |
| 447 // for now, assume that everything from start to finish is coinciden
t |
| 448 if (fUsed > 2) { |
| 449 fPt[1] = fPt[last]; |
| 450 fT[0][1] = fT[0][last]; |
| 451 fT[1][1] = fT[1][last]; |
| 452 fIsCoincident[0] = 0x03; |
| 453 fIsCoincident[1] = 0x03; |
| 454 fUsed = 2; |
| 455 } |
| 456 } |
| 457 } |
429 return fUsed; | 458 return fUsed; |
430 } | 459 } |
431 | 460 |
432 // Up promote the quad to a cubic. | 461 // Up promote the quad to a cubic. |
433 // OPTIMIZATION If this is a common use case, optimize by duplicating | 462 // OPTIMIZATION If this is a common use case, optimize by duplicating |
434 // the intersect 3 loop to avoid the promotion / demotion code | 463 // the intersect 3 loop to avoid the promotion / demotion code |
435 int SkIntersections::intersect(const SkDCubic& cubic, const SkDQuad& quad) { | 464 int SkIntersections::intersect(const SkDCubic& cubic, const SkDQuad& quad) { |
436 SkDCubic up = quad.toCubic(); | 465 SkDCubic up = quad.toCubic(); |
437 (void) intersect(cubic, up); | 466 (void) intersect(cubic, up); |
438 return used(); | 467 return used(); |
(...skipping 13 matching lines...) Expand all Loading... |
452 } | 481 } |
453 (void) intersect(c, c); | 482 (void) intersect(c, c); |
454 if (used() > 0) { | 483 if (used() > 0) { |
455 SkASSERT(used() == 1); | 484 SkASSERT(used() == 1); |
456 if (fT[0][0] > fT[1][0]) { | 485 if (fT[0][0] > fT[1][0]) { |
457 swapPts(); | 486 swapPts(); |
458 } | 487 } |
459 } | 488 } |
460 return used(); | 489 return used(); |
461 } | 490 } |
OLD | NEW |