aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2014-08-26 07:56:44 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-26 07:56:44 -0700
commitb7425173f96e93b090787e2386ba5f022b6c2869 (patch)
treeb73511cfeb4373c7a46a2507ada4274ca4b099e8 /src
parent3d2e50d1aa56d7f65a4c52fa03af4413fa4c616a (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBBoxRecord.cpp16
-rw-r--r--src/core/SkBBoxRecord.h2
-rw-r--r--src/core/SkPictureData.cpp52
-rw-r--r--src/core/SkPictureData.h16
-rw-r--r--src/core/SkPictureFlat.h3
-rw-r--r--src/core/SkPicturePlayback.cpp8
-rw-r--r--src/core/SkPictureRecord.cpp33
-rw-r--r--src/core/SkPictureRecord.h10
-rw-r--r--src/core/SkRecorder.h2
-rw-r--r--src/core/SkTextBlob.cpp87
-rw-r--r--src/pipe/SkGPipePriv.h1
-rw-r--r--src/pipe/SkGPipeRead.cpp5
-rw-r--r--src/pipe/SkGPipeWrite.cpp9
-rw-r--r--src/utils/SkDeferredCanvas.cpp7
-rw-r--r--src/utils/SkDumpCanvas.cpp9
-rw-r--r--src/utils/SkLua.cpp7
-rw-r--r--src/utils/SkLuaCanvas.cpp9
-rw-r--r--src/utils/SkNWayCanvas.cpp8
-rw-r--r--src/utils/SkProxyCanvas.cpp5
-rw-r--r--src/utils/debugger/SkDebugCanvas.cpp5
-rw-r--r--src/utils/debugger/SkDebugCanvas.h2
-rw-r--r--src/utils/debugger/SkDrawCommand.cpp22
-rw-r--r--src/utils/debugger/SkDrawCommand.h15
23 files changed, 323 insertions, 10 deletions
diff --git a/src/core/SkBBoxRecord.cpp b/src/core/SkBBoxRecord.cpp
index 69139ad54d..5837a88f5a 100644
--- a/src/core/SkBBoxRecord.cpp
+++ b/src/core/SkBBoxRecord.cpp
@@ -9,6 +9,8 @@
#include "SkBBoxRecord.h"
#include "SkPatchUtils.h"
+#include "SkTextBlob.h"
+
SkBBoxRecord::~SkBBoxRecord() {
fSaveStack.deleteAll();
}
@@ -272,6 +274,20 @@ void SkBBoxRecord::onDrawTextOnPath(const void* text, size_t byteLength, const S
}
}
+void SkBBoxRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ SkRect bbox = blob->bounds();
+ bbox.offset(x, y);
+ // FIXME: implement implicit blob bounds!
+ if (bbox.isEmpty()) {
+ this->getClipBounds(&bbox);
+ }
+
+ if (this->transformBounds(bbox, &paint)) {
+ INHERITED::onDrawTextBlob(blob, x, y, paint);
+ }
+}
+
void SkBBoxRecord::drawVertices(VertexMode mode, int vertexCount,
const SkPoint vertices[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xfer,
diff --git a/src/core/SkBBoxRecord.h b/src/core/SkBBoxRecord.h
index 1d19b70054..4833452e73 100644
--- a/src/core/SkBBoxRecord.h
+++ b/src/core/SkBBoxRecord.h
@@ -66,6 +66,8 @@ protected:
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 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/SkPictureData.cpp b/src/core/SkPictureData.cpp
index 2bcf7798cc..86a338899e 100644
--- a/src/core/SkPictureData.cpp
+++ b/src/core/SkPictureData.cpp
@@ -10,6 +10,7 @@
#include "SkPictureData.h"
#include "SkPictureRecord.h"
#include "SkReadBuffer.h"
+#include "SkTextBlob.h"
#include "SkTypeface.h"
#include "SkTSort.h"
#include "SkWriteBuffer.h"
@@ -76,6 +77,16 @@ SkPictureData::SkPictureData(const SkPictureRecord& record,
fPictureRefs[i]->ref();
}
}
+
+ // templatize to consolidate with similar picture logic?
+ const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs();
+ fTextBlobCount = blobs.count();
+ if (fTextBlobCount > 0) {
+ fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount);
+ for (int i = 0; i < fTextBlobCount; ++i) {
+ fTextBlobRefs[i] = SkRef(blobs[i]);
+ }
+ }
}
#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
@@ -139,6 +150,8 @@ void SkPictureData::init() {
fPaints = NULL;
fPictureRefs = NULL;
fPictureCount = 0;
+ fTextBlobRefs = NULL;
+ fTextBlobCount = 0;
fOpData = NULL;
fFactoryPlayback = NULL;
fBoundingHierarchy = NULL;
@@ -158,6 +171,11 @@ SkPictureData::~SkPictureData() {
}
SkDELETE_ARRAY(fPictureRefs);
+ for (int i = 0; i < fTextBlobCount; i++) {
+ fTextBlobRefs[i]->unref();
+ }
+ SkDELETE_ARRAY(fTextBlobRefs);
+
SkDELETE(fFactoryPlayback);
}
@@ -268,6 +286,13 @@ void SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n);
fPathHeap->flatten(buffer);
}
+
+ if (fTextBlobCount > 0) {
+ write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount);
+ for (i = 0; i < fTextBlobCount; ++i) {
+ fTextBlobRefs[i]->flatten(buffer);
+ }
+ }
}
void SkPictureData::serialize(SkWStream* stream,
@@ -485,6 +510,33 @@ bool SkPictureData::parseBufferTag(SkReadBuffer& buffer,
fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
}
break;
+ case SK_PICT_TEXTBLOB_BUFFER_TAG: {
+ if (!buffer.validate((0 == fTextBlobCount) && (NULL == fTextBlobRefs))) {
+ return false;
+ }
+ fTextBlobCount = size;
+ fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount);
+ bool success = true;
+ int i = 0;
+ for ( ; i < fTextBlobCount; i++) {
+ fTextBlobRefs[i] = SkTextBlob::CreateFromBuffer(buffer);
+ if (NULL == fTextBlobRefs[i]) {
+ success = false;
+ break;
+ }
+ }
+ if (!success) {
+ // Delete all of the blobs that were already created (up to but excluding i):
+ for (int j = 0; j < i; j++) {
+ fTextBlobRefs[j]->unref();
+ }
+ // Delete the array
+ SkDELETE_ARRAY(fTextBlobRefs);
+ fTextBlobRefs = NULL;
+ fTextBlobCount = 0;
+ return false;
+ }
+ } break;
case SK_PICT_READER_TAG: {
SkAutoMalloc storage(size);
if (!buffer.readByteArray(storage.get(), size) ||
diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h
index a6c840aa0a..14c51860dd 100644
--- a/src/core/SkPictureData.h
+++ b/src/core/SkPictureData.h
@@ -26,6 +26,7 @@ class SkPaint;
class SkPath;
class SkPictureStateTree;
class SkReadBuffer;
+class SkTextBlob;
struct SkPictInfo {
enum Flags {
@@ -49,9 +50,10 @@ struct SkPictInfo {
// This tag specifies the size of the ReadBuffer, needed for the following tags
#define SK_PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y')
// these are all inside the ARRAYS tag
-#define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p')
-#define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ')
-#define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ')
+#define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p')
+#define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ')
+#define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ')
+#define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
// Always write this guy last (with no length field afterwards)
#define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ')
@@ -132,6 +134,12 @@ public:
return &(*fPaints)[index - 1];
}
+ const SkTextBlob* getTextBlob(SkReader32* reader) const {
+ int index = reader->readInt();
+ SkASSERT(index > 0 && index <= fTextBlobCount);
+ return fTextBlobRefs[index - 1];
+ }
+
void initIterator(SkPictureStateTree::Iterator* iter,
const SkTDArray<void*>& draws,
SkCanvas* canvas) const {
@@ -183,6 +191,8 @@ private:
const SkPicture** fPictureRefs;
int fPictureCount;
+ const SkTextBlob** fTextBlobRefs;
+ int fTextBlobCount;
SkBBoxHierarchy* fBoundingHierarchy;
SkPictureStateTree* fStateTree;
diff --git a/src/core/SkPictureFlat.h b/src/core/SkPictureFlat.h
index 536189bf22..3530f3973f 100644
--- a/src/core/SkPictureFlat.h
+++ b/src/core/SkPictureFlat.h
@@ -69,8 +69,9 @@ enum DrawType {
DRAW_PATCH, // could not add in aphabetical order
DRAW_PICTURE_MATRIX_PAINT,
+ DRAW_TEXT_BLOB,
- LAST_DRAWTYPE_ENUM = DRAW_PICTURE_MATRIX_PAINT
+ LAST_DRAWTYPE_ENUM = DRAW_TEXT_BLOB
};
// In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 6197d88d66..a64bf0ff5e 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -12,6 +12,7 @@
#include "SkPictureRecord.h"
#include "SkPictureStateTree.h"
#include "SkReader32.h"
+#include "SkTextBlob.h"
#include "SkTDArray.h"
#include "SkTypes.h"
@@ -420,6 +421,13 @@ void SkPicturePlayback::handleOp(SkReader32* reader,
SkScalar y = reader->readScalar();
canvas->drawText(text.text(), text.length(), x, y, paint);
} break;
+ case DRAW_TEXT_BLOB: {
+ const SkPaint& paint = *fPictureData->getPaint(reader);
+ const SkTextBlob* blob = fPictureData->getTextBlob(reader);
+ SkScalar x = reader->readScalar();
+ SkScalar y = reader->readScalar();
+ canvas->drawTextBlob(blob, x, y, paint);
+ } break;
case DRAW_TEXT_TOP_BOTTOM: {
const SkPaint& paint = *fPictureData->getPaint(reader);
TextContainer text;
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index dd8040071f..67bd9a548b 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -12,6 +12,7 @@
#include "SkPictureStateTree.h"
#include "SkPixelRef.h"
#include "SkRRect.h"
+#include "SkTextBlob.h"
#include "SkTSearch.h"
#define HEAP_BLOCK_SIZE 4096
@@ -59,6 +60,7 @@ SkPictureRecord::~SkPictureRecord() {
SkSafeUnref(fStateTree);
fFlattenableHeap.setBitmapStorage(NULL);
fPictureRefs.unrefAll();
+ fTextBlobRefs.unrefAll();
}
///////////////////////////////////////////////////////////////////////////////
@@ -114,6 +116,7 @@ static inline size_t getPaintOffset(DrawType op, size_t opSize) {
0, // POP_CULL - no paint
1, // DRAW_PATCH - right after op code
1, // DRAW_PICTURE_MATRIX_PAINT - right after op code
+ 1, // DRAW_TEXT_BLOB- right after op code
};
SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1,
@@ -462,7 +465,8 @@ static bool is_drawing_op(DrawType op) {
return (op > CONCAT && op < ROTATE)
|| DRAW_DRRECT == op
|| DRAW_PATCH == op
- || DRAW_PICTURE_MATRIX_PAINT == op;
+ || DRAW_PICTURE_MATRIX_PAINT == op
+ || DRAW_TEXT_BLOB == op;
}
/*
@@ -1207,6 +1211,22 @@ void SkPictureRecord::onDrawTextOnPath(const void* text, size_t byteLength, cons
this->validate(initialOffset, size);
}
+void SkPictureRecord::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+
+ // op + paint index + blob index + x/y
+ size_t size = 3 * kUInt32Size + 2 * sizeof(SkScalar);
+ size_t initialOffset = this->addDraw(DRAW_TEXT_BLOB, &size);
+ SkASSERT(initialOffset + getPaintOffset(DRAW_TEXT_BLOB, size) == fWriter.bytesWritten());
+
+ this->addPaint(paint);
+ this->addTextBlob(blob);
+ this->addScalar(x);
+ this->addScalar(y);
+
+ this->validate(initialOffset, size);
+}
+
void SkPictureRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
const SkPaint* paint) {
// op + picture index
@@ -1523,5 +1543,16 @@ void SkPictureRecord::addText(const void* text, size_t byteLength) {
fWriter.writePad(text, byteLength);
}
+void SkPictureRecord::addTextBlob(const SkTextBlob *blob) {
+ int index = fTextBlobRefs.find(blob);
+ if (index < 0) { // not found
+ index = fTextBlobRefs.count();
+ *fTextBlobRefs.append() = blob;
+ blob->ref();
+ }
+ // follow the convention of recording a 1-based index
+ this->addInt(index + 1);
+}
+
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 8fd40bc230..f2dd87b76a 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -71,6 +71,10 @@ public:
return fPictureRefs;
}
+ const SkTDArray<const SkTextBlob* >& getTextBlobRefs() const {
+ return fTextBlobRefs;
+ }
+
SkData* opData(bool deepCopy) const {
this->validate(fWriter.bytesWritten(), 0);
@@ -181,6 +185,7 @@ private:
void addRRect(const SkRRect&);
void addRegion(const SkRegion& region);
void addText(const void* text, size_t byteLength);
+ void addTextBlob(const SkTextBlob* blob);
int find(const SkBitmap& bitmap);
@@ -213,6 +218,8 @@ protected:
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 onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode,
@@ -281,7 +288,8 @@ private:
SkWriter32 fWriter;
// we ref each item in these arrays
- SkTDArray<const SkPicture*> fPictureRefs;
+ SkTDArray<const SkPicture*> fPictureRefs;
+ SkTDArray<const SkTextBlob*> fTextBlobRefs;
uint32_t fRecordFlags;
bool fOptsEnabled;
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 23ecdf6aab..683d29b411 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -92,7 +92,7 @@ public:
void onDrawTextBlob(const SkTextBlob* blob,
SkScalar x,
SkScalar y,
- const SkPaint& paint);
+ const SkPaint& paint) SK_OVERRIDE;
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/SkTextBlob.cpp b/src/core/SkTextBlob.cpp
index ded801aaa9..d928d7bc25 100644
--- a/src/core/SkTextBlob.cpp
+++ b/src/core/SkTextBlob.cpp
@@ -7,6 +7,9 @@
#include "SkTextBlob.h"
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
+
SkTextBlob::SkTextBlob(uint16_t *glyphs, SkScalar *pos, const SkTArray<Run> *runs,
const SkRect& bounds)
: fGlyphBuffer(glyphs)
@@ -26,6 +29,86 @@ uint32_t SkTextBlob::uniqueID() const {
return fUniqueID;
}
+unsigned SkTextBlob::ScalarsPerGlyph(GlyphPositioning pos) {
+ // GlyphPositioning values are directly mapped to scalars-per-glyph.
+ SkASSERT(pos <= 2);
+ return pos;
+}
+
+void SkTextBlob::flatten(SkWriteBuffer& buffer) const {
+ int runCount = (NULL == fRuns.get()) ? 0 : fRuns->count();
+
+ buffer.write32(runCount);
+ buffer.writeRect(fBounds);
+
+ SkPaint runPaint;
+ RunIterator it(this);
+ while (!it.done()) {
+ SkASSERT(it.glyphCount() > 0);
+
+ buffer.write32(it.glyphCount());
+ buffer.write32(it.positioning());
+ buffer.writePoint(it.offset());
+ // This should go away when switching to SkFont
+ it.applyFontToPaint(&runPaint);
+ buffer.writePaint(runPaint);
+
+ buffer.writeByteArray(it.glyphs(), it.glyphCount() * sizeof(uint16_t));
+ buffer.writeByteArray(it.pos(),
+ it.glyphCount() * sizeof(SkScalar) * ScalarsPerGlyph(it.positioning()));
+
+ it.next();
+ SkDEBUGCODE(runCount--);
+ }
+ SkASSERT(0 == runCount);
+}
+
+const SkTextBlob* SkTextBlob::CreateFromBuffer(SkReadBuffer& reader) {
+ int runCount = reader.read32();
+ if (runCount < 0) {
+ return NULL;
+ }
+
+ SkRect bounds;
+ reader.readRect(&bounds);
+
+ SkTextBlobBuilder blobBuilder;
+ for (int i = 0; i < runCount; ++i) {
+ int glyphCount = reader.read32();
+ GlyphPositioning pos = static_cast<GlyphPositioning>(reader.read32());
+ if (glyphCount <= 0 || pos > kFull_Positioning) {
+ return NULL;
+ }
+
+ SkPoint offset;
+ reader.readPoint(&offset);
+ SkPaint font;
+ reader.readPaint(&font);
+
+ const SkTextBlobBuilder::RunBuffer* buf = NULL;
+ switch (pos) {
+ case kDefault_Positioning:
+ buf = &blobBuilder.allocRun(font, glyphCount, offset.x(), offset.y(), &bounds);
+ break;
+ case kHorizontal_Positioning:
+ buf = &blobBuilder.allocRunPosH(font, glyphCount, offset.y(), &bounds);
+ break;
+ case kFull_Positioning:
+ buf = &blobBuilder.allocRunPos(font, glyphCount, &bounds);
+ break;
+ default:
+ return NULL;
+ }
+
+ if (!reader.readByteArray(buf->glyphs, glyphCount * sizeof(uint16_t)) ||
+ !reader.readByteArray(buf->pos, glyphCount * sizeof(SkScalar) * ScalarsPerGlyph(pos))) {
+ return NULL;
+ }
+ }
+
+ return blobBuilder.build();
+}
+
SkTextBlob::RunIterator::RunIterator(const SkTextBlob* blob)
: fBlob(blob)
, fIndex(0) {
@@ -161,9 +244,7 @@ void SkTextBlobBuilder::allocInternal(const SkPaint &font,
this->ensureRun(font, positioning, offset);
- // SkTextBlob::GlyphPositioning values are directly mapped to scalars-per-glyph.
- unsigned posScalarsPerGlyph = positioning;
- SkASSERT(posScalarsPerGlyph <= 2);
+ unsigned posScalarsPerGlyph = SkTextBlob::ScalarsPerGlyph(positioning);
fGlyphBuffer.append(count);
fPosBuffer.append(count * posScalarsPerGlyph);
diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h
index 821da0ff25..121512d42a 100644
--- a/src/pipe/SkGPipePriv.h
+++ b/src/pipe/SkGPipePriv.h
@@ -58,6 +58,7 @@ enum DrawOps {
kDrawRRect_DrawOp,
kDrawSprite_DrawOp,
kDrawText_DrawOp,
+ kDrawTextBlob_DrawOp,
kDrawTextOnPath_DrawOp,
kDrawVertices_DrawOp,
kRestore_DrawOp,
diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp
index 35de638e05..e48baf3812 100644
--- a/src/pipe/SkGPipeRead.cpp
+++ b/src/pipe/SkGPipeRead.cpp
@@ -670,6 +670,10 @@ static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
UNIMPLEMENTED
}
+static void drawTextBlob_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
+ SkGPipeState* state) {
+ UNIMPLEMENTED
+}
///////////////////////////////////////////////////////////////////////////////
static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32,
@@ -814,6 +818,7 @@ static const ReadProc gReadTable[] = {
drawRRect_rp,
drawSprite_rp,
drawText_rp,
+ drawTextBlob_rp,
drawTextOnPath_rp,
drawVertices_rp,
restore_rp,
diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp
index 94a30a34e2..32af81d921 100644
--- a/src/pipe/SkGPipeWrite.cpp
+++ b/src/pipe/SkGPipeWrite.cpp
@@ -283,6 +283,8 @@ protected:
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 onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
const SkPoint texCoords[4], SkXfermode* xmode,
const SkPaint& paint) SK_OVERRIDE;
@@ -935,6 +937,13 @@ void SkGPipeCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const
}
}
+void SkGPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
+ const SkPaint& paint) {
+ // FIXME: blob serialization only supports SkWriteBuffers
+ // -- convert to SkWriter32 to avoid unrolling?
+ this->INHERITED::onDrawTextBlob(blob, x, y, paint);
+}
+
void SkGPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
const SkPaint* paint) {
// we want to playback the picture into individual draw calls
diff --git a/src/utils/SkDeferredCanvas.cpp b/src/utils/SkDeferredCanvas.cpp
index de3958adbc..cb69b4e282 100644
--- a/src/utils/SkDeferredCanvas.cpp
+++ b/src/utils/SkDeferredCanvas.cpp
@@ -901,6 +901,13 @@ void SkDeferredCanvas::onDrawTextOnPath(const void* text, size_t byteLength, con
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 661f0d8860..5e3d1535d9 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 @@ void SkDumpCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const S
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 9e9477596a..773af54dfd 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(SkPath)
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 @@ void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) {
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 0903ee8c89..8fe1aa2bbf 100644
--- a/src/utils/SkLuaCanvas.cpp
+++ b/src/utils/SkLuaCanvas.cpp
@@ -268,6 +268,15 @@ void SkLuaCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const Sk
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 d436bd4a6b..90fd017e1c 100644
--- a/src/utils/SkNWayCanvas.cpp
+++ b/src/utils/SkNWayCanvas.cpp
@@ -265,6 +265,14 @@ void SkNWayCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const S
}
}
+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 c15acaa78f..1677dafde2 100644
--- a/src/utils/SkProxyCanvas.cpp
+++ b/src/utils/SkProxyCanvas.cpp
@@ -136,6 +136,11 @@ void SkProxyCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const
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 228f25f737..2b0eab7f32 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -571,6 +571,11 @@ void SkDebugCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const
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 e4fb0d9588..94ad4263e5 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -242,6 +242,8 @@ protected:
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 26d2a85a8a..3cebca2c64 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 @@ void SkDrawPosTextHCommand::execute(SkCanvas* canvas) {
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 ce7b1f5f76..f3c8cca9de 100644
--- a/src/utils/debugger/SkDrawCommand.h
+++ b/src/utils/debugger/SkDrawCommand.h
@@ -436,6 +436,21 @@ private:
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);