| 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 |