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
16class SkCanvas;
17class SkData;
18struct SkDeserialProcs;
19class SkImage;
20class SkMatrix;
21struct SkSerialProcs;
22class SkShader;
23class SkStream;
24class 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*/
38class SK_API SkPicture : public SkRefCnt {
39public:
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 */
97 AbortCallback() {}
98
99 /** Has no effect.
100 */
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 */
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
232private:
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.
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