diff options
Diffstat (limited to 'skia/picture/SkPicturePlayback.cpp')
-rw-r--r-- | skia/picture/SkPicturePlayback.cpp | 1366 |
1 files changed, 1366 insertions, 0 deletions
diff --git a/skia/picture/SkPicturePlayback.cpp b/skia/picture/SkPicturePlayback.cpp new file mode 100644 index 0000000..3bf162e --- /dev/null +++ b/skia/picture/SkPicturePlayback.cpp @@ -0,0 +1,1366 @@ +#include "SkPicturePlayback.h" +#include "SkPictureRecord.h" +#include "SkTypeface.h" +#include <new> + +SkPicturePlayback::SkPicturePlayback() { + this->init(); +} + +SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record) { +#ifdef SK_DEBUG_SIZE + size_t overallBytes, bitmapBytes, matricesBytes, + paintBytes, pathBytes, pictureBytes, regionBytes; + int bitmaps = record.bitmaps(&bitmapBytes); + int matrices = record.matrices(&matricesBytes); + int paints = record.paints(&paintBytes); + int paths = record.paths(&pathBytes); + int pictures = record.pictures(&pictureBytes); + int regions = record.regions(®ionBytes); + SkDebugf("picture record mem used %zd (stream %zd) ", record.size(), + record.streamlen()); + if (bitmaps != 0) + SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps); + if (matrices != 0) + SkDebugf("matrices size %zd (matrices:%d) ", matricesBytes, matrices); + if (paints != 0) + SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints); + if (paths != 0) + SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths); + if (pictures != 0) + SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures); + if (regions != 0) + SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions); + if (record.fPointWrites != 0) + SkDebugf("points size %zd (points:%d) ", record.fPointBytes, record.fPointWrites); + if (record.fRectWrites != 0) + SkDebugf("rects size %zd (rects:%d) ", record.fRectBytes, record.fRectWrites); + if (record.fTextWrites != 0) + SkDebugf("text size %zd (text strings:%d) ", record.fTextBytes, record.fTextWrites); + + SkDebugf("\n"); +#endif +#ifdef SK_DEBUG_DUMP + record.dumpMatrices(); + record.dumpPaints(); +#endif + + record.validate(); + const SkWriter32& writer = record.writeStream(); + init(); + if (writer.size() == 0) + return; + + { + size_t size = writer.size(); + void* buffer = sk_malloc_throw(size); + writer.flatten(buffer); + fReader.setMemory(buffer, size); // fReader owns buffer now + } + + // copy over the refcnt dictionary to our reader + // + fRCPlayback.reset(&record.fRCRecorder); + fRCPlayback.setupBuffer(fReader); + + fTFPlayback.reset(&record.fTFRecorder); + fTFPlayback.setupBuffer(fReader); + + const SkTDArray<const SkFlatBitmap* >& bitmaps = record.getBitmaps(); + fBitmapCount = bitmaps.count(); + if (fBitmapCount > 0) { + fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount); + for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin(); + flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) { + const SkFlatBitmap* flatBitmap = *flatBitmapPtr; + int index = flatBitmap->index() - 1; + flatBitmap->unflatten(&fBitmaps[index], &fRCPlayback); + } + } + + const SkTDArray<const SkFlatMatrix* >& matrices = record.getMatrices(); + fMatrixCount = matrices.count(); + if (fMatrixCount > 0) { + fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount); + for (const SkFlatMatrix** matrixPtr = matrices.begin(); + matrixPtr != matrices.end(); matrixPtr++) { + const SkFlatMatrix* flatMatrix = *matrixPtr; + flatMatrix->unflatten(&fMatrices[flatMatrix->index() - 1]); + } + } + + const SkTDArray<const SkFlatPaint* >& paints = record.getPaints(); + fPaintCount = paints.count(); + if (fPaintCount > 0) { + fPaints = SkNEW_ARRAY(SkPaint, fPaintCount); + for (const SkFlatPaint** flatPaintPtr = paints.begin(); + flatPaintPtr != paints.end(); flatPaintPtr++) { + const SkFlatPaint* flatPaint = *flatPaintPtr; + int index = flatPaint->index() - 1; + SkASSERT((unsigned)index < (unsigned)fPaintCount); + flatPaint->unflatten(&fPaints[index], &fRCPlayback, &fTFPlayback); + } + } + + const SkTDArray<const SkFlatPath* >& paths = record.getPaths(); + fPathCount = paths.count(); + if (fPathCount > 0) { + fPaths = SkNEW_ARRAY(SkPath, fPathCount); + for (const SkFlatPath** flatPathPtr = paths.begin(); + flatPathPtr != paths.end(); flatPathPtr++) { + const SkFlatPath* flatPath = *flatPathPtr; + flatPath->unflatten(&fPaths[flatPath->index() - 1]); + } + } + + const SkTDArray<SkPicture* >& pictures = record.getPictureRefs(); + fPictureCount = pictures.count(); + if (fPictureCount > 0) { + fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount); + for (int i = 0; i < fPictureCount; i++) { + fPictureRefs[i] = pictures[i]; + fPictureRefs[i]->ref(); + } + } + + const SkTDArray<const SkFlatRegion* >& regions = record.getRegions(); + fRegionCount = regions.count(); + if (fRegionCount > 0) { + fRegions = SkNEW_ARRAY(SkRegion, fRegionCount); + for (const SkFlatRegion** flatRegionPtr = regions.begin(); + flatRegionPtr != regions.end(); flatRegionPtr++) { + const SkFlatRegion* flatRegion = *flatRegionPtr; + flatRegion->unflatten(&fRegions[flatRegion->index() - 1]); + } + } + +#ifdef SK_DEBUG_SIZE + int overall = fPlayback->size(&overallBytes); + bitmaps = fPlayback->bitmaps(&bitmapBytes); + paints = fPlayback->paints(&paintBytes); + paths = fPlayback->paths(&pathBytes); + pictures = fPlayback->pictures(&pictureBytes); + regions = fPlayback->regions(®ionBytes); + SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall); + if (bitmaps != 0) + SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps); + if (paints != 0) + SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints); + if (paths != 0) + SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths); + if (pictures != 0) + SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures); + if (regions != 0) + SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions); + SkDebugf("\n"); +#endif +} + +SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src) { + this->init(); + + // copy the data from fReader + { + size_t size = src.fReader.size(); + void* buffer = sk_malloc_throw(size); + memcpy(buffer, src.fReader.base(), size); + fReader.setMemory(buffer, size); + } + + int i; + + fBitmapCount = src.fBitmapCount; + fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount); + for (i = 0; i < fBitmapCount; i++) { + fBitmaps[i] = src.fBitmaps[i]; + } + + fMatrixCount = src.fMatrixCount; + fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount); + memcpy(fMatrices, src.fMatrices, fMatrixCount * sizeof(SkMatrix)); + + fPaintCount = src.fPaintCount; + fPaints = SkNEW_ARRAY(SkPaint, fPaintCount); + for (i = 0; i < fPaintCount; i++) { + fPaints[i] = src.fPaints[i]; + } + + fPathCount = src.fPathCount; + fPaths = SkNEW_ARRAY(SkPath, fPathCount); + for (i = 0; i < fPathCount; i++) { + fPaths[i] = src.fPaths[i]; + } + + fPictureCount = src.fPictureCount; + fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount); + for (int i = 0; i < fPictureCount; i++) { + fPictureRefs[i] = src.fPictureRefs[i]; + fPictureRefs[i]->ref(); + } + + fRegionCount = src.fRegionCount; + fRegions = SkNEW_ARRAY(SkRegion, fRegionCount); + for (i = 0; i < fRegionCount; i++) { + fRegions[i] = src.fRegions[i]; + } +} + +void SkPicturePlayback::init() { + fBitmaps = NULL; + fMatrices = NULL; + fPaints = NULL; + fPaths = NULL; + fPictureRefs = NULL; + fRegions = NULL; + fBitmapCount = fMatrixCount = fPaintCount = fPathCount = fPictureCount = + fRegionCount = 0; + + fFactoryPlayback = NULL; +} + +SkPicturePlayback::~SkPicturePlayback() { + sk_free((void*) fReader.base()); + + SkDELETE_ARRAY(fBitmaps); + SkDELETE_ARRAY(fMatrices); + SkDELETE_ARRAY(fPaints); + SkDELETE_ARRAY(fPaths); + SkDELETE_ARRAY(fRegions); + + for (int i = 0; i < fPictureCount; i++) { + fPictureRefs[i]->unref(); + } + SkDELETE_ARRAY(fPictureRefs); + + SkDELETE(fFactoryPlayback); +} + +void SkPicturePlayback::dumpSize() const { + SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] matrices=%d [%d] paints=%d [%d] paths=%d regions=%d\n", + fReader.size(), + fBitmapCount, fBitmapCount * sizeof(SkBitmap), + fMatrixCount, fMatrixCount * sizeof(SkMatrix), + fPaintCount, fPaintCount * sizeof(SkPaint), + fPathCount, + fRegionCount); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// The chunks are writte/read in this order... + +#define PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd') +#define PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't') +#define PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c') +#define PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r') +#define PICT_ARRAYS_TAG SkSetFourByteTag('a', 'r', 'a', 'y') +// these are all inside the ARRAYS tag +#define PICT_BITMAP_TAG SkSetFourByteTag('b', 't', 'm', 'p') +#define PICT_MATRIX_TAG SkSetFourByteTag('m', 't', 'r', 'x') +#define PICT_PAINT_TAG SkSetFourByteTag('p', 'n', 't', ' ') +#define PICT_PATH_TAG SkSetFourByteTag('p', 't', 'h', ' ') +#define PICT_REGION_TAG SkSetFourByteTag('r', 'g', 'n', ' ') + + +#include "SkStream.h" + +static void writeTagSize(SkFlattenableWriteBuffer& buffer, uint32_t tag, + uint32_t size) { + buffer.write32(tag); + buffer.write32(size); +} + +static void writeTagSize(SkWStream* stream, uint32_t tag, + uint32_t size) { + stream->write32(tag); + stream->write32(size); +} + +static void writeFactories(SkWStream* stream, const SkFactoryRecorder& rec) { + int count = rec.count(); + + writeTagSize(stream, PICT_FACTORY_TAG, count); + + SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count); + SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get(); + rec.get(array); + + for (int i = 0; i < count; i++) { + const char* name = SkFlattenable::FactoryToName(array[i]); +// SkDebugf("---- write factories [%d] %p <%s>\n", i, array[i], name); + if (NULL == name || 0 == *name) { + stream->writePackedUInt(0); + } else { + uint32_t len = strlen(name); + stream->writePackedUInt(len); + stream->write(name, len); + } + } +} + +static void writeTypefaces(SkWStream* stream, const SkRefCntRecorder& rec) { + int count = rec.count(); + + writeTagSize(stream, PICT_TYPEFACE_TAG, count); + + SkAutoSTMalloc<16, SkTypeface*> storage(count); + SkTypeface** array = (SkTypeface**)storage.get(); + rec.get((SkRefCnt**)array); + + for (int i = 0; i < count; i++) { + array[i]->serialize(stream); + } +} + +void SkPicturePlayback::serialize(SkWStream* stream) const { + writeTagSize(stream, PICT_READER_TAG, fReader.size()); + stream->write(fReader.base(), fReader.size()); + + SkRefCntRecorder typefaceRecorder; + SkFactoryRecorder factRecorder; + + SkFlattenableWriteBuffer buffer(1024); + + buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag); + buffer.setTypefaceRecorder(&typefaceRecorder); + buffer.setFactoryRecorder(&factRecorder); + + int i; + + writeTagSize(buffer, PICT_BITMAP_TAG, fBitmapCount); + for (i = 0; i < fBitmapCount; i++) { + fBitmaps[i].flatten(buffer); + } + + writeTagSize(buffer, PICT_MATRIX_TAG, fMatrixCount); + buffer.writeMul4(fMatrices, fMatrixCount * sizeof(SkMatrix)); + + writeTagSize(buffer, PICT_PAINT_TAG, fPaintCount); + for (i = 0; i < fPaintCount; i++) { + fPaints[i].flatten(buffer); + } + + writeTagSize(buffer, PICT_PATH_TAG, fPathCount); + for (i = 0; i < fPathCount; i++) { + fPaths[i].flatten(buffer); + } + + writeTagSize(buffer, PICT_REGION_TAG, fRegionCount); + for (i = 0; i < fRegionCount; i++) { + uint32_t size = fRegions[i].flatten(NULL); + buffer.write32(size); + SkAutoSMalloc<512> storage(size); + fRegions[i].flatten(storage.get()); + buffer.writePad(storage.get(), size); + } + + // now we can write to the stream again + + writeFactories(stream, factRecorder); + writeTypefaces(stream, typefaceRecorder); + + writeTagSize(stream, PICT_PICTURE_TAG, fPictureCount); + for (i = 0; i < fPictureCount; i++) { + fPictureRefs[i]->serialize(stream); + } + + writeTagSize(stream, PICT_ARRAYS_TAG, buffer.size()); + buffer.writeToStream(stream); +} + +/////////////////////////////////////////////////////////////////////////////// + +static int readTagSize(SkFlattenableReadBuffer& buffer, uint32_t expectedTag) { + uint32_t tag = buffer.readU32(); + if (tag != expectedTag) { + sk_throw(); + } + return buffer.readU32(); +} + +static int readTagSize(SkStream* stream, uint32_t expectedTag) { + uint32_t tag = stream->readU32(); + if (tag != expectedTag) { + sk_throw(); + } + return stream->readU32(); +} + +SkPicturePlayback::SkPicturePlayback(SkStream* stream) { + this->init(); + + int i; + + { + size_t size = readTagSize(stream, PICT_READER_TAG); + void* storage = sk_malloc_throw(size); + stream->read(storage, size); + fReader.setMemory(storage, size); + } + + int factoryCount = readTagSize(stream, PICT_FACTORY_TAG); + fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (factoryCount)); + for (i = 0; i < factoryCount; i++) { + SkString str; + int len = stream->readPackedUInt(); + str.resize(len); + stream->read(str.writable_str(), len); +// SkDebugf("--- factory playback [%d] <%s>\n", i, str.c_str()); + fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str()); + } + + int typefaceCount = readTagSize(stream, PICT_TYPEFACE_TAG); + fTFPlayback.setCount(typefaceCount); + for (i = 0; i < typefaceCount; i++) { + fTFPlayback.set(i, SkTypeface::Deserialize(stream))->unref(); + } + + fPictureCount = readTagSize(stream, PICT_PICTURE_TAG); + fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount); + for (i = 0; i < fPictureCount; i++) { + fPictureRefs[i] = SkNEW_ARGS(SkPicture, (stream)); + } + + /* + Now read the arrays chunk, and parse using a read buffer + */ + uint32_t size = readTagSize(stream, PICT_ARRAYS_TAG); + SkAutoMalloc storage(size); + stream->read(storage.get(), size); + + SkFlattenableReadBuffer buffer(storage.get(), size); + fFactoryPlayback->setupBuffer(buffer); + fTFPlayback.setupBuffer(buffer); + + fBitmapCount = readTagSize(buffer, PICT_BITMAP_TAG); + fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount); + for (i = 0; i < fBitmapCount; i++) { + fBitmaps[i].unflatten(buffer); + } + + fMatrixCount = readTagSize(buffer, PICT_MATRIX_TAG); + fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount); + buffer.read(fMatrices, fMatrixCount * sizeof(SkMatrix)); + + fPaintCount = readTagSize(buffer, PICT_PAINT_TAG); + fPaints = SkNEW_ARRAY(SkPaint, fPaintCount); + for (i = 0; i < fPaintCount; i++) { + fPaints[i].unflatten(buffer); + } + + fPathCount = readTagSize(buffer, PICT_PATH_TAG); + fPaths = SkNEW_ARRAY(SkPath, fPathCount); + for (i = 0; i < fPathCount; i++) { + fPaths[i].unflatten(buffer); + } + + fRegionCount = readTagSize(buffer, PICT_REGION_TAG); + fRegions = SkNEW_ARRAY(SkRegion, fRegionCount); + for (i = 0; i < fRegionCount; i++) { + uint32_t size = buffer.readU32(); + uint32_t bytes = fRegions[i].unflatten(buffer.skip(size)); + SkASSERT(size == bytes); + } +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +void SkPicturePlayback::draw(SkCanvas& canvas) { +#ifdef ENABLE_TIME_DRAW + SkAutoTime at("SkPicture::draw", 50); +#endif + + TextContainer text; + fReader.rewind(); + bool clipBoundsDirty = true; + SkRect clipBounds; + + while (!fReader.eof()) { + switch (fReader.readInt()) { + case CLIP_PATH: { + const SkPath& path = getPath(); + SkRegion::Op op = (SkRegion::Op) getInt(); + size_t offsetToRestore = getInt(); + // HACK (false) until I can handle op==kReplace <reed> + if (!canvas.clipPath(path, op) && false) { + //SkDebugf("---- skip clipPath for %d bytes\n", offsetToRestore - fReader.offset()); + fReader.setOffset(offsetToRestore); + } + clipBoundsDirty = true; + } break; + case CLIP_REGION: { + const SkRegion& region = getRegion(); + SkRegion::Op op = (SkRegion::Op) getInt(); + size_t offsetToRestore = getInt(); + if (!canvas.clipRegion(region, op)) { + //SkDebugf("---- skip clipDeviceRgn for %d bytes\n", offsetToRestore - fReader.offset()); + fReader.setOffset(offsetToRestore); + } + clipBoundsDirty = true; + } break; + case CLIP_RECT: { + const SkRect* rect = fReader.skipRect(); + SkRegion::Op op = (SkRegion::Op) getInt(); + size_t offsetToRestore = getInt(); + if (!canvas.clipRect(*rect, op)) { + //SkDebugf("---- skip clipRect for %d bytes\n", offsetToRestore - fReader.offset()); + fReader.setOffset(offsetToRestore); + } + clipBoundsDirty = true; + } break; + case CONCAT: + canvas.concat(*getMatrix()); + clipBoundsDirty = true; + break; + case DRAW_BITMAP: { + const SkPaint* paint = getPaint(); + const SkBitmap& bitmap = getBitmap(); + const SkPoint* loc = fReader.skipPoint(); + canvas.drawBitmap(bitmap, loc->fX, loc->fY, paint); + } break; + case DRAW_BITMAP_RECT: { + const SkPaint* paint = getPaint(); + const SkBitmap& bitmap = getBitmap(); + const SkIRect* src = this->getIRectPtr(); // may be null + const SkRect* dst = fReader.skipRect(); // required + canvas.drawBitmapRect(bitmap, src, *dst, paint); + } break; + case DRAW_BITMAP_MATRIX: { + const SkPaint* paint = getPaint(); + const SkBitmap& bitmap = getBitmap(); + const SkMatrix* matrix = getMatrix(); + canvas.drawBitmapMatrix(bitmap, *matrix, paint); + } break; + case DRAW_PAINT: + canvas.drawPaint(*getPaint()); + break; + case DRAW_PATH: { + const SkPaint& paint = *getPaint(); + const SkPath& path = getPath(); + canvas.drawPath(path, paint); + } break; + case DRAW_PICTURE: + canvas.drawPicture(getPicture()); + break; + case DRAW_POINTS: { + const SkPaint& paint = *getPaint(); + SkCanvas::PointMode mode = (SkCanvas::PointMode)getInt(); + size_t count = getInt(); + const SkPoint* pts = (const SkPoint*)fReader.skip(sizeof(SkPoint) * count); + canvas.drawPoints(mode, count, pts, paint); + } break; + case DRAW_POS_TEXT: { + const SkPaint& paint = *getPaint(); + getText(&text); + size_t points = getInt(); + const SkPoint* pos = (const SkPoint*)fReader.skip(points * sizeof(SkPoint)); + canvas.drawPosText(text.text(), text.length(), pos, paint); + } break; + case DRAW_POS_TEXT_H: { + const SkPaint& paint = *getPaint(); + getText(&text); + size_t points = getInt(); + size_t byteLength = text.length(); + const SkScalar* xpos = (const SkScalar*)fReader.skip((3 + points) * sizeof(SkScalar)); + const SkScalar top = *xpos++; + const SkScalar bottom = *xpos++; + const SkScalar constY = *xpos++; + // would be nice to do this before we load the other fields + // (especially the text block). To do that we'd need to record + // the number of bytes to skip... + if (clipBoundsDirty) { + if (!canvas.getClipBounds(&clipBounds)) { + clipBounds.setEmpty(); + } + clipBoundsDirty = false; + } + if (top < clipBounds.fBottom && bottom > clipBounds.fTop) { + canvas.drawPosTextH(text.text(), byteLength, xpos, constY, + paint); + } + } break; + case DRAW_RECT_GENERAL: { + const SkPaint& paint = *getPaint(); + canvas.drawRect(*fReader.skipRect(), paint); + } break; + case DRAW_RECT_SIMPLE: { + const SkPaint& paint = *getPaint(); + const SkRect* rect = fReader.skipRect(); + if (clipBoundsDirty) { + if (!canvas.getClipBounds(&clipBounds)) { + clipBounds.setEmpty(); + } + clipBoundsDirty = false; + } + if (SkRect::Intersects(clipBounds, *rect)) { + canvas.drawRect(*rect, paint); + } + } break; + case DRAW_SPRITE: { + const SkPaint* paint = getPaint(); + const SkBitmap& bitmap = getBitmap(); + int left = getInt(); + int top = getInt(); + canvas.drawSprite(bitmap, left, top, paint); + } break; + case DRAW_TEXT: { + const SkPaint& paint = *getPaint(); + getText(&text); + const SkScalar* ptr = (const SkScalar*)fReader.skip(4 * sizeof(SkScalar)); + // ptr[0] == x + // ptr[1] == y + // ptr[2] == top + // ptr[3] == bottom + if (clipBoundsDirty) { + if (!canvas.getClipBounds(&clipBounds)) { + clipBounds.setEmpty(); + } + clipBoundsDirty = false; + } + if (ptr[2] < clipBounds.fBottom && ptr[3] > clipBounds.fTop) { + canvas.drawText(text.text(), text.length(), ptr[0], ptr[1], + paint); + } + } break; + case DRAW_TEXT_ON_PATH: { + const SkPaint& paint = *getPaint(); + getText(&text); + const SkPath& path = getPath(); + const SkMatrix* matrix = getMatrix(); + canvas.drawTextOnPath(text.text(), text.length(), path, + matrix, paint); + } break; + case DRAW_VERTICES: { + const SkPaint& paint = *getPaint(); + DrawVertexFlags flags = (DrawVertexFlags)getInt(); + SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)getInt(); + int vCount = getInt(); + const SkPoint* verts = (const SkPoint*)fReader.skip( + vCount * sizeof(SkPoint)); + const SkPoint* texs = NULL; + const SkColor* colors = NULL; + const uint16_t* indices = NULL; + int iCount = 0; + if (flags & DRAW_VERTICES_HAS_TEXS) { + texs = (const SkPoint*)fReader.skip( + vCount * sizeof(SkPoint)); + } + if (flags & DRAW_VERTICES_HAS_COLORS) { + colors = (const SkColor*)fReader.skip( + vCount * sizeof(SkColor)); + } + if (flags & DRAW_VERTICES_HAS_INDICES) { + iCount = getInt(); + indices = (const uint16_t*)fReader.skip( + iCount * sizeof(uint16_t)); + } + canvas.drawVertices(vmode, vCount, verts, texs, colors, NULL, + indices, iCount, paint); + } break; + case RESTORE: + canvas.restore(); + clipBoundsDirty = true; + break; + case ROTATE: + canvas.rotate(getScalar()); + clipBoundsDirty = true; + break; + case SAVE: + canvas.save((SkCanvas::SaveFlags) getInt()); + break; + case SAVE_LAYER: { + const SkRect* boundsPtr = getRectPtr(); + const SkPaint* paint = getPaint(); + canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) getInt()); + } break; + case SCALE: { + SkScalar sx = getScalar(); + SkScalar sy = getScalar(); + canvas.scale(sx, sy); + clipBoundsDirty = true; + } break; + case SKEW: { + SkScalar sx = getScalar(); + SkScalar sy = getScalar(); + canvas.skew(sx, sy); + clipBoundsDirty = true; + } break; + case TRANSLATE: { + SkScalar dx = getScalar(); + SkScalar dy = getScalar(); + canvas.translate(dx, dy); + clipBoundsDirty = true; + } break; + default: + SkASSERT(0); + } + } + +// this->dumpSize(); +} + +/////////////////////////////////////////////////////////////////////////////// + +#if 0 +uint32_t SkPicturePlayback::flatten(void* storage) const { + SkWBuffer buffer(storage); + buffer.write32(fBitmapCount); + int index; + for (index = 0; index < fBitmapCount; index++) { + const SkBitmap& bitmap = fBitmaps[index]; + uint32_t size = bitmap.flatten(NULL, true); + buffer.write32(size); + void* local = buffer.skip(size); + bitmap.flatten(local, true); + } + buffer.write32(fPaintCount); + for (index = 0; index < fPaintCount; index++) { + SkFlattenableWriteBuffer flatWrite; + const SkPaint& paint = fPaints[index]; + SkFlatPaint::Write(&flatWrite, paint); + uint32_t size = flatWrite.pos(); + buffer.write32(size); + void* local = buffer.skip(size); + flatWrite.reset(local); + SkFlatPaint::Write(&flatWrite, paint); + } + buffer.write32(fPathCount); + for (index = 0; index < fPathCount; index++) { + const SkPath& path = fPaths[index]; + uint32_t size = path.flatten(NULL); + buffer.write32(size); + void* local = buffer.skip(size); + path.flatten(local); + } + +#if 0 + buffer.write32(fPictureCount); + for (index = 0; index < fPictureCount; index++) { + const SkPicture& picture = fPictures[index]; + uint32_t size = picture.flatten(NULL); + buffer.write32(size); + void* local = buffer.skip(size); + picture.flatten(local); + } +#endif + + buffer.write32(fRegionCount); + for (index = 0; index < fRegionCount; index++) { + const SkRegion& region = fRegions[index]; + size_t size = region.computeBufferSize(); + buffer.write32(size); + void* local = buffer.skip(size); + region.writeToBuffer(local); + } + fReader.rewind(); + size_t length = fReader.size(); + buffer.write32(length); + memcpy(buffer.skip(length), fReader.base(), length); + return (uint32_t) buffer.pos(); +} + +void SkPicturePlayback::unflatten(const void* storage) { + SkRBuffer buffer(storage); + int index; + fBitmapCount = buffer.readU32(); + fBitmaps = new SkBitmap[fBitmapCount]; + for (index = 0; index < fBitmapCount; index++) { + uint32_t size = buffer.readU32(); + const void* local = buffer.skip(size); + fBitmaps[index].unflatten(local); + } + fPaintCount = buffer.readU32(); + fPaints = new SkPaint[fPaintCount]; + for (index = 0; index < fPaintCount; index++) { + uint32_t size = buffer.readU32(); + const void* local = buffer.skip(size); + SkFlatPaint::Read(local, &fPaints[index]); + } + fPathCount = buffer.readU32(); + fPaths = new SkPath[fPathCount]; + for (index = 0; index < fPathCount; index++) { + uint32_t size = buffer.readU32(); + const void* local = buffer.skip(size); + fPaths[index].unflatten(local); + } + +#if 0 + fPictureCount = buffer.readU32(); + fPictures = new SkPicture[fPictureCount]; + for (index = 0; index < fPictureCount; index++) { + uint32_t size = buffer.readU32(); + const void* local = buffer.skip(size); + fPictures[index].unflatten(local); + } +#endif + + fRegionCount = buffer.readU32(); + fRegions = new SkRegion[fRegionCount]; + for (index = 0; index < fRegionCount; index++) { + uint32_t size = buffer.readU32(); + const void* local = buffer.skip(size); + fRegions[index].readFromBuffer(local); + } + int32_t length = buffer.readS32(); + const void* stream = buffer.skip(length); + fReader.setMemory(stream, length); +} +#endif + +/////////////////////////////////////////////////////////////////////////////// + +#ifdef SK_DEBUG_SIZE +int SkPicturePlayback::size(size_t* sizePtr) { + int objects = bitmaps(sizePtr); + objects += paints(sizePtr); + objects += paths(sizePtr); + objects += pictures(sizePtr); + objects += regions(sizePtr); + *sizePtr = fReader.size(); + return objects; +} + +int SkPicturePlayback::bitmaps(size_t* size) { + size_t result = 0; + for (int index = 0; index < fBitmapCount; index++) { + // const SkBitmap& bitmap = fBitmaps[index]; + result += sizeof(SkBitmap); // bitmap->size(); + } + *size = result; + return fBitmapCount; +} + +int SkPicturePlayback::paints(size_t* size) { + size_t result = 0; + for (int index = 0; index < fPaintCount; index++) { + // const SkPaint& paint = fPaints[index]; + result += sizeof(SkPaint); // paint->size(); + } + *size = result; + return fPaintCount; +} + +int SkPicturePlayback::paths(size_t* size) { + size_t result = 0; + for (int index = 0; index < fPathCount; index++) { + const SkPath& path = fPaths[index]; + result += path.flatten(NULL); + } + *size = result; + return fPathCount; +} + +int SkPicturePlayback::regions(size_t* size) { + size_t result = 0; + for (int index = 0; index < fRegionCount; index++) { + // const SkRegion& region = fRegions[index]; + result += sizeof(SkRegion); // region->size(); + } + *size = result; + return fRegionCount; +} +#endif + +#ifdef SK_DEBUG_DUMP +void SkPicturePlayback::dumpBitmap(const SkBitmap& bitmap) const { + char pBuffer[DUMP_BUFFER_SIZE]; + char* bufferPtr = pBuffer; + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "BitmapData bitmap%p = {", &bitmap); + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kWidth, %d}, ", bitmap.width()); + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kHeight, %d}, ", bitmap.height()); + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kRowBytes, %d}, ", bitmap.rowBytes()); +// start here; + SkDebugf("%s{0}};\n", pBuffer); +} + +void dumpMatrix(const SkMatrix& matrix) const { + SkMatrix defaultMatrix; + defaultMatrix.reset(); + char pBuffer[DUMP_BUFFER_SIZE]; + char* bufferPtr = pBuffer; + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "MatrixData matrix%p = {", &matrix); + SkScalar scaleX = matrix.getScaleX(); + if (scaleX != defaultMatrix.getScaleX()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kScaleX, %g}, ", SkScalarToFloat(scaleX)); + SkScalar scaleY = matrix.getScaleY(); + if (scaleY != defaultMatrix.getScaleY()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kScaleY, %g}, ", SkScalarToFloat(scaleY)); + SkScalar skewX = matrix.getSkewX(); + if (skewX != defaultMatrix.getSkewX()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kSkewX, %g}, ", SkScalarToFloat(skewX)); + SkScalar skewY = matrix.getSkewY(); + if (skewY != defaultMatrix.getSkewY()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kSkewY, %g}, ", SkScalarToFloat(skewY)); + SkScalar translateX = matrix.getTranslateX(); + if (translateX != defaultMatrix.getTranslateX()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kTranslateX, %g}, ", SkScalarToFloat(translateX)); + SkScalar translateY = matrix.getTranslateY(); + if (translateY != defaultMatrix.getTranslateY()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kTranslateY, %g}, ", SkScalarToFloat(translateY)); + SkScalar perspX = matrix.getPerspX(); + if (perspX != defaultMatrix.getPerspX()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kPerspX, %g}, ", SkFractToFloat(perspX)); + SkScalar perspY = matrix.getPerspY(); + if (perspY != defaultMatrix.getPerspY()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kPerspY, %g}, ", SkFractToFloat(perspY)); + SkDebugf("%s{0}};\n", pBuffer); +} + +void dumpPaint(const SkPaint& paint) const { + SkPaint defaultPaint; + char pBuffer[DUMP_BUFFER_SIZE]; + char* bufferPtr = pBuffer; + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "PaintPointers paintPtrs%p = {", &paint); + const SkTypeface* typeface = paint.getTypeface(); + if (typeface != defaultPaint.getTypeface()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kTypeface, %p}, ", typeface); + const SkPathEffect* pathEffect = paint.getPathEffect(); + if (pathEffect != defaultPaint.getPathEffect()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kPathEffect, %p}, ", pathEffect); + const SkShader* shader = paint.getShader(); + if (shader != defaultPaint.getShader()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kShader, %p}, ", shader); + const SkXfermode* xfermode = paint.getXfermode(); + if (xfermode != defaultPaint.getXfermode()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kXfermode, %p}, ", xfermode); + const SkMaskFilter* maskFilter = paint.getMaskFilter(); + if (maskFilter != defaultPaint.getMaskFilter()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kMaskFilter, %p}, ", maskFilter); + const SkColorFilter* colorFilter = paint.getColorFilter(); + if (colorFilter != defaultPaint.getColorFilter()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kColorFilter, %p}, ", colorFilter); + const SkRasterizer* rasterizer = paint.getRasterizer(); + if (rasterizer != defaultPaint.getRasterizer()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kRasterizer, %p}, ", rasterizer); + const SkDrawLooper* drawLooper = paint.getLooper(); + if (drawLooper != defaultPaint.getLooper()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kDrawLooper, %p}, ", drawLooper); + SkDebugf("%s{0}};\n", pBuffer); + bufferPtr = pBuffer; + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "PaintScalars paintScalars%p = {", &paint); + SkScalar textSize = paint.getTextSize(); + if (textSize != defaultPaint.getTextSize()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kTextSize, %g}, ", SkScalarToFloat(textSize)); + SkScalar textScaleX = paint.getTextScaleX(); + if (textScaleX != defaultPaint.getTextScaleX()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kTextScaleX, %g}, ", SkScalarToFloat(textScaleX)); + SkScalar textSkewX = paint.getTextSkewX(); + if (textSkewX != defaultPaint.getTextSkewX()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kTextSkewX, %g}, ", SkScalarToFloat(textSkewX)); + SkScalar strokeWidth = paint.getStrokeWidth(); + if (strokeWidth != defaultPaint.getStrokeWidth()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kStrokeWidth, %g}, ", SkScalarToFloat(strokeWidth)); + SkScalar strokeMiter = paint.getStrokeMiter(); + if (strokeMiter != defaultPaint.getStrokeMiter()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kStrokeMiter, %g}, ", SkScalarToFloat(strokeMiter)); + SkDebugf("%s{0}};\n", pBuffer); + bufferPtr = pBuffer; + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "PaintInts = paintInts%p = {", &paint); + unsigned color = paint.getColor(); + if (color != defaultPaint.getColor()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kColor, 0x%x}, ", color); + unsigned flags = paint.getFlags(); + if (flags != defaultPaint.getFlags()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kFlags, 0x%x}, ", flags); + int align = paint.getTextAlign(); + if (align != defaultPaint.getTextAlign()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kAlign, 0x%x}, ", align); + int strokeCap = paint.getStrokeCap(); + if (strokeCap != defaultPaint.getStrokeCap()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kStrokeCap, 0x%x}, ", strokeCap); + int strokeJoin = paint.getStrokeJoin(); + if (strokeJoin != defaultPaint.getStrokeJoin()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kAlign, 0x%x}, ", strokeJoin); + int style = paint.getStyle(); + if (style != defaultPaint.getStyle()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kStyle, 0x%x}, ", style); + int textEncoding = paint.getTextEncoding(); + if (textEncoding != defaultPaint.getTextEncoding()) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "{kTextEncoding, 0x%x}, ", textEncoding); + SkDebugf("%s{0}};\n", pBuffer); + + SkDebugf("PaintData paint%p = {paintPtrs%p, paintScalars%p, paintInts%p};\n", + &paint, &paint, &paint, &paint); +} + +void SkPicturePlayback::dumpPath(const SkPath& path) const { + SkDebugf("path dump unimplemented\n"); +} + +void SkPicturePlayback::dumpPicture(const SkPicture& picture) const { + SkDebugf("picture dump unimplemented\n"); +} + +void SkPicturePlayback::dumpRegion(const SkRegion& region) const { + SkDebugf("region dump unimplemented\n"); +} + +int SkPicturePlayback::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) { + return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "k%s, ", DrawTypeToString(drawType)); +} + +int SkPicturePlayback::dumpInt(char* bufferPtr, char* buffer, char* name) { + return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "%s:%d, ", name, getInt()); +} + +int SkPicturePlayback::dumpRect(char* bufferPtr, char* buffer, char* name) { + const SkRect* rect = fReader.skipRect(); + return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "%s:{l:%g t:%g r:%g b:%g}, ", name, SkScalarToFloat(rect.fLeft), + SkScalarToFloat(rect.fTop), + SkScalarToFloat(rect.fRight), SkScalarToFloat(rect.fBottom)); +} + +int SkPicturePlayback::dumpPoint(char* bufferPtr, char* buffer, char* name) { + SkPoint pt; + getPoint(&pt); + return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "%s:{x:%g y:%g}, ", name, SkScalarToFloat(pt.fX), + SkScalarToFloat(pt.fY)); +} + +void SkPicturePlayback::dumpPointArray(char** bufferPtrPtr, char* buffer, int count) { + char* bufferPtr = *bufferPtrPtr; + const SkPoint* pts = (const SkPoint*)fReadStream.getAtPos(); + fReadStream.skip(sizeof(SkPoint) * count); + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "count:%d {", count); + for (int index = 0; index < count; index++) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "{x:%g y:%g}, ", SkScalarToFloat(pts[index].fX), + SkScalarToFloat(pts[index].fY)); + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "} "); + *bufferPtrPtr = bufferPtr; +} + +int SkPicturePlayback::dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr) { + return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "%s:%p, ", name, ptr); +} + +int SkPicturePlayback::dumpRectPtr(char* bufferPtr, char* buffer, char* name) { + char result; + fReadStream.read(&result, sizeof(result)); + if (result) + return dumpRect(bufferPtr, buffer, name); + else + return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "%s:NULL, ", name); +} + +int SkPicturePlayback::dumpScalar(char* bufferPtr, char* buffer, char* name) { + return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), + "%s:%d, ", name, getScalar()); +} + +void SkPicturePlayback::dumpText(char** bufferPtrPtr, char* buffer) { + char* bufferPtr = *bufferPtrPtr; + int length = getInt(); + bufferPtr += dumpDrawType(bufferPtr, buffer); + fReadStream.skipToAlign4(); + char* text = (char*) fReadStream.getAtPos(); + fReadStream.skip(length); + bufferPtr += dumpInt(bufferPtr, buffer, "length"); + int limit = DUMP_BUFFER_SIZE - (bufferPtr - buffer) - 2; + length >>= 1; + if (limit > length) + limit = length; + if (limit > 0) { + *bufferPtr++ = '"'; + for (int index = 0; index < limit; index++) { + *bufferPtr++ = *(unsigned short*) text; + text += sizeof(unsigned short); + } + *bufferPtr++ = '"'; + } + *bufferPtrPtr = bufferPtr; +} + +#define DUMP_DRAWTYPE(drawType) \ + bufferPtr += dumpDrawType(bufferPtr, buffer, drawType) + +#define DUMP_INT(name) \ + bufferPtr += dumpInt(bufferPtr, buffer, #name) + +#define DUMP_RECT_PTR(name) \ + bufferPtr += dumpRectPtr(bufferPtr, buffer, #name) + +#define DUMP_POINT(name) \ + bufferPtr += dumpRect(bufferPtr, buffer, #name) + +#define DUMP_RECT(name) \ + bufferPtr += dumpRect(bufferPtr, buffer, #name) + +#define DUMP_POINT_ARRAY(count) \ + dumpPointArray(&bufferPtr, buffer, count) + +#define DUMP_PTR(name, ptr) \ + bufferPtr += dumpPtr(bufferPtr, buffer, #name, (void*) ptr) + +#define DUMP_SCALAR(name) \ + bufferPtr += dumpScalar(bufferPtr, buffer, #name) + +#define DUMP_TEXT() \ + dumpText(&bufferPtr, buffer) + +void SkPicturePlayback::dumpStream() { + SkDebugf("RecordStream stream = {\n"); + DrawType drawType; + TextContainer text; + fReadStream.rewind(); + char buffer[DUMP_BUFFER_SIZE], * bufferPtr; + while (fReadStream.read(&drawType, sizeof(drawType))) { + bufferPtr = buffer; + DUMP_DRAWTYPE(drawType); + switch (drawType) { + case CLIP_PATH: { + DUMP_PTR(SkPath, &getPath()); + DUMP_INT(SkRegion::Op); + DUMP_INT(offsetToRestore); + } break; + case CLIP_REGION: { + DUMP_PTR(SkRegion, &getRegion()); + DUMP_INT(SkRegion::Op); + DUMP_INT(offsetToRestore); + } break; + case CLIP_RECT: { + DUMP_RECT(rect); + DUMP_INT(SkRegion::Op); + DUMP_INT(offsetToRestore); + } break; + case CONCAT: + DUMP_PTR(SkMatrix, getMatrix()); + break; + case DRAW_BITMAP: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_PTR(SkBitmap, &getBitmap()); + DUMP_SCALAR(left); + DUMP_SCALAR(top); + } break; + case DRAW_PAINT: + DUMP_PTR(SkPaint, getPaint()); + break; + case DRAW_PATH: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_PTR(SkPath, &getPath()); + } break; + case DRAW_PICTURE: { + DUMP_PTR(SkPicture, &getPicture()); + } break; + case DRAW_POINTS: { + DUMP_PTR(SkPaint, getPaint()); + (void)getInt(); // PointMode + size_t count = getInt(); + fReadStream.skipToAlign4(); + DUMP_POINT_ARRAY(count); + } break; + case DRAW_POS_TEXT: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_TEXT(); + size_t points = getInt(); + fReadStream.skipToAlign4(); + DUMP_POINT_ARRAY(points); + } break; + case DRAW_POS_TEXT_H: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_TEXT(); + size_t points = getInt(); + fReadStream.skipToAlign4(); + DUMP_SCALAR(top); + DUMP_SCALAR(bottom); + DUMP_SCALAR(constY); + DUMP_POINT_ARRAY(points); + } break; + case DRAW_RECT_GENERAL: + case DRAW_RECT_SIMPLE: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_RECT(rect); + } break; + case DRAW_SPRITE: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_PTR(SkBitmap, &getBitmap()); + DUMP_SCALAR(left); + DUMP_SCALAR(top); + } break; + case DRAW_TEXT: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_TEXT(); + DUMP_SCALAR(x); + DUMP_SCALAR(y); + } break; + case DRAW_TEXT_ON_PATH: { + DUMP_PTR(SkPaint, getPaint()); + DUMP_TEXT(); + DUMP_PTR(SkPath, &getPath()); + DUMP_PTR(SkMatrix, getMatrix()); + } break; + case RESTORE: + break; + case ROTATE: + DUMP_SCALAR(rotate); + break; + case SAVE: + DUMP_INT(SkCanvas::SaveFlags); + break; + case SAVE_LAYER: { + DUMP_RECT_PTR(layer); + DUMP_PTR(SkPaint, getPaint()); + DUMP_INT(SkCanvas::SaveFlags); + } break; + case SCALE: { + DUMP_SCALAR(sx); + DUMP_SCALAR(sy); + } break; + case SKEW: { + DUMP_SCALAR(sx); + DUMP_SCALAR(sy); + } break; + case TRANSLATE: { + DUMP_SCALAR(dx); + DUMP_SCALAR(dy); + } break; + default: + SkASSERT(0); + } + SkDebugf("%s\n", buffer); + } +} + +void SkPicturePlayback::dump() const { + char pBuffer[DUMP_BUFFER_SIZE]; + char* bufferPtr = pBuffer; + int index; + if (fBitmapCount > 0) + SkDebugf("// bitmaps (%d)\n", fBitmapCount); + for (index = 0; index < fBitmapCount; index++) { + const SkBitmap& bitmap = fBitmaps[index]; + dumpBitmap(bitmap); + } + if (fBitmapCount > 0) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "Bitmaps bitmaps = {"); + for (index = 0; index < fBitmapCount; index++) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "bitmap%p, ", &fBitmaps[index]); + if (fBitmapCount > 0) + SkDebugf("%s0};\n", pBuffer); + + if (fMatrixCount > 0) + SkDebugf("// matrices (%d)\n", fMatrixCount); + for (index = 0; index < fMatrixCount; index++) { + const SkMatrix& matrix = fMatrices[index]; + dumpMatrix(matrix); + } + bufferPtr = pBuffer; + if (fMatrixCount > 0) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "Matrices matrices = {"); + for (index = 0; index < fMatrixCount; index++) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "matrix%p, ", &fMatrices[index]); + if (fMatrixCount > 0) + SkDebugf("%s0};\n", pBuffer); + + if (fPaintCount > 0) + SkDebugf("// paints (%d)\n", fPaintCount); + for (index = 0; index < fPaintCount; index++) { + const SkPaint& paint = fPaints[index]; + dumpPaint(paint); + } + bufferPtr = pBuffer; + if (fPaintCount > 0) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "Paints paints = {"); + for (index = 0; index < fPaintCount; index++) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "paint%p, ", &fPaints[index]); + if (fPaintCount > 0) + SkDebugf("%s0};\n", pBuffer); + + for (index = 0; index < fPathCount; index++) { + const SkPath& path = fPaths[index]; + dumpPath(path); + } + bufferPtr = pBuffer; + if (fPathCount > 0) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "Paths paths = {"); + for (index = 0; index < fPathCount; index++) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "path%p, ", &fPaths[index]); + if (fPathCount > 0) + SkDebugf("%s0};\n", pBuffer); + + for (index = 0; index < fPictureCount; index++) { + dumpPicture(*fPictureRefs[index]); + } + bufferPtr = pBuffer; + if (fPictureCount > 0) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "Pictures pictures = {"); + for (index = 0; index < fPictureCount; index++) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "picture%p, ", fPictureRefs[index]); + if (fPictureCount > 0) + SkDebugf("%s0};\n", pBuffer); + + for (index = 0; index < fRegionCount; index++) { + const SkRegion& region = fRegions[index]; + dumpRegion(region); + } + bufferPtr = pBuffer; + if (fRegionCount > 0) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "Regions regions = {"); + for (index = 0; index < fRegionCount; index++) + bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), + "region%p, ", &fRegions[index]); + if (fRegionCount > 0) + SkDebugf("%s0};\n", pBuffer); + + const_cast<SkPicturePlayback*>(this)->dumpStream(); +} + +#endif + |