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

Side by Side Diff: src/pathops/SkOpCoincidence.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 2013 Google Inc. 2 * Copyright 2013 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 SkOpCoincidence_DEFINED 7 #ifndef SkOpCoincidence_DEFINED
8 #define SkOpCoincidence_DEFINED 8 #define SkOpCoincidence_DEFINED
9 9
10 #include "SkTDArray.h"
10 #include "SkOpTAllocator.h" 11 #include "SkOpTAllocator.h"
11 #include "SkOpSpan.h" 12 #include "SkOpSpan.h"
12 #include "SkPathOpsTypes.h" 13 #include "SkPathOpsTypes.h"
13 14
14 class SkOpPtT; 15 class SkOpPtT;
15 16 class SkOpSpanBase;
16 struct SkCoincidentSpans { 17
17 SkCoincidentSpans* fNext; 18 class SkCoincidentSpans {
18 SkOpPtT* fCoinPtTStart; 19 public:
19 SkOpPtT* fCoinPtTEnd; 20 const SkOpPtT* coinPtTEnd() const { return fCoinPtTEnd; }
20 SkOpPtT* fOppPtTStart; 21 const SkOpPtT* coinPtTStart() const { return fCoinPtTStart; }
21 SkOpPtT* fOppPtTEnd; 22
22 bool fFlipped; 23 // These return non-const pointers so that, as copies, they can be added
23 SkDEBUGCODE(int fID); 24 // to a new span pair
25 SkOpPtT* coinPtTEndWritable() const { return const_cast<SkOpPtT*>(fCoinPtTEn d); }
26 SkOpPtT* coinPtTStartWritable() const { return const_cast<SkOpPtT*>(fCoinPtT Start); }
27
28 bool collapsed(const SkOpPtT* ) const;
29 bool contains(const SkOpPtT* s, const SkOpPtT* e) const;
30 void correctEnds();
31 void correctOneEnd(const SkOpPtT* (SkCoincidentSpans::* getEnd)() const,
32 void (SkCoincidentSpans::* setEnd)(const SkOpPtT* ptT) );
33
34 #if DEBUG_COINCIDENCE_VERBOSE
35 bool debugExpand(const char* id, SkPathOpsDebug::GlitchLog* log) const;
36 #endif
24 37
25 int debugID() const { 38 int debugID() const {
26 return SkDEBUGRELEASE(fID, -1); 39 return SkDEBUGRELEASE(fID, -1);
27 } 40 }
28 41
42 void debugShow() const;
43 #ifdef SK_DEBUG
44 void debugStartCheck(const SkOpSpanBase* outer, const SkOpSpanBase* over,
45 const SkOpGlobalState* debugState) const;
46 #endif
29 void dump() const; 47 void dump() const;
48 bool expand();
49 bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
50 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
51 bool flipped() const { return fOppPtTStart->fT > fOppPtTEnd->fT; }
52 void init() { sk_bzero(this, sizeof(*this)); }
53 const SkOpPtT* oppPtTStart() const { return fOppPtTStart; }
54 const SkOpPtT* oppPtTEnd() const { return fOppPtTEnd; }
55 // These return non-const pointers so that, as copies, they can be added
56 // to a new span pair
57 SkOpPtT* oppPtTStartWritable() const { return const_cast<SkOpPtT*>(fOppPtTSt art); }
58 SkOpPtT* oppPtTEndWritable() const { return const_cast<SkOpPtT*>(fOppPtTEnd) ; }
59 SkCoincidentSpans* next() { return fNext; }
60 const SkCoincidentSpans* next() const { return fNext; }
61 SkCoincidentSpans** nextPtr() { return &fNext; }
62 int spanCount() const;
63
64 void set(SkCoincidentSpans* next, const SkOpPtT* coinPtTStart, const SkOpPtT * coinPtTEnd,
65 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd
66 SkDEBUGPARAMS(int id));
67
68 void setCoinPtTEnd(const SkOpPtT* ptT) {
69 SkASSERT(ptT == ptT->span()->ptT())
70 SkASSERT(!fCoinPtTStart || ptT->fT != fCoinPtTStart->fT);
71 SkASSERT(!fCoinPtTStart || fCoinPtTStart->segment() == ptT->segment());
72 fCoinPtTEnd = ptT;
73 ptT->setCoincident();
74 }
75
76 void setCoinPtTStart(const SkOpPtT* ptT) {
77 SkASSERT(ptT == ptT->span()->ptT())
78 SkASSERT(!fCoinPtTEnd || ptT->fT != fCoinPtTEnd->fT);
79 SkASSERT(!fCoinPtTEnd || fCoinPtTEnd->segment() == ptT->segment());
80 fCoinPtTStart = ptT;
81 ptT->setCoincident();
82 }
83
84 void setEnds(const SkOpPtT* coinPtTEnd, const SkOpPtT* oppPtTEnd) {
85 this->setCoinPtTEnd(coinPtTEnd);
86 this->setOppPtTEnd(oppPtTEnd);
87 }
88
89 void setOppPtTEnd(const SkOpPtT* ptT) {
90 SkASSERT(ptT == ptT->span()->ptT())
91 SkASSERT(!fOppPtTStart || ptT->fT != fOppPtTStart->fT);
92 SkASSERT(!fOppPtTStart || fOppPtTStart->segment() == ptT->segment());
93 fOppPtTEnd = ptT;
94 ptT->setCoincident();
95 }
96
97 void setOppPtTStart(const SkOpPtT* ptT) {
98 SkASSERT(ptT == ptT->span()->ptT())
99 SkASSERT(!fOppPtTEnd || ptT->fT != fOppPtTEnd->fT);
100 SkASSERT(!fOppPtTEnd || fOppPtTEnd->segment() == ptT->segment());
101 fOppPtTStart = ptT;
102 ptT->setCoincident();
103 }
104
105 void setStarts(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
106 this->setCoinPtTStart(coinPtTStart);
107 this->setOppPtTStart(oppPtTStart);
108 }
109
110 void setNext(SkCoincidentSpans* next) { fNext = next; }
111
112 bool startEquals(const SkOpSpanBase* outer, const SkOpSpanBase* over) const {
113 return fCoinPtTStart->span() == over && fOppPtTStart->span() == outer;
114 }
115 private:
116 SkCoincidentSpans* fNext;
117 const SkOpPtT* fCoinPtTStart;
118 const SkOpPtT* fCoinPtTEnd;
119 const SkOpPtT* fOppPtTStart;
120 const SkOpPtT* fOppPtTEnd;
121 SkDEBUGCODE(int fID);
30 }; 122 };
31 123
32 class SkOpCoincidence { 124 class SkOpCoincidence {
33 public: 125 public:
34 SkOpCoincidence() 126 SkOpCoincidence(SkOpGlobalState* globalState)
35 : fHead(nullptr) 127 : fHead(nullptr)
36 , fTop(nullptr) 128 , fTop(nullptr)
37 SkDEBUGPARAMS(fDebugState(nullptr)) 129 , fGlobalState(globalState)
38 { 130 , fContinue(false)
131 , fSpanDeleted(false)
132 , fPtAllocated(false)
133 , fCoinExtended(false)
134 , fSpanMerged(false) {
135 globalState->setCoincidence(this);
39 } 136 }
40 137
41 void add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart, 138 void add(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart,
42 SkOpPtT* oppPtTEnd, SkChunkAlloc* allocator); 139 SkOpPtT* oppPtTEnd);
43 bool addExpanded(SkChunkAlloc* allocator PATH_OPS_DEBUG_VALIDATE_PARAMS(SkO pGlobalState* )); 140 bool addEndMovedSpans();
44 bool addMissing(SkChunkAlloc* allocator); 141 bool addExpanded();
142 bool addMissing();
143 bool addUncommon();
45 bool apply(); 144 bool apply();
46 bool contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, 145 bool contains(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
47 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, bool fli pped) const; 146 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) const;
48 147 void correctEnds();
148
149 #if DEBUG_COINCIDENCE_VERBOSE
49 void debugAddExpanded(const char* id, SkPathOpsDebug::GlitchLog* ) const; 150 void debugAddExpanded(const char* id, SkPathOpsDebug::GlitchLog* ) const;
50 void debugAddMissing(const char* id, SkPathOpsDebug::GlitchLog* ) const; 151 void debugAddMissing(const char* id, SkPathOpsDebug::GlitchLog* ) const;
152 void debugAddOrOverlap(const SkOpSegment* coinSeg, const SkOpSegment* oppSeg ,
153 double coinTs, double coinTe, double oppTs, double op pTe,
154 const char* id, SkPathOpsDebug::GlitchLog* log) const ;
155 #endif
51 156
52 const SkOpAngle* debugAngle(int id) const { 157 const SkOpAngle* debugAngle(int id) const {
53 return SkDEBUGRELEASE(fDebugState->debugAngle(id), nullptr); 158 return SkDEBUGRELEASE(fGlobalState->debugAngle(id), nullptr);
54 } 159 }
160
161 #if DEBUG_COINCIDENCE_VERBOSE
162 void debugCheckOverlap(const char* id, SkPathOpsDebug::GlitchLog* log) const ;
163 void debugCheckValid(const char* id, SkPathOpsDebug::GlitchLog* log) const;
164 #endif
55 165
56 SkOpContour* debugContour(int id) { 166 SkOpContour* debugContour(int id) {
57 return SkDEBUGRELEASE(fDebugState->debugContour(id), nullptr); 167 return SkDEBUGRELEASE(fGlobalState->debugContour(id), nullptr);
58 } 168 }
59 169
170 #if DEBUG_COINCIDENCE_VERBOSE
60 bool debugExpand(const char* id, SkPathOpsDebug::GlitchLog* ) const; 171 bool debugExpand(const char* id, SkPathOpsDebug::GlitchLog* ) const;
61 void debugMark(const char* id, SkPathOpsDebug::GlitchLog* ) const; 172 void debugMark(const char* id, SkPathOpsDebug::GlitchLog* ) const;
173 void debugMarkCollapsed(const char* id, SkPathOpsDebug::GlitchLog* ,
174 const SkCoincidentSpans* coin, const SkOpPtT* test) const;
175 void debugMarkCollapsed(const char* id, SkPathOpsDebug::GlitchLog* , const S kOpPtT* test) const;
176 #endif
62 177
63 const SkOpPtT* debugPtT(int id) const { 178 const SkOpPtT* debugPtT(int id) const {
64 return SkDEBUGRELEASE(fDebugState->debugPtT(id), nullptr); 179 return SkDEBUGRELEASE(fGlobalState->debugPtT(id), nullptr);
65 } 180 }
66 181
67 const SkOpSegment* debugSegment(int id) const { 182 const SkOpSegment* debugSegment(int id) const {
68 return SkDEBUGRELEASE(fDebugState->debugSegment(id), nullptr); 183 return SkDEBUGRELEASE(fGlobalState->debugSegment(id), nullptr);
69 } 184 }
70 185
71 void debugSetGlobalState(SkOpGlobalState* debugState) { 186 #if DEBUG_COINCIDENCE_VERBOSE
72 SkDEBUGCODE(fDebugState = debugState); 187 void debugRemoveCollapsed(const char* id, SkPathOpsDebug::GlitchLog* ) const ;
73 } 188 void debugReorder(const char* id, SkPathOpsDebug::GlitchLog* ) const;
74 189 void debugRelease(const char* id, SkPathOpsDebug::GlitchLog* , const SkOpSeg ment* ) const;
75 void debugFixAligned(const char* id, SkPathOpsDebug::GlitchLog* ) const; 190 #endif
76 void debugShowCoincidence() const; 191 void debugShowCoincidence() const;
77 192
78 const SkOpSpanBase* debugSpan(int id) const { 193 const SkOpSpanBase* debugSpan(int id) const {
79 return SkDEBUGRELEASE(fDebugState->debugSpan(id), nullptr); 194 return SkDEBUGRELEASE(fGlobalState->debugSpan(id), nullptr);
80 } 195 }
81 196
82 void release(SkCoincidentSpans* ); 197 void debugValidate() const;
83 void dump() const; 198 void dump() const;
199 bool edge(const SkOpPtT* , bool* start) const;
84 bool expand(); 200 bool expand();
85 bool extend(SkOpPtT* coinPtTStart, SkOpPtT* coinPtTEnd, SkOpPtT* oppPtTStart , 201 bool extend(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const Sk OpPtT* oppPtTStart,
86 SkOpPtT* oppPtTEnd); 202 const SkOpPtT* oppPtTEnd);
87 bool findOverlaps(SkOpCoincidence* , SkChunkAlloc* allocator) const; 203 bool findOverlaps(SkOpCoincidence* ) const;
88 bool fixAligned(); 204 void fixUp(SkOpPtT* deleted, const SkOpPtT* kept);
89 void fixUp(SkOpPtT* deleted, SkOpPtT* kept); 205
206 SkOpGlobalState* globalState() {
207 return fGlobalState;
208 }
90 209
91 bool isEmpty() const { 210 bool isEmpty() const {
92 return !fHead; 211 return !fHead && !fTop;
93 } 212 }
94 213
95 bool mark(); 214 bool mark();
215 void markCollapsed(SkOpPtT* );
216
217 static bool Ordered(const SkOpPtT* coinPtTStart, const SkOpPtT* oppPtTStart) {
218 return Ordered(coinPtTStart->segment(), oppPtTStart->segment());
219 }
220
221 static bool Ordered(const SkOpSegment* coin, const SkOpSegment* opp);
222 void release(const SkOpSegment* );
223 bool removeCollapsed();
224 bool reorder();
96 225
97 private: 226 private:
98 bool addIfMissing(const SkCoincidentSpans* outer, SkOpPtT* over1s, SkOpPtT* over1e, 227 void add(const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, const SkOpP tT* oppPtTStart,
99 SkChunkAlloc* ); 228 const SkOpPtT* oppPtTEnd) {
229 this->add(const_cast<SkOpPtT*>(coinPtTStart), const_cast<SkOpPtT*>(coinP tTEnd),
230 const_cast<SkOpPtT*>(oppPtTStart), const_cast<SkOpPtT*>(oppPtTEnd));
231 }
232
233 void addEndMovedSpans(const SkOpSpan* base, const SkOpSpanBase* testSpan);
234 bool addEndMovedSpans(const SkOpPtT* ptT);
235
236 bool addIfMissing(const SkCoincidentSpans* outer, SkOpPtT* over1s, SkOpPtT* over1e);
237
238 bool addIfMissing(const SkCoincidentSpans* outer, const SkOpPtT* over1s,
239 const SkOpPtT* over1e) {
240 return addIfMissing(outer, const_cast<SkOpPtT*>(over1s), const_cast<SkOp PtT*>(over1e));
241 }
242
100 bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, 243 bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e,
101 const SkOpPtT* over2s, const SkOpPtT* over2e, 244 const SkOpPtT* over2s, const SkOpPtT* over2e,
102 double tStart, double tEnd, 245 double tStart, double tEnd,
103 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, 246 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
104 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd, 247 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd);
105 SkChunkAlloc* ); 248
106 bool addOverlap(SkOpSegment* seg1, SkOpSegment* seg1o, SkOpSegment* seg2, Sk OpSegment* seg2o, 249 bool addIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e,
107 SkOpPtT* overS, SkOpPtT* overE, SkChunkAlloc* ); 250 const SkOpPtT* over2s, const SkOpPtT* over2e,
108 bool debugAddIfMissing(const SkCoincidentSpans* outer, const SkOpPtT* over1s , 251 double tStart, double tEnd,
109 const SkOpPtT* over1e) const; 252 const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
110 bool debugAddIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e, 253 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) {
254 return addIfMissing(over1s, over1e, over2s, over2e, tStart, tEnd,
255 const_cast<SkOpPtT*>(coinPtTStart), coinPtTEnd,
256 const_cast<SkOpPtT*>(oppPtTStart), oppPtTEnd);
257 }
258
259 bool addOrOverlap(SkOpSegment* coinSeg, SkOpSegment* oppSeg,
260 double coinTs, double coinTe, double oppTs, double oppTe);
261 bool addOverlap(const SkOpSegment* seg1, const SkOpSegment* seg1o,
262 const SkOpSegment* seg2, const SkOpSegment* seg2o,
263 const SkOpPtT* overS, const SkOpPtT* overE);
264 bool alreadyAdded(const SkCoincidentSpans* check, const SkCoincidentSpans* o uter,
265 const SkOpPtT* over1s, const SkOpPtT* over1e) const;
266 bool checkOverlap(SkCoincidentSpans* check,
267 const SkOpSegment* coinSeg, const SkOpSegment* oppSeg,
268 double coinTs, double coinTe, double oppTs, double oppTe,
269 SkTDArray<SkCoincidentSpans*>* overlaps) const;
270 bool contains(const SkOpSegment* seg, const SkOpSegment* opp, double oppT) c onst;
271 bool contains(const SkCoincidentSpans* coin, const SkOpSegment* seg,
272 const SkOpSegment* opp, double oppT) const;
273 #if DEBUG_COINCIDENCE_VERBOSE
274 void debugAddIfMissing(const SkCoincidentSpans* outer, const SkOpPtT* over1s ,
275 const SkOpPtT* over1e, const char* id, SkPathOpsDebug ::GlitchLog*) const;
276 void debugAddIfMissing(const SkOpPtT* over1s, const SkOpPtT* over1e,
111 const SkOpPtT* over2s, const SkOpPtT* over2e, 277 const SkOpPtT* over2s, const SkOpPtT* over2e,
112 double tStart, double tEnd, 278 double tStart, double tEnd,
113 SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd, 279 const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEn d,
114 SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd) const ; 280 const SkOpPtT* oppPtTStart, const SkOpPtT* oppPtTEnd,
281 const char* id, SkPathOpsDebug::GlitchLog*) const;
282 #endif
283 void fixUp(SkCoincidentSpans* coin, SkOpPtT* deleted, const SkOpPtT* kept);
284 void markCollapsed(SkCoincidentSpans* head, SkOpPtT* test);
115 bool overlap(const SkOpPtT* coinStart1, const SkOpPtT* coinEnd1, 285 bool overlap(const SkOpPtT* coinStart1, const SkOpPtT* coinEnd1,
116 const SkOpPtT* coinStart2, const SkOpPtT* coinEnd2, 286 const SkOpPtT* coinStart2, const SkOpPtT* coinEnd2,
117 double* overS, double* overE) const; 287 double* overS, double* overE) const;
118 288 bool release(SkCoincidentSpans* coin, SkCoincidentSpans* );
289 void restoreHead();
119 bool testForCoincidence(const SkCoincidentSpans* outer, const SkOpPtT* testS , 290 bool testForCoincidence(const SkCoincidentSpans* outer, const SkOpPtT* testS ,
120 const SkOpPtT* testE) const; 291 const SkOpPtT* testE) const;
292 static void TRange(const SkOpPtT* overS, const SkOpPtT* overE, double tStart ,
293 double tEnd, const SkOpPtT* coinPtTStart, const SkOpPtT* coinPtTEnd,
294 double* coinTs, double* coinTe);
295
121 SkCoincidentSpans* fHead; 296 SkCoincidentSpans* fHead;
122 SkCoincidentSpans* fTop; 297 SkCoincidentSpans* fTop;
123 SkDEBUGCODE_(SkOpGlobalState* fDebugState); 298 SkOpGlobalState* fGlobalState;
299 bool fContinue;
300 bool fSpanDeleted;
301 bool fPtAllocated;
302 bool fCoinExtended;
303 bool fSpanMerged;
124 }; 304 };
125 305
126 #endif 306 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698