make RRect and Oval first-class drawing primitives in SkCanvas.
add RRect as a first-class clip primitive.
Review URL: https://codereview.appspot.com/6923058

git-svn-id: http://skia.googlecode.com/svn/trunk@6762 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index 7ea3bbb..c827be6 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -14,6 +14,7 @@
 #include "SkDrawFilter.h"
 #include "SkGPipe.h"
 #include "SkPaint.h"
+#include "SkRRect.h"
 #include "SkShader.h"
 
 enum {
@@ -782,6 +783,15 @@
     return val;
 }
 
+bool SkDeferredCanvas::clipRRect(const SkRRect& rrect,
+                                 SkRegion::Op op,
+                                 bool doAntiAlias) {
+    this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias);
+    bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias);
+    this->recordedDrawCommand();
+    return val;
+}
+
 bool SkDeferredCanvas::clipPath(const SkPath& path,
                                 SkRegion::Op op,
                                 bool doAntiAlias) {
@@ -826,17 +836,35 @@
     this->recordedDrawCommand();
 }
 
+void SkDeferredCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
+    this->drawingCanvas()->drawOval(rect, paint);
+    this->recordedDrawCommand();
+}
+
 void SkDeferredCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
     if (fDeferredDrawing && this->isFullFrame(&rect, &paint) &&
         isPaintOpaque(&paint)) {
         this->getDeferredDevice()->skipPendingCommands();
     }
-
+    
     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
     this->drawingCanvas()->drawRect(rect, paint);
     this->recordedDrawCommand();
 }
 
+void SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+    if (rrect.isRect()) {
+        this->SkDeferredCanvas::drawRect(rrect.getBounds(), paint);
+    } else if (rrect.isOval()) {
+        this->SkDeferredCanvas::drawOval(rrect.getBounds(), paint);
+    } else {
+        AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
+        this->drawingCanvas()->drawRRect(rrect, paint);
+        this->recordedDrawCommand();
+    }
+}
+
 void SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
     AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
     this->drawingCanvas()->drawPath(path, paint);
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 9135849..2722fb4 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -8,6 +8,7 @@
 #include "SkDumpCanvas.h"
 #include "SkPicture.h"
 #include "SkPixelRef.h"
+#include "SkRRect.h"
 #include "SkString.h"
 #include <stdarg.h>
 
@@ -31,6 +32,31 @@
     str->appendf("[%d,%d %d:%d]", r.fLeft, r.fTop, r.width(), r.height());
 }
 
+static void toString(const SkRRect& rrect, SkString* str) {
+    SkRect r = rrect.getBounds();
+    str->appendf("[%g,%g %g:%g]",
+                 SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop),
+                 SkScalarToFloat(r.width()), SkScalarToFloat(r.height()));
+    if (rrect.isOval()) {
+        str->append("()");
+    } else if (rrect.isSimple()) {
+        const SkVector& rad = rrect.getSimpleRadii();
+        str->appendf("(%g,%g)", rad.x(), rad.y());
+    } else if (rrect.isComplex()) {
+        SkVector radii[4] = {
+            rrect.radii(SkRRect::kUpperLeft_Corner),
+            rrect.radii(SkRRect::kUpperRight_Corner),
+            rrect.radii(SkRRect::kLowerRight_Corner),
+            rrect.radii(SkRRect::kLowerLeft_Corner),
+        };
+        str->appendf("(%g,%g %g,%g %g,%g %g,%g)",
+                     radii[0].x(), radii[0].y(),
+                     radii[1].x(), radii[1].y(),
+                     radii[2].x(), radii[2].y(),
+                     radii[3].x(), radii[3].y());
+    }
+}
+
 static void dumpVerbs(const SkPath& path, SkString* str) {
     SkPath::Iter iter(path, false);
     SkPoint pts[4];
@@ -273,6 +299,14 @@
     return this->INHERITED::clipRect(rect, op, doAA);
 }
 
+bool SkDumpCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+    SkString str;
+    toString(rrect, &str);
+    this->dump(kClip_Verb, NULL, "clipRRect(%s %s %s)", str.c_str(), toString(op),
+               bool_to_aastring(doAA));
+    return this->INHERITED::clipRRect(rrect, op, doAA);
+}
+
 bool SkDumpCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
     SkString str;
     toString(path, &str);
@@ -301,12 +335,24 @@
                count);
 }
 
+void SkDumpCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+    SkString str;
+    toString(rect, &str);
+    this->dump(kDrawOval_Verb, &paint, "drawOval(%s)", str.c_str());
+}
+
 void SkDumpCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
     SkString str;
     toString(rect, &str);
     this->dump(kDrawRect_Verb, &paint, "drawRect(%s)", str.c_str());
 }
 
+void SkDumpCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+    SkString str;
+    toString(rrect, &str);
+    this->dump(kDrawRRect_Verb, &paint, "drawRRect(%s)", str.c_str());
+}
+
 void SkDumpCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
     SkString str;
     toString(path, &str);
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index 3b78163..d59d559 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -144,6 +144,14 @@
     return this->INHERITED::clipRect(rect, op, doAA);
 }
 
+bool SkNWayCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+    Iter iter(fList);
+    while (iter.next()) {
+        iter->clipRRect(rrect, op, doAA);
+    }
+    return this->INHERITED::clipRRect(rrect, op, doAA);
+}
+
 bool SkNWayCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
     Iter iter(fList);
     while (iter.next()) {
@@ -175,6 +183,13 @@
     }
 }
 
+void SkNWayCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+    Iter iter(fList);
+    while (iter.next()) {
+        iter->drawOval(rect, paint);
+    }
+}
+
 void SkNWayCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
     Iter iter(fList);
     while (iter.next()) {
@@ -182,6 +197,13 @@
     }
 }
 
+void SkNWayCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+    Iter iter(fList);
+    while (iter.next()) {
+        iter->drawRRect(rrect, paint);
+    }
+}
+
 void SkNWayCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
     Iter iter(fList);
     while (iter.next()) {
diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp
index e245c73..4af509d 100644
--- a/src/utils/SkProxyCanvas.cpp
+++ b/src/utils/SkProxyCanvas.cpp
@@ -62,6 +62,10 @@
     return fProxy->clipRect(rect, op, doAA);
 }
 
+bool SkProxyCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) {
+    return fProxy->clipRRect(rrect, op, doAA);
+}
+
 bool SkProxyCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) {
     return fProxy->clipPath(path, op, doAA);
 }
@@ -79,10 +83,18 @@
     fProxy->drawPoints(mode, count, pts, paint);
 }
 
+void SkProxyCanvas::drawOval(const SkRect& rect, const SkPaint& paint) {
+    fProxy->drawOval(rect, paint);
+}
+
 void SkProxyCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
     fProxy->drawRect(rect, paint);
 }
 
+void SkProxyCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
+    fProxy->drawRRect(rrect, paint);
+}
+
 void SkProxyCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
     fProxy->drawPath(path, paint);
 }