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