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

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

Issue 2128633003: pathops coincidence and security rewrite (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: require resulting t to be between 0 and 1 Created 4 years, 5 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698