LCOV - code coverage report
Current view: top level - slideshow/source/engine/activities - activitiesfactory.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 232 0.4 %
Date: 2014-11-03 Functions: 2 320 0.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : // must be first
      22             : #include <canvas/debug.hxx>
      23             : #include <tools/diagnose_ex.h>
      24             : #include <canvas/verbosetrace.hxx>
      25             : 
      26             : #include <com/sun/star/animations/AnimationCalcMode.hpp>
      27             : #include <comphelper/sequence.hxx>
      28             : 
      29             : #include "activitiesfactory.hxx"
      30             : #include "smilfunctionparser.hxx"
      31             : #include "accumulation.hxx"
      32             : #include "activityparameters.hxx"
      33             : #include "interpolation.hxx"
      34             : #include "tools.hxx"
      35             : #include "simplecontinuousactivitybase.hxx"
      36             : #include "discreteactivitybase.hxx"
      37             : #include "continuousactivitybase.hxx"
      38             : #include "continuouskeytimeactivitybase.hxx"
      39             : 
      40             : #include <boost/optional.hpp>
      41             : #include <boost/shared_ptr.hpp>
      42             : 
      43             : #include <cmath>
      44             : #include <vector>
      45             : #include <algorithm>
      46             : 
      47             : using namespace com::sun::star;
      48             : 
      49             : namespace slideshow {
      50             : namespace internal {
      51             : 
      52             : namespace {
      53             : 
      54             : /** Traits template, to take formula application only for ValueType = double
      55             :  */
      56             : template<typename ValueType> struct FormulaTraits
      57             : {
      58           0 :     static ValueType getPresentationValue(
      59             :         const ValueType& rVal, const ExpressionNodeSharedPtr& )
      60             :     {
      61           0 :         return rVal;
      62             :     }
      63             : };
      64             : 
      65             : /// Specialization for ValueType = double
      66             : template<> struct FormulaTraits<double>
      67             : {
      68           0 :     static double getPresentationValue(
      69             :         double const& rVal, ExpressionNodeSharedPtr const& rFormula )
      70             :     {
      71           0 :         return rFormula ? (*rFormula)(rVal) : rVal;
      72             :     }
      73             : };
      74             : 
      75             : // Various ActivityBase specializations for different animator types
      76             : // =================================================================
      77             : 
      78             : /** FromToBy handler
      79             : 
      80             :     Provides the Activity specializations for FromToBy
      81             :     animations (e.g. those without a values list).
      82             : 
      83             :     This template makes heavy use of SFINAE, only one of
      84             :     the perform*() methods will compile for each of the
      85             :     base classes.
      86             : 
      87             :     Note that we omit the virtual keyword on the perform()
      88             :     overrides on purpose; those that actually do override
      89             :     baseclass virtual methods inherit the property, and
      90             :     the others won't increase our vtable. What's more,
      91             :     having all perform() method in the vtable actually
      92             :     creates POIs for them, which breaks the whole SFINAE
      93             :     concept (IOW, this template won't compile any longer).
      94             : 
      95             :     @tpl BaseType
      96             :     Base class to use for this activity. Only
      97             :     ContinuousActivityBase and DiscreteActivityBase are
      98             :     supported here.
      99             : 
     100             :     @tpl AnimationType
     101             :     Type of the Animation to call.
     102             : */
     103             : template<class BaseType, typename AnimationType>
     104           0 : class FromToByActivity : public BaseType
     105             : {
     106             : public:
     107             :     typedef typename AnimationType::ValueType           ValueType;
     108             :     typedef boost::optional<ValueType>                  OptionalValueType;
     109             : 
     110             : private:
     111             :     // some compilers don't inline whose definition they haven't
     112             :     // seen before the call site...
     113           0 :     ValueType getPresentationValue( const ValueType& rVal ) const
     114             :     {
     115           0 :         return FormulaTraits<ValueType>::getPresentationValue( rVal, mpFormula);
     116             :     }
     117             : 
     118             : public:
     119             :     /** Create FromToByActivity.
     120             : 
     121             :         @param rFrom
     122             :         From this value, the animation starts
     123             : 
     124             :         @param rTo
     125             :         With this value, the animation ends
     126             : 
     127             :         @param rBy
     128             :         With this value, the animation increments the start value
     129             : 
     130             :         @param rParms
     131             :         Standard Activity parameter struct
     132             : 
     133             :         @param rAnim
     134             :         Shared ptr to AnimationType
     135             : 
     136             :         @param rInterpolator
     137             :         Interpolator object to be used for lerping between
     138             :         start and end value (need to be passed, since it
     139             :         might contain state, e.g. interpolation direction
     140             :         for HSL color space).
     141             : 
     142             :         @param bCumulative
     143             :         Whether repeated animations should cumulate the
     144             :         value, or start fresh each time.
     145             :     */
     146           0 :     FromToByActivity(
     147             :         const OptionalValueType&                      rFrom,
     148             :         const OptionalValueType&                      rTo,
     149             :         const OptionalValueType&                      rBy,
     150             :         const ActivityParameters&                     rParms,
     151             :         const ::boost::shared_ptr< AnimationType >&   rAnim,
     152             :         const Interpolator< ValueType >&              rInterpolator,
     153             :         bool                                          bCumulative )
     154             :         : BaseType( rParms ),
     155             :           maFrom( rFrom ),
     156             :           maTo( rTo ),
     157             :           maBy( rBy ),
     158             :           mpFormula( rParms.mpFormula ),
     159             :           maStartValue(),
     160             :           maEndValue(),
     161             :           maPreviousValue(),
     162             :           maStartInterpolationValue(),
     163             :           mnIteration( 0 ),
     164             :           mpAnim( rAnim ),
     165             :           maInterpolator( rInterpolator ),
     166             :           mbDynamicStartValue( false ),
     167           0 :           mbCumulative( bCumulative )
     168             :     {
     169           0 :         ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
     170             : 
     171           0 :         ENSURE_OR_THROW(
     172             :             rTo || rBy,
     173             :             "From and one of To or By, or To or By alone must be valid" );
     174           0 :     }
     175             : 
     176           0 :     virtual void startAnimation()
     177             :     {
     178           0 :         if (this->isDisposed() || !mpAnim)
     179           0 :             return;
     180           0 :         BaseType::startAnimation();
     181             : 
     182             :         // start animation
     183           0 :         mpAnim->start( BaseType::getShape(),
     184             :                        BaseType::getShapeAttributeLayer() );
     185             : 
     186             :         // setup start and end value. Determine animation
     187             :         // start value only when animation actually
     188             :         // started up (this order is part of the Animation
     189             :         // interface contract)
     190           0 :         const ValueType aAnimationStartValue( mpAnim->getUnderlyingValue() );
     191             : 
     192             :         // first of all, determine general type of
     193             :         // animation, by inspecting which of the FromToBy values
     194             :         // are actually valid.
     195             :         // See http://www.w3.org/TR/smil20/animation.html#AnimationNS-FromToBy
     196             :         // for a definition
     197           0 :         if( maFrom )
     198             :         {
     199             :             // From-to or From-by animation. According to
     200             :             // SMIL spec, the To value takes precedence
     201             :             // over the By value, if both are specified
     202           0 :             if( maTo )
     203             :             {
     204             :                 // From-To animation
     205           0 :                 maStartValue = *maFrom;
     206           0 :                 maEndValue = *maTo;
     207             :             }
     208           0 :             else if( maBy )
     209             :             {
     210             :                 // From-By animation
     211           0 :                 maStartValue = *maFrom;
     212           0 :                 maEndValue = maStartValue + *maBy;
     213             :             }
     214             :         }
     215             :         else
     216             :         {
     217           0 :             maStartValue = aAnimationStartValue;
     218           0 :             maStartInterpolationValue = maStartValue;
     219             : 
     220             :             // By or To animation. According to SMIL spec,
     221             :             // the To value takes precedence over the By
     222             :             // value, if both are specified
     223           0 :             if( maTo )
     224             :             {
     225             :                 // To animation
     226             : 
     227             :                 // According to the SMIL spec
     228             :                 // (http://www.w3.org/TR/smil20/animation.html#animationNS-ToAnimation),
     229             :                 // the to animation interpolates between
     230             :                 // the _running_ underlying value and the to value (as the end value)
     231           0 :                 mbDynamicStartValue = true;
     232           0 :                 maPreviousValue = maStartValue;
     233           0 :                 maEndValue = *maTo;
     234             :             }
     235           0 :             else if( maBy )
     236             :             {
     237             :                 // By animation
     238           0 :                 maStartValue = aAnimationStartValue;
     239           0 :                 maEndValue = maStartValue + *maBy;
     240             :             }
     241           0 :         }
     242             :     }
     243             : 
     244           0 :     virtual void endAnimation()
     245             :     {
     246             :         // end animation
     247           0 :         if (mpAnim)
     248           0 :             mpAnim->end();
     249           0 :     }
     250             : 
     251             :     /// perform override for ContinuousActivityBase
     252           0 :     void perform( double nModifiedTime, sal_uInt32 nRepeatCount ) const
     253             :     {
     254           0 :         if (this->isDisposed() || !mpAnim)
     255           0 :             return;
     256             : 
     257             :         // According to SMIL 3.0 spec 'to' animation if no other (lower priority)
     258             :         // animations are active or frozen then a simple interpolation is performed.
     259             :         // That is, the start interpolation value is constant while the animation
     260             :         // is running, and is equal to the underlying value retrieved when
     261             :         // the animation start.
     262             :         // However if another animation is manipulating the underlying value,
     263             :         // the 'to' animation will initially add to the effect of the lower priority
     264             :         // animation, and increasingly dominate it as it nears the end of the
     265             :         // simple duration, eventually overriding it completely.
     266             :         // That is, each time the underlying value is changed between two
     267             :         // computations of the animation function the new underlying value is used
     268             :         // as start value for the interpolation.
     269             :         // See:
     270             :         // http://www.w3.org/TR/SMIL3/smil-animation.html#animationNS-ToAnimation
     271             :         // (Figure 6 - Effect of Additive to animation example)
     272             :         // Moreover when a 'to' animation is repeated, at each new iteration
     273             :         // the start interpolation value is reset to the underlying value
     274             :         // of the animated property when the animation started,
     275             :         // as it is shown in the example provided by the SMIL 3.0 spec.
     276             :         // This is exactly as Firefox performs SVG 'to' animations.
     277           0 :         if( mbDynamicStartValue )
     278             :         {
     279           0 :             if( mnIteration != nRepeatCount )
     280             :             {
     281           0 :                 mnIteration = nRepeatCount;
     282           0 :                 maStartInterpolationValue = maStartValue;
     283             :             }
     284             :             else
     285             :             {
     286           0 :                 ValueType aActualValue = mpAnim->getUnderlyingValue();
     287           0 :                 if( aActualValue != maPreviousValue )
     288           0 :                     maStartInterpolationValue = aActualValue;
     289             :             }
     290             :         }
     291             : 
     292             :         ValueType aValue = maInterpolator( maStartInterpolationValue,
     293           0 :                                            maEndValue, nModifiedTime );
     294             : 
     295             :         // According to the SMIL spec:
     296             :         // Because 'to' animation is defined in terms of absolute values of
     297             :         // the target attribute, cumulative animation is not defined.
     298           0 :         if( mbCumulative && !mbDynamicStartValue )
     299             :         {
     300             :             // aValue = this.aEndValue * nRepeatCount + aValue;
     301           0 :             aValue = accumulate( maEndValue, nRepeatCount, aValue );
     302             :         }
     303             : 
     304           0 :         (*mpAnim)( getPresentationValue( aValue ) );
     305             : 
     306           0 :         if( mbDynamicStartValue )
     307             :         {
     308           0 :             maPreviousValue = mpAnim->getUnderlyingValue();
     309           0 :         }
     310             : 
     311             :     }
     312             : 
     313             :     using BaseType::perform;
     314             : 
     315             :     /// perform override for DiscreteActivityBase base
     316           0 :     void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
     317             :     {
     318           0 :         if (this->isDisposed() || !mpAnim)
     319           0 :             return;
     320           0 :         (*mpAnim)(
     321             :             getPresentationValue(
     322             :                 accumulate( maEndValue, mbCumulative ? nRepeatCount : 0,
     323             :                             lerp( maInterpolator,
     324             :                                   (mbDynamicStartValue
     325           0 :                                    ? mpAnim->getUnderlyingValue()
     326             :                                    : maStartValue),
     327             :                                   maEndValue,
     328             :                                   nFrame,
     329           0 :                                   BaseType::getNumberOfKeyTimes() ) ) ) );
     330             :     }
     331             : 
     332             :     using BaseType::isAutoReverse;
     333             : 
     334           0 :     virtual void performEnd()
     335             :     {
     336             :         // xxx todo: good guess
     337           0 :         if (mpAnim)
     338             :         {
     339           0 :             if (isAutoReverse())
     340           0 :                 (*mpAnim)( getPresentationValue( maStartValue ) );
     341             :             else
     342           0 :                 (*mpAnim)( getPresentationValue( maEndValue ) );
     343             :         }
     344           0 :     }
     345             : 
     346             :     /// Disposable:
     347           0 :     virtual void dispose()
     348             :     {
     349           0 :         mpAnim.reset();
     350           0 :         BaseType::dispose();
     351           0 :     }
     352             : 
     353             : private:
     354             :     const OptionalValueType                 maFrom;
     355             :     const OptionalValueType                 maTo;
     356             :     const OptionalValueType                 maBy;
     357             : 
     358             :     ExpressionNodeSharedPtr                 mpFormula;
     359             : 
     360             :     ValueType                               maStartValue;
     361             :     ValueType                               maEndValue;
     362             : 
     363             :     mutable ValueType                               maPreviousValue;
     364             :     mutable ValueType                               maStartInterpolationValue;
     365             :     mutable sal_uInt32                              mnIteration;
     366             : 
     367             :     ::boost::shared_ptr< AnimationType >    mpAnim;
     368             :     Interpolator< ValueType >               maInterpolator;
     369             :     bool                                    mbDynamicStartValue;
     370             :     bool                                    mbCumulative;
     371             : };
     372             : 
     373             : 
     374             : /** Generate Activity corresponding to given FromToBy values
     375             : 
     376             :     @tpl BaseType
     377             :     BaseType to use for deriving the Activity from
     378             : 
     379             :     @tpl AnimationType
     380             :     Subtype of the Animation object (e.g. NumberAnimation)
     381             : */
     382             : template<class BaseType, typename AnimationType>
     383           0 : AnimationActivitySharedPtr createFromToByActivity(
     384             :     const uno::Any&                                          rFromAny,
     385             :     const uno::Any&                                          rToAny,
     386             :     const uno::Any&                                          rByAny,
     387             :     const ActivityParameters&                                rParms,
     388             :     const ::boost::shared_ptr< AnimationType >&              rAnim,
     389             :     const Interpolator< typename AnimationType::ValueType >& rInterpolator,
     390             :     bool                                                     bCumulative,
     391             :     const ShapeSharedPtr&                                    rShape,
     392             :     const ::basegfx::B2DVector&                              rSlideBounds )
     393             : {
     394             :     typedef typename AnimationType::ValueType           ValueType;
     395             :     typedef boost::optional<ValueType>                  OptionalValueType;
     396             : 
     397           0 :     OptionalValueType aFrom;
     398           0 :     OptionalValueType aTo;
     399           0 :     OptionalValueType aBy;
     400             : 
     401           0 :     ValueType aTmpValue;
     402             : 
     403           0 :     if( rFromAny.hasValue() )
     404             :     {
     405           0 :         ENSURE_OR_THROW(
     406             :             extractValue( aTmpValue, rFromAny, rShape, rSlideBounds ),
     407             :             "createFromToByActivity(): Could not extract from value" );
     408           0 :         aFrom.reset(aTmpValue);
     409             :     }
     410           0 :     if( rToAny.hasValue() )
     411             :     {
     412           0 :         ENSURE_OR_THROW(
     413             :             extractValue( aTmpValue, rToAny, rShape, rSlideBounds ),
     414             :             "createFromToByActivity(): Could not extract to value" );
     415           0 :         aTo.reset(aTmpValue);
     416             :     }
     417           0 :     if( rByAny.hasValue() )
     418             :     {
     419           0 :         ENSURE_OR_THROW(
     420             :             extractValue( aTmpValue, rByAny, rShape, rSlideBounds ),
     421             :             "createFromToByActivity(): Could not extract by value" );
     422           0 :         aBy.reset(aTmpValue);
     423             :     }
     424             : 
     425             :     return AnimationActivitySharedPtr(
     426             :         new FromToByActivity<BaseType, AnimationType>(
     427             :             aFrom,
     428             :             aTo,
     429             :             aBy,
     430             :             rParms,
     431             :             rAnim,
     432             :             rInterpolator,
     433           0 :             bCumulative ) );
     434             : }
     435             : 
     436             : /* The following table shows which animator combines with
     437             :    which Activity type:
     438             : 
     439             :    NumberAnimator:  all
     440             :    PairAnimation:   all
     441             :    ColorAnimation:  all
     442             :    StringAnimation: DiscreteActivityBase
     443             :    BoolAnimation:   DiscreteActivityBase
     444             : */
     445             : 
     446             : /** Values handler
     447             : 
     448             :     Provides the Activity specializations for value lists
     449             :     animations.
     450             : 
     451             :     This template makes heavy use of SFINAE, only one of
     452             :     the perform*() methods will compile for each of the
     453             :     base classes.
     454             : 
     455             :     Note that we omit the virtual keyword on the perform()
     456             :     overrides on purpose; those that actually do override
     457             :     baseclass virtual methods inherit the property, and
     458             :     the others won't increase our vtable. What's more,
     459             :     having all perform() method in the vtable actually
     460             :     creates POIs for them, which breaks the whole SFINAE
     461             :     concept (IOW, this template won't compile any longer).
     462             : 
     463             :     @tpl BaseType
     464             :     Base class to use for this activity. Only
     465             :     ContinuousKeyTimeActivityBase and DiscreteActivityBase
     466             :     are supported here. For values animation without key
     467             :     times, the client must emulate key times by providing
     468             :     a vector of equally spaced values between 0 and 1,
     469             :     with the same number of entries as the values vector.
     470             : 
     471             :     @tpl AnimationType
     472             :     Type of the Animation to call.
     473             : */
     474             : template<class BaseType, typename AnimationType>
     475           0 : class ValuesActivity : public BaseType
     476             : {
     477             : public:
     478             :     typedef typename AnimationType::ValueType   ValueType;
     479             :     typedef std::vector<ValueType>              ValueVectorType;
     480             : 
     481             : private:
     482             :     // some compilers don't inline methods whose definition they haven't
     483             :     // seen before the call site...
     484           0 :     ValueType getPresentationValue( const ValueType& rVal ) const
     485             :     {
     486             :         return FormulaTraits<ValueType>::getPresentationValue(
     487           0 :             rVal, mpFormula );
     488             :     }
     489             : 
     490             : public:
     491             :     /** Create ValuesActivity.
     492             : 
     493             :         @param rValues
     494             :         Value vector to cycle animation through
     495             : 
     496             :         @param rParms
     497             :         Standard Activity parameter struct
     498             : 
     499             :         @param rAnim
     500             :         Shared ptr to AnimationType
     501             : 
     502             :         @param rInterpolator
     503             :         Interpolator object to be used for lerping between
     504             :         start and end value (need to be passed, since it
     505             :         might contain state, e.g. interpolation direction
     506             :         for HSL color space).
     507             : 
     508             :         @param bCumulative
     509             :         Whether repeated animations should cumulate the
     510             :         value, or start afresh each time.
     511             :     */
     512           0 :     ValuesActivity(
     513             :         const ValueVectorType&                      rValues,
     514             :         const ActivityParameters&                   rParms,
     515             :         const boost::shared_ptr<AnimationType>&     rAnim,
     516             :         const Interpolator< ValueType >&            rInterpolator,
     517             :         bool                                        bCumulative )
     518             :         : BaseType( rParms ),
     519             :           maValues( rValues ),
     520             :           mpFormula( rParms.mpFormula ),
     521             :           mpAnim( rAnim ),
     522             :           maInterpolator( rInterpolator ),
     523           0 :           mbCumulative( bCumulative )
     524             :     {
     525           0 :         ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
     526           0 :         ENSURE_OR_THROW( !rValues.empty(), "Empty value vector" );
     527           0 :     }
     528             : 
     529           0 :     virtual void startAnimation()
     530             :     {
     531           0 :         if (this->isDisposed() || !mpAnim)
     532           0 :             return;
     533           0 :         BaseType::startAnimation();
     534             : 
     535             :         // start animation
     536           0 :         mpAnim->start( BaseType::getShape(),
     537             :                        BaseType::getShapeAttributeLayer() );
     538             :     }
     539             : 
     540           0 :     virtual void endAnimation()
     541             :     {
     542             :         // end animation
     543           0 :         if (mpAnim)
     544           0 :             mpAnim->end();
     545           0 :     }
     546             : 
     547             :     /// perform override for ContinuousKeyTimeActivityBase base
     548           0 :     void perform( sal_uInt32    nIndex,
     549             :                   double        nFractionalIndex,
     550             :                   sal_uInt32    nRepeatCount ) const
     551             :     {
     552           0 :         if (this->isDisposed() || !mpAnim)
     553           0 :             return;
     554           0 :         ENSURE_OR_THROW( nIndex+1 < maValues.size(),
     555             :                           "ValuesActivity::perform(): index out of range" );
     556             : 
     557             :         // interpolate between nIndex and nIndex+1 values
     558           0 :         (*mpAnim)(
     559             :             getPresentationValue(
     560             :                 accumulate<ValueType>( maValues.back(),
     561             :                             mbCumulative ? nRepeatCount : 0,
     562           0 :                             maInterpolator( maValues[ nIndex ],
     563           0 :                                             maValues[ nIndex+1 ],
     564           0 :                                             nFractionalIndex ) ) ) );
     565             :     }
     566             : 
     567             :     using BaseType::perform;
     568             : 
     569             :     /// perform override for DiscreteActivityBase base
     570           0 :     void perform( sal_uInt32 nFrame, sal_uInt32 nRepeatCount ) const
     571             :     {
     572           0 :         if (this->isDisposed() || !mpAnim)
     573           0 :             return;
     574           0 :         ENSURE_OR_THROW( nFrame < maValues.size(),
     575             :                           "ValuesActivity::perform(): index out of range" );
     576             : 
     577             :         // this is discrete, thus no lerp here.
     578           0 :         (*mpAnim)(
     579             :             getPresentationValue(
     580             :                 accumulate<ValueType>( maValues.back(),
     581             :                             mbCumulative ? nRepeatCount : 0,
     582           0 :                             maValues[ nFrame ] ) ) );
     583             :     }
     584             : 
     585           0 :     virtual void performEnd()
     586             :     {
     587             :         // xxx todo: good guess
     588           0 :         if (mpAnim)
     589           0 :             (*mpAnim)( getPresentationValue( maValues.back() ) );
     590           0 :     }
     591             : 
     592             :     /// Disposable:
     593           0 :     virtual void dispose()
     594             :     {
     595           0 :         mpAnim.reset();
     596           0 :         BaseType::dispose();
     597           0 :     }
     598             : 
     599             : private:
     600             :     ValueVectorType                         maValues;
     601             : 
     602             :     ExpressionNodeSharedPtr                 mpFormula;
     603             : 
     604             :     boost::shared_ptr<AnimationType>        mpAnim;
     605             :     Interpolator< ValueType >               maInterpolator;
     606             :     bool                                    mbCumulative;
     607             : };
     608             : 
     609             : /** Generate Activity corresponding to given Value vector
     610             : 
     611             :     @tpl BaseType
     612             :     BaseType to use for deriving the Activity from
     613             : 
     614             :     @tpl AnimationType
     615             :     Subtype of the Animation object (e.g. NumberAnimation)
     616             : */
     617             : template<class BaseType, typename AnimationType>
     618           0 : AnimationActivitySharedPtr createValueListActivity(
     619             :     const uno::Sequence<uno::Any>&                            rValues,
     620             :     const ActivityParameters&                                 rParms,
     621             :     const boost::shared_ptr<AnimationType>&                   rAnim,
     622             :     const Interpolator<typename AnimationType::ValueType>&    rInterpolator,
     623             :     bool                                                      bCumulative,
     624             :     const ShapeSharedPtr&                                     rShape,
     625             :     const ::basegfx::B2DVector&                               rSlideBounds )
     626             : {
     627             :     typedef typename AnimationType::ValueType   ValueType;
     628             :     typedef std::vector<ValueType>              ValueVectorType;
     629             : 
     630           0 :     ValueVectorType aValueVector;
     631           0 :     aValueVector.reserve( rValues.getLength() );
     632             : 
     633           0 :     for( ::std::size_t i=0, nLen=rValues.getLength(); i<nLen; ++i )
     634             :     {
     635           0 :         ValueType aValue;
     636           0 :         ENSURE_OR_THROW(
     637             :             extractValue( aValue, rValues[i], rShape, rSlideBounds ),
     638             :             "createValueListActivity(): Could not extract values" );
     639           0 :         aValueVector.push_back( aValue );
     640             :     }
     641             : 
     642             :     return AnimationActivitySharedPtr(
     643             :         new ValuesActivity<BaseType, AnimationType>(
     644             :             aValueVector,
     645             :             rParms,
     646             :             rAnim,
     647             :             rInterpolator,
     648           0 :             bCumulative ) );
     649             : }
     650             : 
     651             : /** Generate Activity for given XAnimate, corresponding to given Value vector
     652             : 
     653             :     @tpl AnimationType
     654             :     Subtype of the Animation object (e.g. NumberAnimation)
     655             : 
     656             :     @param rParms
     657             :     Common activity parameters
     658             : 
     659             :     @param xNode
     660             :     XAnimate node, to retrieve animation values from
     661             : 
     662             :     @param rAnim
     663             :     Actual animation to operate with (gets called with the
     664             :     time-dependent values)
     665             : 
     666             :     @param rInterpolator
     667             :     Interpolator object to be used for lerping between
     668             :     start and end values (need to be passed, since it
     669             :     might contain state, e.g. interpolation direction
     670             :     for HSL color space).
     671             : */
     672             : template<typename AnimationType>
     673           0 : AnimationActivitySharedPtr createActivity(
     674             :     const ActivitiesFactory::CommonParameters&               rParms,
     675             :     const uno::Reference< animations::XAnimate >&            xNode,
     676             :     const ::boost::shared_ptr< AnimationType >&              rAnim,
     677             :     const Interpolator< typename AnimationType::ValueType >& rInterpolator
     678             :     = Interpolator< typename AnimationType::ValueType >() )
     679             : {
     680             :     // setup common parameters
     681             :     // =======================
     682             : 
     683             :     ActivityParameters aActivityParms( rParms.mpEndEvent,
     684             :                                        rParms.mrEventQueue,
     685             :                                        rParms.mrActivitiesQueue,
     686             :                                        rParms.mnMinDuration,
     687             :                                        rParms.maRepeats,
     688             :                                        rParms.mnAcceleration,
     689             :                                        rParms.mnDeceleration,
     690             :                                        rParms.mnMinNumberOfFrames,
     691           0 :                                        rParms.mbAutoReverse );
     692             : 
     693             :     // is a formula given?
     694           0 :     const OUString& rFormulaString( xNode->getFormula() );
     695           0 :     if( !rFormulaString.isEmpty() )
     696             :     {
     697             :         // yep, parse and pass to ActivityParameters
     698             :         try
     699             :         {
     700           0 :             aActivityParms.mpFormula =
     701             :                 SmilFunctionParser::parseSmilFunction(
     702             :                     rFormulaString,
     703             :                     calcRelativeShapeBounds(
     704             :                         rParms.maSlideBounds,
     705           0 :                         rParms.mpShape->getBounds() ) );
     706             :         }
     707           0 :         catch( ParseError& )
     708             :         {
     709             :             // parse error, thus no formula
     710             :             OSL_FAIL( "createActivity(): Error parsing formula string" );
     711             :         }
     712             :     }
     713             : 
     714             :     // are key times given?
     715           0 :     const uno::Sequence< double >& aKeyTimes( xNode->getKeyTimes() );
     716           0 :     if( aKeyTimes.hasElements() )
     717             :     {
     718             :         // yes, convert them from Sequence< double >
     719           0 :         aActivityParms.maDiscreteTimes.resize( aKeyTimes.getLength() );
     720           0 :         comphelper::sequenceToArray(
     721             :             &aActivityParms.maDiscreteTimes[0],
     722           0 :             aKeyTimes ); // saves us some temporary vectors
     723             :     }
     724             : 
     725             :     // values sequence given?
     726           0 :     const sal_Int32 nValueLen( xNode->getValues().getLength() );
     727           0 :     if( nValueLen )
     728             :     {
     729             :         // Value list activity
     730             :         // ===================
     731             : 
     732             :         // fake keytimes, if necessary
     733           0 :         if( !aKeyTimes.hasElements() )
     734             :         {
     735             :             // create a dummy vector of key times,
     736             :             // with aValues.getLength equally spaced entries.
     737           0 :             for( sal_Int32 i=0; i<nValueLen; ++i )
     738           0 :                 aActivityParms.maDiscreteTimes.push_back( double(i)/nValueLen );
     739             :         }
     740             : 
     741             :         // determine type of animation needed here:
     742             :         // Value list activities are possible with
     743             :         // ContinuousKeyTimeActivityBase and DiscreteActivityBase
     744             :         // specializations
     745           0 :         const sal_Int16 nCalcMode( xNode->getCalcMode() );
     746             : 
     747           0 :         switch( nCalcMode )
     748             :         {
     749             :             case animations::AnimationCalcMode::DISCRETE:
     750             :             {
     751             :                 // since DiscreteActivityBase suspends itself
     752             :                 // between the frames, create a WakeupEvent for it.
     753           0 :                 aActivityParms.mpWakeupEvent.reset(
     754             :                     new WakeupEvent(
     755           0 :                         rParms.mrEventQueue.getTimer(),
     756           0 :                         rParms.mrActivitiesQueue ) );
     757             : 
     758             :                 AnimationActivitySharedPtr pActivity(
     759             :                     createValueListActivity< DiscreteActivityBase >(
     760           0 :                         xNode->getValues(),
     761             :                         aActivityParms,
     762             :                         rAnim,
     763             :                         rInterpolator,
     764           0 :                         xNode->getAccumulate(),
     765             :                         rParms.mpShape,
     766           0 :                         rParms.maSlideBounds ) );
     767             : 
     768             :                 // WakeupEvent and DiscreteActivityBase need circular
     769             :                 // references to the corresponding other object.
     770           0 :                 aActivityParms.mpWakeupEvent->setActivity( pActivity );
     771             : 
     772           0 :                 return pActivity;
     773             :             }
     774             : 
     775             :             default:
     776             :                 OSL_FAIL( "createActivity(): unexpected case" );
     777             :                 // FALLTHROUGH intended
     778             :             case animations::AnimationCalcMode::PACED:
     779             :                 // FALLTHROUGH intended
     780             :             case animations::AnimationCalcMode::SPLINE:
     781             :                 // FALLTHROUGH intended
     782             :             case animations::AnimationCalcMode::LINEAR:
     783             :                 return createValueListActivity< ContinuousKeyTimeActivityBase >(
     784           0 :                     xNode->getValues(),
     785             :                     aActivityParms,
     786             :                     rAnim,
     787             :                     rInterpolator,
     788           0 :                     xNode->getAccumulate(),
     789             :                     rParms.mpShape,
     790           0 :                     rParms.maSlideBounds );
     791             :         }
     792             :     }
     793             :     else
     794             :     {
     795             :         // FromToBy activity
     796             :         // =================
     797             : 
     798             :         // determine type of animation needed here:
     799             :         // FromToBy activities are possible with
     800             :         // ContinuousActivityBase and DiscreteActivityBase
     801             :         // specializations
     802           0 :         const sal_Int16 nCalcMode( xNode->getCalcMode() );
     803             : 
     804           0 :         switch( nCalcMode )
     805             :         {
     806             :             case animations::AnimationCalcMode::DISCRETE:
     807             :             {
     808             :                 // fake keytimes, if necessary
     809           0 :                 if( !aKeyTimes.hasElements() )
     810             :                 {
     811             :                     // create a dummy vector of 2 key times
     812           0 :                     const ::std::size_t nLen( 2 );
     813           0 :                     for( ::std::size_t i=0; i<nLen; ++i )
     814           0 :                         aActivityParms.maDiscreteTimes.push_back( double(i)/nLen );
     815             :                 }
     816             : 
     817             :                 // since DiscreteActivityBase suspends itself
     818             :                 // between the frames, create a WakeupEvent for it.
     819           0 :                 aActivityParms.mpWakeupEvent.reset(
     820             :                     new WakeupEvent(
     821           0 :                         rParms.mrEventQueue.getTimer(),
     822           0 :                         rParms.mrActivitiesQueue ) );
     823             : 
     824             :                 AnimationActivitySharedPtr pActivity(
     825             :                     createFromToByActivity< DiscreteActivityBase >(
     826           0 :                         xNode->getFrom(),
     827           0 :                         xNode->getTo(),
     828           0 :                         xNode->getBy(),
     829             :                         aActivityParms,
     830             :                         rAnim,
     831             :                         rInterpolator,
     832           0 :                         xNode->getAccumulate(),
     833             :                         rParms.mpShape,
     834           0 :                         rParms.maSlideBounds ) );
     835             : 
     836             :                 // WakeupEvent and DiscreteActivityBase need circular
     837             :                 // references to the corresponding other object.
     838           0 :                 aActivityParms.mpWakeupEvent->setActivity( pActivity );
     839             : 
     840           0 :                 return pActivity;
     841             :             }
     842             : 
     843             :             default:
     844             :                 OSL_FAIL( "createActivity(): unexpected case" );
     845             :                 // FALLTHROUGH intended
     846             :             case animations::AnimationCalcMode::PACED:
     847             :                 // FALLTHROUGH intended
     848             :             case animations::AnimationCalcMode::SPLINE:
     849             :                 // FALLTHROUGH intended
     850             :             case animations::AnimationCalcMode::LINEAR:
     851             :                 return createFromToByActivity< ContinuousActivityBase >(
     852           0 :                     xNode->getFrom(),
     853           0 :                     xNode->getTo(),
     854           0 :                     xNode->getBy(),
     855             :                     aActivityParms,
     856             :                     rAnim,
     857             :                     rInterpolator,
     858           0 :                     xNode->getAccumulate(),
     859             :                     rParms.mpShape,
     860           0 :                     rParms.maSlideBounds );
     861             :         }
     862           0 :     }
     863             : }
     864             : 
     865             : /** Simple activity for ActivitiesFactory::createSimpleActivity
     866             : 
     867             :     @tpl Direction
     868             :     Determines direction of value generator. A 1 yields a
     869             :     forward direction, starting with 0.0 and ending with
     870             :     1.0. A 0 yields a backward direction, starting with
     871             :     1.0 and ending with 0.0
     872             : */
     873             : template<int Direction>
     874           0 : class SimpleActivity : public ContinuousActivityBase
     875             : {
     876             : public:
     877             :     /** Create SimpleActivity.
     878             : 
     879             :         @param rParms
     880             :         Standard Activity parameter struct
     881             :     */
     882           0 :     SimpleActivity( const ActivityParameters&       rParms,
     883             :                     const NumberAnimationSharedPtr& rAnim ) :
     884             :         ContinuousActivityBase( rParms ),
     885           0 :         mpAnim( rAnim )
     886             :     {
     887           0 :         ENSURE_OR_THROW( mpAnim, "Invalid animation object" );
     888           0 :     }
     889             : 
     890           0 :     virtual void startAnimation() SAL_OVERRIDE
     891             :     {
     892           0 :         if (this->isDisposed() || !mpAnim)
     893           0 :             return;
     894           0 :         ContinuousActivityBase::startAnimation();
     895             : 
     896             :         // start animation
     897           0 :         mpAnim->start( getShape(),
     898             :                        getShapeAttributeLayer() );
     899             :     }
     900             : 
     901           0 :     virtual void endAnimation() SAL_OVERRIDE
     902             :     {
     903             :         // end animation
     904           0 :         if (mpAnim)
     905           0 :             mpAnim->end();
     906           0 :     }
     907             : 
     908             :     using SimpleContinuousActivityBase::perform;
     909             : 
     910             :     /// perform override for ContinuousActivityBase
     911           0 :     virtual void perform( double nModifiedTime, sal_uInt32 ) const SAL_OVERRIDE
     912             :     {
     913           0 :         if (this->isDisposed() || !mpAnim)
     914           0 :             return;
     915             :         // no cumulation, simple [0,1] range
     916           0 :         (*mpAnim)( 1.0 - Direction + nModifiedTime*(2.0*Direction - 1.0) );
     917             :     }
     918             : 
     919           0 :     virtual void performEnd() SAL_OVERRIDE
     920             :     {
     921             :         // xxx todo: review
     922           0 :         if (mpAnim)
     923           0 :             (*mpAnim)( 1.0*Direction );
     924           0 :     }
     925             : 
     926             :     /// Disposable:
     927           0 :     virtual void dispose() SAL_OVERRIDE
     928             :     {
     929           0 :         mpAnim.reset();
     930           0 :         ContinuousActivityBase::dispose();
     931           0 :     }
     932             : 
     933             : private:
     934             :     NumberAnimationSharedPtr    mpAnim;
     935             : };
     936             : 
     937             : } // anon namespace
     938             : 
     939             : 
     940           0 : AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
     941             :     const CommonParameters&                        rParms,
     942             :     const NumberAnimationSharedPtr&                rAnim,
     943             :     const uno::Reference< animations::XAnimate >&  xNode )
     944             : {
     945             :     // forward to appropriate template instantiation
     946           0 :     return createActivity( rParms, xNode, rAnim );
     947             : }
     948             : 
     949           0 : AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
     950             :     const CommonParameters&                        rParms,
     951             :     const EnumAnimationSharedPtr&                  rAnim,
     952             :     const uno::Reference< animations::XAnimate >&  xNode )
     953             : {
     954             :     // forward to appropriate template instantiation
     955           0 :     return createActivity( rParms, xNode, rAnim );
     956             : }
     957             : 
     958           0 : AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
     959             :     const CommonParameters&                        rParms,
     960             :     const ColorAnimationSharedPtr&                 rAnim,
     961             :     const uno::Reference< animations::XAnimate >&  xNode )
     962             : {
     963             :     // forward to appropriate template instantiation
     964           0 :     return createActivity( rParms, xNode, rAnim );
     965             : }
     966             : 
     967           0 : AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
     968             :     const CommonParameters&                            rParms,
     969             :     const HSLColorAnimationSharedPtr&                  rAnim,
     970             :     const uno::Reference< animations::XAnimateColor >& xNode )
     971             : {
     972             :     // forward to appropriate template instantiation
     973             :     return createActivity( rParms,
     974             :                            uno::Reference< animations::XAnimate >(
     975             :                                xNode, uno::UNO_QUERY_THROW ),
     976             :                            rAnim,
     977             :                            // Direction==true means clockwise in SMIL API
     978           0 :                            Interpolator< HSLColor >( !xNode->getDirection() ) );
     979             : }
     980             : 
     981           0 : AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
     982             :     const CommonParameters&                        rParms,
     983             :     const PairAnimationSharedPtr&                  rAnim,
     984             :     const uno::Reference< animations::XAnimate >&  xNode )
     985             : {
     986             :     // forward to appropriate template instantiation
     987           0 :     return createActivity( rParms, xNode, rAnim );
     988             : }
     989             : 
     990           0 : AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
     991             :     const CommonParameters&                        rParms,
     992             :     const StringAnimationSharedPtr&                rAnim,
     993             :     const uno::Reference< animations::XAnimate >&  xNode )
     994             : {
     995             :     // forward to appropriate template instantiation
     996           0 :     return createActivity( rParms, xNode, rAnim );
     997             : }
     998             : 
     999           0 : AnimationActivitySharedPtr ActivitiesFactory::createAnimateActivity(
    1000             :     const CommonParameters&                        rParms,
    1001             :     const BoolAnimationSharedPtr&                  rAnim,
    1002             :     const uno::Reference< animations::XAnimate >&  xNode )
    1003             : {
    1004             :     // forward to appropriate template instantiation
    1005           0 :     return createActivity( rParms, xNode, rAnim );
    1006             : }
    1007             : 
    1008           0 : AnimationActivitySharedPtr ActivitiesFactory::createSimpleActivity(
    1009             :     const CommonParameters&         rParms,
    1010             :     const NumberAnimationSharedPtr& rAnim,
    1011             :     bool                            bDirectionForward )
    1012             : {
    1013             :     ActivityParameters aActivityParms( rParms.mpEndEvent,
    1014             :                                        rParms.mrEventQueue,
    1015             :                                        rParms.mrActivitiesQueue,
    1016             :                                        rParms.mnMinDuration,
    1017             :                                        rParms.maRepeats,
    1018             :                                        rParms.mnAcceleration,
    1019             :                                        rParms.mnDeceleration,
    1020             :                                        rParms.mnMinNumberOfFrames,
    1021           0 :                                        rParms.mbAutoReverse );
    1022             : 
    1023           0 :     if( bDirectionForward )
    1024             :         return AnimationActivitySharedPtr(
    1025           0 :             new SimpleActivity<1>( aActivityParms, rAnim ) );
    1026             :     else
    1027             :         return AnimationActivitySharedPtr(
    1028           0 :             new SimpleActivity<0>( aActivityParms, rAnim ) );
    1029             : }
    1030             : 
    1031             : } // namespace internal
    1032           6 : } // namespace presentation
    1033             : 
    1034             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10