SkTextBlob plumbing

Add SkTextBlob serialization + drawTextBlob() overrides.

R=mtklein@google.com, reed@google.com, robertphillips@google.com
BUG=269080

Author: fmalita@chromium.org

Review URL: https://codereview.chromium.org/499413002
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index de3958a..cb69b4e 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -901,6 +901,13 @@
     this->recordedDrawCommand();
 }
 
+void SkDeferredCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                      const SkPaint& paint) {
+    AutoImmediateDrawIfNeeded autoDraw(*this, &paint);
+    this->drawingCanvas()->drawTextBlob(blob, x, y, paint);
+    this->recordedDrawCommand();
+}
+
 void SkDeferredCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                      const SkPaint* paint) {
     this->drawingCanvas()->drawPicture(picture, matrix, paint);
diff --git a/src/utils/SkDumpCanvas.cpp b/src/utils/SkDumpCanvas.cpp
index 661f0d8..5e3d153 100644
--- a/src/utils/SkDumpCanvas.cpp
+++ b/src/utils/SkDumpCanvas.cpp
@@ -14,6 +14,7 @@
 #include "SkPixelRef.h"
 #include "SkRRect.h"
 #include "SkString.h"
+#include "SkTextBlob.h"
 #include <stdarg.h>
 #include <stdio.h>
 
@@ -423,6 +424,14 @@
                str.c_str(), byteLength);
 }
 
+void SkDumpCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                  const SkPaint& paint) {
+    SkString str;
+    toString(blob->bounds(), &str);
+    this->dump(kDrawText_Verb, &paint, "drawTextBlob(%p) [%s]", blob, str.c_str());
+    // FIXME: dump the actual blob content?
+}
+
 void SkDumpCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                  const SkPaint* paint) {
     this->dump(kDrawPicture_Verb, NULL, "drawPicture(%p) %d:%d", picture,
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index 9e94775..773af54 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -21,6 +21,7 @@
 #include "SkPixelRef.h"
 #include "SkRRect.h"
 #include "SkString.h"
+#include "SkTextBlob.h"
 #include "SkTypeface.h"
 
 extern "C" {
@@ -45,6 +46,7 @@
 DEF_MTNAME(SkPaint)
 DEF_MTNAME(SkPathEffect)
 DEF_MTNAME(SkShader)
+DEF_MTNAME(SkTextBlob)
 DEF_MTNAME(SkTypeface)
 
 template <typename T> T* push_new(lua_State* L) {
@@ -273,6 +275,11 @@
     CHECK_SETFIELD(key);
 }
 
+void SkLua::pushTextBlob(const SkTextBlob* blob, const char key[]) {
+    push_ref(fL, const_cast<SkTextBlob*>(blob));
+    CHECK_SETFIELD(key);
+}
+
 static const char* element_type(SkClipStack::Element::Type type) {
     switch (type) {
         case SkClipStack::Element::kEmpty_Type:
diff --git a/src/utils/SkLuaCanvas.cpp b/src/utils/SkLuaCanvas.cpp
index 0903ee8..8fe1aa2 100644
--- a/src/utils/SkLuaCanvas.cpp
+++ b/src/utils/SkLuaCanvas.cpp
@@ -268,6 +268,15 @@
     lua.pushPaint(paint, "paint");
 }
 
+void SkLuaCanvas::onDrawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y,
+                                 const SkPaint &paint) {
+    AUTO_LUA("drawTextBlob");
+    lua.pushTextBlob(blob, "blob");
+    lua.pushScalar(x, "x");
+    lua.pushScalar(y, "y");
+    lua.pushPaint(paint, "paint");
+}
+
 void SkLuaCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                 const SkPaint* paint) {
     AUTO_LUA("drawPicture");
diff --git a/src/utils/SkNWayCanvas.cpp b/src/utils/SkNWayCanvas.cpp
index d436bd4..90fd017 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -265,6 +265,14 @@
     }
 }
 
+void SkNWayCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                  const SkPaint &paint) {
+    Iter iter(fList);
+    while (iter.next()) {
+        iter->drawTextBlob(blob, x, y, paint);
+    }
+}
+
 void SkNWayCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                  const SkPaint* paint) {
     Iter iter(fList);
diff --git a/src/utils/SkProxyCanvas.cpp b/src/utils/SkProxyCanvas.cpp
index c15acaa..1677daf 100644
--- a/src/utils/SkProxyCanvas.cpp
+++ b/src/utils/SkProxyCanvas.cpp
@@ -136,6 +136,11 @@
     fProxy->drawTextOnPath(text, byteLength, path, matrix, paint);
 }
 
+void SkProxyCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                   const SkPaint& paint) {
+    fProxy->drawTextBlob(blob, x, y, paint);
+}
+
 void SkProxyCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
                                   const SkPaint* paint) {
     fProxy->drawPicture(picture, matrix, paint);
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index 228f25f..2b0eab7 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -571,6 +571,11 @@
         new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint));
 }
 
+void SkDebugCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                   const SkPaint& paint) {
+    this->addDrawCommand(new SkDrawTextBlobCommand(blob, x, y, paint));
+}
+
 void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
         const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
         SkXfermode*, const uint16_t indices[], int indexCount,
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index e4fb0d9..94ad426 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -242,6 +242,8 @@
                                 SkScalar constY, const SkPaint&) SK_OVERRIDE;
     virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
                                   const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
+    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) SK_OVERRIDE;
     virtual void onPushCull(const SkRect& cullRect) SK_OVERRIDE;
     virtual void onPopCull() SK_OVERRIDE;
 
diff --git a/src/utils/debugger/SkDrawCommand.cpp b/src/utils/debugger/SkDrawCommand.cpp
index 26d2a85..3cebca2 100644
--- a/src/utils/debugger/SkDrawCommand.cpp
+++ b/src/utils/debugger/SkDrawCommand.cpp
@@ -10,6 +10,8 @@
 #include "SkDrawCommand.h"
 #include "SkObjectParser.h"
 
+#include "SkTextBlob.h"
+
 // TODO(chudy): Refactor into non subclass model.
 
 SkDrawCommand::SkDrawCommand(DrawType type)
@@ -643,6 +645,26 @@
     canvas->drawPosTextH(fText, fByteLength, fXpos, fConstY, fPaint);
 }
 
+SkDrawTextBlobCommand::SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                             const SkPaint& paint)
+    : INHERITED(DRAW_TEXT_BLOB)
+    , fBlob(blob)
+    , fXPos(x)
+    , fYPos(y)
+    , fPaint(paint) {
+
+    blob->ref();
+
+    // FIXME: push blob info
+    fInfo.push(SkObjectParser::ScalarToString(x, "XPOS: "));
+    fInfo.push(SkObjectParser::ScalarToString(x, "YPOS: "));
+    fInfo.push(SkObjectParser::PaintToString(paint));
+}
+
+void SkDrawTextBlobCommand::execute(SkCanvas* canvas) {
+    canvas->drawTextBlob(fBlob, fXPos, fYPos, fPaint);
+}
+
 SkDrawRectCommand::SkDrawRectCommand(const SkRect& rect, const SkPaint& paint)
     : INHERITED(DRAW_RECT) {
     fRect = rect;
diff --git a/src/utils/debugger/SkDrawCommand.h b/src/utils/debugger/SkDrawCommand.h
index ce7b1f5..f3c8cca 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -436,6 +436,21 @@
     typedef SkDrawCommand INHERITED;
 };
 
+class SkDrawTextBlobCommand : public SkDrawCommand {
+public:
+    SkDrawTextBlobCommand(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint);
+
+    virtual void execute(SkCanvas* canvas) SK_OVERRIDE;
+
+private:
+    SkAutoTUnref<const SkTextBlob> fBlob;
+    SkScalar                       fXPos;
+    SkScalar                       fYPos;
+    SkPaint                        fPaint;
+
+    typedef SkDrawCommand INHERITED;
+};
+
 class SkDrawRectCommand : public SkDrawCommand {
 public:
     SkDrawRectCommand(const SkRect& rect, const SkPaint& paint);