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 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); | 980 bool deleteEmptySpans = this->updateBounded(first, last, oppFirst); |
981 deleteEmptySpans |= sect2->updateBounded(oppFirst, oppLast, first); | 981 deleteEmptySpans |= sect2->updateBounded(oppFirst, oppLast, first); |
982 this->removeSpanRange(first, last); | 982 this->removeSpanRange(first, last); |
983 sect2->removeSpanRange(oppFirst, oppLast); | 983 sect2->removeSpanRange(oppFirst, oppLast); |
984 first->fStartT = start1s; | 984 first->fStartT = start1s; |
985 first->fEndT = start1e; | 985 first->fEndT = start1e; |
986 first->resetBounds(fCurve); | 986 first->resetBounds(fCurve); |
987 first->fCoinStart.setPerp(fCurve, start1s, fCurve[0], sect2->fCurve); | 987 first->fCoinStart.setPerp(fCurve, start1s, fCurve[0], sect2->fCurve); |
988 first->fCoinEnd.setPerp(fCurve, start1e, fCurve[TCurve::kPointLast], sect2->
fCurve); | 988 first->fCoinEnd.setPerp(fCurve, start1e, fCurve[TCurve::kPointLast], sect2->
fCurve); |
989 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); | 989 bool oppMatched = first->fCoinStart.perpT() < first->fCoinEnd.perpT(); |
990 double oppStartT = SkTMax(0., first->fCoinStart.perpT()); | 990 double oppStartT = first->fCoinStart.perpT() == -1 ? 0 : SkTMax(0., first->f
CoinStart.perpT()); |
991 double oppEndT = SkTMin(1., first->fCoinEnd.perpT()); | 991 double oppEndT = first->fCoinEnd.perpT() == -1 ? 1 : SkTMin(1., first->fCoin
End.perpT()); |
992 if (!oppMatched) { | 992 if (!oppMatched) { |
993 SkTSwap(oppStartT, oppEndT); | 993 SkTSwap(oppStartT, oppEndT); |
994 } | 994 } |
995 oppFirst->fStartT = oppStartT; | 995 oppFirst->fStartT = oppStartT; |
996 oppFirst->fEndT = oppEndT; | 996 oppFirst->fEndT = oppEndT; |
997 oppFirst->resetBounds(sect2->fCurve); | 997 oppFirst->resetBounds(sect2->fCurve); |
998 this->removeCoincident(first, false); | 998 this->removeCoincident(first, false); |
999 sect2->removeCoincident(oppFirst, true); | 999 sect2->removeCoincident(oppFirst, true); |
1000 if (deleteEmptySpans) { | 1000 if (deleteEmptySpans) { |
1001 this->deleteEmptySpans(); | 1001 this->deleteEmptySpans(); |
(...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2079 if (coinLoopCount == kMaxCoinLoopCount) { | 2079 if (coinLoopCount == kMaxCoinLoopCount) { |
2080 start1s = sect1->fHead->fStartT; | 2080 start1s = sect1->fHead->fStartT; |
2081 start1e = sect1->tail()->fEndT; | 2081 start1e = sect1->tail()->fEndT; |
2082 } | 2082 } |
2083 sect1->coincidentCheck(sect2); | 2083 sect1->coincidentCheck(sect2); |
2084 sect1->validate(); | 2084 sect1->validate(); |
2085 sect2->validate(); | 2085 sect2->validate(); |
2086 #if DEBUG_T_SECT_LOOP_COUNT | 2086 #if DEBUG_T_SECT_LOOP_COUNT |
2087 intersections->debugBumpLoopCount(SkIntersections::kCoinCheck_DebugL
oop); | 2087 intersections->debugBumpLoopCount(SkIntersections::kCoinCheck_DebugL
oop); |
2088 #endif | 2088 #endif |
2089 if (!--coinLoopCount) { | 2089 if (!--coinLoopCount && sect1->fHead && sect2->fHead) { |
2090 /* All known working cases resolve in two tries. Sadly, cubicCon
icTests[0] | 2090 /* All known working cases resolve in two tries. Sadly, cubicCon
icTests[0] |
2091 gets stuck in a loop. It adds an extension to allow a coincid
ent end | 2091 gets stuck in a loop. It adds an extension to allow a coincid
ent end |
2092 perpendicular to track its intersection in the opposite curve
. However, | 2092 perpendicular to track its intersection in the opposite curve
. However, |
2093 the bounding box of the extension does not intersect the orig
inal curve, | 2093 the bounding box of the extension does not intersect the orig
inal curve, |
2094 so the extension is discarded, only to be added again the nex
t time around. */ | 2094 so the extension is discarded, only to be added again the nex
t time around. */ |
2095 sect1->coincidentForce(sect2, start1s, start1e); | 2095 sect1->coincidentForce(sect2, start1s, start1e); |
2096 sect1->validate(); | 2096 sect1->validate(); |
2097 sect2->validate(); | 2097 sect2->validate(); |
2098 } | 2098 } |
2099 } | 2099 } |
(...skipping 20 matching lines...) Expand all Loading... |
2120 } while (true); | 2120 } while (true); |
2121 SkTSpan<TCurve, OppCurve>* coincident = sect1->fCoincident; | 2121 SkTSpan<TCurve, OppCurve>* coincident = sect1->fCoincident; |
2122 if (coincident) { | 2122 if (coincident) { |
2123 // if there is more than one coincident span, check loosely to see if th
ey should be joined | 2123 // if there is more than one coincident span, check loosely to see if th
ey should be joined |
2124 if (coincident->fNext) { | 2124 if (coincident->fNext) { |
2125 sect1->mergeCoincidence(sect2); | 2125 sect1->mergeCoincidence(sect2); |
2126 coincident = sect1->fCoincident; | 2126 coincident = sect1->fCoincident; |
2127 } | 2127 } |
2128 SkASSERT(sect2->fCoincident); // courtesy check : coincidence only look
s at sect 1 | 2128 SkASSERT(sect2->fCoincident); // courtesy check : coincidence only look
s at sect 1 |
2129 do { | 2129 do { |
2130 SkASSERT(coincident->fCoinStart.isCoincident()); | 2130 if (!coincident->fCoinStart.isCoincident()) { |
2131 SkASSERT(coincident->fCoinEnd.isCoincident()); | 2131 continue; |
| 2132 } |
| 2133 if (!coincident->fCoinEnd.isCoincident()) { |
| 2134 continue; |
| 2135 } |
2132 int index = intersections->insertCoincident(coincident->fStartT, | 2136 int index = intersections->insertCoincident(coincident->fStartT, |
2133 coincident->fCoinStart.perpT(), coincident->fPart[0]); | 2137 coincident->fCoinStart.perpT(), coincident->fPart[0]); |
2134 if ((intersections->insertCoincident(coincident->fEndT, | 2138 if ((intersections->insertCoincident(coincident->fEndT, |
2135 coincident->fCoinEnd.perpT(), | 2139 coincident->fCoinEnd.perpT(), |
2136 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) { | 2140 coincident->fPart[TCurve::kPointLast]) < 0) && index >= 0) { |
2137 intersections->clearCoincidence(index); | 2141 intersections->clearCoincidence(index); |
2138 } | 2142 } |
2139 } while ((coincident = coincident->fNext)); | 2143 } while ((coincident = coincident->fNext)); |
2140 } | 2144 } |
2141 int zeroOneSet = EndsEqual(sect1, sect2, intersections); | 2145 int zeroOneSet = EndsEqual(sect1, sect2, intersections); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2224 } else if (intersections->isCoincident(index + 1)) { | 2228 } else if (intersections->isCoincident(index + 1)) { |
2225 intersections->removeOne(index + 1); | 2229 intersections->removeOne(index + 1); |
2226 --last; | 2230 --last; |
2227 } else { | 2231 } else { |
2228 intersections->setCoincident(index++); | 2232 intersections->setCoincident(index++); |
2229 } | 2233 } |
2230 intersections->setCoincident(index); | 2234 intersections->setCoincident(index); |
2231 } | 2235 } |
2232 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); | 2236 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); |
2233 } | 2237 } |
OLD | NEW |