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 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 if (!span->fWindValue && !span->fOppValue) { | 1075 if (!span->fWindValue && !span->fOppValue) { |
1076 span->fDone = true; | 1076 span->fDone = true; |
1077 ++fDoneSpans; | 1077 ++fDoneSpans; |
1078 return true; | 1078 return true; |
1079 } | 1079 } |
1080 return false; | 1080 return false; |
1081 } | 1081 } |
1082 | 1082 |
1083 // look to see if the curve end intersects an intermediary that intersects the o
ther | 1083 // look to see if the curve end intersects an intermediary that intersects the o
ther |
1084 void SkOpSegment::checkEnds() { | 1084 void SkOpSegment::checkEnds() { |
1085 #if 1 | 1085 debugValidate(); |
1086 return; // FIXME: suspect we will need the code below to make intersections
consistent | |
1087 #else | |
1088 SkTDArray<SkOpSpan> missingSpans; | 1086 SkTDArray<SkOpSpan> missingSpans; |
1089 int count = fTs.count(); | 1087 int count = fTs.count(); |
1090 for (int index = 0; index < count; ++index) { | 1088 for (int index = 0; index < count; ++index) { |
1091 const SkOpSpan& span = fTs[index]; | 1089 const SkOpSpan& span = fTs[index]; |
1092 const SkOpSegment* other = span.fOther; | 1090 const SkOpSegment* other = span.fOther; |
1093 const SkOpSpan* otherSpan = &other->fTs[span.fOtherIndex]; | 1091 const SkOpSpan* otherSpan = &other->fTs[span.fOtherIndex]; |
1094 double otherT = otherSpan->fT; | 1092 double otherT = otherSpan->fT; |
1095 if (otherT != 0 && otherT != 1) { | 1093 if (otherT != 0 && otherT != 1) { |
1096 continue; | 1094 continue; |
1097 } | 1095 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 SkOpSpan* missing = missingSpans.append(); | 1141 SkOpSpan* missing = missingSpans.append(); |
1144 missing->fT = t; | 1142 missing->fT = t; |
1145 missing->fOther = match; | 1143 missing->fOther = match; |
1146 missing->fOtherT = matchT; | 1144 missing->fOtherT = matchT; |
1147 missing->fPt = peekSpan.fPt; | 1145 missing->fPt = peekSpan.fPt; |
1148 } | 1146 } |
1149 nextPeeker: | 1147 nextPeeker: |
1150 ; | 1148 ; |
1151 } | 1149 } |
1152 int missingCount = missingSpans.count(); | 1150 int missingCount = missingSpans.count(); |
| 1151 if (missingCount == 0) { |
| 1152 return; |
| 1153 } |
| 1154 debugValidate(); |
1153 for (int index = 0; index < missingCount; ++index) { | 1155 for (int index = 0; index < missingCount; ++index) { |
1154 const SkOpSpan& missing = missingSpans[index]; | 1156 const SkOpSpan& missing = missingSpans[index]; |
1155 addTPair(missing.fT, missing.fOther, missing.fOtherT, false, missing.fPt
); | 1157 addTPair(missing.fT, missing.fOther, missing.fOtherT, false, missing.fPt
); |
1156 } | 1158 } |
1157 if (missingCount > 0) { | 1159 fixOtherTIndex(); |
1158 fixOtherTIndex(); | 1160 for (int index = 0; index < missingCount; ++index) { |
| 1161 const SkOpSpan& missing = missingSpans[index]; |
| 1162 missing.fOther->fixOtherTIndex(); |
1159 } | 1163 } |
1160 #endif | 1164 debugValidate(); |
1161 } | 1165 } |
1162 | 1166 |
1163 bool SkOpSegment::equalPoints(int greaterTIndex, int lesserTIndex) { | 1167 bool SkOpSegment::equalPoints(int greaterTIndex, int lesserTIndex) { |
1164 SkASSERT(greaterTIndex >= lesserTIndex); | 1168 SkASSERT(greaterTIndex >= lesserTIndex); |
1165 double greaterT = fTs[greaterTIndex].fT; | 1169 double greaterT = fTs[greaterTIndex].fT; |
1166 double lesserT = fTs[lesserTIndex].fT; | 1170 double lesserT = fTs[lesserTIndex].fT; |
1167 if (greaterT == lesserT) { | 1171 if (greaterT == lesserT) { |
1168 return true; | 1172 return true; |
1169 } | 1173 } |
1170 if (!approximately_negative(greaterT - lesserT)) { | 1174 if (!approximately_negative(greaterT - lesserT)) { |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1785 // while the following fixes the indices up again, it isn't smart about | 1789 // while the following fixes the indices up again, it isn't smart about |
1786 // skipping segments whose indices are already correct | 1790 // skipping segments whose indices are already correct |
1787 // assuming we leave the code that wrote the index in the first place | 1791 // assuming we leave the code that wrote the index in the first place |
1788 void SkOpSegment::fixOtherTIndex() { | 1792 void SkOpSegment::fixOtherTIndex() { |
1789 int iCount = fTs.count(); | 1793 int iCount = fTs.count(); |
1790 for (int i = 0; i < iCount; ++i) { | 1794 for (int i = 0; i < iCount; ++i) { |
1791 SkOpSpan& iSpan = fTs[i]; | 1795 SkOpSpan& iSpan = fTs[i]; |
1792 double oT = iSpan.fOtherT; | 1796 double oT = iSpan.fOtherT; |
1793 SkOpSegment* other = iSpan.fOther; | 1797 SkOpSegment* other = iSpan.fOther; |
1794 int oCount = other->fTs.count(); | 1798 int oCount = other->fTs.count(); |
| 1799 SkDEBUGCODE(iSpan.fOtherIndex = -1); |
1795 for (int o = 0; o < oCount; ++o) { | 1800 for (int o = 0; o < oCount; ++o) { |
1796 SkOpSpan& oSpan = other->fTs[o]; | 1801 SkOpSpan& oSpan = other->fTs[o]; |
1797 if (oT == oSpan.fT && this == oSpan.fOther && oSpan.fOtherT == iSpan
.fT) { | 1802 if (oT == oSpan.fT && this == oSpan.fOther && oSpan.fOtherT == iSpan
.fT) { |
1798 iSpan.fOtherIndex = o; | 1803 iSpan.fOtherIndex = o; |
| 1804 oSpan.fOtherIndex = i; |
1799 break; | 1805 break; |
1800 } | 1806 } |
1801 } | 1807 } |
| 1808 SkASSERT(iSpan.fOtherIndex >= 0); |
1802 } | 1809 } |
1803 } | 1810 } |
1804 | 1811 |
1805 void SkOpSegment::init(const SkPoint pts[], SkPath::Verb verb, bool operand, boo
l evenOdd) { | 1812 void SkOpSegment::init(const SkPoint pts[], SkPath::Verb verb, bool operand, boo
l evenOdd) { |
1806 fDoneSpans = 0; | 1813 fDoneSpans = 0; |
1807 fOperand = operand; | 1814 fOperand = operand; |
1808 fXor = evenOdd; | 1815 fXor = evenOdd; |
1809 fPts = pts; | 1816 fPts = pts; |
1810 fVerb = verb; | 1817 fVerb = verb; |
1811 } | 1818 } |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2748 } | 2755 } |
2749 if (done()) { | 2756 if (done()) { |
2750 SkDebugf(" done"); | 2757 SkDebugf(" done"); |
2751 } | 2758 } |
2752 SkDebugf("\n"); | 2759 SkDebugf("\n"); |
2753 } | 2760 } |
2754 #endif | 2761 #endif |
2755 | 2762 |
2756 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY | 2763 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY |
2757 void SkOpSegment::debugShowActiveSpans() const { | 2764 void SkOpSegment::debugShowActiveSpans() const { |
| 2765 debugValidate(); |
2758 if (done()) { | 2766 if (done()) { |
2759 return; | 2767 return; |
2760 } | 2768 } |
2761 #if DEBUG_ACTIVE_SPANS_SHORT_FORM | 2769 #if DEBUG_ACTIVE_SPANS_SHORT_FORM |
2762 int lastId = -1; | 2770 int lastId = -1; |
2763 double lastT = -1; | 2771 double lastT = -1; |
2764 #endif | 2772 #endif |
2765 for (int i = 0; i < fTs.count(); ++i) { | 2773 for (int i = 0; i < fTs.count(); ++i) { |
2766 SkASSERT(&fTs[i] == &fTs[i].fOther->fTs[fTs[i].fOtherIndex].fOther-> | |
2767 fTs[fTs[i].fOther->fTs[fTs[i].fOtherIndex].fOtherIndex]); | |
2768 if (fTs[i].fDone) { | 2774 if (fTs[i].fDone) { |
2769 continue; | 2775 continue; |
2770 } | 2776 } |
2771 SkASSERT(i < fTs.count() - 1); | 2777 SkASSERT(i < fTs.count() - 1); |
2772 #if DEBUG_ACTIVE_SPANS_SHORT_FORM | 2778 #if DEBUG_ACTIVE_SPANS_SHORT_FORM |
2773 if (lastId == fID && lastT == fTs[i].fT) { | 2779 if (lastId == fID && lastT == fTs[i].fT) { |
2774 continue; | 2780 continue; |
2775 } | 2781 } |
2776 lastId = fID; | 2782 lastId = fID; |
2777 lastT = fTs[i].fT; | 2783 lastT = fTs[i].fT; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2988 sum += fTs[i].fWindValue; | 2994 sum += fTs[i].fWindValue; |
2989 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); | 2995 slots[fTs[i].fOther->fID - 1] = as_digit(fTs[i].fWindValue); |
2990 sum += fTs[i].fOppValue; | 2996 sum += fTs[i].fOppValue; |
2991 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); | 2997 slots[slotCount + fTs[i].fOther->fID - 1] = as_digit(fTs[i].fOppValue); |
2992 } | 2998 } |
2993 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, | 2999 SkDebugf("%s id=%2d %.*s | %.*s\n", __FUNCTION__, fID, slotCount, slots.begi
n(), slotCount, |
2994 slots.begin() + slotCount); | 3000 slots.begin() + slotCount); |
2995 return sum; | 3001 return sum; |
2996 } | 3002 } |
2997 #endif | 3003 #endif |
| 3004 |
| 3005 void SkOpSegment::debugValidate() const { |
| 3006 #if DEBUG_VALIDATE |
| 3007 int count = fTs.count(); |
| 3008 SkASSERT(count >= 2); |
| 3009 SkASSERT(fTs[0].fT == 0); |
| 3010 SkASSERT(fTs[count - 1].fT == 1); |
| 3011 int done = 0; |
| 3012 double t = -1; |
| 3013 for (int i = 0; i < count; ++i) { |
| 3014 const SkOpSpan& span = fTs[i]; |
| 3015 SkASSERT(t <= span.fT); |
| 3016 t = span.fT; |
| 3017 int otherIndex = span.fOtherIndex; |
| 3018 const SkOpSegment* other = span.fOther; |
| 3019 const SkOpSpan& otherSpan = other->fTs[otherIndex]; |
| 3020 SkASSERT(otherSpan.fPt == span.fPt); |
| 3021 SkASSERT(otherSpan.fOtherT == t); |
| 3022 SkASSERT(&fTs[i] == &otherSpan.fOther->fTs[otherSpan.fOtherIndex]); |
| 3023 done += span.fDone; |
| 3024 } |
| 3025 SkASSERT(done == fDoneSpans); |
| 3026 #endif |
| 3027 } |
OLD | NEW |