void SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const { int i, n; // we never record bitmaps anymore, only images SkASSERT(fBitmaps.count() == 0); if ((n = fPaints.count()) > 0) { write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n); for (i = 0; i < n; i++) { buffer.writePaint(fPaints[i]); } } if ((n = fPaths.count()) > 0) { write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n); buffer.writeInt(n); for (int i = 0; i < n; i++) { buffer.writePath(fPaths[i]); } } if (fTextBlobCount > 0) { write_tag_size(buffer, SK_PICT_TEXTBLOB_BUFFER_TAG, fTextBlobCount); for (i = 0; i < fTextBlobCount; ++i) { fTextBlobRefs[i]->flatten(buffer); } } if (fImageCount > 0) { write_tag_size(buffer, SK_PICT_IMAGE_BUFFER_TAG, fImageCount); for (i = 0; i < fImageCount; ++i) { buffer.writeImage(fImageRefs[i]); } } }
void SkPictureData::serialize(SkWStream* stream, SkPixelSerializer* pixelSerializer, SkRefCntSet* topLevelTypeFaceSet) const { // This can happen at pretty much any time, so might as well do it first. write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); stream->write(fOpData->bytes(), fOpData->size()); // We serialize all typefaces into the typeface section of the top-level picture. SkRefCntSet localTypefaceSet; SkRefCntSet* typefaceSet = topLevelTypeFaceSet ? topLevelTypeFaceSet : &localTypefaceSet; // We delay serializing the bulk of our data until after we've serialized // factories and typefaces by first serializing to an in-memory write buffer. SkFactorySet factSet; // buffer refs factSet, so factSet must come first. SkWriteBuffer buffer(SkWriteBuffer::kCrossProcess_Flag); buffer.setFactoryRecorder(&factSet); buffer.setPixelSerializer(pixelSerializer); buffer.setTypefaceRecorder(typefaceSet); this->flattenToBuffer(buffer); // Dummy serialize our sub-pictures for the side effect of filling // typefaceSet with typefaces from sub-pictures. struct DevNull: public SkWStream { DevNull() : fBytesWritten(0) {} size_t fBytesWritten; bool write(const void*, size_t size) override { fBytesWritten += size; return true; } size_t bytesWritten() const override { return fBytesWritten; } } devnull; for (int i = 0; i < fPictureCount; i++) { fPictureRefs[i]->serialize(&devnull, pixelSerializer, typefaceSet); } // We need to write factories before we write the buffer. // We need to write typefaces before we write the buffer or any sub-picture. WriteFactories(stream, factSet); if (typefaceSet == &localTypefaceSet) { WriteTypefaces(stream, *typefaceSet); } // Write the buffer. write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten()); buffer.writeToStream(stream); // Write sub-pictures by calling serialize again. if (fPictureCount > 0) { write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); for (int i = 0; i < fPictureCount; i++) { fPictureRefs[i]->serialize(stream, pixelSerializer, typefaceSet); } } stream->write32(SK_PICT_EOF_TAG); }
void SkPictureData::flatten(SkWriteBuffer& buffer) const { write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size()); buffer.writeByteArray(fOpData->bytes(), fOpData->size()); if (fPictureCount > 0) { write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount); for (int i = 0; i < fPictureCount; i++) { fPictureRefs[i]->flatten(buffer); } } // Write this picture playback's data into a writebuffer this->flattenToBuffer(buffer); buffer.write32(SK_PICT_EOF_TAG); }
void SkPictureData::WriteFactories(SkWStream* stream, const SkFactorySet& rec) { int count = rec.count(); SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count); SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get(); rec.copyToArray(array); size_t size = compute_chunk_size(array, count); // TODO: write_tag_size should really take a size_t write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size); SkDEBUGCODE(size_t start = stream->bytesWritten()); stream->write32(count); for (int i = 0; i < count; i++) { const char* name = SkFlattenable::FactoryToName(array[i]); if (nullptr == name || 0 == *name) { stream->writePackedUInt(0); } else { size_t len = strlen(name); stream->writePackedUInt(len); stream->write(name, len); } } SkASSERT(size == (stream->bytesWritten() - start)); }
void SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) { int count = rec.count(); write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count); SkAutoSTMalloc<16, SkTypeface*> storage(count); SkTypeface** array = (SkTypeface**)storage.get(); rec.copyToArray((SkRefCnt**)array); for (int i = 0; i < count; i++) { array[i]->serialize(stream); } }
void SkPictureData::WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec) { int count = rec.count(); write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count); SkAutoSTMalloc<16, SkTypeface*> storage(count); SkTypeface** array = (SkTypeface**)storage.get(); rec.copyToArray((SkRefCnt**)array); for (int i = 0; i < count; i++) { #ifdef SK_PICTURE_FORCE_FONT_EMBEDDING array[i]->serializeForcingEmbedding(stream); #else // TODO: if (embedFonts) { array[i]->serializeForcingEmbedding(stream) } else array[i]->serialize(stream); #endif } }