diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 104dfc4..5a694db 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -22,6 +22,7 @@
 #include "SkSmallAllocator.h"
 #include "SkSurface_Base.h"
 #include "SkTemplates.h"
+#include "SkTextBlob.h"
 #include "SkTextFormatParams.h"
 #include "SkTLazy.h"
 #include "SkUtils.h"
@@ -2215,6 +2216,43 @@
     LOOPER_END
 }
 
+void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                              const SkPaint& paint) {
+    SkASSERT(blob);
+
+    // FIXME: dispatch to the device instead
+
+    if (x || y) {
+        this->translate(x, y);
+    }
+
+    SkTextBlob::RunIterator it(blob);
+    while (!it.done()) {
+        size_t textLen = it.glyphCount() * sizeof(uint16_t);
+        const SkPoint& offset = it.offset();
+
+        switch (it.positioning()) {
+        case SkTextBlob::kDefault_Positioning:
+            this->drawText(it.glyphs(), textLen, offset.x(), offset.y(), paint);
+            break;
+        case SkTextBlob::kHorizontal_Positioning:
+            this->drawPosTextH(it.glyphs(), textLen, it.pos(), offset.y(), paint);
+            break;
+        case SkTextBlob::kFull_Positioning:
+            this->drawPosText(it.glyphs(), textLen, (const SkPoint*)it.pos(), paint);
+            break;
+        default:
+            SkFAIL("unhandled positioning mode");
+        }
+
+        it.next();
+    }
+
+    if (x || y) {
+        this->translate(-x, -y);
+    }
+}
+
 // These will become non-virtual, so they always call the (virtual) onDraw... method
 void SkCanvas::drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
                         const SkPaint& paint) {
@@ -2232,6 +2270,12 @@
                               const SkMatrix* matrix, const SkPaint& paint) {
     this->onDrawTextOnPath(text, byteLength, path, matrix, paint);
 }
+void SkCanvas::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                            const SkPaint& paint) {
+    if (NULL != blob) {
+        this->onDrawTextBlob(blob, x, y, paint);
+    }
+}
 
 void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
                             const SkPoint verts[], const SkPoint texs[],
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index a1c148a..aa3e8de 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -89,6 +89,7 @@
 DRAW(DrawRect, drawRect(r.rect, r.paint));
 DRAW(DrawSprite, drawSprite(shallow_copy(r.bitmap), r.left, r.top, r.paint));
 DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint));
+DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint));
 DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, r.matrix, r.paint));
 DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors,
                                 r.xmode.get(), r.indices, r.indexCount, r.paint));
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index a2ef00b..2e14c3e 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -187,6 +187,11 @@
            this->copy(matrix));
 }
 
+void SkRecorder::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+                                const SkPaint& paint) {
+    APPEND(DrawTextBlob, delay_copy(paint), blob, x, y);
+}
+
 void SkRecorder::onDrawPicture(const SkPicture* pic, const SkMatrix* matrix, const SkPaint* paint) {
     APPEND(DrawPicture, this->copy(paint), pic, this->copy(matrix));
 }
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 1373f8a..8b1430d 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -89,6 +89,10 @@
                           const SkPath& path,
                           const SkMatrix* matrix,
                           const SkPaint& paint) SK_OVERRIDE;
+    void onDrawTextBlob(const SkTextBlob* blob,
+                        SkScalar x,
+                        SkScalar y,
+                        const SkPaint& paint);
     void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                      const SkPoint texCoords[4], SkXfermode* xmode,
                      const SkPaint& paint) SK_OVERRIDE;
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 6ec6e9c..6baabe6 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -10,23 +10,22 @@
 
 #include "SkCanvas.h"
 #include "SkPicture.h"
-
-class SkPictureBox {
-public:
-    SkPictureBox(const SkPicture* obj) : fObj(SkRef(obj)) {}
-    ~SkPictureBox() { fObj->unref(); }
-
-    operator const SkPicture*() const { return fObj; }
-
-private:
-    SkPictureBox(const SkPictureBox&);
-    SkPictureBox& operator=(const SkPictureBox&);
-
-    const SkPicture* fObj;
-};
+#include "SkTextBlob.h"
 
 namespace SkRecords {
 
+template <typename T>
+class RefBox : SkNoncopyable {
+public:
+    RefBox(const T* obj) : fObj(SkRef(obj)) {}
+    ~RefBox() { fObj->unref(); }
+
+    operator const T*() const { return fObj; }
+
+private:
+    const T* fObj;
+};
+
 // A list of all the types of canvas calls we can record.
 // Each of these is reified into a struct below.
 //
@@ -68,6 +67,7 @@
     M(DrawRRect)                                                    \
     M(DrawRect)                                                     \
     M(DrawSprite)                                                   \
+    M(DrawTextBlob)                                                     \
     M(DrawVertices)
 
 // Defines SkRecords::Type, an enum of all record types.
@@ -231,7 +231,7 @@
 RECORD1(DrawPaint, SkPaint, paint);
 RECORD2(DrawPath, SkPaint, paint, SkPath, path);
 //RECORD2(DrawPatch, SkPaint, paint, SkPatch, patch);
-RECORD3(DrawPicture, Optional<SkPaint>, paint, SkPictureBox, picture, Optional<SkMatrix>, matrix);
+RECORD3(DrawPicture, Optional<SkPaint>, paint, RefBox<SkPicture>, picture, Optional<SkMatrix>, matrix);
 RECORD4(DrawPoints, SkPaint, paint, SkCanvas::PointMode, mode, size_t, count, SkPoint*, pts);
 RECORD4(DrawPosText, SkPaint, paint,
                      PODArray<char>, text,
@@ -250,6 +250,10 @@
                   size_t, byteLength,
                   SkScalar, x,
                   SkScalar, y);
+RECORD4(DrawTextBlob, SkPaint, paint,
+                      RefBox<SkTextBlob>, blob,
+                      SkScalar, x,
+                      SkScalar, y);
 RECORD5(DrawTextOnPath, SkPaint, paint,
                         PODArray<char>, text,
                         size_t, byteLength,
diff --git a/src/core/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
new file mode 100644
index 0000000..551d988
--- /dev/null
+++ b/src/core/SkTextBlob.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTextBlob.h"
+
+SkTextBlob::SkTextBlob(uint16_t *glyphs, SkScalar *pos, const SkTArray<Run> *runs,
+                       const SkRect& bounds)
+    : fGlyphBuffer(glyphs)
+    , fPosBuffer(pos)
+    , fRuns(runs)
+    , fBounds(bounds) {
+}
+
+uint32_t SkTextBlob::uniqueID() const {
+    static int32_t  gTextBlobGenerationID; // = 0;
+
+    // loop in case our global wraps around, as we never want to return SK_InvalidGenID
+    while (SK_InvalidGenID == fUniqueID) {
+        fUniqueID = sk_atomic_inc(&gTextBlobGenerationID) + 1;
+    }
+
+    return fUniqueID;
+}
+
+SkTextBlob::RunIterator::RunIterator(const SkTextBlob* blob)
+    : fBlob(blob)
+    , fIndex(0) {
+    SkASSERT(NULL != blob);
+}
+
+bool SkTextBlob::RunIterator::done() const {
+    return NULL == fBlob->fRuns.get() || fIndex >= fBlob->fRuns->count();
+}
+
+void SkTextBlob::RunIterator::next() {
+    SkASSERT(!this->done());
+    fIndex++;
+}
+
+uint32_t SkTextBlob::RunIterator::glyphCount() const {
+    SkASSERT(!this->done());
+    return (*fBlob->fRuns)[fIndex].count;
+}
+
+const uint16_t* SkTextBlob::RunIterator::glyphs() const {
+    SkASSERT(!this->done());
+    return fBlob->fGlyphBuffer.get() + (*fBlob->fRuns)[fIndex].glyphStart;
+}
+
+const SkScalar* SkTextBlob::RunIterator::pos() const {
+    SkASSERT(!this->done());
+    return fBlob->fPosBuffer.get() + (*fBlob->fRuns)[fIndex].posStart;
+}
+
+const SkPoint& SkTextBlob::RunIterator::offset() const {
+    SkASSERT(!this->done());
+    return (*fBlob->fRuns)[fIndex].offset;
+}
+
+const SkPaint& SkTextBlob::RunIterator::font() const {
+    SkASSERT(!this->done());
+    return (*fBlob->fRuns)[fIndex].font;
+}
+
+SkTextBlob::GlyphPositioning SkTextBlob::RunIterator::positioning() const {
+    SkASSERT(!this->done());
+    return (*fBlob->fRuns)[fIndex].positioning;
+}
+
+SkTextBlobBuilder::SkTextBlobBuilder(unsigned runs)
+    : fRuns(NULL)
+    , fDeferredBounds(false) {
+
+    if (runs > 0) {
+        // if the number of runs is known, size our run storage accordingly.
+        fRuns = SkNEW(SkTArray<SkTextBlob::Run>(runs));
+    }
+    fBounds.setEmpty();
+}
+
+SkTextBlobBuilder::~SkTextBlobBuilder() {
+    // unused runs
+    SkDELETE(fRuns);
+}
+
+void SkTextBlobBuilder::updateDeferredBounds() {
+    SkASSERT(!fDeferredBounds || (NULL != fRuns && !fRuns->empty()));
+
+    if (!fDeferredBounds) {
+        return;
+    }
+
+    // FIXME: measure the current run & union bounds
+    fDeferredBounds = false;
+}
+
+void SkTextBlobBuilder::ensureRun(const SkPaint& font, SkTextBlob::GlyphPositioning pos,
+                                  const SkPoint& offset) {
+    SkASSERT(SkPaint::kGlyphID_TextEncoding == font.getTextEncoding());
+
+    if (NULL == fRuns) {
+        fRuns = SkNEW(SkTArray<SkTextBlob::Run>());
+    }
+
+    // we can merge same-font/same-positioning runs in the following cases:
+    //   * fully positioned run following another fully positioned run
+    //   * horizontally postioned run following another horizontally positioned run with the same
+    //     y-offset
+    if (!fRuns->empty()
+        && fRuns->back().positioning == pos
+        && fRuns->back().font == font
+        && (SkTextBlob::kFull_Positioning == fRuns->back().positioning
+            || (SkTextBlob::kHorizontal_Positioning == fRuns->back().positioning
+                && fRuns->back().offset.y() == offset.y()))){
+        return;
+    }
+
+    this->updateDeferredBounds();
+
+    // start a new run
+    SkTextBlob::Run& newRun = fRuns->push_back();
+    newRun.count = 0;
+    newRun.glyphStart = fGlyphBuffer.count();
+    newRun.posStart = fPosBuffer.count();
+    newRun.offset = offset;
+    newRun.font = font;
+    newRun.positioning = pos;
+}
+
+void SkTextBlobBuilder::allocInternal(const SkPaint &font,
+                                      SkTextBlob::GlyphPositioning positioning,
+                                      int count, SkPoint offset, const SkRect* bounds) {
+    SkASSERT(count > 0);
+
+    this->ensureRun(font, positioning, offset);
+
+    // SkTextBlob::GlyphPositioning values are directly mapped to scalars-per-glyph.
+    unsigned posScalarsPerGlyph = positioning;
+    SkASSERT(posScalarsPerGlyph <= 2);
+
+    fGlyphBuffer.append(count);
+    fPosBuffer.append(count * posScalarsPerGlyph);
+
+    SkASSERT(NULL != fRuns && !fRuns->empty());
+    SkTextBlob::Run& run = fRuns->back();
+
+    run.count += count;
+
+    // The current run might have been merged, so the start offset may point to prev run data.
+    // Start from the back (which always points to the end of the current run buffers) instead.
+    fCurrentRunBuffer.glyphs = fGlyphBuffer.isEmpty()
+            ? NULL : fGlyphBuffer.end() - count;
+    SkASSERT(NULL == fCurrentRunBuffer.glyphs || fCurrentRunBuffer.glyphs >= fGlyphBuffer.begin());
+    fCurrentRunBuffer.pos = fPosBuffer.isEmpty()
+            ? NULL : fPosBuffer.end() - count * posScalarsPerGlyph;
+    SkASSERT(NULL == fCurrentRunBuffer.pos || fCurrentRunBuffer.pos >= fPosBuffer.begin());
+
+    if (!fDeferredBounds) {
+        if (NULL != bounds) {
+            fBounds.join(*bounds);
+        } else {
+            fDeferredBounds = true;
+        }
+    }
+}
+
+const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRun(const SkPaint& font, int count,
+                                                                SkScalar x, SkScalar y,
+                                                                const SkRect* bounds) {
+    this->allocInternal(font, SkTextBlob::kDefault_Positioning, count, SkPoint::Make(x, y), bounds);
+
+    return fCurrentRunBuffer;
+}
+
+const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRunPosH(const SkPaint& font, int count,
+                                                                    SkScalar y,
+                                                                    const SkRect* bounds) {
+    this->allocInternal(font, SkTextBlob::kHorizontal_Positioning, count, SkPoint::Make(0, y),
+                        bounds);
+
+    return fCurrentRunBuffer;
+}
+
+const SkTextBlobBuilder::RunBuffer& SkTextBlobBuilder::allocRunPos(const SkPaint& font, int count,
+                                                                   const SkRect *bounds) {
+    this->allocInternal(font, SkTextBlob::kFull_Positioning, count, SkPoint::Make(0, 0), bounds);
+
+    return fCurrentRunBuffer;
+}
+
+const SkTextBlob* SkTextBlobBuilder::build() {
+    const SkTextBlob* blob;
+
+    if (fGlyphBuffer.count() > 0) {
+        // we have some glyphs, construct a real blob
+        SkASSERT(NULL != fRuns && !fRuns->empty());
+
+        this->updateDeferredBounds();
+
+        // ownership of all buffers is transferred to the blob
+        blob = SkNEW_ARGS(SkTextBlob, (fGlyphBuffer.detach(),
+                                       fPosBuffer.detach(),
+                                       fRuns,
+                                       fBounds));
+        fRuns = NULL;
+        fBounds.setEmpty();
+    } else {
+        // empty blob
+        SkASSERT(NULL == fRuns || fRuns->empty());
+        SkASSERT(fBounds.isEmpty());
+
+        blob = SkNEW_ARGS(SkTextBlob, (NULL, NULL, NULL, SkRect::MakeEmpty()));
+    }
+
+    return blob;
+}
+
