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