#include "SkPictureFlat.h" #include "SkColorFilter.h" #include "SkDrawLooper.h" #include "SkMaskFilter.h" #include "SkRasterizer.h" #include "SkShader.h" #include "SkTypeface.h" #include "SkXfermode.h" SkFlatData* SkFlatData::Alloc(SkChunkAlloc* heap, int32_t size, int index) { SkFlatData* result = (SkFlatData*) heap->allocThrow(size + sizeof(SkFlatData)); result->fIndex = index; result->fAllocSize = size + sizeof(result->fAllocSize); return result; } SkFlatBitmap* SkFlatBitmap::Flatten(SkChunkAlloc* heap, const SkBitmap& bitmap, int index, SkRefCntRecorder* rec) { SkFlattenableWriteBuffer buffer(1024); buffer.setRefCntRecorder(rec); bitmap.flatten(buffer); size_t size = buffer.size(); SkFlatBitmap* result = (SkFlatBitmap*) INHERITED::Alloc(heap, size, index); buffer.flatten(result->fBitmapData); return result; } SkFlatMatrix* SkFlatMatrix::Flatten(SkChunkAlloc* heap, const SkMatrix& matrix, int index) { int32_t size = sizeof(SkMatrix); SkFlatMatrix* result = (SkFlatMatrix*) INHERITED::Alloc(heap, size, index); memcpy(&result->fMatrixData, &matrix, sizeof(SkMatrix)); return result; } #ifdef SK_DEBUG_DUMP void SkFlatMatrix::dump() const { const SkMatrix* matrix = (const SkMatrix*) fMatrixData; char pBuffer[DUMP_BUFFER_SIZE]; char* bufferPtr = pBuffer; bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "matrix: "); SkScalar scaleX = matrix->getScaleX(); SkMatrix defaultMatrix; defaultMatrix.reset(); if (scaleX != defaultMatrix.getScaleX()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "scaleX:%g ", SkScalarToFloat(scaleX)); SkScalar scaleY = matrix->getScaleY(); if (scaleY != defaultMatrix.getScaleY()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "scaleY:%g ", SkScalarToFloat(scaleY)); SkScalar skewX = matrix->getSkewX(); if (skewX != defaultMatrix.getSkewX()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "skewX:%g ", SkScalarToFloat(skewX)); SkScalar skewY = matrix->getSkewY(); if (skewY != defaultMatrix.getSkewY()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "skewY:%g ", SkScalarToFloat(skewY)); SkScalar translateX = matrix->getTranslateX(); if (translateX != defaultMatrix.getTranslateX()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "translateX:%g ", SkScalarToFloat(translateX)); SkScalar translateY = matrix->getTranslateY(); if (translateY != defaultMatrix.getTranslateY()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "translateY:%g ", SkScalarToFloat(translateY)); SkScalar perspX = matrix->getPerspX(); if (perspX != defaultMatrix.getPerspX()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "perspX:%g ", SkFractToFloat(perspX)); SkScalar perspY = matrix->getPerspY(); if (perspY != defaultMatrix.getPerspY()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "perspY:%g ", SkFractToFloat(perspY)); SkDebugf("%s\n", pBuffer); } #endif /////////////////////////////////////////////////////////////////////////////// SkFlatPaint* SkFlatPaint::Flatten(SkChunkAlloc* heap, const SkPaint& paint, int index, SkRefCntRecorder* rec, SkRefCntRecorder* faceRecorder) { SkFlattenableWriteBuffer buffer(2*sizeof(SkPaint)); buffer.setRefCntRecorder(rec); buffer.setTypefaceRecorder(faceRecorder); paint.flatten(buffer); uint32_t size = buffer.size(); SkFlatPaint* result = (SkFlatPaint*) INHERITED::Alloc(heap, size, index); buffer.flatten(&result->fPaintData); return result; } void SkFlatPaint::Read(const void* storage, SkPaint* paint, SkRefCntPlayback* rcp, SkTypefacePlayback* facePlayback) { SkFlattenableReadBuffer buffer(storage); if (rcp) { rcp->setupBuffer(buffer); } if (facePlayback) { facePlayback->setupBuffer(buffer); } paint->unflatten(buffer); } #ifdef SK_DEBUG_DUMP void SkFlatPaint::dump() const { SkPaint defaultPaint; SkFlattenableReadBuffer buffer(fPaintData); SkTypeface* typeface = (SkTypeface*) buffer.readPtr(); char pBuffer[DUMP_BUFFER_SIZE]; char* bufferPtr = pBuffer; bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "paint: "); if (typeface != defaultPaint.getTypeface()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "typeface:%p ", typeface); SkScalar textSize = buffer.readScalar(); if (textSize != defaultPaint.getTextSize()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "textSize:%g ", SkScalarToFloat(textSize)); SkScalar textScaleX = buffer.readScalar(); if (textScaleX != defaultPaint.getTextScaleX()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "textScaleX:%g ", SkScalarToFloat(textScaleX)); SkScalar textSkewX = buffer.readScalar(); if (textSkewX != defaultPaint.getTextSkewX()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "textSkewX:%g ", SkScalarToFloat(textSkewX)); const SkPathEffect* pathEffect = (const SkPathEffect*) buffer.readFlattenable(); if (pathEffect != defaultPaint.getPathEffect()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "pathEffect:%p ", pathEffect); SkDELETE(pathEffect); const SkShader* shader = (const SkShader*) buffer.readFlattenable(); if (shader != defaultPaint.getShader()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "shader:%p ", shader); SkDELETE(shader); const SkXfermode* xfermode = (const SkXfermode*) buffer.readFlattenable(); if (xfermode != defaultPaint.getXfermode()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "xfermode:%p ", xfermode); SkDELETE(xfermode); const SkMaskFilter* maskFilter = (const SkMaskFilter*) buffer.readFlattenable(); if (maskFilter != defaultPaint.getMaskFilter()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "maskFilter:%p ", maskFilter); SkDELETE(maskFilter); const SkColorFilter* colorFilter = (const SkColorFilter*) buffer.readFlattenable(); if (colorFilter != defaultPaint.getColorFilter()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "colorFilter:%p ", colorFilter); SkDELETE(colorFilter); const SkRasterizer* rasterizer = (const SkRasterizer*) buffer.readFlattenable(); if (rasterizer != defaultPaint.getRasterizer()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "rasterizer:%p ", rasterizer); SkDELETE(rasterizer); const SkDrawLooper* drawLooper = (const SkDrawLooper*) buffer.readFlattenable(); if (drawLooper != defaultPaint.getLooper()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "drawLooper:%p ", drawLooper); SkDELETE(drawLooper); unsigned color = buffer.readU32(); if (color != defaultPaint.getColor()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "color:0x%x ", color); SkScalar strokeWidth = buffer.readScalar(); if (strokeWidth != defaultPaint.getStrokeWidth()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "strokeWidth:%g ", SkScalarToFloat(strokeWidth)); SkScalar strokeMiter = buffer.readScalar(); if (strokeMiter != defaultPaint.getStrokeMiter()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "strokeMiter:%g ", SkScalarToFloat(strokeMiter)); unsigned flags = buffer.readU16(); if (flags != defaultPaint.getFlags()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "flags:0x%x ", flags); int align = buffer.readU8(); if (align != defaultPaint.getTextAlign()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "align:0x%x ", align); int strokeCap = buffer.readU8(); if (strokeCap != defaultPaint.getStrokeCap()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "strokeCap:0x%x ", strokeCap); int strokeJoin = buffer.readU8(); if (strokeJoin != defaultPaint.getStrokeJoin()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "align:0x%x ", strokeJoin); int style = buffer.readU8(); if (style != defaultPaint.getStyle()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "style:0x%x ", style); int textEncoding = buffer.readU8(); if (textEncoding != defaultPaint.getTextEncoding()) bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), "textEncoding:0x%x ", textEncoding); SkDebugf("%s\n", pBuffer); } #endif SkFlatRegion* SkFlatRegion::Flatten(SkChunkAlloc* heap, const SkRegion& region, int index) { uint32_t size = region.flatten(NULL); SkFlatRegion* result = (SkFlatRegion*) INHERITED::Alloc(heap, size, index); region.flatten(&result->fRegionData); return result; } /////////////////////////////////////////////////////////////////////////////// SkRefCntPlayback::SkRefCntPlayback() : fCount(0), fArray(NULL) {} SkRefCntPlayback::~SkRefCntPlayback() { this->reset(NULL); } void SkRefCntPlayback::reset(const SkRefCntRecorder* rec) { for (int i = 0; i < fCount; i++) { SkASSERT(fArray[i]); fArray[i]->unref(); } SkDELETE_ARRAY(fArray); if (rec) { fCount = rec->count(); fArray = SkNEW_ARRAY(SkRefCnt*, fCount); rec->get(fArray); for (int i = 0; i < fCount; i++) { fArray[i]->ref(); } } else { fCount = 0; fArray = NULL; } } void SkRefCntPlayback::setCount(int count) { this->reset(NULL); fCount = count; fArray = SkNEW_ARRAY(SkRefCnt*, count); bzero(fArray, count * sizeof(SkRefCnt*)); } SkRefCnt* SkRefCntPlayback::set(int index, SkRefCnt* obj) { SkASSERT((unsigned)index < (unsigned)fCount); SkRefCnt_SafeAssign(fArray[index], obj); return obj; }