diff options
Diffstat (limited to 'src/utils/SkShadowTessellator.cpp')
-rwxr-xr-x | src/utils/SkShadowTessellator.cpp | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp index 3d84e8fdad..873e6d2687 100755 --- a/src/utils/SkShadowTessellator.cpp +++ b/src/utils/SkShadowTessellator.cpp @@ -92,7 +92,6 @@ protected: SkPoint fCentroid; SkScalar fArea; SkScalar fLastArea; - int fAreaSignFlips; SkScalar fLastCross; int fFirstVertexIndex; @@ -137,18 +136,16 @@ static bool duplicate_pt(const SkPoint& p0, const SkPoint& p1) { static SkScalar perp_dot(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2) { SkVector v0 = p1 - p0; - SkVector v1 = p2 - p0; + SkVector v1 = p2 - p1; return v0.cross(v1); } - SkBaseShadowTessellator::SkBaseShadowTessellator(const SkPoint3& zPlaneParams, bool transparent) : fZPlaneParams(zPlaneParams) , fZOffset(0) , fCentroid({0, 0}) , fArea(0) , fLastArea(0) - , fAreaSignFlips(0) , fLastCross(0) , fFirstVertexIndex(-1) , fSucceeded(false) @@ -189,15 +186,20 @@ bool SkBaseShadowTessellator::accumulateCentroid(const SkPoint& curr, const SkPo return false; } - SkScalar quadArea = curr.cross(next); - fCentroid.fX += (curr.fX + next.fX) * quadArea; - fCentroid.fY += (curr.fY + next.fY) * quadArea; + SkASSERT(fPathPolygon.count() > 0); + SkVector v0 = curr - fPathPolygon[0]; + SkVector v1 = next - fPathPolygon[0]; + SkScalar quadArea = v0.cross(v1); + fCentroid.fX += (v0.fX + v1.fX) * quadArea; + fCentroid.fY += (v0.fY + v1.fY) * quadArea; fArea += quadArea; // convexity check if (quadArea*fLastArea < 0) { - ++fAreaSignFlips; + fIsConvex = false; + } + if (0 != quadArea) { + fLastArea = quadArea; } - fLastArea = quadArea; return true; } @@ -215,7 +217,9 @@ bool SkBaseShadowTessellator::checkConvexity(const SkPoint& p0, if (fLastCross*cross < 0) { fIsConvex = false; } - fLastCross = cross; + if (0 != cross) { + fLastCross = cross; + } return true; } @@ -229,6 +233,9 @@ void SkBaseShadowTessellator::finishPathPolygon() { } if (fPathPolygon.count() > 2) { + // do this before the final convexity check, so we use the correct fPathPolygon[0] + fCentroid *= sk_ieee_float_divide(1, 3 * fArea); + fCentroid += fPathPolygon[0]; if (!checkConvexity(fPathPolygon[fPathPolygon.count() - 2], fPathPolygon[fPathPolygon.count() - 1], fPathPolygon[0])) { @@ -238,14 +245,6 @@ void SkBaseShadowTessellator::finishPathPolygon() { } } - fCentroid *= sk_ieee_float_divide(1, 3 * fArea); - // It's possible to have a concave path that self-intersects but also passes the - // cross-product check (e.g., a star). In that case, the signed area will change signs more - // than twice, so we check for that here. - if (fAreaSignFlips > 2) { - fIsConvex = false; - } - // if area is positive, winding is ccw fDirection = fArea > 0 ? -1 : 1; } |