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