Preserve convex control point polygon in cubic->quadratic approximation
GM test modified, will require rebaselining.
Review URL: http://codereview.appspot.com/6355088/
git-svn-id: http://skia.googlecode.com/svn/trunk@4518 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index ae4a773..41ab242 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -63,7 +63,7 @@
p0 = segments[0].endPt();
SkPoint pi;
SkPoint pj;
- // the first and last interation of the below loop would compute
+ // the first and last iteration of the below loop would compute
// zeros since the starting / ending point is (0,0). So instead we start
// at i=1 and make the last iteration i=count-2.
pj = segments[1].endPt() - p0;
@@ -200,24 +200,20 @@
}
}
-inline SkPath::Direction get_direction(const SkPath& path, const GrMatrix& m) {
- SkPath::Direction dir;
- GR_DEBUGCODE(bool succeeded = )
- path.cheapComputeDirection(&dir);
- GrAssert(succeeded);
+inline bool get_direction(const SkPath& path, const GrMatrix& m, SkPath::Direction* dir) {
+ if (!path.cheapComputeDirection(dir)) {
+ return false;
+ }
// check whether m reverses the orientation
GrAssert(!m.hasPerspective());
- GrScalar det2x2 =
- GrMul(m.get(SkMatrix::kMScaleX), m.get(SkMatrix::kMScaleY)) -
- GrMul(m.get(SkMatrix::kMSkewX), m.get(SkMatrix::kMSkewY));
+ GrScalar det2x2 = GrMul(m.get(SkMatrix::kMScaleX), m.get(SkMatrix::kMScaleY)) -
+ GrMul(m.get(SkMatrix::kMSkewX), m.get(SkMatrix::kMSkewY));
if (det2x2 < 0) {
- GR_STATIC_ASSERT(0 == SkPath::kCW_Direction ||
- 1 == SkPath::kCW_Direction);
- GR_STATIC_ASSERT(0 == SkPath::kCCW_Direction ||
- 1 == SkPath::kCCW_Direction);
- dir = static_cast<SkPath::Direction>(dir ^ 0x1);
+ GR_STATIC_ASSERT(0 == SkPath::kCW_Direction || 1 == SkPath::kCW_Direction);
+ GR_STATIC_ASSERT(0 == SkPath::kCCW_Direction || 1 == SkPath::kCCW_Direction);
+ *dir = static_cast<SkPath::Direction>(*dir ^ 0x1);
}
- return dir;
+ return true;
}
bool get_segments(const SkPath& path,
@@ -235,6 +231,11 @@
// line paths. We detect paths that are very close to a line (zero area) and
// draw nothing.
DegenerateTestData degenerateData;
+ SkPath::Direction dir;
+ // get_direction can fail for some degenerate paths.
+ if (!get_direction(path, m, &dir)) {
+ return false;
+ }
for (;;) {
GrPoint pts[4];
@@ -269,7 +270,7 @@
// unlike quads and lines, the pts[0] will also be read (in
// convertCubicToQuads).
SkSTArray<15, SkPoint, true> quads;
- GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, &quads);
+ GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads);
int count = quads.count();
for (int q = 0; q < count; q += 3) {
segments->push_back();
@@ -283,7 +284,6 @@
if (degenerateData.isDegenerate()) {
return false;
} else {
- SkPath::Direction dir = get_direction(path, m);
compute_vectors(segments, fanPt, dir, vCount, iCount);
return true;
}