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