| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 #include <new> | 7 #include <new> |
| 8 #include "SkPictureData.h" | 8 #include "SkPictureData.h" |
| 9 #include "SkPictureRecord.h" | 9 #include "SkPictureRecord.h" |
| 10 #include "SkReadBuffer.h" | 10 #include "SkReadBuffer.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 // templatize to consolidate with similar picture logic? | 62 // templatize to consolidate with similar picture logic? |
| 63 const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs(); | 63 const SkTDArray<const SkTextBlob*>& blobs = record.getTextBlobRefs(); |
| 64 fTextBlobCount = blobs.count(); | 64 fTextBlobCount = blobs.count(); |
| 65 if (fTextBlobCount > 0) { | 65 if (fTextBlobCount > 0) { |
| 66 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount); | 66 fTextBlobRefs = SkNEW_ARRAY(const SkTextBlob*, fTextBlobCount); |
| 67 for (int i = 0; i < fTextBlobCount; ++i) { | 67 for (int i = 0; i < fTextBlobCount; ++i) { |
| 68 fTextBlobRefs[i] = SkRef(blobs[i]); | 68 fTextBlobRefs[i] = SkRef(blobs[i]); |
| 69 } | 69 } |
| 70 } | 70 } |
| 71 | 71 |
| 72 const SkTDArray<const SkImage*>& imgs = record.getImageRefs(); | 72 const SkTDArray<const SkImage*>& imgs = record.getImageRefs(); |
| 73 fImageCount = imgs.count(); | 73 fImageCount = imgs.count(); |
| 74 if (fImageCount > 0) { | 74 if (fImageCount > 0) { |
| 75 fImageRefs = SkNEW_ARRAY(const SkImage*, fImageCount); | 75 fImageRefs = SkNEW_ARRAY(const SkImage*, fImageCount); |
| 76 for (int i = 0; i < fImageCount; ++i) { | 76 for (int i = 0; i < fImageCount; ++i) { |
| 77 fImageRefs[i] = SkRef(imgs[i]); | 77 fImageRefs[i] = SkRef(imgs[i]); |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 | 81 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 95 | 95 |
| 96 for (int i = 0; i < fPictureCount; i++) { | 96 for (int i = 0; i < fPictureCount; i++) { |
| 97 fPictureRefs[i]->unref(); | 97 fPictureRefs[i]->unref(); |
| 98 } | 98 } |
| 99 SkDELETE_ARRAY(fPictureRefs); | 99 SkDELETE_ARRAY(fPictureRefs); |
| 100 | 100 |
| 101 for (int i = 0; i < fTextBlobCount; i++) { | 101 for (int i = 0; i < fTextBlobCount; i++) { |
| 102 fTextBlobRefs[i]->unref(); | 102 fTextBlobRefs[i]->unref(); |
| 103 } | 103 } |
| 104 SkDELETE_ARRAY(fTextBlobRefs); | 104 SkDELETE_ARRAY(fTextBlobRefs); |
| 105 | 105 |
| 106 for (int i = 0; i < fImageCount; i++) { | 106 for (int i = 0; i < fImageCount; i++) { |
| 107 fImageRefs[i]->unref(); | 107 fImageRefs[i]->unref(); |
| 108 } | 108 } |
| 109 SkDELETE_ARRAY(fImageRefs); | 109 SkDELETE_ARRAY(fImageRefs); |
| 110 | 110 |
| 111 SkDELETE(fFactoryPlayback); | 111 SkDELETE(fFactoryPlayback); |
| 112 } | 112 } |
| 113 | 113 |
| 114 bool SkPictureData::containsBitmaps() const { | 114 bool SkPictureData::containsBitmaps() const { |
| 115 if (fBitmaps.count() > 0 || fImageCount > 0) { | 115 if (fBitmaps.count() > 0 || fImageCount > 0) { |
| 116 return true; | 116 return true; |
| 117 } | 117 } |
| 118 for (int i = 0; i < fPictureCount; ++i) { | 118 for (int i = 0; i < fPictureCount; ++i) { |
| 119 if (fPictureRefs[i]->willPlayBackBitmaps()) { | 119 if (fPictureRefs[i]->willPlayBackBitmaps()) { |
| 120 return true; | 120 return true; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 buffer.writePath(fPaths[i]); | 226 buffer.writePath(fPaths[i]); |
| 227 } | 227 } |
| 228 } | 228 } |
| 229 | 229 |
| 230 if (fTextBlobCount > 0) { | 230 if (fTextBlobCount > 0) { |
| 231 write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount); | 231 write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount); |
| 232 for (i = 0; i < fTextBlobCount; ++i) { | 232 for (i = 0; i < fTextBlobCount; ++i) { |
| 233 fTextBlobRefs[i]->flatten(buffer); | 233 fTextBlobRefs[i]->flatten(buffer); |
| 234 } | 234 } |
| 235 } | 235 } |
| 236 | 236 |
| 237 if (fImageCount > 0) { | 237 if (fImageCount > 0) { |
| 238 write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount); | 238 write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount); |
| 239 for (i = 0; i < fImageCount; ++i) { | 239 for (i = 0; i < fImageCount; ++i) { |
| 240 buffer.writeImage(fImageRefs[i]); | 240 buffer.writeImage(fImageRefs[i]); |
| 241 } | 241 } |
| 242 } | 242 } |
| 243 } | 243 } |
| 244 | 244 |
| 245 void SkPictureData::serialize(SkWStream* stream, | 245 void SkPictureData::serialize(SkWStream* stream, |
| 246 SkPixelSerializer* pixelSerializer) const { | 246 SkPixelSerializer* pixelSerializer, |
| 247 SkRefCntSet* topLevelTypeFaceSet) const { |
| 248 // This can happen at pretty much any time, so might as well do it first. |
| 247 write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); | 249 write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); |
| 248 stream->write(fOpData->bytes(), fOpData->size()); | 250 stream->write(fOpData->bytes(), fOpData->size()); |
| 249 | 251 |
| 252 // We serialize all typefaces into the typeface section of the top-level pic
ture. |
| 253 SkRefCntSet localTypefaceSet; |
| 254 SkRefCntSet* typefaceSet = topLevelTypeFaceSet ? topLevelTypeFaceSet : &loca
lTypefaceSet; |
| 255 |
| 256 // We delay serializing the bulk of our data until after we've serialized |
| 257 // factories and typefaces by first serializing to an in-memory write buffer
. |
| 258 SkFactorySet factSet; // buffer refs factSet, so factSet must come first. |
| 259 SkWriteBuffer buffer(SkWriteBuffer::kCrossProcess_Flag); |
| 260 buffer.setFactoryRecorder(&factSet); |
| 261 buffer.setPixelSerializer(pixelSerializer); |
| 262 buffer.setTypefaceRecorder(typefaceSet); |
| 263 this->flattenToBuffer(buffer); |
| 264 |
| 265 // Dummy serialize our sub-pictures for the side effect of filling |
| 266 // typefaceSet with typefaces from sub-pictures. |
| 267 struct DevNull: public SkWStream { |
| 268 DevNull() : fBytesWritten(0) {} |
| 269 size_t fBytesWritten; |
| 270 bool write(const void*, size_t size) override { fBytesWritten += size; r
eturn true; } |
| 271 size_t bytesWritten() const override { return fBytesWritten; } |
| 272 } devnull; |
| 273 for (int i = 0; i < fPictureCount; i++) { |
| 274 fPictureRefs[i]->serialize(&devnull, pixelSerializer, typefaceSet); |
| 275 } |
| 276 |
| 277 // We need to write factories before we write the buffer. |
| 278 // We need to write typefaces before we write the buffer or any sub-picture. |
| 279 WriteFactories(stream, factSet); |
| 280 if (typefaceSet == &localTypefaceSet) { |
| 281 WriteTypefaces(stream, *typefaceSet); |
| 282 } |
| 283 |
| 284 // Write the buffer. |
| 285 write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten()); |
| 286 buffer.writeToStream(stream); |
| 287 |
| 288 // Write sub-pictures by calling serialize again. |
| 250 if (fPictureCount > 0) { | 289 if (fPictureCount > 0) { |
| 251 write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); | 290 write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); |
| 252 for (int i = 0; i < fPictureCount; i++) { | 291 for (int i = 0; i < fPictureCount; i++) { |
| 253 fPictureRefs[i]->serialize(stream, pixelSerializer); | 292 fPictureRefs[i]->serialize(stream, pixelSerializer, typefaceSet); |
| 254 } | 293 } |
| 255 } | 294 } |
| 256 | 295 |
| 257 // Write some of our data into a writebuffer, and then serialize that | |
| 258 // into our stream | |
| 259 { | |
| 260 SkRefCntSet typefaceSet; | |
| 261 SkFactorySet factSet; | |
| 262 | |
| 263 SkWriteBuffer buffer(SkWriteBuffer::kCrossProcess_Flag); | |
| 264 buffer.setTypefaceRecorder(&typefaceSet); | |
| 265 buffer.setFactoryRecorder(&factSet); | |
| 266 buffer.setPixelSerializer(pixelSerializer); | |
| 267 | |
| 268 this->flattenToBuffer(buffer); | |
| 269 | |
| 270 // We have to write these two sets into the stream *before* we write | |
| 271 // the buffer, since parsing that buffer will require that we already | |
| 272 // have these sets available to use. | |
| 273 WriteFactories(stream, factSet); | |
| 274 WriteTypefaces(stream, typefaceSet); | |
| 275 | |
| 276 write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten()); | |
| 277 buffer.writeToStream(stream); | |
| 278 } | |
| 279 | |
| 280 stream->write32(SK_PICT_EOF_TAG); | 296 stream->write32(SK_PICT_EOF_TAG); |
| 281 } | 297 } |
| 282 | 298 |
| 283 void SkPictureData::flatten(SkWriteBuffer& buffer) const { | 299 void SkPictureData::flatten(SkWriteBuffer& buffer) const { |
| 284 write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size()); | 300 write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size()); |
| 285 buffer.writeByteArray(fOpData->bytes(), fOpData->size()); | 301 buffer.writeByteArray(fOpData->bytes(), fOpData->size()); |
| 286 | 302 |
| 287 if (fPictureCount > 0) { | 303 if (fPictureCount > 0) { |
| 288 write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount); | 304 write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount); |
| 289 for (int i = 0; i < fPictureCount; i++) { | 305 for (int i = 0; i < fPictureCount; i++) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 317 if (pictInfoFlags & gSD[i].fSrc) { | 333 if (pictInfoFlags & gSD[i].fSrc) { |
| 318 rbMask |= gSD[i].fDst; | 334 rbMask |= gSD[i].fDst; |
| 319 } | 335 } |
| 320 } | 336 } |
| 321 return rbMask; | 337 return rbMask; |
| 322 } | 338 } |
| 323 | 339 |
| 324 bool SkPictureData::parseStreamTag(SkStream* stream, | 340 bool SkPictureData::parseStreamTag(SkStream* stream, |
| 325 uint32_t tag, | 341 uint32_t tag, |
| 326 uint32_t size, | 342 uint32_t size, |
| 327 SkPicture::InstallPixelRefProc proc) { | 343 SkPicture::InstallPixelRefProc proc, |
| 344 SkTypefacePlayback* topLevelTFPlayback) { |
| 328 /* | 345 /* |
| 329 * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen | 346 * By the time we encounter BUFFER_SIZE_TAG, we need to have already seen |
| 330 * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required | 347 * its dependents: FACTORY_TAG and TYPEFACE_TAG. These two are not required |
| 331 * but if they are present, they need to have been seen before the buffer. | 348 * but if they are present, they need to have been seen before the buffer. |
| 332 * | 349 * |
| 333 * We assert that if/when we see either of these, that we have not yet seen | 350 * We assert that if/when we see either of these, that we have not yet seen |
| 334 * the buffer tag, because if we have, then its too-late to deal with the | 351 * the buffer tag, because if we have, then its too-late to deal with the |
| 335 * factories or typefaces. | 352 * factories or typefaces. |
| 336 */ | 353 */ |
| 337 SkDEBUGCODE(bool haveBuffer = false;) | 354 SkDEBUGCODE(bool haveBuffer = false;) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 // the default here. | 386 // the default here. |
| 370 tf.reset(SkTypeface::RefDefault()); | 387 tf.reset(SkTypeface::RefDefault()); |
| 371 } | 388 } |
| 372 fTFPlayback.set(i, tf); | 389 fTFPlayback.set(i, tf); |
| 373 } | 390 } |
| 374 } break; | 391 } break; |
| 375 case SK_PICT_PICTURE_TAG: { | 392 case SK_PICT_PICTURE_TAG: { |
| 376 fPictureCount = 0; | 393 fPictureCount = 0; |
| 377 fPictureRefs = SkNEW_ARRAY(const SkPicture*, size); | 394 fPictureRefs = SkNEW_ARRAY(const SkPicture*, size); |
| 378 for (uint32_t i = 0; i < size; i++) { | 395 for (uint32_t i = 0; i < size; i++) { |
| 379 fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc); | 396 fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc, topL
evelTFPlayback); |
| 380 if (!fPictureRefs[i]) { | 397 if (!fPictureRefs[i]) { |
| 381 return false; | 398 return false; |
| 382 } | 399 } |
| 383 fPictureCount++; | 400 fPictureCount++; |
| 384 } | 401 } |
| 385 } break; | 402 } break; |
| 386 case SK_PICT_BUFFER_SIZE_TAG: { | 403 case SK_PICT_BUFFER_SIZE_TAG: { |
| 387 SkAutoMalloc storage(size); | 404 SkAutoMalloc storage(size); |
| 388 if (stream->read(storage.get(), size) != size) { | 405 if (stream->read(storage.get(), size) != size) { |
| 389 return false; | 406 return false; |
| 390 } | 407 } |
| 391 | 408 |
| 392 /* Should we use SkValidatingReadBuffer instead? */ | 409 /* Should we use SkValidatingReadBuffer instead? */ |
| 393 SkReadBuffer buffer(storage.get(), size); | 410 SkReadBuffer buffer(storage.get(), size); |
| 394 buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags)); | 411 buffer.setFlags(pictInfoFlagsToReadBufferFlags(fInfo.fFlags)); |
| 395 buffer.setVersion(fInfo.fVersion); | 412 buffer.setVersion(fInfo.fVersion); |
| 396 | 413 |
| 397 fFactoryPlayback->setupBuffer(buffer); | 414 fFactoryPlayback->setupBuffer(buffer); |
| 398 fTFPlayback.setupBuffer(buffer); | |
| 399 buffer.setBitmapDecoder(proc); | 415 buffer.setBitmapDecoder(proc); |
| 400 | 416 |
| 417 if (fTFPlayback.count() > 0) { |
| 418 // .skp files <= v43 have typefaces serialized with each sub pic
ture. |
| 419 fTFPlayback.setupBuffer(buffer); |
| 420 } else { |
| 421 // Newer .skp files serialize all typefaces with the top picture
. |
| 422 topLevelTFPlayback->setupBuffer(buffer); |
| 423 } |
| 424 |
| 401 while (!buffer.eof() && buffer.isValid()) { | 425 while (!buffer.eof() && buffer.isValid()) { |
| 402 tag = buffer.readUInt(); | 426 tag = buffer.readUInt(); |
| 403 size = buffer.readUInt(); | 427 size = buffer.readUInt(); |
| 404 if (!this->parseBufferTag(buffer, tag, size)) { | 428 if (!this->parseBufferTag(buffer, tag, size)) { |
| 405 return false; | 429 return false; |
| 406 } | 430 } |
| 407 } | 431 } |
| 408 if (!buffer.isValid()) { | 432 if (!buffer.isValid()) { |
| 409 return false; | 433 return false; |
| 410 } | 434 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 break; | 556 break; |
| 533 default: | 557 default: |
| 534 // The tag was invalid. | 558 // The tag was invalid. |
| 535 return false; | 559 return false; |
| 536 } | 560 } |
| 537 return true; // success | 561 return true; // success |
| 538 } | 562 } |
| 539 | 563 |
| 540 SkPictureData* SkPictureData::CreateFromStream(SkStream* stream, | 564 SkPictureData* SkPictureData::CreateFromStream(SkStream* stream, |
| 541 const SkPictInfo& info, | 565 const SkPictInfo& info, |
| 542 SkPicture::InstallPixelRefProc pr
oc) { | 566 SkPicture::InstallPixelRefProc pr
oc, |
| 567 SkTypefacePlayback* topLevelTFPla
yback) { |
| 543 SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info))); | 568 SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info))); |
| 569 if (!topLevelTFPlayback) { |
| 570 topLevelTFPlayback = &data->fTFPlayback; |
| 571 } |
| 544 | 572 |
| 545 if (!data->parseStream(stream, proc)) { | 573 if (!data->parseStream(stream, proc, topLevelTFPlayback)) { |
| 546 return NULL; | 574 return NULL; |
| 547 } | 575 } |
| 548 return data.detach(); | 576 return data.detach(); |
| 549 } | 577 } |
| 550 | 578 |
| 551 SkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer, | 579 SkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer, |
| 552 const SkPictInfo& info) { | 580 const SkPictInfo& info) { |
| 553 SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info))); | 581 SkAutoTDelete<SkPictureData> data(SkNEW_ARGS(SkPictureData, (info))); |
| 554 buffer.setVersion(info.fVersion); | 582 buffer.setVersion(info.fVersion); |
| 555 | 583 |
| 556 if (!data->parseBuffer(buffer)) { | 584 if (!data->parseBuffer(buffer)) { |
| 557 return NULL; | 585 return NULL; |
| 558 } | 586 } |
| 559 return data.detach(); | 587 return data.detach(); |
| 560 } | 588 } |
| 561 | 589 |
| 562 bool SkPictureData::parseStream(SkStream* stream, | 590 bool SkPictureData::parseStream(SkStream* stream, |
| 563 SkPicture::InstallPixelRefProc proc) { | 591 SkPicture::InstallPixelRefProc proc, |
| 592 SkTypefacePlayback* topLevelTFPlayback) { |
| 564 for (;;) { | 593 for (;;) { |
| 565 uint32_t tag = stream->readU32(); | 594 uint32_t tag = stream->readU32(); |
| 566 if (SK_PICT_EOF_TAG == tag) { | 595 if (SK_PICT_EOF_TAG == tag) { |
| 567 break; | 596 break; |
| 568 } | 597 } |
| 569 | 598 |
| 570 uint32_t size = stream->readU32(); | 599 uint32_t size = stream->readU32(); |
| 571 if (!this->parseStreamTag(stream, tag, size, proc)) { | 600 if (!this->parseStreamTag(stream, tag, size, proc, topLevelTFPlayback))
{ |
| 572 return false; // we're invalid | 601 return false; // we're invalid |
| 573 } | 602 } |
| 574 } | 603 } |
| 575 return true; | 604 return true; |
| 576 } | 605 } |
| 577 | 606 |
| 578 bool SkPictureData::parseBuffer(SkReadBuffer& buffer) { | 607 bool SkPictureData::parseBuffer(SkReadBuffer& buffer) { |
| 579 for (;;) { | 608 for (;;) { |
| 580 uint32_t tag = buffer.readUInt(); | 609 uint32_t tag = buffer.readUInt(); |
| 581 if (SK_PICT_EOF_TAG == tag) { | 610 if (SK_PICT_EOF_TAG == tag) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 610 } | 639 } |
| 611 } | 640 } |
| 612 | 641 |
| 613 bool SkPictureData::suitableForLayerOptimization() const { | 642 bool SkPictureData::suitableForLayerOptimization() const { |
| 614 return fContentInfo.numLayers() > 0; | 643 return fContentInfo.numLayers() > 0; |
| 615 } | 644 } |
| 616 #endif | 645 #endif |
| 617 /////////////////////////////////////////////////////////////////////////////// | 646 /////////////////////////////////////////////////////////////////////////////// |
| 618 | 647 |
| 619 | 648 |
| OLD | NEW |