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