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 "SkIntersections.h" | 7 #include "SkIntersections.h" |
8 #include "SkOpContour.h" | 8 #include "SkOpContour.h" |
9 #include "SkOpSegment.h" | 9 #include "SkOpSegment.h" |
10 #include "SkPathWriter.h" | 10 #include "SkPathWriter.h" |
(...skipping 2276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2287 const SkOpSpan* endSpan = fTs.end() - 1; // last can't be small | 2287 const SkOpSpan* endSpan = fTs.end() - 1; // last can't be small |
2288 while (++thisSpan < endSpan) { | 2288 while (++thisSpan < endSpan) { |
2289 if (!thisSpan->fSmall) { | 2289 if (!thisSpan->fSmall) { |
2290 continue; | 2290 continue; |
2291 } | 2291 } |
2292 if (!thisSpan->fWindValue) { | 2292 if (!thisSpan->fWindValue) { |
2293 continue; | 2293 continue; |
2294 } | 2294 } |
2295 const SkOpSpan& firstSpan = this->firstSpan(*thisSpan); | 2295 const SkOpSpan& firstSpan = this->firstSpan(*thisSpan); |
2296 const SkOpSpan& lastSpan = this->lastSpan(*thisSpan); | 2296 const SkOpSpan& lastSpan = this->lastSpan(*thisSpan); |
| 2297 const SkOpSpan* nextSpan = &firstSpan + 1; |
2297 ptrdiff_t smallCount = &lastSpan - &firstSpan + 1; | 2298 ptrdiff_t smallCount = &lastSpan - &firstSpan + 1; |
2298 SkASSERT(1 <= smallCount && smallCount < count()); | 2299 SkASSERT(1 <= smallCount && smallCount < count()); |
2299 if (smallCount <= 1) { | 2300 if (smallCount <= 1 && !nextSpan->fSmall) { |
2300 SkASSERT(1 == smallCount); | 2301 SkASSERT(1 == smallCount); |
2301 checkSmallCoincidence(firstSpan, NULL); | 2302 checkSmallCoincidence(firstSpan, NULL); |
2302 continue; | 2303 continue; |
2303 } | 2304 } |
2304 // at this point, check for missing computed intersections | 2305 // at this point, check for missing computed intersections |
2305 const SkPoint& testPt = firstSpan.fPt; | 2306 const SkPoint& testPt = firstSpan.fPt; |
2306 thisSpan = &firstSpan - 1; | 2307 thisSpan = &firstSpan - 1; |
2307 SkOpSegment* other = NULL; | 2308 SkOpSegment* other = NULL; |
2308 while (++thisSpan <= &lastSpan) { | 2309 while (++thisSpan <= &lastSpan) { |
2309 other = thisSpan->fOther; | 2310 other = thisSpan->fOther; |
(...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3060 const SkOpSpan& span = fTs[index]; | 3061 const SkOpSpan& span = fTs[index]; |
3061 if (span.fOtherT == t && span.fOther == match) { | 3062 if (span.fOtherT == t && span.fOther == match) { |
3062 return index; | 3063 return index; |
3063 } | 3064 } |
3064 } | 3065 } |
3065 return -1; | 3066 return -1; |
3066 } | 3067 } |
3067 | 3068 |
3068 int SkOpSegment::findT(double t, const SkPoint& pt, const SkOpSegment* match) co
nst { | 3069 int SkOpSegment::findT(double t, const SkPoint& pt, const SkOpSegment* match) co
nst { |
3069 int count = this->count(); | 3070 int count = this->count(); |
| 3071 // prefer exact matches over approximate matches |
| 3072 for (int index = 0; index < count; ++index) { |
| 3073 const SkOpSpan& span = fTs[index]; |
| 3074 if (span.fT == t && span.fOther == match) { |
| 3075 return index; |
| 3076 } |
| 3077 } |
3070 for (int index = 0; index < count; ++index) { | 3078 for (int index = 0; index < count; ++index) { |
3071 const SkOpSpan& span = fTs[index]; | 3079 const SkOpSpan& span = fTs[index]; |
3072 if (approximately_equal_orderable(span.fT, t) && span.fOther == match) { | 3080 if (approximately_equal_orderable(span.fT, t) && span.fOther == match) { |
3073 return index; | 3081 return index; |
3074 } | 3082 } |
3075 } | 3083 } |
3076 // Usually, the pair of ts are an exact match. It's possible that the t valu
es have | 3084 // Usually, the pair of ts are an exact match. It's possible that the t valu
es have |
3077 // been adjusted to make multiple intersections align. In this rare case, lo
ok for a | 3085 // been adjusted to make multiple intersections align. In this rare case, lo
ok for a |
3078 // matching point / match pair instead. | 3086 // matching point / match pair instead. |
3079 for (int index = 0; index < count; ++index) { | 3087 for (int index = 0; index < count; ++index) { |
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3979 void SkOpSegment::pinT(const SkPoint& pt, double* t) { | 3987 void SkOpSegment::pinT(const SkPoint& pt, double* t) { |
3980 if (pt == fPts[0]) { | 3988 if (pt == fPts[0]) { |
3981 *t = 0; | 3989 *t = 0; |
3982 } | 3990 } |
3983 int count = SkPathOpsVerbToPoints(fVerb); | 3991 int count = SkPathOpsVerbToPoints(fVerb); |
3984 if (pt == fPts[count]) { | 3992 if (pt == fPts[count]) { |
3985 *t = 1; | 3993 *t = 1; |
3986 } | 3994 } |
3987 } | 3995 } |
3988 | 3996 |
| 3997 bool SkOpSegment::reversePoints(const SkPoint& p1, const SkPoint& p2) const { |
| 3998 SkASSERT(p1 != p2); |
| 3999 int spanCount = count(); |
| 4000 int p1IndexMin = -1; |
| 4001 int p2IndexMax = spanCount; |
| 4002 for (int index = 0; index < spanCount; ++index) { |
| 4003 const SkOpSpan& span = fTs[index]; |
| 4004 if (span.fPt == p1) { |
| 4005 if (p1IndexMin < 0) { |
| 4006 p1IndexMin = index; |
| 4007 } |
| 4008 } else if (span.fPt == p2) { |
| 4009 p2IndexMax = index; |
| 4010 } |
| 4011 } |
| 4012 return p1IndexMin > p2IndexMax; |
| 4013 } |
| 4014 |
3989 void SkOpSegment::setCoincidentRange(const SkPoint& startPt, const SkPoint& endP
t, | 4015 void SkOpSegment::setCoincidentRange(const SkPoint& startPt, const SkPoint& endP
t, |
3990 SkOpSegment* other) { | 4016 SkOpSegment* other) { |
3991 int count = this->count(); | 4017 int count = this->count(); |
3992 for (int index = 0; index < count; ++index) { | 4018 for (int index = 0; index < count; ++index) { |
3993 SkOpSpan &span = fTs[index]; | 4019 SkOpSpan &span = fTs[index]; |
3994 if ((startPt == span.fPt || endPt == span.fPt) && other == span.fOther)
{ | 4020 if ((startPt == span.fPt || endPt == span.fPt) && other == span.fOther)
{ |
3995 span.fCoincident = true; | 4021 span.fCoincident = true; |
3996 } | 4022 } |
3997 } | 4023 } |
3998 } | 4024 } |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4366 SkASSERT(span->fWindValue > 0 || span->fOppValue != 0); | 4392 SkASSERT(span->fWindValue > 0 || span->fOppValue != 0); |
4367 span->fWindValue = 0; | 4393 span->fWindValue = 0; |
4368 span->fOppValue = 0; | 4394 span->fOppValue = 0; |
4369 if (span->fTiny || span->fSmall) { | 4395 if (span->fTiny || span->fSmall) { |
4370 return; | 4396 return; |
4371 } | 4397 } |
4372 SkASSERT(!span->fDone); | 4398 SkASSERT(!span->fDone); |
4373 span->fDone = true; | 4399 span->fDone = true; |
4374 ++fDoneSpans; | 4400 ++fDoneSpans; |
4375 } | 4401 } |
OLD | NEW |