| 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 |