1 #include "SkPicturePlayback.h"
2 #include "SkPictureRecord.h"
3 #include "SkTypeface.h"
4 #include <new>
5
6 /* Define this to spew out a debug statement whenever we skip the remainder of
7 a save/restore block because a clip... command returned false (empty).
8 */
9 #define SPEW_CLIP_SKIPPINGx
10
SkPicturePlayback()11 SkPicturePlayback::SkPicturePlayback() {
12 this->init();
13 }
14
SkPicturePlayback(const SkPictureRecord & record)15 SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record) {
16 #ifdef SK_DEBUG_SIZE
17 size_t overallBytes, bitmapBytes, matricesBytes,
18 paintBytes, pathBytes, pictureBytes, regionBytes;
19 int bitmaps = record.bitmaps(&bitmapBytes);
20 int matrices = record.matrices(&matricesBytes);
21 int paints = record.paints(&paintBytes);
22 int paths = record.paths(&pathBytes);
23 int pictures = record.pictures(&pictureBytes);
24 int regions = record.regions(®ionBytes);
25 SkDebugf("picture record mem used %zd (stream %zd) ", record.size(),
26 record.streamlen());
27 if (bitmaps != 0)
28 SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
29 if (matrices != 0)
30 SkDebugf("matrices size %zd (matrices:%d) ", matricesBytes, matrices);
31 if (paints != 0)
32 SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
33 if (paths != 0)
34 SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
35 if (pictures != 0)
36 SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
37 if (regions != 0)
38 SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
39 if (record.fPointWrites != 0)
40 SkDebugf("points size %zd (points:%d) ", record.fPointBytes, record.fPointWrites);
41 if (record.fRectWrites != 0)
42 SkDebugf("rects size %zd (rects:%d) ", record.fRectBytes, record.fRectWrites);
43 if (record.fTextWrites != 0)
44 SkDebugf("text size %zd (text strings:%d) ", record.fTextBytes, record.fTextWrites);
45
46 SkDebugf("\n");
47 #endif
48 #ifdef SK_DEBUG_DUMP
49 record.dumpMatrices();
50 record.dumpPaints();
51 #endif
52
53 record.validate();
54 const SkWriter32& writer = record.writeStream();
55 init();
56 if (writer.size() == 0)
57 return;
58
59 {
60 size_t size = writer.size();
61 void* buffer = sk_malloc_throw(size);
62 writer.flatten(buffer);
63 fReader.setMemory(buffer, size); // fReader owns buffer now
64 }
65
66 // copy over the refcnt dictionary to our reader
67 //
68 fRCPlayback.reset(&record.fRCRecorder);
69 fRCPlayback.setupBuffer(fReader);
70
71 fTFPlayback.reset(&record.fTFRecorder);
72 fTFPlayback.setupBuffer(fReader);
73
74 const SkTDArray<const SkFlatBitmap* >& bitmaps = record.getBitmaps();
75 fBitmapCount = bitmaps.count();
76 if (fBitmapCount > 0) {
77 fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount);
78 for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin();
79 flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) {
80 const SkFlatBitmap* flatBitmap = *flatBitmapPtr;
81 int index = flatBitmap->index() - 1;
82 flatBitmap->unflatten(&fBitmaps[index], &fRCPlayback);
83 }
84 }
85
86 const SkTDArray<const SkFlatMatrix* >& matrices = record.getMatrices();
87 fMatrixCount = matrices.count();
88 if (fMatrixCount > 0) {
89 fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount);
90 for (const SkFlatMatrix** matrixPtr = matrices.begin();
91 matrixPtr != matrices.end(); matrixPtr++) {
92 const SkFlatMatrix* flatMatrix = *matrixPtr;
93 flatMatrix->unflatten(&fMatrices[flatMatrix->index() - 1]);
94 }
95 }
96
97 const SkTDArray<const SkFlatPaint* >& paints = record.getPaints();
98 fPaintCount = paints.count();
99 if (fPaintCount > 0) {
100 fPaints = SkNEW_ARRAY(SkPaint, fPaintCount);
101 for (const SkFlatPaint** flatPaintPtr = paints.begin();
102 flatPaintPtr != paints.end(); flatPaintPtr++) {
103 const SkFlatPaint* flatPaint = *flatPaintPtr;
104 int index = flatPaint->index() - 1;
105 SkASSERT((unsigned)index < (unsigned)fPaintCount);
106 flatPaint->unflatten(&fPaints[index], &fRCPlayback, &fTFPlayback);
107 }
108 }
109
110 fPathHeap = record.fPathHeap;
111 fPathHeap->safeRef();
112
113 const SkTDArray<SkPicture* >& pictures = record.getPictureRefs();
114 fPictureCount = pictures.count();
115 if (fPictureCount > 0) {
116 fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
117 for (int i = 0; i < fPictureCount; i++) {
118 fPictureRefs[i] = pictures[i];
119 fPictureRefs[i]->ref();
120 }
121 }
122
123 const SkTDArray<SkShape* >& shapes = record.getShapes();
124 fShapeCount = shapes.count();
125 if (fShapeCount > 0) {
126 fShapes = SkNEW_ARRAY(SkShape*, fShapeCount);
127 for (int i = 0; i < fShapeCount; i++) {
128 SkShape* s = shapes[i];
129 SkSafeRef(s);
130 fShapes[i] = s;
131 }
132 }
133
134 const SkTDArray<const SkFlatRegion* >& regions = record.getRegions();
135 fRegionCount = regions.count();
136 if (fRegionCount > 0) {
137 fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
138 for (const SkFlatRegion** flatRegionPtr = regions.begin();
139 flatRegionPtr != regions.end(); flatRegionPtr++) {
140 const SkFlatRegion* flatRegion = *flatRegionPtr;
141 flatRegion->unflatten(&fRegions[flatRegion->index() - 1]);
142 }
143 }
144
145 #ifdef SK_DEBUG_SIZE
146 int overall = fPlayback->size(&overallBytes);
147 bitmaps = fPlayback->bitmaps(&bitmapBytes);
148 paints = fPlayback->paints(&paintBytes);
149 paths = fPlayback->paths(&pathBytes);
150 pictures = fPlayback->pictures(&pictureBytes);
151 regions = fPlayback->regions(®ionBytes);
152 SkDebugf("playback size %zd (objects:%d) ", overallBytes, overall);
153 if (bitmaps != 0)
154 SkDebugf("bitmaps size %zd (bitmaps:%d) ", bitmapBytes, bitmaps);
155 if (paints != 0)
156 SkDebugf("paints size %zd (paints:%d) ", paintBytes, paints);
157 if (paths != 0)
158 SkDebugf("paths size %zd (paths:%d) ", pathBytes, paths);
159 if (pictures != 0)
160 SkDebugf("pictures size %zd (pictures:%d) ", pictureBytes, pictures);
161 if (regions != 0)
162 SkDebugf("regions size %zd (regions:%d) ", regionBytes, regions);
163 SkDebugf("\n");
164 #endif
165 }
166
SkPicturePlayback(const SkPicturePlayback & src)167 SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src) {
168 this->init();
169
170 // copy the data from fReader
171 {
172 size_t size = src.fReader.size();
173 void* buffer = sk_malloc_throw(size);
174 memcpy(buffer, src.fReader.base(), size);
175 fReader.setMemory(buffer, size);
176 }
177
178 int i;
179
180 fBitmapCount = src.fBitmapCount;
181 fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount);
182 for (i = 0; i < fBitmapCount; i++) {
183 fBitmaps[i] = src.fBitmaps[i];
184 }
185
186 fMatrixCount = src.fMatrixCount;
187 fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount);
188 memcpy(fMatrices, src.fMatrices, fMatrixCount * sizeof(SkMatrix));
189
190 fPaintCount = src.fPaintCount;
191 fPaints = SkNEW_ARRAY(SkPaint, fPaintCount);
192 for (i = 0; i < fPaintCount; i++) {
193 fPaints[i] = src.fPaints[i];
194 }
195
196 fPathHeap = src.fPathHeap;
197 fPathHeap->safeRef();
198
199 fPictureCount = src.fPictureCount;
200 fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
201 for (int i = 0; i < fPictureCount; i++) {
202 fPictureRefs[i] = src.fPictureRefs[i];
203 fPictureRefs[i]->ref();
204 }
205
206 fShapeCount = src.fShapeCount;
207 fShapes = SkNEW_ARRAY(SkShape*, fShapeCount);
208 for (int i = 0; i < fShapeCount; i++) {
209 SkShape* s = src.fShapes[i];
210 SkSafeRef(s);
211 fShapes[i] = s;
212 }
213
214 fRegionCount = src.fRegionCount;
215 fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
216 for (i = 0; i < fRegionCount; i++) {
217 fRegions[i] = src.fRegions[i];
218 }
219 }
220
init()221 void SkPicturePlayback::init() {
222 fBitmaps = NULL;
223 fMatrices = NULL;
224 fPaints = NULL;
225 fPathHeap = NULL;
226 fPictureRefs = NULL;
227 fShapes = NULL;
228 fRegions = NULL;
229 fBitmapCount = fMatrixCount = fPaintCount = fPictureCount =
230 fRegionCount = fShapeCount = 0;
231
232 fFactoryPlayback = NULL;
233 }
234
~SkPicturePlayback()235 SkPicturePlayback::~SkPicturePlayback() {
236 sk_free((void*) fReader.base());
237
238 SkDELETE_ARRAY(fBitmaps);
239 SkDELETE_ARRAY(fMatrices);
240 SkDELETE_ARRAY(fPaints);
241 SkDELETE_ARRAY(fRegions);
242
243 fPathHeap->safeUnref();
244
245 for (int i = 0; i < fPictureCount; i++) {
246 fPictureRefs[i]->unref();
247 }
248 SkDELETE_ARRAY(fPictureRefs);
249
250 for (int i = 0; i < fShapeCount; i++) {
251 SkSafeUnref(fShapes[i]);
252 }
253 SkDELETE_ARRAY(fShapes);
254
255 SkDELETE(fFactoryPlayback);
256 }
257
dumpSize() const258 void SkPicturePlayback::dumpSize() const {
259 SkDebugf("--- picture size: ops=%d bitmaps=%d [%d] matrices=%d [%d] paints=%d [%d] paths=%d regions=%d\n",
260 fReader.size(),
261 fBitmapCount, fBitmapCount * sizeof(SkBitmap),
262 fMatrixCount, fMatrixCount * sizeof(SkMatrix),
263 fPaintCount, fPaintCount * sizeof(SkPaint),
264 fPathHeap ? fPathHeap->count() : 0,
265 fRegionCount);
266 }
267
268 ///////////////////////////////////////////////////////////////////////////////
269 ///////////////////////////////////////////////////////////////////////////////
270
271 // The chunks are writte/read in this order...
272
273 #define PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd')
274 #define PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't')
275 #define PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c')
276 #define PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r')
277 #define PICT_ARRAYS_TAG SkSetFourByteTag('a', 'r', 'a', 'y')
278 // these are all inside the ARRAYS tag
279 #define PICT_BITMAP_TAG SkSetFourByteTag('b', 't', 'm', 'p')
280 #define PICT_MATRIX_TAG SkSetFourByteTag('m', 't', 'r', 'x')
281 #define PICT_PAINT_TAG SkSetFourByteTag('p', 'n', 't', ' ')
282 #define PICT_PATH_TAG SkSetFourByteTag('p', 't', 'h', ' ')
283 #define PICT_REGION_TAG SkSetFourByteTag('r', 'g', 'n', ' ')
284 #define PICT_SHAPE_TAG SkSetFourByteTag('s', 'h', 'p', ' ')
285
286 #include "SkStream.h"
287
writeTagSize(SkFlattenableWriteBuffer & buffer,uint32_t tag,uint32_t size)288 static void writeTagSize(SkFlattenableWriteBuffer& buffer, uint32_t tag,
289 uint32_t size) {
290 buffer.write32(tag);
291 buffer.write32(size);
292 }
293
writeTagSize(SkWStream * stream,uint32_t tag,uint32_t size)294 static void writeTagSize(SkWStream* stream, uint32_t tag,
295 uint32_t size) {
296 stream->write32(tag);
297 stream->write32(size);
298 }
299
writeFactories(SkWStream * stream,const SkFactoryRecorder & rec)300 static void writeFactories(SkWStream* stream, const SkFactoryRecorder& rec) {
301 int count = rec.count();
302
303 writeTagSize(stream, PICT_FACTORY_TAG, count);
304
305 SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count);
306 SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get();
307 rec.get(array);
308
309 for (int i = 0; i < count; i++) {
310 const char* name = SkFlattenable::FactoryToName(array[i]);
311 // SkDebugf("---- write factories [%d] %p <%s>\n", i, array[i], name);
312 if (NULL == name || 0 == *name) {
313 stream->writePackedUInt(0);
314 } else {
315 uint32_t len = strlen(name);
316 stream->writePackedUInt(len);
317 stream->write(name, len);
318 }
319 }
320 }
321
writeTypefaces(SkWStream * stream,const SkRefCntRecorder & rec)322 static void writeTypefaces(SkWStream* stream, const SkRefCntRecorder& rec) {
323 int count = rec.count();
324
325 writeTagSize(stream, PICT_TYPEFACE_TAG, count);
326
327 SkAutoSTMalloc<16, SkTypeface*> storage(count);
328 SkTypeface** array = (SkTypeface**)storage.get();
329 rec.get((SkRefCnt**)array);
330
331 for (int i = 0; i < count; i++) {
332 array[i]->serialize(stream);
333 }
334 }
335
serialize(SkWStream * stream) const336 void SkPicturePlayback::serialize(SkWStream* stream) const {
337 writeTagSize(stream, PICT_READER_TAG, fReader.size());
338 stream->write(fReader.base(), fReader.size());
339
340 SkRefCntRecorder typefaceRecorder;
341 SkFactoryRecorder factRecorder;
342
343 SkFlattenableWriteBuffer buffer(1024);
344
345 buffer.setFlags(SkFlattenableWriteBuffer::kCrossProcess_Flag);
346 buffer.setTypefaceRecorder(&typefaceRecorder);
347 buffer.setFactoryRecorder(&factRecorder);
348
349 int i;
350
351 writeTagSize(buffer, PICT_BITMAP_TAG, fBitmapCount);
352 for (i = 0; i < fBitmapCount; i++) {
353 fBitmaps[i].flatten(buffer);
354 }
355
356 writeTagSize(buffer, PICT_MATRIX_TAG, fMatrixCount);
357 buffer.writeMul4(fMatrices, fMatrixCount * sizeof(SkMatrix));
358
359 writeTagSize(buffer, PICT_PAINT_TAG, fPaintCount);
360 for (i = 0; i < fPaintCount; i++) {
361 fPaints[i].flatten(buffer);
362 }
363
364 {
365 int count = fPathHeap ? fPathHeap->count() : 0;
366 writeTagSize(buffer, PICT_PATH_TAG, count);
367 if (count > 0) {
368 fPathHeap->flatten(buffer);
369 }
370 }
371
372 writeTagSize(buffer, PICT_REGION_TAG, fRegionCount);
373 for (i = 0; i < fRegionCount; i++) {
374 uint32_t size = fRegions[i].flatten(NULL);
375 buffer.write32(size);
376 SkAutoSMalloc<512> storage(size);
377 fRegions[i].flatten(storage.get());
378 buffer.writePad(storage.get(), size);
379 }
380
381 writeTagSize(buffer, PICT_SHAPE_TAG, fShapeCount);
382 for (i = 0; i < fShapeCount; i++) {
383 buffer.writeFlattenable(fShapes[i]);
384 }
385
386 // now we can write to the stream again
387
388 writeFactories(stream, factRecorder);
389 writeTypefaces(stream, typefaceRecorder);
390
391 writeTagSize(stream, PICT_PICTURE_TAG, fPictureCount);
392 for (i = 0; i < fPictureCount; i++) {
393 fPictureRefs[i]->serialize(stream);
394 }
395
396 writeTagSize(stream, PICT_ARRAYS_TAG, buffer.size());
397 buffer.writeToStream(stream);
398 }
399
400 ///////////////////////////////////////////////////////////////////////////////
401
readTagSize(SkFlattenableReadBuffer & buffer,uint32_t expectedTag)402 static int readTagSize(SkFlattenableReadBuffer& buffer, uint32_t expectedTag) {
403 uint32_t tag = buffer.readU32();
404 if (tag != expectedTag) {
405 sk_throw();
406 }
407 return buffer.readU32();
408 }
409
readTagSize(SkStream * stream,uint32_t expectedTag)410 static int readTagSize(SkStream* stream, uint32_t expectedTag) {
411 uint32_t tag = stream->readU32();
412 if (tag != expectedTag) {
413 sk_throw();
414 }
415 return stream->readU32();
416 }
417
SkPicturePlayback(SkStream * stream)418 SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
419 this->init();
420
421 int i;
422
423 {
424 size_t size = readTagSize(stream, PICT_READER_TAG);
425 void* storage = sk_malloc_throw(size);
426 stream->read(storage, size);
427 fReader.setMemory(storage, size);
428 }
429
430 int factoryCount = readTagSize(stream, PICT_FACTORY_TAG);
431 fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (factoryCount));
432 for (i = 0; i < factoryCount; i++) {
433 SkString str;
434 int len = stream->readPackedUInt();
435 str.resize(len);
436 stream->read(str.writable_str(), len);
437 // SkDebugf("--- factory playback [%d] <%s>\n", i, str.c_str());
438 fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str());
439 }
440
441 int typefaceCount = readTagSize(stream, PICT_TYPEFACE_TAG);
442 fTFPlayback.setCount(typefaceCount);
443 for (i = 0; i < typefaceCount; i++) {
444 fTFPlayback.set(i, SkTypeface::Deserialize(stream))->unref();
445 }
446
447 fPictureCount = readTagSize(stream, PICT_PICTURE_TAG);
448 fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
449 for (i = 0; i < fPictureCount; i++) {
450 fPictureRefs[i] = SkNEW_ARGS(SkPicture, (stream));
451 }
452
453 /*
454 Now read the arrays chunk, and parse using a read buffer
455 */
456 uint32_t size = readTagSize(stream, PICT_ARRAYS_TAG);
457 SkAutoMalloc storage(size);
458 stream->read(storage.get(), size);
459
460 SkFlattenableReadBuffer buffer(storage.get(), size);
461 fFactoryPlayback->setupBuffer(buffer);
462 fTFPlayback.setupBuffer(buffer);
463
464 fBitmapCount = readTagSize(buffer, PICT_BITMAP_TAG);
465 fBitmaps = SkNEW_ARRAY(SkBitmap, fBitmapCount);
466 for (i = 0; i < fBitmapCount; i++) {
467 fBitmaps[i].unflatten(buffer);
468 }
469
470 fMatrixCount = readTagSize(buffer, PICT_MATRIX_TAG);
471 fMatrices = SkNEW_ARRAY(SkMatrix, fMatrixCount);
472 buffer.read(fMatrices, fMatrixCount * sizeof(SkMatrix));
473
474 fPaintCount = readTagSize(buffer, PICT_PAINT_TAG);
475 fPaints = SkNEW_ARRAY(SkPaint, fPaintCount);
476 for (i = 0; i < fPaintCount; i++) {
477 fPaints[i].unflatten(buffer);
478 }
479
480 {
481 int count = readTagSize(buffer, PICT_PATH_TAG);
482 if (count > 0) {
483 fPathHeap = SkNEW_ARGS(SkPathHeap, (buffer));
484 }
485 }
486
487 fRegionCount = readTagSize(buffer, PICT_REGION_TAG);
488 fRegions = SkNEW_ARRAY(SkRegion, fRegionCount);
489 for (i = 0; i < fRegionCount; i++) {
490 uint32_t size = buffer.readU32();
491 SkDEBUGCODE(uint32_t bytes =) fRegions[i].unflatten(buffer.skip(size));
492 SkASSERT(size == bytes);
493 }
494
495 fShapeCount = readTagSize(buffer, PICT_SHAPE_TAG);
496 fShapes = SkNEW_ARRAY(SkShape*, fShapeCount);
497 for (i = 0; i < fShapeCount; i++) {
498 fShapes[i] = reinterpret_cast<SkShape*>(buffer.readFlattenable());
499 }
500 }
501
502 ///////////////////////////////////////////////////////////////////////////////
503 ///////////////////////////////////////////////////////////////////////////////
504
505 #ifdef SPEW_CLIP_SKIPPING
506 struct SkipClipRec {
507 int fCount;
508 size_t fSize;
509
SkipClipRecSkipClipRec510 SkipClipRec() {
511 fCount = 0;
512 fSize = 0;
513 }
514
recordSkipSkipClipRec515 void recordSkip(size_t bytes) {
516 fCount += 1;
517 fSize += bytes;
518 }
519 };
520 #endif
521
draw(SkCanvas & canvas)522 void SkPicturePlayback::draw(SkCanvas& canvas) {
523 #ifdef ENABLE_TIME_DRAW
524 SkAutoTime at("SkPicture::draw", 50);
525 #endif
526
527 #ifdef SPEW_CLIP_SKIPPING
528 SkipClipRec skipRect, skipRegion, skipPath;
529 #endif
530
531 TextContainer text;
532 fReader.rewind();
533
534 while (!fReader.eof()) {
535 switch (fReader.readInt()) {
536 case CLIP_PATH: {
537 const SkPath& path = getPath();
538 SkRegion::Op op = (SkRegion::Op) getInt();
539 size_t offsetToRestore = getInt();
540 // HACK (false) until I can handle op==kReplace
541 if (!canvas.clipPath(path, op)) {
542 #ifdef SPEW_CLIP_SKIPPING
543 skipPath.recordSkip(offsetToRestore - fReader.offset());
544 #endif
545 fReader.setOffset(offsetToRestore);
546 }
547 } break;
548 case CLIP_REGION: {
549 const SkRegion& region = getRegion();
550 SkRegion::Op op = (SkRegion::Op) getInt();
551 size_t offsetToRestore = getInt();
552 if (!canvas.clipRegion(region, op)) {
553 #ifdef SPEW_CLIP_SKIPPING
554 skipRegion.recordSkip(offsetToRestore - fReader.offset());
555 #endif
556 fReader.setOffset(offsetToRestore);
557 }
558 } break;
559 case CLIP_RECT: {
560 const SkRect* rect = fReader.skipRect();
561 SkRegion::Op op = (SkRegion::Op) getInt();
562 size_t offsetToRestore = getInt();
563 if (!canvas.clipRect(*rect, op)) {
564 #ifdef SPEW_CLIP_SKIPPING
565 skipRect.recordSkip(offsetToRestore - fReader.offset());
566 #endif
567 fReader.setOffset(offsetToRestore);
568 }
569 } break;
570 case CONCAT:
571 canvas.concat(*getMatrix());
572 break;
573 case DRAW_BITMAP: {
574 const SkPaint* paint = getPaint();
575 const SkBitmap& bitmap = getBitmap();
576 const SkPoint* loc = fReader.skipPoint();
577 canvas.drawBitmap(bitmap, loc->fX, loc->fY, paint);
578 } break;
579 case DRAW_BITMAP_RECT: {
580 const SkPaint* paint = getPaint();
581 const SkBitmap& bitmap = getBitmap();
582 const SkIRect* src = this->getIRectPtr(); // may be null
583 const SkRect* dst = fReader.skipRect(); // required
584 canvas.drawBitmapRect(bitmap, src, *dst, paint);
585 } break;
586 case DRAW_BITMAP_MATRIX: {
587 const SkPaint* paint = getPaint();
588 const SkBitmap& bitmap = getBitmap();
589 const SkMatrix* matrix = getMatrix();
590 canvas.drawBitmapMatrix(bitmap, *matrix, paint);
591 } break;
592 case DRAW_DATA: {
593 size_t length = getInt();
594 canvas.drawData(fReader.skip(length), length);
595 // skip handles padding the read out to a multiple of 4
596 } break;
597 case DRAW_PAINT:
598 canvas.drawPaint(*getPaint());
599 break;
600 case DRAW_PATH: {
601 const SkPaint& paint = *getPaint();
602 canvas.drawPath(getPath(), paint);
603 } break;
604 case DRAW_PICTURE:
605 canvas.drawPicture(getPicture());
606 break;
607 case DRAW_POINTS: {
608 const SkPaint& paint = *getPaint();
609 SkCanvas::PointMode mode = (SkCanvas::PointMode)getInt();
610 size_t count = getInt();
611 const SkPoint* pts = (const SkPoint*)fReader.skip(sizeof(SkPoint) * count);
612 canvas.drawPoints(mode, count, pts, paint);
613 } break;
614 case DRAW_POS_TEXT: {
615 const SkPaint& paint = *getPaint();
616 getText(&text);
617 size_t points = getInt();
618 const SkPoint* pos = (const SkPoint*)fReader.skip(points * sizeof(SkPoint));
619 canvas.drawPosText(text.text(), text.length(), pos, paint);
620 } break;
621 case DRAW_POS_TEXT_H: {
622 const SkPaint& paint = *getPaint();
623 getText(&text);
624 size_t xCount = getInt();
625 const SkScalar constY = getScalar();
626 const SkScalar* xpos = (const SkScalar*)fReader.skip(xCount * sizeof(SkScalar));
627 canvas.drawPosTextH(text.text(), text.length(), xpos, constY,
628 paint);
629 } break;
630 case DRAW_POS_TEXT_H_TOP_BOTTOM: {
631 const SkPaint& paint = *getPaint();
632 getText(&text);
633 size_t xCount = getInt();
634 const SkScalar* xpos = (const SkScalar*)fReader.skip((3 + xCount) * sizeof(SkScalar));
635 const SkScalar top = *xpos++;
636 const SkScalar bottom = *xpos++;
637 const SkScalar constY = *xpos++;
638 if (!canvas.quickRejectY(top, bottom, SkCanvas::kAA_EdgeType)) {
639 canvas.drawPosTextH(text.text(), text.length(), xpos,
640 constY, paint);
641 }
642 } break;
643 case DRAW_RECT: {
644 const SkPaint& paint = *getPaint();
645 canvas.drawRect(*fReader.skipRect(), paint);
646 } break;
647 case DRAW_SHAPE: {
648 SkShape* shape = getShape();
649 if (shape) {
650 canvas.drawShape(shape);
651 }
652 } break;
653 case DRAW_SPRITE: {
654 const SkPaint* paint = getPaint();
655 const SkBitmap& bitmap = getBitmap();
656 int left = getInt();
657 int top = getInt();
658 canvas.drawSprite(bitmap, left, top, paint);
659 } break;
660 case DRAW_TEXT: {
661 const SkPaint& paint = *getPaint();
662 getText(&text);
663 SkScalar x = getScalar();
664 SkScalar y = getScalar();
665 canvas.drawText(text.text(), text.length(), x, y, paint);
666 } break;
667 case DRAW_TEXT_TOP_BOTTOM: {
668 const SkPaint& paint = *getPaint();
669 getText(&text);
670 const SkScalar* ptr = (const SkScalar*)fReader.skip(4 * sizeof(SkScalar));
671 // ptr[0] == x
672 // ptr[1] == y
673 // ptr[2] == top
674 // ptr[3] == bottom
675 if (!canvas.quickRejectY(ptr[2], ptr[3],
676 SkCanvas::kAA_EdgeType)) {
677 canvas.drawText(text.text(), text.length(), ptr[0], ptr[1],
678 paint);
679 }
680 } break;
681 case DRAW_TEXT_ON_PATH: {
682 const SkPaint& paint = *getPaint();
683 getText(&text);
684 const SkPath& path = getPath();
685 const SkMatrix* matrix = getMatrix();
686 canvas.drawTextOnPath(text.text(), text.length(), path,
687 matrix, paint);
688 } break;
689 case DRAW_VERTICES: {
690 const SkPaint& paint = *getPaint();
691 DrawVertexFlags flags = (DrawVertexFlags)getInt();
692 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)getInt();
693 int vCount = getInt();
694 const SkPoint* verts = (const SkPoint*)fReader.skip(
695 vCount * sizeof(SkPoint));
696 const SkPoint* texs = NULL;
697 const SkColor* colors = NULL;
698 const uint16_t* indices = NULL;
699 int iCount = 0;
700 if (flags & DRAW_VERTICES_HAS_TEXS) {
701 texs = (const SkPoint*)fReader.skip(
702 vCount * sizeof(SkPoint));
703 }
704 if (flags & DRAW_VERTICES_HAS_COLORS) {
705 colors = (const SkColor*)fReader.skip(
706 vCount * sizeof(SkColor));
707 }
708 if (flags & DRAW_VERTICES_HAS_INDICES) {
709 iCount = getInt();
710 indices = (const uint16_t*)fReader.skip(
711 iCount * sizeof(uint16_t));
712 }
713 canvas.drawVertices(vmode, vCount, verts, texs, colors, NULL,
714 indices, iCount, paint);
715 } break;
716 case RESTORE:
717 canvas.restore();
718 break;
719 case ROTATE:
720 canvas.rotate(getScalar());
721 break;
722 case SAVE:
723 canvas.save((SkCanvas::SaveFlags) getInt());
724 break;
725 case SAVE_LAYER: {
726 const SkRect* boundsPtr = getRectPtr();
727 const SkPaint* paint = getPaint();
728 canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) getInt());
729 } break;
730 case SCALE: {
731 SkScalar sx = getScalar();
732 SkScalar sy = getScalar();
733 canvas.scale(sx, sy);
734 } break;
735 case SET_MATRIX:
736 canvas.setMatrix(*getMatrix());
737 break;
738 case SKEW: {
739 SkScalar sx = getScalar();
740 SkScalar sy = getScalar();
741 canvas.skew(sx, sy);
742 } break;
743 case TRANSLATE: {
744 SkScalar dx = getScalar();
745 SkScalar dy = getScalar();
746 canvas.translate(dx, dy);
747 } break;
748 default:
749 SkASSERT(0);
750 }
751 }
752
753 #ifdef SPEW_CLIP_SKIPPING
754 {
755 size_t size = skipRect.fSize + skipPath.fSize + skipRegion.fSize;
756 SkDebugf("--- Clip skips %d%% rect:%d path:%d rgn:%d\n",
757 size * 100 / fReader.offset(), skipRect.fCount, skipPath.fCount,
758 skipRegion.fCount);
759 }
760 #endif
761 // this->dumpSize();
762 }
763
abort()764 void SkPicturePlayback::abort() {
765 fReader.skip(fReader.size() - fReader.offset());
766 }
767
768 ///////////////////////////////////////////////////////////////////////////////
769
770 #if 0
771 uint32_t SkPicturePlayback::flatten(void* storage) const {
772 SkWBuffer buffer(storage);
773 buffer.write32(fBitmapCount);
774 int index;
775 for (index = 0; index < fBitmapCount; index++) {
776 const SkBitmap& bitmap = fBitmaps[index];
777 uint32_t size = bitmap.flatten(NULL, true);
778 buffer.write32(size);
779 void* local = buffer.skip(size);
780 bitmap.flatten(local, true);
781 }
782 buffer.write32(fPaintCount);
783 for (index = 0; index < fPaintCount; index++) {
784 SkFlattenableWriteBuffer flatWrite;
785 const SkPaint& paint = fPaints[index];
786 SkFlatPaint::Write(&flatWrite, paint);
787 uint32_t size = flatWrite.pos();
788 buffer.write32(size);
789 void* local = buffer.skip(size);
790 flatWrite.reset(local);
791 SkFlatPaint::Write(&flatWrite, paint);
792 }
793 buffer.write32(fPathCount);
794 for (index = 0; index < fPathCount; index++) {
795 const SkPath& path = fPaths[index];
796 uint32_t size = path.flatten(NULL);
797 buffer.write32(size);
798 void* local = buffer.skip(size);
799 path.flatten(local);
800 }
801
802 #if 0
803 buffer.write32(fPictureCount);
804 for (index = 0; index < fPictureCount; index++) {
805 const SkPicture& picture = fPictures[index];
806 uint32_t size = picture.flatten(NULL);
807 buffer.write32(size);
808 void* local = buffer.skip(size);
809 picture.flatten(local);
810 }
811 #endif
812
813 buffer.write32(fRegionCount);
814 for (index = 0; index < fRegionCount; index++) {
815 const SkRegion& region = fRegions[index];
816 size_t size = region.computeBufferSize();
817 buffer.write32(size);
818 void* local = buffer.skip(size);
819 region.writeToBuffer(local);
820 }
821 fReader.rewind();
822 size_t length = fReader.size();
823 buffer.write32(length);
824 memcpy(buffer.skip(length), fReader.base(), length);
825 return (uint32_t) buffer.pos();
826 }
827
828 void SkPicturePlayback::unflatten(const void* storage) {
829 SkRBuffer buffer(storage);
830 int index;
831 fBitmapCount = buffer.readU32();
832 fBitmaps = new SkBitmap[fBitmapCount];
833 for (index = 0; index < fBitmapCount; index++) {
834 uint32_t size = buffer.readU32();
835 const void* local = buffer.skip(size);
836 fBitmaps[index].unflatten(local);
837 }
838 fPaintCount = buffer.readU32();
839 fPaints = new SkPaint[fPaintCount];
840 for (index = 0; index < fPaintCount; index++) {
841 uint32_t size = buffer.readU32();
842 const void* local = buffer.skip(size);
843 SkFlatPaint::Read(local, &fPaints[index]);
844 }
845 fPathCount = buffer.readU32();
846 fPaths = new SkPath[fPathCount];
847 for (index = 0; index < fPathCount; index++) {
848 uint32_t size = buffer.readU32();
849 const void* local = buffer.skip(size);
850 fPaths[index].unflatten(local);
851 }
852
853 #if 0
854 fPictureCount = buffer.readU32();
855 fPictures = new SkPicture[fPictureCount];
856 for (index = 0; index < fPictureCount; index++) {
857 uint32_t size = buffer.readU32();
858 const void* local = buffer.skip(size);
859 fPictures[index].unflatten(local);
860 }
861 #endif
862
863 fRegionCount = buffer.readU32();
864 fRegions = new SkRegion[fRegionCount];
865 for (index = 0; index < fRegionCount; index++) {
866 uint32_t size = buffer.readU32();
867 const void* local = buffer.skip(size);
868 fRegions[index].readFromBuffer(local);
869 }
870 int32_t length = buffer.readS32();
871 const void* stream = buffer.skip(length);
872 fReader.setMemory(stream, length);
873 }
874 #endif
875
876 ///////////////////////////////////////////////////////////////////////////////
877
878 #ifdef SK_DEBUG_SIZE
size(size_t * sizePtr)879 int SkPicturePlayback::size(size_t* sizePtr) {
880 int objects = bitmaps(sizePtr);
881 objects += paints(sizePtr);
882 objects += paths(sizePtr);
883 objects += pictures(sizePtr);
884 objects += regions(sizePtr);
885 *sizePtr = fReader.size();
886 return objects;
887 }
888
bitmaps(size_t * size)889 int SkPicturePlayback::bitmaps(size_t* size) {
890 size_t result = 0;
891 for (int index = 0; index < fBitmapCount; index++) {
892 // const SkBitmap& bitmap = fBitmaps[index];
893 result += sizeof(SkBitmap); // bitmap->size();
894 }
895 *size = result;
896 return fBitmapCount;
897 }
898
paints(size_t * size)899 int SkPicturePlayback::paints(size_t* size) {
900 size_t result = 0;
901 for (int index = 0; index < fPaintCount; index++) {
902 // const SkPaint& paint = fPaints[index];
903 result += sizeof(SkPaint); // paint->size();
904 }
905 *size = result;
906 return fPaintCount;
907 }
908
paths(size_t * size)909 int SkPicturePlayback::paths(size_t* size) {
910 size_t result = 0;
911 for (int index = 0; index < fPathCount; index++) {
912 const SkPath& path = fPaths[index];
913 result += path.flatten(NULL);
914 }
915 *size = result;
916 return fPathCount;
917 }
918
regions(size_t * size)919 int SkPicturePlayback::regions(size_t* size) {
920 size_t result = 0;
921 for (int index = 0; index < fRegionCount; index++) {
922 // const SkRegion& region = fRegions[index];
923 result += sizeof(SkRegion); // region->size();
924 }
925 *size = result;
926 return fRegionCount;
927 }
928 #endif
929
930 #ifdef SK_DEBUG_DUMP
dumpBitmap(const SkBitmap & bitmap) const931 void SkPicturePlayback::dumpBitmap(const SkBitmap& bitmap) const {
932 char pBuffer[DUMP_BUFFER_SIZE];
933 char* bufferPtr = pBuffer;
934 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
935 "BitmapData bitmap%p = {", &bitmap);
936 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
937 "{kWidth, %d}, ", bitmap.width());
938 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
939 "{kHeight, %d}, ", bitmap.height());
940 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
941 "{kRowBytes, %d}, ", bitmap.rowBytes());
942 // start here;
943 SkDebugf("%s{0}};\n", pBuffer);
944 }
945
dumpMatrix(const SkMatrix & matrix) const946 void dumpMatrix(const SkMatrix& matrix) const {
947 SkMatrix defaultMatrix;
948 defaultMatrix.reset();
949 char pBuffer[DUMP_BUFFER_SIZE];
950 char* bufferPtr = pBuffer;
951 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
952 "MatrixData matrix%p = {", &matrix);
953 SkScalar scaleX = matrix.getScaleX();
954 if (scaleX != defaultMatrix.getScaleX())
955 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
956 "{kScaleX, %g}, ", SkScalarToFloat(scaleX));
957 SkScalar scaleY = matrix.getScaleY();
958 if (scaleY != defaultMatrix.getScaleY())
959 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
960 "{kScaleY, %g}, ", SkScalarToFloat(scaleY));
961 SkScalar skewX = matrix.getSkewX();
962 if (skewX != defaultMatrix.getSkewX())
963 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
964 "{kSkewX, %g}, ", SkScalarToFloat(skewX));
965 SkScalar skewY = matrix.getSkewY();
966 if (skewY != defaultMatrix.getSkewY())
967 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
968 "{kSkewY, %g}, ", SkScalarToFloat(skewY));
969 SkScalar translateX = matrix.getTranslateX();
970 if (translateX != defaultMatrix.getTranslateX())
971 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
972 "{kTranslateX, %g}, ", SkScalarToFloat(translateX));
973 SkScalar translateY = matrix.getTranslateY();
974 if (translateY != defaultMatrix.getTranslateY())
975 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
976 "{kTranslateY, %g}, ", SkScalarToFloat(translateY));
977 SkScalar perspX = matrix.getPerspX();
978 if (perspX != defaultMatrix.getPerspX())
979 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
980 "{kPerspX, %g}, ", SkFractToFloat(perspX));
981 SkScalar perspY = matrix.getPerspY();
982 if (perspY != defaultMatrix.getPerspY())
983 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
984 "{kPerspY, %g}, ", SkFractToFloat(perspY));
985 SkDebugf("%s{0}};\n", pBuffer);
986 }
987
dumpPaint(const SkPaint & paint) const988 void dumpPaint(const SkPaint& paint) const {
989 SkPaint defaultPaint;
990 char pBuffer[DUMP_BUFFER_SIZE];
991 char* bufferPtr = pBuffer;
992 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
993 "PaintPointers paintPtrs%p = {", &paint);
994 const SkTypeface* typeface = paint.getTypeface();
995 if (typeface != defaultPaint.getTypeface())
996 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
997 "{kTypeface, %p}, ", typeface);
998 const SkPathEffect* pathEffect = paint.getPathEffect();
999 if (pathEffect != defaultPaint.getPathEffect())
1000 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1001 "{kPathEffect, %p}, ", pathEffect);
1002 const SkShader* shader = paint.getShader();
1003 if (shader != defaultPaint.getShader())
1004 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1005 "{kShader, %p}, ", shader);
1006 const SkXfermode* xfermode = paint.getXfermode();
1007 if (xfermode != defaultPaint.getXfermode())
1008 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1009 "{kXfermode, %p}, ", xfermode);
1010 const SkMaskFilter* maskFilter = paint.getMaskFilter();
1011 if (maskFilter != defaultPaint.getMaskFilter())
1012 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1013 "{kMaskFilter, %p}, ", maskFilter);
1014 const SkColorFilter* colorFilter = paint.getColorFilter();
1015 if (colorFilter != defaultPaint.getColorFilter())
1016 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1017 "{kColorFilter, %p}, ", colorFilter);
1018 const SkRasterizer* rasterizer = paint.getRasterizer();
1019 if (rasterizer != defaultPaint.getRasterizer())
1020 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1021 "{kRasterizer, %p}, ", rasterizer);
1022 const SkDrawLooper* drawLooper = paint.getLooper();
1023 if (drawLooper != defaultPaint.getLooper())
1024 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1025 "{kDrawLooper, %p}, ", drawLooper);
1026 SkDebugf("%s{0}};\n", pBuffer);
1027 bufferPtr = pBuffer;
1028 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1029 "PaintScalars paintScalars%p = {", &paint);
1030 SkScalar textSize = paint.getTextSize();
1031 if (textSize != defaultPaint.getTextSize())
1032 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1033 "{kTextSize, %g}, ", SkScalarToFloat(textSize));
1034 SkScalar textScaleX = paint.getTextScaleX();
1035 if (textScaleX != defaultPaint.getTextScaleX())
1036 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1037 "{kTextScaleX, %g}, ", SkScalarToFloat(textScaleX));
1038 SkScalar textSkewX = paint.getTextSkewX();
1039 if (textSkewX != defaultPaint.getTextSkewX())
1040 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1041 "{kTextSkewX, %g}, ", SkScalarToFloat(textSkewX));
1042 SkScalar strokeWidth = paint.getStrokeWidth();
1043 if (strokeWidth != defaultPaint.getStrokeWidth())
1044 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1045 "{kStrokeWidth, %g}, ", SkScalarToFloat(strokeWidth));
1046 SkScalar strokeMiter = paint.getStrokeMiter();
1047 if (strokeMiter != defaultPaint.getStrokeMiter())
1048 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1049 "{kStrokeMiter, %g}, ", SkScalarToFloat(strokeMiter));
1050 SkDebugf("%s{0}};\n", pBuffer);
1051 bufferPtr = pBuffer;
1052 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1053 "PaintInts = paintInts%p = {", &paint);
1054 unsigned color = paint.getColor();
1055 if (color != defaultPaint.getColor())
1056 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1057 "{kColor, 0x%x}, ", color);
1058 unsigned flags = paint.getFlags();
1059 if (flags != defaultPaint.getFlags())
1060 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1061 "{kFlags, 0x%x}, ", flags);
1062 int align = paint.getTextAlign();
1063 if (align != defaultPaint.getTextAlign())
1064 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1065 "{kAlign, 0x%x}, ", align);
1066 int strokeCap = paint.getStrokeCap();
1067 if (strokeCap != defaultPaint.getStrokeCap())
1068 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1069 "{kStrokeCap, 0x%x}, ", strokeCap);
1070 int strokeJoin = paint.getStrokeJoin();
1071 if (strokeJoin != defaultPaint.getStrokeJoin())
1072 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1073 "{kAlign, 0x%x}, ", strokeJoin);
1074 int style = paint.getStyle();
1075 if (style != defaultPaint.getStyle())
1076 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1077 "{kStyle, 0x%x}, ", style);
1078 int textEncoding = paint.getTextEncoding();
1079 if (textEncoding != defaultPaint.getTextEncoding())
1080 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1081 "{kTextEncoding, 0x%x}, ", textEncoding);
1082 SkDebugf("%s{0}};\n", pBuffer);
1083
1084 SkDebugf("PaintData paint%p = {paintPtrs%p, paintScalars%p, paintInts%p};\n",
1085 &paint, &paint, &paint, &paint);
1086 }
1087
dumpPath(const SkPath & path) const1088 void SkPicturePlayback::dumpPath(const SkPath& path) const {
1089 SkDebugf("path dump unimplemented\n");
1090 }
1091
dumpPicture(const SkPicture & picture) const1092 void SkPicturePlayback::dumpPicture(const SkPicture& picture) const {
1093 SkDebugf("picture dump unimplemented\n");
1094 }
1095
dumpRegion(const SkRegion & region) const1096 void SkPicturePlayback::dumpRegion(const SkRegion& region) const {
1097 SkDebugf("region dump unimplemented\n");
1098 }
1099
dumpDrawType(char * bufferPtr,char * buffer,DrawType drawType)1100 int SkPicturePlayback::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) {
1101 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1102 "k%s, ", DrawTypeToString(drawType));
1103 }
1104
dumpInt(char * bufferPtr,char * buffer,char * name)1105 int SkPicturePlayback::dumpInt(char* bufferPtr, char* buffer, char* name) {
1106 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1107 "%s:%d, ", name, getInt());
1108 }
1109
dumpRect(char * bufferPtr,char * buffer,char * name)1110 int SkPicturePlayback::dumpRect(char* bufferPtr, char* buffer, char* name) {
1111 const SkRect* rect = fReader.skipRect();
1112 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1113 "%s:{l:%g t:%g r:%g b:%g}, ", name, SkScalarToFloat(rect.fLeft),
1114 SkScalarToFloat(rect.fTop),
1115 SkScalarToFloat(rect.fRight), SkScalarToFloat(rect.fBottom));
1116 }
1117
dumpPoint(char * bufferPtr,char * buffer,char * name)1118 int SkPicturePlayback::dumpPoint(char* bufferPtr, char* buffer, char* name) {
1119 SkPoint pt;
1120 getPoint(&pt);
1121 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1122 "%s:{x:%g y:%g}, ", name, SkScalarToFloat(pt.fX),
1123 SkScalarToFloat(pt.fY));
1124 }
1125
dumpPointArray(char ** bufferPtrPtr,char * buffer,int count)1126 void SkPicturePlayback::dumpPointArray(char** bufferPtrPtr, char* buffer, int count) {
1127 char* bufferPtr = *bufferPtrPtr;
1128 const SkPoint* pts = (const SkPoint*)fReadStream.getAtPos();
1129 fReadStream.skip(sizeof(SkPoint) * count);
1130 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1131 "count:%d {", count);
1132 for (int index = 0; index < count; index++)
1133 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1134 "{x:%g y:%g}, ", SkScalarToFloat(pts[index].fX),
1135 SkScalarToFloat(pts[index].fY));
1136 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1137 "} ");
1138 *bufferPtrPtr = bufferPtr;
1139 }
1140
dumpPtr(char * bufferPtr,char * buffer,char * name,void * ptr)1141 int SkPicturePlayback::dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr) {
1142 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1143 "%s:%p, ", name, ptr);
1144 }
1145
dumpRectPtr(char * bufferPtr,char * buffer,char * name)1146 int SkPicturePlayback::dumpRectPtr(char* bufferPtr, char* buffer, char* name) {
1147 char result;
1148 fReadStream.read(&result, sizeof(result));
1149 if (result)
1150 return dumpRect(bufferPtr, buffer, name);
1151 else
1152 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1153 "%s:NULL, ", name);
1154 }
1155
dumpScalar(char * bufferPtr,char * buffer,char * name)1156 int SkPicturePlayback::dumpScalar(char* bufferPtr, char* buffer, char* name) {
1157 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1158 "%s:%d, ", name, getScalar());
1159 }
1160
dumpText(char ** bufferPtrPtr,char * buffer)1161 void SkPicturePlayback::dumpText(char** bufferPtrPtr, char* buffer) {
1162 char* bufferPtr = *bufferPtrPtr;
1163 int length = getInt();
1164 bufferPtr += dumpDrawType(bufferPtr, buffer);
1165 fReadStream.skipToAlign4();
1166 char* text = (char*) fReadStream.getAtPos();
1167 fReadStream.skip(length);
1168 bufferPtr += dumpInt(bufferPtr, buffer, "length");
1169 int limit = DUMP_BUFFER_SIZE - (bufferPtr - buffer) - 2;
1170 length >>= 1;
1171 if (limit > length)
1172 limit = length;
1173 if (limit > 0) {
1174 *bufferPtr++ = '"';
1175 for (int index = 0; index < limit; index++) {
1176 *bufferPtr++ = *(unsigned short*) text;
1177 text += sizeof(unsigned short);
1178 }
1179 *bufferPtr++ = '"';
1180 }
1181 *bufferPtrPtr = bufferPtr;
1182 }
1183
1184 #define DUMP_DRAWTYPE(drawType) \
1185 bufferPtr += dumpDrawType(bufferPtr, buffer, drawType)
1186
1187 #define DUMP_INT(name) \
1188 bufferPtr += dumpInt(bufferPtr, buffer, #name)
1189
1190 #define DUMP_RECT_PTR(name) \
1191 bufferPtr += dumpRectPtr(bufferPtr, buffer, #name)
1192
1193 #define DUMP_POINT(name) \
1194 bufferPtr += dumpRect(bufferPtr, buffer, #name)
1195
1196 #define DUMP_RECT(name) \
1197 bufferPtr += dumpRect(bufferPtr, buffer, #name)
1198
1199 #define DUMP_POINT_ARRAY(count) \
1200 dumpPointArray(&bufferPtr, buffer, count)
1201
1202 #define DUMP_PTR(name, ptr) \
1203 bufferPtr += dumpPtr(bufferPtr, buffer, #name, (void*) ptr)
1204
1205 #define DUMP_SCALAR(name) \
1206 bufferPtr += dumpScalar(bufferPtr, buffer, #name)
1207
1208 #define DUMP_TEXT() \
1209 dumpText(&bufferPtr, buffer)
1210
dumpStream()1211 void SkPicturePlayback::dumpStream() {
1212 SkDebugf("RecordStream stream = {\n");
1213 DrawType drawType;
1214 TextContainer text;
1215 fReadStream.rewind();
1216 char buffer[DUMP_BUFFER_SIZE], * bufferPtr;
1217 while (fReadStream.read(&drawType, sizeof(drawType))) {
1218 bufferPtr = buffer;
1219 DUMP_DRAWTYPE(drawType);
1220 switch (drawType) {
1221 case CLIP_PATH: {
1222 DUMP_PTR(SkPath, &getPath());
1223 DUMP_INT(SkRegion::Op);
1224 DUMP_INT(offsetToRestore);
1225 } break;
1226 case CLIP_REGION: {
1227 DUMP_PTR(SkRegion, &getRegion());
1228 DUMP_INT(SkRegion::Op);
1229 DUMP_INT(offsetToRestore);
1230 } break;
1231 case CLIP_RECT: {
1232 DUMP_RECT(rect);
1233 DUMP_INT(SkRegion::Op);
1234 DUMP_INT(offsetToRestore);
1235 } break;
1236 case CONCAT:
1237 DUMP_PTR(SkMatrix, getMatrix());
1238 break;
1239 case DRAW_BITMAP: {
1240 DUMP_PTR(SkPaint, getPaint());
1241 DUMP_PTR(SkBitmap, &getBitmap());
1242 DUMP_SCALAR(left);
1243 DUMP_SCALAR(top);
1244 } break;
1245 case DRAW_PAINT:
1246 DUMP_PTR(SkPaint, getPaint());
1247 break;
1248 case DRAW_PATH: {
1249 DUMP_PTR(SkPaint, getPaint());
1250 DUMP_PTR(SkPath, &getPath());
1251 } break;
1252 case DRAW_PICTURE: {
1253 DUMP_PTR(SkPicture, &getPicture());
1254 } break;
1255 case DRAW_POINTS: {
1256 DUMP_PTR(SkPaint, getPaint());
1257 (void)getInt(); // PointMode
1258 size_t count = getInt();
1259 fReadStream.skipToAlign4();
1260 DUMP_POINT_ARRAY(count);
1261 } break;
1262 case DRAW_POS_TEXT: {
1263 DUMP_PTR(SkPaint, getPaint());
1264 DUMP_TEXT();
1265 size_t points = getInt();
1266 fReadStream.skipToAlign4();
1267 DUMP_POINT_ARRAY(points);
1268 } break;
1269 case DRAW_POS_TEXT_H: {
1270 DUMP_PTR(SkPaint, getPaint());
1271 DUMP_TEXT();
1272 size_t points = getInt();
1273 fReadStream.skipToAlign4();
1274 DUMP_SCALAR(top);
1275 DUMP_SCALAR(bottom);
1276 DUMP_SCALAR(constY);
1277 DUMP_POINT_ARRAY(points);
1278 } break;
1279 case DRAW_RECT: {
1280 DUMP_PTR(SkPaint, getPaint());
1281 DUMP_RECT(rect);
1282 } break;
1283 case DRAW_SPRITE: {
1284 DUMP_PTR(SkPaint, getPaint());
1285 DUMP_PTR(SkBitmap, &getBitmap());
1286 DUMP_SCALAR(left);
1287 DUMP_SCALAR(top);
1288 } break;
1289 case DRAW_TEXT: {
1290 DUMP_PTR(SkPaint, getPaint());
1291 DUMP_TEXT();
1292 DUMP_SCALAR(x);
1293 DUMP_SCALAR(y);
1294 } break;
1295 case DRAW_TEXT_ON_PATH: {
1296 DUMP_PTR(SkPaint, getPaint());
1297 DUMP_TEXT();
1298 DUMP_PTR(SkPath, &getPath());
1299 DUMP_PTR(SkMatrix, getMatrix());
1300 } break;
1301 case RESTORE:
1302 break;
1303 case ROTATE:
1304 DUMP_SCALAR(rotate);
1305 break;
1306 case SAVE:
1307 DUMP_INT(SkCanvas::SaveFlags);
1308 break;
1309 case SAVE_LAYER: {
1310 DUMP_RECT_PTR(layer);
1311 DUMP_PTR(SkPaint, getPaint());
1312 DUMP_INT(SkCanvas::SaveFlags);
1313 } break;
1314 case SCALE: {
1315 DUMP_SCALAR(sx);
1316 DUMP_SCALAR(sy);
1317 } break;
1318 case SKEW: {
1319 DUMP_SCALAR(sx);
1320 DUMP_SCALAR(sy);
1321 } break;
1322 case TRANSLATE: {
1323 DUMP_SCALAR(dx);
1324 DUMP_SCALAR(dy);
1325 } break;
1326 default:
1327 SkASSERT(0);
1328 }
1329 SkDebugf("%s\n", buffer);
1330 }
1331 }
1332
dump() const1333 void SkPicturePlayback::dump() const {
1334 char pBuffer[DUMP_BUFFER_SIZE];
1335 char* bufferPtr = pBuffer;
1336 int index;
1337 if (fBitmapCount > 0)
1338 SkDebugf("// bitmaps (%d)\n", fBitmapCount);
1339 for (index = 0; index < fBitmapCount; index++) {
1340 const SkBitmap& bitmap = fBitmaps[index];
1341 dumpBitmap(bitmap);
1342 }
1343 if (fBitmapCount > 0)
1344 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1345 "Bitmaps bitmaps = {");
1346 for (index = 0; index < fBitmapCount; index++)
1347 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1348 "bitmap%p, ", &fBitmaps[index]);
1349 if (fBitmapCount > 0)
1350 SkDebugf("%s0};\n", pBuffer);
1351
1352 if (fMatrixCount > 0)
1353 SkDebugf("// matrices (%d)\n", fMatrixCount);
1354 for (index = 0; index < fMatrixCount; index++) {
1355 const SkMatrix& matrix = fMatrices[index];
1356 dumpMatrix(matrix);
1357 }
1358 bufferPtr = pBuffer;
1359 if (fMatrixCount > 0)
1360 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1361 "Matrices matrices = {");
1362 for (index = 0; index < fMatrixCount; index++)
1363 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1364 "matrix%p, ", &fMatrices[index]);
1365 if (fMatrixCount > 0)
1366 SkDebugf("%s0};\n", pBuffer);
1367
1368 if (fPaintCount > 0)
1369 SkDebugf("// paints (%d)\n", fPaintCount);
1370 for (index = 0; index < fPaintCount; index++) {
1371 const SkPaint& paint = fPaints[index];
1372 dumpPaint(paint);
1373 }
1374 bufferPtr = pBuffer;
1375 if (fPaintCount > 0)
1376 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1377 "Paints paints = {");
1378 for (index = 0; index < fPaintCount; index++)
1379 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1380 "paint%p, ", &fPaints[index]);
1381 if (fPaintCount > 0)
1382 SkDebugf("%s0};\n", pBuffer);
1383
1384 for (index = 0; index < fPathCount; index++) {
1385 const SkPath& path = fPaths[index];
1386 dumpPath(path);
1387 }
1388 bufferPtr = pBuffer;
1389 if (fPathCount > 0)
1390 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1391 "Paths paths = {");
1392 for (index = 0; index < fPathCount; index++)
1393 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1394 "path%p, ", &fPaths[index]);
1395 if (fPathCount > 0)
1396 SkDebugf("%s0};\n", pBuffer);
1397
1398 for (index = 0; index < fPictureCount; index++) {
1399 dumpPicture(*fPictureRefs[index]);
1400 }
1401 bufferPtr = pBuffer;
1402 if (fPictureCount > 0)
1403 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1404 "Pictures pictures = {");
1405 for (index = 0; index < fPictureCount; index++)
1406 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1407 "picture%p, ", fPictureRefs[index]);
1408 if (fPictureCount > 0)
1409 SkDebugf("%s0};\n", pBuffer);
1410
1411 for (index = 0; index < fRegionCount; index++) {
1412 const SkRegion& region = fRegions[index];
1413 dumpRegion(region);
1414 }
1415 bufferPtr = pBuffer;
1416 if (fRegionCount > 0)
1417 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1418 "Regions regions = {");
1419 for (index = 0; index < fRegionCount; index++)
1420 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1421 "region%p, ", &fRegions[index]);
1422 if (fRegionCount > 0)
1423 SkDebugf("%s0};\n", pBuffer);
1424
1425 const_cast<SkPicturePlayback*>(this)->dumpStream();
1426 }
1427
1428 #endif
1429