Flutter Engine
The Flutter Engine
SkResources.h
Go to the documentation of this file.
1/*
2 * Copyright 2019 Google LLC
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 SkResources_DEFINED
9#define SkResources_DEFINED
10
11#include "include/core/SkData.h"
19#include "src/core/SkTHash.h"
20
21#include <memory>
22
24class SkCodec;
25class SkImage;
26
27namespace skresources {
28
29/**
30 * Image asset proxy interface.
31 */
32class SK_API ImageAsset : public SkRefCnt {
33public:
34 /**
35 * Returns true if the image asset is animated.
36 */
37 virtual bool isMultiFrame() = 0;
38
39 /**
40 * DEPRECATED: override getFrameData() instead.
41 *
42 * Returns the SkImage for a given frame.
43 *
44 * If the image asset is static, getFrame() is only called once, at animation load time.
45 * Otherwise, this gets invoked every time the animation time is adjusted (on every seek).
46 *
47 * Embedders should cache and serve the same SkImage whenever possible, for efficiency.
48 *
49 * @param t Frame time code, in seconds, relative to the image layer timeline origin
50 * (in-point).
51 */
52 virtual sk_sp<SkImage> getFrame(float t);
53
54 // Describes how the frame image is to be scaled to the animation-declared asset size.
55 enum class SizeFit {
56 // See SkMatrix::ScaleToFit
61
62 // No scaling.
63 kNone,
64 };
65
66 struct FrameData {
67 // SkImage payload.
69 // Resampling parameters.
71 // Additional image transform to be applied before AE scaling rules.
73 // Strategy for image size -> AE asset size scaling.
74 SizeFit scaling = SizeFit::kCenter;
75 };
76
77 /**
78 * Returns the payload for a given frame.
79 *
80 * If the image asset is static, getFrameData() is only called once, at animation load time.
81 * Otherwise, this gets invoked every time the animation time is adjusted (on every seek).
82 *
83 * Embedders should cache and serve the same SkImage whenever possible, for efficiency.
84 *
85 * @param t Frame time code, in seconds, relative to the image layer timeline origin
86 * (in-point).
87 */
88 virtual FrameData getFrameData(float t);
89};
90
92 // Images are decoded on-the-fly, at rasterization time.
93 // Large images may cause jank as decoding is expensive (and can thrash internal caches).
95 // Force-decode all images upfront, at the cost of potentially more RAM and slower
96 // animation build times.
98};
99
100class MultiFrameImageAsset final : public ImageAsset {
101public:
102 // Clients must call SkCodec::Register() to load the required decoding image codecs before
103 // calling Make. For example:
104 // SkCodec::Register(SkPngDecoder::Decoder());
107 // If the client has already decoded the data, they can use this constructor.
108 static sk_sp<MultiFrameImageAsset> Make(std::unique_ptr<SkCodec>,
110
111
112 bool isMultiFrame() override;
113
114 sk_sp<SkImage> getFrame(float t) override;
115
116private:
117 explicit MultiFrameImageAsset(std::unique_ptr<SkAnimCodecPlayer>, ImageDecodeStrategy);
118
119 sk_sp<SkImage> generateFrame(float t);
120
121 std::unique_ptr<SkAnimCodecPlayer> fPlayer;
122 sk_sp<SkImage> fCachedFrame;
123 ImageDecodeStrategy fStrategy;
124
125 using INHERITED = ImageAsset;
126};
127
128/**
129 * External track (e.g. audio playback) interface.
130 *
131 * Used to wrap data payload and playback controllers.
132 */
134public:
135 /**
136 * Playback control callback, emitted for each corresponding Animation::seek().
137 *
138 * @param t Frame time code, in seconds, relative to the layer's timeline origin
139 * (in-point).
140 *
141 * Negative |t| values are used to signal off state (stop playback outside layer span).
142 */
143 virtual void seek(float t) = 0;
144};
145
146/**
147 * ResourceProvider is an interface that lets rich-content modules defer loading of external
148 * resources (images, fonts, etc.) to embedding clients.
149 */
151public:
152 /**
153 * Load a generic resource (currently only nested animations) specified by |path| + |name|,
154 * and return as an SkData.
155 */
156 virtual sk_sp<SkData> load(const char[] /* resource_path */,
157 const char[] /* resource_name */) const {
158 return nullptr;
159 }
160
161 /**
162 * Load an image asset specified by |path| + |name|, and returns the corresponding
163 * ImageAsset proxy.
164 */
165 virtual sk_sp<ImageAsset> loadImageAsset(const char[] /* resource_path */,
166 const char[] /* resource_name */,
167 const char[] /* resource_id */) const {
168 return nullptr;
169 }
170
171 /**
172 * Load an external audio track specified by |path|/|name|/|id|.
173 */
174 virtual sk_sp<ExternalTrackAsset> loadAudioAsset(const char[] /* resource_path */,
175 const char[] /* resource_name */,
176 const char[] /* resource_id */) {
177 return nullptr;
178 }
179
180 /**
181 * DEPRECATED: implement loadTypeface() instead.
182 *
183 * Load an external font and return as SkData.
184 *
185 * @param name font name ("fName" Lottie property)
186 * @param url web font URL ("fPath" Lottie property)
187 *
188 * -- Note --
189 *
190 * This mechanism assumes monolithic fonts (single data blob). Some web font providers may
191 * serve multiple font blobs, segmented for various unicode ranges, depending on user agent
192 * capabilities (woff, woff2). In that case, the embedder would need to advertise no user
193 * agent capabilities when fetching the URL, in order to receive full font data.
194 */
195 virtual sk_sp<SkData> loadFont(const char[] /* name */,
196 const char[] /* url */) const {
197 return nullptr;
198 }
199
200 /**
201 * Load an external font and return as SkTypeface.
202 *
203 * @param name font name
204 * @param url web font URL
205 */
206 virtual sk_sp<SkTypeface> loadTypeface(const char[] /* name */,
207 const char[] /* url */) const {
208 return nullptr;
209 }
210};
211
213public:
214 // To decode images, clients must call SkCodecs::Register() before calling Make.
217
218 sk_sp<SkData> load(const char resource_path[], const char resource_name[]) const override;
219
220 sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;
221
222private:
224
225 const SkString fDir;
226 const ImageDecodeStrategy fStrategy;
227
229};
230
232protected:
234
235 sk_sp<SkData> load(const char[], const char[]) const override;
236 sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;
237 sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override;
238 sk_sp<SkData> loadFont(const char[], const char[]) const override;
239 sk_sp<ExternalTrackAsset> loadAudioAsset(const char[], const char[], const char[]) override;
240
241protected:
243};
244
246public:
248 return rp ? sk_sp<CachingResourceProvider>(new CachingResourceProvider(std::move(rp)))
249 : nullptr;
250 }
251
252private:
254
255 sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;
256
257 mutable SkMutex fMutex;
259
261};
262
264public:
265 // If font data is supplied via base64 encoding, this needs a provided SkFontMgr to process
266 // that font data into an SkTypeface. To decode images, clients must call SkCodecs::Register()
267 // before calling Make.
272
273private:
277
278 sk_sp<ImageAsset> loadImageAsset(const char[], const char[], const char[]) const override;
279 sk_sp<SkTypeface> loadTypeface(const char[], const char[]) const override;
280
281 const ImageDecodeStrategy fStrategy;
282 sk_sp<const SkFontMgr> fFontMgr;
283
285};
286
287} // namespace skresources
288
289#endif // SkResources_DEFINED
#define SK_API
Definition: SkAPI.h:35
static const char * resource_name(SkPDFResourceType type)
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
skresources::ResourceProvider ResourceProvider
@ kStart_ScaleToFit
scales and aligns to left and top
Definition: SkMatrix.h:138
@ kEnd_ScaleToFit
scales and aligns to right and bottom
Definition: SkMatrix.h:140
@ kCenter_ScaleToFit
scales and aligns to center
Definition: SkMatrix.h:139
@ kFill_ScaleToFit
scales in x and y to fill destination SkRect
Definition: SkMatrix.h:137
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
static sk_sp< CachingResourceProvider > Make(sk_sp< ResourceProvider > rp)
Definition: SkResources.h:247
virtual void seek(float t)=0
sk_sp< ImageAsset > loadImageAsset(const char[], const char[], const char[]) const override
sk_sp< SkData > load(const char resource_path[], const char resource_name[]) const override
static sk_sp< FileResourceProvider > Make(SkString base_dir, ImageDecodeStrategy=ImageDecodeStrategy::kLazyDecode)
virtual bool isMultiFrame()=0
static sk_sp< MultiFrameImageAsset > Make(sk_sp< SkData >, ImageDecodeStrategy=ImageDecodeStrategy::kLazyDecode)
sk_sp< SkImage > getFrame(float t) override
sk_sp< SkTypeface > loadTypeface(const char[], const char[]) const override
ResourceProviderProxyBase(sk_sp< ResourceProvider >)
sk_sp< ImageAsset > loadImageAsset(const char[], const char[], const char[]) const override
sk_sp< ExternalTrackAsset > loadAudioAsset(const char[], const char[], const char[]) override
const sk_sp< ResourceProvider > fProxy
Definition: SkResources.h:242
sk_sp< SkData > load(const char[], const char[]) const override
sk_sp< SkData > loadFont(const char[], const char[]) const override
virtual sk_sp< SkData > load(const char[], const char[]) const
Definition: SkResources.h:156
virtual sk_sp< SkData > loadFont(const char[], const char[]) const
Definition: SkResources.h:195
virtual sk_sp< ExternalTrackAsset > loadAudioAsset(const char[], const char[], const char[])
Definition: SkResources.h:174
virtual sk_sp< ImageAsset > loadImageAsset(const char[], const char[], const char[]) const
Definition: SkResources.h:165
virtual sk_sp< SkTypeface > loadTypeface(const char[], const char[]) const
Definition: SkResources.h:206
sk_sp< SkFontMgr > fontMgr
Definition: examples.cpp:32
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
skresources::ImageAsset ImageAsset
Definition: Skottie.h:45