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_H: { 629 const SkPaint& paint = *getPaint(); 630 getText(&text); 631 size_t xCount = getInt(); 632 const SkScalar constY = getScalar(); 633 const SkScalar* xpos = (const SkScalar*)fReader.skip(xCount * sizeof(SkScalar)); 634 canvas.drawPosTextH(text.text(), text.length(), xpos, constY, 635 paint); 636 } break; 637 case DRAW_POS_TEXT_H_TOP_BOTTOM: { 638 const SkPaint& paint = *getPaint(); 639 getText(&text); 640 size_t xCount = getInt(); 641 const SkScalar* xpos = (const SkScalar*)fReader.skip((3 + xCount) * sizeof(SkScalar)); 642 const SkScalar top = *xpos++; 643 const SkScalar bottom = *xpos++; 644 const SkScalar constY = *xpos++; 645 if (!canvas.quickRejectY(top, bottom, SkCanvas::kAA_EdgeType)) { 646 canvas.drawPosTextH(text.text(), text.length(), xpos, 647 constY, paint); 648 } 649 } break; 650 case DRAW_RECT: { 651 const SkPaint& paint = *getPaint(); 652 canvas.drawRect(*fReader.skipRect(), paint); 653 } break; 654 case DRAW_SHAPE: { 655 SkShape* shape = getShape(); 656 if (shape) { 657 canvas.drawShape(shape); 658 } 659 } break; 660 case DRAW_SPRITE: { 661 const SkPaint* paint = getPaint(); 662 const SkBitmap& bitmap = getBitmap(); 663 int left = getInt(); 664 int top = getInt(); 665 canvas.drawSprite(bitmap, left, top, paint); 666 } break; 667 case DRAW_TEXT: { 668 const SkPaint& paint = *getPaint(); 669 getText(&text); 670 SkScalar x = getScalar(); 671 SkScalar y = getScalar(); 672 canvas.drawText(text.text(), text.length(), x, y, paint); 673 } break; 674 case DRAW_TEXT_TOP_BOTTOM: { 675 const SkPaint& paint = *getPaint(); 676 getText(&text); 677 const SkScalar* ptr = (const SkScalar*)fReader.skip(4 * sizeof(SkScalar)); 678 // ptr[0] == x 679 // ptr[1] == y 680 // ptr[2] == top 681 // ptr[3] == bottom 682 if (!canvas.quickRejectY(ptr[2], ptr[3], 683 SkCanvas::kAA_EdgeType)) { 684 canvas.drawText(text.text(), text.length(), ptr[0], ptr[1], 685 paint); 686 } 687 } break; 688 case DRAW_TEXT_ON_PATH: { 689 const SkPaint& paint = *getPaint(); 690 getText(&text); 691 const SkPath& path = getPath(); 692 const SkMatrix* matrix = getMatrix(); 693 canvas.drawTextOnPath(text.text(), text.length(), path, 694 matrix, paint); 695 } break; 696 case DRAW_VERTICES: { 697 const SkPaint& paint = *getPaint(); 698 DrawVertexFlags flags = (DrawVertexFlags)getInt(); 699 SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)getInt(); 700 int vCount = getInt(); 701 const SkPoint* verts = (const SkPoint*)fReader.skip( 702 vCount * sizeof(SkPoint)); 703 const SkPoint* texs = NULL; 704 const SkColor* colors = NULL; 705 const uint16_t* indices = NULL; 706 int iCount = 0; 707 if (flags & DRAW_VERTICES_HAS_TEXS) { 708 texs = (const SkPoint*)fReader.skip( 709 vCount * sizeof(SkPoint)); 710 } 711 if (flags & DRAW_VERTICES_HAS_COLORS) { 712 colors = (const SkColor*)fReader.skip( 713 vCount * sizeof(SkColor)); 714 } 715 if (flags & DRAW_VERTICES_HAS_INDICES) { 716 iCount = getInt(); 717 indices = (const uint16_t*)fReader.skip( 718 iCount * sizeof(uint16_t)); 719 } 720 canvas.drawVertices(vmode, vCount, verts, texs, colors, NULL, 721 indices, iCount, paint); 722 } break; 723 case RESTORE: 724 canvas.restore(); 725 break; 726 case ROTATE: 727 canvas.rotate(getScalar()); 728 break; 729 case SAVE: 730 canvas.save((SkCanvas::SaveFlags) getInt()); 731 break; 732 case SAVE_LAYER: { 733 const SkRect* boundsPtr = getRectPtr(); 734 const SkPaint* paint = getPaint(); 735 canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) getInt()); 736 } break; 737 case SCALE: { 738 SkScalar sx = getScalar(); 739 SkScalar sy = getScalar(); 740 canvas.scale(sx, sy); 741 } break; 742 case SET_MATRIX: 743 canvas.setMatrix(*getMatrix()); 744 break; 745 case SKEW: { 746 SkScalar sx = getScalar(); 747 SkScalar sy = getScalar(); 748 canvas.skew(sx, sy); 749 } break; 750 case TRANSLATE: { 751 SkScalar dx = getScalar(); 752 SkScalar dy = getScalar(); 753 canvas.translate(dx, dy); 754 } break; 755 default: 756 SkASSERT(0); 757 } 758 } 759 760 #ifdef SPEW_CLIP_SKIPPING 761 { 762 size_t size = skipRect.fSize + skipPath.fSize + skipRegion.fSize; 763 SkDebugf("--- Clip skips %d%% rect:%d path:%d rgn:%d\n", 764 size * 100 / fReader.offset(), skipRect.fCount, skipPath.fCount, 765 skipRegion.fCount); 766 } 767 #endif 768 // this->dumpSize(); 769 } 770 771 void SkPicturePlayback::abort() { 772 fReader.skip(fReader.size() - fReader.offset()); 773 } 774 775 /////////////////////////////////////////////////////////////////////////////// 776 777 #if 0 778 uint32_t SkPicturePlayback::flatten(void* storage) const { 779 SkWBuffer buffer(storage); 780 buffer.write32(fBitmapCount); 781 int index; 782 for (index = 0; index < fBitmapCount; index++) { 783 const SkBitmap& bitmap = fBitmaps[index]; 784 uint32_t size = bitmap.flatten(NULL, true); 785 buffer.write32(size); 786 void* local = buffer.skip(size); 787 bitmap.flatten(local, true); 788 } 789 buffer.write32(fPaintCount); 790 for (index = 0; index < fPaintCount; index++) { 791 SkFlattenableWriteBuffer flatWrite; 792 const SkPaint& paint = fPaints[index]; 793 SkFlatPaint::Write(&flatWrite, paint); 794 uint32_t size = flatWrite.pos(); 795 buffer.write32(size); 796 void* local = buffer.skip(size); 797 flatWrite.reset(local); 798 SkFlatPaint::Write(&flatWrite, paint); 799 } 800 buffer.write32(fPathCount); 801 for (index = 0; index < fPathCount; index++) { 802 const SkPath& path = fPaths[index]; 803 uint32_t size = path.flatten(NULL); 804 buffer.write32(size); 805 void* local = buffer.skip(size); 806 path.flatten(local); 807 } 808 809 #if 0 810 buffer.write32(fPictureCount); 811 for (index = 0; index < fPictureCount; index++) { 812 const SkPicture& picture = fPictures[index]; 813 uint32_t size = picture.flatten(NULL); 814 buffer.write32(size); 815 void* local = buffer.skip(size); 816 picture.flatten(local); 817 } 818 #endif 819 820 buffer.write32(fRegionCount); 821 for (index = 0; index < fRegionCount; index++) { 822 const SkRegion& region = fRegions[index]; 823 size_t size = region.computeBufferSize(); 824 buffer.write32(size); 825 void* local = buffer.skip(size); 826 region.writeToBuffer(local); 827 } 828 fReader.rewind(); 829 size_t length = fReader.size(); 830 buffer.write32(length); 831 memcpy(buffer.skip(length), fReader.base(), length); 832 return (uint32_t) buffer.pos(); 833 } 834 835 void SkPicturePlayback::unflatten(const void* storage) { 836 SkRBuffer buffer(storage); 837 int index; 838 fBitmapCount = buffer.readU32(); 839 fBitmaps = new SkBitmap[fBitmapCount]; 840 for (index = 0; index < fBitmapCount; index++) { 841 uint32_t size = buffer.readU32(); 842 const void* local = buffer.skip(size); 843 fBitmaps[index].unflatten(local); 844 } 845 fPaintCount = buffer.readU32(); 846 fPaints = new SkPaint[fPaintCount]; 847 for (index = 0; index < fPaintCount; index++) { 848 uint32_t size = buffer.readU32(); 849 const void* local = buffer.skip(size); 850 SkFlatPaint::Read(local, &fPaints[index]); 851 } 852 fPathCount = buffer.readU32(); 853 fPaths = new SkPath[fPathCount]; 854 for (index = 0; index < fPathCount; index++) { 855 uint32_t size = buffer.readU32(); 856 const void* local = buffer.skip(size); 857 fPaths[index].unflatten(local); 858 } 859 860 #if 0 861 fPictureCount = buffer.readU32(); 862 fPictures = new SkPicture[fPictureCount]; 863 for (index = 0; index < fPictureCount; index++) { 864 uint32_t size = buffer.readU32(); 865 const void* local = buffer.skip(size); 866 fPictures[index].unflatten(local); 867 } 868 #endif 869 870 fRegionCount = buffer.readU32(); 871 fRegions = new SkRegion[fRegionCount]; 872 for (index = 0; index < fRegionCount; index++) { 873 uint32_t size = buffer.readU32(); 874 const void* local = buffer.skip(size); 875 fRegions[index].readFromBuffer(local); 876 } 877 int32_t length = buffer.readS32(); 878 const void* stream = buffer.skip(length); 879 fReader.setMemory(stream, length); 880 } 881 #endif 882 883 /////////////////////////////////////////////////////////////////////////////// 884 885 #ifdef SK_DEBUG_SIZE 886 int SkPicturePlayback::size(size_t* sizePtr) { 887 int objects = bitmaps(sizePtr); 888 objects += paints(sizePtr); 889 objects += paths(sizePtr); 890 objects += pictures(sizePtr); 891 objects += regions(sizePtr); 892 *sizePtr = fReader.size(); 893 return objects; 894 } 895 896 int SkPicturePlayback::bitmaps(size_t* size) { 897 size_t result = 0; 898 for (int index = 0; index < fBitmapCount; index++) { 899 // const SkBitmap& bitmap = fBitmaps[index]; 900 result += sizeof(SkBitmap); // bitmap->size(); 901 } 902 *size = result; 903 return fBitmapCount; 904 } 905 906 int SkPicturePlayback::paints(size_t* size) { 907 size_t result = 0; 908 for (int index = 0; index < fPaintCount; index++) { 909 // const SkPaint& paint = fPaints[index]; 910 result += sizeof(SkPaint); // paint->size(); 911 } 912 *size = result; 913 return fPaintCount; 914 } 915 916 int SkPicturePlayback::paths(size_t* size) { 917 size_t result = 0; 918 for (int index = 0; index < fPathCount; index++) { 919 const SkPath& path = fPaths[index]; 920 result += path.flatten(NULL); 921 } 922 *size = result; 923 return fPathCount; 924 } 925 926 int SkPicturePlayback::regions(size_t* size) { 927 size_t result = 0; 928 for (int index = 0; index < fRegionCount; index++) { 929 // const SkRegion& region = fRegions[index]; 930 result += sizeof(SkRegion); // region->size(); 931 } 932 *size = result; 933 return fRegionCount; 934 } 935 #endif 936 937 #ifdef SK_DEBUG_DUMP 938 void SkPicturePlayback::dumpBitmap(const SkBitmap& bitmap) const { 939 char pBuffer[DUMP_BUFFER_SIZE]; 940 char* bufferPtr = pBuffer; 941 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 942 "BitmapData bitmap%p = {", &bitmap); 943 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 944 "{kWidth, %d}, ", bitmap.width()); 945 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 946 "{kHeight, %d}, ", bitmap.height()); 947 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 948 "{kRowBytes, %d}, ", bitmap.rowBytes()); 949 // start here; 950 SkDebugf("%s{0}};\n", pBuffer); 951 } 952 953 void dumpMatrix(const SkMatrix& matrix) const { 954 SkMatrix defaultMatrix; 955 defaultMatrix.reset(); 956 char pBuffer[DUMP_BUFFER_SIZE]; 957 char* bufferPtr = pBuffer; 958 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 959 "MatrixData matrix%p = {", &matrix); 960 SkScalar scaleX = matrix.getScaleX(); 961 if (scaleX != defaultMatrix.getScaleX()) 962 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 963 "{kScaleX, %g}, ", SkScalarToFloat(scaleX)); 964 SkScalar scaleY = matrix.getScaleY(); 965 if (scaleY != defaultMatrix.getScaleY()) 966 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 967 "{kScaleY, %g}, ", SkScalarToFloat(scaleY)); 968 SkScalar skewX = matrix.getSkewX(); 969 if (skewX != defaultMatrix.getSkewX()) 970 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 971 "{kSkewX, %g}, ", SkScalarToFloat(skewX)); 972 SkScalar skewY = matrix.getSkewY(); 973 if (skewY != defaultMatrix.getSkewY()) 974 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 975 "{kSkewY, %g}, ", SkScalarToFloat(skewY)); 976 SkScalar translateX = matrix.getTranslateX(); 977 if (translateX != defaultMatrix.getTranslateX()) 978 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 979 "{kTranslateX, %g}, ", SkScalarToFloat(translateX)); 980 SkScalar translateY = matrix.getTranslateY(); 981 if (translateY != defaultMatrix.getTranslateY()) 982 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 983 "{kTranslateY, %g}, ", SkScalarToFloat(translateY)); 984 SkScalar perspX = matrix.getPerspX(); 985 if (perspX != defaultMatrix.getPerspX()) 986 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 987 "{kPerspX, %g}, ", SkFractToFloat(perspX)); 988 SkScalar perspY = matrix.getPerspY(); 989 if (perspY != defaultMatrix.getPerspY()) 990 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 991 "{kPerspY, %g}, ", SkFractToFloat(perspY)); 992 SkDebugf("%s{0}};\n", pBuffer); 993 } 994 995 void dumpPaint(const SkPaint& paint) const { 996 SkPaint defaultPaint; 997 char pBuffer[DUMP_BUFFER_SIZE]; 998 char* bufferPtr = pBuffer; 999 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1000 "PaintPointers paintPtrs%p = {", &paint); 1001 const SkTypeface* typeface = paint.getTypeface(); 1002 if (typeface != defaultPaint.getTypeface()) 1003 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1004 "{kTypeface, %p}, ", typeface); 1005 const SkPathEffect* pathEffect = paint.getPathEffect(); 1006 if (pathEffect != defaultPaint.getPathEffect()) 1007 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1008 "{kPathEffect, %p}, ", pathEffect); 1009 const SkShader* shader = paint.getShader(); 1010 if (shader != defaultPaint.getShader()) 1011 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1012 "{kShader, %p}, ", shader); 1013 const SkXfermode* xfermode = paint.getXfermode(); 1014 if (xfermode != defaultPaint.getXfermode()) 1015 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1016 "{kXfermode, %p}, ", xfermode); 1017 const SkMaskFilter* maskFilter = paint.getMaskFilter(); 1018 if (maskFilter != defaultPaint.getMaskFilter()) 1019 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1020 "{kMaskFilter, %p}, ", maskFilter); 1021 const SkColorFilter* colorFilter = paint.getColorFilter(); 1022 if (colorFilter != defaultPaint.getColorFilter()) 1023 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1024 "{kColorFilter, %p}, ", colorFilter); 1025 const SkRasterizer* rasterizer = paint.getRasterizer(); 1026 if (rasterizer != defaultPaint.getRasterizer()) 1027 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1028 "{kRasterizer, %p}, ", rasterizer); 1029 const SkDrawLooper* drawLooper = paint.getLooper(); 1030 if (drawLooper != defaultPaint.getLooper()) 1031 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1032 "{kDrawLooper, %p}, ", drawLooper); 1033 SkDebugf("%s{0}};\n", pBuffer); 1034 bufferPtr = pBuffer; 1035 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1036 "PaintScalars paintScalars%p = {", &paint); 1037 SkScalar textSize = paint.getTextSize(); 1038 if (textSize != defaultPaint.getTextSize()) 1039 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1040 "{kTextSize, %g}, ", SkScalarToFloat(textSize)); 1041 SkScalar textScaleX = paint.getTextScaleX(); 1042 if (textScaleX != defaultPaint.getTextScaleX()) 1043 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1044 "{kTextScaleX, %g}, ", SkScalarToFloat(textScaleX)); 1045 SkScalar textSkewX = paint.getTextSkewX(); 1046 if (textSkewX != defaultPaint.getTextSkewX()) 1047 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1048 "{kTextSkewX, %g}, ", SkScalarToFloat(textSkewX)); 1049 SkScalar strokeWidth = paint.getStrokeWidth(); 1050 if (strokeWidth != defaultPaint.getStrokeWidth()) 1051 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1052 "{kStrokeWidth, %g}, ", SkScalarToFloat(strokeWidth)); 1053 SkScalar strokeMiter = paint.getStrokeMiter(); 1054 if (strokeMiter != defaultPaint.getStrokeMiter()) 1055 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1056 "{kStrokeMiter, %g}, ", SkScalarToFloat(strokeMiter)); 1057 SkDebugf("%s{0}};\n", pBuffer); 1058 bufferPtr = pBuffer; 1059 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1060 "PaintInts = paintInts%p = {", &paint); 1061 unsigned color = paint.getColor(); 1062 if (color != defaultPaint.getColor()) 1063 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1064 "{kColor, 0x%x}, ", color); 1065 unsigned flags = paint.getFlags(); 1066 if (flags != defaultPaint.getFlags()) 1067 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1068 "{kFlags, 0x%x}, ", flags); 1069 int align = paint.getTextAlign(); 1070 if (align != defaultPaint.getTextAlign()) 1071 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1072 "{kAlign, 0x%x}, ", align); 1073 int strokeCap = paint.getStrokeCap(); 1074 if (strokeCap != defaultPaint.getStrokeCap()) 1075 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1076 "{kStrokeCap, 0x%x}, ", strokeCap); 1077 int strokeJoin = paint.getStrokeJoin(); 1078 if (strokeJoin != defaultPaint.getStrokeJoin()) 1079 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1080 "{kAlign, 0x%x}, ", strokeJoin); 1081 int style = paint.getStyle(); 1082 if (style != defaultPaint.getStyle()) 1083 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1084 "{kStyle, 0x%x}, ", style); 1085 int textEncoding = paint.getTextEncoding(); 1086 if (textEncoding != defaultPaint.getTextEncoding()) 1087 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1088 "{kTextEncoding, 0x%x}, ", textEncoding); 1089 SkDebugf("%s{0}};\n", pBuffer); 1090 1091 SkDebugf("PaintData paint%p = {paintPtrs%p, paintScalars%p, paintInts%p};\n", 1092 &paint, &paint, &paint, &paint); 1093 } 1094 1095 void SkPicturePlayback::dumpPath(const SkPath& path) const { 1096 SkDebugf("path dump unimplemented\n"); 1097 } 1098 1099 void SkPicturePlayback::dumpPicture(const SkPicture& picture) const { 1100 SkDebugf("picture dump unimplemented\n"); 1101 } 1102 1103 void SkPicturePlayback::dumpRegion(const SkRegion& region) const { 1104 SkDebugf("region dump unimplemented\n"); 1105 } 1106 1107 int SkPicturePlayback::dumpDrawType(char* bufferPtr, char* buffer, DrawType drawType) { 1108 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1109 "k%s, ", DrawTypeToString(drawType)); 1110 } 1111 1112 int SkPicturePlayback::dumpInt(char* bufferPtr, char* buffer, char* name) { 1113 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1114 "%s:%d, ", name, getInt()); 1115 } 1116 1117 int SkPicturePlayback::dumpRect(char* bufferPtr, char* buffer, char* name) { 1118 const SkRect* rect = fReader.skipRect(); 1119 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1120 "%s:{l:%g t:%g r:%g b:%g}, ", name, SkScalarToFloat(rect.fLeft), 1121 SkScalarToFloat(rect.fTop), 1122 SkScalarToFloat(rect.fRight), SkScalarToFloat(rect.fBottom)); 1123 } 1124 1125 int SkPicturePlayback::dumpPoint(char* bufferPtr, char* buffer, char* name) { 1126 SkPoint pt; 1127 getPoint(&pt); 1128 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1129 "%s:{x:%g y:%g}, ", name, SkScalarToFloat(pt.fX), 1130 SkScalarToFloat(pt.fY)); 1131 } 1132 1133 void SkPicturePlayback::dumpPointArray(char** bufferPtrPtr, char* buffer, int count) { 1134 char* bufferPtr = *bufferPtrPtr; 1135 const SkPoint* pts = (const SkPoint*)fReadStream.getAtPos(); 1136 fReadStream.skip(sizeof(SkPoint) * count); 1137 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1138 "count:%d {", count); 1139 for (int index = 0; index < count; index++) 1140 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1141 "{x:%g y:%g}, ", SkScalarToFloat(pts[index].fX), 1142 SkScalarToFloat(pts[index].fY)); 1143 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1144 "} "); 1145 *bufferPtrPtr = bufferPtr; 1146 } 1147 1148 int SkPicturePlayback::dumpPtr(char* bufferPtr, char* buffer, char* name, void* ptr) { 1149 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1150 "%s:%p, ", name, ptr); 1151 } 1152 1153 int SkPicturePlayback::dumpRectPtr(char* bufferPtr, char* buffer, char* name) { 1154 char result; 1155 fReadStream.read(&result, sizeof(result)); 1156 if (result) 1157 return dumpRect(bufferPtr, buffer, name); 1158 else 1159 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1160 "%s:NULL, ", name); 1161 } 1162 1163 int SkPicturePlayback::dumpScalar(char* bufferPtr, char* buffer, char* name) { 1164 return snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - buffer), 1165 "%s:%d, ", name, getScalar()); 1166 } 1167 1168 void SkPicturePlayback::dumpText(char** bufferPtrPtr, char* buffer) { 1169 char* bufferPtr = *bufferPtrPtr; 1170 int length = getInt(); 1171 bufferPtr += dumpDrawType(bufferPtr, buffer); 1172 fReadStream.skipToAlign4(); 1173 char* text = (char*) fReadStream.getAtPos(); 1174 fReadStream.skip(length); 1175 bufferPtr += dumpInt(bufferPtr, buffer, "length"); 1176 int limit = DUMP_BUFFER_SIZE - (bufferPtr - buffer) - 2; 1177 length >>= 1; 1178 if (limit > length) 1179 limit = length; 1180 if (limit > 0) { 1181 *bufferPtr++ = '"'; 1182 for (int index = 0; index < limit; index++) { 1183 *bufferPtr++ = *(unsigned short*) text; 1184 text += sizeof(unsigned short); 1185 } 1186 *bufferPtr++ = '"'; 1187 } 1188 *bufferPtrPtr = bufferPtr; 1189 } 1190 1191 #define DUMP_DRAWTYPE(drawType) \ 1192 bufferPtr += dumpDrawType(bufferPtr, buffer, drawType) 1193 1194 #define DUMP_INT(name) \ 1195 bufferPtr += dumpInt(bufferPtr, buffer, #name) 1196 1197 #define DUMP_RECT_PTR(name) \ 1198 bufferPtr += dumpRectPtr(bufferPtr, buffer, #name) 1199 1200 #define DUMP_POINT(name) \ 1201 bufferPtr += dumpRect(bufferPtr, buffer, #name) 1202 1203 #define DUMP_RECT(name) \ 1204 bufferPtr += dumpRect(bufferPtr, buffer, #name) 1205 1206 #define DUMP_POINT_ARRAY(count) \ 1207 dumpPointArray(&bufferPtr, buffer, count) 1208 1209 #define DUMP_PTR(name, ptr) \ 1210 bufferPtr += dumpPtr(bufferPtr, buffer, #name, (void*) ptr) 1211 1212 #define DUMP_SCALAR(name) \ 1213 bufferPtr += dumpScalar(bufferPtr, buffer, #name) 1214 1215 #define DUMP_TEXT() \ 1216 dumpText(&bufferPtr, buffer) 1217 1218 void SkPicturePlayback::dumpStream() { 1219 SkDebugf("RecordStream stream = {\n"); 1220 DrawType drawType; 1221 TextContainer text; 1222 fReadStream.rewind(); 1223 char buffer[DUMP_BUFFER_SIZE], * bufferPtr; 1224 while (fReadStream.read(&drawType, sizeof(drawType))) { 1225 bufferPtr = buffer; 1226 DUMP_DRAWTYPE(drawType); 1227 switch (drawType) { 1228 case CLIP_PATH: { 1229 DUMP_PTR(SkPath, &getPath()); 1230 DUMP_INT(SkRegion::Op); 1231 DUMP_INT(offsetToRestore); 1232 } break; 1233 case CLIP_REGION: { 1234 DUMP_PTR(SkRegion, &getRegion()); 1235 DUMP_INT(SkRegion::Op); 1236 DUMP_INT(offsetToRestore); 1237 } break; 1238 case CLIP_RECT: { 1239 DUMP_RECT(rect); 1240 DUMP_INT(SkRegion::Op); 1241 DUMP_INT(offsetToRestore); 1242 } break; 1243 case CONCAT: 1244 DUMP_PTR(SkMatrix, getMatrix()); 1245 break; 1246 case DRAW_BITMAP: { 1247 DUMP_PTR(SkPaint, getPaint()); 1248 DUMP_PTR(SkBitmap, &getBitmap()); 1249 DUMP_SCALAR(left); 1250 DUMP_SCALAR(top); 1251 } break; 1252 case DRAW_PAINT: 1253 DUMP_PTR(SkPaint, getPaint()); 1254 break; 1255 case DRAW_PATH: { 1256 DUMP_PTR(SkPaint, getPaint()); 1257 DUMP_PTR(SkPath, &getPath()); 1258 } break; 1259 case DRAW_PICTURE: { 1260 DUMP_PTR(SkPicture, &getPicture()); 1261 } break; 1262 case DRAW_POINTS: { 1263 DUMP_PTR(SkPaint, getPaint()); 1264 (void)getInt(); // PointMode 1265 size_t count = getInt(); 1266 fReadStream.skipToAlign4(); 1267 DUMP_POINT_ARRAY(count); 1268 } break; 1269 case DRAW_POS_TEXT: { 1270 DUMP_PTR(SkPaint, getPaint()); 1271 DUMP_TEXT(); 1272 size_t points = getInt(); 1273 fReadStream.skipToAlign4(); 1274 DUMP_POINT_ARRAY(points); 1275 } break; 1276 case DRAW_POS_TEXT_H: { 1277 DUMP_PTR(SkPaint, getPaint()); 1278 DUMP_TEXT(); 1279 size_t points = getInt(); 1280 fReadStream.skipToAlign4(); 1281 DUMP_SCALAR(top); 1282 DUMP_SCALAR(bottom); 1283 DUMP_SCALAR(constY); 1284 DUMP_POINT_ARRAY(points); 1285 } break; 1286 case DRAW_RECT: { 1287 DUMP_PTR(SkPaint, getPaint()); 1288 DUMP_RECT(rect); 1289 } break; 1290 case DRAW_SPRITE: { 1291 DUMP_PTR(SkPaint, getPaint()); 1292 DUMP_PTR(SkBitmap, &getBitmap()); 1293 DUMP_SCALAR(left); 1294 DUMP_SCALAR(top); 1295 } break; 1296 case DRAW_TEXT: { 1297 DUMP_PTR(SkPaint, getPaint()); 1298 DUMP_TEXT(); 1299 DUMP_SCALAR(x); 1300 DUMP_SCALAR(y); 1301 } break; 1302 case DRAW_TEXT_ON_PATH: { 1303 DUMP_PTR(SkPaint, getPaint()); 1304 DUMP_TEXT(); 1305 DUMP_PTR(SkPath, &getPath()); 1306 DUMP_PTR(SkMatrix, getMatrix()); 1307 } break; 1308 case RESTORE: 1309 break; 1310 case ROTATE: 1311 DUMP_SCALAR(rotate); 1312 break; 1313 case SAVE: 1314 DUMP_INT(SkCanvas::SaveFlags); 1315 break; 1316 case SAVE_LAYER: { 1317 DUMP_RECT_PTR(layer); 1318 DUMP_PTR(SkPaint, getPaint()); 1319 DUMP_INT(SkCanvas::SaveFlags); 1320 } break; 1321 case SCALE: { 1322 DUMP_SCALAR(sx); 1323 DUMP_SCALAR(sy); 1324 } break; 1325 case SKEW: { 1326 DUMP_SCALAR(sx); 1327 DUMP_SCALAR(sy); 1328 } break; 1329 case TRANSLATE: { 1330 DUMP_SCALAR(dx); 1331 DUMP_SCALAR(dy); 1332 } break; 1333 default: 1334 SkASSERT(0); 1335 } 1336 SkDebugf("%s\n", buffer); 1337 } 1338 } 1339 1340 void SkPicturePlayback::dump() const { 1341 char pBuffer[DUMP_BUFFER_SIZE]; 1342 char* bufferPtr = pBuffer; 1343 int index; 1344 if (fBitmapCount > 0) 1345 SkDebugf("// bitmaps (%d)\n", fBitmapCount); 1346 for (index = 0; index < fBitmapCount; index++) { 1347 const SkBitmap& bitmap = fBitmaps[index]; 1348 dumpBitmap(bitmap); 1349 } 1350 if (fBitmapCount > 0) 1351 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1352 "Bitmaps bitmaps = {"); 1353 for (index = 0; index < fBitmapCount; index++) 1354 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1355 "bitmap%p, ", &fBitmaps[index]); 1356 if (fBitmapCount > 0) 1357 SkDebugf("%s0};\n", pBuffer); 1358 1359 if (fMatrixCount > 0) 1360 SkDebugf("// matrices (%d)\n", fMatrixCount); 1361 for (index = 0; index < fMatrixCount; index++) { 1362 const SkMatrix& matrix = fMatrices[index]; 1363 dumpMatrix(matrix); 1364 } 1365 bufferPtr = pBuffer; 1366 if (fMatrixCount > 0) 1367 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1368 "Matrices matrices = {"); 1369 for (index = 0; index < fMatrixCount; index++) 1370 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1371 "matrix%p, ", &fMatrices[index]); 1372 if (fMatrixCount > 0) 1373 SkDebugf("%s0};\n", pBuffer); 1374 1375 if (fPaintCount > 0) 1376 SkDebugf("// paints (%d)\n", fPaintCount); 1377 for (index = 0; index < fPaintCount; index++) { 1378 const SkPaint& paint = fPaints[index]; 1379 dumpPaint(paint); 1380 } 1381 bufferPtr = pBuffer; 1382 if (fPaintCount > 0) 1383 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1384 "Paints paints = {"); 1385 for (index = 0; index < fPaintCount; index++) 1386 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1387 "paint%p, ", &fPaints[index]); 1388 if (fPaintCount > 0) 1389 SkDebugf("%s0};\n", pBuffer); 1390 1391 for (index = 0; index < fPathCount; index++) { 1392 const SkPath& path = fPaths[index]; 1393 dumpPath(path); 1394 } 1395 bufferPtr = pBuffer; 1396 if (fPathCount > 0) 1397 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1398 "Paths paths = {"); 1399 for (index = 0; index < fPathCount; index++) 1400 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1401 "path%p, ", &fPaths[index]); 1402 if (fPathCount > 0) 1403 SkDebugf("%s0};\n", pBuffer); 1404 1405 for (index = 0; index < fPictureCount; index++) { 1406 dumpPicture(*fPictureRefs[index]); 1407 } 1408 bufferPtr = pBuffer; 1409 if (fPictureCount > 0) 1410 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1411 "Pictures pictures = {"); 1412 for (index = 0; index < fPictureCount; index++) 1413 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1414 "picture%p, ", fPictureRefs[index]); 1415 if (fPictureCount > 0) 1416 SkDebugf("%s0};\n", pBuffer); 1417 1418 for (index = 0; index < fRegionCount; index++) { 1419 const SkRegion& region = fRegions[index]; 1420 dumpRegion(region); 1421 } 1422 bufferPtr = pBuffer; 1423 if (fRegionCount > 0) 1424 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1425 "Regions regions = {"); 1426 for (index = 0; index < fRegionCount; index++) 1427 bufferPtr += snprintf(bufferPtr, DUMP_BUFFER_SIZE - (bufferPtr - pBuffer), 1428 "region%p, ", &fRegions[index]); 1429 if (fRegionCount > 0) 1430 SkDebugf("%s0};\n", pBuffer); 1431 1432 const_cast<SkPicturePlayback*>(this)->dumpStream(); 1433 } 1434 1435 #endif 1436