update credits
[LibreOffice.git] / drawinglayer / source / animation / animationtiming.cxx
blob3a0362b17c74c8e91814a44b11c4828b1c204f81
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <drawinglayer/animation/animationtiming.hxx>
21 #include <basegfx/numeric/ftools.hxx>
23 //////////////////////////////////////////////////////////////////////////////
25 namespace drawinglayer
27 namespace animation
29 //////////////////////////////////////////////////////////////////////////////
31 AnimationEntry::AnimationEntry()
35 AnimationEntry::~AnimationEntry()
39 //////////////////////////////////////////////////////////////////////////////
41 AnimationEntryFixed::AnimationEntryFixed(double fDuration, double fState)
42 : mfDuration(fDuration),
43 mfState(fState)
47 AnimationEntryFixed::~AnimationEntryFixed()
51 AnimationEntry* AnimationEntryFixed::clone() const
53 return new AnimationEntryFixed(mfDuration, mfState);
56 bool AnimationEntryFixed::operator==(const AnimationEntry& rCandidate) const
58 const AnimationEntryFixed* pCompare = dynamic_cast< const AnimationEntryFixed* >(&rCandidate);
60 return (pCompare
61 && basegfx::fTools::equal(mfDuration, pCompare->mfDuration)
62 && basegfx::fTools::equal(mfState, pCompare->mfState));
65 double AnimationEntryFixed::getDuration() const
67 return mfDuration;
70 double AnimationEntryFixed::getStateAtTime(double /*fTime*/) const
72 return mfState;
75 double AnimationEntryFixed::getNextEventTime(double fTime) const
77 if(basegfx::fTools::less(fTime, mfDuration))
79 return mfDuration;
81 else
83 return 0.0;
87 //////////////////////////////////////////////////////////////////////////////
89 AnimationEntryLinear::AnimationEntryLinear(double fDuration, double fFrequency, double fStart, double fStop)
90 : mfDuration(fDuration),
91 mfFrequency(fFrequency),
92 mfStart(fStart),
93 mfStop(fStop)
97 AnimationEntryLinear::~AnimationEntryLinear()
101 AnimationEntry* AnimationEntryLinear::clone() const
103 return new AnimationEntryLinear(mfDuration, mfFrequency, mfStart, mfStop);
106 bool AnimationEntryLinear::operator==(const AnimationEntry& rCandidate) const
108 const AnimationEntryLinear* pCompare = dynamic_cast< const AnimationEntryLinear* >(&rCandidate);
110 return (pCompare
111 && basegfx::fTools::equal(mfDuration, pCompare->mfDuration)
112 && basegfx::fTools::equal(mfStart, pCompare->mfStart)
113 && basegfx::fTools::equal(mfStop, pCompare->mfStop));
116 double AnimationEntryLinear::getDuration() const
118 return mfDuration;
121 double AnimationEntryLinear::getStateAtTime(double fTime) const
123 if(basegfx::fTools::more(mfDuration, 0.0))
125 const double fFactor(fTime / mfDuration);
127 if(fFactor > 1.0)
129 return mfStop;
131 else
133 return mfStart + ((mfStop - mfStart) * fFactor);
136 else
138 return mfStart;
142 double AnimationEntryLinear::getNextEventTime(double fTime) const
144 if(basegfx::fTools::less(fTime, mfDuration))
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 fTime += mfFrequency;
151 if(basegfx::fTools::more(fTime, mfDuration))
153 fTime = mfDuration;
156 return fTime;
158 else
160 return 0.0;
164 //////////////////////////////////////////////////////////////////////////////
166 sal_uInt32 AnimationEntryList::impGetIndexAtTime(double fTime, double &rfAddedTime) const
168 sal_uInt32 nIndex(0L);
170 while(nIndex < maEntries.size() && basegfx::fTools::lessOrEqual(rfAddedTime + maEntries[nIndex]->getDuration(), fTime))
172 rfAddedTime += maEntries[nIndex++]->getDuration();
175 return nIndex;
178 AnimationEntryList::AnimationEntryList()
179 : mfDuration(0.0)
183 AnimationEntryList::~AnimationEntryList()
185 for(sal_uInt32 a(0L); a < maEntries.size(); a++)
187 delete maEntries[a];
191 AnimationEntry* AnimationEntryList::clone() const
193 AnimationEntryList* pNew = new AnimationEntryList();
195 for(sal_uInt32 a(0L); a < maEntries.size(); a++)
197 pNew->append(*maEntries[a]);
200 return pNew;
203 bool AnimationEntryList::operator==(const AnimationEntry& rCandidate) const
205 const AnimationEntryList* pCompare = dynamic_cast< const AnimationEntryList* >(&rCandidate);
207 if(pCompare && mfDuration == pCompare->mfDuration)
209 for(sal_uInt32 a(0L); a < maEntries.size(); a++)
211 if(!(*maEntries[a] == *pCompare->maEntries[a]))
213 return false;
217 return true;
220 return false;
223 void AnimationEntryList::append(const AnimationEntry& rCandidate)
225 const double fDuration(rCandidate.getDuration());
227 if(!basegfx::fTools::equalZero(fDuration))
229 maEntries.push_back(rCandidate.clone());
230 mfDuration += fDuration;
234 double AnimationEntryList::getDuration() const
236 return mfDuration;
239 double AnimationEntryList::getStateAtTime(double fTime) const
241 if(!basegfx::fTools::equalZero(mfDuration))
243 double fAddedTime(0.0);
244 const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime));
246 if(nIndex < maEntries.size())
248 return maEntries[nIndex]->getStateAtTime(fTime - fAddedTime);
252 return 0.0;
255 double AnimationEntryList::getNextEventTime(double fTime) const
257 double fNewTime(0.0);
259 if(!basegfx::fTools::equalZero(mfDuration))
261 double fAddedTime(0.0);
262 const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime));
264 if(nIndex < maEntries.size())
266 fNewTime = maEntries[nIndex]->getNextEventTime(fTime - fAddedTime) + fAddedTime;
270 return fNewTime;
273 //////////////////////////////////////////////////////////////////////////////
275 AnimationEntryLoop::AnimationEntryLoop(sal_uInt32 nRepeat)
276 : AnimationEntryList(),
277 mnRepeat(nRepeat)
281 AnimationEntryLoop::~AnimationEntryLoop()
285 AnimationEntry* AnimationEntryLoop::clone() const
287 AnimationEntryLoop* pNew = new AnimationEntryLoop(mnRepeat);
289 for(sal_uInt32 a(0L); a < maEntries.size(); a++)
291 pNew->append(*maEntries[a]);
294 return pNew;
297 bool AnimationEntryLoop::operator==(const AnimationEntry& rCandidate) const
299 const AnimationEntryLoop* pCompare = dynamic_cast< const AnimationEntryLoop* >(&rCandidate);
301 return (pCompare
302 && mnRepeat == pCompare->mnRepeat
303 && AnimationEntryList::operator==(rCandidate));
306 double AnimationEntryLoop::getDuration() const
308 return (mfDuration * (double)mnRepeat);
311 double AnimationEntryLoop::getStateAtTime(double fTime) const
313 if(mnRepeat && !basegfx::fTools::equalZero(mfDuration))
315 const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration));
317 if(nCurrentLoop > mnRepeat)
319 return 1.0;
321 else
323 const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration);
324 const double fRelativeTime(fTime - fTimeAtLoopStart);
325 return AnimationEntryList::getStateAtTime(fRelativeTime);
329 return 0.0;
332 double AnimationEntryLoop::getNextEventTime(double fTime) const
334 double fNewTime(0.0);
336 if(mnRepeat && !basegfx::fTools::equalZero(mfDuration))
338 const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration));
340 if(nCurrentLoop <= mnRepeat)
342 const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration);
343 const double fRelativeTime(fTime - fTimeAtLoopStart);
344 const double fNextEventAtLoop(AnimationEntryList::getNextEventTime(fRelativeTime));
346 if(!basegfx::fTools::equalZero(fNextEventAtLoop))
348 fNewTime = fNextEventAtLoop + fTimeAtLoopStart;
353 return fNewTime;
355 } // end of namespace animation
356 } // end of namespace drawinglayer
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */