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 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 break; | 398 break; |
399 default: | 399 default: |
400 SkASSERT(0); | 400 SkASSERT(0); |
401 } | 401 } |
402 } | 402 } |
403 } | 403 } |
404 // return ePtr[SkPathOpsVerbToPoints(fVerb)]; | 404 // return ePtr[SkPathOpsVerbToPoints(fVerb)]; |
405 } | 405 } |
406 | 406 |
407 void SkOpSegment::addEndSpan(int endIndex) { | 407 void SkOpSegment::addEndSpan(int endIndex) { |
| 408 SkASSERT(span(endIndex).fT == 1 || (span(endIndex).fTiny |
| 409 && approximately_greater_than_one(span(endIndex).fT))); |
408 int spanCount = fTs.count(); | 410 int spanCount = fTs.count(); |
409 int startIndex = endIndex - 1; | 411 int startIndex = endIndex - 1; |
410 while (fTs[startIndex].fT == 1 || fTs[startIndex].fTiny) { | 412 while (fTs[startIndex].fT == 1 || fTs[startIndex].fTiny) { |
411 ++startIndex; | 413 --startIndex; |
412 SkASSERT(startIndex < spanCount - 1); | 414 SkASSERT(startIndex > 0); |
413 ++endIndex; | 415 --endIndex; |
414 } | 416 } |
415 SkOpAngle& angle = fAngles.push_back(); | 417 SkOpAngle& angle = fAngles.push_back(); |
416 angle.set(this, spanCount - 1, startIndex); | 418 angle.set(this, spanCount - 1, startIndex); |
417 #if DEBUG_ANGLE | 419 #if DEBUG_ANGLE |
418 debugCheckPointsEqualish(endIndex, spanCount); | 420 debugCheckPointsEqualish(endIndex, spanCount); |
419 #endif | 421 #endif |
420 setFromAngle(endIndex, &angle); | 422 setFromAngle(endIndex, &angle); |
421 } | 423 } |
422 | 424 |
423 void SkOpSegment::setFromAngle(int endIndex, SkOpAngle* angle) { | 425 void SkOpSegment::setFromAngle(int endIndex, SkOpAngle* angle) { |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
808 fLoop = span->fLoop = true; | 810 fLoop = span->fLoop = true; |
809 return result; | 811 return result; |
810 } | 812 } |
811 | 813 |
812 // find the starting or ending span with an existing loop of angles | 814 // find the starting or ending span with an existing loop of angles |
813 // FIXME? replicate for all identical starting/ending spans? | 815 // FIXME? replicate for all identical starting/ending spans? |
814 // OPTIMIZE? remove the spans pointing to windValue==0 here or earlier? | 816 // OPTIMIZE? remove the spans pointing to windValue==0 here or earlier? |
815 // FIXME? assert that only one other span has a valid windValue or oppValue | 817 // FIXME? assert that only one other span has a valid windValue or oppValue |
816 void SkOpSegment::addSimpleAngle(int index) { | 818 void SkOpSegment::addSimpleAngle(int index) { |
817 SkOpSpan* span = &fTs[index]; | 819 SkOpSpan* span = &fTs[index]; |
818 if (index == 0) { | 820 int idx; |
| 821 int start, end; |
| 822 if (span->fT == 0) { |
| 823 idx = 0; |
| 824 span = &fTs[0]; |
819 do { | 825 do { |
820 if (span->fToAngle) { | 826 if (span->fToAngle) { |
821 SkASSERT(span->fToAngle->loopCount() == 2); | 827 SkASSERT(span->fToAngle->loopCount() == 2); |
822 SkASSERT(!span->fFromAngle); | 828 SkASSERT(!span->fFromAngle); |
823 span->fFromAngle = span->fToAngle->next(); | 829 span->fFromAngle = span->fToAngle->next(); |
824 return; | 830 return; |
825 } | 831 } |
826 span = &fTs[++index]; | 832 span = &fTs[++idx]; |
827 } while (span->fT == 0); | 833 } while (span->fT == 0); |
828 SkASSERT(index == 1); | 834 SkASSERT(!fTs[0].fTiny && fTs[idx].fT > 0); |
829 index = 0; | 835 addStartSpan(idx); |
830 SkASSERT(!fTs[0].fTiny && fTs[1].fT > 0); | 836 start = 0; |
831 addStartSpan(1); | 837 end = idx; |
832 } else { | 838 } else { |
| 839 idx = count() - 1; |
| 840 span = &fTs[idx]; |
833 do { | 841 do { |
834 if (span->fFromAngle) { | 842 if (span->fFromAngle) { |
835 SkASSERT(span->fFromAngle->loopCount() == 2); | 843 SkASSERT(span->fFromAngle->loopCount() == 2); |
836 SkASSERT(!span->fToAngle); | 844 SkASSERT(!span->fToAngle); |
837 span->fToAngle = span->fFromAngle->next(); | 845 span->fToAngle = span->fFromAngle->next(); |
838 return; | 846 return; |
839 } | 847 } |
840 span = &fTs[--index]; | 848 span = &fTs[--idx]; |
841 } while (span->fT == 1); | 849 } while (span->fT == 1); |
842 SkASSERT(index == count() - 2); | 850 SkASSERT(!fTs[idx].fTiny && fTs[idx].fT < 1); |
843 index = count() - 1; | 851 addEndSpan(++idx); |
844 SkASSERT(!fTs[index - 1].fTiny && fTs[index - 1].fT < 1); | 852 start = idx; |
845 addEndSpan(index); | 853 end = count(); |
846 } | 854 } |
847 span = &fTs[index]; | 855 SkOpSegment* other; |
848 SkOpSegment* other = span->fOther; | 856 SkOpSpan* oSpan; |
849 SkOpSpan& oSpan = other->fTs[span->fOtherIndex]; | 857 index = start; |
| 858 do { |
| 859 span = &fTs[index]; |
| 860 other = span->fOther; |
| 861 int oFrom = span->fOtherIndex; |
| 862 oSpan = &other->fTs[oFrom]; |
| 863 if (oSpan->fT < 1 && oSpan->fWindValue) { |
| 864 break; |
| 865 } |
| 866 if (oSpan->fT == 0) { |
| 867 continue; |
| 868 } |
| 869 oFrom = other->nextExactSpan(oFrom, -1); |
| 870 SkOpSpan* oFromSpan = &other->fTs[oFrom]; |
| 871 SkASSERT(oFromSpan->fT < 1); |
| 872 if (oFromSpan->fWindValue) { |
| 873 break; |
| 874 } |
| 875 } while (++index < end); |
850 SkOpAngle* angle, * oAngle; | 876 SkOpAngle* angle, * oAngle; |
851 if (index == 0) { | 877 if (span->fT == 0) { |
852 SkASSERT(span->fOtherIndex - 1 >= 0); | 878 SkASSERT(span->fOtherIndex - 1 >= 0); |
853 SkASSERT(span->fOtherT == 1); | 879 SkASSERT(span->fOtherT == 1); |
854 SkDEBUGCODE(SkOpSpan& oPrior = other->fTs[span->fOtherIndex - 1]); | 880 SkDEBUGCODE(int oPriorIndex = other->nextExactSpan(span->fOtherIndex, -1
)); |
| 881 SkDEBUGCODE(const SkOpSpan& oPrior = other->span(oPriorIndex)); |
855 SkASSERT(!oPrior.fTiny && oPrior.fT < 1); | 882 SkASSERT(!oPrior.fTiny && oPrior.fT < 1); |
856 other->addEndSpan(span->fOtherIndex); | 883 other->addEndSpan(span->fOtherIndex); |
857 angle = span->fToAngle; | 884 angle = span->fToAngle; |
858 oAngle = oSpan.fFromAngle; | 885 oAngle = oSpan->fFromAngle; |
859 } else { | 886 } else { |
860 SkASSERT(span->fOtherIndex + 1 < other->count()); | 887 SkASSERT(span->fOtherIndex + 1 < other->count()); |
861 SkASSERT(span->fOtherT == 0); | 888 SkASSERT(span->fOtherT == 0); |
862 SkASSERT(!oSpan.fTiny && (other->fTs[span->fOtherIndex + 1].fT > 0 | 889 SkASSERT(!oSpan->fTiny && (other->fTs[span->fOtherIndex + 1].fT > 0 |
863 || (other->fTs[span->fOtherIndex + 1].fFromAngle == NULL | 890 || (other->fTs[span->fOtherIndex + 1].fFromAngle == NULL |
864 && other->fTs[span->fOtherIndex + 1].fToAngle == NULL))); | 891 && other->fTs[span->fOtherIndex + 1].fToAngle == NULL))); |
865 int oIndex = 1; | 892 int oIndex = 1; |
866 do { | 893 do { |
867 const SkOpSpan& osSpan = other->span(oIndex); | 894 const SkOpSpan& osSpan = other->span(oIndex); |
868 if (osSpan.fFromAngle || osSpan.fT > 0) { | 895 if (osSpan.fFromAngle || osSpan.fT > 0) { |
869 break; | 896 break; |
870 } | 897 } |
871 ++oIndex; | 898 ++oIndex; |
872 SkASSERT(oIndex < other->count()); | 899 SkASSERT(oIndex < other->count()); |
873 } while (true); | 900 } while (true); |
874 other->addStartSpan(oIndex); | 901 other->addStartSpan(oIndex); |
875 angle = span->fFromAngle; | 902 angle = span->fFromAngle; |
876 oAngle = oSpan.fToAngle; | 903 oAngle = oSpan->fToAngle; |
877 } | 904 } |
878 angle->insert(oAngle); | 905 angle->insert(oAngle); |
879 } | 906 } |
880 | 907 |
881 void SkOpSegment::alignMultiples(SkTDArray<AlignedSpan>* alignedArray) { | 908 void SkOpSegment::alignMultiples(SkTDArray<AlignedSpan>* alignedArray) { |
882 debugValidate(); | 909 debugValidate(); |
883 int count = this->count(); | 910 int count = this->count(); |
884 for (int index = 0; index < count; ++index) { | 911 for (int index = 0; index < count; ++index) { |
885 SkOpSpan& span = fTs[index]; | 912 SkOpSpan& span = fTs[index]; |
886 if (!span.fMultiple) { | 913 if (!span.fMultiple) { |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1341 } | 1368 } |
1342 } while (endPt != oPeek->fPt); | 1369 } while (endPt != oPeek->fPt); |
1343 if (success) { | 1370 if (success) { |
1344 // make sure the matching point completes the coincidence span | 1371 // make sure the matching point completes the coincidence span |
1345 success = false; | 1372 success = false; |
1346 do { | 1373 do { |
1347 if (oPeek->fOther == this) { | 1374 if (oPeek->fOther == this) { |
1348 success = true; | 1375 success = true; |
1349 break; | 1376 break; |
1350 } | 1377 } |
1351 oPeek = &other->fTs[++oPeekIndex]; | 1378 if (++oPeekIndex == oCount) { |
| 1379 break; |
| 1380 } |
| 1381 oPeek = &other->fTs[oPeekIndex]; |
1352 } while (endPt == oPeek->fPt); | 1382 } while (endPt == oPeek->fPt); |
1353 } | 1383 } |
1354 if (success) { | 1384 if (success) { |
1355 do { | 1385 do { |
1356 if (!binary || test->fWindValue + oTest->fOppValue >= 0) { | 1386 if (!binary || test->fWindValue + oTest->fOppValue >= 0) { |
1357 other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts); | 1387 other->bumpCoincidentOther(*test, &oIndex, &oOutsidePts); |
1358 } else { | 1388 } else { |
1359 other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsideP
ts); | 1389 other->bumpCoincidentThis(*test, binary, &oIndex, &oOutsideP
ts); |
1360 } | 1390 } |
1361 oTest = &other->fTs[oIndex]; | 1391 oTest = &other->fTs[oIndex]; |
(...skipping 2033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3395 SkOpSpan* SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding)
{ | 3425 SkOpSpan* SkOpSegment::markAndChaseWinding(const SkOpAngle* angle, int winding)
{ |
3396 int index = angle->start(); | 3426 int index = angle->start(); |
3397 int endIndex = angle->end(); | 3427 int endIndex = angle->end(); |
3398 int step = SkSign32(endIndex - index); | 3428 int step = SkSign32(endIndex - index); |
3399 int min = SkMin32(index, endIndex); | 3429 int min = SkMin32(index, endIndex); |
3400 markWinding(min, winding); | 3430 markWinding(min, winding); |
3401 SkOpSpan* last = NULL; | 3431 SkOpSpan* last = NULL; |
3402 SkOpSegment* other = this; | 3432 SkOpSegment* other = this; |
3403 while ((other = other->nextChase(&index, &step, &min, &last))) { | 3433 while ((other = other->nextChase(&index, &step, &min, &last))) { |
3404 if (other->fTs[min].fWindSum != SK_MinS32) { | 3434 if (other->fTs[min].fWindSum != SK_MinS32) { |
3405 SkASSERT(other->fTs[min].fWindSum == winding); | 3435 // SkASSERT(other->fTs[min].fWindSum == winding); |
3406 SkASSERT(!last); | 3436 SkASSERT(!last); |
3407 break; | 3437 break; |
3408 } | 3438 } |
3409 other->markWinding(min, winding); | 3439 other->markWinding(min, winding); |
3410 } | 3440 } |
3411 return last; | 3441 return last; |
3412 } | 3442 } |
3413 | 3443 |
3414 SkOpSpan* SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding)
{ | 3444 SkOpSpan* SkOpSegment::markAndChaseWinding(int index, int endIndex, int winding)
{ |
3415 int min = SkMin32(index, endIndex); | 3445 int min = SkMin32(index, endIndex); |
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4336 SkASSERT(span->fWindValue > 0 || span->fOppValue != 0); | 4366 SkASSERT(span->fWindValue > 0 || span->fOppValue != 0); |
4337 span->fWindValue = 0; | 4367 span->fWindValue = 0; |
4338 span->fOppValue = 0; | 4368 span->fOppValue = 0; |
4339 if (span->fTiny || span->fSmall) { | 4369 if (span->fTiny || span->fSmall) { |
4340 return; | 4370 return; |
4341 } | 4371 } |
4342 SkASSERT(!span->fDone); | 4372 SkASSERT(!span->fDone); |
4343 span->fDone = true; | 4373 span->fDone = true; |
4344 ++fDoneSpans; | 4374 ++fDoneSpans; |
4345 } | 4375 } |
OLD | NEW |