aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/convexpaths.cpp26
-rw-r--r--include/core/SkPoint.h4
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp45
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: