[go: nahoru, domu]

add routines to compute error between conic and quad



git-svn-id: http://skia.googlecode.com/svn/trunk/src@8916 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkGeometry.cpp b/core/SkGeometry.cpp
index dcdbf9c..b6b23bc 100644
--- a/core/SkGeometry.cpp
+++ b/core/SkGeometry.cpp
@@ -1547,32 +1547,36 @@
  *  "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;
+#define AS_QUAD_ERROR_SETUP                                         \
+    SkScalar a = fW - 1;                                            \
+    SkScalar k = a / (4 * (2 + a));                                 \
+    SkScalar x = k * (fPts[0].fX - 2 * fPts[1].fX + fPts[2].fX);    \
+    SkScalar y = k * (fPts[0].fY - 2 * fPts[1].fY + fPts[2].fY);
+
+void SkConic::computeAsQuadError(SkVector* err) const {
+    AS_QUAD_ERROR_SETUP
+    err->set(x, y);
+}
+
+bool SkConic::asQuadTol(SkScalar tol) const {
+    AS_QUAD_ERROR_SETUP
+    return (x * x + y * y) <= tol * tol;
 }
 
 int SkConic::computeQuadPOW2(SkScalar tol) const {
-    SkVector diff;
-    if (!this->computeErrorAsQuad(&diff)) {
+    AS_QUAD_ERROR_SETUP
+    SkScalar error = SkScalarSqrt(x * x + y * y) - tol;
+
+    if (error <= 0) {
         return 0;
     }
-
-    // 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;
+    return (34 - SkCLZ(ierr)) >> 1;
 }
 
 static SkPoint* subdivide(const SkConic& src, SkPoint pts[], int level) {
     SkASSERT(level >= 0);
+
     if (0 == level) {
         memcpy(pts, &src.fPts[1], 2 * sizeof(SkPoint));
         return pts + 2;
@@ -1586,22 +1590,7 @@
 }
 
 int SkConic::chopIntoQuadsPOW2(SkPoint pts[], int pow2) const {
-    if (pow2 < 0) {
-        return 0;
-    }
-    if (0 == pow2) {
-        memcpy(pts, fPts, 3 * sizeof(SkPoint));
-        return 1;
-    }
-    if (1 == pow2) {
-        SkConic dst[2];
-        this->chop(dst);
-        memcpy(pts, dst[0].fPts, 3 * sizeof(SkPoint));
-        pts += 3;
-        memcpy(pts, dst[1].fPts + 1, 2 * sizeof(SkPoint));
-        return 2;
-    }
-
+    SkASSERT(pow2 >= 0);
     *pts = fPts[0];
     SkDEBUGCODE(SkPoint* endPts =) subdivide(*this, pts + 1, pow2);
     SkASSERT(endPts - pts == (2 * (1 << pow2) + 1));