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 18SkPicturePlayback::SkPicturePlayback() { 19 this->init(); 20} 21 22SkPicturePlayback::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 163SkPicturePlayback::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 209void 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 222SkPicturePlayback::~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 240void 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 270static void writeTagSize(SkFlattenableWriteBuffer& buffer, uint32_t tag, 271 uint32_t size) { 272 buffer.write32(tag); 273 buffer.write32(size); 274} 275 276static void writeTagSize(SkWStream* stream, uint32_t tag, 277 uint32_t size) { 278 stream->write32(tag); 279 stream->write32(size); 280} 281 282static 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 304static 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 318void 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 379static 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 387static 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 395SkPicturePlayback::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 486struct SkipClipRec { 487 int fCount; 488 size_t fSize; 489 490 SkipClipRec() { 491 fCount = 0; 492 fSize = 0; 493 } 494 495 void recordSkip(size_t bytes) { 496 fCount += 1; 497 fSize += bytes; 498 } 499}; 500#endif 501 502void 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 767void SkPicturePlayback::abort() { 768 fReader.skip(fReader.size() - fReader.offset()); 769} 770 771/////////////////////////////////////////////////////////////////////////////// 772 773#if 0 774uint32_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 831void 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 882int 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 892int 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 902int 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 912int 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 922int 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 934void 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 949void 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 991void 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 1091void SkPicturePlayback::dumpPath(const SkPath& path) const { 1092 SkDebugf("path dump unimplemented\n"); 1093} 1094 1095void SkPicturePlayback::dumpPicture(const SkPicture& picture) const { 1096 SkDebugf("picture dump unimplemented\n"); 1097} 1098 1099void SkPicturePlayback::dumpRegion(const SkRegion& region) const { 1100 SkDebugf("region dump unimplemented\n"); 1101} 1102 1103int SkPicturePlayback::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) { 1104 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1105 "k%s, ", DrawTypeToString(drawType)); 1106} 1107 1108int SkPicturePlayback::dumpInt(char* bufferPtr, char* buffer, char* name) { 1109 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1110 "%s:%d, ", name, getInt()); 1111} 1112 1113int 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 1121int 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 1129void 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 1144int 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 1149int 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 1159int SkPicturePlayback::dumpScalar(char* bufferPtr, char* buffer, char* name) { 1160 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1161 "%s:%d, ", name, getScalar()); 1162} 1163 1164void 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 1214void 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 1336void 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