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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 int lineStart = fStart->t() < fEnd->t() ? 0 : 1; | 182 int lineStart = fStart->t() < fEnd->t() ? 0 : 1; |
183 line = linePts[lineStart ^ 1] - linePts[lineStart]; | 183 line = linePts[lineStart ^ 1] - linePts[lineStart]; |
184 } else { | 184 } else { |
185 SkPoint shortPts[2] = { fCurvePart[0].asSkPoint(), fCurvePart[1].asSkPoi
nt() }; | 185 SkPoint shortPts[2] = { fCurvePart[0].asSkPoint(), fCurvePart[1].asSkPoi
nt() }; |
186 line = shortPts[1] - shortPts[0]; | 186 line = shortPts[1] - shortPts[0]; |
187 } | 187 } |
188 float crosses[3]; | 188 float crosses[3]; |
189 SkPath::Verb testVerb = test->segment()->verb(); | 189 SkPath::Verb testVerb = test->segment()->verb(); |
190 int iMax = SkPathOpsVerbToPoints(testVerb); | 190 int iMax = SkPathOpsVerbToPoints(testVerb); |
191 // SkASSERT(origin == test.fCurveHalf[0]); | 191 // SkASSERT(origin == test.fCurveHalf[0]); |
192 const SkDCubic& testCurve = test->fCurvePart; | 192 const SkDCurve& testCurve = test->fCurvePart; |
193 for (int index = 1; index <= iMax; ++index) { | 193 for (int index = 1; index <= iMax; ++index) { |
194 float xy1 = (float) (line.fX * (testCurve[index].fY - origin.fY)); | 194 float xy1 = (float) (line.fX * (testCurve[index].fY - origin.fY)); |
195 float xy2 = (float) (line.fY * (testCurve[index].fX - origin.fX)); | 195 float xy2 = (float) (line.fY * (testCurve[index].fX - origin.fX)); |
196 crosses[index - 1] = AlmostEqualUlps(xy1, xy2) ? 0 : xy1 - xy2; | 196 crosses[index - 1] = AlmostEqualUlps(xy1, xy2) ? 0 : xy1 - xy2; |
197 } | 197 } |
198 if (crosses[0] * crosses[1] < 0) { | 198 if (crosses[0] * crosses[1] < 0) { |
199 return -1; | 199 return -1; |
200 } | 200 } |
201 if (SkPath::kCubic_Verb == testVerb) { | 201 if (SkPath::kCubic_Verb == testVerb) { |
202 if (crosses[0] * crosses[2] < 0 || crosses[1] * crosses[2] < 0) { | 202 if (crosses[0] * crosses[2] < 0 || crosses[1] * crosses[2] < 0) { |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 int lPts = SkPathOpsVerbToPoints(lVerb); | 438 int lPts = SkPathOpsVerbToPoints(lVerb); |
439 int rPts = SkPathOpsVerbToPoints(rVerb); | 439 int rPts = SkPathOpsVerbToPoints(rVerb); |
440 SkDLine rays[] = {{{this->fCurvePart[0], rh->fCurvePart[rPts]}}, | 440 SkDLine rays[] = {{{this->fCurvePart[0], rh->fCurvePart[rPts]}}, |
441 {{this->fCurvePart[0], this->fCurvePart[lPts]}}}; | 441 {{this->fCurvePart[0], this->fCurvePart[lPts]}}}; |
442 if (rays[0][1] == rays[1][1]) { | 442 if (rays[0][1] == rays[1][1]) { |
443 return checkParallel(rh); | 443 return checkParallel(rh); |
444 } | 444 } |
445 double smallTs[2] = {-1, -1}; | 445 double smallTs[2] = {-1, -1}; |
446 bool limited[2] = {false, false}; | 446 bool limited[2] = {false, false}; |
447 for (int index = 0; index < 2; ++index) { | 447 for (int index = 0; index < 2; ++index) { |
448 int cPts = index ? rPts : lPts; | 448 SkPath::Verb cVerb = index ? rVerb : lVerb; |
449 // if the curve is a line, then the line and the ray intersect only at t
heir crossing | 449 // if the curve is a line, then the line and the ray intersect only at t
heir crossing |
450 if (cPts == 1) { // line | 450 if (cVerb == SkPath::kLine_Verb) { |
451 continue; | 451 continue; |
452 } | 452 } |
453 const SkOpSegment& segment = index ? *rh->segment() : *this->segment(); | 453 const SkOpSegment& segment = index ? *rh->segment() : *this->segment(); |
454 SkIntersections i; | 454 SkIntersections i; |
455 (*CurveIntersectRay[cPts])(segment.pts(), rays[index], &i); | 455 (*CurveIntersectRay[cVerb])(segment.pts(), segment.weight(), rays[index]
, &i); |
456 double tStart = index ? rh->fStart->t() : this->fStart->t(); | 456 double tStart = index ? rh->fStart->t() : this->fStart->t(); |
457 double tEnd = index ? rh->fComputedEnd->t() : this->fComputedEnd->t(); | 457 double tEnd = index ? rh->fComputedEnd->t() : this->fComputedEnd->t(); |
458 bool testAscends = tStart < (index ? rh->fComputedEnd->t() : this->fComp
utedEnd->t()); | 458 bool testAscends = tStart < (index ? rh->fComputedEnd->t() : this->fComp
utedEnd->t()); |
459 double t = testAscends ? 0 : 1; | 459 double t = testAscends ? 0 : 1; |
460 for (int idx2 = 0; idx2 < i.used(); ++idx2) { | 460 for (int idx2 = 0; idx2 < i.used(); ++idx2) { |
461 double testT = i[0][idx2]; | 461 double testT = i[0][idx2]; |
462 if (!approximately_between_orderable(tStart, testT, tEnd)) { | 462 if (!approximately_between_orderable(tStart, testT, tEnd)) { |
463 continue; | 463 continue; |
464 } | 464 } |
465 if (approximately_equal_orderable(tStart, testT)) { | 465 if (approximately_equal_orderable(tStart, testT)) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 sRayLonger = rayLonger; | 502 sRayLonger = rayLonger; |
503 sCept = cept; | 503 sCept = cept; |
504 sCeptT = smallTs[index]; | 504 sCeptT = smallTs[index]; |
505 sIndex = index; | 505 sIndex = index; |
506 break; | 506 break; |
507 } | 507 } |
508 double delta = fabs(rayDist - endDist); | 508 double delta = fabs(rayDist - endDist); |
509 double minX, minY, maxX, maxY; | 509 double minX, minY, maxX, maxY; |
510 minX = minY = SK_ScalarInfinity; | 510 minX = minY = SK_ScalarInfinity; |
511 maxX = maxY = -SK_ScalarInfinity; | 511 maxX = maxY = -SK_ScalarInfinity; |
512 const SkDCubic& curve = index ? rh->fCurvePart : this->fCurvePart; | 512 const SkDCurve& curve = index ? rh->fCurvePart : this->fCurvePart; |
513 int ptCount = index ? rPts : lPts; | 513 int ptCount = index ? rPts : lPts; |
514 for (int idx2 = 0; idx2 <= ptCount; ++idx2) { | 514 for (int idx2 = 0; idx2 <= ptCount; ++idx2) { |
515 minX = SkTMin(minX, curve[idx2].fX); | 515 minX = SkTMin(minX, curve[idx2].fX); |
516 minY = SkTMin(minY, curve[idx2].fY); | 516 minY = SkTMin(minY, curve[idx2].fY); |
517 maxX = SkTMax(maxX, curve[idx2].fX); | 517 maxX = SkTMax(maxX, curve[idx2].fX); |
518 maxY = SkTMax(maxY, curve[idx2].fY); | 518 maxY = SkTMax(maxY, curve[idx2].fY); |
519 } | 519 } |
520 double maxWidth = SkTMax(maxX - minX, maxY - minY); | 520 double maxWidth = SkTMax(maxX - minX, maxY - minY); |
521 delta /= maxWidth; | 521 delta /= maxWidth; |
522 if (delta > 1e-3 && (useIntersect ^= true)) { // FIXME: move this magic
number | 522 if (delta > 1e-3 && (useIntersect ^= true)) { // FIXME: move this magic
number |
523 sRayLonger = rayLonger; | 523 sRayLonger = rayLonger; |
524 sCept = cept; | 524 sCept = cept; |
525 sCeptT = smallTs[index]; | 525 sCeptT = smallTs[index]; |
526 sIndex = index; | 526 sIndex = index; |
527 } | 527 } |
528 } | 528 } |
529 if (useIntersect) { | 529 if (useIntersect) { |
530 const SkDCubic& curve = sIndex ? rh->fCurvePart : this->fCurvePart; | 530 const SkDCurve& curve = sIndex ? rh->fCurvePart : this->fCurvePart; |
531 const SkOpSegment& segment = sIndex ? *rh->segment() : *this->segment(); | 531 const SkOpSegment& segment = sIndex ? *rh->segment() : *this->segment(); |
532 double tStart = sIndex ? rh->fStart->t() : fStart->t(); | 532 double tStart = sIndex ? rh->fStart->t() : fStart->t(); |
533 SkDVector mid = segment.dPtAtT(tStart + (sCeptT - tStart) / 2) - curve[0
]; | 533 SkDVector mid = segment.dPtAtT(tStart + (sCeptT - tStart) / 2) - curve[0
]; |
534 double septDir = mid.crossCheck(sCept); | 534 double septDir = mid.crossCheck(sCept); |
535 if (!septDir) { | 535 if (!septDir) { |
536 return checkParallel(rh); | 536 return checkParallel(rh); |
537 } | 537 } |
538 return sRayLonger ^ (sIndex == 0) ^ (septDir < 0); | 538 return sRayLonger ^ (sIndex == 0) ^ (septDir < 0); |
539 } else { | 539 } else { |
540 return checkParallel(rh); | 540 return checkParallel(rh); |
541 } | 541 } |
542 } | 542 } |
543 | 543 |
544 bool SkOpAngle::endToSide(const SkOpAngle* rh, bool* inside) const { | 544 bool SkOpAngle::endToSide(const SkOpAngle* rh, bool* inside) const { |
545 const SkOpSegment* segment = this->segment(); | 545 const SkOpSegment* segment = this->segment(); |
546 SkPath::Verb verb = segment->verb(); | 546 SkPath::Verb verb = segment->verb(); |
547 int pts = SkPathOpsVerbToPoints(verb); | |
548 SkDLine rayEnd; | 547 SkDLine rayEnd; |
549 rayEnd[0].set(this->fEnd->pt()); | 548 rayEnd[0].set(this->fEnd->pt()); |
550 rayEnd[1] = rayEnd[0]; | 549 rayEnd[1] = rayEnd[0]; |
551 SkDVector slopeAtEnd = (*CurveDSlopeAtT[pts])(segment->pts(), this->fEnd->t(
)); | 550 SkDVector slopeAtEnd = (*CurveDSlopeAtT[verb])(segment->pts(), segment->weig
ht(), |
| 551 this->fEnd->t()); |
552 rayEnd[1].fX += slopeAtEnd.fY; | 552 rayEnd[1].fX += slopeAtEnd.fY; |
553 rayEnd[1].fY -= slopeAtEnd.fX; | 553 rayEnd[1].fY -= slopeAtEnd.fX; |
554 SkIntersections iEnd; | 554 SkIntersections iEnd; |
555 const SkOpSegment* oppSegment = rh->segment(); | 555 const SkOpSegment* oppSegment = rh->segment(); |
556 SkPath::Verb oppVerb = oppSegment->verb(); | 556 SkPath::Verb oppVerb = oppSegment->verb(); |
557 int oppPts = SkPathOpsVerbToPoints(oppVerb); | 557 (*CurveIntersectRay[oppVerb])(oppSegment->pts(), oppSegment->weight(), rayEn
d, &iEnd); |
558 (*CurveIntersectRay[oppPts])(oppSegment->pts(), rayEnd, &iEnd); | |
559 double endDist; | 558 double endDist; |
560 int closestEnd = iEnd.closestTo(rh->fStart->t(), rh->fEnd->t(), rayEnd[0], &
endDist); | 559 int closestEnd = iEnd.closestTo(rh->fStart->t(), rh->fEnd->t(), rayEnd[0], &
endDist); |
561 if (closestEnd < 0) { | 560 if (closestEnd < 0) { |
562 return false; | 561 return false; |
563 } | 562 } |
564 if (!endDist) { | 563 if (!endDist) { |
565 return false; | 564 return false; |
566 } | 565 } |
567 SkDPoint start; | 566 SkDPoint start; |
568 start.set(this->fStart->pt()); | 567 start.set(this->fStart->pt()); |
569 // OPTIMIZATION: multiple times in the code we find the max scalar | 568 // OPTIMIZATION: multiple times in the code we find the max scalar |
570 double minX, minY, maxX, maxY; | 569 double minX, minY, maxX, maxY; |
571 minX = minY = SK_ScalarInfinity; | 570 minX = minY = SK_ScalarInfinity; |
572 maxX = maxY = -SK_ScalarInfinity; | 571 maxX = maxY = -SK_ScalarInfinity; |
573 const SkDCubic& curve = rh->fCurvePart; | 572 const SkDCurve& curve = rh->fCurvePart; |
| 573 int oppPts = SkPathOpsVerbToPoints(oppVerb); |
574 for (int idx2 = 0; idx2 <= oppPts; ++idx2) { | 574 for (int idx2 = 0; idx2 <= oppPts; ++idx2) { |
575 minX = SkTMin(minX, curve[idx2].fX); | 575 minX = SkTMin(minX, curve[idx2].fX); |
576 minY = SkTMin(minY, curve[idx2].fY); | 576 minY = SkTMin(minY, curve[idx2].fY); |
577 maxX = SkTMax(maxX, curve[idx2].fX); | 577 maxX = SkTMax(maxX, curve[idx2].fX); |
578 maxY = SkTMax(maxY, curve[idx2].fY); | 578 maxY = SkTMax(maxY, curve[idx2].fY); |
579 } | 579 } |
580 double maxWidth = SkTMax(maxX - minX, maxY - minY); | 580 double maxWidth = SkTMax(maxX - minX, maxY - minY); |
581 endDist /= maxWidth; | 581 endDist /= maxWidth; |
582 if (endDist < 5e-11) { // empirically found | 582 if (endDist < 5e-11) { // empirically found |
583 return false; | 583 return false; |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
850 return true; | 850 return true; |
851 } | 851 } |
852 | 852 |
853 double SkOpAngle::midT() const { | 853 double SkOpAngle::midT() const { |
854 return (fStart->t() + fEnd->t()) / 2; | 854 return (fStart->t() + fEnd->t()) / 2; |
855 } | 855 } |
856 | 856 |
857 bool SkOpAngle::midToSide(const SkOpAngle* rh, bool* inside) const { | 857 bool SkOpAngle::midToSide(const SkOpAngle* rh, bool* inside) const { |
858 const SkOpSegment* segment = this->segment(); | 858 const SkOpSegment* segment = this->segment(); |
859 SkPath::Verb verb = segment->verb(); | 859 SkPath::Verb verb = segment->verb(); |
860 int pts = SkPathOpsVerbToPoints(verb); | |
861 const SkPoint& startPt = this->fStart->pt(); | 860 const SkPoint& startPt = this->fStart->pt(); |
862 const SkPoint& endPt = this->fEnd->pt(); | 861 const SkPoint& endPt = this->fEnd->pt(); |
863 SkDPoint dStartPt; | 862 SkDPoint dStartPt; |
864 dStartPt.set(startPt); | 863 dStartPt.set(startPt); |
865 SkDLine rayMid; | 864 SkDLine rayMid; |
866 rayMid[0].fX = (startPt.fX + endPt.fX) / 2; | 865 rayMid[0].fX = (startPt.fX + endPt.fX) / 2; |
867 rayMid[0].fY = (startPt.fY + endPt.fY) / 2; | 866 rayMid[0].fY = (startPt.fY + endPt.fY) / 2; |
868 rayMid[1].fX = rayMid[0].fX + (endPt.fY - startPt.fY); | 867 rayMid[1].fX = rayMid[0].fX + (endPt.fY - startPt.fY); |
869 rayMid[1].fY = rayMid[0].fY - (endPt.fX - startPt.fX); | 868 rayMid[1].fY = rayMid[0].fY - (endPt.fX - startPt.fX); |
870 SkIntersections iMid; | 869 SkIntersections iMid; |
871 (*CurveIntersectRay[pts])(segment->pts(), rayMid, &iMid); | 870 (*CurveIntersectRay[verb])(segment->pts(), segment->weight(), rayMid, &iMid)
; |
872 int iOutside = iMid.mostOutside(this->fStart->t(), this->fEnd->t(), dStartPt
); | 871 int iOutside = iMid.mostOutside(this->fStart->t(), this->fEnd->t(), dStartPt
); |
873 if (iOutside < 0) { | 872 if (iOutside < 0) { |
874 return false; | 873 return false; |
875 } | 874 } |
876 const SkOpSegment* oppSegment = rh->segment(); | 875 const SkOpSegment* oppSegment = rh->segment(); |
877 SkPath::Verb oppVerb = oppSegment->verb(); | 876 SkPath::Verb oppVerb = oppSegment->verb(); |
878 int oppPts = SkPathOpsVerbToPoints(oppVerb); | |
879 SkIntersections oppMid; | 877 SkIntersections oppMid; |
880 (*CurveIntersectRay[oppPts])(oppSegment->pts(), rayMid, &oppMid); | 878 (*CurveIntersectRay[oppVerb])(oppSegment->pts(), oppSegment->weight(), rayMi
d, &oppMid); |
881 int oppOutside = oppMid.mostOutside(rh->fStart->t(), rh->fEnd->t(), dStartPt
); | 879 int oppOutside = oppMid.mostOutside(rh->fStart->t(), rh->fEnd->t(), dStartPt
); |
882 if (oppOutside < 0) { | 880 if (oppOutside < 0) { |
883 return false; | 881 return false; |
884 } | 882 } |
885 SkDVector iSide = iMid.pt(iOutside) - dStartPt; | 883 SkDVector iSide = iMid.pt(iOutside) - dStartPt; |
886 SkDVector oppSide = oppMid.pt(oppOutside) - dStartPt; | 884 SkDVector oppSide = oppMid.pt(oppOutside) - dStartPt; |
887 double dir = iSide.crossCheck(oppSide); | 885 double dir = iSide.crossCheck(oppSide); |
888 if (!dir) { | 886 if (!dir) { |
889 return false; | 887 return false; |
890 } | 888 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
959 | 957 |
960 void SkOpAngle::set(SkOpSpanBase* start, SkOpSpanBase* end) { | 958 void SkOpAngle::set(SkOpSpanBase* start, SkOpSpanBase* end) { |
961 fStart = start; | 959 fStart = start; |
962 fComputedEnd = fEnd = end; | 960 fComputedEnd = fEnd = end; |
963 SkASSERT(start != end); | 961 SkASSERT(start != end); |
964 fNext = NULL; | 962 fNext = NULL; |
965 fComputeSector = fComputedSector = fCheckCoincidence = false; | 963 fComputeSector = fComputedSector = fCheckCoincidence = false; |
966 fStop = false; | 964 fStop = false; |
967 setSpans(); | 965 setSpans(); |
968 setSector(); | 966 setSector(); |
969 PATH_OPS_DEBUG_CODE(fID = start->globalState()->nextAngleID()); | 967 SkDEBUGCODE(fID = start->globalState()->nextAngleID()); |
970 } | 968 } |
971 | 969 |
972 void SkOpAngle::setCurveHullSweep() { | 970 void SkOpAngle::setCurveHullSweep() { |
973 fUnorderedSweep = false; | 971 fUnorderedSweep = false; |
974 fSweep[0] = fCurvePart[1] - fCurvePart[0]; | 972 fSweep[0] = fCurvePart[1] - fCurvePart[0]; |
975 const SkOpSegment* segment = fStart->segment(); | 973 const SkOpSegment* segment = fStart->segment(); |
976 if (SkPath::kLine_Verb == segment->verb()) { | 974 if (SkPath::kLine_Verb == segment->verb()) { |
977 fSweep[1] = fSweep[0]; | 975 fSweep[1] = fSweep[0]; |
978 return; | 976 return; |
979 } | 977 } |
(...skipping 30 matching lines...) Expand all Loading... |
1010 fUnorderedSweep = true; | 1008 fUnorderedSweep = true; |
1011 } | 1009 } |
1012 fSweep[1] = thirdSweep; | 1010 fSweep[1] = thirdSweep; |
1013 } | 1011 } |
1014 | 1012 |
1015 void SkOpAngle::setSpans() { | 1013 void SkOpAngle::setSpans() { |
1016 fUnorderable = false; | 1014 fUnorderable = false; |
1017 fLastMarked = NULL; | 1015 fLastMarked = NULL; |
1018 const SkOpSegment* segment = fStart->segment(); | 1016 const SkOpSegment* segment = fStart->segment(); |
1019 const SkPoint* pts = segment->pts(); | 1017 const SkPoint* pts = segment->pts(); |
| 1018 SkDEBUGCODE(fCurvePart.fVerb = SkPath::kCubic_Verb); |
1020 SkDEBUGCODE(fCurvePart[2].fX = fCurvePart[2].fY = fCurvePart[3].fX = fCurveP
art[3].fY | 1019 SkDEBUGCODE(fCurvePart[2].fX = fCurvePart[2].fY = fCurvePart[3].fX = fCurveP
art[3].fY |
1021 = SK_ScalarNaN); | 1020 = SK_ScalarNaN); |
| 1021 SkDEBUGCODE(fCurvePart.fVerb = segment->verb()); |
1022 segment->subDivide(fStart, fEnd, &fCurvePart); | 1022 segment->subDivide(fStart, fEnd, &fCurvePart); |
1023 setCurveHullSweep(); | 1023 setCurveHullSweep(); |
1024 const SkPath::Verb verb = segment->verb(); | 1024 const SkPath::Verb verb = segment->verb(); |
1025 if (verb != SkPath::kLine_Verb | 1025 if (verb != SkPath::kLine_Verb |
1026 && !(fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0)) { | 1026 && !(fIsCurve = fSweep[0].crossCheck(fSweep[1]) != 0)) { |
1027 SkDLine lineHalf; | 1027 SkDLine lineHalf; |
1028 lineHalf[0].set(fCurvePart[0].asSkPoint()); | 1028 lineHalf[0].set(fCurvePart[0].asSkPoint()); |
1029 lineHalf[1].set(fCurvePart[SkPathOpsVerbToPoints(verb)].asSkPoint()); | 1029 lineHalf[1].set(fCurvePart[SkPathOpsVerbToPoints(verb)].asSkPoint()); |
1030 fTangentHalf.lineEndPoints(lineHalf); | 1030 fTangentHalf.lineEndPoints(lineHalf); |
1031 fSide = 0; | 1031 fSide = 0; |
1032 } | 1032 } |
1033 switch (verb) { | 1033 switch (verb) { |
1034 case SkPath::kLine_Verb: { | 1034 case SkPath::kLine_Verb: { |
1035 SkASSERT(fStart != fEnd); | 1035 SkASSERT(fStart != fEnd); |
1036 const SkPoint& cP1 = pts[fStart->t() < fEnd->t()]; | 1036 const SkPoint& cP1 = pts[fStart->t() < fEnd->t()]; |
1037 SkDLine lineHalf; | 1037 SkDLine lineHalf; |
1038 lineHalf[0].set(fStart->pt()); | 1038 lineHalf[0].set(fStart->pt()); |
1039 lineHalf[1].set(cP1); | 1039 lineHalf[1].set(cP1); |
1040 fTangentHalf.lineEndPoints(lineHalf); | 1040 fTangentHalf.lineEndPoints(lineHalf); |
1041 fSide = 0; | 1041 fSide = 0; |
1042 fIsCurve = false; | 1042 fIsCurve = false; |
1043 } return; | 1043 } return; |
1044 case SkPath::kQuad_Verb: { | 1044 case SkPath::kQuad_Verb: |
| 1045 case SkPath::kConic_Verb: { |
1045 SkLineParameters tangentPart; | 1046 SkLineParameters tangentPart; |
1046 SkDQuad& quad2 = *SkTCast<SkDQuad*>(&fCurvePart); | 1047 (void) tangentPart.quadEndPoints(fCurvePart.fQuad); |
1047 (void) tangentPart.quadEndPoints(quad2); | |
1048 fSide = -tangentPart.pointDistance(fCurvePart[2]); // not normalized --
compare sign only | 1048 fSide = -tangentPart.pointDistance(fCurvePart[2]); // not normalized --
compare sign only |
1049 } break; | 1049 } break; |
1050 case SkPath::kCubic_Verb: { | 1050 case SkPath::kCubic_Verb: { |
1051 SkLineParameters tangentPart; | 1051 SkLineParameters tangentPart; |
1052 (void) tangentPart.cubicPart(fCurvePart); | 1052 (void) tangentPart.cubicPart(fCurvePart.fCubic); |
1053 fSide = -tangentPart.pointDistance(fCurvePart[3]); | 1053 fSide = -tangentPart.pointDistance(fCurvePart[3]); |
1054 double testTs[4]; | 1054 double testTs[4]; |
1055 // OPTIMIZATION: keep inflections precomputed with cubic segment? | 1055 // OPTIMIZATION: keep inflections precomputed with cubic segment? |
1056 int testCount = SkDCubic::FindInflections(pts, testTs); | 1056 int testCount = SkDCubic::FindInflections(pts, testTs); |
1057 double startT = fStart->t(); | 1057 double startT = fStart->t(); |
1058 double endT = fEnd->t(); | 1058 double endT = fEnd->t(); |
1059 double limitT = endT; | 1059 double limitT = endT; |
1060 int index; | 1060 int index; |
1061 for (index = 0; index < testCount; ++index) { | 1061 for (index = 0; index < testCount; ++index) { |
1062 if (!::between(startT, testTs[index], limitT)) { | 1062 if (!::between(startT, testTs[index], limitT)) { |
(...skipping 10 matching lines...) Expand all Loading... |
1073 ++index; | 1073 ++index; |
1074 } | 1074 } |
1075 index <<= 1; | 1075 index <<= 1; |
1076 for (; index < testCases; ++index) { | 1076 for (; index < testCases; ++index) { |
1077 int testIndex = index >> 1; | 1077 int testIndex = index >> 1; |
1078 double testT = testTs[testIndex]; | 1078 double testT = testTs[testIndex]; |
1079 if (index & 1) { | 1079 if (index & 1) { |
1080 testT = (testT + testTs[testIndex + 1]) / 2; | 1080 testT = (testT + testTs[testIndex + 1]) / 2; |
1081 } | 1081 } |
1082 // OPTIMIZE: could avoid call for t == startT, endT | 1082 // OPTIMIZE: could avoid call for t == startT, endT |
1083 SkDPoint pt = dcubic_xy_at_t(pts, testT); | 1083 SkDPoint pt = dcubic_xy_at_t(pts, segment->weight(), testT); |
1084 SkLineParameters tangentPart; | 1084 SkLineParameters tangentPart; |
1085 tangentPart.cubicEndPoints(fCurvePart); | 1085 tangentPart.cubicEndPoints(fCurvePart.fCubic); |
1086 double testSide = tangentPart.pointDistance(pt); | 1086 double testSide = tangentPart.pointDistance(pt); |
1087 if (fabs(bestSide) < fabs(testSide)) { | 1087 if (fabs(bestSide) < fabs(testSide)) { |
1088 bestSide = testSide; | 1088 bestSide = testSide; |
1089 } | 1089 } |
1090 } | 1090 } |
1091 fSide = -bestSide; // compare sign only | 1091 fSide = -bestSide; // compare sign only |
1092 } break; | 1092 } break; |
1093 default: | 1093 default: |
1094 SkASSERT(0); | 1094 SkASSERT(0); |
1095 } | 1095 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 return true; | 1171 return true; |
1172 } | 1172 } |
1173 SkASSERT(s0dt0 != 0); | 1173 SkASSERT(s0dt0 != 0); |
1174 double m = s0xt0 / s0dt0; | 1174 double m = s0xt0 / s0dt0; |
1175 double sDist = sweep[0].length() * m; | 1175 double sDist = sweep[0].length() * m; |
1176 double tDist = tweep[0].length() * m; | 1176 double tDist = tweep[0].length() * m; |
1177 bool useS = fabs(sDist) < fabs(tDist); | 1177 bool useS = fabs(sDist) < fabs(tDist); |
1178 double mFactor = fabs(useS ? this->distEndRatio(sDist) : rh->distEndRatio(tD
ist)); | 1178 double mFactor = fabs(useS ? this->distEndRatio(sDist) : rh->distEndRatio(tD
ist)); |
1179 return mFactor < 5000; // empirically found limit | 1179 return mFactor < 5000; // empirically found limit |
1180 } | 1180 } |
OLD | NEW |