| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 | 7 |
| 8 #include "SkChunkAlloc.h" | 8 #include "SkChunkAlloc.h" |
| 9 #include "SkPathOpsBounds.h" | 9 #include "SkPathOpsBounds.h" |
| 10 #include "SkPathOpsRect.h" | 10 #include "SkPathOpsRect.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 fCoinEnd.init(); | 80 fCoinEnd.init(); |
| 81 } | 81 } |
| 82 | 82 |
| 83 const SkTSect<OppCurve, TCurve>* debugOpp() const; | 83 const SkTSect<OppCurve, TCurve>* debugOpp() const; |
| 84 const SkTSpan* debugSpan(int ) const; | 84 const SkTSpan* debugSpan(int ) const; |
| 85 const SkTSpan* debugT(double t) const; | 85 const SkTSpan* debugT(double t) const; |
| 86 #ifdef SK_DEBUG | 86 #ifdef SK_DEBUG |
| 87 bool debugIsBefore(const SkTSpan* span) const; | 87 bool debugIsBefore(const SkTSpan* span) const; |
| 88 #endif | 88 #endif |
| 89 void dump() const; | 89 void dump() const; |
| 90 void dumpAll() const; |
| 90 void dumpBounded(int id) const; | 91 void dumpBounded(int id) const; |
| 91 void dumpBounds() const; | 92 void dumpBounds() const; |
| 92 void dumpCoin() const; | 93 void dumpCoin() const; |
| 93 | 94 |
| 94 double endT() const { | 95 double endT() const { |
| 95 return fEndT; | 96 return fEndT; |
| 96 } | 97 } |
| 97 | 98 |
| 98 SkTSpan<OppCurve, TCurve>* findOppSpan(const SkTSpan<OppCurve, TCurve>* opp)
const; | 99 SkTSpan<OppCurve, TCurve>* findOppSpan(const SkTSpan<OppCurve, TCurve>* opp)
const; |
| 99 | 100 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 result->splitAt(span, t, &fHeap); | 238 result->splitAt(span, t, &fHeap); |
| 238 result->initBounds(fCurve); | 239 result->initBounds(fCurve); |
| 239 span->initBounds(fCurve); | 240 span->initBounds(fCurve); |
| 240 return result; | 241 return result; |
| 241 } | 242 } |
| 242 | 243 |
| 243 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt
ep, double* t, | 244 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt
ep, double* t, |
| 244 double* oppT); | 245 double* oppT); |
| 245 SkTSpan<TCurve, OppCurve>* boundsMax() const; | 246 SkTSpan<TCurve, OppCurve>* boundsMax() const; |
| 246 void coincidentCheck(SkTSect<OppCurve, TCurve>* sect2); | 247 void coincidentCheck(SkTSect<OppCurve, TCurve>* sect2); |
| 248 void coincidentForce(SkTSect<OppCurve, TCurve>* sect2, double start1s, doubl
e start1e); |
| 247 bool coincidentHasT(double t); | 249 bool coincidentHasT(double t); |
| 248 int collapsed() const; | 250 int collapsed() const; |
| 249 void computePerpendiculars(SkTSect<OppCurve, TCurve>* sect2, SkTSpan<TCurve,
OppCurve>* first, | 251 void computePerpendiculars(SkTSect<OppCurve, TCurve>* sect2, SkTSpan<TCurve,
OppCurve>* first, |
| 250 SkTSpan<TCurve, OppCurve>* last); | 252 SkTSpan<TCurve, OppCurve>* last); |
| 251 int countConsecutiveSpans(SkTSpan<TCurve, OppCurve>* first, | 253 int countConsecutiveSpans(SkTSpan<TCurve, OppCurve>* first, |
| 252 SkTSpan<TCurve, OppCurve>** last) const; | 254 SkTSpan<TCurve, OppCurve>** last) const; |
| 253 | 255 |
| 254 int debugID() const { | 256 int debugID() const { |
| 255 return PATH_OPS_DEBUG_T_SECT_RELEASE(fID, -1); | 257 return PATH_OPS_DEBUG_T_SECT_RELEASE(fID, -1); |
| 256 } | 258 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 } | 380 } |
| 379 | 381 |
| 380 template<typename TCurve, typename OppCurve> | 382 template<typename TCurve, typename OppCurve> |
| 381 void SkTSect<TCurve, OppCurve>::addForPerp(SkTSpan<OppCurve, TCurve>* span, doub
le t) { | 383 void SkTSect<TCurve, OppCurve>::addForPerp(SkTSpan<OppCurve, TCurve>* span, doub
le t) { |
| 382 if (!span->hasOppT(t)) { | 384 if (!span->hasOppT(t)) { |
| 383 SkTSpan<TCurve, OppCurve>* priorSpan; | 385 SkTSpan<TCurve, OppCurve>* priorSpan; |
| 384 SkTSpan<TCurve, OppCurve>* opp = this->spanAtT(t, &priorSpan); | 386 SkTSpan<TCurve, OppCurve>* opp = this->spanAtT(t, &priorSpan); |
| 385 if (!opp) { | 387 if (!opp) { |
| 386 opp = this->addFollowing(priorSpan); | 388 opp = this->addFollowing(priorSpan); |
| 387 #if DEBUG_PERP | 389 #if DEBUG_PERP |
| 388 SkDebugf("%s priorSpan=%d t=%1.9g opp=%d\n", __FUNCTION__, priorSpan
->debugID(), t, | 390 SkDebugf("%s priorSpan=%d t=%1.9g opp=%d\n", __FUNCTION__, priorSpan
? |
| 389 opp->debugID()); | 391 priorSpan->debugID() : -1, t, opp->debugID()); |
| 390 #endif | 392 #endif |
| 391 } | 393 } |
| 392 #if DEBUG_PERP | 394 #if DEBUG_PERP |
| 393 opp->dump(); SkDebugf("\n"); | 395 opp->dump(); SkDebugf("\n"); |
| 394 SkDebugf("%s addBounded span=%d opp=%d\n", __FUNCTION__, priorSpan->debu
gID(), | 396 SkDebugf("%s addBounded span=%d opp=%d\n", __FUNCTION__, priorSpan ? |
| 395 opp->debugID()); | 397 priorSpan->debugID() : -1, opp->debugID()); |
| 396 #endif | 398 #endif |
| 397 opp->addBounded(span, &fHeap); | 399 opp->addBounded(span, &fHeap); |
| 398 span->addBounded(opp, &fHeap); | 400 span->addBounded(opp, &fHeap); |
| 399 } | 401 } |
| 400 this->validate(); | 402 this->validate(); |
| 401 #if DEBUG_T_SECT | 403 #if DEBUG_T_SECT |
| 402 span->validatePerpT(t); | 404 span->validatePerpT(t); |
| 403 #endif | 405 #endif |
| 404 } | 406 } |
| 405 | 407 |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 testBounded = testBounded->fNext; | 787 testBounded = testBounded->fNext; |
| 786 } | 788 } |
| 787 #endif | 789 #endif |
| 788 } | 790 } |
| 789 | 791 |
| 790 template<typename TCurve, typename OppCurve> | 792 template<typename TCurve, typename OppCurve> |
| 791 void SkTSpan<TCurve, OppCurve>::validatePerpT(double oppT) const { | 793 void SkTSpan<TCurve, OppCurve>::validatePerpT(double oppT) const { |
| 792 const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; | 794 const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded; |
| 793 while (testBounded) { | 795 while (testBounded) { |
| 794 const SkTSpan<OppCurve, TCurve>* overlap = testBounded->fBounded; | 796 const SkTSpan<OppCurve, TCurve>* overlap = testBounded->fBounded; |
| 795 if (between(overlap->fStartT, oppT, overlap->fEndT)) { | 797 if (precisely_between(overlap->fStartT, oppT, overlap->fEndT)) { |
| 796 return; | 798 return; |
| 797 } | 799 } |
| 798 testBounded = testBounded->fNext; | 800 testBounded = testBounded->fNext; |
| 799 } | 801 } |
| 800 SkASSERT(0); | 802 SkASSERT(0); |
| 801 } | 803 } |
| 802 | 804 |
| 803 template<typename TCurve, typename OppCurve> | 805 template<typename TCurve, typename OppCurve> |
| 804 void SkTSpan<TCurve, OppCurve>::validatePerpPt(double t, const SkDPoint& pt) con
st { | 806 void SkTSpan<TCurve, OppCurve>::validatePerpPt(double t, const SkDPoint& pt) con
st { |
| 805 SkASSERT(fDebugSect->fOppSect->fCurve.ptAtT(t) == pt); | 807 SkASSERT(fDebugSect->fOppSect->fCurve.ptAtT(t) == pt); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 937 sect2->validate(); | 939 sect2->validate(); |
| 938 // check to see if a range of points are on the curve | 940 // check to see if a range of points are on the curve |
| 939 SkTSpan<TCurve, OppCurve>* coinStart = first; | 941 SkTSpan<TCurve, OppCurve>* coinStart = first; |
| 940 do { | 942 do { |
| 941 coinStart = this->extractCoincident(sect2, coinStart, last); | 943 coinStart = this->extractCoincident(sect2, coinStart, last); |
| 942 } while (coinStart && !last->fDeleted); | 944 } while (coinStart && !last->fDeleted); |
| 943 } while ((first = next)); | 945 } while ((first = next)); |
| 944 } | 946 } |
| 945 | 947 |
| 946 template<typename TCurve, typename OppCurve> | 948 template<typename TCurve, typename OppCurve> |
| 949 void SkTSect<TCurve, OppCurve>::coincidentForce(SkTSect<OppCurve, TCurve>* sect2
, |
| 950 double start1s, double start1e) { |
| 951 SkTSpan<TCurve, OppCurve>* first = fHead; |
| 952 SkTSpan<TCurve, OppCurve>* last = this->tail(); |
| 953 SkTSpan<OppCurve, TCurve>* oppFirst = sect2->fHead; |
| 954 SkTSpan<OppCurve, TCurve>* oppLast = sect2->tail(); |
| 955 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); |
| 956 deleteEmptySpans |= sect2->updateBounded(oppFirst, oppLast, first); |
| 957 this->removeSpanRange(first, last); |
| 958 sect2->removeSpanRange(oppFirst, oppLast); |
| 959 first->fStartT = start1s; |
| 960 first->fEndT = start1e; |
| 961 first->resetBounds(fCurve); |
| 962 first->fCoinStart.setPerp(fCurve, start1s, fCurve[0], sect2->fCurve); |
| 963 first->fCoinEnd.setPerp(fCurve, start1e, fCurve[TCurve::kPointLast], sect2->
fCurve); |
| 964 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); |
| 965 double oppStartT = SkTMax(0., first->fCoinStart.perpT()); |
| 966 double oppEndT = SkTMin(1., first->fCoinEnd.perpT()); |
| 967 if (!oppMatched) { |
| 968 SkTSwap(oppStartT, oppEndT); |
| 969 } |
| 970 oppFirst->fStartT = oppStartT; |
| 971 oppFirst->fEndT = oppEndT; |
| 972 oppFirst->resetBounds(sect2->fCurve); |
| 973 this->removeCoincident(first, false); |
| 974 sect2->removeCoincident(oppFirst, true); |
| 975 if (deleteEmptySpans) { |
| 976 this->deleteEmptySpans(); |
| 977 sect2->deleteEmptySpans(); |
| 978 } |
| 979 } |
| 980 |
| 981 template<typename TCurve, typename OppCurve> |
| 947 bool SkTSect<TCurve, OppCurve>::coincidentHasT(double t) { | 982 bool SkTSect<TCurve, OppCurve>::coincidentHasT(double t) { |
| 948 SkTSpan<TCurve, OppCurve>* test = fCoincident; | 983 SkTSpan<TCurve, OppCurve>* test = fCoincident; |
| 949 while (test) { | 984 while (test) { |
| 950 if (between(test->fStartT, t, test->fEndT)) { | 985 if (between(test->fStartT, t, test->fEndT)) { |
| 951 return true; | 986 return true; |
| 952 } | 987 } |
| 953 test = test->fNext; | 988 test = test->fNext; |
| 954 } | 989 } |
| 955 return false; | 990 return false; |
| 956 } | 991 } |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1219 *oppResult = 1; | 1254 *oppResult = 1; |
| 1220 } | 1255 } |
| 1221 } else { | 1256 } else { |
| 1222 *oppResult = 1; | 1257 *oppResult = 1; |
| 1223 } | 1258 } |
| 1224 return hullResult; | 1259 return hullResult; |
| 1225 } | 1260 } |
| 1226 if (span->fIsLine && oppSpan->fIsLine) { | 1261 if (span->fIsLine && oppSpan->fIsLine) { |
| 1227 SkIntersections i; | 1262 SkIntersections i; |
| 1228 int sects = this->linesIntersect(span, opp, oppSpan, &i); | 1263 int sects = this->linesIntersect(span, opp, oppSpan, &i); |
| 1264 if (sects == 2) { |
| 1265 return *oppResult = 1; |
| 1266 } |
| 1229 if (!sects) { | 1267 if (!sects) { |
| 1230 return -1; | 1268 return -1; |
| 1231 } | 1269 } |
| 1232 span->fStartT = span->fEndT = i[0][0]; | 1270 span->fStartT = span->fEndT = i[0][0]; |
| 1233 oppSpan->fStartT = oppSpan->fEndT = i[1][0]; | 1271 oppSpan->fStartT = oppSpan->fEndT = i[1][0]; |
| 1234 return *oppResult = 2; | 1272 return *oppResult = 2; |
| 1235 } | 1273 } |
| 1236 if (span->fIsLinear || oppSpan->fIsLinear) { | 1274 if (span->fIsLinear || oppSpan->fIsLinear) { |
| 1237 return *oppResult = (int) span->linearsIntersect(oppSpan); | 1275 return *oppResult = (int) span->linearsIntersect(oppSpan); |
| 1238 } | 1276 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1250 SkDLine thisLine = {{ span->fPart[0], span->fPart[TCurve::kPointLast] }}; | 1288 SkDLine thisLine = {{ span->fPart[0], span->fPart[TCurve::kPointLast] }}; |
| 1251 SkDLine oppLine = {{ oppSpan->fPart[0], oppSpan->fPart[OppCurve::kPointLast]
}}; | 1289 SkDLine oppLine = {{ oppSpan->fPart[0], oppSpan->fPart[OppCurve::kPointLast]
}}; |
| 1252 int loopCount = 0; | 1290 int loopCount = 0; |
| 1253 double bestDistSq = DBL_MAX; | 1291 double bestDistSq = DBL_MAX; |
| 1254 if (!thisRayI.intersectRay(opp->fCurve, thisLine)) { | 1292 if (!thisRayI.intersectRay(opp->fCurve, thisLine)) { |
| 1255 return 0; | 1293 return 0; |
| 1256 } | 1294 } |
| 1257 if (!oppRayI.intersectRay(this->fCurve, oppLine)) { | 1295 if (!oppRayI.intersectRay(this->fCurve, oppLine)) { |
| 1258 return 0; | 1296 return 0; |
| 1259 } | 1297 } |
| 1298 // if the ends of each line intersect the opposite curve, the lines are coin
cident |
| 1299 if (thisRayI.used() > 1) { |
| 1300 int ptMatches = 0; |
| 1301 for (int tIndex = 0; tIndex < thisRayI.used(); ++tIndex) { |
| 1302 for (int lIndex = 0; lIndex < (int) SK_ARRAY_COUNT(thisLine.fPts); +
+lIndex) { |
| 1303 ptMatches += thisRayI.pt(tIndex).approximatelyEqual(thisLine.fPt
s[lIndex]); |
| 1304 } |
| 1305 } |
| 1306 if (ptMatches == 2) { |
| 1307 return 2; |
| 1308 } |
| 1309 } |
| 1310 if (oppRayI.used() > 1) { |
| 1311 int ptMatches = 0; |
| 1312 for (int oIndex = 0; oIndex < oppRayI.used(); ++oIndex) { |
| 1313 for (int lIndex = 0; lIndex < (int) SK_ARRAY_COUNT(thisLine.fPts); +
+lIndex) { |
| 1314 ptMatches += oppRayI.pt(oIndex).approximatelyEqual(oppLine.fPts[
lIndex]); |
| 1315 } |
| 1316 } |
| 1317 if (ptMatches == 2) { |
| 1318 return 2; |
| 1319 } |
| 1320 } |
| 1260 do { | 1321 do { |
| 1261 // pick the closest pair of points | 1322 // pick the closest pair of points |
| 1262 double closest = DBL_MAX; | 1323 double closest = DBL_MAX; |
| 1263 int closeIndex SK_INIT_TO_AVOID_WARNING; | 1324 int closeIndex SK_INIT_TO_AVOID_WARNING; |
| 1264 int oppCloseIndex SK_INIT_TO_AVOID_WARNING; | 1325 int oppCloseIndex SK_INIT_TO_AVOID_WARNING; |
| 1265 for (int index = 0; index < oppRayI.used(); ++index) { | 1326 for (int index = 0; index < oppRayI.used(); ++index) { |
| 1266 if (!roughly_between(span->fStartT, oppRayI[0][index], span->fEndT))
{ | 1327 if (!roughly_between(span->fStartT, oppRayI[0][index], span->fEndT))
{ |
| 1267 continue; | 1328 continue; |
| 1268 } | 1329 } |
| 1269 for (int oIndex = 0; oIndex < thisRayI.used(); ++oIndex) { | 1330 for (int oIndex = 0; oIndex < thisRayI.used(); ++oIndex) { |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 // SkASSERT(between(0, sect, 2)); | 1975 // SkASSERT(between(0, sect, 2)); |
| 1915 if (!sect) { | 1976 if (!sect) { |
| 1916 return; | 1977 return; |
| 1917 } | 1978 } |
| 1918 if (sect == 2 && oppSect == 2) { | 1979 if (sect == 2 && oppSect == 2) { |
| 1919 (void) EndsEqual(sect1, sect2, intersections); | 1980 (void) EndsEqual(sect1, sect2, intersections); |
| 1920 return; | 1981 return; |
| 1921 } | 1982 } |
| 1922 span1->addBounded(span2, §1->fHeap); | 1983 span1->addBounded(span2, §1->fHeap); |
| 1923 span2->addBounded(span1, §2->fHeap); | 1984 span2->addBounded(span1, §2->fHeap); |
| 1985 const int kMaxCoinLoopCount = 8; |
| 1986 int coinLoopCount = kMaxCoinLoopCount; |
| 1987 double start1s SK_INIT_TO_AVOID_WARNING; |
| 1988 double start1e SK_INIT_TO_AVOID_WARNING; |
| 1924 do { | 1989 do { |
| 1925 // find the largest bounds | 1990 // find the largest bounds |
| 1926 SkTSpan<TCurve, OppCurve>* largest1 = sect1->boundsMax(); | 1991 SkTSpan<TCurve, OppCurve>* largest1 = sect1->boundsMax(); |
| 1927 if (!largest1) { | 1992 if (!largest1) { |
| 1928 break; | 1993 break; |
| 1929 } | 1994 } |
| 1930 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax(); | 1995 SkTSpan<OppCurve, TCurve>* largest2 = sect2->boundsMax(); |
| 1931 // split it | 1996 // split it |
| 1932 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM
ax | 1997 if (!largest2 || (largest1 && (largest1->fBoundsMax > largest2->fBoundsM
ax |
| 1933 || (!largest1->fCollapsed && largest2->fCollapsed)))) { | 1998 || (!largest1->fCollapsed && largest2->fCollapsed)))) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1948 // trim parts that don't intersect the opposite | 2013 // trim parts that don't intersect the opposite |
| 1949 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); | 2014 SkTSpan<OppCurve, TCurve>* half2 = sect2->addOne(); |
| 1950 if (!half2->split(largest2, §2->fHeap)) { | 2015 if (!half2->split(largest2, §2->fHeap)) { |
| 1951 break; | 2016 break; |
| 1952 } | 2017 } |
| 1953 sect2->trim(largest2, sect1); | 2018 sect2->trim(largest2, sect1); |
| 1954 sect2->trim(half2, sect1); | 2019 sect2->trim(half2, sect1); |
| 1955 } | 2020 } |
| 1956 sect1->validate(); | 2021 sect1->validate(); |
| 1957 sect2->validate(); | 2022 sect2->validate(); |
| 2023 #if DEBUG_T_SECT_LOOP_COUNT |
| 2024 intersections->debugBumpLoopCount(SkIntersections::kIterations_DebugLoop
); |
| 2025 #endif |
| 1958 // if there are 9 or more continuous spans on both sects, suspect coinci
dence | 2026 // if there are 9 or more continuous spans on both sects, suspect coinci
dence |
| 1959 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT | 2027 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT |
| 1960 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { | 2028 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { |
| 2029 if (coinLoopCount == kMaxCoinLoopCount) { |
| 2030 start1s = sect1->fHead->fStartT; |
| 2031 start1e = sect1->tail()->fEndT; |
| 2032 } |
| 1961 sect1->coincidentCheck(sect2); | 2033 sect1->coincidentCheck(sect2); |
| 1962 sect1->validate(); | 2034 sect1->validate(); |
| 1963 sect2->validate(); | 2035 sect2->validate(); |
| 2036 #if DEBUG_T_SECT_LOOP_COUNT |
| 2037 intersections->debugBumpLoopCount(SkIntersections::kCoinCheck_DebugL
oop); |
| 2038 #endif |
| 2039 if (!--coinLoopCount) { |
| 2040 /* All known working cases resolve in two tries. Sadly, cubicCon
icTests[0] |
| 2041 gets stuck in a loop. It adds an extension to allow a coincid
ent end |
| 2042 perpendicular to track its intersection in the opposite curve
. However, |
| 2043 the bounding box of the extension does not intersect the orig
inal curve, |
| 2044 so the extension is discarded, only to be added again the nex
t time around. */ |
| 2045 sect1->coincidentForce(sect2, start1s, start1e); |
| 2046 sect1->validate(); |
| 2047 sect2->validate(); |
| 2048 } |
| 1964 } | 2049 } |
| 1965 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT | 2050 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT |
| 1966 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { | 2051 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { |
| 1967 sect1->computePerpendiculars(sect2, sect1->fHead, sect1->tail()); | 2052 sect1->computePerpendiculars(sect2, sect1->fHead, sect1->tail()); |
| 1968 sect2->computePerpendiculars(sect1, sect2->fHead, sect2->tail()); | 2053 sect2->computePerpendiculars(sect1, sect2->fHead, sect2->tail()); |
| 1969 sect1->removeByPerpendicular(sect2); | 2054 sect1->removeByPerpendicular(sect2); |
| 1970 sect1->validate(); | 2055 sect1->validate(); |
| 1971 sect2->validate(); | 2056 sect2->validate(); |
| 2057 #if DEBUG_T_SECT_LOOP_COUNT |
| 2058 intersections->debugBumpLoopCount(SkIntersections::kComputePerp_Debu
gLoop); |
| 2059 #endif |
| 1972 if (sect1->collapsed() > TCurve::kMaxIntersections) { | 2060 if (sect1->collapsed() > TCurve::kMaxIntersections) { |
| 1973 break; | 2061 break; |
| 1974 } | 2062 } |
| 1975 } | 2063 } |
| 1976 #if DEBUG_T_SECT_DUMP | 2064 #if DEBUG_T_SECT_DUMP |
| 1977 sect1->dumpBoth(sect2); | 2065 sect1->dumpBoth(sect2); |
| 1978 #endif | 2066 #endif |
| 1979 if (!sect1->fHead || !sect2->fHead) { | 2067 if (!sect1->fHead || !sect2->fHead) { |
| 1980 break; | 2068 break; |
| 1981 } | 2069 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 } else if (intersections->isCoincident(index + 1)) { | 2174 } else if (intersections->isCoincident(index + 1)) { |
| 2087 intersections->removeOne(index + 1); | 2175 intersections->removeOne(index + 1); |
| 2088 --last; | 2176 --last; |
| 2089 } else { | 2177 } else { |
| 2090 intersections->setCoincident(index++); | 2178 intersections->setCoincident(index++); |
| 2091 } | 2179 } |
| 2092 intersections->setCoincident(index); | 2180 intersections->setCoincident(index); |
| 2093 } | 2181 } |
| 2094 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); | 2182 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); |
| 2095 } | 2183 } |
| OLD | NEW |