1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: animationtiming.cxx,v $
9 * last change: $Author: aw $ $Date: 2008-05-27 14:11:19 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_drawinglayer.hxx"
39 #include <drawinglayer/animation/animationtiming.hxx>
40 #include <basegfx/numeric/ftools.hxx>
42 //////////////////////////////////////////////////////////////////////////////
44 namespace drawinglayer
48 //////////////////////////////////////////////////////////////////////////////
50 AnimationEntry::AnimationEntry()
54 AnimationEntry::~AnimationEntry()
58 //////////////////////////////////////////////////////////////////////////////
60 AnimationEntryFixed::AnimationEntryFixed(double fDuration
, double fState
)
61 : mfDuration(fDuration
),
66 AnimationEntryFixed::~AnimationEntryFixed()
70 AnimationEntry
* AnimationEntryFixed::clone() const
72 return new AnimationEntryFixed(mfDuration
, mfState
);
75 bool AnimationEntryFixed::operator==(const AnimationEntry
& rCandidate
) const
77 const AnimationEntryFixed
* pCompare
= dynamic_cast< const AnimationEntryFixed
* >(&rCandidate
);
80 && basegfx::fTools::equal(mfDuration
, pCompare
->mfDuration
)
81 && basegfx::fTools::equal(mfState
, pCompare
->mfState
));
84 double AnimationEntryFixed::getDuration() const
89 double AnimationEntryFixed::getStateAtTime(double /*fTime*/) const
94 double AnimationEntryFixed::getNextEventTime(double fTime
) const
96 if(basegfx::fTools::less(fTime
, mfDuration
))
106 //////////////////////////////////////////////////////////////////////////////
108 AnimationEntryLinear::AnimationEntryLinear(double fDuration
, double fFrequency
, double fStart
, double fStop
)
109 : mfDuration(fDuration
),
110 mfFrequency(fFrequency
),
116 AnimationEntryLinear::~AnimationEntryLinear()
120 AnimationEntry
* AnimationEntryLinear::clone() const
122 return new AnimationEntryLinear(mfDuration
, mfFrequency
, mfStart
, mfStop
);
125 bool AnimationEntryLinear::operator==(const AnimationEntry
& rCandidate
) const
127 const AnimationEntryLinear
* pCompare
= dynamic_cast< const AnimationEntryLinear
* >(&rCandidate
);
130 && basegfx::fTools::equal(mfDuration
, pCompare
->mfDuration
)
131 && basegfx::fTools::equal(mfStart
, pCompare
->mfStart
)
132 && basegfx::fTools::equal(mfStop
, pCompare
->mfStop
));
135 double AnimationEntryLinear::getDuration() const
140 double AnimationEntryLinear::getStateAtTime(double fTime
) const
142 if(basegfx::fTools::more(mfDuration
, 0.0))
144 const double fFactor(fTime
/ mfDuration
);
152 return mfStart
+ ((mfStop
- mfStart
) * fFactor
);
161 double AnimationEntryLinear::getNextEventTime(double fTime
) const
163 if(basegfx::fTools::less(fTime
, mfDuration
))
165 // use the simple solution: just add the frequency. More correct (but also more
166 // complicated) would be to calculate the slice of time we are in and when this
167 // slice will end. For the animations, this makes no quality difference.
168 fTime
+= mfFrequency
;
170 if(basegfx::fTools::more(fTime
, mfDuration
))
183 //////////////////////////////////////////////////////////////////////////////
185 sal_uInt32
AnimationEntryList::impGetIndexAtTime(double fTime
, double &rfAddedTime
) const
187 sal_uInt32
nIndex(0L);
189 while(nIndex
< maEntries
.size() && basegfx::fTools::lessOrEqual(rfAddedTime
+ maEntries
[nIndex
]->getDuration(), fTime
))
191 rfAddedTime
+= maEntries
[nIndex
++]->getDuration();
197 AnimationEntryList::AnimationEntryList()
202 AnimationEntryList::~AnimationEntryList()
204 for(sal_uInt32
a(0L); a
< maEntries
.size(); a
++)
210 AnimationEntry
* AnimationEntryList::clone() const
212 AnimationEntryList
* pNew
= new AnimationEntryList();
214 for(sal_uInt32
a(0L); a
< maEntries
.size(); a
++)
216 pNew
->append(*maEntries
[a
]);
222 bool AnimationEntryList::operator==(const AnimationEntry
& rCandidate
) const
224 const AnimationEntryList
* pCompare
= dynamic_cast< const AnimationEntryList
* >(&rCandidate
);
226 if(pCompare
&& mfDuration
== pCompare
->mfDuration
)
228 for(sal_uInt32
a(0L); a
< maEntries
.size(); a
++)
230 if(!(*maEntries
[a
] == *pCompare
->maEntries
[a
]))
242 void AnimationEntryList::append(const AnimationEntry
& rCandidate
)
244 const double fDuration(rCandidate
.getDuration());
246 if(!basegfx::fTools::equalZero(fDuration
))
248 maEntries
.push_back(rCandidate
.clone());
249 mfDuration
+= fDuration
;
253 double AnimationEntryList::getDuration() const
258 double AnimationEntryList::getStateAtTime(double fTime
) const
260 if(!basegfx::fTools::equalZero(mfDuration
))
262 double fAddedTime(0.0);
263 const sal_uInt32
nIndex(impGetIndexAtTime(fTime
, fAddedTime
));
265 if(nIndex
< maEntries
.size())
267 return maEntries
[nIndex
]->getStateAtTime(fTime
- fAddedTime
);
274 double AnimationEntryList::getNextEventTime(double fTime
) const
276 double fNewTime(0.0);
278 if(!basegfx::fTools::equalZero(mfDuration
))
280 double fAddedTime(0.0);
281 const sal_uInt32
nIndex(impGetIndexAtTime(fTime
, fAddedTime
));
283 if(nIndex
< maEntries
.size())
285 fNewTime
= maEntries
[nIndex
]->getNextEventTime(fTime
- fAddedTime
) + fAddedTime
;
292 //////////////////////////////////////////////////////////////////////////////
294 AnimationEntryLoop::AnimationEntryLoop(sal_uInt32 nRepeat
)
295 : AnimationEntryList(),
300 AnimationEntryLoop::~AnimationEntryLoop()
304 AnimationEntry
* AnimationEntryLoop::clone() const
306 AnimationEntryLoop
* pNew
= new AnimationEntryLoop(mnRepeat
);
308 for(sal_uInt32
a(0L); a
< maEntries
.size(); a
++)
310 pNew
->append(*maEntries
[a
]);
316 bool AnimationEntryLoop::operator==(const AnimationEntry
& rCandidate
) const
318 const AnimationEntryLoop
* pCompare
= dynamic_cast< const AnimationEntryLoop
* >(&rCandidate
);
321 && mnRepeat
== pCompare
->mnRepeat
322 && AnimationEntryList::operator==(rCandidate
));
325 double AnimationEntryLoop::getDuration() const
327 return (mfDuration
* (double)mnRepeat
);
330 double AnimationEntryLoop::getStateAtTime(double fTime
) const
332 if(mnRepeat
&& !basegfx::fTools::equalZero(mfDuration
))
334 const sal_uInt32
nCurrentLoop((sal_uInt32
)(fTime
/ mfDuration
));
336 if(nCurrentLoop
> mnRepeat
)
342 const double fTimeAtLoopStart((double)nCurrentLoop
* mfDuration
);
343 const double fRelativeTime(fTime
- fTimeAtLoopStart
);
344 return AnimationEntryList::getStateAtTime(fRelativeTime
);
351 double AnimationEntryLoop::getNextEventTime(double fTime
) const
353 double fNewTime(0.0);
355 if(mnRepeat
&& !basegfx::fTools::equalZero(mfDuration
))
357 const sal_uInt32
nCurrentLoop((sal_uInt32
)(fTime
/ mfDuration
));
359 if(nCurrentLoop
<= mnRepeat
)
361 const double fTimeAtLoopStart((double)nCurrentLoop
* mfDuration
);
362 const double fRelativeTime(fTime
- fTimeAtLoopStart
);
363 const double fNextEventAtLoop(AnimationEntryList::getNextEventTime(fRelativeTime
));
365 if(!basegfx::fTools::equalZero(fNextEventAtLoop
))
367 fNewTime
= fNextEventAtLoop
+ fTimeAtLoopStart
;
374 } // end of namespace animation
375 } // end of namespace drawinglayer
377 //////////////////////////////////////////////////////////////////////////////