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" |
(...skipping 30 matching lines...) Expand all Loading... |
41 // OPTIMIZE | 41 // OPTIMIZE |
42 // when the edges are initially walked, they don't automatically get the pri
or and next | 42 // when the edges are initially walked, they don't automatically get the pri
or and next |
43 // edges assigned to positions t=0 and t=1. Doing that would remove the need
for this check, | 43 // edges assigned to positions t=0 and t=1. Doing that would remove the need
for this check, |
44 // and would additionally remove the need for similar checks in condition ed
ges. It would | 44 // and would additionally remove the need for similar checks in condition ed
ges. It would |
45 // also allow intersection code to assume end of segment intersections (mayb
e?) | 45 // also allow intersection code to assume end of segment intersections (mayb
e?) |
46 bool complete() const { | 46 bool complete() const { |
47 int count = fTs.count(); | 47 int count = fTs.count(); |
48 return count > 1 && fTs[0].fT == 0 && fTs[--count].fT == 1; | 48 return count > 1 && fTs[0].fT == 0 && fTs[--count].fT == 1; |
49 } | 49 } |
50 | 50 |
51 void constructLine(SkPoint shortLine[2]); | |
52 | |
53 int count() const { | 51 int count() const { |
54 return fTs.count(); | 52 return fTs.count(); |
55 } | 53 } |
56 | 54 |
57 bool done() const { | 55 bool done() const { |
58 SkASSERT(fDoneSpans <= fTs.count()); | 56 SkASSERT(fDoneSpans <= fTs.count()); |
59 return fDoneSpans == fTs.count(); | 57 return fDoneSpans == fTs.count(); |
60 } | 58 } |
61 | 59 |
62 bool done(int min) const { | 60 bool done(int min) const { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 int index = tStart < tEnd ? span.fToAngleIndex : span.fFromAngleIndex; | 184 int index = tStart < tEnd ? span.fToAngleIndex : span.fFromAngleIndex; |
187 return index >= 0 ? &angle(index) : NULL; | 185 return index >= 0 ? &angle(index) : NULL; |
188 } | 186 } |
189 | 187 |
190 // FIXME: create some sort of macro or template that avoids casting | 188 // FIXME: create some sort of macro or template that avoids casting |
191 SkOpAngle* spanToAngle(int tStart, int tEnd) { | 189 SkOpAngle* spanToAngle(int tStart, int tEnd) { |
192 const SkOpAngle* cAngle = (const_cast<const SkOpSegment*>(this))->spanTo
Angle(tStart, tEnd); | 190 const SkOpAngle* cAngle = (const_cast<const SkOpSegment*>(this))->spanTo
Angle(tStart, tEnd); |
193 return const_cast<SkOpAngle*>(cAngle); | 191 return const_cast<SkOpAngle*>(cAngle); |
194 } | 192 } |
195 | 193 |
196 // OPTIMIZATION: mark as debugging only if used solely by tests | |
197 const SkTDArray<SkOpSpan>& spans() const { | |
198 return fTs; | |
199 } | |
200 | |
201 int spanSign(const SkOpAngle* angle) const { | 194 int spanSign(const SkOpAngle* angle) const { |
202 SkASSERT(angle->segment() == this); | 195 SkASSERT(angle->segment() == this); |
203 return spanSign(angle->start(), angle->end()); | 196 return spanSign(angle->start(), angle->end()); |
204 } | 197 } |
205 | 198 |
206 int spanSign(int startIndex, int endIndex) const { | 199 int spanSign(int startIndex, int endIndex) const { |
207 int result = startIndex < endIndex ? -fTs[startIndex].fWindValue : fTs[e
ndIndex].fWindValue; | 200 int result = startIndex < endIndex ? -fTs[startIndex].fWindValue : fTs[e
ndIndex].fWindValue; |
208 #if DEBUG_WIND_BUMP | 201 #if DEBUG_WIND_BUMP |
209 SkDebugf("%s spanSign=%d\n", __FUNCTION__, result); | 202 SkDebugf("%s spanSign=%d\n", __FUNCTION__, result); |
210 #endif | 203 #endif |
211 return result; | 204 return result; |
212 } | 205 } |
213 | 206 |
214 double t(int tIndex) const { | 207 double t(int tIndex) const { |
215 return fTs[tIndex].fT; | 208 return fTs[tIndex].fT; |
216 } | 209 } |
217 | 210 |
218 double tAtMid(int start, int end, double mid) const { | 211 double tAtMid(int start, int end, double mid) const { |
219 return fTs[start].fT * (1 - mid) + fTs[end].fT * mid; | 212 return fTs[start].fT * (1 - mid) + fTs[end].fT * mid; |
220 } | 213 } |
221 | 214 |
222 bool unsortable(int index) const { | |
223 return fTs[index].fUnsortableStart || fTs[index].fUnsortableEnd; | |
224 } | |
225 | |
226 void updatePts(const SkPoint pts[]) { | 215 void updatePts(const SkPoint pts[]) { |
227 fPts = pts; | 216 fPts = pts; |
228 } | 217 } |
229 | 218 |
230 SkPath::Verb verb() const { | 219 SkPath::Verb verb() const { |
231 return fVerb; | 220 return fVerb; |
232 } | 221 } |
233 | 222 |
234 int windSum(int tIndex) const { | 223 int windSum(int tIndex) const { |
235 return fTs[tIndex].fWindSum; | 224 return fTs[tIndex].fWindSum; |
(...skipping 24 matching lines...) Expand all Loading... |
260 } | 249 } |
261 | 250 |
262 #if defined(SK_DEBUG) || DEBUG_WINDING | 251 #if defined(SK_DEBUG) || DEBUG_WINDING |
263 SkScalar yAtT(int index) const { | 252 SkScalar yAtT(int index) const { |
264 return yAtT(&fTs[index]); | 253 return yAtT(&fTs[index]); |
265 } | 254 } |
266 #endif | 255 #endif |
267 | 256 |
268 const SkOpAngle* activeAngle(int index, int* start, int* end, bool* done, | 257 const SkOpAngle* activeAngle(int index, int* start, int* end, bool* done, |
269 bool* sortable) const; | 258 bool* sortable) const; |
270 SkPoint activeLeftTop(bool onlySortable, int* firstT) const; | 259 SkPoint activeLeftTop(int* firstT) const; |
271 bool activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathO
p op); | 260 bool activeOp(int index, int endIndex, int xorMiMask, int xorSuMask, SkPathO
p op); |
272 bool activeWinding(int index, int endIndex); | 261 bool activeWinding(int index, int endIndex); |
273 void addCubic(const SkPoint pts[4], bool operand, bool evenOdd); | 262 void addCubic(const SkPoint pts[4], bool operand, bool evenOdd); |
274 void addCurveTo(int start, int end, SkPathWriter* path, bool active) const; | 263 void addCurveTo(int start, int end, SkPathWriter* path, bool active) const; |
275 void addEndSpan(int endIndex); | 264 void addEndSpan(int endIndex); |
276 void addLine(const SkPoint pts[2], bool operand, bool evenOdd); | 265 void addLine(const SkPoint pts[2], bool operand, bool evenOdd); |
277 void addOtherT(int index, double otherT, int otherIndex); | 266 void addOtherT(int index, double otherT, int otherIndex); |
278 void addQuad(const SkPoint pts[3], bool operand, bool evenOdd); | 267 void addQuad(const SkPoint pts[3], bool operand, bool evenOdd); |
279 void addSimpleAngle(int endIndex); | 268 void addSimpleAngle(int endIndex); |
280 int addSelfT(const SkPoint& pt, double newT); | 269 int addSelfT(const SkPoint& pt, double newT); |
281 void addStartSpan(int endIndex); | 270 void addStartSpan(int endIndex); |
282 int addT(SkOpSegment* other, const SkPoint& pt, double newT); | 271 int addT(SkOpSegment* other, const SkPoint& pt, double newT); |
283 void addTCancel(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* o
ther); | 272 void addTCancel(const SkPoint& startPt, const SkPoint& endPt, SkOpSegment* o
ther); |
284 void addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double end
T, | 273 void addTCoincident(const SkPoint& startPt, const SkPoint& endPt, double end
T, |
285 SkOpSegment* other); | 274 SkOpSegment* other); |
286 const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool b
orrowWind, | 275 const SkOpSpan* addTPair(double t, SkOpSegment* other, double otherT, bool b
orrowWind, |
287 const SkPoint& pt); | 276 const SkPoint& pt); |
288 bool alignSpan(int index, double thisT, const SkPoint& thisPt); | 277 bool alignSpan(int index, double thisT, const SkPoint& thisPt); |
289 void alignSpanState(int start, int end); | 278 void alignSpanState(int start, int end); |
290 const SkOpAngle& angle(int index) const; | 279 const SkOpAngle& angle(int index) const; |
291 bool betweenTs(int lesser, double testT, int greater) const; | 280 bool betweenTs(int lesser, double testT, int greater) const; |
292 bool calcAngles(); | 281 bool calcAngles(); |
293 void checkDuplicates(); | 282 void checkDuplicates(); |
294 void checkEnds(); | 283 void checkEnds(); |
295 void checkMultiples(); | 284 void checkMultiples(); |
296 void checkSmall(); | 285 void checkSmall(); |
297 bool checkSmall(int index) const; | 286 bool checkSmall(int index) const; |
298 void checkTiny(); | 287 void checkTiny(); |
299 int computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType includeT
ype); | 288 int computeSum(int startIndex, int endIndex, SkOpAngle::IncludeType includeT
ype); |
| 289 bool containsPt(const SkPoint& , int index, int endIndex) const; |
300 int crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hitT, bool*
hitSomething, | 290 int crossedSpanY(const SkPoint& basePt, SkScalar* bestY, double* hitT, bool*
hitSomething, |
301 double mid, bool opp, bool current) const; | 291 double mid, bool opp, bool current) const; |
302 bool findCoincidentMatch(const SkOpSpan* span, const SkOpSegment* other, int
oStart, int oEnd, | 292 bool findCoincidentMatch(const SkOpSpan* span, const SkOpSegment* other, int
oStart, int oEnd, |
303 int step, SkPoint* startPt, SkPoint* endPt, double*
endT) const; | 293 int step, SkPoint* startPt, SkPoint* endPt, double*
endT) const; |
304 SkOpSegment* findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* ne
xtEnd, | 294 SkOpSegment* findNextOp(SkTDArray<SkOpSpan*>* chase, int* nextStart, int* ne
xtEnd, |
305 bool* unsortable, SkPathOp op, int xorMiMask, int xo
rSuMask); | 295 bool* unsortable, SkPathOp op, int xorMiMask, int xo
rSuMask); |
306 SkOpSegment* findNextWinding(SkTDArray<SkOpSpan*>* chase, int* nextStart, in
t* nextEnd, | 296 SkOpSegment* findNextWinding(SkTDArray<SkOpSpan*>* chase, int* nextStart, in
t* nextEnd, |
307 bool* unsortable); | 297 bool* unsortable); |
308 SkOpSegment* findNextXor(int* nextStart, int* nextEnd, bool* unsortable); | 298 SkOpSegment* findNextXor(int* nextStart, int* nextEnd, bool* unsortable); |
309 int findExactT(double t, const SkOpSegment* ) const; | 299 int findExactT(double t, const SkOpSegment* ) const; |
310 int findT(double t, const SkOpSegment* ) const; | 300 int findT(double t, const SkPoint& , const SkOpSegment* ) const; |
311 SkOpSegment* findTop(int* tIndex, int* endIndex, bool* unsortable); | 301 SkOpSegment* findTop(int* tIndex, int* endIndex, bool* unsortable, bool firs
tPass); |
312 void fixOtherTIndex(); | 302 void fixOtherTIndex(); |
313 void initWinding(int start, int end, SkOpAngle::IncludeType angleIncludeType
); | 303 void initWinding(int start, int end, SkOpAngle::IncludeType angleIncludeType
); |
314 void initWinding(int start, int end, double tHit, int winding, SkScalar hitD
x, int oppWind, | 304 void initWinding(int start, int end, double tHit, int winding, SkScalar hitD
x, int oppWind, |
315 SkScalar hitOppDx); | 305 SkScalar hitOppDx); |
316 bool isMissing(double startT, const SkPoint& pt) const; | 306 bool isMissing(double startT, const SkPoint& pt) const; |
317 bool isSmall(const SkOpAngle* angle) const; | |
318 bool isTiny(const SkOpAngle* angle) const; | 307 bool isTiny(const SkOpAngle* angle) const; |
319 bool joinCoincidence(SkOpSegment* other, double otherT, int step, bool cance
l); | 308 bool joinCoincidence(SkOpSegment* other, double otherT, const SkPoint& other
Pt, int step, |
| 309 bool cancel); |
320 SkOpSpan* markAndChaseDoneBinary(int index, int endIndex); | 310 SkOpSpan* markAndChaseDoneBinary(int index, int endIndex); |
321 SkOpSpan* markAndChaseDoneUnary(int index, int endIndex); | 311 SkOpSpan* markAndChaseDoneUnary(int index, int endIndex); |
322 SkOpSpan* markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWi
nding); | 312 SkOpSpan* markAndChaseWinding(const SkOpAngle* angle, int winding, int oppWi
nding); |
323 SkOpSpan* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int o
ppSumWinding, | 313 SkOpSpan* markAngle(int maxWinding, int sumWinding, int oppMaxWinding, int o
ppSumWinding, |
324 const SkOpAngle* angle); | 314 const SkOpAngle* angle); |
325 void markDone(int index, int winding); | 315 void markDone(int index, int winding); |
326 void markDoneBinary(int index); | 316 void markDoneBinary(int index); |
327 void markDoneUnary(int index); | 317 void markDoneUnary(int index); |
328 bool nextCandidate(int* start, int* end) const; | 318 bool nextCandidate(int* start, int* end) const; |
329 int nextSpan(int from, int step) const; | 319 int nextSpan(int from, int step) const; |
(...skipping 24 matching lines...) Expand all Loading... |
354 #endif | 344 #endif |
355 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY | 345 #if DEBUG_ACTIVE_SPANS || DEBUG_ACTIVE_SPANS_FIRST_ONLY |
356 void debugShowActiveSpans() const; | 346 void debugShowActiveSpans() const; |
357 #endif | 347 #endif |
358 #if DEBUG_CONCIDENT | 348 #if DEBUG_CONCIDENT |
359 void debugShowTs(const char* prefix) const; | 349 void debugShowTs(const char* prefix) const; |
360 #endif | 350 #endif |
361 #if DEBUG_SHOW_WINDING | 351 #if DEBUG_SHOW_WINDING |
362 int debugShowWindingValues(int slotCount, int ofInterest) const; | 352 int debugShowWindingValues(int slotCount, int ofInterest) const; |
363 #endif | 353 #endif |
| 354 const SkTDArray<SkOpSpan>& debugSpans() const; |
364 void debugValidate() const; | 355 void debugValidate() const; |
365 // available to testing only | 356 // available to testing only |
366 void dumpAngles() const; | 357 void dumpAngles() const; |
367 void dumpContour(int firstID, int lastID) const; | 358 void dumpContour(int firstID, int lastID) const; |
368 void dumpPts() const; | 359 void dumpPts() const; |
369 void dumpSpans() const; | 360 void dumpSpans() const; |
370 | 361 |
371 private: | 362 private: |
372 struct MissingSpan { | 363 struct MissingSpan { |
373 double fT; | 364 double fT; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 void markDoneBinary(int index, int winding, int oppWinding); | 423 void markDoneBinary(int index, int winding, int oppWinding); |
433 SkOpSpan* markAndChaseDoneUnary(const SkOpAngle* angle, int winding); | 424 SkOpSpan* markAndChaseDoneUnary(const SkOpAngle* angle, int winding); |
434 void markOneDone(const char* funName, int tIndex, int winding); | 425 void markOneDone(const char* funName, int tIndex, int winding); |
435 void markOneDoneBinary(const char* funName, int tIndex); | 426 void markOneDoneBinary(const char* funName, int tIndex); |
436 void markOneDoneBinary(const char* funName, int tIndex, int winding, int opp
Winding); | 427 void markOneDoneBinary(const char* funName, int tIndex, int winding, int opp
Winding); |
437 void markOneDoneUnary(const char* funName, int tIndex); | 428 void markOneDoneUnary(const char* funName, int tIndex); |
438 SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding); | 429 SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding); |
439 SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding, int o
ppWinding); | 430 SkOpSpan* markOneWinding(const char* funName, int tIndex, int winding, int o
ppWinding); |
440 void markWinding(int index, int winding); | 431 void markWinding(int index, int winding); |
441 void markWinding(int index, int winding, int oppWinding); | 432 void markWinding(int index, int winding, int oppWinding); |
442 void markUnsortable(int start, int end); | |
443 bool monotonicInY(int tStart, int tEnd) const; | 433 bool monotonicInY(int tStart, int tEnd) const; |
444 | 434 |
445 bool multipleEnds() const { | 435 bool multipleEnds() const { |
446 return fTs[count() - 2].fT == 1; | 436 return fTs[count() - 2].fT == 1; |
447 } | 437 } |
448 | 438 |
449 bool multipleStarts() const { | 439 bool multipleStarts() const { |
450 return fTs[1].fT == 0; | 440 return fTs[1].fT == 0; |
451 } | 441 } |
452 | 442 |
(...skipping 30 matching lines...) Expand all Loading... |
483 #if DEBUG_SWAP_TOP | 473 #if DEBUG_SWAP_TOP |
484 bool controlsContainedByEnds(int tStart, int tEnd) const; | 474 bool controlsContainedByEnds(int tStart, int tEnd) const; |
485 #endif | 475 #endif |
486 void debugAddAngle(int start, int end); | 476 void debugAddAngle(int start, int end); |
487 #if DEBUG_CONCIDENT | 477 #if DEBUG_CONCIDENT |
488 void debugAddTPair(double t, const SkOpSegment& other, double otherT) const; | 478 void debugAddTPair(double t, const SkOpSegment& other, double otherT) const; |
489 #endif | 479 #endif |
490 #if DEBUG_ANGLE | 480 #if DEBUG_ANGLE |
491 void debugCheckPointsEqualish(int tStart, int tEnd) const; | 481 void debugCheckPointsEqualish(int tStart, int tEnd) const; |
492 #endif | 482 #endif |
| 483 #if DEBUG_SWAP_TOP |
| 484 int debugInflections(int index, int endIndex) const; |
| 485 #endif |
493 #if DEBUG_MARK_DONE || DEBUG_UNSORTABLE | 486 #if DEBUG_MARK_DONE || DEBUG_UNSORTABLE |
494 void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding)
; | 487 void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding)
; |
495 void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding,
int oppWinding); | 488 void debugShowNewWinding(const char* fun, const SkOpSpan& span, int winding,
int oppWinding); |
496 #endif | 489 #endif |
497 #if DEBUG_WINDING | 490 #if DEBUG_WINDING |
498 static char as_digit(int value) { | 491 static char as_digit(int value) { |
499 return value < 0 ? '?' : value <= 9 ? '0' + value : '+'; | 492 return value < 0 ? '?' : value <= 9 ? '0' + value : '+'; |
500 } | 493 } |
501 #endif | 494 #endif |
502 // available to testing only | 495 // available to testing only |
(...skipping 23 matching lines...) Expand all Loading... |
526 bool fSmall; // set if some span is small | 519 bool fSmall; // set if some span is small |
527 bool fTiny; // set if some span is tiny | 520 bool fTiny; // set if some span is tiny |
528 #if defined(SK_DEBUG) || !FORCE_RELEASE | 521 #if defined(SK_DEBUG) || !FORCE_RELEASE |
529 int fID; | 522 int fID; |
530 #endif | 523 #endif |
531 | 524 |
532 friend class PathOpsSegmentTester; | 525 friend class PathOpsSegmentTester; |
533 }; | 526 }; |
534 | 527 |
535 #endif | 528 #endif |
OLD | NEW |