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