calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / drawinglayer / source / animation / animationtiming.cxx
blobc1471e43bd710da955ed1120b92b594d195e352c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <memory>
22 #include <drawinglayer/animation/animationtiming.hxx>
23 #include <basegfx/numeric/ftools.hxx>
25 namespace drawinglayer::animation
29 AnimationEntry::AnimationEntry()
33 AnimationEntry::~AnimationEntry()
38 AnimationEntryFixed::AnimationEntryFixed(double fDuration, double fState)
39 : mfDuration(fDuration),
40 mfState(fState)
44 AnimationEntryFixed::~AnimationEntryFixed()
48 std::unique_ptr<AnimationEntry> AnimationEntryFixed::clone() const
50 return std::make_unique<AnimationEntryFixed>(mfDuration, mfState);
53 bool AnimationEntryFixed::operator==(const AnimationEntry& rCandidate) const
55 const AnimationEntryFixed* pCompare = dynamic_cast< const AnimationEntryFixed* >(&rCandidate);
57 return (pCompare
58 && basegfx::fTools::equal(mfDuration, pCompare->mfDuration)
59 && basegfx::fTools::equal(mfState, pCompare->mfState));
62 double AnimationEntryFixed::getDuration() const
64 return mfDuration;
67 double AnimationEntryFixed::getStateAtTime(double /*fTime*/) const
69 return mfState;
72 double AnimationEntryFixed::getNextEventTime(double fTime) const
74 if(basegfx::fTools::less(fTime, mfDuration))
76 return mfDuration;
78 else
80 return 0.0;
85 AnimationEntryLinear::AnimationEntryLinear(double fDuration, double fFrequency, double fStart, double fStop)
86 : mfDuration(fDuration),
87 mfFrequency(fFrequency),
88 mfStart(fStart),
89 mfStop(fStop)
93 AnimationEntryLinear::~AnimationEntryLinear()
97 std::unique_ptr<AnimationEntry> AnimationEntryLinear::clone() const
99 return std::make_unique<AnimationEntryLinear>(mfDuration, mfFrequency, mfStart, mfStop);
102 bool AnimationEntryLinear::operator==(const AnimationEntry& rCandidate) const
104 const AnimationEntryLinear* pCompare = dynamic_cast< const AnimationEntryLinear* >(&rCandidate);
106 return (pCompare
107 && basegfx::fTools::equal(mfDuration, pCompare->mfDuration)
108 && basegfx::fTools::equal(mfStart, pCompare->mfStart)
109 && basegfx::fTools::equal(mfStop, pCompare->mfStop));
112 double AnimationEntryLinear::getDuration() const
114 return mfDuration;
117 double AnimationEntryLinear::getStateAtTime(double fTime) const
119 if(basegfx::fTools::more(mfDuration, 0.0))
121 const double fFactor(fTime / mfDuration);
123 if(fFactor > 1.0)
125 return mfStop;
127 else
129 return mfStart + ((mfStop - mfStart) * fFactor);
132 else
134 return mfStart;
138 double AnimationEntryLinear::getNextEventTime(double fTime) const
140 if(basegfx::fTools::less(fTime, mfDuration))
142 // use the simple solution: just add the frequency. More correct (but also more
143 // complicated) would be to calculate the slice of time we are in and when this
144 // slice will end. For the animations, this makes no quality difference.
145 fTime += mfFrequency;
147 if(basegfx::fTools::more(fTime, mfDuration))
149 fTime = mfDuration;
152 return fTime;
154 else
156 return 0.0;
161 AnimationEntryList::Entries::size_type AnimationEntryList::impGetIndexAtTime(double fTime, double &rfAddedTime) const
163 Entries::size_type nIndex(0);
165 while(nIndex < maEntries.size() && basegfx::fTools::lessOrEqual(rfAddedTime + maEntries[nIndex]->getDuration(), fTime))
167 rfAddedTime += maEntries[nIndex++]->getDuration();
170 return nIndex;
173 AnimationEntryList::AnimationEntryList()
174 : mfDuration(0.0)
178 AnimationEntryList::~AnimationEntryList()
182 std::unique_ptr<AnimationEntry> AnimationEntryList::clone() const
184 std::unique_ptr<AnimationEntryList> pNew(std::make_unique<AnimationEntryList>());
186 for(const auto &i : maEntries)
188 pNew->append(*i);
191 return pNew;
194 bool AnimationEntryList::operator==(const AnimationEntry& rCandidate) const
196 const AnimationEntryList* pCompare = dynamic_cast< const AnimationEntryList* >(&rCandidate);
198 if(pCompare && mfDuration == pCompare->mfDuration)
200 for(size_t a(0); a < maEntries.size(); a++)
202 if(!(*maEntries[a] == *pCompare->maEntries[a]))
204 return false;
208 return true;
211 return false;
214 void AnimationEntryList::append(const AnimationEntry& rCandidate)
216 const double fDuration(rCandidate.getDuration());
218 if(!basegfx::fTools::equalZero(fDuration))
220 maEntries.push_back(rCandidate.clone());
221 mfDuration += fDuration;
225 double AnimationEntryList::getDuration() const
227 return mfDuration;
230 double AnimationEntryList::getStateAtTime(double fTime) const
232 if(!basegfx::fTools::equalZero(mfDuration))
234 double fAddedTime(0.0);
235 const auto nIndex(impGetIndexAtTime(fTime, fAddedTime));
237 if(nIndex < maEntries.size())
239 return maEntries[nIndex]->getStateAtTime(fTime - fAddedTime);
243 return 0.0;
246 double AnimationEntryList::getNextEventTime(double fTime) const
248 double fNewTime(0.0);
250 if(!basegfx::fTools::equalZero(mfDuration))
252 double fAddedTime(0.0);
253 const auto nIndex(impGetIndexAtTime(fTime, fAddedTime));
255 if(nIndex < maEntries.size())
257 fNewTime = maEntries[nIndex]->getNextEventTime(fTime - fAddedTime) + fAddedTime;
261 return fNewTime;
265 AnimationEntryLoop::AnimationEntryLoop(sal_uInt32 nRepeat)
266 : mnRepeat(nRepeat)
270 AnimationEntryLoop::~AnimationEntryLoop()
274 std::unique_ptr<AnimationEntry> AnimationEntryLoop::clone() const
276 std::unique_ptr<AnimationEntryLoop> pNew(std::make_unique<AnimationEntryLoop>(mnRepeat));
278 for(const auto &i : maEntries)
280 pNew->append(*i);
283 return pNew;
286 bool AnimationEntryLoop::operator==(const AnimationEntry& rCandidate) const
288 const AnimationEntryLoop* pCompare = dynamic_cast< const AnimationEntryLoop* >(&rCandidate);
290 return (pCompare
291 && mnRepeat == pCompare->mnRepeat
292 && AnimationEntryList::operator==(rCandidate));
295 double AnimationEntryLoop::getDuration() const
297 return (mfDuration * static_cast<double>(mnRepeat));
300 double AnimationEntryLoop::getStateAtTime(double fTime) const
302 if(mnRepeat && !basegfx::fTools::equalZero(mfDuration))
304 const sal_uInt32 nCurrentLoop(static_cast<sal_uInt32>(fTime / mfDuration));
306 if(nCurrentLoop > mnRepeat)
308 return 1.0;
310 else
312 const double fTimeAtLoopStart(static_cast<double>(nCurrentLoop) * mfDuration);
313 const double fRelativeTime(fTime - fTimeAtLoopStart);
314 return AnimationEntryList::getStateAtTime(fRelativeTime);
318 return 0.0;
321 double AnimationEntryLoop::getNextEventTime(double fTime) const
323 double fNewTime(0.0);
325 if(mnRepeat && !basegfx::fTools::equalZero(mfDuration))
327 const sal_uInt32 nCurrentLoop(static_cast<sal_uInt32>(fTime / mfDuration));
329 if(nCurrentLoop <= mnRepeat)
331 const double fTimeAtLoopStart(static_cast<double>(nCurrentLoop) * mfDuration);
332 const double fRelativeTime(fTime - fTimeAtLoopStart);
333 const double fNextEventAtLoop(AnimationEntryList::getNextEventTime(fRelativeTime));
335 if(!basegfx::fTools::equalZero(fNextEventAtLoop))
337 fNewTime = fNextEventAtLoop + fTimeAtLoopStart;
342 return fNewTime;
344 } // end of namespace
346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */