Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: src/pathops/SkPathOpsTSect.h

Issue 2128633003: pathops coincidence and security rewrite (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: require resulting t to be between 0 and 1 Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #ifndef SkPathOpsTSect_DEFINED 7 #ifndef SkPathOpsTSect_DEFINED
8 #define SkPathOpsTSect_DEFINED 8 #define SkPathOpsTSect_DEFINED
9 9
10 #include "SkChunkAlloc.h" 10 #include "SkChunkAlloc.h"
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 enum { 243 enum {
244 kZeroS1Set = 1, 244 kZeroS1Set = 1,
245 kOneS1Set = 2, 245 kOneS1Set = 2,
246 kZeroS2Set = 4, 246 kZeroS2Set = 4,
247 kOneS2Set = 8 247 kOneS2Set = 8
248 }; 248 };
249 249
250 SkTSpan<TCurve, OppCurve>* addFollowing(SkTSpan<TCurve, OppCurve>* prior); 250 SkTSpan<TCurve, OppCurve>* addFollowing(SkTSpan<TCurve, OppCurve>* prior);
251 void addForPerp(SkTSpan<OppCurve, TCurve>* span, double t); 251 void addForPerp(SkTSpan<OppCurve, TCurve>* span, double t);
252 SkTSpan<TCurve, OppCurve>* addOne(); 252 SkTSpan<TCurve, OppCurve>* addOne();
253 253
254 SkTSpan<TCurve, OppCurve>* addSplitAt(SkTSpan<TCurve, OppCurve>* span, doubl e t) { 254 SkTSpan<TCurve, OppCurve>* addSplitAt(SkTSpan<TCurve, OppCurve>* span, doubl e t) {
255 SkTSpan<TCurve, OppCurve>* result = this->addOne(); 255 SkTSpan<TCurve, OppCurve>* result = this->addOne();
256 result->splitAt(span, t, &fHeap); 256 result->splitAt(span, t, &fHeap);
257 result->initBounds(fCurve); 257 result->initBounds(fCurve);
258 span->initBounds(fCurve); 258 span->initBounds(fCurve);
259 return result; 259 return result;
260 } 260 }
261 261
262 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt ep, double* t, 262 bool binarySearchCoin(SkTSect<OppCurve, TCurve>* , double tStart, double tSt ep, double* t,
263 double* oppT); 263 double* oppT);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 void SkTCoincident<TCurve, OppCurve>::setPerp(const TCurve& c1, double t, 336 void SkTCoincident<TCurve, OppCurve>::setPerp(const TCurve& c1, double t,
337 const SkDPoint& cPt, const OppCurve& c2) { 337 const SkDPoint& cPt, const OppCurve& c2) {
338 SkDVector dxdy = c1.dxdyAtT(t); 338 SkDVector dxdy = c1.dxdyAtT(t);
339 SkDLine perp = {{ cPt, {cPt.fX + dxdy.fY, cPt.fY - dxdy.fX} }}; 339 SkDLine perp = {{ cPt, {cPt.fX + dxdy.fY, cPt.fY - dxdy.fX} }};
340 SkIntersections i; 340 SkIntersections i;
341 int used = i.intersectRay(c2, perp); 341 int used = i.intersectRay(c2, perp);
342 // only keep closest 342 // only keep closest
343 if (used == 0 || used == 3) { 343 if (used == 0 || used == 3) {
344 this->init(); 344 this->init();
345 return; 345 return;
346 } 346 }
347 fPerpT = i[0][0]; 347 fPerpT = i[0][0];
348 fPerpPt = i.pt(0); 348 fPerpPt = i.pt(0);
349 SkASSERT(used <= 2); 349 SkASSERT(used <= 2);
350 if (used == 2) { 350 if (used == 2) {
351 double distSq = (fPerpPt - cPt).lengthSquared(); 351 double distSq = (fPerpPt - cPt).lengthSquared();
352 double dist2Sq = (i.pt(1) - cPt).lengthSquared(); 352 double dist2Sq = (i.pt(1) - cPt).lengthSquared();
353 if (dist2Sq < distSq) { 353 if (dist2Sq < distSq) {
354 fPerpT = i[0][1]; 354 fPerpT = i[0][1];
355 fPerpPt = i.pt(1); 355 fPerpPt = i.pt(1);
356 } 356 }
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 } else { 851 } else {
852 result = new (fHeap.allocThrow(sizeof(SkTSpan<TCurve, OppCurve>)))( 852 result = new (fHeap.allocThrow(sizeof(SkTSpan<TCurve, OppCurve>)))(
853 SkTSpan<TCurve, OppCurve>); 853 SkTSpan<TCurve, OppCurve>);
854 #if DEBUG_T_SECT 854 #if DEBUG_T_SECT
855 ++fDebugAllocatedCount; 855 ++fDebugAllocatedCount;
856 #endif 856 #endif
857 } 857 }
858 result->reset(); 858 result->reset();
859 result->fHasPerp = false; 859 result->fHasPerp = false;
860 result->fDeleted = false; 860 result->fDeleted = false;
861 ++fActiveCount; 861 ++fActiveCount;
862 PATH_OPS_DEBUG_T_SECT_CODE(result->fID = fDebugCount++ * 2 + fID); 862 PATH_OPS_DEBUG_T_SECT_CODE(result->fID = fDebugCount++ * 2 + fID);
863 SkDEBUGCODE(result->fDebugSect = this); 863 SkDEBUGCODE(result->fDebugSect = this);
864 #ifdef SK_DEBUG 864 #ifdef SK_DEBUG
865 result->fPart.debugInit(); 865 result->fPart.debugInit();
866 result->fCoinStart.debugInit(); 866 result->fCoinStart.debugInit();
867 result->fCoinEnd.debugInit(); 867 result->fCoinEnd.debugInit();
868 result->fPrev = result->fNext = nullptr; 868 result->fPrev = result->fNext = nullptr;
869 result->fBounds.debugInit(); 869 result->fBounds.debugInit();
870 result->fStartT = result->fEndT = result->fBoundsMax = SK_ScalarNaN; 870 result->fStartT = result->fEndT = result->fBoundsMax = SK_ScalarNaN;
871 result->fCollapsed = result->fIsLinear = result->fIsLine = 0xFF; 871 result->fCollapsed = result->fIsLinear = result->fIsLine = 0xFF;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 this->validate(); 962 this->validate();
963 sect2->validate(); 963 sect2->validate();
964 this->computePerpendiculars(sect2, first, last); 964 this->computePerpendiculars(sect2, first, last);
965 this->validate(); 965 this->validate();
966 sect2->validate(); 966 sect2->validate();
967 // check to see if a range of points are on the curve 967 // check to see if a range of points are on the curve
968 SkTSpan<TCurve, OppCurve>* coinStart = first; 968 SkTSpan<TCurve, OppCurve>* coinStart = first;
969 do { 969 do {
970 coinStart = this->extractCoincident(sect2, coinStart, last); 970 coinStart = this->extractCoincident(sect2, coinStart, last);
971 } while (coinStart && !last->fDeleted); 971 } while (coinStart && !last->fDeleted);
972 if (!fHead || !sect2->fHead) {
973 break;
974 }
972 } while ((first = next)); 975 } while ((first = next));
973 } 976 }
974 977
975 template<typename TCurve, typename OppCurve> 978 template<typename TCurve, typename OppCurve>
976 void SkTSect<TCurve, OppCurve>::coincidentForce(SkTSect<OppCurve, TCurve>* sect2 , 979 void SkTSect<TCurve, OppCurve>::coincidentForce(SkTSect<OppCurve, TCurve>* sect2 ,
977 double start1s, double start1e) { 980 double start1s, double start1e) {
978 SkTSpan<TCurve, OppCurve>* first = fHead; 981 SkTSpan<TCurve, OppCurve>* first = fHead;
979 SkTSpan<TCurve, OppCurve>* last = this->tail(); 982 SkTSpan<TCurve, OppCurve>* last = this->tail();
980 SkTSpan<OppCurve, TCurve>* oppFirst = sect2->fHead; 983 SkTSpan<OppCurve, TCurve>* oppFirst = sect2->fHead;
981 SkTSpan<OppCurve, TCurve>* oppLast = sect2->tail(); 984 SkTSpan<OppCurve, TCurve>* oppLast = sect2->tail();
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 sect2->validateBounded(); 1204 sect2->validateBounded();
1202 last = first->fNext; 1205 last = first->fNext;
1203 this->removeCoincident(first, false); 1206 this->removeCoincident(first, false);
1204 sect2->removeCoincident(oppFirst, true); 1207 sect2->removeCoincident(oppFirst, true);
1205 if (deleteEmptySpans) { 1208 if (deleteEmptySpans) {
1206 this->deleteEmptySpans(); 1209 this->deleteEmptySpans();
1207 sect2->deleteEmptySpans(); 1210 sect2->deleteEmptySpans();
1208 } 1211 }
1209 this->validate(); 1212 this->validate();
1210 sect2->validate(); 1213 sect2->validate();
1211 return last && !last->fDeleted ? last : nullptr; 1214 return last && !last->fDeleted && fHead && sect2->fHead ? last : nullptr;
1212 } 1215 }
1213 1216
1214 template<typename TCurve, typename OppCurve> 1217 template<typename TCurve, typename OppCurve>
1215 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::findCoincidentRun( 1218 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::findCoincidentRun(
1216 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>** lastPtr) { 1219 SkTSpan<TCurve, OppCurve>* first, SkTSpan<TCurve, OppCurve>** lastPtr) {
1217 SkTSpan<TCurve, OppCurve>* work = first; 1220 SkTSpan<TCurve, OppCurve>* work = first;
1218 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr; 1221 SkTSpan<TCurve, OppCurve>* lastCandidate = nullptr;
1219 first = nullptr; 1222 first = nullptr;
1220 // find the first fully coincident span 1223 // find the first fully coincident span
1221 do { 1224 do {
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 double t2) const { 1507 double t2) const {
1505 SkDVector dxdy = this->fCurve.dxdyAtT(t); 1508 SkDVector dxdy = this->fCurve.dxdyAtT(t);
1506 SkDVector dxdy2 = sect2->fCurve.dxdyAtT(t2); 1509 SkDVector dxdy2 = sect2->fCurve.dxdyAtT(t2);
1507 return dxdy.dot(dxdy2) >= 0; 1510 return dxdy.dot(dxdy2) >= 0;
1508 } 1511 }
1509 1512
1510 template<typename TCurve, typename OppCurve> 1513 template<typename TCurve, typename OppCurve>
1511 void SkTSect<TCurve, OppCurve>::matchedDirCheck(double t, const SkTSect<OppCurve , TCurve>* sect2, 1514 void SkTSect<TCurve, OppCurve>::matchedDirCheck(double t, const SkTSect<OppCurve , TCurve>* sect2,
1512 double t2, bool* calcMatched, bool* oppMatched) const { 1515 double t2, bool* calcMatched, bool* oppMatched) const {
1513 if (*calcMatched) { 1516 if (*calcMatched) {
1514 SkASSERT(*oppMatched == this->matchedDirection(t, sect2, t2)); 1517 SkASSERT(*oppMatched == this->matchedDirection(t, sect2, t2));
1515 } else { 1518 } else {
1516 *oppMatched = this->matchedDirection(t, sect2, t2); 1519 *oppMatched = this->matchedDirection(t, sect2, t2);
1517 *calcMatched = true; 1520 *calcMatched = true;
1518 } 1521 }
1519 } 1522 }
1520 1523
1521 template<typename TCurve, typename OppCurve> 1524 template<typename TCurve, typename OppCurve>
1522 void SkTSect<TCurve, OppCurve>::mergeCoincidence(SkTSect<OppCurve, TCurve>* sect 2) { 1525 void SkTSect<TCurve, OppCurve>::mergeCoincidence(SkTSect<OppCurve, TCurve>* sect 2) {
1523 double smallLimit = 0; 1526 double smallLimit = 0;
1524 do { 1527 do {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 template<typename TCurve, typename OppCurve> 1580 template<typename TCurve, typename OppCurve>
1578 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::prev( 1581 SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::prev(
1579 SkTSpan<TCurve, OppCurve>* span) const { 1582 SkTSpan<TCurve, OppCurve>* span) const {
1580 SkTSpan<TCurve, OppCurve>* result = nullptr; 1583 SkTSpan<TCurve, OppCurve>* result = nullptr;
1581 SkTSpan<TCurve, OppCurve>* test = fHead; 1584 SkTSpan<TCurve, OppCurve>* test = fHead;
1582 while (span != test) { 1585 while (span != test) {
1583 result = test; 1586 result = test;
1584 test = test->fNext; 1587 test = test->fNext;
1585 SkASSERT(test); 1588 SkASSERT(test);
1586 } 1589 }
1587 return result; 1590 return result;
1588 } 1591 }
1589 1592
1590 template<typename TCurve, typename OppCurve> 1593 template<typename TCurve, typename OppCurve>
1591 void SkTSect<TCurve, OppCurve>::recoverCollapsed() { 1594 void SkTSect<TCurve, OppCurve>::recoverCollapsed() {
1592 SkTSpan<TCurve, OppCurve>* deleted = fDeleted; 1595 SkTSpan<TCurve, OppCurve>* deleted = fDeleted;
1593 while (deleted) { 1596 while (deleted) {
1594 SkTSpan<TCurve, OppCurve>* delNext = deleted->fNext; 1597 SkTSpan<TCurve, OppCurve>* delNext = deleted->fNext;
1595 if (deleted->fCollapsed) { 1598 if (deleted->fCollapsed) {
1596 SkTSpan<TCurve, OppCurve>** spanPtr = &fHead; 1599 SkTSpan<TCurve, OppCurve>** spanPtr = &fHead;
1597 while (*spanPtr && (*spanPtr)->fEndT <= deleted->fStartT) { 1600 while (*spanPtr && (*spanPtr)->fEndT <= deleted->fStartT) {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 || fC2Span->startT() == mate.fC2Span->endT(); 1935 || fC2Span->startT() == mate.fC2Span->endT();
1933 } 1936 }
1934 1937
1935 void merge(const SkClosestRecord& mate) { 1938 void merge(const SkClosestRecord& mate) {
1936 fC1Span = mate.fC1Span; 1939 fC1Span = mate.fC1Span;
1937 fC2Span = mate.fC2Span; 1940 fC2Span = mate.fC2Span;
1938 fClosest = mate.fClosest; 1941 fClosest = mate.fClosest;
1939 fC1Index = mate.fC1Index; 1942 fC1Index = mate.fC1Index;
1940 fC2Index = mate.fC2Index; 1943 fC2Index = mate.fC2Index;
1941 } 1944 }
1942 1945
1943 void reset() { 1946 void reset() {
1944 fClosest = FLT_MAX; 1947 fClosest = FLT_MAX;
1945 SkDEBUGCODE(fC1Span = nullptr); 1948 SkDEBUGCODE(fC1Span = nullptr);
1946 SkDEBUGCODE(fC2Span = nullptr); 1949 SkDEBUGCODE(fC2Span = nullptr);
1947 SkDEBUGCODE(fC1Index = fC2Index = -1); 1950 SkDEBUGCODE(fC1Index = fC2Index = -1);
1948 } 1951 }
1949 1952
1950 void update(const SkClosestRecord& mate) { 1953 void update(const SkClosestRecord& mate) {
1951 fC1StartT = SkTMin(fC1StartT, mate.fC1StartT); 1954 fC1StartT = SkTMin(fC1StartT, mate.fC1StartT);
1952 fC1EndT = SkTMax(fC1EndT, mate.fC1EndT); 1955 fC1EndT = SkTMax(fC1EndT, mate.fC1EndT);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 sect1->validate(); 2095 sect1->validate();
2093 sect2->validate(); 2096 sect2->validate();
2094 #if DEBUG_T_SECT_LOOP_COUNT 2097 #if DEBUG_T_SECT_LOOP_COUNT
2095 intersections->debugBumpLoopCount(SkIntersections::kCoinCheck_DebugL oop); 2098 intersections->debugBumpLoopCount(SkIntersections::kCoinCheck_DebugL oop);
2096 #endif 2099 #endif
2097 if (!--coinLoopCount && sect1->fHead && sect2->fHead) { 2100 if (!--coinLoopCount && sect1->fHead && sect2->fHead) {
2098 /* All known working cases resolve in two tries. Sadly, cubicCon icTests[0] 2101 /* All known working cases resolve in two tries. Sadly, cubicCon icTests[0]
2099 gets stuck in a loop. It adds an extension to allow a coincid ent end 2102 gets stuck in a loop. It adds an extension to allow a coincid ent end
2100 perpendicular to track its intersection in the opposite curve . However, 2103 perpendicular to track its intersection in the opposite curve . However,
2101 the bounding box of the extension does not intersect the orig inal curve, 2104 the bounding box of the extension does not intersect the orig inal curve,
2102 so the extension is discarded, only to be added again the nex t time around. */ 2105 so the extension is discarded, only to be added again the nex t time around. */
2103 sect1->coincidentForce(sect2, start1s, start1e); 2106 sect1->coincidentForce(sect2, start1s, start1e);
2104 sect1->validate(); 2107 sect1->validate();
2105 sect2->validate(); 2108 sect2->validate();
2106 } 2109 }
2107 } 2110 }
2108 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT 2111 if (sect1->fActiveCount >= COINCIDENT_SPAN_COUNT
2109 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) { 2112 && sect2->fActiveCount >= COINCIDENT_SPAN_COUNT) {
2110 sect1->computePerpendiculars(sect2, sect1->fHead, sect1->tail()); 2113 sect1->computePerpendiculars(sect2, sect1->fHead, sect1->tail());
2111 sect2->computePerpendiculars(sect1, sect2->fHead, sect2->tail()); 2114 sect2->computePerpendiculars(sect1, sect2->fHead, sect2->tail());
2112 sect1->removeByPerpendicular(sect2); 2115 sect1->removeByPerpendicular(sect2);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2238 --last; 2241 --last;
2239 } else { 2242 } else {
2240 intersections->setCoincident(index++); 2243 intersections->setCoincident(index++);
2241 } 2244 }
2242 intersections->setCoincident(index); 2245 intersections->setCoincident(index);
2243 } 2246 }
2244 SkASSERT(intersections->used() <= TCurve::kMaxIntersections); 2247 SkASSERT(intersections->used() <= TCurve::kMaxIntersections);
2245 } 2248 }
2246 2249
2247 #endif 2250 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698