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