use conics

BUG=skia:

Review URL: https://codereview.chromium.org/455043002
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 6dc056e..6e09af7 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2006 The Android Open Source Project
  *
@@ -6,15 +5,17 @@
  * found in the LICENSE file.
  */
 
-
 #include "SkBuffer.h"
 #include "SkErrorInternals.h"
+#include "SkGeometry.h"
 #include "SkMath.h"
 #include "SkPath.h"
 #include "SkPathRef.h"
 #include "SkRRect.h"
 #include "SkThread.h"
 
+#define SK_SUPPORT_LEGACY_ADDOVAL
+
 ////////////////////////////////////////////////////////////////////////////
 
 /**
@@ -282,8 +283,23 @@
                 SkDEBUGFAIL("unknown verb");
         }
         if (-1 != nextPt) {
-            if (!check_edge_against_rect(prevPt, pts[nextPt], rect, direction)) {
-                return false;
+            if (SkPath::kConic_Verb == verb) {
+                SkConic orig;
+                orig.set(pts, iter.conicWeight());
+                SkPoint quadPts[5];
+                int count = orig.chopIntoQuadsPOW2(quadPts, 1);
+                SK_ALWAYSBREAK(2 == count);
+
+                if (!check_edge_against_rect(quadPts[0], quadPts[2], rect, direction)) {
+                    return false;
+                }
+                if (!check_edge_against_rect(quadPts[2], quadPts[4], rect, direction)) {
+                    return false;
+                }
+            } else {
+                if (!check_edge_against_rect(prevPt, pts[nextPt], rect, direction)) {
+                    return false;
+                }
             }
             prevPt = pts[nextPt];
         }
@@ -1173,6 +1189,7 @@
 
     SkAutoPathBoundsUpdate apbu(this, oval);
 
+#ifdef SK_SUPPORT_LEGACY_ADDOVAL
     SkScalar    cx = oval.centerX();
     SkScalar    cy = oval.centerY();
     SkScalar    rx = SkScalarHalf(oval.width());
@@ -1184,11 +1201,11 @@
     SkScalar    my = SkScalarMul(ry, SK_ScalarRoot2Over2);
 
     /*
-        To handle imprecision in computing the center and radii, we revert to
-        the provided bounds when we can (i.e. use oval.fLeft instead of cx-rx)
-        to ensure that we don't exceed the oval's bounds *ever*, since we want
-        to use oval for our fast-bounds, rather than have to recompute it.
-    */
+     To handle imprecision in computing the center and radii, we revert to
+     the provided bounds when we can (i.e. use oval.fLeft instead of cx-rx)
+     to ensure that we don't exceed the oval's bounds *ever*, since we want
+     to use oval for our fast-bounds, rather than have to recompute it.
+     */
     const SkScalar L = oval.fLeft;      // cx - rx
     const SkScalar T = oval.fTop;       // cy - ry
     const SkScalar R = oval.fRight;     // cx + rx
@@ -1215,6 +1232,29 @@
         this->quadTo(cx + sx,       T, cx + mx, cy - my);
         this->quadTo(      R, cy - sy,       R, cy     );
     }
+#else
+    const SkScalar L = oval.fLeft;
+    const SkScalar T = oval.fTop;
+    const SkScalar R = oval.fRight;
+    const SkScalar B = oval.fBottom;
+    const SkScalar cx = oval.centerX();
+    const SkScalar cy = oval.centerY();
+    const SkScalar weight = SK_ScalarRoot2Over2;
+
+    this->incReserve(9);   // move + 4 conics
+    this->moveTo(R, cy);
+    if (dir == kCCW_Direction) {
+        this->conicTo(R, T, cx, T, weight);
+        this->conicTo(L, T, L, cy, weight);
+        this->conicTo(L, B, cx, B, weight);
+        this->conicTo(R, B, R, cy, weight);
+    } else {
+        this->conicTo(R, B, cx, B, weight);
+        this->conicTo(L, B, L, cy, weight);
+        this->conicTo(L, T, cx, T, weight);
+        this->conicTo(R, T, R, cy, weight);
+    }
+#endif
     this->close();
 
     SkPathRef::Editor ed(&fPathRef);
@@ -1530,21 +1570,6 @@
     this->transform(matrix, dst);
 }
 
-#include "SkGeometry.h"
-
-static void subdivide_quad_to(SkPath* path, const SkPoint pts[3],
-                              int level = 2) {
-    if (--level >= 0) {
-        SkPoint tmp[5];
-
-        SkChopQuadAtHalf(pts, tmp);
-        subdivide_quad_to(path, &tmp[0], level);
-        subdivide_quad_to(path, &tmp[2], level);
-    } else {
-        path->quadTo(pts[1], pts[2]);
-    }
-}
-
 static void subdivide_cubic_to(SkPath* path, const SkPoint pts[4],
                                int level = 2) {
     if (--level >= 0) {
@@ -1581,11 +1606,13 @@
                     tmp.lineTo(pts[1]);
                     break;
                 case kQuad_Verb:
-                    subdivide_quad_to(&tmp, pts);
+                    // promote the quad to a conic
+                    tmp.conicTo(pts[1], pts[2],
+                                SkConic::TransformW(pts, SK_Scalar1, matrix));
                     break;
                 case kConic_Verb:
-                    SkDEBUGFAIL("TODO: compute new weight");
-                    tmp.conicTo(pts[1], pts[2], iter.conicWeight());
+                    tmp.conicTo(pts[1], pts[2],
+                                SkConic::TransformW(pts, iter.conicWeight(), matrix));
                     break;
                 case kCubic_Verb:
                     subdivide_cubic_to(&tmp, pts);