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