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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrPathUtils.cpp
diff --git a/src/gpu/GrPathUtils.cpp b/src/gpu/GrPathUtils.cpp
index 8e4eeb0a3141fec7c7b45f5149d53c4651de5d73..464231a8dc3656b184c837f9dacac8d7c373a17f 100644
--- a/src/gpu/GrPathUtils.cpp
+++ b/src/gpu/GrPathUtils.cpp
@@ -405,49 +405,56 @@ void convert_noninflect_cubic_to_quads(const SkPoint p[4],
dc = p[1] - p[3];
}
- // When the ab and cd tangents are nearly parallel with vector from d to a the constraint that
- // the quad point falls between the tangents becomes hard to enforce and we are likely to hit
- // the max subdivision count. However, in this case the cubic is approaching a line and the
- // accuracy of the quad point isn't so important. We check if the two middle cubic control
- // points are very close to the baseline vector. If so then we just pick quadratic points on the
- // control polygon.
+ // When the ab and cd tangents are degenerate or nearly parallel with vector from d to a the
+ // constraint that the quad point falls between the tangents becomes hard to enforce and we are
+ // likely to hit the max subdivision count. However, in this case the cubic is approaching a
+ // line and the accuracy of the quad point isn't so important. We check if the two middle cubic
+ // control points are very close to the baseline vector. If so then we just pick quadratic
+ // points on the control polygon.
if (constrainWithinTangents) {
SkVector da = p[0] - p[3];
- SkScalar invDALengthSqd = da.lengthSqd();
- if (invDALengthSqd > SK_ScalarNearlyZero) {
- invDALengthSqd = SkScalarInvert(invDALengthSqd);
- // cross(ab, da)^2/length(da)^2 == sqd distance from b to line from d to a.
- // same goed for point c using vector cd.
- SkScalar detABSqd = ab.cross(da);
- detABSqd = SkScalarSquare(detABSqd);
- SkScalar detDCSqd = dc.cross(da);
- detDCSqd = SkScalarSquare(detDCSqd);
- if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd &&
- SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) {
- SkPoint b = p[0] + ab;
- SkPoint c = p[3] + dc;
- SkPoint mid = b + c;
- mid.scale(SK_ScalarHalf);
- // Insert two quadratics to cover the case when ab points away from d and/or dc
- // points away from a.
- if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab,da) > 0) {
- SkPoint* qpts = quads->push_back_n(6);
- qpts[0] = p[0];
- qpts[1] = b;
- qpts[2] = mid;
- qpts[3] = mid;
- qpts[4] = c;
- qpts[5] = p[3];
- } else {
- SkPoint* qpts = quads->push_back_n(3);
- qpts[0] = p[0];
- qpts[1] = mid;
- qpts[2] = p[3];
+ bool doQuads = dc.lengthSqd() < SK_ScalarNearlyZero ||
+ ab.lengthSqd() < SK_ScalarNearlyZero;
+ if (!doQuads) {
+ SkScalar invDALengthSqd = da.lengthSqd();
+ if (invDALengthSqd > SK_ScalarNearlyZero) {
+ invDALengthSqd = SkScalarInvert(invDALengthSqd);
+ // cross(ab, da)^2/length(da)^2 == sqd distance from b to line from d to a.
+ // same goes for point c using vector cd.
+ SkScalar detABSqd = ab.cross(da);
+ detABSqd = SkScalarSquare(detABSqd);
+ SkScalar detDCSqd = dc.cross(da);
+ detDCSqd = SkScalarSquare(detDCSqd);
+ if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd &&
+ SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) {
+ doQuads = true;
}
- return;
}
}
+ if (doQuads) {
+ SkPoint b = p[0] + ab;
+ SkPoint c = p[3] + dc;
+ SkPoint mid = b + c;
+ mid.scale(SK_ScalarHalf);
+ // Insert two quadratics to cover the case when ab points away from d and/or dc
+ // points away from a.
+ if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab,da) > 0) {
+ SkPoint* qpts = quads->push_back_n(6);
+ qpts[0] = p[0];
+ qpts[1] = b;
+ qpts[2] = mid;
+ qpts[3] = mid;
+ qpts[4] = c;
+ qpts[5] = p[3];
+ } else {
+ SkPoint* qpts = quads->push_back_n(3);
+ qpts[0] = p[0];
+ qpts[1] = mid;
+ qpts[2] = p[3];
+ }
+ return;
+ }
}
static const SkScalar kLengthScale = 3 * SK_Scalar1 / 2;
« 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