add computation for error in conic-as-quad
git-svn-id: http://skia.googlecode.com/svn/trunk@8887 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp
index 6b525fa..6be6218 100644
--- a/src/core/SkGeometry.cpp
+++ b/src/core/SkGeometry.cpp
@@ -1543,21 +1543,32 @@
dst[0].fW = dst[1].fW = subdivide_w_value(fW);
}
+/*
+ * "High order approximation of conic sections by quadratic splines"
+ * by Michael Floater, 1993
+ */
+bool SkConic::computeErrorAsQuad(SkVector* err) const {
+ if (fW <= 0) {
+ return false;
+ }
+ SkScalar a = fW - 1;
+ SkScalar k = a / (4 * (2 + a));
+ err->set(k * (fPts[0].fX - 2 * fPts[1].fX + fPts[2].fX),
+ k * (fPts[0].fY - 2 * fPts[1].fY + fPts[2].fY));
+ return true;
+}
+
int SkConic::computeQuadPOW2(SkScalar tol) const {
- if (fW <= SK_ScalarNearlyZero) {
- return 0; // treat as a line
+ SkVector diff;
+ if (!this->computeErrorAsQuad(&diff)) {
+ return 0;
}
- tol = SkScalarAbs(tol);
- SkScalar w = fW;
- int i = 0;
- for (; i < 8; ++i) {
- if (SkScalarAbs(w - 1) <= tol) {
- break;
- }
- w = subdivide_w_value(w);
- }
- return i;
+ // the error reduces by 4 with each subdivision, so return the subdivision
+ // count needed.
+ SkScalar error = diff.length() - SkScalarAbs(tol);
+ uint32_t ierr = (uint32_t)error;
+ return (33 - SkCLZ(ierr)) >> 1;
}
static SkPoint* subdivide(const SkConic& src, SkPoint pts[], int level) {
@@ -1655,12 +1666,3 @@
bounds->set(fPts, 3);
}
-/*
- * "High order approximation of conic sections by quadratic splines"
- * by Michael Floater, 1993
- *
- * Max error between conic and simple quad is bounded by this equation
- *
- * a <-- w - 1 (where w >= 0)
- * diff <-- a * (p0 - 2p1 + p2) / (4*(2 + a))
- */