1 /*
2  * Copyright 2007 The Android Open Source Project
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 SkPicture_DEFINED
9 #define SkPicture_DEFINED
10 
11 #include "include/core/SkRect.h"
12 #include "include/core/SkRefCnt.h"
13 #include "include/core/SkTileMode.h"
14 #include "include/core/SkTypes.h"
15 
16 class SkCanvas;
17 class SkData;
18 struct SkDeserialProcs;
19 class SkImage;
20 class SkMatrix;
21 struct SkSerialProcs;
22 class SkShader;
23 class SkStream;
24 class SkWStream;
25 
26 /** \class SkPicture
27     SkPicture records drawing commands made to SkCanvas. The command stream may be
28     played in whole or in part at a later time.
29 
30     SkPicture is an abstract class. SkPicture may be generated by SkPictureRecorder
31     or SkDrawable, or from SkPicture previously saved to SkData or SkStream.
32 
33     SkPicture may contain any SkCanvas drawing command, as well as one or more
34     SkCanvas matrix or SkCanvas clip. SkPicture has a cull SkRect, which is used as
35     a bounding box hint. To limit SkPicture bounds, use SkCanvas clip when
36     recording or drawing SkPicture.
37 */
38 class SK_API SkPicture : public SkRefCnt {
39 public:
40 
41     /** Recreates SkPicture that was serialized into a stream. Returns constructed SkPicture
42         if successful; otherwise, returns nullptr. Fails if data does not permit
43         constructing valid SkPicture.
44 
45         procs->fPictureProc permits supplying a custom function to decode SkPicture.
46         If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
47         may be used to provide user context to procs->fPictureProc; procs->fPictureProc
48         is called with a pointer to data, data byte length, and user context.
49 
50         @param stream  container for serial data
51         @param procs   custom serial data decoders; may be nullptr
52         @return        SkPicture constructed from stream data
53     */
54     static sk_sp<SkPicture> MakeFromStream(SkStream* stream,
55                                            const SkDeserialProcs* procs = nullptr);
56 
57     /** Recreates SkPicture that was serialized into data. Returns constructed SkPicture
58         if successful; otherwise, returns nullptr. Fails if data does not permit
59         constructing valid SkPicture.
60 
61         procs->fPictureProc permits supplying a custom function to decode SkPicture.
62         If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
63         may be used to provide user context to procs->fPictureProc; procs->fPictureProc
64         is called with a pointer to data, data byte length, and user context.
65 
66         @param data   container for serial data
67         @param procs  custom serial data decoders; may be nullptr
68         @return       SkPicture constructed from data
69     */
70     static sk_sp<SkPicture> MakeFromData(const SkData* data,
71                                          const SkDeserialProcs* procs = nullptr);
72 
73     /**
74 
75         @param data   pointer to serial data
76         @param size   size of data
77         @param procs  custom serial data decoders; may be nullptr
78         @return       SkPicture constructed from data
79     */
80     static sk_sp<SkPicture> MakeFromData(const void* data, size_t size,
81                                          const SkDeserialProcs* procs = nullptr);
82 
83     /** \class SkPicture::AbortCallback
84         AbortCallback is an abstract class. An implementation of AbortCallback may
85         passed as a parameter to SkPicture::playback, to stop it before all drawing
86         commands have been processed.
87 
88         If AbortCallback::abort returns true, SkPicture::playback is interrupted.
89     */
90     class SK_API AbortCallback {
91     public:
92 
93         /** Has no effect.
94 
95             @return  abstract class cannot be instantiated
96         */
AbortCallback()97         AbortCallback() {}
98 
99         /** Has no effect.
100         */
~AbortCallback()101         virtual ~AbortCallback() {}
102 
103         /** Stops SkPicture playback when some condition is met. A subclass of
104             AbortCallback provides an override for abort() that can stop SkPicture::playback.
105 
106             The part of SkPicture drawn when aborted is undefined. SkPicture instantiations are
107             free to stop drawing at different points during playback.
108 
109             If the abort happens inside one or more calls to SkCanvas::save(), stack
110             of SkCanvas matrix and SkCanvas clip values is restored to its state before
111             SkPicture::playback was called.
112 
113             @return  true to stop playback
114 
115         example: https://fiddle.skia.org/c/@Picture_AbortCallback_abort
116         */
117         virtual bool abort() = 0;
118     };
119 
120     /** Replays the drawing commands on the specified canvas. In the case that the
121         commands are recorded, each command in the SkPicture is sent separately to canvas.
122 
123         To add a single command to draw SkPicture to recording canvas, call
124         SkCanvas::drawPicture instead.
125 
126         @param canvas    receiver of drawing commands
127         @param callback  allows interruption of playback
128 
129         example: https://fiddle.skia.org/c/@Picture_playback
130     */
131     virtual void playback(SkCanvas* canvas, AbortCallback* callback = nullptr) const = 0;
132 
133     /** Returns cull SkRect for this picture, passed in when SkPicture was created.
134         Returned SkRect does not specify clipping SkRect for SkPicture; cull is hint
135         of SkPicture bounds.
136 
137         SkPicture is free to discard recorded drawing commands that fall outside
138         cull.
139 
140         @return  bounds passed when SkPicture was created
141 
142         example: https://fiddle.skia.org/c/@Picture_cullRect
143     */
144     virtual SkRect cullRect() const = 0;
145 
146     /** Returns a non-zero value unique among SkPicture in Skia process.
147 
148         @return  identifier for SkPicture
149     */
uniqueID()150     uint32_t uniqueID() const { return fUniqueID; }
151 
152     /** Returns storage containing SkData describing SkPicture, using optional custom
153         encoders.
154 
155         procs->fPictureProc permits supplying a custom function to encode SkPicture.
156         If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
157         may be used to provide user context to procs->fPictureProc; procs->fPictureProc
158         is called with a pointer to SkPicture and user context.
159 
160         @param procs  custom serial data encoders; may be nullptr
161         @return       storage containing serialized SkPicture
162 
163         example: https://fiddle.skia.org/c/@Picture_serialize
164     */
165     sk_sp<SkData> serialize(const SkSerialProcs* procs = nullptr) const;
166 
167     /** Writes picture to stream, using optional custom encoders.
168 
169         procs->fPictureProc permits supplying a custom function to encode SkPicture.
170         If procs->fPictureProc is nullptr, default encoding is used. procs->fPictureCtx
171         may be used to provide user context to procs->fPictureProc; procs->fPictureProc
172         is called with a pointer to SkPicture and user context.
173 
174         @param stream  writable serial data stream
175         @param procs   custom serial data encoders; may be nullptr
176 
177         example: https://fiddle.skia.org/c/@Picture_serialize_2
178     */
179     void serialize(SkWStream* stream, const SkSerialProcs* procs = nullptr) const;
180 
181     /** Returns a placeholder SkPicture. Result does not draw, and contains only
182         cull SkRect, a hint of its bounds. Result is immutable; it cannot be changed
183         later. Result identifier is unique.
184 
185         Returned placeholder can be intercepted during playback to insert other
186         commands into SkCanvas draw stream.
187 
188         @param cull  placeholder dimensions
189         @return      placeholder with unique identifier
190 
191         example: https://fiddle.skia.org/c/@Picture_MakePlaceholder
192     */
193     static sk_sp<SkPicture> MakePlaceholder(SkRect cull);
194 
195     /** Returns the approximate number of operations in SkPicture. Returned value
196         may be greater or less than the number of SkCanvas calls
197         recorded: some calls may be recorded as more than one operation, other
198         calls may be optimized away.
199 
200         @return  approximate operation count
201 
202         example: https://fiddle.skia.org/c/@Picture_approximateOpCount
203     */
204     virtual int approximateOpCount() const = 0;
205 
206     /** Returns the approximate byte size of SkPicture. Does not include large objects
207         referenced by SkPicture.
208 
209         @return  approximate size
210 
211         example: https://fiddle.skia.org/c/@Picture_approximateBytesUsed
212     */
213     virtual size_t approximateBytesUsed() const = 0;
214 
215     /** Return a new shader that will draw with this picture.
216      *
217      *  @param tmx  The tiling mode to use when sampling in the x-direction.
218      *  @param tmy  The tiling mode to use when sampling in the y-direction.
219      *  @param localMatrix Optional matrix used when sampling
220      *  @param tile The tile rectangle in picture coordinates: this represents the subset
221      *              (or superset) of the picture used when building a tile. It is not
222      *              affected by localMatrix and does not imply scaling (only translation
223      *              and cropping). If null, the tile rect is considered equal to the picture
224      *              bounds.
225      *  @return     Returns a new shader object. Note: this function never returns null.
226      */
227     sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
228                                const SkMatrix* localMatrix, const SkRect* tileRect) const;
229     sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy,
230                                const SkMatrix* localMatrix = nullptr) const;
231 
232 private:
233     // Subclass whitelist.
234     SkPicture();
235     friend class SkBigPicture;
236     friend class SkEmptyPicture;
237     friend class SkPicturePriv;
238     template <typename> friend class SkMiniPicture;
239 
240     void serialize(SkWStream*, const SkSerialProcs*, class SkRefCntSet* typefaces,
241         bool textBlobsOnly=false) const;
242     static sk_sp<SkPicture> MakeFromStream(SkStream*, const SkDeserialProcs*,
243                                            class SkTypefacePlayback*);
244     friend class SkPictureData;
245 
246     /** Return true if the SkStream/Buffer represents a serialized picture, and
247      fills out SkPictInfo. After this function returns, the data source is not
248      rewound so it will have to be manually reset before passing to
249      MakeFromStream or MakeFromBuffer. Note, MakeFromStream and
250      MakeFromBuffer perform this check internally so these entry points are
251      intended for stand alone tools.
252      If false is returned, SkPictInfo is unmodified.
253      */
254     static bool StreamIsSKP(SkStream*, struct SkPictInfo*);
255     static bool BufferIsSKP(class SkReadBuffer*, struct SkPictInfo*);
256     friend bool SkPicture_StreamIsSKP(SkStream*, struct SkPictInfo*);
257 
258     // Returns NULL if this is not an SkBigPicture.
asSkBigPicture()259     virtual const class SkBigPicture* asSkBigPicture() const { return nullptr; }
260 
261     friend struct SkPathCounter;
262 
263     static bool IsValidPictInfo(const struct SkPictInfo& info);
264     static sk_sp<SkPicture> Forwardport(const struct SkPictInfo&,
265                                         const class SkPictureData*,
266                                         class SkReadBuffer* buffer);
267 
268     struct SkPictInfo createHeader() const;
269     class SkPictureData* backport() const;
270 
271     uint32_t fUniqueID;
272 };
273 
274 #endif
275