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 |