Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include <drawinglayer/animation/animationtiming.hxx>
21 : : #include <basegfx/numeric/ftools.hxx>
22 : :
23 : : //////////////////////////////////////////////////////////////////////////////
24 : :
25 : : namespace drawinglayer
26 : : {
27 : : namespace animation
28 : : {
29 : : //////////////////////////////////////////////////////////////////////////////
30 : :
31 : 0 : AnimationEntry::AnimationEntry()
32 : : {
33 : 0 : }
34 : :
35 : 0 : AnimationEntry::~AnimationEntry()
36 : : {
37 [ # # ]: 0 : }
38 : :
39 : : //////////////////////////////////////////////////////////////////////////////
40 : :
41 : 0 : AnimationEntryFixed::AnimationEntryFixed(double fDuration, double fState)
42 : : : mfDuration(fDuration),
43 : 0 : mfState(fState)
44 : : {
45 : 0 : }
46 : :
47 : 0 : AnimationEntryFixed::~AnimationEntryFixed()
48 : : {
49 [ # # ]: 0 : }
50 : :
51 : 0 : AnimationEntry* AnimationEntryFixed::clone() const
52 : : {
53 [ # # ]: 0 : return new AnimationEntryFixed(mfDuration, mfState);
54 : : }
55 : :
56 : 0 : bool AnimationEntryFixed::operator==(const AnimationEntry& rCandidate) const
57 : : {
58 [ # # ]: 0 : const AnimationEntryFixed* pCompare = dynamic_cast< const AnimationEntryFixed* >(&rCandidate);
59 : :
60 : : return (pCompare
61 : 0 : && basegfx::fTools::equal(mfDuration, pCompare->mfDuration)
62 [ # # # # ]: 0 : && basegfx::fTools::equal(mfState, pCompare->mfState));
[ # # ]
63 : : }
64 : :
65 : 0 : double AnimationEntryFixed::getDuration() const
66 : : {
67 : 0 : return mfDuration;
68 : : }
69 : :
70 : 0 : double AnimationEntryFixed::getStateAtTime(double /*fTime*/) const
71 : : {
72 : 0 : return mfState;
73 : : }
74 : :
75 : 0 : double AnimationEntryFixed::getNextEventTime(double fTime) const
76 : : {
77 [ # # ]: 0 : if(basegfx::fTools::less(fTime, mfDuration))
78 : : {
79 : 0 : return mfDuration;
80 : : }
81 : : else
82 : : {
83 : 0 : return 0.0;
84 : : }
85 : : }
86 : :
87 : : //////////////////////////////////////////////////////////////////////////////
88 : :
89 : 0 : AnimationEntryLinear::AnimationEntryLinear(double fDuration, double fFrequency, double fStart, double fStop)
90 : : : mfDuration(fDuration),
91 : : mfFrequency(fFrequency),
92 : : mfStart(fStart),
93 : 0 : mfStop(fStop)
94 : : {
95 : 0 : }
96 : :
97 : 0 : AnimationEntryLinear::~AnimationEntryLinear()
98 : : {
99 [ # # ]: 0 : }
100 : :
101 : 0 : AnimationEntry* AnimationEntryLinear::clone() const
102 : : {
103 [ # # ]: 0 : return new AnimationEntryLinear(mfDuration, mfFrequency, mfStart, mfStop);
104 : : }
105 : :
106 : 0 : bool AnimationEntryLinear::operator==(const AnimationEntry& rCandidate) const
107 : : {
108 [ # # ]: 0 : const AnimationEntryLinear* pCompare = dynamic_cast< const AnimationEntryLinear* >(&rCandidate);
109 : :
110 : : return (pCompare
111 : 0 : && basegfx::fTools::equal(mfDuration, pCompare->mfDuration)
112 : 0 : && basegfx::fTools::equal(mfStart, pCompare->mfStart)
113 [ # # # # : 0 : && basegfx::fTools::equal(mfStop, pCompare->mfStop));
# # ][ # # ]
114 : : }
115 : :
116 : 0 : double AnimationEntryLinear::getDuration() const
117 : : {
118 : 0 : return mfDuration;
119 : : }
120 : :
121 : 0 : double AnimationEntryLinear::getStateAtTime(double fTime) const
122 : : {
123 [ # # ]: 0 : if(basegfx::fTools::more(mfDuration, 0.0))
124 : : {
125 : 0 : const double fFactor(fTime / mfDuration);
126 : :
127 [ # # ]: 0 : if(fFactor > 1.0)
128 : : {
129 : 0 : return mfStop;
130 : : }
131 : : else
132 : : {
133 : 0 : return mfStart + ((mfStop - mfStart) * fFactor);
134 : : }
135 : : }
136 : : else
137 : : {
138 : 0 : return mfStart;
139 : : }
140 : : }
141 : :
142 : 0 : double AnimationEntryLinear::getNextEventTime(double fTime) const
143 : : {
144 [ # # ]: 0 : if(basegfx::fTools::less(fTime, mfDuration))
145 : : {
146 : : // use the simple solution: just add the frequency. More correct (but also more
147 : : // complicated) would be to calculate the slice of time we are in and when this
148 : : // slice will end. For the animations, this makes no quality difference.
149 : 0 : fTime += mfFrequency;
150 : :
151 [ # # ]: 0 : if(basegfx::fTools::more(fTime, mfDuration))
152 : : {
153 : 0 : fTime = mfDuration;
154 : : }
155 : :
156 : 0 : return fTime;
157 : : }
158 : : else
159 : : {
160 : 0 : return 0.0;
161 : : }
162 : : }
163 : :
164 : : //////////////////////////////////////////////////////////////////////////////
165 : :
166 : 0 : sal_uInt32 AnimationEntryList::impGetIndexAtTime(double fTime, double &rfAddedTime) const
167 : : {
168 : 0 : sal_uInt32 nIndex(0L);
169 : :
170 [ # # ][ # # ]: 0 : while(nIndex < maEntries.size() && basegfx::fTools::lessOrEqual(rfAddedTime + maEntries[nIndex]->getDuration(), fTime))
[ # # ][ # # ]
[ # # ]
[ # # # # ]
171 : : {
172 : 0 : rfAddedTime += maEntries[nIndex++]->getDuration();
173 : : }
174 : :
175 : 0 : return nIndex;
176 : : }
177 : :
178 : 0 : AnimationEntryList::AnimationEntryList()
179 [ # # ]: 0 : : mfDuration(0.0)
180 : : {
181 : 0 : }
182 : :
183 : 0 : AnimationEntryList::~AnimationEntryList()
184 : : {
185 [ # # ]: 0 : for(sal_uInt32 a(0L); a < maEntries.size(); a++)
186 : : {
187 [ # # ][ # # ]: 0 : delete maEntries[a];
[ # # ]
188 : : }
189 [ # # ]: 0 : }
190 : :
191 : 0 : AnimationEntry* AnimationEntryList::clone() const
192 : : {
193 [ # # ]: 0 : AnimationEntryList* pNew = new AnimationEntryList();
194 : :
195 [ # # ]: 0 : for(sal_uInt32 a(0L); a < maEntries.size(); a++)
196 : : {
197 : 0 : pNew->append(*maEntries[a]);
198 : : }
199 : :
200 : 0 : return pNew;
201 : : }
202 : :
203 : 0 : bool AnimationEntryList::operator==(const AnimationEntry& rCandidate) const
204 : : {
205 [ # # ]: 0 : const AnimationEntryList* pCompare = dynamic_cast< const AnimationEntryList* >(&rCandidate);
206 : :
207 [ # # ][ # # ]: 0 : if(pCompare && mfDuration == pCompare->mfDuration)
208 : : {
209 [ # # ]: 0 : for(sal_uInt32 a(0L); a < maEntries.size(); a++)
210 : : {
211 [ # # ]: 0 : if(!(*maEntries[a] == *pCompare->maEntries[a]))
212 : : {
213 : 0 : return false;
214 : : }
215 : : }
216 : :
217 : 0 : return true;
218 : : }
219 : :
220 : 0 : return false;
221 : : }
222 : :
223 : 0 : void AnimationEntryList::append(const AnimationEntry& rCandidate)
224 : : {
225 [ # # ]: 0 : const double fDuration(rCandidate.getDuration());
226 : :
227 [ # # ]: 0 : if(!basegfx::fTools::equalZero(fDuration))
228 : : {
229 [ # # ][ # # ]: 0 : maEntries.push_back(rCandidate.clone());
230 : 0 : mfDuration += fDuration;
231 : : }
232 : 0 : }
233 : :
234 : 0 : double AnimationEntryList::getDuration() const
235 : : {
236 : 0 : return mfDuration;
237 : : }
238 : :
239 : 0 : double AnimationEntryList::getStateAtTime(double fTime) const
240 : : {
241 [ # # ]: 0 : if(!basegfx::fTools::equalZero(mfDuration))
242 : : {
243 : 0 : double fAddedTime(0.0);
244 [ # # ]: 0 : const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime));
245 : :
246 [ # # ]: 0 : if(nIndex < maEntries.size())
247 : : {
248 [ # # ][ # # ]: 0 : return maEntries[nIndex]->getStateAtTime(fTime - fAddedTime);
249 : : }
250 : : }
251 : :
252 : 0 : return 0.0;
253 : : }
254 : :
255 : 0 : double AnimationEntryList::getNextEventTime(double fTime) const
256 : : {
257 : 0 : double fNewTime(0.0);
258 : :
259 [ # # ]: 0 : if(!basegfx::fTools::equalZero(mfDuration))
260 : : {
261 : 0 : double fAddedTime(0.0);
262 [ # # ]: 0 : const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime));
263 : :
264 [ # # ]: 0 : if(nIndex < maEntries.size())
265 : : {
266 [ # # ][ # # ]: 0 : fNewTime = maEntries[nIndex]->getNextEventTime(fTime - fAddedTime) + fAddedTime;
267 : : }
268 : : }
269 : :
270 : 0 : return fNewTime;
271 : : }
272 : :
273 : : //////////////////////////////////////////////////////////////////////////////
274 : :
275 : 0 : AnimationEntryLoop::AnimationEntryLoop(sal_uInt32 nRepeat)
276 : : : AnimationEntryList(),
277 : 0 : mnRepeat(nRepeat)
278 : : {
279 : 0 : }
280 : :
281 : 0 : AnimationEntryLoop::~AnimationEntryLoop()
282 : : {
283 [ # # ]: 0 : }
284 : :
285 : 0 : AnimationEntry* AnimationEntryLoop::clone() const
286 : : {
287 [ # # ]: 0 : AnimationEntryLoop* pNew = new AnimationEntryLoop(mnRepeat);
288 : :
289 [ # # ]: 0 : for(sal_uInt32 a(0L); a < maEntries.size(); a++)
290 : : {
291 : 0 : pNew->append(*maEntries[a]);
292 : : }
293 : :
294 : 0 : return pNew;
295 : : }
296 : :
297 : 0 : bool AnimationEntryLoop::operator==(const AnimationEntry& rCandidate) const
298 : : {
299 [ # # ]: 0 : const AnimationEntryLoop* pCompare = dynamic_cast< const AnimationEntryLoop* >(&rCandidate);
300 : :
301 : : return (pCompare
302 : : && mnRepeat == pCompare->mnRepeat
303 [ # # ][ # # ]: 0 : && AnimationEntryList::operator==(rCandidate));
[ # # ]
304 : : }
305 : :
306 : 0 : double AnimationEntryLoop::getDuration() const
307 : : {
308 : 0 : return (mfDuration * (double)mnRepeat);
309 : : }
310 : :
311 : 0 : double AnimationEntryLoop::getStateAtTime(double fTime) const
312 : : {
313 [ # # ][ # # ]: 0 : if(mnRepeat && !basegfx::fTools::equalZero(mfDuration))
[ # # ]
314 : : {
315 : 0 : const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration));
316 : :
317 [ # # ]: 0 : if(nCurrentLoop > mnRepeat)
318 : : {
319 : 0 : return 1.0;
320 : : }
321 : : else
322 : : {
323 : 0 : const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration);
324 : 0 : const double fRelativeTime(fTime - fTimeAtLoopStart);
325 : 0 : return AnimationEntryList::getStateAtTime(fRelativeTime);
326 : : }
327 : : }
328 : :
329 : 0 : return 0.0;
330 : : }
331 : :
332 : 0 : double AnimationEntryLoop::getNextEventTime(double fTime) const
333 : : {
334 : 0 : double fNewTime(0.0);
335 : :
336 [ # # ][ # # ]: 0 : if(mnRepeat && !basegfx::fTools::equalZero(mfDuration))
[ # # ]
337 : : {
338 : 0 : const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration));
339 : :
340 [ # # ]: 0 : if(nCurrentLoop <= mnRepeat)
341 : : {
342 : 0 : const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration);
343 : 0 : const double fRelativeTime(fTime - fTimeAtLoopStart);
344 [ # # ]: 0 : const double fNextEventAtLoop(AnimationEntryList::getNextEventTime(fRelativeTime));
345 : :
346 [ # # ]: 0 : if(!basegfx::fTools::equalZero(fNextEventAtLoop))
347 : : {
348 : 0 : fNewTime = fNextEventAtLoop + fTimeAtLoopStart;
349 : : }
350 : : }
351 : : }
352 : :
353 : 0 : return fNewTime;
354 : : }
355 : : } // end of namespace animation
356 : : } // end of namespace drawinglayer
357 : :
358 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|