1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <canvas/debug.hxx>
23 #include <tools/diagnose_ex.h>
24 #include <canvas/verbosetrace.hxx>
25 #include <canvas/canvastools.hxx>
27 #include <activitybase.hxx>
34 // TODO(P1): Elide some virtual function calls, by templifying this
37 ActivityBase::ActivityBase( const ActivityParameters
& rParms
) :
38 mpEndEvent( rParms
.mrEndEvent
),
39 mrEventQueue( rParms
.mrEventQueue
),
42 maRepeats( rParms
.mrRepeats
),
43 mnAccelerationFraction( rParms
.mnAccelerationFraction
),
44 mnDecelerationFraction( rParms
.mnDecelerationFraction
),
45 mbAutoReverse( rParms
.mbAutoReverse
),
46 mbFirstPerformCall( true ),
49 void ActivityBase::dispose()
56 mpEndEvent
->dispose();
61 mpAttributeLayer
.reset();
64 double ActivityBase::calcTimeLag() const
66 // TODO(Q1): implement different init process!
67 if (isActive() && mbFirstPerformCall
)
69 mbFirstPerformCall
= false;
71 // notify derived classes that we're
73 const_cast<ActivityBase
*>(this)->startAnimation();
78 bool ActivityBase::perform()
82 return false; // no, early exit.
84 OSL_ASSERT( ! mbFirstPerformCall
);
89 bool ActivityBase::isActive() const
94 void ActivityBase::setTargets( const AnimatableShapeSharedPtr
& rShape
,
95 const ShapeAttributeLayerSharedPtr
& rAttrLayer
)
97 ENSURE_OR_THROW( rShape
,
98 "ActivityBase::setTargets(): Invalid shape" );
99 ENSURE_OR_THROW( rAttrLayer
,
100 "ActivityBase::setTargets(): Invalid attribute layer" );
103 mpAttributeLayer
= rAttrLayer
;
106 void ActivityBase::endActivity()
108 // this is a regular activity end
111 // Activity is ending, queue event, then
113 mrEventQueue
.addEvent( mpEndEvent
);
115 // release references
119 void ActivityBase::dequeued()
122 // // ignored here, if we're still active. Discrete
123 // // activities are dequeued after every perform() call,
124 // // thus, the call is only significant when isActive() ==
130 void ActivityBase::end()
132 if (!isActive() || isDisposed())
134 // assure animation is started:
135 if (mbFirstPerformCall
) {
136 mbFirstPerformCall
= false;
137 // notify derived classes that we're starting now
138 this->startAnimation();
141 performEnd(); // calling private virtual
146 double ActivityBase::calcAcceleratedTime( double nT
) const
148 // Handle acceleration/deceleration
149 // ================================
151 // clamp nT to permissible [0,1] range
152 nT
= ::basegfx::clamp( nT
, 0.0, 1.0 );
154 // take acceleration/deceleration into account. if the sum
155 // of mnAccelerationFraction and mnDecelerationFraction
156 // exceeds 1.0, ignore both (that's according to SMIL spec)
157 if( (mnAccelerationFraction
> 0.0 ||
158 mnDecelerationFraction
> 0.0) &&
159 mnAccelerationFraction
+ mnDecelerationFraction
<= 1.0 )
162 // calc accelerated/decelerated time.
164 // We have three intervals:
167 // 3 [d,1] (with a and d being acceleration/deceleration
170 // The change rate during interval 1 is constantly
171 // increasing, reaching 1 at a. It then stays at 1,
172 // starting a linear decrease at d, ending with 0 at
173 // time 1. The integral of this function is the
174 // required new time nT'.
176 // As we arbitrarily assumed 1 as the upper value of
177 // the change rate, the integral must be normalized to
178 // reach nT'=1 at the end of the interval. This
179 // normalization constant is:
181 // c = 1 - 0.5a - 0.5d
183 // The integral itself then amounts to:
185 // 0.5 nT^2 / a + (nT-a) + (nT - 0.5 nT^2 / d)
187 // (where each of the three summands correspond to the
188 // three intervals above, and are applied only if nT
189 // has reached the corresponding interval)
191 // The graph of the change rate is a trapezoid:
194 // 1| /--------------\
198 // -----------------------------
202 const double nC( 1.0 - 0.5*mnAccelerationFraction
- 0.5*mnDecelerationFraction
);
204 // this variable accumulates the new time value
207 if( nT
< mnAccelerationFraction
)
209 nTPrime
+= 0.5*nT
*nT
/mnAccelerationFraction
; // partial first interval
213 nTPrime
+= 0.5*mnAccelerationFraction
; // full first interval
215 if( nT
<= 1.0-mnDecelerationFraction
)
217 nTPrime
+= nT
-mnAccelerationFraction
; // partial second interval
221 nTPrime
+= 1.0 - mnAccelerationFraction
- mnDecelerationFraction
; // full second interval
223 const double nTRelative( nT
- 1.0 + mnDecelerationFraction
);
225 nTPrime
+= nTRelative
- 0.5*nTRelative
*nTRelative
/ mnDecelerationFraction
;
229 // normalize, and assign to work variable
238 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */