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 "SkOpAngle.h" | 7 #include "SkOpAngle.h" |
8 #include "SkOpSegment.h" | 8 #include "SkOpSegment.h" |
9 #include "SkPathOpsCurve.h" | 9 #include "SkPathOpsCurve.h" |
10 #include "SkTSort.h" | 10 #include "SkTSort.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 20 | 26 | 55 20 | 26 |
56 21 | 25 | 56 21 | 25 |
57 22 23 24 | 57 22 23 24 |
58 */ | 58 */ |
59 | 59 |
60 // return true if lh < this < rh | 60 // return true if lh < this < rh |
61 bool SkOpAngle::after(SkOpAngle* test) { | 61 bool SkOpAngle::after(SkOpAngle* test) { |
62 SkOpAngle* lh = test; | 62 SkOpAngle* lh = test; |
63 SkOpAngle* rh = lh->fNext; | 63 SkOpAngle* rh = lh->fNext; |
64 SkASSERT(lh != rh); | 64 SkASSERT(lh != rh); |
| 65 fCurvePart = fOriginalCurvePart; |
| 66 lh->fCurvePart = lh->fOriginalCurvePart; |
| 67 lh->fCurvePart.offset(lh->segment()->verb(), fCurvePart[0] - lh->fCurvePart[
0]); |
| 68 rh->fCurvePart = rh->fOriginalCurvePart; |
| 69 rh->fCurvePart.offset(rh->segment()->verb(), fCurvePart[0] - rh->fCurvePart[
0]); |
| 70 |
65 #if DEBUG_ANGLE | 71 #if DEBUG_ANGLE |
66 SkString bugOut; | 72 SkString bugOut; |
67 bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" | 73 bugOut.printf("%s [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" |
68 " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" | 74 " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g" |
69 " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__, | 75 " < [%d/%d] %d/%d tStart=%1.9g tEnd=%1.9g ", __FUNCTION__, |
70 lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSect
orEnd, | 76 lh->segment()->debugID(), lh->debugID(), lh->fSectorStart, lh->fSect
orEnd, |
71 lh->fStart->t(), lh->fEnd->t(), | 77 lh->fStart->t(), lh->fEnd->t(), |
72 segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t
(), fEnd->t(), | 78 segment()->debugID(), debugID(), fSectorStart, fSectorEnd, fStart->t
(), fEnd->t(), |
73 rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSect
orEnd, | 79 rh->segment()->debugID(), rh->debugID(), rh->fSectorStart, rh->fSect
orEnd, |
74 rh->fStart->t(), rh->fEnd->t()); | 80 rh->fStart->t(), rh->fEnd->t()); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 // FIXME : once all variants are understood, rewrite this more simply | 149 // FIXME : once all variants are understood, rewrite this more simply |
144 if (ltOrder == 0 && lrOrder == 0) { | 150 if (ltOrder == 0 && lrOrder == 0) { |
145 SkASSERT(trOrder < 0); | 151 SkASSERT(trOrder < 0); |
146 // FIXME : once this is verified to work, remove one opposite angle call | 152 // FIXME : once this is verified to work, remove one opposite angle call |
147 SkDEBUGCODE(bool lrOpposite = lh->oppositePlanes(rh)); | 153 SkDEBUGCODE(bool lrOpposite = lh->oppositePlanes(rh)); |
148 bool ltOpposite = lh->oppositePlanes(this); | 154 bool ltOpposite = lh->oppositePlanes(this); |
149 SkASSERT(lrOpposite != ltOpposite); | 155 SkASSERT(lrOpposite != ltOpposite); |
150 return COMPARE_RESULT(8, ltOpposite); | 156 return COMPARE_RESULT(8, ltOpposite); |
151 } else if (ltOrder == 1 && trOrder == 0) { | 157 } else if (ltOrder == 1 && trOrder == 0) { |
152 SkASSERT(lrOrder < 0); | 158 SkASSERT(lrOrder < 0); |
153 SkDEBUGCODE(bool ltOpposite = lh->oppositePlanes(this)); | |
154 bool trOpposite = oppositePlanes(rh); | 159 bool trOpposite = oppositePlanes(rh); |
155 SkASSERT(ltOpposite != trOpposite); | |
156 return COMPARE_RESULT(9, trOpposite); | 160 return COMPARE_RESULT(9, trOpposite); |
157 } else if (lrOrder == 1 && trOrder == 1) { | 161 } else if (lrOrder == 1 && trOrder == 1) { |
158 SkASSERT(ltOrder < 0); | 162 SkASSERT(ltOrder < 0); |
159 SkDEBUGCODE(bool trOpposite = oppositePlanes(rh)); | 163 SkDEBUGCODE(bool trOpposite = oppositePlanes(rh)); |
160 bool lrOpposite = lh->oppositePlanes(rh); | 164 bool lrOpposite = lh->oppositePlanes(rh); |
161 SkASSERT(lrOpposite != trOpposite); | 165 SkASSERT(lrOpposite != trOpposite); |
162 return COMPARE_RESULT(10, lrOpposite); | 166 return COMPARE_RESULT(10, lrOpposite); |
163 } | 167 } |
164 if (lrOrder < 0) { | 168 if (lrOrder < 0) { |
165 if (ltOrder < 0) { | 169 if (ltOrder < 0) { |
166 return COMPARE_RESULT(11, trOrder); | 170 return COMPARE_RESULT(11, trOrder); |
167 } | 171 } |
168 return COMPARE_RESULT(12, ltOrder); | 172 return COMPARE_RESULT(12, ltOrder); |
169 } | 173 } |
170 return COMPARE_RESULT(13, !lrOrder); | 174 return COMPARE_RESULT(13, !lrOrder); |
171 } | 175 } |
172 | 176 |
173 // given a line, see if the opposite curve's convex hull is all on one side | 177 // given a line, see if the opposite curve's convex hull is all on one side |
174 // returns -1=not on one side 0=this CW of test 1=this CCW of test | 178 // returns -1=not on one side 0=this CW of test 1=this CCW of test |
175 int SkOpAngle::allOnOneSide(const SkOpAngle* test) { | 179 int SkOpAngle::allOnOneSide(const SkOpAngle* test) { |
176 SkASSERT(!fIsCurve); | 180 SkASSERT(!fIsCurve); |
177 SkASSERT(test->fIsCurve); | 181 SkASSERT(test->fIsCurve); |
178 const SkDPoint& origin = test->fCurvePart[0]; | 182 SkDPoint origin = fCurvePart[0]; |
179 SkVector line; | 183 SkDVector line = fCurvePart[1] - origin; |
180 if (segment()->verb() == SkPath::kLine_Verb) { | |
181 const SkPoint* linePts = segment()->pts(); | |
182 int lineStart = fStart->t() < fEnd->t() ? 0 : 1; | |
183 line = linePts[lineStart ^ 1] - linePts[lineStart]; | |
184 } else { | |
185 line = (fCurvePart[1] - fCurvePart[0]).asSkVector(); | |
186 } | |
187 float crosses[3]; | 184 float crosses[3]; |
188 SkPath::Verb testVerb = test->segment()->verb(); | 185 SkPath::Verb testVerb = test->segment()->verb(); |
189 int iMax = SkPathOpsVerbToPoints(testVerb); | 186 int iMax = SkPathOpsVerbToPoints(testVerb); |
190 // SkASSERT(origin == test.fCurveHalf[0]); | 187 // SkASSERT(origin == test.fCurveHalf[0]); |
191 const SkDCurve& testCurve = test->fCurvePart; | 188 const SkDCurve& testCurve = test->fCurvePart; |
192 for (int index = 1; index <= iMax; ++index) { | 189 for (int index = 1; index <= iMax; ++index) { |
193 float xy1 = (float) (line.fX * (testCurve[index].fY - origin.fY)); | 190 float xy1 = (float) (line.fX * (testCurve[index].fY - origin.fY)); |
194 float xy2 = (float) (line.fY * (testCurve[index].fX - origin.fX)); | 191 float xy2 = (float) (line.fY * (testCurve[index].fX - origin.fX)); |
195 crosses[index - 1] = AlmostEqualUlps(xy1, xy2) ? 0 : xy1 - xy2; | 192 crosses[index - 1] = AlmostEqualUlps(xy1, xy2) ? 0 : xy1 - xy2; |
196 } | 193 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 scratch[1] = rh->fCurvePart[1] - rh->fCurvePart[0]; | 234 scratch[1] = rh->fCurvePart[1] - rh->fCurvePart[0]; |
238 tweep = &scratch[1]; | 235 tweep = &scratch[1]; |
239 } | 236 } |
240 double s0xt0 = sweep->crossCheck(*tweep); | 237 double s0xt0 = sweep->crossCheck(*tweep); |
241 if (tangentsDiverge(rh, s0xt0)) { | 238 if (tangentsDiverge(rh, s0xt0)) { |
242 return s0xt0 < 0; | 239 return s0xt0 < 0; |
243 } | 240 } |
244 // compute the perpendicular to the endpoints and see where it intersects th
e opposite curve | 241 // compute the perpendicular to the endpoints and see where it intersects th
e opposite curve |
245 // if the intersections within the t range, do a cross check on those | 242 // if the intersections within the t range, do a cross check on those |
246 bool inside; | 243 bool inside; |
247 if (!fCurvePart[SkPathOpsVerbToPoints(this->segment()->verb())].approximatel
yEqual( | 244 if (!fEnd->contains(rh->fEnd)) { |
248 rh->fCurvePart[SkPathOpsVerbToPoints(rh->segment()->verb())])) { | |
249 if (this->endToSide(rh, &inside)) { | 245 if (this->endToSide(rh, &inside)) { |
250 return inside; | 246 return inside; |
251 } | 247 } |
252 if (rh->endToSide(this, &inside)) { | 248 if (rh->endToSide(this, &inside)) { |
253 return !inside; | 249 return !inside; |
254 } | 250 } |
255 } | 251 } |
256 if (this->midToSide(rh, &inside)) { | 252 if (this->midToSide(rh, &inside)) { |
257 return inside; | 253 return inside; |
258 } | 254 } |
(...skipping 14 matching lines...) Expand all Loading... |
273 | 269 |
274 // the original angle is too short to get meaningful sector information | 270 // the original angle is too short to get meaningful sector information |
275 // lengthen it until it is long enough to be meaningful or leave it unset if len
gthening it | 271 // lengthen it until it is long enough to be meaningful or leave it unset if len
gthening it |
276 // would cause it to intersect one of the adjacent angles | 272 // would cause it to intersect one of the adjacent angles |
277 bool SkOpAngle::computeSector() { | 273 bool SkOpAngle::computeSector() { |
278 if (fComputedSector) { | 274 if (fComputedSector) { |
279 return !fUnorderable; | 275 return !fUnorderable; |
280 } | 276 } |
281 fComputedSector = true; | 277 fComputedSector = true; |
282 bool stepUp = fStart->t() < fEnd->t(); | 278 bool stepUp = fStart->t() < fEnd->t(); |
283 const SkOpSpanBase* checkEnd = fEnd; | 279 SkOpSpanBase* checkEnd = fEnd; |
284 if (checkEnd->final() && stepUp) { | 280 if (checkEnd->final() && stepUp) { |
285 fUnorderable = true; | 281 fUnorderable = true; |
286 return false; | 282 return false; |
287 } | 283 } |
288 do { | 284 do { |
289 // advance end | 285 // advance end |
290 const SkOpSegment* other = checkEnd->segment(); | 286 const SkOpSegment* other = checkEnd->segment(); |
291 const SkOpSpanBase* oSpan = other->head(); | 287 const SkOpSpanBase* oSpan = other->head(); |
292 do { | 288 do { |
293 if (oSpan->segment() != segment()) { | 289 if (oSpan->segment() != segment()) { |
294 continue; | 290 continue; |
295 } | 291 } |
296 if (oSpan == checkEnd) { | 292 if (oSpan == checkEnd) { |
297 continue; | 293 continue; |
298 } | 294 } |
299 if (!approximately_equal(oSpan->t(), checkEnd->t())) { | 295 if (!approximately_equal(oSpan->t(), checkEnd->t())) { |
300 continue; | 296 continue; |
301 } | 297 } |
302 goto recomputeSector; | 298 goto recomputeSector; |
303 } while (!oSpan->final() && (oSpan = oSpan->upCast()->next())); | 299 } while (!oSpan->final() && (oSpan = oSpan->upCast()->next())); |
304 checkEnd = stepUp ? !checkEnd->final() | 300 checkEnd = stepUp ? !checkEnd->final() |
305 ? checkEnd->upCast()->next() : nullptr | 301 ? checkEnd->upCast()->next() : nullptr |
306 : checkEnd->prev(); | 302 : checkEnd->prev(); |
307 } while (checkEnd); | 303 } while (checkEnd); |
308 recomputeSector: | 304 recomputeSector: |
309 SkOpSpanBase* computedEnd = stepUp ? checkEnd ? checkEnd->prev() : fEnd->seg
ment()->head() | 305 SkOpSpanBase* computedEnd = stepUp ? checkEnd ? checkEnd->prev() : fEnd->seg
ment()->head() |
310 : checkEnd ? checkEnd->upCast()->next() : fEnd->segment()->tail(); | 306 : checkEnd ? checkEnd->upCast()->next() : fEnd->segment()->tail(); |
311 if (checkEnd == fEnd || computedEnd == fEnd || computedEnd == fStart) { | 307 if (checkEnd == fEnd || computedEnd == fEnd || computedEnd == fStart) { |
312 fUnorderable = true; | 308 fUnorderable = true; |
313 return false; | 309 return false; |
314 } | 310 } |
315 if (stepUp != (fStart->t() < computedEnd->t())) { | 311 if (stepUp != (fStart->t() < computedEnd->t())) { |
316 fUnorderable = true; | 312 fUnorderable = true; |
317 return false; | 313 return false; |
318 } | 314 } |
319 SkOpSpanBase* saveEnd = fEnd; | 315 SkOpSpanBase* saveEnd = fEnd; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 return sqrt(longest) / dist; | 387 return sqrt(longest) / dist; |
392 } | 388 } |
393 | 389 |
394 bool SkOpAngle::endsIntersect(SkOpAngle* rh) { | 390 bool SkOpAngle::endsIntersect(SkOpAngle* rh) { |
395 SkPath::Verb lVerb = this->segment()->verb(); | 391 SkPath::Verb lVerb = this->segment()->verb(); |
396 SkPath::Verb rVerb = rh->segment()->verb(); | 392 SkPath::Verb rVerb = rh->segment()->verb(); |
397 int lPts = SkPathOpsVerbToPoints(lVerb); | 393 int lPts = SkPathOpsVerbToPoints(lVerb); |
398 int rPts = SkPathOpsVerbToPoints(rVerb); | 394 int rPts = SkPathOpsVerbToPoints(rVerb); |
399 SkDLine rays[] = {{{this->fCurvePart[0], rh->fCurvePart[rPts]}}, | 395 SkDLine rays[] = {{{this->fCurvePart[0], rh->fCurvePart[rPts]}}, |
400 {{this->fCurvePart[0], this->fCurvePart[lPts]}}}; | 396 {{this->fCurvePart[0], this->fCurvePart[lPts]}}}; |
401 if (rays[0][1] == rays[1][1]) { | 397 if (this->fEnd->contains(rh->fEnd)) { |
402 return checkParallel(rh); | 398 return checkParallel(rh); |
403 } | 399 } |
404 double smallTs[2] = {-1, -1}; | 400 double smallTs[2] = {-1, -1}; |
405 bool limited[2] = {false, false}; | 401 bool limited[2] = {false, false}; |
406 for (int index = 0; index < 2; ++index) { | 402 for (int index = 0; index < 2; ++index) { |
407 SkPath::Verb cVerb = index ? rVerb : lVerb; | 403 SkPath::Verb cVerb = index ? rVerb : lVerb; |
408 // if the curve is a line, then the line and the ray intersect only at t
heir crossing | 404 // if the curve is a line, then the line and the ray intersect only at t
heir crossing |
409 if (cVerb == SkPath::kLine_Verb) { | 405 if (cVerb == SkPath::kLine_Verb) { |
410 continue; | 406 continue; |
411 } | 407 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 const SkDCurve& curve = rh->fCurvePart; | 527 const SkDCurve& curve = rh->fCurvePart; |
532 int oppPts = SkPathOpsVerbToPoints(oppVerb); | 528 int oppPts = SkPathOpsVerbToPoints(oppVerb); |
533 for (int idx2 = 0; idx2 <= oppPts; ++idx2) { | 529 for (int idx2 = 0; idx2 <= oppPts; ++idx2) { |
534 minX = SkTMin(minX, curve[idx2].fX); | 530 minX = SkTMin(minX, curve[idx2].fX); |
535 minY = SkTMin(minY, curve[idx2].fY); | 531 minY = SkTMin(minY, curve[idx2].fY); |
536 maxX = SkTMax(maxX, curve[idx2].fX); | 532 maxX = SkTMax(maxX, curve[idx2].fX); |
537 maxY = SkTMax(maxY, curve[idx2].fY); | 533 maxY = SkTMax(maxY, curve[idx2].fY); |
538 } | 534 } |
539 double maxWidth = SkTMax(maxX - minX, maxY - minY); | 535 double maxWidth = SkTMax(maxX - minX, maxY - minY); |
540 endDist /= maxWidth; | 536 endDist /= maxWidth; |
541 if (endDist < 5e-11) { // empirically found | 537 if (endDist < 5e-12) { // empirically found |
542 return false; | 538 return false; |
543 } | 539 } |
544 const SkDPoint* endPt = &rayEnd[0]; | 540 const SkDPoint* endPt = &rayEnd[0]; |
545 SkDPoint oppPt = iEnd.pt(closestEnd); | 541 SkDPoint oppPt = iEnd.pt(closestEnd); |
546 SkDVector vLeft = *endPt - start; | 542 SkDVector vLeft = *endPt - start; |
547 SkDVector vRight = oppPt - start; | 543 SkDVector vRight = oppPt - start; |
548 double dir = vLeft.crossCheck(vRight); | 544 double dir = vLeft.crossNoNormalCheck(vRight); |
549 if (!dir) { | 545 if (!dir) { |
550 return false; | 546 return false; |
551 } | 547 } |
552 *inside = dir < 0; | 548 *inside = dir < 0; |
553 return true; | 549 return true; |
554 } | 550 } |
555 | 551 |
556 /* y<0 y==0 y>0 x<0 x==0 x>0 xy<0 xy==0 xy>0 | 552 /* y<0 y==0 y>0 x<0 x==0 x>0 xy<0 xy==0 xy>0 |
557 0 x x x | 553 0 x x x |
558 1 x x x | 554 1 x x x |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 double rx_y = rightX * leftY; | 774 double rx_y = rightX * leftY; |
779 if (x_ry == rx_y) { | 775 if (x_ry == rx_y) { |
780 if (leftX * rightX < 0 || leftY * rightY < 0) { | 776 if (leftX * rightX < 0 || leftY * rightY < 0) { |
781 return true; // exactly 180 degrees apart | 777 return true; // exactly 180 degrees apart |
782 } | 778 } |
783 goto unorderable; | 779 goto unorderable; |
784 } | 780 } |
785 SkASSERT(x_ry != rx_y); // indicates an undetected coincidence -- wo
rth finding earlier | 781 SkASSERT(x_ry != rx_y); // indicates an undetected coincidence -- wo
rth finding earlier |
786 return x_ry < rx_y; | 782 return x_ry < rx_y; |
787 } | 783 } |
788 if ((result = allOnOneSide(rh)) >= 0) { | 784 if ((result = this->allOnOneSide(rh)) >= 0) { |
789 return result; | 785 return result; |
790 } | 786 } |
791 if (fUnorderable || approximately_zero(rh->fSide)) { | 787 if (fUnorderable || approximately_zero(rh->fSide)) { |
792 goto unorderable; | 788 goto unorderable; |
793 } | 789 } |
794 } else if (!rh->fIsCurve) { | 790 } else if (!rh->fIsCurve) { |
795 if ((result = rh->allOnOneSide(this)) >= 0) { | 791 if ((result = rh->allOnOneSide(this)) >= 0) { |
796 return !result; | 792 return !result; |
797 } | 793 } |
798 if (rh->fUnorderable || approximately_zero(fSide)) { | 794 if (rh->fUnorderable || approximately_zero(fSide)) { |
799 goto unorderable; | 795 goto unorderable; |
800 } | 796 } |
801 } | 797 } else if ((result = this->convexHullOverlaps(rh)) >= 0) { |
802 if ((result = convexHullOverlaps(rh)) >= 0) { | |
803 return result; | 798 return result; |
804 } | 799 } |
805 return endsIntersect(rh); | 800 return this->endsIntersect(rh); |
806 unorderable: | 801 unorderable: |
807 fUnorderable = true; | 802 fUnorderable = true; |
808 rh->fUnorderable = true; | 803 rh->fUnorderable = true; |
809 return true; | 804 return true; |
810 } | 805 } |
811 | 806 |
812 // OPTIMIZE: if this shows up in a profile, add a previous pointer | 807 // OPTIMIZE: if this shows up in a profile, add a previous pointer |
813 // as is, this should be rarely called | 808 // as is, this should be rarely called |
814 SkOpAngle* SkOpAngle::previous() const { | 809 SkOpAngle* SkOpAngle::previous() const { |
815 SkOpAngle* last = fNext; | 810 SkOpAngle* last = fNext; |
(...skipping 23 matching lines...) Expand all Loading... |
839 | 834 |
840 void SkOpAngle::setCurveHullSweep() { | 835 void SkOpAngle::setCurveHullSweep() { |
841 fUnorderedSweep = false; | 836 fUnorderedSweep = false; |
842 fSweep[0] = fCurvePart[1] - fCurvePart[0]; | 837 fSweep[0] = fCurvePart[1] - fCurvePart[0]; |
843 const SkOpSegment* segment = fStart->segment(); | 838 const SkOpSegment* segment = fStart->segment(); |
844 if (SkPath::kLine_Verb == segment->verb()) { | 839 if (SkPath::kLine_Verb == segment->verb()) { |
845 fSweep[1] = fSweep[0]; | 840 fSweep[1] = fSweep[0]; |
846 return; | 841 return; |
847 } | 842 } |
848 fSweep[1] = fCurvePart[2] - fCurvePart[0]; | 843 fSweep[1] = fCurvePart[2] - fCurvePart[0]; |
| 844 // OPTIMIZE: I do the following float check a lot -- probably need a |
| 845 // central place for this val-is-small-compared-to-curve check |
| 846 double maxVal = 0; |
| 847 for (int index = 0; index < SkPathOpsVerbToPoints(segment->verb()); ++index)
{ |
| 848 maxVal = SkTMax(maxVal, SkTMax(SkTAbs(fCurvePart[index].fX), |
| 849 SkTAbs(fCurvePart[index].fY))); |
| 850 } |
| 851 |
849 if (SkPath::kCubic_Verb != segment->verb()) { | 852 if (SkPath::kCubic_Verb != segment->verb()) { |
850 if (!fSweep[0].fX && !fSweep[0].fY) { | 853 if (roughly_zero_when_compared_to(fSweep[0].fX, maxVal) |
| 854 && roughly_zero_when_compared_to(fSweep[0].fY, maxVal)) { |
851 fSweep[0] = fSweep[1]; | 855 fSweep[0] = fSweep[1]; |
852 } | 856 } |
853 return; | 857 return; |
854 } | 858 } |
855 SkDVector thirdSweep = fCurvePart[3] - fCurvePart[0]; | 859 SkDVector thirdSweep = fCurvePart[3] - fCurvePart[0]; |
856 if (fSweep[0].fX == 0 && fSweep[0].fY == 0) { | 860 if (fSweep[0].fX == 0 && fSweep[0].fY == 0) { |
857 fSweep[0] = fSweep[1]; | 861 fSweep[0] = fSweep[1]; |
858 fSweep[1] = thirdSweep; | 862 fSweep[1] = thirdSweep; |
859 if (fSweep[0].fX == 0 && fSweep[0].fY == 0) { | 863 if (roughly_zero_when_compared_to(fSweep[0].fX, maxVal) |
| 864 && roughly_zero_when_compared_to(fSweep[0].fY, maxVal)) { |
860 fSweep[0] = fSweep[1]; | 865 fSweep[0] = fSweep[1]; |
861 fCurvePart[1] = fCurvePart[3]; | 866 fCurvePart[1] = fCurvePart[3]; |
862 fIsCurve = false; | 867 fIsCurve = false; |
863 } | 868 } |
864 return; | 869 return; |
865 } | 870 } |
866 double s1x3 = fSweep[0].crossCheck(thirdSweep); | 871 double s1x3 = fSweep[0].crossCheck(thirdSweep); |
867 double s3x2 = thirdSweep.crossCheck(fSweep[1]); | 872 double s3x2 = thirdSweep.crossCheck(fSweep[1]); |
868 if (s1x3 * s3x2 >= 0) { // if third vector is on or between first two vecto
rs | 873 if (s1x3 * s3x2 >= 0) { // if third vector is on or between first two vecto
rs |
869 return; | 874 return; |
(...skipping 17 matching lines...) Expand all Loading... |
887 fUnorderable = true; | 892 fUnorderable = true; |
888 return; | 893 return; |
889 } | 894 } |
890 const SkOpSegment* segment = fStart->segment(); | 895 const SkOpSegment* segment = fStart->segment(); |
891 const SkPoint* pts = segment->pts(); | 896 const SkPoint* pts = segment->pts(); |
892 SkDEBUGCODE(fCurvePart.fVerb = SkPath::kCubic_Verb); | 897 SkDEBUGCODE(fCurvePart.fVerb = SkPath::kCubic_Verb); |
893 SkDEBUGCODE(fCurvePart[2].fX = fCurvePart[2].fY = fCurvePart[3].fX = fCurveP
art[3].fY | 898 SkDEBUGCODE(fCurvePart[2].fX = fCurvePart[2].fY = fCurvePart[3].fX = fCurveP
art[3].fY |
894 = SK_ScalarNaN); | 899 = SK_ScalarNaN); |
895 SkDEBUGCODE(fCurvePart.fVerb = segment->verb()); | 900 SkDEBUGCODE(fCurvePart.fVerb = segment->verb()); |
896 segment->subDivide(fStart, fEnd, &fCurvePart); | 901 segment->subDivide(fStart, fEnd, &fCurvePart); |
| 902 fOriginalCurvePart = fCurvePart; |
897 setCurveHullSweep(); | 903 setCurveHullSweep(); |
898 const SkPath::Verb verb = segment->verb(); | 904 const SkPath::Verb verb = segment->verb(); |
899 if (verb != SkPath::kLine_Verb | 905 if (verb != SkPath::kLine_Verb |
900 && !(fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0)) { | 906 && !(fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0)) { |
901 SkDLine lineHalf; | 907 SkDLine lineHalf; |
902 lineHalf[0].set(fCurvePart[0].asSkPoint()); | 908 lineHalf[0].set(fCurvePart[0].asSkPoint()); |
903 lineHalf[1].set(fCurvePart[SkPathOpsVerbToPoints(verb)].asSkPoint()); | 909 lineHalf[1].set(fCurvePart[SkPathOpsVerbToPoints(verb)].asSkPoint()); |
904 fTangentHalf.lineEndPoints(lineHalf); | 910 fTangentHalf.lineEndPoints(lineHalf); |
905 fSide = 0; | 911 fSide = 0; |
906 } | 912 } |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 double s0dt0 = sweep[0].dot(tweep[0]); | 1048 double s0dt0 = sweep[0].dot(tweep[0]); |
1043 if (!s0dt0) { | 1049 if (!s0dt0) { |
1044 return true; | 1050 return true; |
1045 } | 1051 } |
1046 SkASSERT(s0dt0 != 0); | 1052 SkASSERT(s0dt0 != 0); |
1047 double m = s0xt0 / s0dt0; | 1053 double m = s0xt0 / s0dt0; |
1048 double sDist = sweep[0].length() * m; | 1054 double sDist = sweep[0].length() * m; |
1049 double tDist = tweep[0].length() * m; | 1055 double tDist = tweep[0].length() * m; |
1050 bool useS = fabs(sDist) < fabs(tDist); | 1056 bool useS = fabs(sDist) < fabs(tDist); |
1051 double mFactor = fabs(useS ? this->distEndRatio(sDist) : rh->distEndRatio(tD
ist)); | 1057 double mFactor = fabs(useS ? this->distEndRatio(sDist) : rh->distEndRatio(tD
ist)); |
1052 return mFactor < 2400; // empirically found limit | 1058 return mFactor < 50; // empirically found limit |
1053 } | 1059 } |
OLD | NEW |