diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-02-23 19:18:37 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-02-23 19:18:37 +0000 |
commit | 5b56d9e43fee4393f25f41d400981ce3960cd1aa (patch) | |
tree | cdbed69db73ae382a4fd748141041c7abb5880a4 | |
parent | 8796ee60b79307629c56bf9f3e146833b312b957 (diff) |
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
-rw-r--r-- | gm/convexpaths.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 35 |
2 files changed, 29 insertions, 10 deletions
diff --git a/gm/convexpaths.cpp b/gm/convexpaths.cpp index 9aedcbc4fc..2c719e826d 100644 --- a/gm/convexpaths.cpp +++ b/gm/convexpaths.cpp @@ -162,6 +162,10 @@ protected: fPaths.push_back().cubicTo(0, 0, 0, 0, 100 * SK_Scalar1, 100 * SK_Scalar1); + + // small circle. This is listed last so that it has device coords far + // from the origin (small area relative to x,y values). + fPaths.push_back().addCircle(0, 0, SkFloatToScalar(0.8f)); } virtual void onDraw(SkCanvas* canvas) { diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 1a8a38904c..d5962849f0 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -60,18 +60,32 @@ void center_of_mass(const SegmentArray& segments, SkPoint* c) { 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 @@ void center_of_mass(const SegmentArray& segments, SkPoint* c) { 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)); } |