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 #include "SkIntersections.h" | 7 #include "SkIntersections.h" |
8 #include "SkOpAngle.h" | 8 #include "SkOpAngle.h" |
9 #include "SkOpSegment.h" | 9 #include "SkOpSegment.h" |
10 #include "SkPathOpsCurve.h" | 10 #include "SkPathOpsCurve.h" |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 } | 282 } |
283 | 283 |
284 // the original angle is too short to get meaningful sector information | 284 // the original angle is too short to get meaningful sector information |
285 // lengthen it until it is long enough to be meaningful or leave it unset if len
gthening it | 285 // lengthen it until it is long enough to be meaningful or leave it unset if len
gthening it |
286 // would cause it to intersect one of the adjacent angles | 286 // would cause it to intersect one of the adjacent angles |
287 bool SkOpAngle::computeSector() { | 287 bool SkOpAngle::computeSector() { |
288 if (fComputedSector) { | 288 if (fComputedSector) { |
289 // FIXME: logically, this should return !fUnorderable, but doing so brea
ks testQuadratic51 | 289 // FIXME: logically, this should return !fUnorderable, but doing so brea
ks testQuadratic51 |
290 // -- but in general, this code may not work so this may be the least of
problems | 290 // -- but in general, this code may not work so this may be the least of
problems |
291 // adding the bang fixes testQuads46x in release, however | 291 // adding the bang fixes testQuads46x in release, however |
292 return fUnorderable; | 292 return !fUnorderable; |
293 } | 293 } |
294 SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small()); | 294 SkASSERT(fSegment->verb() != SkPath::kLine_Verb && small()); |
295 fComputedSector = true; | 295 fComputedSector = true; |
296 int step = fStart < fEnd ? 1 : -1; | 296 int step = fStart < fEnd ? 1 : -1; |
297 int limit = step > 0 ? fSegment->count() : -1; | 297 int limit = step > 0 ? fSegment->count() : -1; |
298 int checkEnd = fEnd; | 298 int checkEnd = fEnd; |
299 do { | 299 do { |
300 // advance end | 300 // advance end |
301 const SkOpSpan& span = fSegment->span(checkEnd); | 301 const SkOpSpan& span = fSegment->span(checkEnd); |
302 const SkOpSegment* other = span.fOther; | 302 const SkOpSegment* other = span.fOther; |
(...skipping 12 matching lines...) Expand all Loading... |
315 goto recomputeSector; | 315 goto recomputeSector; |
316 } | 316 } |
317 checkEnd += step; | 317 checkEnd += step; |
318 } while (checkEnd != limit); | 318 } while (checkEnd != limit); |
319 recomputeSector: | 319 recomputeSector: |
320 if (checkEnd == fEnd || checkEnd - step == fEnd) { | 320 if (checkEnd == fEnd || checkEnd - step == fEnd) { |
321 fUnorderable = true; | 321 fUnorderable = true; |
322 return false; | 322 return false; |
323 } | 323 } |
324 int saveEnd = fEnd; | 324 int saveEnd = fEnd; |
325 fEnd = checkEnd - step; | 325 fComputedEnd = fEnd = checkEnd - step; |
326 setSpans(); | 326 setSpans(); |
327 setSector(); | 327 setSector(); |
328 fEnd = saveEnd; | 328 fEnd = saveEnd; |
329 return !fUnorderable; | 329 return !fUnorderable; |
330 } | 330 } |
331 | 331 |
332 // returns -1 if overlaps 0 if no overlap cw 1 if no overlap ccw | 332 // returns -1 if overlaps 0 if no overlap cw 1 if no overlap ccw |
333 int SkOpAngle::convexHullOverlaps(const SkOpAngle& rh) const { | 333 int SkOpAngle::convexHullOverlaps(const SkOpAngle& rh) const { |
334 const SkDVector* sweep = fSweep; | 334 const SkDVector* sweep = fSweep; |
335 const SkDVector* tweep = rh.fSweep; | 335 const SkDVector* tweep = rh.fSweep; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 if (rays[0][1] == rays[1][1]) { | 407 if (rays[0][1] == rays[1][1]) { |
408 return checkParallel(rh); | 408 return checkParallel(rh); |
409 } | 409 } |
410 double smallTs[2] = {-1, -1}; | 410 double smallTs[2] = {-1, -1}; |
411 bool limited[2] = {false, false}; | 411 bool limited[2] = {false, false}; |
412 for (int index = 0; index < 2; ++index) { | 412 for (int index = 0; index < 2; ++index) { |
413 const SkOpSegment& segment = index ? *rh.fSegment : *fSegment; | 413 const SkOpSegment& segment = index ? *rh.fSegment : *fSegment; |
414 SkIntersections i; | 414 SkIntersections i; |
415 (*CurveIntersectRay[index ? rPts : lPts])(segment.pts(), rays[index], &i
); | 415 (*CurveIntersectRay[index ? rPts : lPts])(segment.pts(), rays[index], &i
); |
416 // SkASSERT(i.used() >= 1); | 416 // SkASSERT(i.used() >= 1); |
417 if (i.used() <= 1) { | 417 // if (i.used() <= 1) { |
418 continue; | 418 // continue; |
419 } | 419 // } |
420 double tStart = segment.t(index ? rh.fStart : fStart); | 420 double tStart = segment.t(index ? rh.fStart : fStart); |
421 double tEnd = segment.t(index ? rh.fEnd : fEnd); | 421 double tEnd = segment.t(index ? rh.fComputedEnd : fComputedEnd); |
422 bool testAscends = index ? rh.fStart < rh.fEnd : fStart < fEnd; | 422 bool testAscends = index ? rh.fStart < rh.fComputedEnd : fStart < fCompu
tedEnd; |
423 double t = testAscends ? 0 : 1; | 423 double t = testAscends ? 0 : 1; |
424 for (int idx2 = 0; idx2 < i.used(); ++idx2) { | 424 for (int idx2 = 0; idx2 < i.used(); ++idx2) { |
425 double testT = i[0][idx2]; | 425 double testT = i[0][idx2]; |
426 if (!approximately_between_orderable(tStart, testT, tEnd)) { | 426 if (!approximately_between_orderable(tStart, testT, tEnd)) { |
427 continue; | 427 continue; |
428 } | 428 } |
429 if (approximately_equal_orderable(tStart, testT)) { | 429 if (approximately_equal_orderable(tStart, testT)) { |
430 continue; | 430 continue; |
431 } | 431 } |
432 smallTs[index] = t = testAscends ? SkTMax(t, testT) : SkTMin(t, test
T); | 432 smallTs[index] = t = testAscends ? SkTMax(t, testT) : SkTMin(t, test
T); |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 do { | 872 do { |
873 SkOpAngle* next = last->fNext; | 873 SkOpAngle* next = last->fNext; |
874 if (next == this) { | 874 if (next == this) { |
875 return last; | 875 return last; |
876 } | 876 } |
877 last = next; | 877 last = next; |
878 } while (true); | 878 } while (true); |
879 } | 879 } |
880 | 880 |
881 void SkOpAngle::set(const SkOpSegment* segment, int start, int end) { | 881 void SkOpAngle::set(const SkOpSegment* segment, int start, int end) { |
882 #if DEBUG_ANGLE | |
883 fID = 0; | |
884 #endif | |
885 fSegment = segment; | 882 fSegment = segment; |
886 fStart = start; | 883 fStart = start; |
887 fEnd = end; | 884 fComputedEnd = fEnd = end; |
888 fNext = NULL; | 885 fNext = NULL; |
889 fComputeSector = fComputedSector = false; | 886 fComputeSector = fComputedSector = false; |
890 fStop = false; | 887 fStop = false; |
891 setSpans(); | 888 setSpans(); |
892 setSector(); | 889 setSector(); |
893 } | 890 } |
894 | 891 |
895 void SkOpAngle::setCurveHullSweep() { | 892 void SkOpAngle::setCurveHullSweep() { |
896 fUnorderedSweep = false; | 893 fUnorderedSweep = false; |
897 fSweep[0] = fCurvePart[1] - fCurvePart[0]; | 894 fSweep[0] = fCurvePart[1] - fCurvePart[0]; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1090 return true; | 1087 return true; |
1091 } | 1088 } |
1092 SkASSERT(s0dt0 != 0); | 1089 SkASSERT(s0dt0 != 0); |
1093 double m = s0xt0 / s0dt0; | 1090 double m = s0xt0 / s0dt0; |
1094 double sDist = sweep[0].length() * m; | 1091 double sDist = sweep[0].length() * m; |
1095 double tDist = tweep[0].length() * m; | 1092 double tDist = tweep[0].length() * m; |
1096 bool useS = fabs(sDist) < fabs(tDist); | 1093 bool useS = fabs(sDist) < fabs(tDist); |
1097 double mFactor = fabs(useS ? distEndRatio(sDist) : rh.distEndRatio(tDist)); | 1094 double mFactor = fabs(useS ? distEndRatio(sDist) : rh.distEndRatio(tDist)); |
1098 return mFactor < 5000; // empirically found limit | 1095 return mFactor < 5000; // empirically found limit |
1099 } | 1096 } |
| 1097 |
| 1098 SkOpAngleSet::SkOpAngleSet() |
| 1099 : fAngles(NULL) |
| 1100 #if DEBUG_ANGLE |
| 1101 , fCount(0) |
| 1102 #endif |
| 1103 { |
| 1104 } |
| 1105 |
| 1106 SkOpAngleSet::~SkOpAngleSet() { |
| 1107 SkDELETE(fAngles); |
| 1108 } |
| 1109 |
| 1110 SkOpAngle& SkOpAngleSet::push_back() { |
| 1111 if (!fAngles) { |
| 1112 fAngles = SkNEW_ARGS(SkChunkAlloc, (2)); |
| 1113 } |
| 1114 void* ptr = fAngles->allocThrow(sizeof(SkOpAngle)); |
| 1115 SkOpAngle* angle = (SkOpAngle*) ptr; |
| 1116 #if DEBUG_ANGLE |
| 1117 angle->setID(++fCount); |
| 1118 #endif |
| 1119 return *angle; |
| 1120 } |
| 1121 |
| 1122 void SkOpAngleSet::reset() { |
| 1123 if (fAngles) { |
| 1124 fAngles->reset(); |
| 1125 } |
| 1126 } |
OLD | NEW |