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_PAINT:
593 canvas.drawPaint(*getPaint());
594 break;
595 case DRAW_PATH: {
596 const SkPaint& paint = *getPaint();
597 canvas.drawPath(getPath(), paint);
598 } break;
599 case DRAW_PICTURE:
600 canvas.drawPicture(getPicture());
601 break;
602 case DRAW_POINTS: {
603 const SkPaint& paint = *getPaint();
604 SkCanvas::PointMode mode = (SkCanvas::PointMode)getInt();
605 size_t count = getInt();
606 const SkPoint* pts = (const SkPoint*)fReader.skip(sizeof(SkPoint) * count);
607 canvas.drawPoints(mode, count, pts, paint);
608 } break;
609 case DRAW_POS_TEXT: {
610 const SkPaint& paint = *getPaint();
611 getText(&text);
612 size_t points = getInt();
613 const SkPoint* pos = (const SkPoint*)fReader.skip(points * sizeof(SkPoint));
614 canvas.drawPosText(text.text(), text.length(), pos, paint);
615 } break;
616 case DRAW_POS_TEXT_H: {
617 const SkPaint& paint = *getPaint();
618 getText(&text);
619 size_t xCount = getInt();
620 const SkScalar constY = getScalar();
621 const SkScalar* xpos = (const SkScalar*)fReader.skip(xCount * sizeof(SkScalar));
622 canvas.drawPosTextH(text.text(), text.length(), xpos, constY,
623 paint);
624 } break;
625 case DRAW_POS_TEXT_H_TOP_BOTTOM: {
626 const SkPaint& paint = *getPaint();
627 getText(&text);
628 size_t xCount = getInt();
629 const SkScalar* xpos = (const SkScalar*)fReader.skip((3 + xCount) * sizeof(SkScalar));
630 const SkScalar top = *xpos++;
631 const SkScalar bottom = *xpos++;
632 const SkScalar constY = *xpos++;
633 if (!canvas.quickRejectY(top, bottom, SkCanvas::kAA_EdgeType)) {
634 canvas.drawPosTextH(text.text(), text.length(), xpos,
635 constY, paint);
636 }
637 } break;
638 case DRAW_RECT: {
639 const SkPaint& paint = *getPaint();
640 canvas.drawRect(*fReader.skipRect(), paint);
641 } break;
642 case DRAW_SHAPE: {
643 SkShape* shape = getShape();
644 if (shape) {
645 canvas.drawShape(shape);
646 }
647 } break;
648 case DRAW_SPRITE: {
649 const SkPaint* paint = getPaint();
650 const SkBitmap& bitmap = getBitmap();
651 int left = getInt();
652 int top = getInt();
653 canvas.drawSprite(bitmap, left, top, paint);
654 } break;
655 case DRAW_TEXT: {
656 const SkPaint& paint = *getPaint();
657 getText(&text);
658 SkScalar x = getScalar();
659 SkScalar y = getScalar();
660 canvas.drawText(text.text(), text.length(), x, y, paint);
661 } break;
662 case DRAW_TEXT_TOP_BOTTOM: {
663 const SkPaint& paint = *getPaint();
664 getText(&text);
665 const SkScalar* ptr = (const SkScalar*)fReader.skip(4 * sizeof(SkScalar));
666 // ptr[0] == x
667 // ptr[1] == y
668 // ptr[2] == top
669 // ptr[3] == bottom
670 if (!canvas.quickRejectY(ptr[2], ptr[3],
671 SkCanvas::kAA_EdgeType)) {
672 canvas.drawText(text.text(), text.length(), ptr[0], ptr[1],
673 paint);
674 }
675 } break;
676 case DRAW_TEXT_ON_PATH: {
677 const SkPaint& paint = *getPaint();
678 getText(&text);
679 const SkPath& path = getPath();
680 const SkMatrix* matrix = getMatrix();
681 canvas.drawTextOnPath(text.text(), text.length(), path,
682 matrix, paint);
683 } break;
684 case DRAW_VERTICES: {
685 const SkPaint& paint = *getPaint();
686 DrawVertexFlags flags = (DrawVertexFlags)getInt();
687 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)getInt();
688 int vCount = getInt();
689 const SkPoint* verts = (const SkPoint*)fReader.skip(
690 vCount * sizeof(SkPoint));
691 const SkPoint* texs = NULL;
692 const SkColor* colors = NULL;
693 const uint16_t* indices = NULL;
694 int iCount = 0;
695 if (flags & DRAW_VERTICES_HAS_TEXS) {
696 texs = (const SkPoint*)fReader.skip(
697 vCount * sizeof(SkPoint));
698 }
699 if (flags & DRAW_VERTICES_HAS_COLORS) {
700 colors = (const SkColor*)fReader.skip(
701 vCount * sizeof(SkColor));
702 }
703 if (flags & DRAW_VERTICES_HAS_INDICES) {
704 iCount = getInt();
705 indices = (const uint16_t*)fReader.skip(
706 iCount * sizeof(uint16_t));
707 }
708 canvas.drawVertices(vmode, vCount, verts, texs, colors, NULL,
709 indices, iCount, paint);
710 } break;
711 case RESTORE:
712 canvas.restore();
713 break;
714 case ROTATE:
715 canvas.rotate(getScalar());
716 break;
717 case SAVE:
718 canvas.save((SkCanvas::SaveFlags) getInt());
719 break;
720 case SAVE_LAYER: {
721 const SkRect* boundsPtr = getRectPtr();
722 const SkPaint* paint = getPaint();
723 canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) getInt());
724 } break;
725 case SCALE: {
726 SkScalar sx = getScalar();
727 SkScalar sy = getScalar();
728 canvas.scale(sx, sy);
729 } break;
730 case SET_MATRIX:
731 canvas.setMatrix(*getMatrix());
732 break;
733 case SKEW: {
734 SkScalar sx = getScalar();
735 SkScalar sy = getScalar();
736 canvas.skew(sx, sy);
737 } break;
738 case TRANSLATE: {
739 SkScalar dx = getScalar();
740 SkScalar dy = getScalar();
741 canvas.translate(dx, dy);
742 } break;
743 default:
744 SkASSERT(0);
745 }
746 }
747
748 #ifdef SPEW_CLIP_SKIPPING
749 {
750 size_t size = skipRect.fSize + skipPath.fSize + skipRegion.fSize;
751 SkDebugf("--- Clip skips %d%% rect:%d path:%d rgn:%d\n",
752 size * 100 / fReader.offset(), skipRect.fCount, skipPath.fCount,
753 skipRegion.fCount);
754 }
755 #endif
756 // this->dumpSize();
757 }
758
abort()759 void SkPicturePlayback::abort() {
760 fReader.skip(fReader.size() - fReader.offset());
761 }
762
763 ///////////////////////////////////////////////////////////////////////////////
764
765 #if 0
766 uint32_t SkPicturePlayback::flatten(void* storage) const {
767 SkWBuffer buffer(storage);
768 buffer.write32(fBitmapCount);
769 int index;
770 for (index = 0; index < fBitmapCount; index++) {
771 const SkBitmap& bitmap = fBitmaps[index];
772 uint32_t size = bitmap.flatten(NULL, true);
773 buffer.write32(size);
774 void* local = buffer.skip(size);
775 bitmap.flatten(local, true);
776 }
777 buffer.write32(fPaintCount);
778 for (index = 0; index < fPaintCount; index++) {
779 SkFlattenableWriteBuffer flatWrite;
780 const SkPaint& paint = fPaints[index];
781 SkFlatPaint::Write(&flatWrite, paint);
782 uint32_t size = flatWrite.pos();
783 buffer.write32(size);
784 void* local = buffer.skip(size);
785 flatWrite.reset(local);
786 SkFlatPaint::Write(&flatWrite, paint);
787 }
788 buffer.write32(fPathCount);
789 for (index = 0; index < fPathCount; index++) {
790 const SkPath& path = fPaths[index];
791 uint32_t size = path.flatten(NULL);
792 buffer.write32(size);
793 void* local = buffer.skip(size);
794 path.flatten(local);
795 }
796
797 #if 0
798 buffer.write32(fPictureCount);
799 for (index = 0; index < fPictureCount; index++) {
800 const SkPicture& picture = fPictures[index];
801 uint32_t size = picture.flatten(NULL);
802 buffer.write32(size);
803 void* local = buffer.skip(size);
804 picture.flatten(local);
805 }
806 #endif
807
808 buffer.write32(fRegionCount);
809 for (index = 0; index < fRegionCount; index++) {
810 const SkRegion& region = fRegions[index];
811 size_t size = region.computeBufferSize();
812 buffer.write32(size);
813 void* local = buffer.skip(size);
814 region.writeToBuffer(local);
815 }
816 fReader.rewind();
817 size_t length = fReader.size();
818 buffer.write32(length);
819 memcpy(buffer.skip(length), fReader.base(), length);
820 return (uint32_t) buffer.pos();
821 }
822
823 void SkPicturePlayback::unflatten(const void* storage) {
824 SkRBuffer buffer(storage);
825 int index;
826 fBitmapCount = buffer.readU32();
827 fBitmaps = new SkBitmap[fBitmapCount];
828 for (index = 0; index < fBitmapCount; index++) {
829 uint32_t size = buffer.readU32();
830 const void* local = buffer.skip(size);
831 fBitmaps[index].unflatten(local);
832 }
833 fPaintCount = buffer.readU32();
834 fPaints = new SkPaint[fPaintCount];
835 for (index = 0; index < fPaintCount; index++) {
836 uint32_t size = buffer.readU32();
837 const void* local = buffer.skip(size);
838 SkFlatPaint::Read(local, &fPaints[index]);
839 }
840 fPathCount = buffer.readU32();
841 fPaths = new SkPath[fPathCount];
842 for (index = 0; index < fPathCount; index++) {
843 uint32_t size = buffer.readU32();
844 const void* local = buffer.skip(size);
845 fPaths[index].unflatten(local);
846 }
847
848 #if 0
849 fPictureCount = buffer.readU32();
850 fPictures = new SkPicture[fPictureCount];
851 for (index = 0; index < fPictureCount; index++) {
852 uint32_t size = buffer.readU32();
853 const void* local = buffer.skip(size);
854 fPictures[index].unflatten(local);
855 }
856 #endif
857
858 fRegionCount = buffer.readU32();
859 fRegions = new SkRegion[fRegionCount];
860 for (index = 0; index < fRegionCount; index++) {
861 uint32_t size = buffer.readU32();
862 const void* local = buffer.skip(size);
863 fRegions[index].readFromBuffer(local);
864 }
865 int32_t length = buffer.readS32();
866 const void* stream = buffer.skip(length);
867 fReader.setMemory(stream, length);
868 }
869 #endif
870
871 ///////////////////////////////////////////////////////////////////////////////
872
873 #ifdef SK_DEBUG_SIZE
size(size_t * sizePtr)874 int SkPicturePlayback::size(size_t* sizePtr) {
875 int objects = bitmaps(sizePtr);
876 objects += paints(sizePtr);
877 objects += paths(sizePtr);
878 objects += pictures(sizePtr);
879 objects += regions(sizePtr);
880 *sizePtr = fReader.size();
881 return objects;
882 }
883
bitmaps(size_t * size)884 int SkPicturePlayback::bitmaps(size_t* size) {
885 size_t result = 0;
886 for (int index = 0; index < fBitmapCount; index++) {
887 // const SkBitmap& bitmap = fBitmaps[index];
888 result += sizeof(SkBitmap); // bitmap->size();
889 }
890 *size = result;
891 return fBitmapCount;
892 }
893
paints(size_t * size)894 int SkPicturePlayback::paints(size_t* size) {
895 size_t result = 0;
896 for (int index = 0; index < fPaintCount; index++) {
897 // const SkPaint& paint = fPaints[index];
898 result += sizeof(SkPaint); // paint->size();
899 }
900 *size = result;
901 return fPaintCount;
902 }
903
paths(size_t * size)904 int SkPicturePlayback::paths(size_t* size) {
905 size_t result = 0;
906 for (int index = 0; index < fPathCount; index++) {
907 const SkPath& path = fPaths[index];
908 result += path.flatten(NULL);
909 }
910 *size = result;
911 return fPathCount;
912 }
913
regions(size_t * size)914 int SkPicturePlayback::regions(size_t* size) {
915 size_t result = 0;
916 for (int index = 0; index < fRegionCount; index++) {
917 // const SkRegion& region = fRegions[index];
918 result += sizeof(SkRegion); // region->size();
919 }
920 *size = result;
921 return fRegionCount;
922 }
923 #endif
924
925 #ifdef SK_DEBUG_DUMP
dumpBitmap(const SkBitmap & bitmap) const926 void SkPicturePlayback::dumpBitmap(const SkBitmap& bitmap) const {
927 char pBuffer[DUMP_BUFFER_SIZE];
928 char* bufferPtr = pBuffer;
929 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
930 "BitmapData bitmap%p = {", &bitmap);
931 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
932 "{kWidth, %d}, ", bitmap.width());
933 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
934 "{kHeight, %d}, ", bitmap.height());
935 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
936 "{kRowBytes, %d}, ", bitmap.rowBytes());
937 // start here;
938 SkDebugf("%s{0}};\n", pBuffer);
939 }
940
dumpMatrix(const SkMatrix & matrix) const941 void dumpMatrix(const SkMatrix& matrix) const {
942 SkMatrix defaultMatrix;
943 defaultMatrix.reset();
944 char pBuffer[DUMP_BUFFER_SIZE];
945 char* bufferPtr = pBuffer;
946 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
947 "MatrixData matrix%p = {", &matrix);
948 SkScalar scaleX = matrix.getScaleX();
949 if (scaleX != defaultMatrix.getScaleX())
950 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
951 "{kScaleX, %g}, ", SkScalarToFloat(scaleX));
952 SkScalar scaleY = matrix.getScaleY();
953 if (scaleY != defaultMatrix.getScaleY())
954 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
955 "{kScaleY, %g}, ", SkScalarToFloat(scaleY));
956 SkScalar skewX = matrix.getSkewX();
957 if (skewX != defaultMatrix.getSkewX())
958 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
959 "{kSkewX, %g}, ", SkScalarToFloat(skewX));
960 SkScalar skewY = matrix.getSkewY();
961 if (skewY != defaultMatrix.getSkewY())
962 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
963 "{kSkewY, %g}, ", SkScalarToFloat(skewY));
964 SkScalar translateX = matrix.getTranslateX();
965 if (translateX != defaultMatrix.getTranslateX())
966 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
967 "{kTranslateX, %g}, ", SkScalarToFloat(translateX));
968 SkScalar translateY = matrix.getTranslateY();
969 if (translateY != defaultMatrix.getTranslateY())
970 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
971 "{kTranslateY, %g}, ", SkScalarToFloat(translateY));
972 SkScalar perspX = matrix.getPerspX();
973 if (perspX != defaultMatrix.getPerspX())
974 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
975 "{kPerspX, %g}, ", SkFractToFloat(perspX));
976 SkScalar perspY = matrix.getPerspY();
977 if (perspY != defaultMatrix.getPerspY())
978 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
979 "{kPerspY, %g}, ", SkFractToFloat(perspY));
980 SkDebugf("%s{0}};\n", pBuffer);
981 }
982
dumpPaint(const SkPaint & paint) const983 void dumpPaint(const SkPaint& paint) const {
984 SkPaint defaultPaint;
985 char pBuffer[DUMP_BUFFER_SIZE];
986 char* bufferPtr = pBuffer;
987 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
988 "PaintPointers paintPtrs%p = {", &paint);
989 const SkTypeface* typeface = paint.getTypeface();
990 if (typeface != defaultPaint.getTypeface())
991 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
992 "{kTypeface, %p}, ", typeface);
993 const SkPathEffect* pathEffect = paint.getPathEffect();
994 if (pathEffect != defaultPaint.getPathEffect())
995 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
996 "{kPathEffect, %p}, ", pathEffect);
997 const SkShader* shader = paint.getShader();
998 if (shader != defaultPaint.getShader())
999 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1000 "{kShader, %p}, ", shader);
1001 const SkXfermode* xfermode = paint.getXfermode();
1002 if (xfermode != defaultPaint.getXfermode())
1003 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1004 "{kXfermode, %p}, ", xfermode);
1005 const SkMaskFilter* maskFilter = paint.getMaskFilter();
1006 if (maskFilter != defaultPaint.getMaskFilter())
1007 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1008 "{kMaskFilter, %p}, ", maskFilter);
1009 const SkColorFilter* colorFilter = paint.getColorFilter();
1010 if (colorFilter != defaultPaint.getColorFilter())
1011 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1012 "{kColorFilter, %p}, ", colorFilter);
1013 const SkRasterizer* rasterizer = paint.getRasterizer();
1014 if (rasterizer != defaultPaint.getRasterizer())
1015 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1016 "{kRasterizer, %p}, ", rasterizer);
1017 const SkDrawLooper* drawLooper = paint.getLooper();
1018 if (drawLooper != defaultPaint.getLooper())
1019 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1020 "{kDrawLooper, %p}, ", drawLooper);
1021 SkDebugf("%s{0}};\n", pBuffer);
1022 bufferPtr = pBuffer;
1023 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1024 "PaintScalars paintScalars%p = {", &paint);
1025 SkScalar textSize = paint.getTextSize();
1026 if (textSize != defaultPaint.getTextSize())
1027 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1028 "{kTextSize, %g}, ", SkScalarToFloat(textSize));
1029 SkScalar textScaleX = paint.getTextScaleX();
1030 if (textScaleX != defaultPaint.getTextScaleX())
1031 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1032 "{kTextScaleX, %g}, ", SkScalarToFloat(textScaleX));
1033 SkScalar textSkewX = paint.getTextSkewX();
1034 if (textSkewX != defaultPaint.getTextSkewX())
1035 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1036 "{kTextSkewX, %g}, ", SkScalarToFloat(textSkewX));
1037 SkScalar strokeWidth = paint.getStrokeWidth();
1038 if (strokeWidth != defaultPaint.getStrokeWidth())
1039 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1040 "{kStrokeWidth, %g}, ", SkScalarToFloat(strokeWidth));
1041 SkScalar strokeMiter = paint.getStrokeMiter();
1042 if (strokeMiter != defaultPaint.getStrokeMiter())
1043 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1044 "{kStrokeMiter, %g}, ", SkScalarToFloat(strokeMiter));
1045 SkDebugf("%s{0}};\n", pBuffer);
1046 bufferPtr = pBuffer;
1047 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1048 "PaintInts = paintInts%p = {", &paint);
1049 unsigned color = paint.getColor();
1050 if (color != defaultPaint.getColor())
1051 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1052 "{kColor, 0x%x}, ", color);
1053 unsigned flags = paint.getFlags();
1054 if (flags != defaultPaint.getFlags())
1055 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1056 "{kFlags, 0x%x}, ", flags);
1057 int align = paint.getTextAlign();
1058 if (align != defaultPaint.getTextAlign())
1059 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1060 "{kAlign, 0x%x}, ", align);
1061 int strokeCap = paint.getStrokeCap();
1062 if (strokeCap != defaultPaint.getStrokeCap())
1063 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1064 "{kStrokeCap, 0x%x}, ", strokeCap);
1065 int strokeJoin = paint.getStrokeJoin();
1066 if (strokeJoin != defaultPaint.getStrokeJoin())
1067 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1068 "{kAlign, 0x%x}, ", strokeJoin);
1069 int style = paint.getStyle();
1070 if (style != defaultPaint.getStyle())
1071 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1072 "{kStyle, 0x%x}, ", style);
1073 int textEncoding = paint.getTextEncoding();
1074 if (textEncoding != defaultPaint.getTextEncoding())
1075 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1076 "{kTextEncoding, 0x%x}, ", textEncoding);
1077 SkDebugf("%s{0}};\n", pBuffer);
1078
1079 SkDebugf("PaintData paint%p = {paintPtrs%p, paintScalars%p, paintInts%p};\n",
1080 &paint, &paint, &paint, &paint);
1081 }
1082
dumpPath(const SkPath & path) const1083 void SkPicturePlayback::dumpPath(const SkPath& path) const {
1084 SkDebugf("path dump unimplemented\n");
1085 }
1086
dumpPicture(const SkPicture & picture) const1087 void SkPicturePlayback::dumpPicture(const SkPicture& picture) const {
1088 SkDebugf("picture dump unimplemented\n");
1089 }
1090
dumpRegion(const SkRegion & region) const1091 void SkPicturePlayback::dumpRegion(const SkRegion& region) const {
1092 SkDebugf("region dump unimplemented\n");
1093 }
1094
dumpDrawType(char * bufferPtr,char * buffer,DrawType drawType)1095 int SkPicturePlayback::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) {
1096 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1097 "k%s, ", DrawTypeToString(drawType));
1098 }
1099
dumpInt(char * bufferPtr,char * buffer,char * name)1100 int SkPicturePlayback::dumpInt(char* bufferPtr, char* buffer, char* name) {
1101 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1102 "%s:%d, ", name, getInt());
1103 }
1104
dumpRect(char * bufferPtr,char * buffer,char * name)1105 int SkPicturePlayback::dumpRect(char* bufferPtr, char* buffer, char* name) {
1106 const SkRect* rect = fReader.skipRect();
1107 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1108 "%s:{l:%g t:%g r:%g b:%g}, ", name, SkScalarToFloat(rect.fLeft),
1109 SkScalarToFloat(rect.fTop),
1110 SkScalarToFloat(rect.fRight), SkScalarToFloat(rect.fBottom));
1111 }
1112
dumpPoint(char * bufferPtr,char * buffer,char * name)1113 int SkPicturePlayback::dumpPoint(char* bufferPtr, char* buffer, char* name) {
1114 SkPoint pt;
1115 getPoint(&pt);
1116 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1117 "%s:{x:%g y:%g}, ", name, SkScalarToFloat(pt.fX),
1118 SkScalarToFloat(pt.fY));
1119 }
1120
dumpPointArray(char ** bufferPtrPtr,char * buffer,int count)1121 void SkPicturePlayback::dumpPointArray(char** bufferPtrPtr, char* buffer, int count) {
1122 char* bufferPtr = *bufferPtrPtr;
1123 const SkPoint* pts = (const SkPoint*)fReadStream.getAtPos();
1124 fReadStream.skip(sizeof(SkPoint) * count);
1125 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1126 "count:%d {", count);
1127 for (int index = 0; index < count; index++)
1128 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1129 "{x:%g y:%g}, ", SkScalarToFloat(pts[index].fX),
1130 SkScalarToFloat(pts[index].fY));
1131 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1132 "} ");
1133 *bufferPtrPtr = bufferPtr;
1134 }
1135
dumpPtr(char * bufferPtr,char * buffer,char * name,void * ptr)1136 int SkPicturePlayback::dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr) {
1137 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1138 "%s:%p, ", name, ptr);
1139 }
1140
dumpRectPtr(char * bufferPtr,char * buffer,char * name)1141 int SkPicturePlayback::dumpRectPtr(char* bufferPtr, char* buffer, char* name) {
1142 char result;
1143 fReadStream.read(&result, sizeof(result));
1144 if (result)
1145 return dumpRect(bufferPtr, buffer, name);
1146 else
1147 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1148 "%s:NULL, ", name);
1149 }
1150
dumpScalar(char * bufferPtr,char * buffer,char * name)1151 int SkPicturePlayback::dumpScalar(char* bufferPtr, char* buffer, char* name) {
1152 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer),
1153 "%s:%d, ", name, getScalar());
1154 }
1155
dumpText(char ** bufferPtrPtr,char * buffer)1156 void SkPicturePlayback::dumpText(char** bufferPtrPtr, char* buffer) {
1157 char* bufferPtr = *bufferPtrPtr;
1158 int length = getInt();
1159 bufferPtr += dumpDrawType(bufferPtr, buffer);
1160 fReadStream.skipToAlign4();
1161 char* text = (char*) fReadStream.getAtPos();
1162 fReadStream.skip(length);
1163 bufferPtr += dumpInt(bufferPtr, buffer, "length");
1164 int limit = DUMP_BUFFER_SIZE - (bufferPtr - buffer) - 2;
1165 length >>= 1;
1166 if (limit > length)
1167 limit = length;
1168 if (limit > 0) {
1169 *bufferPtr++ = '"';
1170 for (int index = 0; index < limit; index++) {
1171 *bufferPtr++ = *(unsigned short*) text;
1172 text += sizeof(unsigned short);
1173 }
1174 *bufferPtr++ = '"';
1175 }
1176 *bufferPtrPtr = bufferPtr;
1177 }
1178
1179 #define DUMP_DRAWTYPE(drawType) \
1180 bufferPtr += dumpDrawType(bufferPtr, buffer, drawType)
1181
1182 #define DUMP_INT(name) \
1183 bufferPtr += dumpInt(bufferPtr, buffer, #name)
1184
1185 #define DUMP_RECT_PTR(name) \
1186 bufferPtr += dumpRectPtr(bufferPtr, buffer, #name)
1187
1188 #define DUMP_POINT(name) \
1189 bufferPtr += dumpRect(bufferPtr, buffer, #name)
1190
1191 #define DUMP_RECT(name) \
1192 bufferPtr += dumpRect(bufferPtr, buffer, #name)
1193
1194 #define DUMP_POINT_ARRAY(count) \
1195 dumpPointArray(&bufferPtr, buffer, count)
1196
1197 #define DUMP_PTR(name, ptr) \
1198 bufferPtr += dumpPtr(bufferPtr, buffer, #name, (void*) ptr)
1199
1200 #define DUMP_SCALAR(name) \
1201 bufferPtr += dumpScalar(bufferPtr, buffer, #name)
1202
1203 #define DUMP_TEXT() \
1204 dumpText(&bufferPtr, buffer)
1205
dumpStream()1206 void SkPicturePlayback::dumpStream() {
1207 SkDebugf("RecordStream stream = {\n");
1208 DrawType drawType;
1209 TextContainer text;
1210 fReadStream.rewind();
1211 char buffer[DUMP_BUFFER_SIZE], * bufferPtr;
1212 while (fReadStream.read(&drawType, sizeof(drawType))) {
1213 bufferPtr = buffer;
1214 DUMP_DRAWTYPE(drawType);
1215 switch (drawType) {
1216 case CLIP_PATH: {
1217 DUMP_PTR(SkPath, &getPath());
1218 DUMP_INT(SkRegion::Op);
1219 DUMP_INT(offsetToRestore);
1220 } break;
1221 case CLIP_REGION: {
1222 DUMP_PTR(SkRegion, &getRegion());
1223 DUMP_INT(SkRegion::Op);
1224 DUMP_INT(offsetToRestore);
1225 } break;
1226 case CLIP_RECT: {
1227 DUMP_RECT(rect);
1228 DUMP_INT(SkRegion::Op);
1229 DUMP_INT(offsetToRestore);
1230 } break;
1231 case CONCAT:
1232 DUMP_PTR(SkMatrix, getMatrix());
1233 break;
1234 case DRAW_BITMAP: {
1235 DUMP_PTR(SkPaint, getPaint());
1236 DUMP_PTR(SkBitmap, &getBitmap());
1237 DUMP_SCALAR(left);
1238 DUMP_SCALAR(top);
1239 } break;
1240 case DRAW_PAINT:
1241 DUMP_PTR(SkPaint, getPaint());
1242 break;
1243 case DRAW_PATH: {
1244 DUMP_PTR(SkPaint, getPaint());
1245 DUMP_PTR(SkPath, &getPath());
1246 } break;
1247 case DRAW_PICTURE: {
1248 DUMP_PTR(SkPicture, &getPicture());
1249 } break;
1250 case DRAW_POINTS: {
1251 DUMP_PTR(SkPaint, getPaint());
1252 (void)getInt(); // PointMode
1253 size_t count = getInt();
1254 fReadStream.skipToAlign4();
1255 DUMP_POINT_ARRAY(count);
1256 } break;
1257 case DRAW_POS_TEXT: {
1258 DUMP_PTR(SkPaint, getPaint());
1259 DUMP_TEXT();
1260 size_t points = getInt();
1261 fReadStream.skipToAlign4();
1262 DUMP_POINT_ARRAY(points);
1263 } break;
1264 case DRAW_POS_TEXT_H: {
1265 DUMP_PTR(SkPaint, getPaint());
1266 DUMP_TEXT();
1267 size_t points = getInt();
1268 fReadStream.skipToAlign4();
1269 DUMP_SCALAR(top);
1270 DUMP_SCALAR(bottom);
1271 DUMP_SCALAR(constY);
1272 DUMP_POINT_ARRAY(points);
1273 } break;
1274 case DRAW_RECT: {
1275 DUMP_PTR(SkPaint, getPaint());
1276 DUMP_RECT(rect);
1277 } break;
1278 case DRAW_SPRITE: {
1279 DUMP_PTR(SkPaint, getPaint());
1280 DUMP_PTR(SkBitmap, &getBitmap());
1281 DUMP_SCALAR(left);
1282 DUMP_SCALAR(top);
1283 } break;
1284 case DRAW_TEXT: {
1285 DUMP_PTR(SkPaint, getPaint());
1286 DUMP_TEXT();
1287 DUMP_SCALAR(x);
1288 DUMP_SCALAR(y);
1289 } break;
1290 case DRAW_TEXT_ON_PATH: {
1291 DUMP_PTR(SkPaint, getPaint());
1292 DUMP_TEXT();
1293 DUMP_PTR(SkPath, &getPath());
1294 DUMP_PTR(SkMatrix, getMatrix());
1295 } break;
1296 case RESTORE:
1297 break;
1298 case ROTATE:
1299 DUMP_SCALAR(rotate);
1300 break;
1301 case SAVE:
1302 DUMP_INT(SkCanvas::SaveFlags);
1303 break;
1304 case SAVE_LAYER: {
1305 DUMP_RECT_PTR(layer);
1306 DUMP_PTR(SkPaint, getPaint());
1307 DUMP_INT(SkCanvas::SaveFlags);
1308 } break;
1309 case SCALE: {
1310 DUMP_SCALAR(sx);
1311 DUMP_SCALAR(sy);
1312 } break;
1313 case SKEW: {
1314 DUMP_SCALAR(sx);
1315 DUMP_SCALAR(sy);
1316 } break;
1317 case TRANSLATE: {
1318 DUMP_SCALAR(dx);
1319 DUMP_SCALAR(dy);
1320 } break;
1321 default:
1322 SkASSERT(0);
1323 }
1324 SkDebugf("%s\n", buffer);
1325 }
1326 }
1327
dump() const1328 void SkPicturePlayback::dump() const {
1329 char pBuffer[DUMP_BUFFER_SIZE];
1330 char* bufferPtr = pBuffer;
1331 int index;
1332 if (fBitmapCount > 0)
1333 SkDebugf("// bitmaps (%d)\n", fBitmapCount);
1334 for (index = 0; index < fBitmapCount; index++) {
1335 const SkBitmap& bitmap = fBitmaps[index];
1336 dumpBitmap(bitmap);
1337 }
1338 if (fBitmapCount > 0)
1339 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1340 "Bitmaps bitmaps = {");
1341 for (index = 0; index < fBitmapCount; index++)
1342 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1343 "bitmap%p, ", &fBitmaps[index]);
1344 if (fBitmapCount > 0)
1345 SkDebugf("%s0};\n", pBuffer);
1346
1347 if (fMatrixCount > 0)
1348 SkDebugf("// matrices (%d)\n", fMatrixCount);
1349 for (index = 0; index < fMatrixCount; index++) {
1350 const SkMatrix& matrix = fMatrices[index];
1351 dumpMatrix(matrix);
1352 }
1353 bufferPtr = pBuffer;
1354 if (fMatrixCount > 0)
1355 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1356 "Matrices matrices = {");
1357 for (index = 0; index < fMatrixCount; index++)
1358 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1359 "matrix%p, ", &fMatrices[index]);
1360 if (fMatrixCount > 0)
1361 SkDebugf("%s0};\n", pBuffer);
1362
1363 if (fPaintCount > 0)
1364 SkDebugf("// paints (%d)\n", fPaintCount);
1365 for (index = 0; index < fPaintCount; index++) {
1366 const SkPaint& paint = fPaints[index];
1367 dumpPaint(paint);
1368 }
1369 bufferPtr = pBuffer;
1370 if (fPaintCount > 0)
1371 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1372 "Paints paints = {");
1373 for (index = 0; index < fPaintCount; index++)
1374 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1375 "paint%p, ", &fPaints[index]);
1376 if (fPaintCount > 0)
1377 SkDebugf("%s0};\n", pBuffer);
1378
1379 for (index = 0; index < fPathCount; index++) {
1380 const SkPath& path = fPaths[index];
1381 dumpPath(path);
1382 }
1383 bufferPtr = pBuffer;
1384 if (fPathCount > 0)
1385 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1386 "Paths paths = {");
1387 for (index = 0; index < fPathCount; index++)
1388 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1389 "path%p, ", &fPaths[index]);
1390 if (fPathCount > 0)
1391 SkDebugf("%s0};\n", pBuffer);
1392
1393 for (index = 0; index < fPictureCount; index++) {
1394 dumpPicture(*fPictureRefs[index]);
1395 }
1396 bufferPtr = pBuffer;
1397 if (fPictureCount > 0)
1398 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1399 "Pictures pictures = {");
1400 for (index = 0; index < fPictureCount; index++)
1401 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1402 "picture%p, ", fPictureRefs[index]);
1403 if (fPictureCount > 0)
1404 SkDebugf("%s0};\n", pBuffer);
1405
1406 for (index = 0; index < fRegionCount; index++) {
1407 const SkRegion& region = fRegions[index];
1408 dumpRegion(region);
1409 }
1410 bufferPtr = pBuffer;
1411 if (fRegionCount > 0)
1412 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1413 "Regions regions = {");
1414 for (index = 0; index < fRegionCount; index++)
1415 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer),
1416 "region%p, ", &fRegions[index]);
1417 if (fRegionCount > 0)
1418 SkDebugf("%s0};\n", pBuffer);
1419
1420 const_cast<SkPicturePlayback*>(this)->dumpStream();
1421 }
1422
1423 #endif
1424