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

Side by Side Diff: src/pathops/SkOpContour.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 SkOpContour_DEFINED 7 #ifndef SkOpContour_DEFINED
8 #define SkOpContour_DEFINED 8 #define SkOpContour_DEFINED
9 9
10 #include "SkOpSegment.h" 10 #include "SkOpSegment.h"
11 #include "SkTDArray.h" 11 #include "SkTDArray.h"
12 #include "SkTSort.h" 12 #include "SkTSort.h"
13 13
14 class SkChunkAlloc;
15 enum class SkOpRayDir; 14 enum class SkOpRayDir;
16 struct SkOpRayHit; 15 struct SkOpRayHit;
17 class SkPathWriter; 16 class SkPathWriter;
18 17
19 class SkOpContour { 18 class SkOpContour {
20 public: 19 public:
21 SkOpContour() { 20 SkOpContour() {
22 reset(); 21 reset();
23 } 22 }
24 23
25 ~SkOpContour() { 24 ~SkOpContour() {
26 if (fNext) { 25 if (fNext) {
27 fNext->~SkOpContour(); 26 fNext->~SkOpContour();
28 } 27 }
29 } 28 }
30 29
31 bool operator<(const SkOpContour& rh) const { 30 bool operator<(const SkOpContour& rh) const {
32 return fBounds.fTop == rh.fBounds.fTop 31 return fBounds.fTop == rh.fBounds.fTop
33 ? fBounds.fLeft < rh.fBounds.fLeft 32 ? fBounds.fLeft < rh.fBounds.fLeft
34 : fBounds.fTop < rh.fBounds.fTop; 33 : fBounds.fTop < rh.fBounds.fTop;
35 } 34 }
36 35
37 void addAlignIntersections(SkOpContourHead* contourList, SkChunkAlloc* alloc ator) { 36 void addConic(SkPoint pts[3], SkScalar weight) {
38 SkASSERT(fCount > 0); 37 appendSegment().addConic(pts, weight, this);
39 SkOpSegment* segment = &fHead;
40 do {
41 segment->addAlignIntersections(contourList, allocator);
42 } while ((segment = segment->next()));
43 } 38 }
44 39
45 void addConic(SkPoint pts[3], SkScalar weight, SkChunkAlloc* allocator) { 40 void addCubic(SkPoint pts[4]) {
46 appendSegment(allocator).addConic(pts, weight, this); 41 appendSegment().addCubic(pts, this);
47 } 42 }
48 43
49 void addCubic(SkPoint pts[4], SkChunkAlloc* allocator) { 44 SkOpSegment* addCurve(SkPath::Verb verb, const SkPoint pts[4]);
50 appendSegment(allocator).addCubic(pts, this); 45
46 SkOpSegment* addLine(SkPoint pts[2]) {
47 return appendSegment().addLine(pts, this);
51 } 48 }
52 49
53 SkOpSegment* addCurve(SkPath::Verb verb, const SkPoint pts[4], SkChunkAlloc* allocator); 50 void addQuad(SkPoint pts[3]) {
54 51 appendSegment().addQuad(pts, this);
55 void addLine(SkPoint pts[2], SkChunkAlloc* allocator) {
56 appendSegment(allocator).addLine(pts, this);
57 } 52 }
58 53
59 void addQuad(SkPoint pts[3], SkChunkAlloc* allocator) { 54 SkOpSegment& appendSegment() {
60 appendSegment(allocator).addQuad(pts, this);
61 }
62
63 void align() {
64 SkASSERT(fCount > 0);
65 SkOpSegment* segment = &fHead;
66 do {
67 segment->align();
68 } while ((segment = segment->next()));
69 }
70
71 SkOpSegment& appendSegment(SkChunkAlloc* allocator) {
72 SkOpSegment* result = fCount++ 55 SkOpSegment* result = fCount++
73 ? SkOpTAllocator<SkOpSegment>::Allocate(allocator) : &fHead; 56 ? SkOpTAllocator<SkOpSegment>::Allocate(this->globalState()->allocat or()) : &fHead;
74 result->setPrev(fTail); 57 result->setPrev(fTail);
75 if (fTail) { 58 if (fTail) {
76 fTail->setNext(result); 59 fTail->setNext(result);
77 } 60 }
78 fTail = result; 61 fTail = result;
79 return *result; 62 return *result;
80 } 63 }
81 64
82 SkOpContour* appendContour(SkChunkAlloc* allocator) { 65 SkOpContour* appendContour() {
83 SkOpContour* contour = SkOpTAllocator<SkOpContour>::New(allocator); 66 SkOpContour* contour = SkOpTAllocator<SkOpContour>::New(this->globalStat e()->allocator());
84 contour->setNext(nullptr); 67 contour->setNext(nullptr);
85 SkOpContour* prev = this; 68 SkOpContour* prev = this;
86 SkOpContour* next; 69 SkOpContour* next;
87 while ((next = prev->next())) { 70 while ((next = prev->next())) {
88 prev = next; 71 prev = next;
89 } 72 }
90 prev->setNext(contour); 73 prev->setNext(contour);
91 return contour; 74 return contour;
92 } 75 }
93 76
94 const SkPathOpsBounds& bounds() const { 77 const SkPathOpsBounds& bounds() const {
95 return fBounds; 78 return fBounds;
96 } 79 }
97 80
98 void calcAngles(SkChunkAlloc* allocator) { 81 void calcAngles() {
99 SkASSERT(fCount > 0); 82 SkASSERT(fCount > 0);
100 SkOpSegment* segment = &fHead; 83 SkOpSegment* segment = &fHead;
101 do { 84 do {
102 segment->calcAngles(allocator); 85 segment->calcAngles();
103 } while ((segment = segment->next())); 86 } while ((segment = segment->next()));
104 } 87 }
105 88
106 void complete() { 89 void complete() {
107 setBounds(); 90 setBounds();
108 } 91 }
109 92
110 int count() const { 93 int count() const {
111 return fCount; 94 return fCount;
112 } 95 }
(...skipping 12 matching lines...) Expand all
125 do { 108 do {
126 segment->debugShowActiveSpans(); 109 segment->debugShowActiveSpans();
127 } while ((segment = segment->next())); 110 } while ((segment = segment->next()));
128 } 111 }
129 #endif 112 #endif
130 113
131 const SkOpAngle* debugAngle(int id) const { 114 const SkOpAngle* debugAngle(int id) const {
132 return SkDEBUGRELEASE(this->globalState()->debugAngle(id), nullptr); 115 return SkDEBUGRELEASE(this->globalState()->debugAngle(id), nullptr);
133 } 116 }
134 117
118 const SkOpCoincidence* debugCoincidence() const {
119 return this->globalState()->coincidence();
120 }
121
122 #if DEBUG_COINCIDENCE_VERBOSE
135 void debugCheckHealth(const char* id, SkPathOpsDebug::GlitchLog* ) const; 123 void debugCheckHealth(const char* id, SkPathOpsDebug::GlitchLog* ) const;
124 #endif
136 125
137 SkOpContour* debugContour(int id) { 126 SkOpContour* debugContour(int id) {
138 return SkDEBUGRELEASE(this->globalState()->debugContour(id), nullptr); 127 return SkDEBUGRELEASE(this->globalState()->debugContour(id), nullptr);
139 } 128 }
140 129
141 void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* log, 130 #if DEBUG_COINCIDENCE_VERBOSE
142 const SkOpCoincidence* coincidence) const; 131 void debugMissingCoincidence(const char* id, SkPathOpsDebug::GlitchLog* log) const;
132 #endif
143 133
144 const SkOpPtT* debugPtT(int id) const { 134 const SkOpPtT* debugPtT(int id) const {
145 return SkDEBUGRELEASE(this->globalState()->debugPtT(id), nullptr); 135 return SkDEBUGRELEASE(this->globalState()->debugPtT(id), nullptr);
146 } 136 }
147 137
148 const SkOpSegment* debugSegment(int id) const { 138 const SkOpSegment* debugSegment(int id) const {
149 return SkDEBUGRELEASE(this->globalState()->debugSegment(id), nullptr); 139 return SkDEBUGRELEASE(this->globalState()->debugSegment(id), nullptr);
150 } 140 }
151 141
152 const SkOpSpanBase* debugSpan(int id) const { 142 const SkOpSpanBase* debugSpan(int id) const {
153 return SkDEBUGRELEASE(this->globalState()->debugSpan(id), nullptr); 143 return SkDEBUGRELEASE(this->globalState()->debugSpan(id), nullptr);
154 } 144 }
155 145
156 SkOpGlobalState* globalState() const { 146 SkOpGlobalState* globalState() const {
157 return fState; 147 return fState;
158 } 148 }
159 149
160 void debugValidate() const { 150 void debugValidate() const {
161 #if DEBUG_VALIDATE 151 #if DEBUG_VALIDATE
162 const SkOpSegment* segment = &fHead; 152 const SkOpSegment* segment = &fHead;
163 const SkOpSegment* prior = nullptr; 153 const SkOpSegment* prior = nullptr;
164 do { 154 do {
165 segment->debugValidate(); 155 segment->debugValidate();
166 SkASSERT(segment->prev() == prior); 156 SkASSERT(segment->prev() == prior);
167 prior = segment; 157 prior = segment;
(...skipping 22 matching lines...) Expand all
190 void dumpPtsX(const char* prefix) const; 180 void dumpPtsX(const char* prefix) const;
191 void dumpSegment(int ) const; 181 void dumpSegment(int ) const;
192 void dumpSegments(const char* prefix = "seg", SkPathOp op = (SkPathOp) -1) c onst; 182 void dumpSegments(const char* prefix = "seg", SkPathOp op = (SkPathOp) -1) c onst;
193 void dumpSpan(int ) const; 183 void dumpSpan(int ) const;
194 void dumpSpans() const; 184 void dumpSpans() const;
195 185
196 const SkPoint& end() const { 186 const SkPoint& end() const {
197 return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())]; 187 return fTail->pts()[SkPathOpsVerbToPoints(fTail->verb())];
198 } 188 }
199 189
200 bool findCollapsed() {
201 SkASSERT(fCount > 0);
202 SkOpSegment* segment = &fHead;
203 do {
204 segment->findCollapsed();
205 } while ((segment = segment->next()));
206 return true;
207 }
208
209 SkOpSpan* findSortableTop(SkOpContour* ); 190 SkOpSpan* findSortableTop(SkOpContour* );
210 191
211 SkOpSegment* first() { 192 SkOpSegment* first() {
212 SkASSERT(fCount > 0); 193 SkASSERT(fCount > 0);
213 return &fHead; 194 return &fHead;
214 } 195 }
215 196
216 const SkOpSegment* first() const { 197 const SkOpSegment* first() const {
217 SkASSERT(fCount > 0); 198 SkASSERT(fCount > 0);
218 return &fHead; 199 return &fHead;
(...skipping 11 matching lines...) Expand all
230 } 211 }
231 212
232 int isCcw() const { 213 int isCcw() const {
233 return fCcw; 214 return fCcw;
234 } 215 }
235 216
236 bool isXor() const { 217 bool isXor() const {
237 return fXor; 218 return fXor;
238 } 219 }
239 220
240 void markDone() { 221 void markAllDone() {
241 SkOpSegment* segment = &fHead; 222 SkOpSegment* segment = &fHead;
242 do { 223 do {
243 segment->markAllDone(); 224 segment->markAllDone();
244 } while ((segment = segment->next())); 225 } while ((segment = segment->next()));
245 } 226 }
246 227
247 bool missingCoincidence(SkOpCoincidence* coincidences, SkChunkAlloc* allocat or) { 228 // Please keep this aligned with debugMissingCoincidence()
229 bool missingCoincidence() {
248 SkASSERT(fCount > 0); 230 SkASSERT(fCount > 0);
249 SkOpSegment* segment = &fHead; 231 SkOpSegment* segment = &fHead;
250 bool result = false; 232 bool result = false;
251 do { 233 do {
252 if (fState->angleCoincidence()) { 234 if (fState->angleCoincidence()) {
253 #if DEBUG_ANGLE 235 #if DEBUG_ANGLE
254 segment->debugCheckAngleCoin(); 236 segment->debugCheckAngleCoin();
255 #endif 237 #endif
256 } else if (segment->missingCoincidence(coincidences, allocator)) { 238 } else if (segment->missingCoincidence()) {
257 result = true; 239 result = true;
258 // FIXME: trying again loops forever in issue3651_6 240 // FIXME: trying again loops forever in issue3651_6
259 // The continue below is speculative -- once there's an actual case that req uires it, 241 // The continue below is speculative -- once there's an actual case that req uires it,
260 // add the plumbing necessary to look for another missing coincidence in the same segment 242 // add the plumbing necessary to look for another missing coincidence in the same segment
261 // continue; // try again in case another missing coincidence is further along 243 // continue; // try again in case another missing coincidence is further along
262 } 244 }
263 segment = segment->next(); 245 segment = segment->next();
264 } while (segment); 246 } while (segment);
265 return result; 247 return result;
266 } 248 }
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 bool fXor; // set if original path had even-odd fill 411 bool fXor; // set if original path had even-odd fill
430 bool fOppXor; // set if opposite path had even-odd fill 412 bool fOppXor; // set if opposite path had even-odd fill
431 SkDEBUGCODE(int fID); 413 SkDEBUGCODE(int fID);
432 SkDEBUGCODE(mutable int fDebugIndent); 414 SkDEBUGCODE(mutable int fDebugIndent);
433 }; 415 };
434 416
435 class SkOpContourHead : public SkOpContour { 417 class SkOpContourHead : public SkOpContour {
436 }; 418 };
437 419
438 #endif 420 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698