1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkAnimatedImage_DEFINED
#define SkAnimatedImage_DEFINED
#include "SkBitmap.h"
#include "SkCodecAnimation.h"
#include "SkDrawable.h"
#include "SkMatrix.h"
#include "SkRect.h"
class SkAndroidCodec;
class SkPicture;
/**
* Thread unsafe drawable for drawing animated images (e.g. GIF).
*/
class SK_API SkAnimatedImage : public SkDrawable {
public:
/**
* Create an SkAnimatedImage from the SkAndroidCodec.
*
* Returns null on failure to allocate pixels. On success, this will
* decode the first frame. It will not animate until start() is called.
*
* @param scaledSize Size to draw the image, possibly requiring scaling.
* @param cropRect Rectangle to crop to after scaling.
* @param postProcess Picture to apply after scaling and cropping.
*/
static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>,
SkISize scaledSize, SkIRect cropRect, sk_sp<SkPicture> postProcess);
/**
* Simpler version that uses the default size, no cropping, and no postProcess.
*/
static sk_sp<SkAnimatedImage> Make(std::unique_ptr<SkAndroidCodec>);
~SkAnimatedImage() override;
/**
* Start or resume the animation. update() must be called to advance the
* time.
*/
void start();
/**
* Stop the animation. update() has no effect while the animation is
* stopped.
*/
void stop();
/**
* Reset the animation to the beginning.
*/
void reset();
/**
* Whether the animation is active.
*
* If true, update() can be called to animate.
*/
bool isRunning() const { return fRunning && !fFinished; }
/**
* Update the current time. If the image is animating, this may decode
* a new frame.
*
* @return the time to show the next frame.
* Returns numeric_limits<double>::max() if there is no max frame to
* show, and -1.0 if the animation is not running.
*/
double update(double msecs);
protected:
SkRect onGetBounds() override;
void onDraw(SkCanvas*) override;
private:
struct Frame {
SkBitmap fBitmap;
int fIndex;
SkCodecAnimation::DisposalMethod fDisposalMethod;
Frame();
bool copyTo(Frame*) const;
};
std::unique_ptr<SkAndroidCodec> fCodec;
const SkISize fScaledSize;
const SkImageInfo fDecodeInfo;
const SkIRect fCropRect;
const sk_sp<SkPicture> fPostProcess;
const bool fSimple; // no crop, scale, or postprocess
SkMatrix fMatrix; // used only if !fSimple
bool fFinished;
bool fRunning;
double fNowMS;
double fRemainingMS;
Frame fActiveFrame;
Frame fRestoreFrame;
SkAnimatedImage(std::unique_ptr<SkAndroidCodec>, SkISize scaledSize,
SkImageInfo decodeInfo, SkIRect cropRect, sk_sp<SkPicture> postProcess);
typedef SkDrawable INHERITED;
};
#endif // SkAnimatedImage_DEFINED
|