diff options
-rw-r--r-- | gm/convexpaths.cpp | 26 | ||||
-rw-r--r-- | include/core/SkPoint.h | 4 | ||||
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 45 |
3 files changed, 62 insertions, 13 deletions
diff --git a/gm/convexpaths.cpp b/gm/convexpaths.cpp index d4f2e7f6b7..9aedcbc4fc 100644 --- a/gm/convexpaths.cpp +++ b/gm/convexpaths.cpp @@ -29,6 +29,32 @@ protected: } void makePaths() { + // CW + fPaths.push_back().moveTo(0, 0); + fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1, + 0, 100 * SK_Scalar1); + fPaths.back().lineTo(0, 0); + + // CCW + fPaths.push_back().moveTo(0, 0); + fPaths.back().lineTo(0, 100 * SK_Scalar1); + fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1, + 0, 0); + + // CW + fPaths.push_back().moveTo(0, 50 * SK_Scalar1); + fPaths.back().quadTo(50 * SK_Scalar1, 0, + 100 * SK_Scalar1, 50 * SK_Scalar1); + fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1, + 0, 50 * SK_Scalar1); + + // CCW + fPaths.push_back().moveTo(0, 50 * SK_Scalar1); + fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1, + 100 * SK_Scalar1, 50 * SK_Scalar1); + fPaths.back().quadTo(50 * SK_Scalar1, 0, + 0, 50 * SK_Scalar1); + fPaths.push_back().addRect(0, 0, 100 * SK_Scalar1, 100 * SK_Scalar1, SkPath::kCW_Direction); diff --git a/include/core/SkPoint.h b/include/core/SkPoint.h index de7c0ef47e..d371e648bb 100644 --- a/include/core/SkPoint.h +++ b/include/core/SkPoint.h @@ -442,11 +442,11 @@ struct SK_API SkPoint { void setOrthog(const SkPoint& vec, Side side = kLeft_Side) { // vec could be this SkScalar tmp = vec.fX; - if (kLeft_Side == side) { + if (kRight_Side == side) { fX = -vec.fY; fY = tmp; } else { - SkASSERT(kRight_Side == side); + SkASSERT(kLeft_Side == side); fX = vec.fY; fY = -tmp; } diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index e1dbb63380..1a8a38904c 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -69,25 +69,44 @@ void center_of_mass(const SegmentArray& segments, SkPoint* c) { center.fX += (pi.fX + pj.fX) * t; center.fY += (pi.fY + pj.fY) * t; } - area *= 3; - area = GrScalarDiv(GR_Scalar1, area); - center.fX = GrScalarMul(center.fX, area); - center.fY = GrScalarMul(center.fY, area); - *c = center; + // If the poly has no area then we instead return the average of + // its points. + if (SkScalarAbs(area) < SK_ScalarNearlyZero) { + SkPoint avg; + avg.set(0, 0); + for (int i = 0; i < count; ++i) { + const SkPoint& pt = segments[i].endPt(); + avg.fX += pt.fX; + avg.fY += pt.fY; + } + SkScalar denom = SK_Scalar1 / count; + avg.scale(denom); + *c = avg; + } else { + area *= 3; + area = GrScalarDiv(GR_Scalar1, area); + center.fX = GrScalarMul(center.fX, area); + center.fY = GrScalarMul(center.fY, area); + *c = center; + } + GrAssert(!SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY)); } void compute_vectors(SegmentArray* segments, - SkPoint* fanPt, + SkPoint* fanPt, + SkPath::Direction dir, int* vCount, int* iCount) { center_of_mass(*segments, fanPt); int count = segments->count(); - // figure out which way the normals should point + // Make the normals point towards the outside GrPoint::Side normSide; - fanPt->distanceToLineBetweenSqd((*segments)[0].endPt(), - (*segments)[1].endPt(), - &normSide); + if (dir == SkPath::kCCW_Direction) { + normSide = GrPoint::kRight_Side; + } else { + normSide = GrPoint::kLeft_Side; + } *vCount = 0; *iCount = 0; @@ -227,7 +246,11 @@ bool get_segments(const GrPath& path, if (degenerateData.isDegenerate()) { return false; } else { - compute_vectors(segments, fanPt, vCount, iCount); + SkPath::Direction dir; + GR_DEBUGCODE(bool succeeded = ) + path.cheapComputeDirection(&dir); + GrAssert(succeeded); + compute_vectors(segments, fanPt, dir, vCount, iCount); return true; } default: |