1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "SkPictureFlat.h"
9
10#include "SkColorFilter.h"
11#include "SkDrawLooper.h"
12#include "SkMaskFilter.h"
13#include "SkRasterizer.h"
14#include "SkShader.h"
15#include "SkTypeface.h"
16#include "SkXfermode.h"
17
18SkFlatData* SkFlatData::Alloc(SkChunkAlloc* heap, int32_t size, int index) {
19    SkFlatData* result = (SkFlatData*) heap->allocThrow(size + sizeof(SkFlatData));
20    result->fIndex = index;
21    result->fAllocSize = size + sizeof(result->fAllocSize);
22    return result;
23}
24
25SkFlatBitmap* SkFlatBitmap::Flatten(SkChunkAlloc* heap, const SkBitmap& bitmap,
26                                    int index, SkRefCntSet* rec) {
27    SkFlattenableWriteBuffer buffer(1024);
28    buffer.setRefCntRecorder(rec);
29
30    bitmap.flatten(buffer);
31    size_t size = buffer.size();
32    SkFlatBitmap* result = (SkFlatBitmap*) INHERITED::Alloc(heap, size, index);
33    buffer.flatten(result->fBitmapData);
34    return result;
35}
36
37SkFlatMatrix* SkFlatMatrix::Flatten(SkChunkAlloc* heap, const SkMatrix& matrix, int index) {
38    size_t size = matrix.flatten(NULL);
39    SkFlatMatrix* result = (SkFlatMatrix*) INHERITED::Alloc(heap, size, index);
40    matrix.flatten(&result->fMatrixData);
41    return result;
42}
43
44#ifdef SK_DEBUG_DUMP
45void SkFlatMatrix::dump() const {
46    const SkMatrix* matrix = (const SkMatrix*) fMatrixData;
47    char pBuffer[DUMP_BUFFER_SIZE];
48    char* bufferPtr = pBuffer;
49    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
50    "matrix: ");
51    SkScalar scaleX = matrix->getScaleX();
52    SkMatrix defaultMatrix;
53    defaultMatrix.reset();
54    if (scaleX != defaultMatrix.getScaleX())
55        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
56            "scaleX:%g ", SkScalarToFloat(scaleX));
57    SkScalar scaleY = matrix->getScaleY();
58    if (scaleY != defaultMatrix.getScaleY())
59        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
60            "scaleY:%g ", SkScalarToFloat(scaleY));
61    SkScalar skewX = matrix->getSkewX();
62    if (skewX != defaultMatrix.getSkewX())
63        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
64            "skewX:%g ", SkScalarToFloat(skewX));
65    SkScalar skewY = matrix->getSkewY();
66    if (skewY != defaultMatrix.getSkewY())
67        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
68            "skewY:%g ", SkScalarToFloat(skewY));
69    SkScalar translateX = matrix->getTranslateX();
70    if (translateX != defaultMatrix.getTranslateX())
71        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
72            "translateX:%g ", SkScalarToFloat(translateX));
73    SkScalar translateY = matrix->getTranslateY();
74    if (translateY != defaultMatrix.getTranslateY())
75        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
76            "translateY:%g ", SkScalarToFloat(translateY));
77    SkScalar perspX = matrix->getPerspX();
78    if (perspX != defaultMatrix.getPerspX())
79        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
80            "perspX:%g ", SkFractToFloat(perspX));
81    SkScalar perspY = matrix->getPerspY();
82    if (perspY != defaultMatrix.getPerspY())
83        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
84            "perspY:%g ", SkFractToFloat(perspY));
85    SkDebugf("%s\n", pBuffer);
86}
87#endif
88
89///////////////////////////////////////////////////////////////////////////////
90
91SkFlatPaint* SkFlatPaint::Flatten(SkChunkAlloc* heap, const SkPaint& paint,
92                                  int index, SkRefCntSet* rec,
93                                  SkRefCntSet* faceRecorder) {
94    SkFlattenableWriteBuffer buffer(2*sizeof(SkPaint));
95    buffer.setRefCntRecorder(rec);
96    buffer.setTypefaceRecorder(faceRecorder);
97
98    paint.flatten(buffer);
99    uint32_t size = buffer.size();
100    SkFlatPaint* result = (SkFlatPaint*) INHERITED::Alloc(heap, size, index);
101    buffer.flatten(&result->fPaintData);
102    return result;
103}
104
105void SkFlatPaint::Read(const void* storage, SkPaint* paint,
106                   SkRefCntPlayback* rcp, SkTypefacePlayback* facePlayback) {
107    SkFlattenableReadBuffer buffer(storage);
108    if (rcp) {
109        rcp->setupBuffer(buffer);
110    }
111    if (facePlayback) {
112        facePlayback->setupBuffer(buffer);
113    }
114    paint->unflatten(buffer);
115}
116
117#ifdef SK_DEBUG_DUMP
118void SkFlatPaint::dump() const {
119    SkPaint defaultPaint;
120    SkFlattenableReadBuffer buffer(fPaintData);
121    SkTypeface* typeface = (SkTypeface*) buffer.readPtr();
122    char pBuffer[DUMP_BUFFER_SIZE];
123    char* bufferPtr = pBuffer;
124    bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
125        "paint: ");
126    if (typeface != defaultPaint.getTypeface())
127        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
128            "typeface:%p ", typeface);
129    SkScalar textSize = buffer.readScalar();
130    if (textSize != defaultPaint.getTextSize())
131        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
132            "textSize:%g ", SkScalarToFloat(textSize));
133    SkScalar textScaleX = buffer.readScalar();
134    if (textScaleX != defaultPaint.getTextScaleX())
135        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
136            "textScaleX:%g ", SkScalarToFloat(textScaleX));
137    SkScalar textSkewX = buffer.readScalar();
138    if (textSkewX != defaultPaint.getTextSkewX())
139        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
140            "textSkewX:%g ", SkScalarToFloat(textSkewX));
141    const SkPathEffect* pathEffect = (const SkPathEffect*) buffer.readFlattenable();
142    if (pathEffect != defaultPaint.getPathEffect())
143        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
144            "pathEffect:%p ", pathEffect);
145    SkDELETE(pathEffect);
146    const SkShader* shader = (const SkShader*) buffer.readFlattenable();
147    if (shader != defaultPaint.getShader())
148        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
149            "shader:%p ", shader);
150    SkDELETE(shader);
151    const SkXfermode* xfermode = (const SkXfermode*) buffer.readFlattenable();
152    if (xfermode != defaultPaint.getXfermode())
153        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
154            "xfermode:%p ", xfermode);
155    SkDELETE(xfermode);
156    const SkMaskFilter* maskFilter = (const SkMaskFilter*) buffer.readFlattenable();
157    if (maskFilter != defaultPaint.getMaskFilter())
158        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
159            "maskFilter:%p ", maskFilter);
160    SkDELETE(maskFilter);
161    const SkColorFilter* colorFilter = (const SkColorFilter*) buffer.readFlattenable();
162    if (colorFilter != defaultPaint.getColorFilter())
163        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
164            "colorFilter:%p ", colorFilter);
165    SkDELETE(colorFilter);
166    const SkRasterizer* rasterizer = (const SkRasterizer*) buffer.readFlattenable();
167    if (rasterizer != defaultPaint.getRasterizer())
168        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
169            "rasterizer:%p ", rasterizer);
170    SkDELETE(rasterizer);
171    const SkDrawLooper* drawLooper = (const SkDrawLooper*) buffer.readFlattenable();
172    if (drawLooper != defaultPaint.getLooper())
173        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
174            "drawLooper:%p ", drawLooper);
175    SkDELETE(drawLooper);
176    unsigned color = buffer.readU32();
177    if (color != defaultPaint.getColor())
178        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
179            "color:0x%x ", color);
180    SkScalar strokeWidth = buffer.readScalar();
181    if (strokeWidth != defaultPaint.getStrokeWidth())
182        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
183            "strokeWidth:%g ", SkScalarToFloat(strokeWidth));
184    SkScalar strokeMiter = buffer.readScalar();
185    if (strokeMiter != defaultPaint.getStrokeMiter())
186        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
187            "strokeMiter:%g ", SkScalarToFloat(strokeMiter));
188    unsigned flags = buffer.readU16();
189    if (flags != defaultPaint.getFlags())
190        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
191            "flags:0x%x ", flags);
192    int align = buffer.readU8();
193    if (align != defaultPaint.getTextAlign())
194        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
195            "align:0x%x ", align);
196    int strokeCap = buffer.readU8();
197    if (strokeCap != defaultPaint.getStrokeCap())
198        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
199            "strokeCap:0x%x ", strokeCap);
200    int strokeJoin = buffer.readU8();
201    if (strokeJoin != defaultPaint.getStrokeJoin())
202        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
203            "align:0x%x ", strokeJoin);
204    int style = buffer.readU8();
205    if (style != defaultPaint.getStyle())
206        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
207            "style:0x%x ", style);
208    int textEncoding = buffer.readU8();
209    if (textEncoding != defaultPaint.getTextEncoding())
210        bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
211            "textEncoding:0x%x ", textEncoding);
212    SkDebugf("%s\n", pBuffer);
213}
214#endif
215
216SkFlatRegion* SkFlatRegion::Flatten(SkChunkAlloc* heap, const SkRegion& region, int index) {
217    uint32_t size = region.flatten(NULL);
218    SkFlatRegion* result = (SkFlatRegion*) INHERITED::Alloc(heap, size, index);
219    region.flatten(&result->fRegionData);
220    return result;
221}
222
223///////////////////////////////////////////////////////////////////////////////
224
225SkRefCntPlayback::SkRefCntPlayback() : fCount(0), fArray(NULL) {}
226
227SkRefCntPlayback::~SkRefCntPlayback() {
228    this->reset(NULL);
229}
230
231void SkRefCntPlayback::reset(const SkRefCntSet* rec) {
232    for (int i = 0; i < fCount; i++) {
233        SkASSERT(fArray[i]);
234        fArray[i]->unref();
235    }
236    SkDELETE_ARRAY(fArray);
237
238    if (rec) {
239        fCount = rec->count();
240        fArray = SkNEW_ARRAY(SkRefCnt*, fCount);
241        rec->copyToArray(fArray);
242        for (int i = 0; i < fCount; i++) {
243            fArray[i]->ref();
244        }
245    } else {
246        fCount = 0;
247        fArray = NULL;
248    }
249}
250
251void SkRefCntPlayback::setCount(int count) {
252    this->reset(NULL);
253
254    fCount = count;
255    fArray = SkNEW_ARRAY(SkRefCnt*, count);
256    sk_bzero(fArray, count * sizeof(SkRefCnt*));
257}
258
259SkRefCnt* SkRefCntPlayback::set(int index, SkRefCnt* obj) {
260    SkASSERT((unsigned)index < (unsigned)fCount);
261    SkRefCnt_SafeAssign(fArray[index], obj);
262    return obj;
263}
264
265