OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "SkPathWriter.h" | 9 #include "SkPathWriter.h" |
10 #include "SkTSort.h" | 10 #include "SkTSort.h" |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 if (count > 0) { | 167 if (count > 0) { |
168 SkDebugf("%s count=%d\n", __FUNCTION__, count); | 168 SkDebugf("%s count=%d\n", __FUNCTION__, count); |
169 } | 169 } |
170 #endif | 170 #endif |
171 for (int index = 0; index < count; ++index) { | 171 for (int index = 0; index < count; ++index) { |
172 SkCoincidence& coincidence = fPartialCoincidences[index]; | 172 SkCoincidence& coincidence = fPartialCoincidences[index]; |
173 calcCommonCoincidentWinding(coincidence); | 173 calcCommonCoincidentWinding(coincidence); |
174 } | 174 } |
175 } | 175 } |
176 | 176 |
| 177 void SkOpContour::joinCoincidence(const SkTArray<SkCoincidence, true>& coinciden
ces, bool partial) { |
| 178 int count = coincidences.count(); |
| 179 #if DEBUG_CONCIDENT |
| 180 if (count > 0) { |
| 181 SkDebugf("%s count=%d\n", __FUNCTION__, count); |
| 182 } |
| 183 #endif |
| 184 // look for a lineup where the partial implies another adjoining coincidence |
| 185 for (int index = 0; index < count; ++index) { |
| 186 const SkCoincidence& coincidence = coincidences[index]; |
| 187 int thisIndex = coincidence.fSegments[0]; |
| 188 SkOpSegment& thisOne = fSegments[thisIndex]; |
| 189 SkOpContour* otherContour = coincidence.fOther; |
| 190 int otherIndex = coincidence.fSegments[1]; |
| 191 SkOpSegment& other = otherContour->fSegments[otherIndex]; |
| 192 double startT = coincidence.fTs[0][0]; |
| 193 double endT = coincidence.fTs[0][1]; |
| 194 if (startT == endT) { // this can happen in very large compares |
| 195 continue; |
| 196 } |
| 197 double oStartT = coincidence.fTs[1][0]; |
| 198 double oEndT = coincidence.fTs[1][1]; |
| 199 if (oStartT == oEndT) { |
| 200 continue; |
| 201 } |
| 202 bool swapStart = startT > endT; |
| 203 bool swapOther = oStartT > oEndT; |
| 204 if (swapStart) { |
| 205 SkTSwap<double>(startT, endT); |
| 206 SkTSwap<double>(oStartT, oEndT); |
| 207 } |
| 208 bool cancel = swapOther != swapStart; |
| 209 int step = swapStart ? -1 : 1; |
| 210 int oStep = swapOther ? -1 : 1; |
| 211 double oMatchStart = cancel ? oEndT : oStartT; |
| 212 if (partial ? startT != 0 || oMatchStart != 0 : (startT == 0) != (oMatch
Start == 0)) { |
| 213 bool added = false; |
| 214 if (oMatchStart != 0) { |
| 215 added = thisOne.joinCoincidence(false, &other, oMatchStart, oSte
p, cancel); |
| 216 } |
| 217 if (startT != 0 && !added) { |
| 218 (void) other.joinCoincidence(cancel, &thisOne, startT, step, can
cel); |
| 219 } |
| 220 } |
| 221 double oMatchEnd = cancel ? oStartT : oEndT; |
| 222 if (partial ? endT != 1 || oMatchEnd != 1 : (endT == 1) != (oMatchEnd ==
1)) { |
| 223 bool added = false; |
| 224 if (oMatchEnd != 1) { |
| 225 added = thisOne.joinCoincidence(true, &other, oMatchEnd, -oStep,
cancel); |
| 226 } |
| 227 if (endT != 1 && !added) { |
| 228 (void) other.joinCoincidence(!cancel, &thisOne, endT, -step, can
cel); |
| 229 } |
| 230 } |
| 231 } |
| 232 } |
| 233 |
177 void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence)
{ | 234 void SkOpContour::calcCommonCoincidentWinding(const SkCoincidence& coincidence)
{ |
178 int thisIndex = coincidence.fSegments[0]; | 235 int thisIndex = coincidence.fSegments[0]; |
179 SkOpSegment& thisOne = fSegments[thisIndex]; | 236 SkOpSegment& thisOne = fSegments[thisIndex]; |
180 if (thisOne.done()) { | 237 if (thisOne.done()) { |
181 return; | 238 return; |
182 } | 239 } |
183 SkOpContour* otherContour = coincidence.fOther; | 240 SkOpContour* otherContour = coincidence.fOther; |
184 int otherIndex = coincidence.fSegments[1]; | 241 int otherIndex = coincidence.fSegments[1]; |
185 SkOpSegment& other = otherContour->fSegments[otherIndex]; | 242 SkOpSegment& other = otherContour->fSegments[otherIndex]; |
186 if (other.done()) { | 243 if (other.done()) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 SkDebugf("%s empty contour\n", __FUNCTION__); | 382 SkDebugf("%s empty contour\n", __FUNCTION__); |
326 SkASSERT(0); | 383 SkASSERT(0); |
327 // FIXME: delete empty contour? | 384 // FIXME: delete empty contour? |
328 return; | 385 return; |
329 } | 386 } |
330 fBounds = fSegments.front().bounds(); | 387 fBounds = fSegments.front().bounds(); |
331 for (int index = 1; index < count; ++index) { | 388 for (int index = 1; index < count; ++index) { |
332 fBounds.add(fSegments[index].bounds()); | 389 fBounds.add(fSegments[index].bounds()); |
333 } | 390 } |
334 } | 391 } |
OLD | NEW |