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

Side by Side Diff: src/pathops/SkDQuadLineIntersection.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 "SkIntersections.h" 7 #include "SkIntersections.h"
8 #include "SkPathOpsCurve.h"
8 #include "SkPathOpsLine.h" 9 #include "SkPathOpsLine.h"
9 #include "SkPathOpsQuad.h" 10 #include "SkPathOpsQuad.h"
10 11
11 /* 12 /*
12 Find the interection of a line and quadratic by solving for valid t values. 13 Find the interection of a line and quadratic by solving for valid t values.
13 14
14 From http://stackoverflow.com/questions/1853637/how-to-find-the-mathematical-fun ction-defining-a-bezier-curve 15 From http://stackoverflow.com/questions/1853637/how-to-find-the-mathematical-fun ction-defining-a-bezier-curve
15 16
16 "A Bezier curve is a parametric function. A quadratic Bezier curve (i.e. three 17 "A Bezier curve is a parametric function. A quadratic Bezier curve (i.e. three
17 control points) can be expressed as: F(t) = A(1 - t)^2 + B(1 - t)t + Ct^2 where 18 control points) can be expressed as: F(t) = A(1 - t)^2 + B(1 - t)t + Ct^2 where
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 enum PinTPoint { 92 enum PinTPoint {
92 kPointUninitialized, 93 kPointUninitialized,
93 kPointInitialized 94 kPointInitialized
94 }; 95 };
95 96
96 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio ns* i) 97 LineQuadraticIntersections(const SkDQuad& q, const SkDLine& l, SkIntersectio ns* i)
97 : fQuad(q) 98 : fQuad(q)
98 , fLine(&l) 99 , fLine(&l)
99 , fIntersections(i) 100 , fIntersections(i)
100 , fAllowNear(true) { 101 , fAllowNear(true) {
101 i->setMax(3); // allow short partial coincidence plus discrete intersec tion 102 i->setMax(4); // allow short partial coincidence plus discrete intersec tions
102 } 103 }
103 104
104 LineQuadraticIntersections(const SkDQuad& q) 105 LineQuadraticIntersections(const SkDQuad& q)
105 : fQuad(q) 106 : fQuad(q)
106 SkDEBUGPARAMS(fLine(nullptr)) 107 SkDEBUGPARAMS(fLine(nullptr))
107 SkDEBUGPARAMS(fIntersections(nullptr)) 108 SkDEBUGPARAMS(fIntersections(nullptr))
108 SkDEBUGPARAMS(fAllowNear(false)) { 109 SkDEBUGPARAMS(fAllowNear(false)) {
109 } 110 }
110 111
111 void allowNear(bool allow) { 112 void allowNear(bool allow) {
112 fAllowNear = allow; 113 fAllowNear = allow;
113 } 114 }
114 115
115 void checkCoincident() { 116 void checkCoincident() {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 double quadT = (double) (qIndex >> 1); 291 double quadT = (double) (qIndex >> 1);
291 if (fIntersections->hasT(quadT)) { 292 if (fIntersections->hasT(quadT)) {
292 continue; 293 continue;
293 } 294 }
294 double lineT = fLine->nearPoint(fQuad[qIndex], nullptr); 295 double lineT = fLine->nearPoint(fQuad[qIndex], nullptr);
295 if (lineT < 0) { 296 if (lineT < 0) {
296 continue; 297 continue;
297 } 298 }
298 fIntersections->insert(quadT, lineT, fQuad[qIndex]); 299 fIntersections->insert(quadT, lineT, fQuad[qIndex]);
299 } 300 }
300 // FIXME: see if line end is nearly on quad 301 addLineNearEndPoints();
302 }
303
304 void addLineNearEndPoints() {
305 for (int lIndex = 0; lIndex < 2; ++lIndex) {
306 double lineT = (double) lIndex;
307 if (fIntersections->hasOppT(lineT)) {
308 continue;
309 }
310 double quadT = ((SkDCurve*) &fQuad)->nearPoint(SkPath::kQuad_Verb,
311 (*fLine)[lIndex], (*fLine)[!lIndex]);
312 if (quadT < 0) {
313 continue;
314 }
315 fIntersections->insert(quadT, lineT, (*fLine)[lIndex]);
316 }
301 } 317 }
302 318
303 void addExactHorizontalEndPoints(double left, double right, double y) { 319 void addExactHorizontalEndPoints(double left, double right, double y) {
304 for (int qIndex = 0; qIndex < 3; qIndex += 2) { 320 for (int qIndex = 0; qIndex < 3; qIndex += 2) {
305 double lineT = SkDLine::ExactPointH(fQuad[qIndex], left, right, y); 321 double lineT = SkDLine::ExactPointH(fQuad[qIndex], left, right, y);
306 if (lineT < 0) { 322 if (lineT < 0) {
307 continue; 323 continue;
308 } 324 }
309 double quadT = (double) (qIndex >> 1); 325 double quadT = (double) (qIndex >> 1);
310 fIntersections->insert(quadT, lineT, fQuad[qIndex]); 326 fIntersections->insert(quadT, lineT, fQuad[qIndex]);
311 } 327 }
312 } 328 }
313 329
314 void addNearHorizontalEndPoints(double left, double right, double y) { 330 void addNearHorizontalEndPoints(double left, double right, double y) {
315 for (int qIndex = 0; qIndex < 3; qIndex += 2) { 331 for (int qIndex = 0; qIndex < 3; qIndex += 2) {
316 double quadT = (double) (qIndex >> 1); 332 double quadT = (double) (qIndex >> 1);
317 if (fIntersections->hasT(quadT)) { 333 if (fIntersections->hasT(quadT)) {
318 continue; 334 continue;
319 } 335 }
320 double lineT = SkDLine::NearPointH(fQuad[qIndex], left, right, y); 336 double lineT = SkDLine::NearPointH(fQuad[qIndex], left, right, y);
321 if (lineT < 0) { 337 if (lineT < 0) {
322 continue; 338 continue;
323 } 339 }
324 fIntersections->insert(quadT, lineT, fQuad[qIndex]); 340 fIntersections->insert(quadT, lineT, fQuad[qIndex]);
325 } 341 }
326 // FIXME: see if line end is nearly on quad 342 addLineNearEndPoints();
herb_g 2016/07/18 15:13:39 this->
caryclark 2016/07/18 15:55:49 Done.
327 } 343 }
328 344
329 void addExactVerticalEndPoints(double top, double bottom, double x) { 345 void addExactVerticalEndPoints(double top, double bottom, double x) {
330 for (int qIndex = 0; qIndex < 3; qIndex += 2) { 346 for (int qIndex = 0; qIndex < 3; qIndex += 2) {
331 double lineT = SkDLine::ExactPointV(fQuad[qIndex], top, bottom, x); 347 double lineT = SkDLine::ExactPointV(fQuad[qIndex], top, bottom, x);
332 if (lineT < 0) { 348 if (lineT < 0) {
333 continue; 349 continue;
334 } 350 }
335 double quadT = (double) (qIndex >> 1); 351 double quadT = (double) (qIndex >> 1);
336 fIntersections->insert(quadT, lineT, fQuad[qIndex]); 352 fIntersections->insert(quadT, lineT, fQuad[qIndex]);
337 } 353 }
338 } 354 }
339 355
340 void addNearVerticalEndPoints(double top, double bottom, double x) { 356 void addNearVerticalEndPoints(double top, double bottom, double x) {
341 for (int qIndex = 0; qIndex < 3; qIndex += 2) { 357 for (int qIndex = 0; qIndex < 3; qIndex += 2) {
342 double quadT = (double) (qIndex >> 1); 358 double quadT = (double) (qIndex >> 1);
343 if (fIntersections->hasT(quadT)) { 359 if (fIntersections->hasT(quadT)) {
344 continue; 360 continue;
345 } 361 }
346 double lineT = SkDLine::NearPointV(fQuad[qIndex], top, bottom, x); 362 double lineT = SkDLine::NearPointV(fQuad[qIndex], top, bottom, x);
347 if (lineT < 0) { 363 if (lineT < 0) {
348 continue; 364 continue;
349 } 365 }
350 fIntersections->insert(quadT, lineT, fQuad[qIndex]); 366 fIntersections->insert(quadT, lineT, fQuad[qIndex]);
351 } 367 }
352 // FIXME: see if line end is nearly on quad 368 addLineNearEndPoints();
353 } 369 }
354 370
355 double findLineT(double t) { 371 double findLineT(double t) {
356 SkDPoint xy = fQuad.ptAtT(t); 372 SkDPoint xy = fQuad.ptAtT(t);
357 double dx = (*fLine)[1].fX - (*fLine)[0].fX; 373 double dx = (*fLine)[1].fX - (*fLine)[0].fX;
358 double dy = (*fLine)[1].fY - (*fLine)[0].fY; 374 double dy = (*fLine)[1].fY - (*fLine)[0].fY;
359 if (fabs(dx) > fabs(dy)) { 375 if (fabs(dx) > fabs(dy)) {
360 return (xy.fX - (*fLine)[0].fX) / dx; 376 return (xy.fX - (*fLine)[0].fX) / dx;
361 } 377 }
362 return (xy.fY - (*fLine)[0].fY) / dy; 378 return (xy.fY - (*fLine)[0].fY) / dy;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 461
446 // SkDQuad accessors to Intersection utilities 462 // SkDQuad accessors to Intersection utilities
447 463
448 int SkDQuad::horizontalIntersect(double yIntercept, double roots[2]) const { 464 int SkDQuad::horizontalIntersect(double yIntercept, double roots[2]) const {
449 return SkIntersections::HorizontalIntercept(*this, yIntercept, roots); 465 return SkIntersections::HorizontalIntercept(*this, yIntercept, roots);
450 } 466 }
451 467
452 int SkDQuad::verticalIntersect(double xIntercept, double roots[2]) const { 468 int SkDQuad::verticalIntersect(double xIntercept, double roots[2]) const {
453 return SkIntersections::VerticalIntercept(*this, xIntercept, roots); 469 return SkIntersections::VerticalIntercept(*this, xIntercept, roots);
454 } 470 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698