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 "SkOpSegment.h" | 8 #include "SkOpSegment.h" |
9 #include "SkPathWriter.h" | 9 #include "SkPathWriter.h" |
10 #include "SkTSort.h" | 10 #include "SkTSort.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 // suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 | 25 // suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 suTo=0,1 |
26 {{{{F, F}, {F, F}}, {{T, F}, {T, F}}}, {{{T, T}, {F, F}}, {{F, T}, {T, F}}}}
, // mi - su | 26 {{{{F, F}, {F, F}}, {{T, F}, {T, F}}}, {{{T, T}, {F, F}}, {{F, T}, {T, F}}}}
, // mi - su |
27 {{{{F, F}, {F, F}}, {{F, T}, {F, T}}}, {{{F, F}, {T, T}}, {{F, T}, {T, F}}}}
, // mi & su | 27 {{{{F, F}, {F, F}}, {{F, T}, {F, T}}}, {{{F, F}, {T, T}}, {{F, T}, {T, F}}}}
, // mi & su |
28 {{{{F, T}, {T, F}}, {{T, T}, {F, F}}}, {{{T, F}, {T, F}}, {{F, F}, {F, F}}}}
, // mi | su | 28 {{{{F, T}, {T, F}}, {{T, T}, {F, F}}}, {{{T, F}, {T, F}}, {{F, F}, {F, F}}}}
, // mi | su |
29 {{{{F, T}, {T, F}}, {{T, F}, {F, T}}}, {{{T, F}, {F, T}}, {{F, T}, {T, F}}}}
, // mi ^ su | 29 {{{{F, T}, {T, F}}, {{T, F}, {F, T}}}, {{{T, F}, {F, T}}, {{F, T}, {T, F}}}}
, // mi ^ su |
30 }; | 30 }; |
31 | 31 |
32 #undef F | 32 #undef F |
33 #undef T | 33 #undef T |
34 | 34 |
| 35 enum { kOutsideTrackedTCount = 16 }; // FIXME: determine what this should be |
| 36 |
35 // OPTIMIZATION: does the following also work, and is it any faster? | 37 // OPTIMIZATION: does the following also work, and is it any faster? |
36 // return outerWinding * innerWinding > 0 | 38 // return outerWinding * innerWinding > 0 |
37 // || ((outerWinding + innerWinding < 0) ^ ((outerWinding - innerWinding) <
0))) | 39 // || ((outerWinding + innerWinding < 0) ^ ((outerWinding - innerWinding) <
0))) |
38 bool SkOpSegment::UseInnerWinding(int outerWinding, int innerWinding) { | 40 bool SkOpSegment::UseInnerWinding(int outerWinding, int innerWinding) { |
39 SkASSERT(outerWinding != SK_MaxS32); | 41 SkASSERT(outerWinding != SK_MaxS32); |
40 SkASSERT(innerWinding != SK_MaxS32); | 42 SkASSERT(innerWinding != SK_MaxS32); |
41 int absOut = abs(outerWinding); | 43 int absOut = abs(outerWinding); |
42 int absIn = abs(innerWinding); | 44 int absIn = abs(innerWinding); |
43 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn; | 45 bool result = absOut == absIn ? outerWinding < 0 : absOut < absIn; |
44 return result; | 46 return result; |
45 } | 47 } |
46 | 48 |
47 bool SkOpSegment::activeAngle(int index, int* done, SkTDArray<SkOpAngle>* angles
) { | 49 bool SkOpSegment::activeAngle(int index, int* done, SkTArray<SkOpAngle, true>* a
ngles) { |
48 if (activeAngleInner(index, done, angles)) { | 50 if (activeAngleInner(index, done, angles)) { |
49 return true; | 51 return true; |
50 } | 52 } |
51 int lesser = index; | 53 int lesser = index; |
52 while (--lesser >= 0 && equalPoints(index, lesser)) { | 54 while (--lesser >= 0 && equalPoints(index, lesser)) { |
53 if (activeAngleOther(lesser, done, angles)) { | 55 if (activeAngleOther(lesser, done, angles)) { |
54 return true; | 56 return true; |
55 } | 57 } |
56 } | 58 } |
57 lesser = index; | 59 lesser = index; |
58 do { | 60 do { |
59 if (activeAngleOther(index, done, angles)) { | 61 if (activeAngleOther(index, done, angles)) { |
60 return true; | 62 return true; |
61 } | 63 } |
62 } while (++index < fTs.count() && equalPoints(index, lesser)); | 64 } while (++index < fTs.count() && equalPoints(index, lesser)); |
63 return false; | 65 return false; |
64 } | 66 } |
65 | 67 |
66 bool SkOpSegment::activeAngleOther(int index, int* done, SkTDArray<SkOpAngle>* a
ngles) { | 68 bool SkOpSegment::activeAngleOther(int index, int* done, SkTArray<SkOpAngle, tru
e>* angles) { |
67 SkOpSpan* span = &fTs[index]; | 69 SkOpSpan* span = &fTs[index]; |
68 SkOpSegment* other = span->fOther; | 70 SkOpSegment* other = span->fOther; |
69 int oIndex = span->fOtherIndex; | 71 int oIndex = span->fOtherIndex; |
70 return other->activeAngleInner(oIndex, done, angles); | 72 return other->activeAngleInner(oIndex, done, angles); |
71 } | 73 } |
72 | 74 |
73 bool SkOpSegment::activeAngleInner(int index, int* done, SkTDArray<SkOpAngle>* a
ngles) { | 75 bool SkOpSegment::activeAngleInner(int index, int* done, SkTArray<SkOpAngle, tru
e>* angles) { |
74 int next = nextExactSpan(index, 1); | 76 int next = nextExactSpan(index, 1); |
75 if (next > 0) { | 77 if (next > 0) { |
76 SkOpSpan& upSpan = fTs[index]; | 78 SkOpSpan& upSpan = fTs[index]; |
77 if (upSpan.fWindValue || upSpan.fOppValue) { | 79 if (upSpan.fWindValue || upSpan.fOppValue) { |
78 addAngle(angles, index, next); | 80 addAngle(angles, index, next); |
79 if (upSpan.fDone || upSpan.fUnsortableEnd) { | 81 if (upSpan.fDone || upSpan.fUnsortableEnd) { |
80 (*done)++; | 82 (*done)++; |
81 } else if (upSpan.fWindSum != SK_MinS32) { | 83 } else if (upSpan.fWindSum != SK_MinS32) { |
82 return true; | 84 return true; |
83 } | 85 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 } | 199 } |
198 | 200 |
199 bool SkOpSegment::activeWinding(int index, int endIndex, int* maxWinding, int* s
umWinding) { | 201 bool SkOpSegment::activeWinding(int index, int endIndex, int* maxWinding, int* s
umWinding) { |
200 setUpWinding(index, endIndex, maxWinding, sumWinding); | 202 setUpWinding(index, endIndex, maxWinding, sumWinding); |
201 bool from = *maxWinding != 0; | 203 bool from = *maxWinding != 0; |
202 bool to = *sumWinding != 0; | 204 bool to = *sumWinding != 0; |
203 bool result = gUnaryActiveEdge[from][to]; | 205 bool result = gUnaryActiveEdge[from][to]; |
204 return result; | 206 return result; |
205 } | 207 } |
206 | 208 |
207 void SkOpSegment::addAngle(SkTDArray<SkOpAngle>* anglesPtr, int start, int end)
const { | 209 void SkOpSegment::addAngle(SkTArray<SkOpAngle, true>* anglesPtr, int start, int
end) const { |
208 SkASSERT(start != end); | 210 SkASSERT(start != end); |
209 SkOpAngle* angle = anglesPtr->append(); | 211 SkOpAngle& angle = anglesPtr->push_back(); |
210 #if DEBUG_ANGLE | 212 #if DEBUG_ANGLE |
211 SkTDArray<SkOpAngle>& angles = *anglesPtr; | 213 SkTArray<SkOpAngle, true>& angles = *anglesPtr; |
212 if (angles.count() > 1) { | 214 if (angles.count() > 1) { |
213 const SkOpSegment* aSeg = angles[0].segment(); | 215 const SkOpSegment* aSeg = angles[0].segment(); |
214 int aStart = angles[0].start(); | 216 int aStart = angles[0].start(); |
215 if (!aSeg->fTs[aStart].fTiny) { | 217 if (!aSeg->fTs[aStart].fTiny) { |
216 const SkPoint& angle0Pt = aSeg->xyAtT(aStart); | 218 const SkPoint& angle0Pt = aSeg->xyAtT(aStart); |
217 SkDPoint newPt = (*CurveDPointAtT[SkPathOpsVerbToPoints(aSeg->fVerb)
])(aSeg->fPts, | 219 SkDPoint newPt = (*CurveDPointAtT[SkPathOpsVerbToPoints(aSeg->fVerb)
])(aSeg->fPts, |
218 aSeg->fTs[aStart].fT); | 220 aSeg->fTs[aStart].fT); |
219 #if ONE_OFF_DEBUG | 221 #if ONE_OFF_DEBUG |
220 SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g)\n", __FUNCTION__
, | 222 SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g)\n", __FUNCTION__
, |
221 aSeg->fTs[aStart].fT, newPt.fX, newPt.fY, angle0Pt.fX, angle
0Pt.fY); | 223 aSeg->fTs[aStart].fT, newPt.fX, newPt.fY, angle0Pt.fX, angle
0Pt.fY); |
222 #endif | 224 #endif |
223 SkASSERT(newPt.approximatelyEqual(angle0Pt)); | 225 SkASSERT(newPt.approximatelyEqual(angle0Pt)); |
224 } | 226 } |
225 } | 227 } |
226 #endif | 228 #endif |
227 angle->set(this, start, end); | 229 angle.set(this, start, end); |
228 } | 230 } |
229 | 231 |
230 void SkOpSegment::addCancelOutsides(double tStart, double oStart, SkOpSegment* o
ther, double oEnd) { | 232 void SkOpSegment::addCancelOutsides(double tStart, double oStart, SkOpSegment* o
ther, double oEnd) { |
231 int tIndex = -1; | 233 int tIndex = -1; |
232 int tCount = fTs.count(); | 234 int tCount = fTs.count(); |
233 int oIndex = -1; | 235 int oIndex = -1; |
234 int oCount = other->fTs.count(); | 236 int oCount = other->fTs.count(); |
235 do { | 237 do { |
236 ++tIndex; | 238 ++tIndex; |
237 } while (!approximately_negative(tStart - fTs[tIndex].fT) && tIndex < tCount
); | 239 } while (!approximately_negative(tStart - fTs[tIndex].fT) && tIndex < tCount
); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 SkDebugf("%s 4 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n", | 294 SkDebugf("%s 4 this=%d other=%d t [%d] %1.9g (%1.9g,%1.9g)\n", |
293 __FUNCTION__, fID, other->fID, oIndex, | 295 __FUNCTION__, fID, other->fID, oIndex, |
294 other->fTs[oIndex].fT, other->xyAtT(oIndex).fX, | 296 other->fTs[oIndex].fT, other->xyAtT(oIndex).fX, |
295 other->xyAtT(oIndex).fY); | 297 other->xyAtT(oIndex).fY); |
296 other->debugAddTPair(other->fTs[oIndex].fT, *this, fTs[tIndexStart].
fT); | 298 other->debugAddTPair(other->fTs[oIndex].fT, *this, fTs[tIndexStart].
fT); |
297 #endif | 299 #endif |
298 } | 300 } |
299 } | 301 } |
300 } | 302 } |
301 | 303 |
302 void SkOpSegment::addCoinOutsides(const SkTDArray<double>& outsideTs, SkOpSegmen
t* other, | 304 void SkOpSegment::addCoinOutsides(const SkTArray<double, true>& outsideTs, SkOpS
egment* other, |
303 double oEnd) { | 305 double oEnd) { |
304 // walk this to outsideTs[0] | 306 // walk this to outsideTs[0] |
305 // walk other to outsideTs[1] | 307 // walk other to outsideTs[1] |
306 // if either is > 0, add a pointer to the other, copying adjacent winding | 308 // if either is > 0, add a pointer to the other, copying adjacent winding |
307 int tIndex = -1; | 309 int tIndex = -1; |
308 int oIndex = -1; | 310 int oIndex = -1; |
309 double tStart = outsideTs[0]; | 311 double tStart = outsideTs[0]; |
310 double oStart = outsideTs[1]; | 312 double oStart = outsideTs[1]; |
311 do { | 313 do { |
312 ++tIndex; | 314 ++tIndex; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 int index = 0; | 561 int index = 0; |
560 while (!approximately_negative(startT - fTs[index].fT)) { | 562 while (!approximately_negative(startT - fTs[index].fT)) { |
561 ++index; | 563 ++index; |
562 } | 564 } |
563 int oIndex = other->fTs.count(); | 565 int oIndex = other->fTs.count(); |
564 while (approximately_positive(other->fTs[--oIndex].fT - oEndT)) | 566 while (approximately_positive(other->fTs[--oIndex].fT - oEndT)) |
565 ; | 567 ; |
566 double tRatio = (oEndT - oStartT) / (endT - startT); | 568 double tRatio = (oEndT - oStartT) / (endT - startT); |
567 SkOpSpan* test = &fTs[index]; | 569 SkOpSpan* test = &fTs[index]; |
568 SkOpSpan* oTest = &other->fTs[oIndex]; | 570 SkOpSpan* oTest = &other->fTs[oIndex]; |
569 SkTDArray<double> outsideTs; | 571 SkSTArray<kOutsideTrackedTCount, double, true> outsideTs; |
570 SkTDArray<double> oOutsideTs; | 572 SkSTArray<kOutsideTrackedTCount, double, true> oOutsideTs; |
571 do { | 573 do { |
572 bool decrement = test->fWindValue && oTest->fWindValue; | 574 bool decrement = test->fWindValue && oTest->fWindValue; |
573 bool track = test->fWindValue || oTest->fWindValue; | 575 bool track = test->fWindValue || oTest->fWindValue; |
574 bool bigger = test->fWindValue >= oTest->fWindValue; | 576 bool bigger = test->fWindValue >= oTest->fWindValue; |
575 double testT = test->fT; | 577 double testT = test->fT; |
576 double oTestT = oTest->fT; | 578 double oTestT = oTest->fT; |
577 SkOpSpan* span = test; | 579 SkOpSpan* span = test; |
578 do { | 580 do { |
579 if (decrement) { | 581 if (decrement) { |
580 if (binary && bigger) { | 582 if (binary && bigger) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 } else { | 653 } else { |
652 span[result].fUnsortableEnd = true; | 654 span[result].fUnsortableEnd = true; |
653 if (result + 1 < fTs.count()) { | 655 if (result + 1 < fTs.count()) { |
654 span[result + 1].fUnsortableStart = true; | 656 span[result + 1].fUnsortableStart = true; |
655 } | 657 } |
656 } | 658 } |
657 return result; | 659 return result; |
658 } | 660 } |
659 | 661 |
660 int SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, | 662 int SkOpSegment::bumpCoincidentThis(const SkOpSpan& oTest, bool opp, int index, |
661 SkTDArray<double>* outsideTs) { | 663 SkTArray<double, true>* outsideTs) { |
662 int oWindValue = oTest.fWindValue; | 664 int oWindValue = oTest.fWindValue; |
663 int oOppValue = oTest.fOppValue; | 665 int oOppValue = oTest.fOppValue; |
664 if (opp) { | 666 if (opp) { |
665 SkTSwap<int>(oWindValue, oOppValue); | 667 SkTSwap<int>(oWindValue, oOppValue); |
666 } | 668 } |
667 SkOpSpan* const test = &fTs[index]; | 669 SkOpSpan* const test = &fTs[index]; |
668 SkOpSpan* end = test; | 670 SkOpSpan* end = test; |
669 const double oStartT = oTest.fT; | 671 const double oStartT = oTest.fT; |
670 do { | 672 do { |
671 if (bumpSpan(end, oWindValue, oOppValue)) { | 673 if (bumpSpan(end, oWindValue, oOppValue)) { |
672 TrackOutside(outsideTs, end->fT, oStartT); | 674 TrackOutside(outsideTs, end->fT, oStartT); |
673 } | 675 } |
674 end = &fTs[++index]; | 676 end = &fTs[++index]; |
675 } while (approximately_negative(end->fT - test->fT)); | 677 } while (approximately_negative(end->fT - test->fT)); |
676 return index; | 678 return index; |
677 } | 679 } |
678 | 680 |
679 // because of the order in which coincidences are resolved, this and other | 681 // because of the order in which coincidences are resolved, this and other |
680 // may not have the same intermediate points. Compute the corresponding | 682 // may not have the same intermediate points. Compute the corresponding |
681 // intermediate T values (using this as the master, other as the follower) | 683 // intermediate T values (using this as the master, other as the follower) |
682 // and walk other conditionally -- hoping that it catches up in the end | 684 // and walk other conditionally -- hoping that it catches up in the end |
683 int SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oI
ndex, | 685 int SkOpSegment::bumpCoincidentOther(const SkOpSpan& test, double oEndT, int& oI
ndex, |
684 SkTDArray<double>* oOutsideTs) { | 686 SkTArray<double, true>* oOutsideTs) { |
685 SkOpSpan* const oTest = &fTs[oIndex]; | 687 SkOpSpan* const oTest = &fTs[oIndex]; |
686 SkOpSpan* oEnd = oTest; | 688 SkOpSpan* oEnd = oTest; |
687 const double startT = test.fT; | 689 const double startT = test.fT; |
688 const double oStartT = oTest->fT; | 690 const double oStartT = oTest->fT; |
689 while (!approximately_negative(oEndT - oEnd->fT) | 691 while (!approximately_negative(oEndT - oEnd->fT) |
690 && approximately_negative(oEnd->fT - oStartT)) { | 692 && approximately_negative(oEnd->fT - oStartT)) { |
691 zeroSpan(oEnd); | 693 zeroSpan(oEnd); |
692 TrackOutside(oOutsideTs, oEnd->fT, startT); | 694 TrackOutside(oOutsideTs, oEnd->fT, startT); |
693 oEnd = &fTs[++oIndex]; | 695 oEnd = &fTs[++oIndex]; |
694 } | 696 } |
(...skipping 17 matching lines...) Expand all Loading... |
712 int index = 0; | 714 int index = 0; |
713 while (!approximately_negative(startT - fTs[index].fT)) { | 715 while (!approximately_negative(startT - fTs[index].fT)) { |
714 ++index; | 716 ++index; |
715 } | 717 } |
716 int oIndex = 0; | 718 int oIndex = 0; |
717 while (!approximately_negative(oStartT - other->fTs[oIndex].fT)) { | 719 while (!approximately_negative(oStartT - other->fTs[oIndex].fT)) { |
718 ++oIndex; | 720 ++oIndex; |
719 } | 721 } |
720 SkOpSpan* test = &fTs[index]; | 722 SkOpSpan* test = &fTs[index]; |
721 SkOpSpan* oTest = &other->fTs[oIndex]; | 723 SkOpSpan* oTest = &other->fTs[oIndex]; |
722 SkTDArray<double> outsideTs; | 724 SkSTArray<kOutsideTrackedTCount, double, true> outsideTs; |
723 SkTDArray<double> oOutsideTs; | 725 SkSTArray<kOutsideTrackedTCount, double, true> oOutsideTs; |
724 do { | 726 do { |
725 // if either span has an opposite value and the operands don't match, re
solve first | 727 // if either span has an opposite value and the operands don't match, re
solve first |
726 // SkASSERT(!test->fDone || !oTest->fDone); | 728 // SkASSERT(!test->fDone || !oTest->fDone); |
727 if (test->fDone || oTest->fDone) { | 729 if (test->fDone || oTest->fDone) { |
728 index = advanceCoincidentThis(oTest, opp, index); | 730 index = advanceCoincidentThis(oTest, opp, index); |
729 oIndex = other->advanceCoincidentOther(test, oEndT, oIndex); | 731 oIndex = other->advanceCoincidentOther(test, oEndT, oIndex); |
730 } else { | 732 } else { |
731 index = bumpCoincidentThis(*oTest, opp, index, &outsideTs); | 733 index = bumpCoincidentThis(*oTest, opp, index, &outsideTs); |
732 oIndex = other->bumpCoincidentOther(*test, oEndT, oIndex, &oOutsideT
s); | 734 oIndex = other->bumpCoincidentOther(*test, oEndT, oIndex, &oOutsideT
s); |
733 } | 735 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 __FUNCTION__, fID, t, other->fID, otherT); | 770 __FUNCTION__, fID, t, other->fID, otherT); |
769 #endif | 771 #endif |
770 int insertedAt = addT(other, pt, t); | 772 int insertedAt = addT(other, pt, t); |
771 int otherInsertedAt = other->addT(this, pt, otherT); | 773 int otherInsertedAt = other->addT(this, pt, otherT); |
772 addOtherT(insertedAt, otherT, otherInsertedAt); | 774 addOtherT(insertedAt, otherT, otherInsertedAt); |
773 other->addOtherT(otherInsertedAt, t, insertedAt); | 775 other->addOtherT(otherInsertedAt, t, insertedAt); |
774 matchWindingValue(insertedAt, t, borrowWind); | 776 matchWindingValue(insertedAt, t, borrowWind); |
775 other->matchWindingValue(otherInsertedAt, otherT, borrowWind); | 777 other->matchWindingValue(otherInsertedAt, otherT, borrowWind); |
776 } | 778 } |
777 | 779 |
778 void SkOpSegment::addTwoAngles(int start, int end, SkTDArray<SkOpAngle>* angles)
const { | 780 void SkOpSegment::addTwoAngles(int start, int end, SkTArray<SkOpAngle, true>* an
gles) const { |
779 // add edge leading into junction | 781 // add edge leading into junction |
780 int min = SkMin32(end, start); | 782 int min = SkMin32(end, start); |
781 if (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0) { | 783 if (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0) { |
782 addAngle(angles, end, start); | 784 addAngle(angles, end, start); |
783 } | 785 } |
784 // add edge leading away from junction | 786 // add edge leading away from junction |
785 int step = SkSign32(end - start); | 787 int step = SkSign32(end - start); |
786 int tIndex = nextExactSpan(end, step); | 788 int tIndex = nextExactSpan(end, step); |
787 min = SkMin32(end, tIndex); | 789 min = SkMin32(end, tIndex); |
788 if (tIndex >= 0 && (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0)) { | 790 if (tIndex >= 0 && (fTs[min].fWindValue > 0 || fTs[min].fOppValue != 0)) { |
(...skipping 21 matching lines...) Expand all Loading... |
810 return oIndex; | 812 return oIndex; |
811 } | 813 } |
812 | 814 |
813 bool SkOpSegment::betweenTs(int lesser, double testT, int greater) const { | 815 bool SkOpSegment::betweenTs(int lesser, double testT, int greater) const { |
814 if (lesser > greater) { | 816 if (lesser > greater) { |
815 SkTSwap<int>(lesser, greater); | 817 SkTSwap<int>(lesser, greater); |
816 } | 818 } |
817 return approximately_between(fTs[lesser].fT, testT, fTs[greater].fT); | 819 return approximately_between(fTs[lesser].fT, testT, fTs[greater].fT); |
818 } | 820 } |
819 | 821 |
820 void SkOpSegment::buildAngles(int index, SkTDArray<SkOpAngle>* angles, bool incl
udeOpp) const { | 822 void SkOpSegment::buildAngles(int index, SkTArray<SkOpAngle, true>* angles, bool
includeOpp) const { |
821 double referenceT = fTs[index].fT; | 823 double referenceT = fTs[index].fT; |
822 int lesser = index; | 824 int lesser = index; |
823 while (--lesser >= 0 && (includeOpp || fTs[lesser].fOther->fOperand == fOper
and) | 825 while (--lesser >= 0 && (includeOpp || fTs[lesser].fOther->fOperand == fOper
and) |
824 && precisely_negative(referenceT - fTs[lesser].fT)) { | 826 && precisely_negative(referenceT - fTs[lesser].fT)) { |
825 buildAnglesInner(lesser, angles); | 827 buildAnglesInner(lesser, angles); |
826 } | 828 } |
827 do { | 829 do { |
828 buildAnglesInner(index, angles); | 830 buildAnglesInner(index, angles); |
829 } while (++index < fTs.count() && (includeOpp || fTs[index].fOther->fOperand
== fOperand) | 831 } while (++index < fTs.count() && (includeOpp || fTs[index].fOther->fOperand
== fOperand) |
830 && precisely_negative(fTs[index].fT - referenceT)); | 832 && precisely_negative(fTs[index].fT - referenceT)); |
831 } | 833 } |
832 | 834 |
833 void SkOpSegment::buildAnglesInner(int index, SkTDArray<SkOpAngle>* angles) cons
t { | 835 void SkOpSegment::buildAnglesInner(int index, SkTArray<SkOpAngle, true>* angles)
const { |
834 const SkOpSpan* span = &fTs[index]; | 836 const SkOpSpan* span = &fTs[index]; |
835 SkOpSegment* other = span->fOther; | 837 SkOpSegment* other = span->fOther; |
836 // if there is only one live crossing, and no coincidence, continue | 838 // if there is only one live crossing, and no coincidence, continue |
837 // in the same direction | 839 // in the same direction |
838 // if there is coincidence, the only choice may be to reverse direction | 840 // if there is coincidence, the only choice may be to reverse direction |
839 // find edge on either side of intersection | 841 // find edge on either side of intersection |
840 int oIndex = span->fOtherIndex; | 842 int oIndex = span->fOtherIndex; |
841 // if done == -1, prior span has already been processed | 843 // if done == -1, prior span has already been processed |
842 int step = 1; | 844 int step = 1; |
843 int next = other->nextExactSpan(oIndex, step); | 845 int next = other->nextExactSpan(oIndex, step); |
844 if (next < 0) { | 846 if (next < 0) { |
845 step = -step; | 847 step = -step; |
846 next = other->nextExactSpan(oIndex, step); | 848 next = other->nextExactSpan(oIndex, step); |
847 } | 849 } |
848 // add candidate into and away from junction | 850 // add candidate into and away from junction |
849 other->addTwoAngles(next, oIndex, angles); | 851 other->addTwoAngles(next, oIndex, angles); |
850 } | 852 } |
851 | 853 |
852 int SkOpSegment::computeSum(int startIndex, int endIndex, bool binary) { | 854 int SkOpSegment::computeSum(int startIndex, int endIndex, bool binary) { |
853 SkTDArray<SkOpAngle> angles; | 855 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
854 addTwoAngles(startIndex, endIndex, &angles); | 856 addTwoAngles(startIndex, endIndex, &angles); |
855 buildAngles(endIndex, &angles, false); | 857 buildAngles(endIndex, &angles, false); |
856 // OPTIMIZATION: check all angles to see if any have computed wind sum | 858 // OPTIMIZATION: check all angles to see if any have computed wind sum |
857 // before sorting (early exit if none) | 859 // before sorting (early exit if none) |
858 SkTDArray<SkOpAngle*> sorted; | 860 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
859 // FIXME?: Not sure if this sort must be ordered or if the relaxed ordering
is OK ... | 861 // FIXME?: Not sure if this sort must be ordered or if the relaxed ordering
is OK ... |
860 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); | 862 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); |
861 #if DEBUG_SORT | 863 #if DEBUG_SORT |
862 sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0, 0, 0); | 864 sorted[0]->segment()->debugShowSort(__FUNCTION__, sorted, 0, 0, 0); |
863 #endif | 865 #endif |
864 if (!sortable) { | 866 if (!sortable) { |
865 return SK_MinS32; | 867 return SK_MinS32; |
866 } | 868 } |
867 int angleCount = angles.count(); | 869 int angleCount = angles.count(); |
868 const SkOpAngle* angle; | 870 const SkOpAngle* angle; |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 *nextEnd += step; | 1132 *nextEnd += step; |
1131 } | 1133 } |
1132 while (precisely_zero(startT - other->fTs[*nextEnd].fT)); | 1134 while (precisely_zero(startT - other->fTs[*nextEnd].fT)); |
1133 SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); | 1135 SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); |
1134 if (other->isTiny(SkMin32(*nextStart, *nextEnd))) { | 1136 if (other->isTiny(SkMin32(*nextStart, *nextEnd))) { |
1135 return NULL; | 1137 return NULL; |
1136 } | 1138 } |
1137 return other; | 1139 return other; |
1138 } | 1140 } |
1139 // more than one viable candidate -- measure angles to find best | 1141 // more than one viable candidate -- measure angles to find best |
1140 SkTDArray<SkOpAngle> angles; | 1142 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
1141 SkASSERT(startIndex - endIndex != 0); | 1143 SkASSERT(startIndex - endIndex != 0); |
1142 SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); | 1144 SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); |
1143 addTwoAngles(startIndex, end, &angles); | 1145 addTwoAngles(startIndex, end, &angles); |
1144 buildAngles(end, &angles, true); | 1146 buildAngles(end, &angles, true); |
1145 SkTDArray<SkOpAngle*> sorted; | 1147 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
1146 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); | 1148 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); |
1147 int angleCount = angles.count(); | 1149 int angleCount = angles.count(); |
1148 int firstIndex = findStartingEdge(sorted, startIndex, end); | 1150 int firstIndex = findStartingEdge(sorted, startIndex, end); |
1149 SkASSERT(firstIndex >= 0); | 1151 SkASSERT(firstIndex >= 0); |
1150 #if DEBUG_SORT | 1152 #if DEBUG_SORT |
1151 debugShowSort(__FUNCTION__, sorted, firstIndex); | 1153 debugShowSort(__FUNCTION__, sorted, firstIndex); |
1152 #endif | 1154 #endif |
1153 if (!sortable) { | 1155 if (!sortable) { |
1154 *unsortable = true; | 1156 *unsortable = true; |
1155 return NULL; | 1157 return NULL; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 double startT = other->fTs[*nextStart].fT; | 1254 double startT = other->fTs[*nextStart].fT; |
1253 *nextEnd = *nextStart; | 1255 *nextEnd = *nextStart; |
1254 do { | 1256 do { |
1255 *nextEnd += step; | 1257 *nextEnd += step; |
1256 } | 1258 } |
1257 while (precisely_zero(startT - other->fTs[*nextEnd].fT)); | 1259 while (precisely_zero(startT - other->fTs[*nextEnd].fT)); |
1258 SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); | 1260 SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); |
1259 return other; | 1261 return other; |
1260 } | 1262 } |
1261 // more than one viable candidate -- measure angles to find best | 1263 // more than one viable candidate -- measure angles to find best |
1262 SkTDArray<SkOpAngle> angles; | 1264 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
1263 SkASSERT(startIndex - endIndex != 0); | 1265 SkASSERT(startIndex - endIndex != 0); |
1264 SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); | 1266 SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); |
1265 addTwoAngles(startIndex, end, &angles); | 1267 addTwoAngles(startIndex, end, &angles); |
1266 buildAngles(end, &angles, true); | 1268 buildAngles(end, &angles, true); |
1267 SkTDArray<SkOpAngle*> sorted; | 1269 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
1268 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); | 1270 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); |
1269 int angleCount = angles.count(); | 1271 int angleCount = angles.count(); |
1270 int firstIndex = findStartingEdge(sorted, startIndex, end); | 1272 int firstIndex = findStartingEdge(sorted, startIndex, end); |
1271 SkASSERT(firstIndex >= 0); | 1273 SkASSERT(firstIndex >= 0); |
1272 #if DEBUG_SORT | 1274 #if DEBUG_SORT |
1273 debugShowSort(__FUNCTION__, sorted, firstIndex); | 1275 debugShowSort(__FUNCTION__, sorted, firstIndex); |
1274 #endif | 1276 #endif |
1275 if (!sortable) { | 1277 if (!sortable) { |
1276 *unsortable = true; | 1278 *unsortable = true; |
1277 return NULL; | 1279 return NULL; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1381 } | 1383 } |
1382 #ifdef SK_DEBUG | 1384 #ifdef SK_DEBUG |
1383 SkASSERT(firstLoop); | 1385 SkASSERT(firstLoop); |
1384 #endif | 1386 #endif |
1385 SkDEBUGCODE(firstLoop = false;) | 1387 SkDEBUGCODE(firstLoop = false;) |
1386 step = -step; | 1388 step = -step; |
1387 } while (true); | 1389 } while (true); |
1388 SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); | 1390 SkASSERT(step < 0 ? *nextEnd >= 0 : *nextEnd < other->fTs.count()); |
1389 return other; | 1391 return other; |
1390 } | 1392 } |
1391 SkTDArray<SkOpAngle> angles; | 1393 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
1392 SkASSERT(startIndex - endIndex != 0); | 1394 SkASSERT(startIndex - endIndex != 0); |
1393 SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); | 1395 SkASSERT((startIndex - endIndex < 0) ^ (step < 0)); |
1394 addTwoAngles(startIndex, end, &angles); | 1396 addTwoAngles(startIndex, end, &angles); |
1395 buildAngles(end, &angles, false); | 1397 buildAngles(end, &angles, false); |
1396 SkTDArray<SkOpAngle*> sorted; | 1398 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
1397 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); | 1399 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMustBeOrdered_Sort
AngleKind); |
1398 if (!sortable) { | 1400 if (!sortable) { |
1399 *unsortable = true; | 1401 *unsortable = true; |
1400 #if DEBUG_SORT | 1402 #if DEBUG_SORT |
1401 debugShowSort(__FUNCTION__, sorted, findStartingEdge(sorted, startIndex,
end), 0, 0); | 1403 debugShowSort(__FUNCTION__, sorted, findStartingEdge(sorted, startIndex,
end), 0, 0); |
1402 #endif | 1404 #endif |
1403 return NULL; | 1405 return NULL; |
1404 } | 1406 } |
1405 int angleCount = angles.count(); | 1407 int angleCount = angles.count(); |
1406 int firstIndex = findStartingEdge(sorted, startIndex, end); | 1408 int firstIndex = findStartingEdge(sorted, startIndex, end); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1442 *nextStart = foundAngle->start(); | 1444 *nextStart = foundAngle->start(); |
1443 *nextEnd = foundAngle->end(); | 1445 *nextEnd = foundAngle->end(); |
1444 nextSegment = foundAngle->segment(); | 1446 nextSegment = foundAngle->segment(); |
1445 #if DEBUG_WINDING | 1447 #if DEBUG_WINDING |
1446 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", | 1448 SkDebugf("%s from:[%d] to:[%d] start=%d end=%d\n", |
1447 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); | 1449 __FUNCTION__, debugID(), nextSegment->debugID(), *nextStart, *nextEn
d); |
1448 #endif | 1450 #endif |
1449 return nextSegment; | 1451 return nextSegment; |
1450 } | 1452 } |
1451 | 1453 |
1452 int SkOpSegment::findStartingEdge(const SkTDArray<SkOpAngle*>& sorted, int start
, int end) { | 1454 int SkOpSegment::findStartingEdge(const SkTArray<SkOpAngle*, true>& sorted, int
start, int end) { |
1453 int angleCount = sorted.count(); | 1455 int angleCount = sorted.count(); |
1454 int firstIndex = -1; | 1456 int firstIndex = -1; |
1455 for (int angleIndex = 0; angleIndex < angleCount; ++angleIndex) { | 1457 for (int angleIndex = 0; angleIndex < angleCount; ++angleIndex) { |
1456 const SkOpAngle* angle = sorted[angleIndex]; | 1458 const SkOpAngle* angle = sorted[angleIndex]; |
1457 if (angle->segment() == this && angle->start() == end && | 1459 if (angle->segment() == this && angle->start() == end && |
1458 angle->end() == start) { | 1460 angle->end() == start) { |
1459 firstIndex = angleIndex; | 1461 firstIndex = angleIndex; |
1460 break; | 1462 break; |
1461 } | 1463 } |
1462 } | 1464 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 // sort the edges to find the leftmost | 1626 // sort the edges to find the leftmost |
1625 int step = 1; | 1627 int step = 1; |
1626 int end = nextSpan(firstT, step); | 1628 int end = nextSpan(firstT, step); |
1627 if (end == -1) { | 1629 if (end == -1) { |
1628 step = -1; | 1630 step = -1; |
1629 end = nextSpan(firstT, step); | 1631 end = nextSpan(firstT, step); |
1630 SkASSERT(end != -1); | 1632 SkASSERT(end != -1); |
1631 } | 1633 } |
1632 // if the topmost T is not on end, or is three-way or more, find left | 1634 // if the topmost T is not on end, or is three-way or more, find left |
1633 // look for left-ness from tLeft to firstT (matching y of other) | 1635 // look for left-ness from tLeft to firstT (matching y of other) |
1634 SkTDArray<SkOpAngle> angles; | 1636 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle, true> angles; |
1635 SkASSERT(firstT - end != 0); | 1637 SkASSERT(firstT - end != 0); |
1636 addTwoAngles(end, firstT, &angles); | 1638 addTwoAngles(end, firstT, &angles); |
1637 buildAngles(firstT, &angles, true); | 1639 buildAngles(firstT, &angles, true); |
1638 SkTDArray<SkOpAngle*> sorted; | 1640 SkSTArray<SkOpAngle::kStackBasedCount, SkOpAngle*, true> sorted; |
1639 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMayBeUnordered_Sor
tAngleKind); | 1641 bool sortable = SortAngles(angles, &sorted, SkOpSegment::kMayBeUnordered_Sor
tAngleKind); |
1640 int first = SK_MaxS32; | 1642 int first = SK_MaxS32; |
1641 SkScalar top = SK_ScalarMax; | 1643 SkScalar top = SK_ScalarMax; |
1642 int count = sorted.count(); | 1644 int count = sorted.count(); |
1643 for (int index = 0; index < count; ++index) { | 1645 for (int index = 0; index < count; ++index) { |
1644 const SkOpAngle* angle = sorted[index]; | 1646 const SkOpAngle* angle = sorted[index]; |
1645 SkOpSegment* next = angle->segment(); | 1647 SkOpSegment* next = angle->segment(); |
1646 SkPathOpsBounds bounds; | 1648 SkPathOpsBounds bounds; |
1647 next->subDivideBounds(angle->end(), angle->start(), &bounds); | 1649 next->subDivideBounds(angle->end(), angle->start(), &bounds); |
1648 if (approximately_greater(top, bounds.fTop)) { | 1650 if (approximately_greater(top, bounds.fTop)) { |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2336 *sumWinding = *sumMiWinding -= deltaSum; | 2338 *sumWinding = *sumMiWinding -= deltaSum; |
2337 *oppMaxWinding = *sumSuWinding; | 2339 *oppMaxWinding = *sumSuWinding; |
2338 *oppSumWinding = *sumSuWinding -= oppDeltaSum; | 2340 *oppSumWinding = *sumSuWinding -= oppDeltaSum; |
2339 } | 2341 } |
2340 } | 2342 } |
2341 | 2343 |
2342 // This marks all spans unsortable so that this info is available for early | 2344 // This marks all spans unsortable so that this info is available for early |
2343 // exclusion in find top and others. This could be optimized to only mark | 2345 // exclusion in find top and others. This could be optimized to only mark |
2344 // adjacent spans that unsortable. However, this makes it difficult to later | 2346 // adjacent spans that unsortable. However, this makes it difficult to later |
2345 // determine starting points for edge detection in find top and the like. | 2347 // determine starting points for edge detection in find top and the like. |
2346 bool SkOpSegment::SortAngles(const SkTDArray<SkOpAngle>& angles, SkTDArray<SkOpA
ngle*>* angleList, | 2348 bool SkOpSegment::SortAngles(const SkTArray<SkOpAngle, true>& angles, |
| 2349 SkTArray<SkOpAngle*, true>* angleList, |
2347 SortAngleKind orderKind) { | 2350 SortAngleKind orderKind) { |
2348 bool sortable = true; | 2351 bool sortable = true; |
2349 int angleCount = angles.count(); | 2352 int angleCount = angles.count(); |
2350 int angleIndex; | 2353 int angleIndex; |
2351 angleList->setReserve(angleCount); | 2354 // FIXME: caller needs to use SkTArray constructor with reserve count |
| 2355 // angleList->setReserve(angleCount); |
2352 for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { | 2356 for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { |
2353 const SkOpAngle& angle = angles[angleIndex]; | 2357 const SkOpAngle& angle = angles[angleIndex]; |
2354 *angleList->append() = const_cast<SkOpAngle*>(&angle); | 2358 angleList->push_back(const_cast<SkOpAngle*>(&angle)); |
2355 #if DEBUG_ANGLE | 2359 #if DEBUG_ANGLE |
2356 (*(angleList->end() - 1))->setID(angleIndex); | 2360 (*(angleList->end() - 1))->setID(angleIndex); |
2357 #endif | 2361 #endif |
2358 sortable &= !(angle.unsortable() || (orderKind == kMustBeOrdered_SortAng
leKind | 2362 sortable &= !(angle.unsortable() || (orderKind == kMustBeOrdered_SortAng
leKind |
2359 && angle.unorderable())); | 2363 && angle.unorderable())); |
2360 } | 2364 } |
2361 if (sortable) { | 2365 if (sortable) { |
2362 SkTQSort<SkOpAngle>(angleList->begin(), angleList->end() - 1); | 2366 SkTQSort<SkOpAngle>(angleList->begin(), angleList->end() - 1); |
2363 for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { | 2367 for (angleIndex = 0; angleIndex < angleCount; ++angleIndex) { |
2364 if (angles[angleIndex].unsortable() || (orderKind == kMustBeOrdered_
SortAngleKind | 2368 if (angles[angleIndex].unsortable() || (orderKind == kMustBeOrdered_
SortAngleKind |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2463 int start = angle->start(); | 2467 int start = angle->start(); |
2464 int end = angle->end(); | 2468 int end = angle->end(); |
2465 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; | 2469 const SkOpSpan& mSpan = fTs[SkMin32(start, end)]; |
2466 return mSpan.fTiny; | 2470 return mSpan.fTiny; |
2467 } | 2471 } |
2468 | 2472 |
2469 bool SkOpSegment::isTiny(int index) const { | 2473 bool SkOpSegment::isTiny(int index) const { |
2470 return fTs[index].fTiny; | 2474 return fTs[index].fTiny; |
2471 } | 2475 } |
2472 | 2476 |
2473 void SkOpSegment::TrackOutside(SkTDArray<double>* outsideTs, double end, double
start) { | 2477 void SkOpSegment::TrackOutside(SkTArray<double, true>* outsideTs, double end, do
uble start) { |
2474 int outCount = outsideTs->count(); | 2478 int outCount = outsideTs->count(); |
2475 if (outCount == 0 || !approximately_negative(end - (*outsideTs)[outCount - 2
])) { | 2479 if (outCount == 0 || !approximately_negative(end - (*outsideTs)[outCount - 2
])) { |
2476 *outsideTs->append() = end; | 2480 outsideTs->push_back(end); |
2477 *outsideTs->append() = start; | 2481 outsideTs->push_back(start); |
2478 } | 2482 } |
2479 } | 2483 } |
2480 | 2484 |
2481 void SkOpSegment::undoneSpan(int* start, int* end) { | 2485 void SkOpSegment::undoneSpan(int* start, int* end) { |
2482 size_t tCount = fTs.count(); | 2486 size_t tCount = fTs.count(); |
2483 size_t index; | 2487 size_t index; |
2484 for (index = 0; index < tCount; ++index) { | 2488 for (index = 0; index < tCount; ++index) { |
2485 if (!fTs[index].fDone) { | 2489 if (!fTs[index].fDone) { |
2486 break; | 2490 break; |
2487 } | 2491 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2756 if (span.fWindSum == SK_MinS32) { | 2760 if (span.fWindSum == SK_MinS32) { |
2757 SkDebugf("?"); | 2761 SkDebugf("?"); |
2758 } else { | 2762 } else { |
2759 SkDebugf("%d", span.fWindSum); | 2763 SkDebugf("%d", span.fWindSum); |
2760 } | 2764 } |
2761 SkDebugf(" windValue=%d\n", span.fWindValue); | 2765 SkDebugf(" windValue=%d\n", span.fWindValue); |
2762 } | 2766 } |
2763 #endif | 2767 #endif |
2764 | 2768 |
2765 #if DEBUG_SORT || DEBUG_SWAP_TOP | 2769 #if DEBUG_SORT || DEBUG_SWAP_TOP |
2766 void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& an
gles, int first, | 2770 void SkOpSegment::debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true
>& angles, |
2767 const int contourWinding, const int oppContourWinding) const { | 2771 int first, const int contourWinding, |
| 2772 const int oppContourWinding) const { |
2768 if (--gDebugSortCount < 0) { | 2773 if (--gDebugSortCount < 0) { |
2769 return; | 2774 return; |
2770 } | 2775 } |
2771 SkASSERT(angles[first]->segment() == this); | 2776 SkASSERT(angles[first]->segment() == this); |
2772 SkASSERT(angles.count() > 1); | 2777 SkASSERT(angles.count() > 1); |
2773 int lastSum = contourWinding; | 2778 int lastSum = contourWinding; |
2774 int oppLastSum = oppContourWinding; | 2779 int oppLastSum = oppContourWinding; |
2775 const SkOpAngle* firstAngle = angles[first]; | 2780 const SkOpAngle* firstAngle = angles[first]; |
2776 int windSum = lastSum - spanSign(firstAngle); | 2781 int windSum = lastSum - spanSign(firstAngle); |
2777 int oppoSign = oppSign(firstAngle); | 2782 int oppoSign = oppSign(firstAngle); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2865 ++index; | 2870 ++index; |
2866 if (index == angles.count()) { | 2871 if (index == angles.count()) { |
2867 index = 0; | 2872 index = 0; |
2868 } | 2873 } |
2869 if (firstTime) { | 2874 if (firstTime) { |
2870 firstTime = false; | 2875 firstTime = false; |
2871 } | 2876 } |
2872 } while (index != first); | 2877 } while (index != first); |
2873 } | 2878 } |
2874 | 2879 |
2875 void SkOpSegment::debugShowSort(const char* fun, const SkTDArray<SkOpAngle*>& an
gles, int first) { | 2880 void SkOpSegment::debugShowSort(const char* fun, const SkTArray<SkOpAngle*, true
>& angles, |
| 2881 int first) { |
2876 const SkOpAngle* firstAngle = angles[first]; | 2882 const SkOpAngle* firstAngle = angles[first]; |
2877 const SkOpSegment* segment = firstAngle->segment(); | 2883 const SkOpSegment* segment = firstAngle->segment(); |
2878 int winding = segment->updateWinding(firstAngle); | 2884 int winding = segment->updateWinding(firstAngle); |
2879 int oppWinding = segment->updateOppWinding(firstAngle); | 2885 int oppWinding = segment->updateOppWinding(firstAngle); |
2880 debugShowSort(fun, angles, first, winding, oppWinding); | 2886 debugShowSort(fun, angles, first, winding, oppWinding); |
2881 } | 2887 } |
2882 | 2888 |
2883 #endif | 2889 #endif |
2884 | 2890 |
2885 #if DEBUG_SHOW_WINDING | 2891 #if DEBUG_SHOW_WINDING |
2886 int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const { | 2892 int SkOpSegment::debugShowWindingValues(int slotCount, int ofInterest) const { |
2887 if (!(1 << fID & ofInterest)) { | 2893 if (!(1 << fID & ofInterest)) { |
2888 return 0; | 2894 return 0; |
2889 } | 2895 } |
2890 int sum = 0; | 2896 int sum = 0; |
2891 SkTDArray<char> slots; | 2897 SkTArray<char, true> slots(slotCount * 2); |
2892 slots.setCount(slotCount * 2); | |
2893 memset(slots.begin(), ' ', slotCount * 2); | 2898 memset(slots.begin(), ' ', slotCount * 2); |
2894 for (int i = 0; i < fTs.count(); ++i) { | 2899 for (int i = 0; i < fTs.count(); ++i) { |
2895 // if (!(1 << fTs[i].fOther->fID & ofInterest)) { | 2900 // if (!(1 << fTs[i].fOther->fID & ofInterest)) { |
2896 // continue; | 2901 // continue; |
2897 // } | 2902 // } |
2898 sum += fTs[i].fWindValue; | 2903 sum += fTs[i].fWindValue; |
2899 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); | 2904 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); |
2900 sum += fTs[i].fOppValue; | 2905 sum += fTs[i].fOppValue; |
2901 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); | 2906 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); |
2902 } | 2907 } |
2903 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, | 2908 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, |
2904 slots.begin() + slotCount); | 2909 slots.begin() + slotCount); |
2905 return sum; | 2910 return sum; |
2906 } | 2911 } |
2907 #endif | 2912 #endif |
OLD | NEW |