1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
29 //////////////////////////////////////////////////////////////////////////////
31 AnimationEntry::AnimationEntry()
35 AnimationEntry::~AnimationEntry()
39 //////////////////////////////////////////////////////////////////////////////
41 AnimationEntryFixed::AnimationEntryFixed(double fDuration
, double fState
)
42 : mfDuration(fDuration
),
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
);
61 && basegfx::fTools::equal(mfDuration
, pCompare
->mfDuration
)
62 && basegfx::fTools::equal(mfState
, pCompare
->mfState
));
65 double AnimationEntryFixed::getDuration() const
70 double AnimationEntryFixed::getStateAtTime(double /*fTime*/) const
75 double AnimationEntryFixed::getNextEventTime(double fTime
) const
77 if(basegfx::fTools::less(fTime
, mfDuration
))
87 //////////////////////////////////////////////////////////////////////////////
89 AnimationEntryLinear::AnimationEntryLinear(double fDuration
, double fFrequency
, double fStart
, double fStop
)
90 : mfDuration(fDuration
),
91 mfFrequency(fFrequency
),
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
);
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
121 double AnimationEntryLinear::getStateAtTime(double fTime
) const
123 if(basegfx::fTools::more(mfDuration
, 0.0))
125 const double fFactor(fTime
/ mfDuration
);
133 return mfStart
+ ((mfStop
- mfStart
) * fFactor
);
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
))
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();
178 AnimationEntryList::AnimationEntryList()
183 AnimationEntryList::~AnimationEntryList()
185 for(sal_uInt32
a(0L); a
< maEntries
.size(); 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
]);
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
]))
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
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
);
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
;
273 //////////////////////////////////////////////////////////////////////////////
275 AnimationEntryLoop::AnimationEntryLoop(sal_uInt32 nRepeat
)
276 : AnimationEntryList(),
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
]);
297 bool AnimationEntryLoop::operator==(const AnimationEntry
& rCandidate
) const
299 const AnimationEntryLoop
* pCompare
= dynamic_cast< const AnimationEntryLoop
* >(&rCandidate
);
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
)
323 const double fTimeAtLoopStart((double)nCurrentLoop
* mfDuration
);
324 const double fRelativeTime(fTime
- fTimeAtLoopStart
);
325 return AnimationEntryList::getStateAtTime(fRelativeTime
);
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
;
355 } // end of namespace animation
356 } // end of namespace drawinglayer
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */