add dumpHex option to rect and rrect, to match path

BUG=skia:

Review URL: https://codereview.chromium.org/801383002
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 2cb33e2..f8280bd 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -2021,24 +2021,11 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#include "SkString.h"
+#include "SkStringUtils.h"
 #include "SkStream.h"
 
-static void append_scalar(SkString* str, SkScalar value, bool dumpAsHex) {
-    if (dumpAsHex) {
-        str->appendf("SkBits2Float(0x%08x)", SkFloat2Bits(value));
-        return;
-    }
-    SkString tmp;
-    tmp.printf("%g", value);
-    if (tmp.contains('.')) {
-        tmp.appendUnichar('f');
-    }
-    str->append(tmp);
-}
-
 static void append_params(SkString* str, const char label[], const SkPoint pts[],
-                          int count, bool dumpAsHex, SkScalar conicWeight = -1) {
+                          int count, SkScalarAsStringType strType, SkScalar conicWeight = -1) {
     str->append(label);
     str->append("(");
 
@@ -2046,33 +2033,34 @@
     count *= 2;
 
     for (int i = 0; i < count; ++i) {
-        append_scalar(str, values[i], dumpAsHex);
+        SkAppendScalar(str, values[i], strType);
         if (i < count - 1) {
             str->append(", ");
         }
     }
     if (conicWeight >= 0) {
         str->append(", ");
-        append_scalar(str, conicWeight, dumpAsHex);
+        SkAppendScalar(str, conicWeight, strType);
     }
     str->append(");");
-    if (dumpAsHex) {
+    if (kHex_SkScalarAsStringType == strType) {
         str->append("  // ");
         for (int i = 0; i < count; ++i) {
-            append_scalar(str, values[i], false);
+            SkAppendScalarDec(str, values[i]);
             if (i < count - 1) {
                 str->append(", ");
             }
         }
         if (conicWeight >= 0) {
             str->append(", ");
-            append_scalar(str, conicWeight, false);
+            SkAppendScalarDec(str, conicWeight);
         }
     }
     str->append("\n");
 }
 
 void SkPath::dump(SkWStream* wStream, bool forceClose, bool dumpAsHex) const {
+    SkScalarAsStringType asType = dumpAsHex ? kHex_SkScalarAsStringType : kDec_SkScalarAsStringType;
     Iter    iter(*this, forceClose);
     SkPoint pts[4];
     Verb    verb;
@@ -2085,19 +2073,19 @@
     while ((verb = iter.next(pts, false)) != kDone_Verb) {
         switch (verb) {
             case kMove_Verb:
-                append_params(&builder, "path.moveTo", &pts[0], 1, dumpAsHex);
+                append_params(&builder, "path.moveTo", &pts[0], 1, asType);
                 break;
             case kLine_Verb:
-                append_params(&builder, "path.lineTo", &pts[1], 1, dumpAsHex);
+                append_params(&builder, "path.lineTo", &pts[1], 1, asType);
                 break;
             case kQuad_Verb:
-                append_params(&builder, "path.quadTo", &pts[1], 2, dumpAsHex);
+                append_params(&builder, "path.quadTo", &pts[1], 2, asType);
                 break;
             case kConic_Verb:
-                append_params(&builder, "path.conicTo", &pts[1], 2, dumpAsHex, iter.conicWeight());
+                append_params(&builder, "path.conicTo", &pts[1], 2, asType, iter.conicWeight());
                 break;
             case kCubic_Verb:
-                append_params(&builder, "path.cubicTo", &pts[1], 3, dumpAsHex);
+                append_params(&builder, "path.cubicTo", &pts[1], 3, asType);
                 break;
             case kClose_Verb:
                 builder.append("path.close();\n");
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index 10d3d76..d3a571f 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -445,17 +445,27 @@
     return kSizeInMemory;
 }
 
-#ifdef SK_DEVELOPER
-void SkRRect::dump() const {
-    SkDebugf("Rect: ");
-    fRect.dump();
-    SkDebugf(" Corners: { TL: (%f, %f), TR: (%f, %f), BR: (%f, %f), BL: (%f, %f) }",
-             fRadii[kUpperLeft_Corner].fX,  fRadii[kUpperLeft_Corner].fY,
-             fRadii[kUpperRight_Corner].fX, fRadii[kUpperRight_Corner].fY,
-             fRadii[kLowerRight_Corner].fX, fRadii[kLowerRight_Corner].fY,
-             fRadii[kLowerLeft_Corner].fX,  fRadii[kLowerLeft_Corner].fY);
+#include "SkString.h"
+#include "SkStringUtils.h"
+
+void SkRRect::dump(bool asHex) const {
+    SkScalarAsStringType asType = asHex ? kHex_SkScalarAsStringType : kDec_SkScalarAsStringType;
+
+    fRect.dump(asHex);
+    SkString line("const SkPoint corners[] = {\n");
+    for (int i = 0; i < 4; ++i) {
+        SkString strX, strY;
+        SkAppendScalar(&strX, fRadii[i].x(), asType);
+        SkAppendScalar(&strY, fRadii[i].y(), asType);
+        line.appendf("    { %s, %s },", strX.c_str(), strY.c_str());
+        if (asHex) {
+            line.appendf(" /* %f %f */", fRadii[i].x(), fRadii[i].y());
+        }
+        line.append("\n");
+    }
+    line.append("};");
+    SkDebugf("%s\n", line.c_str());
 }
-#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/core/SkRect.cpp b/src/core/SkRect.cpp
index fbf03ef..afd8bd8 100644
--- a/src/core/SkRect.cpp
+++ b/src/core/SkRect.cpp
@@ -130,3 +130,35 @@
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkString.h"
+#include "SkStringUtils.h"
+
+static const char* set_scalar(SkString* storage, SkScalar value, SkScalarAsStringType asType) {
+    storage->reset();
+    SkAppendScalar(storage, value, asType);
+    return storage->c_str();
+}
+
+void SkRect::dump(bool asHex) const {
+    SkScalarAsStringType asType = asHex ? kHex_SkScalarAsStringType : kDec_SkScalarAsStringType;
+
+    SkString line;
+    if (asHex) {
+        SkString tmp;
+        line.printf( "SkRect::MakeLTRB(%s, /* %f */\n", set_scalar(&tmp, fLeft, asType), fLeft);
+        line.appendf("                 %s, /* %f */\n", set_scalar(&tmp, fTop, asType), fTop);
+        line.appendf("                 %s, /* %f */\n", set_scalar(&tmp, fRight, asType), fRight);
+        line.appendf("                 %s  /* %f */);", set_scalar(&tmp, fBottom, asType), fBottom);
+    } else {
+        SkString strL, strT, strR, strB;
+        SkAppendScalarDec(&strL, fLeft);
+        SkAppendScalarDec(&strT, fTop);
+        SkAppendScalarDec(&strR, fRight);
+        SkAppendScalarDec(&strB, fBottom);
+        line.printf("SkRect::MakeLTRB(%s, %s, %s, %s);",
+                    strL.c_str(), strT.c_str(), strR.c_str(), strB.c_str());
+    }
+    SkDebugf("%s\n", line.c_str());
+}
diff --git a/src/core/SkStringUtils.cpp b/src/core/SkStringUtils.cpp
index 0f93b8e..390de7f 100644
--- a/src/core/SkStringUtils.cpp
+++ b/src/core/SkStringUtils.cpp
@@ -17,3 +17,21 @@
         *needSeparator = true;
     }
 }
+
+void SkAppendScalar(SkString* str, SkScalar value, SkScalarAsStringType asType) {
+    switch (asType) {
+        case kHex_SkScalarAsStringType:
+            str->appendf("SkBits2Float(0x%08x)", SkFloat2Bits(value));
+            break;
+        case kDec_SkScalarAsStringType: {
+            SkString tmp;
+            tmp.printf("%g", value);
+            if (tmp.contains('.')) {
+                tmp.appendUnichar('f');
+            }
+            str->append(tmp);
+            break;
+        }
+    }
+}
+
diff --git a/src/core/SkStringUtils.h b/src/core/SkStringUtils.h
index aa5c809..2839ac2 100644
--- a/src/core/SkStringUtils.h
+++ b/src/core/SkStringUtils.h
@@ -20,4 +20,19 @@
                        const char* flagStr, bool* needSeparator);
 
 
+enum SkScalarAsStringType {
+    kDec_SkScalarAsStringType,
+    kHex_SkScalarAsStringType,
+};
+
+void SkAppendScalar(SkString*, SkScalar, SkScalarAsStringType);
+
+static inline void SkAppendScalarDec(SkString* str, SkScalar value) {
+    SkAppendScalar(str, value, kDec_SkScalarAsStringType);
+}
+
+static inline void SkAppendScalarHex(SkString* str, SkScalar value) {
+    SkAppendScalar(str, value, kHex_SkScalarAsStringType);
+}
+
 #endif