aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkGeometry.cpp
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-11-01 15:24:55 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-11-01 15:24:55 +0000
commitf91aaecbe9d3630123d803d80f7b29f06c8976c7 (patch)
tree491e9e34702d2cb61545e070d3bef08286b0a57f /src/core/SkGeometry.cpp
parent679eb674fc064993d534df4d48a4ddaff4e33e06 (diff)
Construct round rects with perpendicular tangents.
The round rects are constructed as before out of quadratics, but without fudging the control points. Instead, the mid on- curve point is nudged slightly outward to prevent the convexity test from failing. The convexity test now includes an error term for sign inequality after computing the cross product of the control lines. When the control points are represented as vectors, the number of bits of precision may be greatly reduced. Account for this by passing the number of bits available from the original control point values into the equality check. Making round rect construction lines perpendicular improves the chances of success when path ops encounters clips. No new tests are needed -- this change is exercised by the convex Path unit tests and the gm tests arcofzorro and hairlines. R=robertphillips@google.com, reed@google.com Author: caryclark@google.com Review URL: https://codereview.chromium.org/48783002 git-svn-id: http://skia.googlecode.com/svn/trunk@12085 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkGeometry.cpp')
-rw-r--r--src/core/SkGeometry.cpp63
1 files changed, 27 insertions, 36 deletions
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp
index 5d0707a6c4..9b15f9f1f9 100644
--- a/src/core/SkGeometry.cpp
+++ b/src/core/SkGeometry.cpp
@@ -1256,43 +1256,34 @@ static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y, S
return false;
}
-#ifdef SK_SCALAR_IS_FLOAT
-
-// Due to floating point issues (i.e., 1.0f - SK_ScalarRoot2Over2 !=
-// SK_ScalarRoot2Over2 - SK_ScalarTanPIOver8), the "correct" off curve
-// control points cause the quadratic circle approximation to be concave.
-// SK_OffEps is used to pull in the off-curve control points a bit
-// to make the quadratic approximation convex.
-// Pulling the off-curve controls points in is preferable to pushing some
-// of the on-curve points off.
-#define SK_OffEps 0.0001f
-#else
-#define SK_OffEps 0
-#endif
-
-
static const SkPoint gQuadCirclePts[kSkBuildQuadArcStorage] = {
- { SK_Scalar1, 0 },
- { SK_Scalar1 - SK_OffEps, SK_ScalarTanPIOver8 - SK_OffEps },
- { SK_ScalarRoot2Over2, SK_ScalarRoot2Over2 },
- { SK_ScalarTanPIOver8 - SK_OffEps, SK_Scalar1 - SK_OffEps },
-
- { 0, SK_Scalar1 },
- { -SK_ScalarTanPIOver8 + SK_OffEps,SK_Scalar1 - SK_OffEps },
- { -SK_ScalarRoot2Over2, SK_ScalarRoot2Over2 },
- { -SK_Scalar1 + SK_OffEps, SK_ScalarTanPIOver8 - SK_OffEps },
-
- { -SK_Scalar1, 0 },
- { -SK_Scalar1 + SK_OffEps, -SK_ScalarTanPIOver8 + SK_OffEps },
- { -SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2 },
- { -SK_ScalarTanPIOver8 + SK_OffEps,-SK_Scalar1 + SK_OffEps },
-
- { 0, -SK_Scalar1 },
- { SK_ScalarTanPIOver8 - SK_OffEps, -SK_Scalar1 + SK_OffEps },
- { SK_ScalarRoot2Over2, -SK_ScalarRoot2Over2 },
- { SK_Scalar1 - SK_OffEps, -SK_ScalarTanPIOver8 + SK_OffEps },
-
- { SK_Scalar1, 0 }
+// The mid point of the quadratic arc approximation is half way between the two
+// control points. The float epsilon adjustment moves the on curve point out by
+// two bits, distributing the convex test error between the round rect approximation
+// and the convex cross product sign equality test.
+#define SK_MID_RRECT_OFFSET (SK_Scalar1 + SK_ScalarTanPIOver8 + FLT_EPSILON * 4) / 2
+ { SK_Scalar1, 0 },
+ { SK_Scalar1, SK_ScalarTanPIOver8 },
+ { SK_MID_RRECT_OFFSET, SK_MID_RRECT_OFFSET },
+ { SK_ScalarTanPIOver8, SK_Scalar1 },
+
+ { 0, SK_Scalar1 },
+ { -SK_ScalarTanPIOver8, SK_Scalar1 },
+ { -SK_MID_RRECT_OFFSET, SK_MID_RRECT_OFFSET },
+ { -SK_Scalar1, SK_ScalarTanPIOver8 },
+
+ { -SK_Scalar1, 0 },
+ { -SK_Scalar1, -SK_ScalarTanPIOver8 },
+ { -SK_MID_RRECT_OFFSET, -SK_MID_RRECT_OFFSET },
+ { -SK_ScalarTanPIOver8, -SK_Scalar1 },
+
+ { 0, -SK_Scalar1 },
+ { SK_ScalarTanPIOver8, -SK_Scalar1 },
+ { SK_MID_RRECT_OFFSET, -SK_MID_RRECT_OFFSET },
+ { SK_Scalar1, -SK_ScalarTanPIOver8 },
+
+ { SK_Scalar1, 0 }
+#undef SK_MID_RRECT_OFFSET
};
int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop,