1*464702f4SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*464702f4SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*464702f4SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*464702f4SAndrew Rist * distributed with this work for additional information 6*464702f4SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*464702f4SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*464702f4SAndrew Rist * "License"); you may not use this file except in compliance 9*464702f4SAndrew Rist * with the License. You may obtain a copy of the License at 10*464702f4SAndrew Rist * 11*464702f4SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*464702f4SAndrew Rist * 13*464702f4SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*464702f4SAndrew Rist * software distributed under the License is distributed on an 15*464702f4SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*464702f4SAndrew Rist * KIND, either express or implied. See the License for the 17*464702f4SAndrew Rist * specific language governing permissions and limitations 18*464702f4SAndrew Rist * under the License. 19*464702f4SAndrew Rist * 20*464702f4SAndrew Rist *************************************************************/ 21*464702f4SAndrew Rist 22*464702f4SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <drawinglayer/animation/animationtiming.hxx> 28cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx> 29cdf0e10cSrcweir 30cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 31cdf0e10cSrcweir 32cdf0e10cSrcweir namespace drawinglayer 33cdf0e10cSrcweir { 34cdf0e10cSrcweir namespace animation 35cdf0e10cSrcweir { 36cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 37cdf0e10cSrcweir AnimationEntry()38cdf0e10cSrcweir AnimationEntry::AnimationEntry() 39cdf0e10cSrcweir { 40cdf0e10cSrcweir } 41cdf0e10cSrcweir ~AnimationEntry()42cdf0e10cSrcweir AnimationEntry::~AnimationEntry() 43cdf0e10cSrcweir { 44cdf0e10cSrcweir } 45cdf0e10cSrcweir 46cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 47cdf0e10cSrcweir AnimationEntryFixed(double fDuration,double fState)48cdf0e10cSrcweir AnimationEntryFixed::AnimationEntryFixed(double fDuration, double fState) 49cdf0e10cSrcweir : mfDuration(fDuration), 50cdf0e10cSrcweir mfState(fState) 51cdf0e10cSrcweir { 52cdf0e10cSrcweir } 53cdf0e10cSrcweir ~AnimationEntryFixed()54cdf0e10cSrcweir AnimationEntryFixed::~AnimationEntryFixed() 55cdf0e10cSrcweir { 56cdf0e10cSrcweir } 57cdf0e10cSrcweir clone() const58cdf0e10cSrcweir AnimationEntry* AnimationEntryFixed::clone() const 59cdf0e10cSrcweir { 60cdf0e10cSrcweir return new AnimationEntryFixed(mfDuration, mfState); 61cdf0e10cSrcweir } 62cdf0e10cSrcweir operator ==(const AnimationEntry & rCandidate) const63cdf0e10cSrcweir bool AnimationEntryFixed::operator==(const AnimationEntry& rCandidate) const 64cdf0e10cSrcweir { 65cdf0e10cSrcweir const AnimationEntryFixed* pCompare = dynamic_cast< const AnimationEntryFixed* >(&rCandidate); 66cdf0e10cSrcweir 67cdf0e10cSrcweir return (pCompare 68cdf0e10cSrcweir && basegfx::fTools::equal(mfDuration, pCompare->mfDuration) 69cdf0e10cSrcweir && basegfx::fTools::equal(mfState, pCompare->mfState)); 70cdf0e10cSrcweir } 71cdf0e10cSrcweir getDuration() const72cdf0e10cSrcweir double AnimationEntryFixed::getDuration() const 73cdf0e10cSrcweir { 74cdf0e10cSrcweir return mfDuration; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir getStateAtTime(double) const77cdf0e10cSrcweir double AnimationEntryFixed::getStateAtTime(double /*fTime*/) const 78cdf0e10cSrcweir { 79cdf0e10cSrcweir return mfState; 80cdf0e10cSrcweir } 81cdf0e10cSrcweir getNextEventTime(double fTime) const82cdf0e10cSrcweir double AnimationEntryFixed::getNextEventTime(double fTime) const 83cdf0e10cSrcweir { 84cdf0e10cSrcweir if(basegfx::fTools::less(fTime, mfDuration)) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir return mfDuration; 87cdf0e10cSrcweir } 88cdf0e10cSrcweir else 89cdf0e10cSrcweir { 90cdf0e10cSrcweir return 0.0; 91cdf0e10cSrcweir } 92cdf0e10cSrcweir } 93cdf0e10cSrcweir 94cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 95cdf0e10cSrcweir AnimationEntryLinear(double fDuration,double fFrequency,double fStart,double fStop)96cdf0e10cSrcweir AnimationEntryLinear::AnimationEntryLinear(double fDuration, double fFrequency, double fStart, double fStop) 97cdf0e10cSrcweir : mfDuration(fDuration), 98cdf0e10cSrcweir mfFrequency(fFrequency), 99cdf0e10cSrcweir mfStart(fStart), 100cdf0e10cSrcweir mfStop(fStop) 101cdf0e10cSrcweir { 102cdf0e10cSrcweir } 103cdf0e10cSrcweir ~AnimationEntryLinear()104cdf0e10cSrcweir AnimationEntryLinear::~AnimationEntryLinear() 105cdf0e10cSrcweir { 106cdf0e10cSrcweir } 107cdf0e10cSrcweir clone() const108cdf0e10cSrcweir AnimationEntry* AnimationEntryLinear::clone() const 109cdf0e10cSrcweir { 110cdf0e10cSrcweir return new AnimationEntryLinear(mfDuration, mfFrequency, mfStart, mfStop); 111cdf0e10cSrcweir } 112cdf0e10cSrcweir operator ==(const AnimationEntry & rCandidate) const113cdf0e10cSrcweir bool AnimationEntryLinear::operator==(const AnimationEntry& rCandidate) const 114cdf0e10cSrcweir { 115cdf0e10cSrcweir const AnimationEntryLinear* pCompare = dynamic_cast< const AnimationEntryLinear* >(&rCandidate); 116cdf0e10cSrcweir 117cdf0e10cSrcweir return (pCompare 118cdf0e10cSrcweir && basegfx::fTools::equal(mfDuration, pCompare->mfDuration) 119cdf0e10cSrcweir && basegfx::fTools::equal(mfStart, pCompare->mfStart) 120cdf0e10cSrcweir && basegfx::fTools::equal(mfStop, pCompare->mfStop)); 121cdf0e10cSrcweir } 122cdf0e10cSrcweir getDuration() const123cdf0e10cSrcweir double AnimationEntryLinear::getDuration() const 124cdf0e10cSrcweir { 125cdf0e10cSrcweir return mfDuration; 126cdf0e10cSrcweir } 127cdf0e10cSrcweir getStateAtTime(double fTime) const128cdf0e10cSrcweir double AnimationEntryLinear::getStateAtTime(double fTime) const 129cdf0e10cSrcweir { 130cdf0e10cSrcweir if(basegfx::fTools::more(mfDuration, 0.0)) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir const double fFactor(fTime / mfDuration); 133cdf0e10cSrcweir 134cdf0e10cSrcweir if(fFactor > 1.0) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir return mfStop; 137cdf0e10cSrcweir } 138cdf0e10cSrcweir else 139cdf0e10cSrcweir { 140cdf0e10cSrcweir return mfStart + ((mfStop - mfStart) * fFactor); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir } 143cdf0e10cSrcweir else 144cdf0e10cSrcweir { 145cdf0e10cSrcweir return mfStart; 146cdf0e10cSrcweir } 147cdf0e10cSrcweir } 148cdf0e10cSrcweir getNextEventTime(double fTime) const149cdf0e10cSrcweir double AnimationEntryLinear::getNextEventTime(double fTime) const 150cdf0e10cSrcweir { 151cdf0e10cSrcweir if(basegfx::fTools::less(fTime, mfDuration)) 152cdf0e10cSrcweir { 153cdf0e10cSrcweir // use the simple solution: just add the frequency. More correct (but also more 154cdf0e10cSrcweir // complicated) would be to calculate the slice of time we are in and when this 155cdf0e10cSrcweir // slice will end. For the animations, this makes no quality difference. 156cdf0e10cSrcweir fTime += mfFrequency; 157cdf0e10cSrcweir 158cdf0e10cSrcweir if(basegfx::fTools::more(fTime, mfDuration)) 159cdf0e10cSrcweir { 160cdf0e10cSrcweir fTime = mfDuration; 161cdf0e10cSrcweir } 162cdf0e10cSrcweir 163cdf0e10cSrcweir return fTime; 164cdf0e10cSrcweir } 165cdf0e10cSrcweir else 166cdf0e10cSrcweir { 167cdf0e10cSrcweir return 0.0; 168cdf0e10cSrcweir } 169cdf0e10cSrcweir } 170cdf0e10cSrcweir 171cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 172cdf0e10cSrcweir impGetIndexAtTime(double fTime,double & rfAddedTime) const173cdf0e10cSrcweir sal_uInt32 AnimationEntryList::impGetIndexAtTime(double fTime, double &rfAddedTime) const 174cdf0e10cSrcweir { 175cdf0e10cSrcweir sal_uInt32 nIndex(0L); 176cdf0e10cSrcweir 177cdf0e10cSrcweir while(nIndex < maEntries.size() && basegfx::fTools::lessOrEqual(rfAddedTime + maEntries[nIndex]->getDuration(), fTime)) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir rfAddedTime += maEntries[nIndex++]->getDuration(); 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir return nIndex; 183cdf0e10cSrcweir } 184cdf0e10cSrcweir AnimationEntryList()185cdf0e10cSrcweir AnimationEntryList::AnimationEntryList() 186cdf0e10cSrcweir : mfDuration(0.0) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir } 189cdf0e10cSrcweir ~AnimationEntryList()190cdf0e10cSrcweir AnimationEntryList::~AnimationEntryList() 191cdf0e10cSrcweir { 192cdf0e10cSrcweir for(sal_uInt32 a(0L); a < maEntries.size(); a++) 193cdf0e10cSrcweir { 194cdf0e10cSrcweir delete maEntries[a]; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir } 197cdf0e10cSrcweir clone() const198cdf0e10cSrcweir AnimationEntry* AnimationEntryList::clone() const 199cdf0e10cSrcweir { 200cdf0e10cSrcweir AnimationEntryList* pNew = new AnimationEntryList(); 201cdf0e10cSrcweir 202cdf0e10cSrcweir for(sal_uInt32 a(0L); a < maEntries.size(); a++) 203cdf0e10cSrcweir { 204cdf0e10cSrcweir pNew->append(*maEntries[a]); 205cdf0e10cSrcweir } 206cdf0e10cSrcweir 207cdf0e10cSrcweir return pNew; 208cdf0e10cSrcweir } 209cdf0e10cSrcweir operator ==(const AnimationEntry & rCandidate) const210cdf0e10cSrcweir bool AnimationEntryList::operator==(const AnimationEntry& rCandidate) const 211cdf0e10cSrcweir { 212cdf0e10cSrcweir const AnimationEntryList* pCompare = dynamic_cast< const AnimationEntryList* >(&rCandidate); 213cdf0e10cSrcweir 214cdf0e10cSrcweir if(pCompare && mfDuration == pCompare->mfDuration) 215cdf0e10cSrcweir { 216cdf0e10cSrcweir for(sal_uInt32 a(0L); a < maEntries.size(); a++) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir if(!(*maEntries[a] == *pCompare->maEntries[a])) 219cdf0e10cSrcweir { 220cdf0e10cSrcweir return false; 221cdf0e10cSrcweir } 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir return true; 225cdf0e10cSrcweir } 226cdf0e10cSrcweir 227cdf0e10cSrcweir return false; 228cdf0e10cSrcweir } 229cdf0e10cSrcweir append(const AnimationEntry & rCandidate)230cdf0e10cSrcweir void AnimationEntryList::append(const AnimationEntry& rCandidate) 231cdf0e10cSrcweir { 232cdf0e10cSrcweir const double fDuration(rCandidate.getDuration()); 233cdf0e10cSrcweir 234cdf0e10cSrcweir if(!basegfx::fTools::equalZero(fDuration)) 235cdf0e10cSrcweir { 236cdf0e10cSrcweir maEntries.push_back(rCandidate.clone()); 237cdf0e10cSrcweir mfDuration += fDuration; 238cdf0e10cSrcweir } 239cdf0e10cSrcweir } 240cdf0e10cSrcweir getDuration() const241cdf0e10cSrcweir double AnimationEntryList::getDuration() const 242cdf0e10cSrcweir { 243cdf0e10cSrcweir return mfDuration; 244cdf0e10cSrcweir } 245cdf0e10cSrcweir getStateAtTime(double fTime) const246cdf0e10cSrcweir double AnimationEntryList::getStateAtTime(double fTime) const 247cdf0e10cSrcweir { 248cdf0e10cSrcweir if(!basegfx::fTools::equalZero(mfDuration)) 249cdf0e10cSrcweir { 250cdf0e10cSrcweir double fAddedTime(0.0); 251cdf0e10cSrcweir const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime)); 252cdf0e10cSrcweir 253cdf0e10cSrcweir if(nIndex < maEntries.size()) 254cdf0e10cSrcweir { 255cdf0e10cSrcweir return maEntries[nIndex]->getStateAtTime(fTime - fAddedTime); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir 259cdf0e10cSrcweir return 0.0; 260cdf0e10cSrcweir } 261cdf0e10cSrcweir getNextEventTime(double fTime) const262cdf0e10cSrcweir double AnimationEntryList::getNextEventTime(double fTime) const 263cdf0e10cSrcweir { 264cdf0e10cSrcweir double fNewTime(0.0); 265cdf0e10cSrcweir 266cdf0e10cSrcweir if(!basegfx::fTools::equalZero(mfDuration)) 267cdf0e10cSrcweir { 268cdf0e10cSrcweir double fAddedTime(0.0); 269cdf0e10cSrcweir const sal_uInt32 nIndex(impGetIndexAtTime(fTime, fAddedTime)); 270cdf0e10cSrcweir 271cdf0e10cSrcweir if(nIndex < maEntries.size()) 272cdf0e10cSrcweir { 273cdf0e10cSrcweir fNewTime = maEntries[nIndex]->getNextEventTime(fTime - fAddedTime) + fAddedTime; 274cdf0e10cSrcweir } 275cdf0e10cSrcweir } 276cdf0e10cSrcweir 277cdf0e10cSrcweir return fNewTime; 278cdf0e10cSrcweir } 279cdf0e10cSrcweir 280cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 281cdf0e10cSrcweir AnimationEntryLoop(sal_uInt32 nRepeat)282cdf0e10cSrcweir AnimationEntryLoop::AnimationEntryLoop(sal_uInt32 nRepeat) 283cdf0e10cSrcweir : AnimationEntryList(), 284cdf0e10cSrcweir mnRepeat(nRepeat) 285cdf0e10cSrcweir { 286cdf0e10cSrcweir } 287cdf0e10cSrcweir ~AnimationEntryLoop()288cdf0e10cSrcweir AnimationEntryLoop::~AnimationEntryLoop() 289cdf0e10cSrcweir { 290cdf0e10cSrcweir } 291cdf0e10cSrcweir clone() const292cdf0e10cSrcweir AnimationEntry* AnimationEntryLoop::clone() const 293cdf0e10cSrcweir { 294cdf0e10cSrcweir AnimationEntryLoop* pNew = new AnimationEntryLoop(mnRepeat); 295cdf0e10cSrcweir 296cdf0e10cSrcweir for(sal_uInt32 a(0L); a < maEntries.size(); a++) 297cdf0e10cSrcweir { 298cdf0e10cSrcweir pNew->append(*maEntries[a]); 299cdf0e10cSrcweir } 300cdf0e10cSrcweir 301cdf0e10cSrcweir return pNew; 302cdf0e10cSrcweir } 303cdf0e10cSrcweir operator ==(const AnimationEntry & rCandidate) const304cdf0e10cSrcweir bool AnimationEntryLoop::operator==(const AnimationEntry& rCandidate) const 305cdf0e10cSrcweir { 306cdf0e10cSrcweir const AnimationEntryLoop* pCompare = dynamic_cast< const AnimationEntryLoop* >(&rCandidate); 307cdf0e10cSrcweir 308cdf0e10cSrcweir return (pCompare 309cdf0e10cSrcweir && mnRepeat == pCompare->mnRepeat 310cdf0e10cSrcweir && AnimationEntryList::operator==(rCandidate)); 311cdf0e10cSrcweir } 312cdf0e10cSrcweir getDuration() const313cdf0e10cSrcweir double AnimationEntryLoop::getDuration() const 314cdf0e10cSrcweir { 315cdf0e10cSrcweir return (mfDuration * (double)mnRepeat); 316cdf0e10cSrcweir } 317cdf0e10cSrcweir getStateAtTime(double fTime) const318cdf0e10cSrcweir double AnimationEntryLoop::getStateAtTime(double fTime) const 319cdf0e10cSrcweir { 320cdf0e10cSrcweir if(mnRepeat && !basegfx::fTools::equalZero(mfDuration)) 321cdf0e10cSrcweir { 322cdf0e10cSrcweir const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration)); 323cdf0e10cSrcweir 324cdf0e10cSrcweir if(nCurrentLoop > mnRepeat) 325cdf0e10cSrcweir { 326cdf0e10cSrcweir return 1.0; 327cdf0e10cSrcweir } 328cdf0e10cSrcweir else 329cdf0e10cSrcweir { 330cdf0e10cSrcweir const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration); 331cdf0e10cSrcweir const double fRelativeTime(fTime - fTimeAtLoopStart); 332cdf0e10cSrcweir return AnimationEntryList::getStateAtTime(fRelativeTime); 333cdf0e10cSrcweir } 334cdf0e10cSrcweir } 335cdf0e10cSrcweir 336cdf0e10cSrcweir return 0.0; 337cdf0e10cSrcweir } 338cdf0e10cSrcweir getNextEventTime(double fTime) const339cdf0e10cSrcweir double AnimationEntryLoop::getNextEventTime(double fTime) const 340cdf0e10cSrcweir { 341cdf0e10cSrcweir double fNewTime(0.0); 342cdf0e10cSrcweir 343cdf0e10cSrcweir if(mnRepeat && !basegfx::fTools::equalZero(mfDuration)) 344cdf0e10cSrcweir { 345cdf0e10cSrcweir const sal_uInt32 nCurrentLoop((sal_uInt32)(fTime / mfDuration)); 346cdf0e10cSrcweir 347cdf0e10cSrcweir if(nCurrentLoop <= mnRepeat) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir const double fTimeAtLoopStart((double)nCurrentLoop * mfDuration); 350cdf0e10cSrcweir const double fRelativeTime(fTime - fTimeAtLoopStart); 351cdf0e10cSrcweir const double fNextEventAtLoop(AnimationEntryList::getNextEventTime(fRelativeTime)); 352cdf0e10cSrcweir 353cdf0e10cSrcweir if(!basegfx::fTools::equalZero(fNextEventAtLoop)) 354cdf0e10cSrcweir { 355cdf0e10cSrcweir fNewTime = fNextEventAtLoop + fTimeAtLoopStart; 356cdf0e10cSrcweir } 357cdf0e10cSrcweir } 358cdf0e10cSrcweir } 359cdf0e10cSrcweir 360cdf0e10cSrcweir return fNewTime; 361cdf0e10cSrcweir } 362cdf0e10cSrcweir } // end of namespace animation 363cdf0e10cSrcweir } // end of namespace drawinglayer 364cdf0e10cSrcweir 365cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 366cdf0e10cSrcweir // eof 367