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

Side by Side Diff: src/gpu/GrPathUtils.cpp

Issue 338633007: Check for degenerate edges in cubic->quad conversion called by convex path renderer. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update comment Created 6 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 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 7
8 #include "GrPathUtils.h" 8 #include "GrPathUtils.h"
9 9
10 #include "GrTypes.h" 10 #include "GrTypes.h"
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 degQuad[1] = p[0]; 398 degQuad[1] = p[0];
399 degQuad[2] = p[3]; 399 degQuad[2] = p[3];
400 return; 400 return;
401 } 401 }
402 ab = p[2] - p[0]; 402 ab = p[2] - p[0];
403 } 403 }
404 if (dc.isZero()) { 404 if (dc.isZero()) {
405 dc = p[1] - p[3]; 405 dc = p[1] - p[3];
406 } 406 }
407 407
408 // When the ab and cd tangents are nearly parallel with vector from d to a t he constraint that 408 // When the ab and cd tangents are degenerate or nearly parallel with vector from d to a the
409 // the quad point falls between the tangents becomes hard to enforce and we are likely to hit 409 // constraint that the quad point falls between the tangents becomes hard to enforce and we are
410 // the max subdivision count. However, in this case the cubic is approaching a line and the 410 // likely to hit the max subdivision count. However, in this case the cubic is approaching a
411 // accuracy of the quad point isn't so important. We check if the two middle cubic control 411 // line and the accuracy of the quad point isn't so important. We check if t he two middle cubic
412 // points are very close to the baseline vector. If so then we just pick qua dratic points on the 412 // control points are very close to the baseline vector. If so then we just pick quadratic
413 // control polygon. 413 // points on the control polygon.
414 414
415 if (constrainWithinTangents) { 415 if (constrainWithinTangents) {
416 SkVector da = p[0] - p[3]; 416 SkVector da = p[0] - p[3];
417 SkScalar invDALengthSqd = da.lengthSqd(); 417 bool doQuads = dc.lengthSqd() < SK_ScalarNearlyZero ||
418 if (invDALengthSqd > SK_ScalarNearlyZero) { 418 ab.lengthSqd() < SK_ScalarNearlyZero;
419 invDALengthSqd = SkScalarInvert(invDALengthSqd); 419 if (!doQuads) {
420 // cross(ab, da)^2/length(da)^2 == sqd distance from b to line from d to a. 420 SkScalar invDALengthSqd = da.lengthSqd();
421 // same goed for point c using vector cd. 421 if (invDALengthSqd > SK_ScalarNearlyZero) {
422 SkScalar detABSqd = ab.cross(da); 422 invDALengthSqd = SkScalarInvert(invDALengthSqd);
423 detABSqd = SkScalarSquare(detABSqd); 423 // cross(ab, da)^2/length(da)^2 == sqd distance from b to line f rom d to a.
424 SkScalar detDCSqd = dc.cross(da); 424 // same goes for point c using vector cd.
425 detDCSqd = SkScalarSquare(detDCSqd); 425 SkScalar detABSqd = ab.cross(da);
426 if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd && 426 detABSqd = SkScalarSquare(detABSqd);
427 SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) { 427 SkScalar detDCSqd = dc.cross(da);
428 SkPoint b = p[0] + ab; 428 detDCSqd = SkScalarSquare(detDCSqd);
429 SkPoint c = p[3] + dc; 429 if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd &&
430 SkPoint mid = b + c; 430 SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) {
431 mid.scale(SK_ScalarHalf); 431 doQuads = true;
432 // Insert two quadratics to cover the case when ab points away f rom d and/or dc
433 // points away from a.
434 if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab, da) > 0) {
435 SkPoint* qpts = quads->push_back_n(6);
436 qpts[0] = p[0];
437 qpts[1] = b;
438 qpts[2] = mid;
439 qpts[3] = mid;
440 qpts[4] = c;
441 qpts[5] = p[3];
442 } else {
443 SkPoint* qpts = quads->push_back_n(3);
444 qpts[0] = p[0];
445 qpts[1] = mid;
446 qpts[2] = p[3];
447 } 432 }
448 return;
449 } 433 }
450 } 434 }
435 if (doQuads) {
436 SkPoint b = p[0] + ab;
437 SkPoint c = p[3] + dc;
438 SkPoint mid = b + c;
439 mid.scale(SK_ScalarHalf);
440 // Insert two quadratics to cover the case when ab points away from d and/or dc
441 // points away from a.
442 if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab,da) > 0) {
443 SkPoint* qpts = quads->push_back_n(6);
444 qpts[0] = p[0];
445 qpts[1] = b;
446 qpts[2] = mid;
447 qpts[3] = mid;
448 qpts[4] = c;
449 qpts[5] = p[3];
450 } else {
451 SkPoint* qpts = quads->push_back_n(3);
452 qpts[0] = p[0];
453 qpts[1] = mid;
454 qpts[2] = p[3];
455 }
456 return;
457 }
451 } 458 }
452 459
453 static const SkScalar kLengthScale = 3 * SK_Scalar1 / 2; 460 static const SkScalar kLengthScale = 3 * SK_Scalar1 / 2;
454 static const int kMaxSubdivs = 10; 461 static const int kMaxSubdivs = 10;
455 462
456 ab.scale(kLengthScale); 463 ab.scale(kLengthScale);
457 dc.scale(kLengthScale); 464 dc.scale(kLengthScale);
458 465
459 // e0 and e1 are extrapolations along vectors ab and dc. 466 // e0 and e1 are extrapolations along vectors ab and dc.
460 SkVector c0 = p[0]; 467 SkVector c0 = p[0];
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 set_loop_klm(d, controlK, controlL, controlM); 866 set_loop_klm(d, controlK, controlL, controlM);
860 } else if (kCusp_CubicType == cType) { 867 } else if (kCusp_CubicType == cType) {
861 SkASSERT(0.f == d[0]); 868 SkASSERT(0.f == d[0]);
862 set_cusp_klm(d, controlK, controlL, controlM); 869 set_cusp_klm(d, controlK, controlL, controlM);
863 } else if (kQuadratic_CubicType == cType) { 870 } else if (kQuadratic_CubicType == cType) {
864 set_quadratic_klm(d, controlK, controlL, controlM); 871 set_quadratic_klm(d, controlK, controlL, controlM);
865 } 872 }
866 873
867 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]); 874 calc_cubic_klm(p, controlK, controlL, controlM, klm, &klm[3], &klm[6]);
868 } 875 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698