Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/pathops/SkOpAngle.cpp

Issue 1037953004: add conics to path ops (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix linux build Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698