• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/core/SkBitmap.h"
12 #include "include/core/SkData.h"
13 #include "include/core/SkDrawable.h"
14 #include "include/core/SkImage.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkPath.h"
17 #include "include/core/SkPicture.h"
18 #include "include/core/SkRect.h"
19 #include "include/core/SkRefCnt.h"
20 #include "include/core/SkTextBlob.h"
21 #include "include/core/SkTypes.h"
22 #include "include/core/SkVertices.h"
23 #include "include/private/base/SkTArray.h"
24 #include "include/private/chromium/Slug.h"
25 #include "src/core/SkPictureFlat.h"
26 #include "src/core/SkReadBuffer.h"
27 
28 #include <cstdint>
29 #include <memory>
30 
31 class SkFactorySet;
32 class SkPictureRecord;
33 class SkRefCntSet;
34 class SkStream;
35 class SkWStream;
36 class SkWriteBuffer;
37 struct SkDeserialProcs;
38 struct SkSerialProcs;
39 
40 struct SkPictInfo {
SkPictInfoSkPictInfo41     SkPictInfo() : fVersion(~0U) {}
42 
getVersionSkPictInfo43     uint32_t getVersion() const {
44         SkASSERT(fVersion != ~0U);
45         return fVersion;
46     }
47 
setVersionSkPictInfo48     void setVersion(uint32_t version) {
49         SkASSERT(version != ~0U);
50         fVersion = version;
51     }
52 
53 public:
54     char        fMagic[8];
55 private:
56     uint32_t    fVersion;
57 public:
58     SkRect      fCullRect;
59 };
60 
61 #define SK_PICT_READER_TAG     SkSetFourByteTag('r', 'e', 'a', 'd')
62 #define SK_PICT_FACTORY_TAG    SkSetFourByteTag('f', 'a', 'c', 't')
63 #define SK_PICT_TYPEFACE_TAG   SkSetFourByteTag('t', 'p', 'f', 'c')
64 #define SK_PICT_PICTURE_TAG    SkSetFourByteTag('p', 'c', 't', 'r')
65 #define SK_PICT_DRAWABLE_TAG   SkSetFourByteTag('d', 'r', 'a', 'w')
66 
67 // This tag specifies the size of the ReadBuffer, needed for the following tags
68 #define SK_PICT_BUFFER_SIZE_TAG     SkSetFourByteTag('a', 'r', 'a', 'y')
69 // these are all inside the ARRAYS tag
70 #define SK_PICT_PAINT_BUFFER_TAG    SkSetFourByteTag('p', 'n', 't', ' ')
71 #define SK_PICT_PATH_BUFFER_TAG     SkSetFourByteTag('p', 't', 'h', ' ')
72 #define SK_PICT_TEXTBLOB_BUFFER_TAG SkSetFourByteTag('b', 'l', 'o', 'b')
73 #define SK_PICT_SLUG_BUFFER_TAG SkSetFourByteTag('s', 'l', 'u', 'g')
74 #define SK_PICT_VERTICES_BUFFER_TAG SkSetFourByteTag('v', 'e', 'r', 't')
75 #define SK_PICT_IMAGE_BUFFER_TAG    SkSetFourByteTag('i', 'm', 'a', 'g')
76 
77 // Always write this last (with no length field afterwards)
78 #define SK_PICT_EOF_TAG     SkSetFourByteTag('e', 'o', 'f', ' ')
79 
80 template <typename T>
read_index_base_1_or_null(SkReadBuffer * reader,const skia_private::TArray<sk_sp<T>> & array)81 T* read_index_base_1_or_null(SkReadBuffer* reader,
82                              const skia_private::TArray<sk_sp<T>>& array) {
83     int index = reader->readInt();
84     return reader->validate(index > 0 && index <= array.size()) ? array[index - 1].get() : nullptr;
85 }
86 
87 class SkPictureData {
88 public:
89     SkPictureData(const SkPictureRecord& record, const SkPictInfo&);
90     // Does not affect ownership of SkStream.
91     static SkPictureData* CreateFromStream(SkStream*,
92                                            const SkPictInfo&,
93                                            const SkDeserialProcs&,
94                                            SkTypefacePlayback*,
95                                            int recursionLimit);
96     static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
97 
98     void serialize(SkWStream*, const SkSerialProcs&, SkRefCntSet*, bool textBlobsOnly=false) const;
99     void flatten(SkWriteBuffer&) const;
100 
info()101     const SkPictInfo& info() const { return fInfo; }
102 
opData()103     const sk_sp<SkData>& opData() const { return fOpData; }
104 
105 protected:
106     explicit SkPictureData(const SkPictInfo& info);
107 
108     // Does not affect ownership of SkStream.
109     bool parseStream(SkStream*, const SkDeserialProcs&, SkTypefacePlayback*,
110                      int recursionLimit);
111     bool parseBuffer(SkReadBuffer& buffer);
112 
113 public:
getImage(SkReadBuffer * reader)114     const SkImage* getImage(SkReadBuffer* reader) const {
115         // images are written base-0, unlike paths, pictures, drawables, etc.
116         const int index = reader->readInt();
117         return reader->validateIndex(index, fImages.size()) ? fImages[index].get() : nullptr;
118     }
119 
getPath(SkReadBuffer * reader)120     const SkPath& getPath(SkReadBuffer* reader) const {
121         int index = reader->readInt();
122         return reader->validate(index > 0 && index <= fPaths.size()) ?
123                 fPaths[index - 1] : fEmptyPath;
124     }
125 
getPicture(SkReadBuffer * reader)126     const SkPicture* getPicture(SkReadBuffer* reader) const {
127         return read_index_base_1_or_null(reader, fPictures);
128     }
129 
getDrawable(SkReadBuffer * reader)130     SkDrawable* getDrawable(SkReadBuffer* reader) const {
131         return read_index_base_1_or_null(reader, fDrawables);
132     }
133 
134     // Return a paint if one was used for this op, or nullptr if none was used.
135     const SkPaint* optionalPaint(SkReadBuffer* reader) const;
136 
137     // Return the paint used for this op, invalidating the SkReadBuffer if there appears to be none.
138     // The returned paint is always safe to use.
139     const SkPaint& requiredPaint(SkReadBuffer* reader) const;
140 
getTextBlob(SkReadBuffer * reader)141     const SkTextBlob* getTextBlob(SkReadBuffer* reader) const {
142         return read_index_base_1_or_null(reader, fTextBlobs);
143     }
144 
getSlug(SkReadBuffer * reader)145     const sktext::gpu::Slug* getSlug(SkReadBuffer* reader) const {
146         return read_index_base_1_or_null(reader, fSlugs);
147     }
148 
getVertices(SkReadBuffer * reader)149     const SkVertices* getVertices(SkReadBuffer* reader) const {
150         return read_index_base_1_or_null(reader, fVertices);
151     }
152 
153 private:
154     // these help us with reading/writing
155     // Does not affect ownership of SkStream.
156     bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size,
157                         const SkDeserialProcs&, SkTypefacePlayback*,
158                         int recursionLimit);
159     void parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
160     void flattenToBuffer(SkWriteBuffer&, bool textBlobsOnly) const;
161 
162     skia_private::TArray<SkPaint> fPaints;
163     skia_private::TArray<SkPath>  fPaths;
164 
165     sk_sp<SkData>                 fOpData;    // opcodes and parameters
166 
167     const SkPath                  fEmptyPath;
168     const SkBitmap                fEmptyBitmap;
169 
170     skia_private::TArray<sk_sp<const SkPicture>>   fPictures;
171     skia_private::TArray<sk_sp<SkDrawable>>        fDrawables;
172     skia_private::TArray<sk_sp<const SkTextBlob>>  fTextBlobs;
173     skia_private::TArray<sk_sp<const SkVertices>>  fVertices;
174     skia_private::TArray<sk_sp<const SkImage>>     fImages;
175     skia_private::TArray<sk_sp<const sktext::gpu::Slug>> fSlugs;
176 
177     SkTypefacePlayback                 fTFPlayback;
178     std::unique_ptr<SkFactoryPlayback> fFactoryPlayback;
179 
180     const SkPictInfo fInfo;
181 
182     static void WriteFactories(SkWStream* stream, const SkFactorySet& rec);
183     static void WriteTypefaces(SkWStream* stream, const SkRefCntSet& rec, const SkSerialProcs&);
184 
185     void initForPlayback() const;
186 };
187 
188 #endif
189