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