• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/SkSamplingOptions.h"
14 #include "include/core/SkShader.h"
15 #include "include/core/SkTileMode.h"
16 #include "include/core/SkTypes.h"
17 
18 class SkCanvas;
19 class SkData;
20 struct SkDeserialProcs;
21 class SkImage;
22 class SkMatrix;
23 struct SkSerialProcs;
24 class SkStream;
25 class SkWStream;
26 
27 /** \class SkPicture
28     SkPicture records drawing commands made to SkCanvas. The command stream may be
29     played in whole or in part at a later time.
30 
31     SkPicture is an abstract class. SkPicture may be generated by SkPictureRecorder
32     or SkDrawable, or from SkPicture previously saved to SkData or SkStream.
33 
34     SkPicture may contain any SkCanvas drawing command, as well as one or more
35     SkCanvas matrix or SkCanvas clip. SkPicture has a cull SkRect, which is used as
36     a bounding box hint. To limit SkPicture bounds, use SkCanvas clip when
37     recording or drawing SkPicture.
38 */
39 class SK_API SkPicture : public SkRefCnt {
40 public:
41     ~SkPicture() override;
42 
43     /** Recreates SkPicture that was serialized into a stream. Returns constructed SkPicture
44         if successful; otherwise, returns nullptr. Fails if data does not permit
45         constructing valid SkPicture.
46 
47         procs->fPictureProc permits supplying a custom function to decode SkPicture.
48         If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
49         may be used to provide user context to procs->fPictureProc; procs->fPictureProc
50         is called with a pointer to data, data byte length, and user context.
51 
52         @param stream  container for serial data
53         @param procs   custom serial data decoders; may be nullptr
54         @return        SkPicture constructed from stream data
55     */
56     static sk_sp<SkPicture> MakeFromStream(SkStream* stream,
57                                            const SkDeserialProcs* procs = nullptr);
58 
59     /** Recreates SkPicture that was serialized into data. Returns constructed SkPicture
60         if successful; otherwise, returns nullptr. Fails if data does not permit
61         constructing valid SkPicture.
62 
63         procs->fPictureProc permits supplying a custom function to decode SkPicture.
64         If procs->fPictureProc is nullptr, default decoding is used. procs->fPictureCtx
65         may be used to provide user context to procs->fPictureProc; procs->fPictureProc
66         is called with a pointer to data, data byte length, and user context.
67 
68         @param data   container for serial data
69         @param procs  custom serial data decoders; may be nullptr
70         @return       SkPicture constructed from data
71     */
72     static sk_sp<SkPicture> MakeFromData(const SkData* data,
73                                          const SkDeserialProcs* procs = nullptr);
74 
75     /**
76 
77         @param data   pointer to serial data
78         @param size   size of data
79         @param procs  custom serial data decoders; may be nullptr
80         @return       SkPicture constructed from data
81     */
82     static sk_sp<SkPicture> MakeFromData(const void* data, size_t size,
83                                          const SkDeserialProcs* procs = nullptr);
84 
85     /** \class SkPicture::AbortCallback
86         AbortCallback is an abstract class. An implementation of AbortCallback may
87         passed as a parameter to SkPicture::playback, to stop it before all drawing
88         commands have been processed.
89 
90         If AbortCallback::abort returns true, SkPicture::playback is interrupted.
91     */
92     class SK_API AbortCallback {
93     public:
94         /** Has no effect.
95         */
96         virtual ~AbortCallback() = default;
97 
98         /** Stops SkPicture playback when some condition is met. A subclass of
99             AbortCallback provides an override for abort() that can stop SkPicture::playback.
100 
101             The part of SkPicture drawn when aborted is undefined. SkPicture instantiations are
102             free to stop drawing at different points during playback.
103 
104             If the abort happens inside one or more calls to SkCanvas::save(), stack
105             of SkCanvas matrix and SkCanvas clip values is restored to its state before
106             SkPicture::playback was called.
107 
108             @return  true to stop playback
109 
110         example: https://fiddle.skia.org/c/@Picture_AbortCallback_abort
111         */
112         virtual bool abort() = 0;
113 
114     protected:
115         AbortCallback() = default;
116         AbortCallback(const AbortCallback&) = delete;
117         AbortCallback& operator=(const AbortCallback&) = delete;
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         @param nested  if true, include the op-counts of nested pictures as well, else
201                        just return count the ops in the top-level picture.
202         @return  approximate operation count
203 
204         example: https://fiddle.skia.org/c/@Picture_approximateOpCount
205     */
206     virtual int approximateOpCount(bool nested = false) const = 0;
207 
208     /** Returns the approximate byte size of SkPicture. Does not include large objects
209         referenced by SkPicture.
210 
211         @return  approximate size
212 
213         example: https://fiddle.skia.org/c/@Picture_approximateBytesUsed
214     */
215     virtual size_t approximateBytesUsed() const = 0;
216 
217     /** Return a new shader that will draw with this picture.
218      *
219      *  @param tmx  The tiling mode to use when sampling in the x-direction.
220      *  @param tmy  The tiling mode to use when sampling in the y-direction.
221      *  @param mode How to filter the tiles
222      *  @param localMatrix Optional matrix used when sampling
223      *  @param tile The tile rectangle in picture coordinates: this represents the subset
224      *              (or superset) of the picture used when building a tile. It is not
225      *              affected by localMatrix and does not imply scaling (only translation
226      *              and cropping). If null, the tile rect is considered equal to the picture
227      *              bounds.
228      *  @return     Returns a new shader object. Note: this function never returns null.
229      */
230     sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode,
231                                const SkMatrix* localMatrix, const SkRect* tileRect) const;
232 
makeShader(SkTileMode tmx,SkTileMode tmy,SkFilterMode mode)233     sk_sp<SkShader> makeShader(SkTileMode tmx, SkTileMode tmy, SkFilterMode mode) const {
234         return this->makeShader(tmx, tmy, mode, nullptr, nullptr);
235     }
236 
237 private:
238     // Allowed subclasses.
239     SkPicture();
240     friend class SkBigPicture;
241     friend class SkEmptyPicture;
242     friend class SkPicturePriv;
243     template <typename> friend class SkMiniPicture;
244 
245     void serialize(SkWStream*, const SkSerialProcs*, class SkRefCntSet* typefaces,
246         bool textBlobsOnly=false) const;
247     static sk_sp<SkPicture> MakeFromStream(SkStream*, const SkDeserialProcs*,
248                                            class SkTypefacePlayback*);
249     friend class SkPictureData;
250 
251     /** Return true if the SkStream/Buffer represents a serialized picture, and
252      fills out SkPictInfo. After this function returns, the data source is not
253      rewound so it will have to be manually reset before passing to
254      MakeFromStream or MakeFromBuffer. Note, MakeFromStream and
255      MakeFromBuffer perform this check internally so these entry points are
256      intended for stand alone tools.
257      If false is returned, SkPictInfo is unmodified.
258      */
259     static bool StreamIsSKP(SkStream*, struct SkPictInfo*);
260     static bool BufferIsSKP(class SkReadBuffer*, struct SkPictInfo*);
261     friend bool SkPicture_StreamIsSKP(SkStream*, struct SkPictInfo*);
262 
263     // Returns NULL if this is not an SkBigPicture.
asSkBigPicture()264     virtual const class SkBigPicture* asSkBigPicture() const { return nullptr; }
265 
266     friend struct SkPathCounter;
267 
268     static bool IsValidPictInfo(const struct SkPictInfo& info);
269     static sk_sp<SkPicture> Forwardport(const struct SkPictInfo&,
270                                         const class SkPictureData*,
271                                         class SkReadBuffer* buffer);
272 
273     struct SkPictInfo createHeader() const;
274     class SkPictureData* backport() const;
275 
276     uint32_t fUniqueID;
277     mutable std::atomic<bool> fAddedToCache{false};
278 };
279 
280 #endif
281