| Index: src/core/SkPath.cpp
|
| ===================================================================
|
| --- src/core/SkPath.cpp (revision 11858)
|
| +++ src/core/SkPath.cpp (working copy)
|
| @@ -17,8 +17,6 @@
|
|
|
| SK_DEFINE_INST_COUNT(SkPath);
|
|
|
| -#define SK_IGNORE_QUAD_RR_CORNERS_OPT 1
|
| -
|
| // This value is just made-up for now. When count is 4, calling memset was much
|
| // slower than just writing the loop. This seems odd, and hopefully in the
|
| // future this we appear to have been a fluke...
|
| @@ -966,8 +964,7 @@
|
|
|
| static void add_corner_arc(SkPath* path, const SkRect& rect,
|
| SkScalar rx, SkScalar ry, int startAngle,
|
| - SkPath::Direction dir, bool addArcTo,
|
| - bool forceMoveTo = false) {
|
| + SkPath::Direction dir, bool forceMoveTo) {
|
| // These two asserts are not sufficient, since really we want to know
|
| // that the pair of radii (e.g. left and right, or top and bottom) sum
|
| // to <= dimension, but we don't have that data here, so we just have
|
| @@ -997,15 +994,7 @@
|
| sweep = -sweep;
|
| }
|
|
|
| - if (addArcTo) {
|
| - path->arcTo(r, start, sweep, forceMoveTo);
|
| - } else {
|
| - SkPoint pts[kSkBuildQuadArcStorage];
|
| - int count = build_arc_points(r, start, sweep, pts);
|
| - for (int i = 1; i < count; i += 2) {
|
| - path->quadTo(pts[i], pts[i+1]);
|
| - }
|
| - }
|
| + path->arcTo(r, start, sweep, forceMoveTo);
|
| }
|
|
|
| void SkPath::addRoundRect(const SkRect& rect, const SkScalar radii[],
|
| @@ -1035,15 +1024,15 @@
|
| SkAutoPathBoundsUpdate apbu(this, bounds);
|
|
|
| if (kCW_Direction == dir) {
|
| - add_corner_arc(this, bounds, rrect.fRadii[0].fX, rrect.fRadii[0].fY, 180, dir, true, true);
|
| - add_corner_arc(this, bounds, rrect.fRadii[1].fX, rrect.fRadii[1].fY, 270, dir, true);
|
| - add_corner_arc(this, bounds, rrect.fRadii[2].fX, rrect.fRadii[2].fY, 0, dir, true);
|
| - add_corner_arc(this, bounds, rrect.fRadii[3].fX, rrect.fRadii[3].fY, 90, dir, true);
|
| + add_corner_arc(this, bounds, rrect.fRadii[0].fX, rrect.fRadii[0].fY, 180, dir, true);
|
| + add_corner_arc(this, bounds, rrect.fRadii[1].fX, rrect.fRadii[1].fY, 270, dir, false);
|
| + add_corner_arc(this, bounds, rrect.fRadii[2].fX, rrect.fRadii[2].fY, 0, dir, false);
|
| + add_corner_arc(this, bounds, rrect.fRadii[3].fX, rrect.fRadii[3].fY, 90, dir, false);
|
| } else {
|
| - add_corner_arc(this, bounds, rrect.fRadii[0].fX, rrect.fRadii[0].fY, 180, dir, true, true);
|
| - add_corner_arc(this, bounds, rrect.fRadii[3].fX, rrect.fRadii[3].fY, 90, dir, true);
|
| - add_corner_arc(this, bounds, rrect.fRadii[2].fX, rrect.fRadii[2].fY, 0, dir, true);
|
| - add_corner_arc(this, bounds, rrect.fRadii[1].fX, rrect.fRadii[1].fY, 270, dir, true);
|
| + add_corner_arc(this, bounds, rrect.fRadii[0].fX, rrect.fRadii[0].fY, 180, dir, true);
|
| + add_corner_arc(this, bounds, rrect.fRadii[3].fX, rrect.fRadii[3].fY, 90, dir, false);
|
| + add_corner_arc(this, bounds, rrect.fRadii[2].fX, rrect.fRadii[2].fY, 0, dir, false);
|
| + add_corner_arc(this, bounds, rrect.fRadii[1].fX, rrect.fRadii[1].fY, 270, dir, false);
|
| }
|
| this->close();
|
| }
|
| @@ -1113,9 +1102,20 @@
|
|
|
| this->incReserve(17);
|
| #else
|
| - this->incReserve(13);
|
| + // Please see SkBuildQuadArc for more information but, we need to pull
|
| + // the off-curve quadratic points in a little bit to make the round
|
| + // rects convex.
|
| + static const SkScalar kOffCurveEpsilon = 0.0001f;
|
| +
|
| + SkScalar midPtX = rx * SK_ScalarRoot2Over2;
|
| + SkScalar midPtY = ry * SK_ScalarRoot2Over2;
|
| +
|
| + SkScalar offPtX = rx * SK_ScalarTanPIOver8 - kOffCurveEpsilon;
|
| + SkScalar offPtY = ry * SK_ScalarTanPIOver8 - kOffCurveEpsilon;
|
| +
|
| + this->incReserve(21);
|
| #endif
|
| - this->moveTo(rect.fRight - rx, rect.fTop);
|
| + this->moveTo(rect.fRight - rx, rect.fTop); // top-right
|
| if (dir == kCCW_Direction) {
|
| if (!skip_hori) {
|
| this->lineTo(rect.fLeft + rx, rect.fTop); // top
|
| @@ -1125,7 +1125,10 @@
|
| rect.fLeft, rect.fTop + ry - sy,
|
| rect.fLeft, rect.fTop + ry); // top-left
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 180, dir, false); // top-left
|
| + this->quadTo(rect.fLeft + rx - offPtX, rect.fTop + kOffCurveEpsilon,
|
| + rect.fLeft + rx - midPtX, rect.fTop + ry - midPtY);
|
| + this->quadTo(rect.fLeft + kOffCurveEpsilon, rect.fTop + ry - offPtY,
|
| + rect.fLeft, rect.fTop + ry);
|
| #endif
|
| if (!skip_vert) {
|
| this->lineTo(rect.fLeft, rect.fBottom - ry); // left
|
| @@ -1135,7 +1138,10 @@
|
| rect.fLeft + rx - sx, rect.fBottom,
|
| rect.fLeft + rx, rect.fBottom); // bot-left
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 90, dir, false); // bot-left
|
| + this->quadTo(rect.fLeft + kOffCurveEpsilon, rect.fBottom - ry + offPtY,
|
| + rect.fLeft + rx - midPtX, rect.fBottom - ry + midPtY);
|
| + this->quadTo(rect.fLeft + rx - offPtX, rect.fBottom - kOffCurveEpsilon,
|
| + rect.fLeft + rx, rect.fBottom);
|
| #endif
|
| if (!skip_hori) {
|
| this->lineTo(rect.fRight - rx, rect.fBottom); // bottom
|
| @@ -1145,7 +1151,10 @@
|
| rect.fRight, rect.fBottom - ry + sy,
|
| rect.fRight, rect.fBottom - ry); // bot-right
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 0, dir, false); // bot-right
|
| + this->quadTo(rect.fRight - rx + offPtX, rect.fBottom - kOffCurveEpsilon,
|
| + rect.fRight - rx + midPtX, rect.fBottom - ry + midPtY);
|
| + this->quadTo(rect.fRight - kOffCurveEpsilon, rect.fBottom - ry + offPtY,
|
| + rect.fRight, rect.fBottom - ry);
|
| #endif
|
| if (!skip_vert) {
|
| this->lineTo(rect.fRight, rect.fTop + ry); // right
|
| @@ -1155,7 +1164,10 @@
|
| rect.fRight - rx + sx, rect.fTop,
|
| rect.fRight - rx, rect.fTop); // top-right
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 270, dir, false); // top-right
|
| + this->quadTo(rect.fRight - kOffCurveEpsilon, rect.fTop + ry - offPtY,
|
| + rect.fRight - rx + midPtX, rect.fTop + ry - midPtY);
|
| + this->quadTo(rect.fRight - rx + offPtX, rect.fTop + kOffCurveEpsilon,
|
| + rect.fRight - rx, rect.fTop);
|
| #endif
|
| } else {
|
| #ifdef SK_IGNORE_QUAD_RR_CORNERS_OPT
|
| @@ -1163,7 +1175,10 @@
|
| rect.fRight, rect.fTop + ry - sy,
|
| rect.fRight, rect.fTop + ry); // top-right
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 270, dir, false); // top-right
|
| + this->quadTo(rect.fRight - rx + offPtX, rect.fTop + kOffCurveEpsilon,
|
| + rect.fRight - rx + midPtX, rect.fTop + ry - midPtY);
|
| + this->quadTo(rect.fRight - kOffCurveEpsilon, rect.fTop + ry - offPtY,
|
| + rect.fRight, rect.fTop + ry);
|
| #endif
|
| if (!skip_vert) {
|
| this->lineTo(rect.fRight, rect.fBottom - ry); // right
|
| @@ -1173,7 +1188,10 @@
|
| rect.fRight - rx + sx, rect.fBottom,
|
| rect.fRight - rx, rect.fBottom); // bot-right
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 0, dir, false); // bot-right
|
| + this->quadTo(rect.fRight - kOffCurveEpsilon, rect.fBottom - ry + offPtY,
|
| + rect.fRight - rx + midPtX, rect.fBottom - ry + midPtY);
|
| + this->quadTo(rect.fRight - rx + offPtX, rect.fBottom - kOffCurveEpsilon,
|
| + rect.fRight - rx, rect.fBottom);
|
| #endif
|
| if (!skip_hori) {
|
| this->lineTo(rect.fLeft + rx, rect.fBottom); // bottom
|
| @@ -1183,7 +1201,10 @@
|
| rect.fLeft, rect.fBottom - ry + sy,
|
| rect.fLeft, rect.fBottom - ry); // bot-left
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 90, dir, false); // bot-left
|
| + this->quadTo(rect.fLeft + rx - offPtX, rect.fBottom - kOffCurveEpsilon,
|
| + rect.fLeft + rx - midPtX, rect.fBottom - ry + midPtY);
|
| + this->quadTo(rect.fLeft + kOffCurveEpsilon, rect.fBottom - ry + offPtY,
|
| + rect.fLeft, rect.fBottom - ry);
|
| #endif
|
| if (!skip_vert) {
|
| this->lineTo(rect.fLeft, rect.fTop + ry); // left
|
| @@ -1193,7 +1214,10 @@
|
| rect.fLeft + rx - sx, rect.fTop,
|
| rect.fLeft + rx, rect.fTop); // top-left
|
| #else
|
| - add_corner_arc(this, rect, rx, ry, 180, dir, false); // top-left
|
| + this->quadTo(rect.fLeft + kOffCurveEpsilon, rect.fTop + ry - offPtY,
|
| + rect.fLeft + rx - midPtX, rect.fTop + ry - midPtY);
|
| + this->quadTo(rect.fLeft + rx - offPtX, rect.fTop + kOffCurveEpsilon,
|
| + rect.fLeft + rx, rect.fTop);
|
| #endif
|
| if (!skip_hori) {
|
| this->lineTo(rect.fRight - rx, rect.fTop); // top
|
|
|