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