diff options
author | fmalita <fmalita@chromium.org> | 2014-08-26 07:56:44 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-08-26 07:56:44 -0700 |
commit | b7425173f96e93b090787e2386ba5f022b6c2869 (patch) | |
tree | b73511cfeb4373c7a46a2507ada4274ca4b099e8 /src | |
parent | 3d2e50d1aa56d7f65a4c52fa03af4413fa4c616a (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.cpp | 16 | ||||
-rw-r--r-- | src/core/SkBBoxRecord.h | 2 | ||||
-rw-r--r-- | src/core/SkPictureData.cpp | 52 | ||||
-rw-r--r-- | src/core/SkPictureData.h | 16 | ||||
-rw-r--r-- | src/core/SkPictureFlat.h | 3 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 8 | ||||
-rw-r--r-- | src/core/SkPictureRecord.cpp | 33 | ||||
-rw-r--r-- | src/core/SkPictureRecord.h | 10 | ||||
-rw-r--r-- | src/core/SkRecorder.h | 2 | ||||
-rw-r--r-- | src/core/SkTextBlob.cpp | 87 | ||||
-rw-r--r-- | src/pipe/SkGPipePriv.h | 1 | ||||
-rw-r--r-- | src/pipe/SkGPipeRead.cpp | 5 | ||||
-rw-r--r-- | src/pipe/SkGPipeWrite.cpp | 9 | ||||
-rw-r--r-- | src/utils/SkDeferredCanvas.cpp | 7 | ||||
-rw-r--r-- | src/utils/SkDumpCanvas.cpp | 9 | ||||
-rw-r--r-- | src/utils/SkLua.cpp | 7 | ||||
-rw-r--r-- | src/utils/SkLuaCanvas.cpp | 9 | ||||
-rw-r--r-- | src/utils/SkNWayCanvas.cpp | 8 | ||||
-rw-r--r-- | src/utils/SkProxyCanvas.cpp | 5 | ||||
-rw-r--r-- | src/utils/debugger/SkDebugCanvas.cpp | 5 | ||||
-rw-r--r-- | src/utils/debugger/SkDebugCanvas.h | 2 | ||||
-rw-r--r-- | src/utils/debugger/SkDrawCommand.cpp | 22 | ||||
-rw-r--r-- | src/utils/debugger/SkDrawCommand.h | 15 |
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); |