/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: animationtiming.cxx,v $ * * $Revision: 1.6 $ * * last change: $Author: aw $ $Date: 2008-05-27 14:11:19 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_drawinglayer.hxx" #include #include ////////////////////////////////////////////////////////////////////////////// namespace drawinglayer { namespace animation { ////////////////////////////////////////////////////////////////////////////// AnimationEntry::AnimationEntry() { } AnimationEntry::~AnimationEntry() { } ////////////////////////////////////////////////////////////////////////////// AnimationEntryFixed::AnimationEntryFixed(double fDuration, double fState) : mfDuration(fDuration), mfState(fState) { } AnimationEntryFixed::~AnimationEntryFixed() { } AnimationEntry* AnimationEntryFixed::clone() const { return new AnimationEntryFixed(mfDuration, mfState); } bool AnimationEntryFixed::operator==(const AnimationEntry& rCandidate) const { const AnimationEntryFixed* pCompare = dynamic_cast< const AnimationEntryFixed* >(&rCandidate); return (pCompare && basegfx::fTools::equal(mfDuration, pCompare->mfDuration) && basegfx::fTools::equal(mfState, pCompare->mfState)); } double AnimationEntryFixed::getDuration() const { return mfDuration; } double AnimationEntryFixed::getStateAtTime(double /*fTime*/) const { return mfState; } double AnimationEntryFixed::getNextEventTime(double fTime) const { if(basegfx::fTools::less(fTime, mfDuration)) { return mfDuration; } else { return 0.0; } } ////////////////////////////////////////////////////////////////////////////// AnimationEntryLinear::AnimationEntryLinear(double fDuration, double fFrequency, double fStart, double fStop) : mfDuration(fDuration), mfFrequency(fFrequency), mfStart(fStart), mfStop(fStop) { } AnimationEntryLinear::~AnimationEntryLinear() { } AnimationEntry* AnimationEntryLinear::clone() const { return new AnimationEntryLinear(mfDuration, mfFrequency, mfStart, mfStop); } bool AnimationEntryLinear::operator==(const AnimationEntry& rCandidate) const { const AnimationEntryLinear* pCompare = dynamic_cast< const AnimationEntryLinear* >(&rCandidate); return (pCompare && basegfx::fTools::equal(mfDuration, pCompare->mfDuration) && basegfx::fTools::equal(mfStart, pCompare->mfStart) && basegfx::fTools::equal(mfStop, pCompare->mfStop)); } double AnimationEntryLinear::getDuration() const { return mfDuration; } double AnimationEntryLinear::getStateAtTime(double fTime) const { if(basegfx::fTools::more(mfDuration, 0.0)) { const double fFactor(fTime / mfDuration); if(fFactor > 1.0) { return mfStop; } else { return mfStart + ((mfStop - mfStart) * fFactor); } } else { return mfStart; } } double AnimationEntryLinear::getNextEventTime(double fTime) const { if(basegfx::fTools::less(fTime, mfDuration)) { // use the simple solution: just add the frequency. More correct (but also more // complicated) would be to calculate the slice of time we are in and when this // slice will end. For the animations, this makes no quality difference. fTime += mfFrequency; if(basegfx::fTools::more(fTime, mfDuration)) { fTime = mfDuration; } return fTime; } else { return 0.0; } } ////////////////////////////////////////////////////////////////////////////// sal_uInt32 AnimationEntryList::impGetIndexAtTime(double fTime, double &rfAddedTime) const { sal_uInt32 nIndex(0L); while(nIndex < maEntries.size() && basegfx::fTools::lessOrEqual(rfAddedTime + maEntries[nIndex]->getDuration(), fTime)) { rfAddedTime += maEntries[nIndex++]->getDuration(); } return nIndex; } AnimationEntryList::AnimationEntryList() : mfDuration(0.0) { } AnimationEntryList::~AnimationEntryList() { for(sal_uInt32 a(0L); a < maEntries.size(); a++) { delete maEntries[a]; } } AnimationEntry* AnimationEntryList::clone() const { AnimationEntryList* pNew = new AnimationEntryList(); for(sal_uInt32 a(0L); a < maEntries.size(); a++) { pNew->append(*maEntries[a]); } return pNew; } bool AnimationEntryList::operator==(const AnimationEntry& rCandidate) const { const AnimationEntryList* pCompare = dynamic_cast< const AnimationEntryList* >(&rCandidate); if(pCompare && mfDuration == pCompare->mfDuration) { for(sal_uInt32 a(0L); a < maEntries.size(); a++) { if(!(*maEntries[a] == *pCompare->maEntries[a])) { return false; } } return true; } return false; } void AnimationEntryList::append(const AnimationEntry& rCandidate) { const double fDuration(rCandidate.getDuration()); if(!basegfx::fTools::equalZero(fDuration)) { maEntries.push_back(rCandidate.clone()); mfDuration += fDuration; } } double AnimationEntryList::getDuration() const { return mfDuration; } double AnimationEntryList::getStateAtTime(double fTime) const { if(!basegfx::fTools::equalZero(mfDuration)) { double fAddedTime(0.0); const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime)); if(nIndex < maEntries.size()) { return maEntries[nIndex]->getStateAtTime(fTime - fAddedTime); } } return 0.0; } double AnimationEntryList::getNextEventTime(double fTime) const { double fNewTime(0.0); if(!basegfx::fTools::equalZero(mfDuration)) { double fAddedTime(0.0); const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime)); if(nIndex < maEntries.size()) { fNewTime = maEntries[nIndex]->getNextEventTime(fTime - fAddedTime) + fAddedTime; } } return fNewTime; } ////////////////////////////////////////////////////////////////////////////// AnimationEntryLoop::AnimationEntryLoop(sal_uInt32 nRepeat) : AnimationEntryList(), mnRepeat(nRepeat) { } AnimationEntryLoop::~AnimationEntryLoop() { } AnimationEntry* AnimationEntryLoop::clone() const { AnimationEntryLoop* pNew = new AnimationEntryLoop(mnRepeat); for(sal_uInt32 a(0L); a < maEntries.size(); a++) { pNew->append(*maEntries[a]); } return pNew; } bool AnimationEntryLoop::operator==(const AnimationEntry& rCandidate) const { const AnimationEntryLoop* pCompare = dynamic_cast< const AnimationEntryLoop* >(&rCandidate); return (pCompare && mnRepeat == pCompare->mnRepeat && AnimationEntryList::operator==(rCandidate)); } double AnimationEntryLoop::getDuration() const { return (mfDuration * (double)mnRepeat); } double AnimationEntryLoop::getStateAtTime(double fTime) const { if(mnRepeat && !basegfx::fTools::equalZero(mfDuration)) { const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration)); if(nCurrentLoop > mnRepeat) { return 1.0; } else { const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration); const double fRelativeTime(fTime - fTimeAtLoopStart); return AnimationEntryList::getStateAtTime(fRelativeTime); } } return 0.0; } double AnimationEntryLoop::getNextEventTime(double fTime) const { double fNewTime(0.0); if(mnRepeat && !basegfx::fTools::equalZero(mfDuration)) { const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration)); if(nCurrentLoop <= mnRepeat) { const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration); const double fRelativeTime(fTime - fTimeAtLoopStart); const double fNextEventAtLoop(AnimationEntryList::getNextEventTime(fRelativeTime)); if(!basegfx::fTools::equalZero(fNextEventAtLoop)) { fNewTime = fNextEventAtLoop + fTimeAtLoopStart; } } } return fNewTime; } } // end of namespace animation } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// // eof