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