OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 SkOpSegment_DEFINE | 7 #ifndef SkOpSegment_DEFINE |
8 #define SkOpSegment_DEFINE | 8 #define SkOpSegment_DEFINE |
9 | 9 |
10 #include "SkOpAngle.h" | 10 #include "SkOpAngle.h" |
11 #include "SkOpSpan.h" | 11 #include "SkOpSpan.h" |
12 #include "SkOpTAllocator.h" | 12 #include "SkOpTAllocator.h" |
13 #include "SkPathOpsBounds.h" | 13 #include "SkPathOpsBounds.h" |
14 #include "SkPathOpsCurve.h" | 14 #include "SkPathOpsCurve.h" |
15 | 15 |
| 16 struct SkDCurve; |
16 class SkOpCoincidence; | 17 class SkOpCoincidence; |
17 class SkOpContour; | 18 class SkOpContour; |
18 class SkPathWriter; | 19 class SkPathWriter; |
19 | 20 |
20 class SkOpSegment { | 21 class SkOpSegment { |
21 public: | 22 public: |
22 enum AllowAlias { | 23 enum AllowAlias { |
23 kAllowAlias, | 24 kAllowAlias, |
24 kNoAlias | 25 kNoAlias |
25 }; | 26 }; |
(...skipping 11 matching lines...) Expand all Loading... |
37 bool activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask, int xor
SuMask, | 38 bool activeOp(SkOpSpanBase* start, SkOpSpanBase* end, int xorMiMask, int xor
SuMask, |
38 SkPathOp op); | 39 SkPathOp op); |
39 bool activeOp(int xorMiMask, int xorSuMask, SkOpSpanBase* start, SkOpSpanBas
e* end, SkPathOp op, | 40 bool activeOp(int xorMiMask, int xorSuMask, SkOpSpanBase* start, SkOpSpanBas
e* end, SkPathOp op, |
40 int* sumMiWinding, int* sumSuWinding); | 41 int* sumMiWinding, int* sumSuWinding); |
41 | 42 |
42 SkPoint activeLeftTop(SkOpSpanBase** firstT); | 43 SkPoint activeLeftTop(SkOpSpanBase** firstT); |
43 | 44 |
44 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end); | 45 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end); |
45 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* sumWinding); | 46 bool activeWinding(SkOpSpanBase* start, SkOpSpanBase* end, int* sumWinding); |
46 | 47 |
| 48 void addConic(SkPoint pts[3], SkScalar weight, SkOpContour* parent) { |
| 49 init(pts, weight, parent, SkPath::kConic_Verb); |
| 50 fBounds.setConicBounds(pts, weight); |
| 51 } |
| 52 |
47 void addCubic(SkPoint pts[4], SkOpContour* parent) { | 53 void addCubic(SkPoint pts[4], SkOpContour* parent) { |
48 init(pts, parent, SkPath::kCubic_Verb); | 54 init(pts, 1, parent, SkPath::kCubic_Verb); |
49 fBounds.setCubicBounds(pts); | 55 fBounds.setCubicBounds(pts, 1); |
50 } | 56 } |
51 | 57 |
52 void addCurveTo(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPathWr
iter* path, | 58 void addCurveTo(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPathWr
iter* path, |
53 bool active) const; | 59 bool active) const; |
54 | 60 |
55 SkOpAngle* addEndSpan(SkChunkAlloc* allocator) { | 61 SkOpAngle* addEndSpan(SkChunkAlloc* allocator) { |
56 SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator); | 62 SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator); |
57 angle->set(&fTail, fTail.prev()); | 63 angle->set(&fTail, fTail.prev()); |
58 fTail.setFromAngle(angle); | 64 fTail.setFromAngle(angle); |
59 return angle; | 65 return angle; |
60 } | 66 } |
61 | 67 |
62 void addLine(SkPoint pts[2], SkOpContour* parent) { | 68 void addLine(SkPoint pts[2], SkOpContour* parent) { |
63 init(pts, parent, SkPath::kLine_Verb); | 69 init(pts, 1, parent, SkPath::kLine_Verb); |
64 fBounds.set(pts, 2); | 70 fBounds.set(pts, 2); |
65 } | 71 } |
66 | 72 |
67 SkOpPtT* addMissing(double t, SkOpSegment* opp, SkChunkAlloc* ); | 73 SkOpPtT* addMissing(double t, SkOpSegment* opp, SkChunkAlloc* ); |
68 SkOpAngle* addSingletonAngleDown(SkOpSegment** otherPtr, SkOpAngle** , SkChu
nkAlloc* ); | 74 SkOpAngle* addSingletonAngleDown(SkOpSegment** otherPtr, SkOpAngle** , SkChu
nkAlloc* ); |
69 SkOpAngle* addSingletonAngles(int step, SkChunkAlloc* ); | 75 SkOpAngle* addSingletonAngles(int step, SkChunkAlloc* ); |
70 SkOpAngle* addSingletonAngleUp(SkOpSegment** otherPtr, SkOpAngle** , SkChunk
Alloc* ); | 76 SkOpAngle* addSingletonAngleUp(SkOpSegment** otherPtr, SkOpAngle** , SkChunk
Alloc* ); |
71 | 77 |
72 SkOpAngle* addStartSpan(SkChunkAlloc* allocator) { | 78 SkOpAngle* addStartSpan(SkChunkAlloc* allocator) { |
73 SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator); | 79 SkOpAngle* angle = SkOpTAllocator<SkOpAngle>::Allocate(allocator); |
74 angle->set(&fHead, fHead.next()); | 80 angle->set(&fHead, fHead.next()); |
75 fHead.setToAngle(angle); | 81 fHead.setToAngle(angle); |
76 return angle; | 82 return angle; |
77 } | 83 } |
78 | 84 |
79 void addQuad(SkPoint pts[3], SkOpContour* parent) { | 85 void addQuad(SkPoint pts[3], SkOpContour* parent) { |
80 init(pts, parent, SkPath::kQuad_Verb); | 86 init(pts, 1, parent, SkPath::kQuad_Verb); |
81 fBounds.setQuadBounds(pts); | 87 fBounds.setQuadBounds(pts, 1); |
82 } | 88 } |
83 | 89 |
84 SkOpPtT* addT(double t, AllowAlias , SkChunkAlloc* ); | 90 SkOpPtT* addT(double t, AllowAlias , SkChunkAlloc* ); |
85 | 91 |
86 void align(); | 92 void align(); |
87 static bool BetweenTs(const SkOpSpanBase* lesser, double testT, const SkOpSp
anBase* greater); | 93 static bool BetweenTs(const SkOpSpanBase* lesser, double testT, const SkOpSp
anBase* greater); |
88 | 94 |
89 const SkPathOpsBounds& bounds() const { | 95 const SkPathOpsBounds& bounds() const { |
90 return fBounds; | 96 return fBounds; |
91 } | 97 } |
(...skipping 21 matching lines...) Expand all Loading... |
113 } | 119 } |
114 | 120 |
115 SkOpSpan* crossedSpanY(const SkPoint& basePt, double mid, bool opp, bool cur
rent, | 121 SkOpSpan* crossedSpanY(const SkPoint& basePt, double mid, bool opp, bool cur
rent, |
116 SkScalar* bestY, double* hitT, bool* hitSomething, b
ool* vertical); | 122 SkScalar* bestY, double* hitT, bool* hitSomething, b
ool* vertical); |
117 | 123 |
118 void debugAddAngle(double startT, double endT, SkChunkAlloc*); | 124 void debugAddAngle(double startT, double endT, SkChunkAlloc*); |
119 const SkOpAngle* debugAngle(int id) const; | 125 const SkOpAngle* debugAngle(int id) const; |
120 SkOpContour* debugContour(int id); | 126 SkOpContour* debugContour(int id); |
121 | 127 |
122 int debugID() const { | 128 int debugID() const { |
123 return PATH_OPS_DEBUG_RELEASE(fID, -1); | 129 return SkDEBUGRELEASE(fID, -1); |
124 } | 130 } |
125 | 131 |
126 #if DEBUG_SWAP_TOP | 132 #if DEBUG_SWAP_TOP |
127 int debugInflections(const SkOpSpanBase* start, const SkOpSpanBase* end) con
st; | 133 int debugInflections(const SkOpSpanBase* start, const SkOpSpanBase* end) con
st; |
128 #endif | 134 #endif |
129 | 135 |
130 SkOpAngle* debugLastAngle(); | 136 SkOpAngle* debugLastAngle(); |
131 const SkOpPtT* debugPtT(int id) const; | 137 const SkOpPtT* debugPtT(int id) const; |
132 void debugReset(); | 138 void debugReset(); |
133 const SkOpSegment* debugSegment(int id) const; | 139 const SkOpSegment* debugSegment(int id) const; |
(...skipping 14 matching lines...) Expand all Loading... |
148 bool done() const { | 154 bool done() const { |
149 SkASSERT(fDoneCount <= fCount); | 155 SkASSERT(fDoneCount <= fCount); |
150 return fDoneCount == fCount; | 156 return fDoneCount == fCount; |
151 } | 157 } |
152 | 158 |
153 bool done(const SkOpAngle* angle) const { | 159 bool done(const SkOpAngle* angle) const { |
154 return angle->start()->starter(angle->end())->done(); | 160 return angle->start()->starter(angle->end())->done(); |
155 } | 161 } |
156 | 162 |
157 SkDPoint dPtAtT(double mid) const { | 163 SkDPoint dPtAtT(double mid) const { |
158 return (*CurveDPointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid); | 164 return (*CurveDPointAtT[fVerb])(fPts, fWeight, mid); |
159 } | 165 } |
160 | 166 |
161 SkDVector dSlopeAtT(double mid) const { | 167 SkDVector dSlopeAtT(double mid) const { |
162 return (*CurveDSlopeAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid); | 168 return (*CurveDSlopeAtT[fVerb])(fPts, fWeight, mid); |
163 } | 169 } |
164 | 170 |
165 void dump() const; | 171 void dump() const; |
166 void dumpAll() const; | 172 void dumpAll() const; |
167 void dumpAngles() const; | 173 void dumpAngles() const; |
168 void dumpCoin() const; | 174 void dumpCoin() const; |
169 void dumpPts() const; | 175 void dumpPts() const; |
170 | 176 |
171 SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** next
Start, | 177 SkOpSegment* findNextOp(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase** next
Start, |
172 SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp
op, | 178 SkOpSpanBase** nextEnd, bool* unsortable, SkPathOp
op, |
173 int xorMiMask, int xorSuMask); | 179 int xorMiMask, int xorSuMask); |
174 SkOpSegment* findNextWinding(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase**
nextStart, | 180 SkOpSegment* findNextWinding(SkTDArray<SkOpSpanBase*>* chase, SkOpSpanBase**
nextStart, |
175 SkOpSpanBase** nextEnd, bool* unsortable); | 181 SkOpSpanBase** nextEnd, bool* unsortable); |
176 SkOpSegment* findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, b
ool* unsortable); | 182 SkOpSegment* findNextXor(SkOpSpanBase** nextStart, SkOpSpanBase** nextEnd, b
ool* unsortable); |
177 SkOpSegment* findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpSpanBase**
endPtr, | 183 SkOpSegment* findTop(bool firstPass, SkOpSpanBase** startPtr, SkOpSpanBase**
endPtr, |
178 bool* unsortable, SkChunkAlloc* ); | 184 bool* unsortable, SkChunkAlloc* ); |
179 SkOpGlobalState* globalState() const; | 185 SkOpGlobalState* globalState() const; |
180 | 186 |
181 const SkOpSpan* head() const { | 187 const SkOpSpan* head() const { |
182 return &fHead; | 188 return &fHead; |
183 } | 189 } |
184 | 190 |
185 SkOpSpan* head() { | 191 SkOpSpan* head() { |
186 return &fHead; | 192 return &fHead; |
187 } | 193 } |
188 | 194 |
189 void init(SkPoint pts[], SkOpContour* parent, SkPath::Verb verb); | 195 void init(SkPoint pts[], SkScalar weight, SkOpContour* parent, SkPath::Verb
verb); |
190 void initWinding(SkOpSpanBase* start, SkOpSpanBase* end, | 196 void initWinding(SkOpSpanBase* start, SkOpSpanBase* end, |
191 SkOpAngle::IncludeType angleIncludeType); | 197 SkOpAngle::IncludeType angleIncludeType); |
192 bool initWinding(SkOpSpanBase* start, SkOpSpanBase* end, double tHit, int wi
nding, | 198 bool initWinding(SkOpSpanBase* start, SkOpSpanBase* end, double tHit, int wi
nding, |
193 SkScalar hitDx, int oppWind, SkScalar hitOppDx); | 199 SkScalar hitDx, int oppWind, SkScalar hitOppDx); |
194 | 200 |
195 SkOpSpan* insert(SkOpSpan* prev, SkChunkAlloc* allocator) { | 201 SkOpSpan* insert(SkOpSpan* prev, SkChunkAlloc* allocator) { |
196 SkOpSpan* result = SkOpTAllocator<SkOpSpan>::Allocate(allocator); | 202 SkOpSpan* result = SkOpTAllocator<SkOpSpan>::Allocate(allocator); |
197 SkOpSpanBase* next = prev->next(); | 203 SkOpSpanBase* next = prev->next(); |
198 result->setPrev(prev); | 204 result->setPrev(prev); |
199 prev->setNext(result); | 205 prev->setNext(result); |
(...skipping 13 matching lines...) Expand all Loading... |
213 | 219 |
214 SkOpSegment* isSimple(SkOpSpanBase** end, int* step) { | 220 SkOpSegment* isSimple(SkOpSpanBase** end, int* step) { |
215 return nextChase(end, step, NULL, NULL); | 221 return nextChase(end, step, NULL, NULL); |
216 } | 222 } |
217 | 223 |
218 bool isVertical() const { | 224 bool isVertical() const { |
219 return fBounds.fLeft == fBounds.fRight; | 225 return fBounds.fLeft == fBounds.fRight; |
220 } | 226 } |
221 | 227 |
222 bool isVertical(SkOpSpanBase* start, SkOpSpanBase* end) const { | 228 bool isVertical(SkOpSpanBase* start, SkOpSpanBase* end) const { |
223 return (*CurveIsVertical[SkPathOpsVerbToPoints(fVerb)])(fPts, start->t()
, end->t()); | 229 return (*CurveIsVertical[fVerb])(fPts, fWeight, start->t(), end->t()); |
224 } | 230 } |
225 | 231 |
226 bool isXor() const; | 232 bool isXor() const; |
227 | 233 |
228 const SkPoint& lastPt() const { | 234 const SkPoint& lastPt() const { |
229 return fPts[SkPathOpsVerbToPoints(fVerb)]; | 235 return fPts[SkPathOpsVerbToPoints(fVerb)]; |
230 } | 236 } |
231 | 237 |
232 SkOpSpanBase* markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end); | 238 SkOpSpanBase* markAndChaseDone(SkOpSpanBase* start, SkOpSpanBase* end); |
233 bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding
, | 239 bool markAndChaseWinding(SkOpSpanBase* start, SkOpSpanBase* end, int winding
, |
(...skipping 25 matching lines...) Expand all Loading... |
259 return result; | 265 return result; |
260 } | 266 } |
261 | 267 |
262 bool oppXor() const; | 268 bool oppXor() const; |
263 | 269 |
264 const SkOpSegment* prev() const { | 270 const SkOpSegment* prev() const { |
265 return fPrev; | 271 return fPrev; |
266 } | 272 } |
267 | 273 |
268 SkPoint ptAtT(double mid) const { | 274 SkPoint ptAtT(double mid) const { |
269 return (*CurvePointAtT[SkPathOpsVerbToPoints(fVerb)])(fPts, mid); | 275 return (*CurvePointAtT[fVerb])(fPts, fWeight, mid); |
270 } | 276 } |
271 | 277 |
272 const SkPoint* pts() const { | 278 const SkPoint* pts() const { |
273 return fPts; | 279 return fPts; |
274 } | 280 } |
275 | 281 |
276 bool ptsDisjoint(const SkOpPtT& span, const SkOpPtT& test) const { | 282 bool ptsDisjoint(const SkOpPtT& span, const SkOpPtT& test) const { |
277 return ptsDisjoint(span.fT, span.fPt, test.fT, test.fPt); | 283 return ptsDisjoint(span.fT, span.fPt, test.fT, test.fPt); |
278 } | 284 } |
279 | 285 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 int result = start->t() < end->t() ? -start->upCast()->windValue() | 328 int result = start->t() < end->t() ? -start->upCast()->windValue() |
323 : end->upCast()->windValue(); | 329 : end->upCast()->windValue(); |
324 return result; | 330 return result; |
325 } | 331 } |
326 | 332 |
327 SkOpAngle* spanToAngle(SkOpSpanBase* start, SkOpSpanBase* end) { | 333 SkOpAngle* spanToAngle(SkOpSpanBase* start, SkOpSpanBase* end) { |
328 SkASSERT(start != end); | 334 SkASSERT(start != end); |
329 return start->t() < end->t() ? start->upCast()->toAngle() : start->fromA
ngle(); | 335 return start->t() < end->t() ? start->upCast()->toAngle() : start->fromA
ngle(); |
330 } | 336 } |
331 | 337 |
332 bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkPoint e
dge[4]) const; | 338 bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkDCurve*
result) const; |
333 bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkDCubic*
result) const; | 339 bool subDivide(const SkOpSpanBase* start, const SkOpSpanBase* end, SkOpCurve
* result) const; |
334 void subDivideBounds(const SkOpSpanBase* start, const SkOpSpanBase* end, | 340 void subDivideBounds(const SkOpSpanBase* start, const SkOpSpanBase* end, |
335 SkPathOpsBounds* bounds) const; | 341 SkPathOpsBounds* bounds) const; |
336 | 342 |
337 const SkOpSpanBase* tail() const { | 343 const SkOpSpanBase* tail() const { |
338 return &fTail; | 344 return &fTail; |
339 } | 345 } |
340 | 346 |
341 SkOpSpanBase* tail() { | 347 SkOpSpanBase* tail() { |
342 return &fTail; | 348 return &fTail; |
343 } | 349 } |
344 | 350 |
345 static double TAtMid(const SkOpSpanBase* start, const SkOpSpanBase* end, dou
ble mid) { | 351 static double TAtMid(const SkOpSpanBase* start, const SkOpSpanBase* end, dou
ble mid) { |
346 return start->t() * (1 - mid) + end->t() * mid; | 352 return start->t() * (1 - mid) + end->t() * mid; |
347 } | 353 } |
348 | 354 |
349 void undoneSpan(SkOpSpanBase** start, SkOpSpanBase** end); | 355 void undoneSpan(SkOpSpanBase** start, SkOpSpanBase** end); |
350 int updateOppWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) con
st; | 356 int updateOppWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) con
st; |
351 int updateOppWinding(const SkOpAngle* angle) const; | 357 int updateOppWinding(const SkOpAngle* angle) const; |
352 int updateOppWindingReverse(const SkOpAngle* angle) const; | 358 int updateOppWindingReverse(const SkOpAngle* angle) const; |
353 int updateWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const; | 359 int updateWinding(const SkOpSpanBase* start, const SkOpSpanBase* end) const; |
354 int updateWinding(const SkOpAngle* angle) const; | 360 int updateWinding(const SkOpAngle* angle) const; |
355 int updateWindingReverse(const SkOpAngle* angle) const; | 361 int updateWindingReverse(const SkOpAngle* angle) const; |
356 | 362 |
357 static bool UseInnerWinding(int outerWinding, int innerWinding); | 363 static bool UseInnerWinding(int outerWinding, int innerWinding); |
358 | 364 |
359 SkPath::Verb verb() const { | 365 SkPath::Verb verb() const { |
360 return fVerb; | 366 return fVerb; |
361 } | 367 } |
362 | 368 |
| 369 SkScalar weight() const { |
| 370 return fWeight; |
| 371 } |
| 372 |
363 int windingAtT(double tHit, const SkOpSpan* span, bool crossOpp, SkScalar* d
x) const; | 373 int windingAtT(double tHit, const SkOpSpan* span, bool crossOpp, SkScalar* d
x) const; |
364 int windSum(const SkOpAngle* angle) const; | 374 int windSum(const SkOpAngle* angle) const; |
365 | 375 |
366 SkPoint* writablePt(bool end) { | 376 SkPoint* writablePt(bool end) { |
367 return &fPts[end ? SkPathOpsVerbToPoints(fVerb) : 0]; | 377 return &fPts[end ? SkPathOpsVerbToPoints(fVerb) : 0]; |
368 } | 378 } |
369 | 379 |
370 private: | 380 private: |
371 SkOpSpan fHead; // the head span always has its t set to zero | 381 SkOpSpan fHead; // the head span always has its t set to zero |
372 SkOpSpanBase fTail; // the tail span always has its t set to one | 382 SkOpSpanBase fTail; // the tail span always has its t set to one |
373 SkOpContour* fContour; | 383 SkOpContour* fContour; |
374 SkOpSegment* fNext; // forward-only linked list used by contour to walk the
segments | 384 SkOpSegment* fNext; // forward-only linked list used by contour to walk the
segments |
375 const SkOpSegment* fPrev; | 385 const SkOpSegment* fPrev; |
376 SkPoint* fPts; // pointer into array of points owned by edge builder that m
ay be tweaked | 386 SkPoint* fPts; // pointer into array of points owned by edge builder that m
ay be tweaked |
377 SkPathOpsBounds fBounds; // tight bounds | 387 SkPathOpsBounds fBounds; // tight bounds |
| 388 SkScalar fWeight; |
378 int fCount; // number of spans (one for a non-intersecting segment) | 389 int fCount; // number of spans (one for a non-intersecting segment) |
379 int fDoneCount; // number of processed spans (zero initially) | 390 int fDoneCount; // number of processed spans (zero initially) |
380 SkPath::Verb fVerb; | 391 SkPath::Verb fVerb; |
381 bool fVisited; // used by missing coincidence check | 392 bool fVisited; // used by missing coincidence check |
382 PATH_OPS_DEBUG_CODE(int fID); | 393 SkDEBUGCODE(int fID); |
383 }; | 394 }; |
384 | 395 |
385 #endif | 396 #endif |
OLD | NEW |