In convex path renderer, translate polygon to origin for fanPt computation
Review URL: http://codereview.appspot.com/5698051/
git-svn-id: http://skia.googlecode.com/svn/trunk@3241 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 1a8a389..d596284 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -60,18 +60,32 @@
SkPoint center;
center.set(0, 0);
int count = segments.count();
- for (int i = 0; i < count; ++i) {
- const SkPoint& pi = segments[i].endPt();
- int j = (i + 1) % count;
- const SkPoint& pj = segments[j].endPt();
- GrScalar t = GrMul(pi.fX, pj.fY) - GrMul(pj.fX, pi.fY);
- area += t;
- center.fX += (pi.fX + pj.fX) * t;
- center.fY += (pi.fY + pj.fY) * t;
+ SkPoint p0;
+ if (count > 2) {
+ // We translate the polygon so that the first point is at the origin.
+ // This avoids some precision issues with small area polygons far away
+ // from the origin.
+ p0 = segments[0].endPt();
+ SkPoint pi;
+ SkPoint pj;
+ // the first and last interation 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;
+ for (int i = 1; i < count - 1; ++i) {
+ pi = pj;
+ const SkPoint pj = segments[i + 1].endPt() - p0;
+
+ GrScalar t = GrMul(pi.fX, pj.fY) - GrMul(pj.fX, pi.fY);
+ area += t;
+ center.fX += (pi.fX + pj.fX) * t;
+ center.fY += (pi.fY + pj.fY) * t;
+
+ }
}
// If the poly has no area then we instead return the average of
// its points.
- if (SkScalarAbs(area) < SK_ScalarNearlyZero) {
+ if (SkScalarNearlyZero(area)) {
SkPoint avg;
avg.set(0, 0);
for (int i = 0; i < count; ++i) {
@@ -87,7 +101,8 @@
area = GrScalarDiv(GR_Scalar1, area);
center.fX = GrScalarMul(center.fX, area);
center.fY = GrScalarMul(center.fY, area);
- *c = center;
+ // undo the translate of p0 to the origin.
+ *c = center + p0;
}
GrAssert(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY));
}