Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkOpContour.h
Go to the documentation of this file.
1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#ifndef SkOpContour_DEFINED
8#define SkOpContour_DEFINED
9
10#include "include/core/SkPath.h"
21
22class SkOpAngle;
23class SkOpCoincidence;
24class SkPathWriter;
25enum class SkOpRayDir;
26struct SkOpRayHit;
27
29public:
31 reset();
32 }
33
34 bool operator<(const SkOpContour& rh) const {
35 return fBounds.fTop == rh.fBounds.fTop
37 : fBounds.fTop < rh.fBounds.fTop;
38 }
39
40 void addConic(SkPoint pts[3], SkScalar weight) {
41 appendSegment().addConic(pts, weight, this);
42 }
43
44 void addCubic(SkPoint pts[4]) {
45 appendSegment().addCubic(pts, this);
46 }
47
49 SkASSERT(pts[0] != pts[1]);
50 return appendSegment().addLine(pts, this);
51 }
52
53 void addQuad(SkPoint pts[3]) {
54 appendSegment().addQuad(pts, this);
55 }
56
59 : &fHead;
61 if (fTail) {
63 }
64 fTail = result;
65 return *result;
66 }
67
68 const SkPathOpsBounds& bounds() const {
69 return fBounds;
70 }
71
72 void calcAngles() {
73 SkASSERT(fCount > 0);
74 SkOpSegment* segment = &fHead;
75 do {
76 segment->calcAngles();
77 } while ((segment = segment->next()));
78 }
79
80 void complete() {
81 setBounds();
82 }
83
84 int count() const {
85 return fCount;
86 }
87
88 int debugID() const {
89 return SkDEBUGRELEASE(fID, -1);
90 }
91
92 int debugIndent() const {
93 return SkDEBUGRELEASE(fDebugIndent, 0);
94 }
95
96 const SkOpAngle* debugAngle(int id) const {
97 return SkDEBUGRELEASE(this->globalState()->debugAngle(id), nullptr);
98 }
99
101 return this->globalState()->coincidence();
102 }
103
104#if DEBUG_COIN
105 void debugCheckHealth(SkPathOpsDebug::GlitchLog* ) const;
106#endif
107
108 SkOpContour* debugContour(int id) const {
109 return SkDEBUGRELEASE(this->globalState()->debugContour(id), nullptr);
110 }
111
112#if DEBUG_COIN
113 void debugMissingCoincidence(SkPathOpsDebug::GlitchLog* log) const;
114 void debugMoveMultiples(SkPathOpsDebug::GlitchLog* ) const;
115 void debugMoveNearby(SkPathOpsDebug::GlitchLog* log) const;
116#endif
117
118 const SkOpPtT* debugPtT(int id) const {
119 return SkDEBUGRELEASE(this->globalState()->debugPtT(id), nullptr);
120 }
121
122 const SkOpSegment* debugSegment(int id) const {
123 return SkDEBUGRELEASE(this->globalState()->debugSegment(id), nullptr);
124 }
125
126#if DEBUG_ACTIVE_SPANS
127 void debugShowActiveSpans(SkString* str) {
128 SkOpSegment* segment = &fHead;
129 do {
130 segment->debugShowActiveSpans(str);
131 } while ((segment = segment->next()));
132 }
133#endif
134
135 const SkOpSpanBase* debugSpan(int id) const {
136 return SkDEBUGRELEASE(this->globalState()->debugSpan(id), nullptr);
137 }
138
140 return fState;
141 }
142
143 void debugValidate() const {
144#if DEBUG_VALIDATE
145 const SkOpSegment* segment = &fHead;
146 const SkOpSegment* prior = nullptr;
147 do {
148 segment->debugValidate();
149 SkASSERT(segment->prev() == prior);
150 prior = segment;
151 } while ((segment = segment->next()));
152 SkASSERT(prior == fTail);
153#endif
154 }
155
156 bool done() const {
157 return fDone;
158 }
159
160 void dump() const;
161 void dumpAll() const;
162 void dumpAngles() const;
163 void dumpContours() const;
164 void dumpContoursAll() const;
165 void dumpContoursAngles() const;
166 void dumpContoursPts() const;
167 void dumpContoursPt(int segmentID) const;
168 void dumpContoursSegment(int segmentID) const;
169 void dumpContoursSpan(int segmentID) const;
170 void dumpContoursSpans() const;
171 void dumpPt(int ) const;
172 void dumpPts(const char* prefix = "seg") const;
173 void dumpPtsX(const char* prefix) const;
174 void dumpSegment(int ) const;
175 void dumpSegments(const char* prefix = "seg", SkPathOp op = (SkPathOp) -1) const;
176 void dumpSpan(int ) const;
177 void dumpSpans() const;
178
179 const SkPoint& end() const {
181 }
182
184
186 SkASSERT(fCount > 0);
187 return &fHead;
188 }
189
190 const SkOpSegment* first() const {
191 SkASSERT(fCount > 0);
192 return &fHead;
193 }
194
195 void indentDump() const {
196 SkDEBUGCODE(fDebugIndent += 2);
197 }
198
202 fXor = isXor;
203 SkDEBUGCODE(fID = globalState->nextContourID());
204 }
205
206 int isCcw() const {
207 return fCcw;
208 }
209
210 bool isXor() const {
211 return fXor;
212 }
213
215 SkOpSegment* segment = &fHead;
217 do {
218 next = segment->next();
219 segment->joinEnds(next ? next : &fHead);
220 } while ((segment = next));
221 }
222
223 void markAllDone() {
224 SkOpSegment* segment = &fHead;
225 do {
226 segment->markAllDone();
227 } while ((segment = segment->next()));
228 }
229
230 // Please keep this aligned with debugMissingCoincidence()
232 SkASSERT(fCount > 0);
233 SkOpSegment* segment = &fHead;
234 bool result = false;
235 do {
236 if (segment->missingCoincidence()) {
237 result = true;
238 }
239 segment = segment->next();
240 } while (segment);
241 return result;
242 }
243
245 SkASSERT(fCount > 0);
246 SkOpSegment* segment = &fHead;
247 do {
248 if (!segment->moveMultiples()) {
249 return false;
250 }
251 } while ((segment = segment->next()));
252 return true;
253 }
254
255 bool moveNearby() {
256 SkASSERT(fCount > 0);
257 SkOpSegment* segment = &fHead;
258 do {
259 if (!segment->moveNearby()) {
260 return false;
261 }
262 } while ((segment = segment->next()));
263 return true;
264 }
265
267 return fNext;
268 }
269
270 const SkOpContour* next() const {
271 return fNext;
272 }
273
274 bool operand() const {
275 return fOperand;
276 }
277
278 bool oppXor() const {
279 return fOppXor;
280 }
281
282 void outdentDump() const {
283 SkDEBUGCODE(fDebugIndent -= 2);
284 }
285
286 void rayCheck(const SkOpRayHit& base, SkOpRayDir dir, SkOpRayHit** hits, SkArenaAlloc*);
287
288 void reset() {
289 fTail = nullptr;
290 fNext = nullptr;
291 fCount = 0;
292 fDone = false;
295 SkDEBUGCODE(fDebugIndent = 0);
296 }
297
299 SkOpContour* next = this;
300 do {
301 if (!next->count()) {
302 continue;
303 }
304 next->fCcw = -1;
305 next->fReverse = false;
306 } while ((next = next->next()));
307 }
308
309 bool reversed() const {
310 return fReverse;
311 }
312
313 void setBounds() {
314 SkASSERT(fCount > 0);
315 const SkOpSegment* segment = &fHead;
316 fBounds = segment->bounds();
317 while ((segment = segment->next())) {
318 fBounds.add(segment->bounds());
319 }
320 }
321
322 void setCcw(int ccw) {
323 fCcw = ccw;
324 }
325
329
331// SkASSERT(!fNext == !!contour);
332 fNext = contour;
333 }
334
335 void setOperand(bool isOp) {
336 fOperand = isOp;
337 }
338
339 void setOppXor(bool isOppXor) {
340 fOppXor = isOppXor;
341 }
342
343 void setReverse() {
344 fReverse = true;
345 }
346
347 void setXor(bool isXor) {
348 fXor = isXor;
349 }
350
351 bool sortAngles() {
352 SkASSERT(fCount > 0);
353 SkOpSegment* segment = &fHead;
354 do {
355 FAIL_IF(!segment->sortAngles());
356 } while ((segment = segment->next()));
357 return true;
358 }
359
360 const SkPoint& start() const {
361 return fHead.pts()[0];
362 }
363
364 void toPartialBackward(SkPathWriter* path) const {
365 const SkOpSegment* segment = fTail;
366 do {
367 SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path));
368 } while ((segment = segment->prev()));
369 }
370
371 void toPartialForward(SkPathWriter* path) const {
372 const SkOpSegment* segment = &fHead;
373 do {
374 SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path));
375 } while ((segment = segment->next()));
376 }
377
378 void toReversePath(SkPathWriter* path) const;
379 void toPath(SkPathWriter* path) const;
381
382protected:
388 int fCcw;
391 bool fDone; // set by find top segment
392 bool fOperand; // true for the second argument to a binary operator
393 bool fReverse; // true if contour should be reverse written to path (used only by fix winding)
394 bool fXor; // set if original path had even-odd fill
395 bool fOppXor; // set if opposite path had even-odd fill
396 SkDEBUGCODE(int fID;)
397 SkDEBUGCODE(mutable int fDebugIndent;)
398};
399
401public:
404 contour->setNext(nullptr);
405 SkOpContour* prev = this;
407 while ((next = prev->next())) {
408 prev = next;
409 }
411 return contour;
412 }
413
415 SkOpContour* next = this;
416 do {
417 if (!next->count()) {
418 continue;
419 }
421 } while ((next = next->next()));
422 }
423
425 if (contour == this) {
426 SkASSERT(this->count() == 0);
427 return;
428 }
429 SkASSERT(contour->next() == nullptr);
430 SkOpContour* prev = this;
432 while ((next = prev->next()) != contour) {
433 SkASSERT(next);
434 prev = next;
435 }
436 SkASSERT(prev);
437 prev->setNext(nullptr);
438 }
439};
440
442public:
447
448 void addConic(SkPoint pts[3], SkScalar weight);
449 void addCubic(SkPoint pts[4]);
450 void addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight = 1);
451 void addLine(const SkPoint pts[2]);
452 void addQuad(SkPoint pts[3]);
453 void flush();
456protected:
460};
461
462#endif
static float prev(float f)
#define SkAssertResult(cond)
Definition SkAssert.h:123
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
#define SkDEBUGRELEASE(a, b)
#define FAIL_IF(cond)
int SkPathOpsVerbToPoints(SkPath::Verb verb)
SkPathOp
Definition SkPathOps.h:22
#define SK_ScalarMin
Definition SkScalar.h:25
#define SK_ScalarMax
Definition SkScalar.h:24
auto make(Ctor &&ctor) -> decltype(ctor(nullptr))
SkOpContour * fContour
void addConic(SkPoint pts[3], SkScalar weight)
void addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight=1)
void setContour(SkOpContour *contour)
SkOpContourBuilder(SkOpContour *contour)
SkPoint fLastLine[2]
void addCubic(SkPoint pts[4])
void addQuad(SkPoint pts[3])
void addLine(const SkPoint pts[2])
SkOpContour * contour()
SkOpContour * appendContour()
void joinAllSegments()
void remove(SkOpContour *contour)
SkOpGlobalState * fState
const SkPathOpsBounds & bounds() const
Definition SkOpContour.h:68
void joinSegments()
int count() const
Definition SkOpContour.h:84
void addCubic(SkPoint pts[4])
Definition SkOpContour.h:44
void setXor(bool isXor)
bool isXor() const
void calcAngles()
Definition SkOpContour.h:72
void setReverse()
bool reversed() const
void toReversePath(SkPathWriter *path) const
SkOpGlobalState * globalState() const
void setBounds()
void dumpPt(int) const
SkOpContour * fNext
SkOpSpan * undoneSpan()
bool operand() const
const SkOpSegment * debugSegment(int id) const
void dumpAll() const
int isCcw() const
const SkPoint & end() const
void dumpAngles() const
bool moveNearby()
bool missingCoincidence()
void setOppXor(bool isOppXor)
SkOpSegment & appendSegment()
Definition SkOpContour.h:57
void init(SkOpGlobalState *globalState, bool operand, bool isXor)
int debugIndent() const
Definition SkOpContour.h:92
SkDEBUGCODE(int fID;) SkDEBUGCODE(mutable int fDebugIndent
void markAllDone()
void dumpContoursAngles() const
const SkOpCoincidence * debugCoincidence() const
bool operator<(const SkOpContour &rh) const
Definition SkOpContour.h:34
const SkOpContour * next() const
bool done() const
const SkOpSpanBase * debugSpan(int id) const
void dump() const
SkOpSegment * fTail
SkOpSpan * findSortableTop(SkOpContour *)
SkOpContour * debugContour(int id) const
SkOpSegment * first()
void dumpContoursPts() const
void dumpSpan(int) const
void rayCheck(const SkOpRayHit &base, SkOpRayDir dir, SkOpRayHit **hits, SkArenaAlloc *)
void dumpContoursAll() const
void indentDump() const
void toPartialForward(SkPathWriter *path) const
void complete()
Definition SkOpContour.h:80
void dumpContoursSpans() const
bool sortAngles()
const SkOpSegment * first() const
void dumpPts(const char *prefix="seg") const
void dumpSegments(const char *prefix="seg", SkPathOp op=(SkPathOp) -1) const
void dumpContours() const
void dumpSegment(int) const
void dumpSpans() const
void dumpContoursPt(int segmentID) const
void addQuad(SkPoint pts[3])
Definition SkOpContour.h:53
void setCcw(int ccw)
void outdentDump() const
void addConic(SkPoint pts[3], SkScalar weight)
Definition SkOpContour.h:40
bool oppXor() const
int debugID() const
Definition SkOpContour.h:88
SkOpContour * next()
void toPath(SkPathWriter *path) const
const SkOpAngle * debugAngle(int id) const
Definition SkOpContour.h:96
SkOpSegment fHead
void toPartialBackward(SkPathWriter *path) const
SkOpSegment * addLine(SkPoint pts[2])
Definition SkOpContour.h:48
void dumpPtsX(const char *prefix) const
void resetReverse()
const SkPoint & start() const
void dumpContoursSpan(int segmentID) const
void setNext(SkOpContour *contour)
const SkOpPtT * debugPtT(int id) const
void setGlobalState(SkOpGlobalState *state)
void dumpContoursSegment(int segmentID) const
void debugValidate() const
SkPathOpsBounds fBounds
void setOperand(bool isOp)
bool moveMultiples()
SkArenaAlloc * allocator()
SkOpCoincidence * coincidence()
SkOpSegment * addConic(SkPoint pts[3], SkScalar weight, SkOpContour *parent)
Definition SkOpSegment.h:55
void debugValidate() const
void joinEnds(SkOpSegment *start)
SkPath::Verb verb() const
SkOpSegment * addLine(SkPoint pts[2], SkOpContour *parent)
Definition SkOpSegment.h:82
void setPrev(SkOpSegment *prev)
const SkPathOpsBounds & bounds() const
bool moveMultiples()
const SkOpSegment * prev() const
const SkOpSpanBase * tail() const
void markAllDone()
void calcAngles()
const SkOpSpan * head() const
bool addCurveTo(const SkOpSpanBase *start, const SkOpSpanBase *end, SkPathWriter *path) const
SkOpSegment * addCubic(SkPoint pts[4], SkOpContour *parent)
Definition SkOpSegment.h:63
void setNext(SkOpSegment *next)
const SkPoint * pts() const
SkOpSegment * addQuad(SkPoint pts[3], SkOpContour *parent)
Definition SkOpSegment.h:98
bool missingCoincidence()
SkOpSegment * next() const
float SkScalar
Definition extension.cpp:12
AtkStateType state
GAsyncResult * result
void add(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
void setLTRB(float left, float top, float right, float bottom)
Definition SkRect.h:865
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15