image/src/FrameAnimator.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:522588afec19
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef mozilla_imagelib_FrameAnimator_h_
8 #define mozilla_imagelib_FrameAnimator_h_
9
10 #include "mozilla/TimeStamp.h"
11 #include "nsRect.h"
12
13 namespace mozilla {
14 namespace image {
15
16 class FrameBlender;
17
18 class FrameAnimator
19 {
20 public:
21 FrameAnimator(FrameBlender& aBlender, uint16_t aAnimationMode);
22
23 /**
24 * Return value from RequestRefresh. Tells callers what happened in that call
25 * to RequestRefresh.
26 */
27 struct RefreshResult
28 {
29 // The dirty rectangle to be re-drawn after this RequestRefresh().
30 nsIntRect dirtyRect;
31
32 // Whether any frame changed, and hence the dirty rect was set.
33 bool frameAdvanced : 1;
34
35 // Whether the animation has finished playing.
36 bool animationFinished : 1;
37
38 // Whether an error has occurred when trying to advance a frame. Note that
39 // errors do not, on their own, end the animation.
40 bool error : 1;
41
42 RefreshResult()
43 : frameAdvanced(false)
44 , animationFinished(false)
45 , error(false)
46 {}
47
48 void Accumulate(const RefreshResult& other)
49 {
50 frameAdvanced = frameAdvanced || other.frameAdvanced;
51 animationFinished = animationFinished || other.animationFinished;
52 error = error || other.error;
53 dirtyRect = dirtyRect.Union(other.dirtyRect);
54 }
55 };
56
57 /**
58 * Re-evaluate what frame we're supposed to be on, and do whatever blending
59 * is necessary to get us to that frame.
60 *
61 * Returns the result of that blending, including whether the current frame
62 * changed and what the resulting dirty rectangle is.
63 */
64 RefreshResult RequestRefresh(const mozilla::TimeStamp& aTime);
65
66 /**
67 * Call when this image is finished decoding so we know that there aren't any
68 * more frames coming.
69 */
70 void SetDoneDecoding(bool aDone);
71
72 /**
73 * Call when you need to re-start animating. Ensures we start from the first
74 * frame.
75 */
76 void ResetAnimation();
77
78 /**
79 * The animation mode of the image.
80 *
81 * Constants defined in imgIContainer.idl.
82 */
83 void SetAnimationMode(uint16_t aAnimationMode);
84
85 /**
86 * Set the area to refresh when we loop around to the first frame.
87 */
88 void SetFirstFrameRefreshArea(const nsIntRect& aRect);
89
90 /**
91 * Union the area to refresh when we loop around to the first frame with this
92 * rect.
93 */
94 void UnionFirstFrameRefreshArea(const nsIntRect& aRect);
95
96 /**
97 * If the animation frame time has not yet been set, set it to
98 * TimeStamp::Now().
99 */
100 void InitAnimationFrameTimeIfNecessary();
101
102 /**
103 * Set the animation frame time to @aTime.
104 */
105 void SetAnimationFrameTime(const TimeStamp& aTime);
106
107 /**
108 * The current frame we're on, from 0 to (numFrames - 1).
109 */
110 uint32_t GetCurrentAnimationFrameIndex() const;
111
112 /**
113 * Get the area we refresh when we loop around to the first frame.
114 */
115 nsIntRect GetFirstFrameRefreshArea() const;
116
117 private: // methods
118 /**
119 * Gets the length of a single loop of this image, in milliseconds.
120 *
121 * If this image is not finished decoding, is not animated, or it is animated
122 * but does not loop, returns -1. Can return 0 in the case of an animated image
123 * that has a 0ms delay between its frames and does not loop.
124 */
125 int32_t GetSingleLoopTime() const;
126
127 /**
128 * Advances the animation. Typically, this will advance a single frame, but it
129 * may advance multiple frames. This may happen if we have infrequently
130 * "ticking" refresh drivers (e.g. in background tabs), or extremely short-
131 * lived animation frames.
132 *
133 * @param aTime the time that the animation should advance to. This will
134 * typically be <= TimeStamp::Now().
135 *
136 * @returns a RefreshResult that shows whether the frame was successfully
137 * advanced, and its resulting dirty rect.
138 */
139 RefreshResult AdvanceFrame(mozilla::TimeStamp aTime);
140
141 /**
142 * Get the time the frame we're currently displaying is supposed to end.
143 *
144 * In the error case, returns an "infinity" timestamp.
145 */
146 mozilla::TimeStamp GetCurrentImgFrameEndTime() const;
147
148 private: // data
149 //! Area of the first frame that needs to be redrawn on subsequent loops.
150 nsIntRect mFirstFrameRefreshArea;
151
152 //! the time that the animation advanced to the current frame
153 TimeStamp mCurrentAnimationFrameTime;
154
155 //! The current frame index we're on. 0 to (numFrames - 1).
156 uint32_t mCurrentAnimationFrameIndex;
157
158 //! number of loops remaining before animation stops (-1 no stop)
159 int32_t mLoopCounter;
160
161 //! All the frames of the image, shared with our owner
162 FrameBlender& mFrameBlender;
163
164 //! The animation mode of this image. Constants defined in imgIContainer.
165 uint16_t mAnimationMode;
166
167 //! Whether this image is done being decoded.
168 bool mDoneDecoding;
169 };
170
171 } // namespace image
172 } // namespace mozilla
173
174 #endif /* mozilla_imagelib_FrameAnimator_h_ */

mercurial