| 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 "SkOpEdgeBuilder.h" | 7 #include "SkOpEdgeBuilder.h" |
| 8 #include "SkPathOpsCommon.h" | 8 #include "SkPathOpsCommon.h" |
| 9 #include "SkPathWriter.h" | 9 #include "SkPathWriter.h" |
| 10 #include "SkTSort.h" | 10 #include "SkTSort.h" |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 if (!contour->done()) { | 243 if (!contour->done()) { |
| 244 *done = false; | 244 *done = false; |
| 245 } | 245 } |
| 246 } | 246 } |
| 247 if (!topStart) { | 247 if (!topStart) { |
| 248 return NULL; | 248 return NULL; |
| 249 } | 249 } |
| 250 *topLeft = bestXY; | 250 *topLeft = bestXY; |
| 251 result = topStart->findTop(index, endIndex, unsortable, onlySortable); | 251 result = topStart->findTop(index, endIndex, unsortable, onlySortable); |
| 252 } while (!result); | 252 } while (!result); |
| 253 if (result) { |
| 254 *unsortable = false; |
| 255 } |
| 253 return result; | 256 return result; |
| 254 } | 257 } |
| 255 | 258 |
| 256 static int rightAngleWinding(const SkTArray<SkOpContour*, true>& contourList, | 259 static int rightAngleWinding(const SkTArray<SkOpContour*, true>& contourList, |
| 257 SkOpSegment** current, int* index, int* endIndex, d
ouble* tHit, | 260 SkOpSegment** current, int* index, int* endIndex, d
ouble* tHit, |
| 258 SkScalar* hitDx, bool* tryAgain, bool opp) { | 261 SkScalar* hitDx, bool* tryAgain, bool opp) { |
| 259 double test = 0.9; | 262 double test = 0.9; |
| 260 int contourWinding; | 263 int contourWinding; |
| 261 do { | 264 do { |
| 262 contourWinding = contourRangeCheckY(contourList, current, index, endInde
x, tHit, hitDx, | 265 contourWinding = contourRangeCheckY(contourList, current, index, endInde
x, tHit, hitDx, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 281 if (contour->done()) { | 284 if (contour->done()) { |
| 282 continue; | 285 continue; |
| 283 } | 286 } |
| 284 *current = contour->nonVerticalSegment(index, endIndex); | 287 *current = contour->nonVerticalSegment(index, endIndex); |
| 285 if (*current) { | 288 if (*current) { |
| 286 return; | 289 return; |
| 287 } | 290 } |
| 288 } | 291 } |
| 289 } | 292 } |
| 290 | 293 |
| 291 SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList, bo
ol* firstContour, | 294 SkOpSegment* FindSortableTop(const SkTArray<SkOpContour*, true>& contourList, |
| 292 int* indexPtr, int* endIndexPtr, SkPoint* topLeft,
bool* unsortable, | 295 SkOpAngle::IncludeType angleIncludeType, bool* firstContour, int* indexP
tr, |
| 293 bool* done, bool binary) { | 296 int* endIndexPtr, SkPoint* topLeft, bool* unsortable, bool* done) { |
| 294 SkOpSegment* current = findSortableTop(contourList, indexPtr, endIndexPtr, t
opLeft, unsortable, | 297 SkOpSegment* current = findSortableTop(contourList, indexPtr, endIndexPtr, t
opLeft, unsortable, |
| 295 done, true); | 298 done, true); |
| 296 if (!current) { | 299 if (!current) { |
| 297 return NULL; | 300 return NULL; |
| 298 } | 301 } |
| 299 const int index = *indexPtr; | 302 const int index = *indexPtr; |
| 300 const int endIndex = *endIndexPtr; | 303 const int endIndex = *endIndexPtr; |
| 301 if (*firstContour) { | 304 if (*firstContour) { |
| 302 current->initWinding(index, endIndex); | 305 current->initWinding(index, endIndex); |
| 303 *firstContour = false; | 306 *firstContour = false; |
| 304 return current; | 307 return current; |
| 305 } | 308 } |
| 306 int minIndex = SkMin32(index, endIndex); | 309 int minIndex = SkMin32(index, endIndex); |
| 307 int sumWinding = current->windSum(minIndex); | 310 int sumWinding = current->windSum(minIndex); |
| 308 if (sumWinding != SK_MinS32) { | 311 if (sumWinding != SK_MinS32) { |
| 309 return current; | 312 return current; |
| 310 } | 313 } |
| 311 sumWinding = current->computeSum(index, endIndex, binary); | 314 SkASSERT(current->windSum(SkMin32(index, endIndex)) == SK_MinS32); |
| 312 if (sumWinding != SK_MinS32) { | 315 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
| 316 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
| 317 sumWinding = current->computeSum(index, endIndex, angleIncludeType, &angles,
&sorted); |
| 318 if (sumWinding != SK_MinS32 && sumWinding != SK_NaN32) { |
| 313 return current; | 319 return current; |
| 314 } | 320 } |
| 315 int contourWinding; | 321 int contourWinding; |
| 316 int oppContourWinding = 0; | 322 int oppContourWinding = 0; |
| 317 // the simple upward projection of the unresolved points hit unsortable angl
es | 323 // the simple upward projection of the unresolved points hit unsortable angl
es |
| 318 // shoot rays at right angles to the segment to find its winding, ignoring a
ngle cases | 324 // shoot rays at right angles to the segment to find its winding, ignoring a
ngle cases |
| 319 bool tryAgain; | 325 bool tryAgain; |
| 320 double tHit; | 326 double tHit; |
| 321 SkScalar hitDx = 0; | 327 SkScalar hitDx = 0; |
| 322 SkScalar hitOppDx = 0; | 328 SkScalar hitOppDx = 0; |
| 323 do { | 329 do { |
| 324 // if current is vertical, find another candidate which is not | 330 // if current is vertical, find another candidate which is not |
| 325 // if only remaining candidates are vertical, then they can be marked do
ne | 331 // if only remaining candidates are vertical, then they can be marked do
ne |
| 326 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >=
0); | 332 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >=
0); |
| 327 skipVertical(contourList, ¤t, indexPtr, endIndexPtr); | 333 skipVertical(contourList, ¤t, indexPtr, endIndexPtr); |
| 328 | 334 |
| 329 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >=
0); | 335 SkASSERT(*indexPtr != *endIndexPtr && *indexPtr >= 0 && *endIndexPtr >=
0); |
| 330 tryAgain = false; | 336 tryAgain = false; |
| 331 contourWinding = rightAngleWinding(contourList, ¤t, indexPtr, endI
ndexPtr, &tHit, | 337 contourWinding = rightAngleWinding(contourList, ¤t, indexPtr, endI
ndexPtr, &tHit, |
| 332 &hitDx, &tryAgain, false); | 338 &hitDx, &tryAgain, false); |
| 333 if (tryAgain) { | 339 if (tryAgain) { |
| 334 continue; | 340 continue; |
| 335 } | 341 } |
| 336 if (!binary) { | 342 if (angleIncludeType < SkOpAngle::kBinarySingle) { |
| 337 break; | 343 break; |
| 338 } | 344 } |
| 339 oppContourWinding = rightAngleWinding(contourList, ¤t, indexPtr, e
ndIndexPtr, &tHit, | 345 oppContourWinding = rightAngleWinding(contourList, ¤t, indexPtr, e
ndIndexPtr, &tHit, |
| 340 &hitOppDx, &tryAgain, true); | 346 &hitOppDx, &tryAgain, true); |
| 341 } while (tryAgain); | 347 } while (tryAgain); |
| 342 current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx, o
ppContourWinding, | 348 current->initWinding(*indexPtr, *endIndexPtr, tHit, contourWinding, hitDx, o
ppContourWinding, |
| 343 hitOppDx); | 349 hitOppDx); |
| 344 return current; | 350 return current; |
| 345 } | 351 } |
| 346 | 352 |
| 347 void CheckEnds(SkTArray<SkOpContour*, true>* contourList) { | 353 void CheckEnds(SkTArray<SkOpContour*, true>* contourList) { |
| 348 // it's hard to determine if the end of a cubic or conic nearly intersects a
nother curve. | 354 // it's hard to determine if the end of a cubic or conic nearly intersects a
nother curve. |
| 349 // instead, look to see if the connecting curve intersected at that same end
. | 355 // instead, look to see if the connecting curve intersected at that same end
. |
| 350 int contourCount = (*contourList).count(); | 356 int contourCount = (*contourList).count(); |
| 351 for (int cTest = 0; cTest < contourCount; ++cTest) { | 357 for (int cTest = 0; cTest < contourCount; ++cTest) { |
| 352 SkOpContour* contour = (*contourList)[cTest]; | 358 SkOpContour* contour = (*contourList)[cTest]; |
| 353 contour->checkEnds(); | 359 contour->checkEnds(); |
| 354 } | 360 } |
| 355 } | 361 } |
| 356 | 362 |
| 363 // A tiny interval may indicate an undiscovered coincidence. Find and fix. |
| 364 void CheckTiny(SkTArray<SkOpContour*, true>* contourList) { |
| 365 int contourCount = (*contourList).count(); |
| 366 for (int cTest = 0; cTest < contourCount; ++cTest) { |
| 367 SkOpContour* contour = (*contourList)[cTest]; |
| 368 contour->checkTiny(); |
| 369 } |
| 370 } |
| 371 |
| 357 void FixOtherTIndex(SkTArray<SkOpContour*, true>* contourList) { | 372 void FixOtherTIndex(SkTArray<SkOpContour*, true>* contourList) { |
| 358 int contourCount = (*contourList).count(); | 373 int contourCount = (*contourList).count(); |
| 359 for (int cTest = 0; cTest < contourCount; ++cTest) { | 374 for (int cTest = 0; cTest < contourCount; ++cTest) { |
| 360 SkOpContour* contour = (*contourList)[cTest]; | 375 SkOpContour* contour = (*contourList)[cTest]; |
| 361 contour->fixOtherTIndex(); | 376 contour->fixOtherTIndex(); |
| 362 } | 377 } |
| 363 } | 378 } |
| 364 | 379 |
| 365 void SortSegments(SkTArray<SkOpContour*, true>* contourList) { | 380 void SortSegments(SkTArray<SkOpContour*, true>* contourList) { |
| 366 int contourCount = (*contourList).count(); | 381 int contourCount = (*contourList).count(); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 } | 600 } |
| 586 } | 601 } |
| 587 } while (rIndex < count); | 602 } while (rIndex < count); |
| 588 #if DEBUG_ASSEMBLE | 603 #if DEBUG_ASSEMBLE |
| 589 for (rIndex = 0; rIndex < count; ++rIndex) { | 604 for (rIndex = 0; rIndex < count; ++rIndex) { |
| 590 SkASSERT(sLink[rIndex] == SK_MaxS32); | 605 SkASSERT(sLink[rIndex] == SK_MaxS32); |
| 591 SkASSERT(eLink[rIndex] == SK_MaxS32); | 606 SkASSERT(eLink[rIndex] == SK_MaxS32); |
| 592 } | 607 } |
| 593 #endif | 608 #endif |
| 594 } | 609 } |
| OLD | NEW |