blob: 10585269127eddad39ca40a3fb111850ac484f2c [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#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,
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000026 int index, SkRefCntSet* rec) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000027 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) {
senorblanco@chromium.org50108cd2011-05-24 20:25:32 +000038 size_t size = matrix.flatten(NULL);
reed@android.com8a1c16f2008-12-17 15:59:43 +000039 SkFlatMatrix* result = (SkFlatMatrix*) INHERITED::Alloc(heap, size, index);
senorblanco@chromium.org50108cd2011-05-24 20:25:32 +000040 matrix.flatten(&result->fMatrixData);
reed@android.com8a1c16f2008-12-17 15:59:43 +000041 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,
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +000092 int index, SkRefCntSet* rec,
93 SkRefCntSet* faceRecorder) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000094 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
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000231void SkRefCntPlayback::reset(const SkRefCntSet* rec) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000232 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);
mike@reedtribe.orge9e08cc2011-04-29 01:44:52 +0000241 rec->copyToArray(fArray);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000242 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);
reed@android.com4516f472009-06-29 16:25:36 +0000256 sk_bzero(fArray, count * sizeof(SkRefCnt*));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000257}
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