| 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 |