Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkPictureData_DEFINED
      9 #define SkPictureData_DEFINED
     10 
     11 #include "SkBitmap.h"
     12 #include "SkDrawable.h"
     13 #include "SkPicture.h"
     14 #include "SkPictureFlat.h"
     15 #include "SkTArray.h"
     16 
     17 #include <memory>
     18 
     19 class SkData;
     20 class SkPictureRecord;
     21 class SkReader32;
     22 struct SkSerialProcs;
     23 class SkStream;
     24 class SkWStream;
     25 class SkBBoxHierarchy;
     26 class SkMatrix;
     27 class SkPaint;
     28 class SkPath;
     29 class SkReadBuffer;
     30 class SkTextBlob;
     31 
     32 struct SkPictInfo {
     33     SkPictInfo() : fVersion(~0U) {}
     34 
     35     uint32_t getVersion() const {
     36         SkASSERT(fVersion != ~0U);
     37         return fVersion;
     38     }
     39 
     40     void setVersion(uint32_t version) {
     41         SkASSERT(version != ~0U);
     42         fVersion = version;
     43     }
     44 
     45 public:
     46     char        fMagic[8];
     47 private:
     48     uint32_t    fVersion;
     49 public:
     50     SkRect      fCullRect;
     51 };
     52 
     53 #define SK_PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
     54 #define SK_PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
     55 #define SK_PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
     56 #define SK_PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
     57 #define SK_PICT_DRAWABLE_TAG   SkSetFourByteTag('d', 'r', 'a', 'w')
     58 
     59 // This tag specifies the size of the ReadBuffer, needed for the following tags
     60 #define SK_PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
     61 // these are all inside the ARRAYS tag
     62 #define SK_PICT_PAINT_BUFFER_TAG    SkSetFourByteTag('p', 'n', 't', ' ')
     63 #define SK_PICT_PATH_BUFFER_TAG     SkSetFourByteTag('p', 't', 'h', ' ')
     64 #define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
     65 #define SK_PICT_VERTICES_BUFFER_TAG SkSetFourByteTag('v', 'e', 'r', 't')
     66 #define SK_PICT_IMAGE_BUFFER_TAG    SkSetFourByteTag('i', 'm', 'a', 'g')
     67 
     68 // Always write this guy last (with no length field afterwards)
     69 #define SK_PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
     70 
     71 template <typename T>
     72 T* read_index_base_1_or_null(SkReadBuffer* reader, const SkTArray<sk_sp<T>>& array) {
     73     int index = reader->readInt();
     74     return reader->validate(index > 0 && index <= array.count()) ? array[index - 1].get() : nullptr;
     75 }
     76 
     77 class SkPictureData {
     78 public:
     79     SkPictureData(const SkPictureRecord& record, const SkPictInfo&);
     80     // Does not affect ownership of SkStream.
     81     static SkPictureData* CreateFromStream(SkStream*,
     82                                            const SkPictInfo&,
     83                                            const SkDeserialProcs&,
     84                                            SkTypefacePlayback*);
     85     static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
     86 
     87     void serialize(SkWStream*, const SkSerialProcs&, SkRefCntSet*) const;
     88     void flatten(SkWriteBuffer&) const;
     89 
     90     const sk_sp<SkData>& opData() const { return fOpData; }
     91 
     92 protected:
     93     explicit SkPictureData(const SkPictInfo& info);
     94 
     95     // Does not affect ownership of SkStream.
     96     bool parseStream(SkStream*, const SkDeserialProcs&, SkTypefacePlayback*);
     97     bool parseBuffer(SkReadBuffer& buffer);
     98 
     99 public:
    100     const SkImage* getImage(SkReadBuffer* reader) const {
    101         // images are written base-0, unlike paths, pictures, drawables, etc.
    102         const int index = reader->readInt();
    103         return reader->validateIndex(index, fImages.count()) ? fImages[index].get() : nullptr;
    104     }
    105 
    106     const SkPath& getPath(SkReadBuffer* reader) const {
    107         int index = reader->readInt();
    108         return reader->validate(index > 0 && index <= fPaths.count()) ?
    109                 fPaths[index - 1] : fEmptyPath;
    110     }
    111 
    112     const SkPicture* getPicture(SkReadBuffer* reader) const {
    113         return read_index_base_1_or_null(reader, fPictures);
    114     }
    115 
    116     SkDrawable* getDrawable(SkReadBuffer* reader) const {
    117         return read_index_base_1_or_null(reader, fDrawables);
    118     }
    119 
    120     const SkPaint* getPaint(SkReadBuffer* reader) const {
    121         int index = reader->readInt();
    122         if (index == 0) {
    123             return nullptr; // recorder wrote a zero for no paint (likely drawimage)
    124         }
    125         return reader->validate(index > 0 && index <= fPaints.count()) ?
    126                 &fPaints[index - 1] : nullptr;
    127     }
    128 
    129     const SkTextBlob* getTextBlob(SkReadBuffer* reader) const {
    130         return read_index_base_1_or_null(reader, fTextBlobs);
    131     }
    132 
    133     const SkVertices* getVertices(SkReadBuffer* reader) const {
    134         return read_index_base_1_or_null(reader, fVertices);
    135     }
    136 
    137 private:
    138     // these help us with reading/writing
    139     // Does not affect ownership of SkStream.
    140     bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size,
    141                         const SkDeserialProcs&, SkTypefacePlayback*);
    142     void parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
    143     void flattenToBuffer(SkWriteBuffer&) const;
    144 
    145     SkTArray<SkPaint>  fPaints;
    146     SkTArray<SkPath>   fPaths;
    147 
    148     sk_sp<SkData>   fOpData;    // opcodes and parameters
    149 
    150     const SkPath    fEmptyPath;
    151     const SkBitmap  fEmptyBitmap;
    152 
    153     SkTArray<sk_sp<const SkPicture>>   fPictures;
    154     SkTArray<sk_sp<SkDrawable>>        fDrawables;
    155     SkTArray<sk_sp<const SkTextBlob>>  fTextBlobs;
    156     SkTArray<sk_sp<const SkVertices>>  fVertices;
    157     SkTArray<sk_sp<const SkImage>>     fImages;
    158 
    159     SkTypefacePlayback                 fTFPlayback;
    160     std::unique_ptr<SkFactoryPlayback> fFactoryPlayback;
    161 
    162     const SkPictInfo fInfo;
    163 
    164     static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
    165     static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec, const SkSerialProcs&);
    166 
    167     void initForPlayback() const;
    168 };
    169 
    170 #endif
    171