[Libreoffice-commits] .: Branch 'feature/svg-export' - 2 commits - filter/source slideshow/source

Marco Cecchetti mcecchetti at kemper.freedesktop.org
Sun Jun 17 02:56:04 PDT 2012


 filter/source/svg/presentation_engine.js                     |   95 +++++++++--
 slideshow/source/engine/activities/activitiesfactory.cxx     |   75 +++++++-
 slideshow/source/engine/animationnodes/animationbasenode.cxx |   14 +
 slideshow/source/engine/color.cxx                            |   25 ++
 slideshow/source/inc/hslcolor.hxx                            |    2 
 slideshow/source/inc/rgbcolor.hxx                            |    2 
 6 files changed, 193 insertions(+), 20 deletions(-)

New commits:
commit a42f479ae3a951656e0a29c46760d9df1615fff2
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Wed Jun 13 19:50:38 2012 +0200

    Now to animations and repeated to animations are handled by the C++ presentation engine
    as the SMIL spec describes.

diff --git a/slideshow/source/engine/activities/activitiesfactory.cxx b/slideshow/source/engine/activities/activitiesfactory.cxx
index f142456..a99a32a 100644
--- a/slideshow/source/engine/activities/activitiesfactory.cxx
+++ b/slideshow/source/engine/activities/activitiesfactory.cxx
@@ -167,6 +167,9 @@ public:
           mpFormula( rParms.mpFormula ),
           maStartValue(),
           maEndValue(),
+          maPreviousValue(),
+          maStartInterpolationValue(),
+          mnIteration( 0 ),
           mpAnim( rAnim ),
           maInterpolator( rInterpolator ),
           mbDynamicStartValue( false ),
@@ -220,6 +223,9 @@ public:
         }
         else
         {
+            maStartValue = aAnimationStartValue;
+            maStartInterpolationValue = maStartValue;
+
             // By or To animation. According to SMIL spec,
             // the To value takes precedence over the By
             // value, if both are specified
@@ -232,6 +238,7 @@ public:
                 // the to animation interpolates between
                 // the _running_ underlying value and the to value (as the end value)
                 mbDynamicStartValue = true;
+                maPreviousValue = maStartValue;
                 maEndValue = *maTo;
             }
             else if( maBy )
@@ -255,15 +262,61 @@ public:
     {
         if (this->isDisposed() || !mpAnim)
             return;
-        (*mpAnim)(
-            getPresentationValue(
-                accumulate( maEndValue,
-                            mbCumulative * nRepeatCount, // means: mbCumulative ? nRepeatCount : 0,
-                            maInterpolator( (mbDynamicStartValue
-                                             ? mpAnim->getUnderlyingValue()
-                                             : maStartValue),
-                                            maEndValue,
-                                            nModifiedTime ) ) ) );
+
+        // According to SMIL 3.0 spec 'to' animation if no other (lower priority)
+        // animations are active or frozen then a simple interpolation is performed.
+        // That is, the start interpolation value is constant while the animation
+        // is running, and is equal to the underlying value retrieved when
+        // the animation start.
+        // However if another animation is manipulating the underlying value,
+        // the 'to' animation will initially add to the effect of the lower priority
+        // animation, and increasingly dominate it as it nears the end of the
+        // simple duration, eventually overriding it completely.
+        // That is, each time the underlying value is changed between two
+        // computations of the animation function the new underlying value is used
+        // as start value for the interpolation.
+        // See:
+        // http://www.w3.org/TR/SMIL3/smil-animation.html#animationNS-ToAnimation
+        // (Figure 6 - Effect of Additive to animation example)
+        // Moreover when a 'to' animation is repeated, at each new iteration
+        // the start interpolation value is reset to the underlying value
+        // of the animated property when the animation started,
+        // as it is shown in the example provided by the SMIL 3.0 spec.
+        // This is exactly as Firefox performs SVG 'to' animations.
+        if( mbDynamicStartValue )
+        {
+            if( mnIteration != nRepeatCount )
+            {
+                mnIteration = nRepeatCount;
+                maStartInterpolationValue = maStartValue;
+            }
+            else
+            {
+                ValueType aActualValue = mpAnim->getUnderlyingValue();
+                if( aActualValue != maPreviousValue )
+                    maStartInterpolationValue = aActualValue;
+            }
+        }
+
+        ValueType aValue = maInterpolator( maStartInterpolationValue,
+                                           maEndValue, nModifiedTime );
+
+        // According to the SMIL spec:
+        // Because 'to' animation is defined in terms of absolute values of
+        // the target attribute, cumulative animation is not defined.
+        if( mbCumulative && !mbDynamicStartValue )
+        {
+            // aValue = this.aEndValue * nRepeatCount + aValue;
+            aValue = accumulate( maEndValue, nRepeatCount, aValue );
+        }
+
+        (*mpAnim)( getPresentationValue( aValue ) );
+
+        if( mbDynamicStartValue )
+        {
+            maPreviousValue = mpAnim->getUnderlyingValue();
+        }
+
     }
 
     using BaseType::perform;
@@ -316,6 +369,10 @@ private:
     ValueType                               maStartValue;
     ValueType                               maEndValue;
 
+    mutable ValueType                               maPreviousValue;
+    mutable ValueType                               maStartInterpolationValue;
+    mutable sal_uInt32                              mnIteration;
+
     ::boost::shared_ptr< AnimationType >    mpAnim;
     Interpolator< ValueType >               maInterpolator;
     bool                                    mbDynamicStartValue;
diff --git a/slideshow/source/engine/animationnodes/animationbasenode.cxx b/slideshow/source/engine/animationnodes/animationbasenode.cxx
index df1bcc5..ed63495 100644
--- a/slideshow/source/engine/animationnodes/animationbasenode.cxx
+++ b/slideshow/source/engine/animationnodes/animationbasenode.cxx
@@ -33,6 +33,7 @@
 #include <cppuhelper/exc_hlp.hxx>
 #include <comphelper/anytostring.hxx>
 #include <com/sun/star/presentation/ParagraphTarget.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
 #include <com/sun/star/animations/Timing.hpp>
 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
@@ -421,7 +422,18 @@ AnimationBaseNode::fillCommonParameters() const
             else
                 aRepeats.reset( nRepeats / nDuration );
         }
-        else {
+        // This is a temporary workaround:
+        // as the repeatCount attribute is defined on the <par> parent node
+        // and activities are created only for animation node leaves, that
+        // actual performs a shape effect, we get the repeatCount value
+        // from the parent node.
+        else if( ( getXAnimationNode()->getType() != animations::AnimationNodeType::SET )
+                 && (getParentNode()->getXAnimationNode()->getRepeatCount() >>= nRepeats) )
+        {
+            aRepeats.reset( nRepeats );
+        }
+        else
+        {
             // no double value for both values - Timing::INDEFINITE?
             animations::Timing eTiming;
 
diff --git a/slideshow/source/engine/color.cxx b/slideshow/source/engine/color.cxx
index dc5092b..c9ce4f2 100644
--- a/slideshow/source/engine/color.cxx
+++ b/slideshow/source/engine/color.cxx
@@ -217,6 +217,19 @@ namespace slideshow
             return maHSLTriple.mnLuminance;
         }
 
+
+        sal_Bool operator==( const HSLColor& rLHS, const HSLColor& rRHS )
+        {
+            return ( rLHS.getHue() == rRHS.getHue() &&
+                     rLHS.getSaturation() == rRHS.getSaturation() &&
+                     rLHS.getLuminance() == rRHS.getLuminance() );
+        }
+
+        sal_Bool operator!=( const HSLColor& rLHS, const HSLColor& rRHS )
+        {
+            return !( rLHS == rRHS );
+        }
+
         HSLColor operator+( const HSLColor& rLHS, const HSLColor& rRHS )
         {
             return HSLColor( rLHS.getHue() + rRHS.getHue(),
@@ -346,6 +359,18 @@ namespace slideshow
                                            255 );
         }
 
+        sal_Bool operator==( const RGBColor& rLHS, const RGBColor& rRHS )
+        {
+            return ( rLHS.getRed() == rRHS.getRed() &&
+                     rLHS.getGreen() == rRHS.getGreen() &&
+                     rLHS.getBlue() == rRHS.getBlue() );
+        }
+
+        sal_Bool operator!=( const RGBColor& rLHS, const RGBColor& rRHS )
+        {
+            return !( rLHS == rRHS );
+        }
+
         RGBColor operator+( const RGBColor& rLHS, const RGBColor& rRHS )
         {
             return RGBColor( rLHS.getRed() + rRHS.getRed(),
diff --git a/slideshow/source/inc/hslcolor.hxx b/slideshow/source/inc/hslcolor.hxx
index 6659923..15500c7 100644
--- a/slideshow/source/inc/hslcolor.hxx
+++ b/slideshow/source/inc/hslcolor.hxx
@@ -88,6 +88,8 @@ namespace slideshow
             double      mnMagicValue;
         };
 
+        sal_Bool operator==( const HSLColor& rLHS, const HSLColor& rRHS );
+        sal_Bool operator!=( const HSLColor& rLHS, const HSLColor& rRHS );
         HSLColor operator+( const HSLColor& rLHS, const HSLColor& rRHS );
         HSLColor operator*( const HSLColor& rLHS, const HSLColor& rRHS );
         HSLColor operator*( double nFactor, const HSLColor& rRHS );
diff --git a/slideshow/source/inc/rgbcolor.hxx b/slideshow/source/inc/rgbcolor.hxx
index fc161f7..844f324 100644
--- a/slideshow/source/inc/rgbcolor.hxx
+++ b/slideshow/source/inc/rgbcolor.hxx
@@ -84,6 +84,8 @@ namespace slideshow
             RGBTriple   maRGBTriple;
         };
 
+        sal_Bool operator==( const RGBColor& rLHS, const RGBColor& rRHS );
+        sal_Bool operator!=( const RGBColor& rLHS, const RGBColor& rRHS );
         RGBColor operator+( const RGBColor& rLHS, const RGBColor& rRHS );
         RGBColor operator*( const RGBColor& rLHS, const RGBColor& rRHS );
         RGBColor operator*( double nFactor, const RGBColor& rRHS );
commit 1c0b86543fd22a04d391bc96124024b7168128e7
Author: Marco Cecchetti <mrcekets at gmail.com>
Date:   Tue Jun 12 21:42:41 2012 +0200

    Now to animations and repeated to animations are handled by the JavaScript engine as the
    SMIL spec describes.

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 1ce3e16..13efb60 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -3375,6 +3375,13 @@ RGBColor.prototype.clone = function()
     return new RGBColor( this.nRed, this.nGreen, this.nBlue );
 };
 
+RGBColor.prototype.equal = function( aRGBColor )
+{
+    return ( this.nRed == aRGBColor.nRed ) &&
+           ( this.nGreen == aRGBColor.nGreen ) &&
+           ( this.nBlue == aRGBColor.nBlue );
+};
+
 RGBColor.prototype.add = function( aRGBColor )
 {
     this.nRed += aRGBColor.nRed;
@@ -3488,6 +3495,13 @@ HSLColor.prototype.clone = function()
     return new HSLColor( this.nHue, this.nSaturation, this.nLuminance );
 };
 
+HSLColor.prototype.equal = function( aHSLColor )
+{
+    return ( this.nHue == aHSLColor.nHue ) &&
+           ( this.nSaturation += aHSLColor.nSaturation ) &&
+           ( this.nLuminance += aHSLColor.nLuminance );
+};
+
 HSLColor.prototype.add = function( aHSLColor )
 {
     this.nHue += aHSLColor.nHue;
@@ -3990,11 +4004,11 @@ aPresetIdInMap = {};
 
 
 // Restart Modes
-RESTART_MODE_DEFAULT            = 0;
-RESTART_MODE_INHERIT            = 0;
-RESTART_MODE_ALWAYS             = 1;
-RESTART_MODE_WHEN_NOT_ACTIVE    = 2;
-RESTART_MODE_NEVER              = 3;
+var RESTART_MODE_DEFAULT            = 0;
+var RESTART_MODE_INHERIT            = 0;
+var RESTART_MODE_ALWAYS             = 1;
+var RESTART_MODE_WHEN_NOT_ACTIVE    = 2;
+var RESTART_MODE_NEVER              = 3;
 
 aRestartModeInMap = {
     'inherit'       : RESTART_MODE_DEFAULT,
@@ -4168,7 +4182,7 @@ BOXWIPE_TRANSITION          = 2;
 FOURBOXWIPE_TRANSITION      = 3;
 ELLIPSEWIPE_TRANSITION      = 4; // 17
 CLOCKWIPE_TRANSITION        = 5; // 22
-PINWHEELWIPE_TRANSITION     = 6  // 23
+PINWHEELWIPE_TRANSITION     = 6;  // 23
 PUSHWIPE_TRANSITION         = 7; // 35
 SLIDEWIPE_TRANSITION        = 8; // 36
 FADE_TRANSITION             = 9; // 37
@@ -9613,6 +9627,11 @@ var aOperatorSetMap = new Array();
 // number operators
 aOperatorSetMap[ NUMBER_PROPERTY ] = new Object();
 
+aOperatorSetMap[ NUMBER_PROPERTY ].equal = function( a, b )
+{
+    return ( a === b );
+};
+
 aOperatorSetMap[ NUMBER_PROPERTY ].add = function( a, b )
 {
     return ( a + b );
@@ -9626,6 +9645,11 @@ aOperatorSetMap[ NUMBER_PROPERTY ].scale = function( k, v )
 // color operators
 aOperatorSetMap[ COLOR_PROPERTY ] = new Object();
 
+aOperatorSetMap[ COLOR_PROPERTY ].equal = function( a, b )
+{
+    return a.equal( b );
+};
+
 aOperatorSetMap[ COLOR_PROPERTY ].add = function( a, b )
 {
     var c = a.clone();
@@ -10318,11 +10342,15 @@ function FromToByActivityTemplate( BaseType ) // template parameter
         this.aBy = aByValue;
         this.aStartValue = null;
         this.aEndValue = null;
+        this.aPreviousValue = null;
+        this.aStartInterpolationValue = null;
         this.aAnimation = aAnimation;
         this.aInterpolator = aInterpolator;
+        this.equal = aOperatorSet.equal;
         this.add = aOperatorSet.add;
         this.scale = aOperatorSet.scale;
         this.bDynamicStartValue = false;
+        this.nIteration = 0;
         this.bCumulative = bAccumulate;
 
         this.initAnimatedElement();
@@ -10378,6 +10406,9 @@ function FromToByActivityTemplate( BaseType ) // template parameter
         }
         else
         {
+            this.aStartValue = aAnimationStartValue;
+            this.aStartInterpolationValue = this.aStartValue;
+
             // By or To animation. According to SMIL spec,
             // the To value takes precedence over the By
             // value, if both are specified
@@ -10390,6 +10421,7 @@ function FromToByActivityTemplate( BaseType ) // template parameter
                 // the to animation interpolates between
                 // the _running_ underlying value and the to value (as the end value)
                 this.bDynamicStartValue = true;
+                this.aPreviousValue = this.aStartValue;
                 this.aEndValue = this.aTo;
             }
             else if( this.aBy )
@@ -10420,18 +10452,61 @@ function FromToByActivityTemplate( BaseType ) // template parameter
             return;
         }
 
-        var aValue = this.bDynamicStartValue ? this.aAnimation.getUnderlyingValue()
-                                             : this.aStartValue;
 
-        aValue = this.aInterpolator( aValue, this.aEndValue, nModifiedTime );
+        // According to SMIL 3.0 spec 'to' animation if no other (lower priority)
+        // animations are active or frozen then a simple interpolation is performed.
+        // That is, the start interpolation value is constant while the animation
+        // is running, and is equal to the underlying value retrieved when
+        // the animation start.
+        // However if another animation is manipulating the underlying value,
+        // the 'to' animation will initially add to the effect of the lower priority
+        // animation, and increasingly dominate it as it nears the end of the
+        // simple duration, eventually overriding it completely.
+        // That is, each time the underlying value is changed between two
+        // computations of the animation function the new underlying value is used
+        // as start value for the interpolation.
+        // See:
+        // http://www.w3.org/TR/SMIL3/smil-animation.html#animationNS-ToAnimation
+        // (Figure 6 - Effect of Additive to animation example)
+        // Moreover when a 'to' animation is repeated, at each new iteration
+        // the start interpolation value is reset to the underlying value
+        // of the animated property when the animation started,
+        // as it is shown in the example provided by the SMIL 3.0 spec.
+        // This is exactly as Firefox performs SVG 'to' animations.
+        if( this.bDynamicStartValue )
+        {
+            if( this.nIteration != nRepeatCount )
+            {
+                this.nIteration = nRepeatCount;
+                this.aStartInterpolationValue =  this.aStartValue;
+            }
+            else
+            {
+                var aActualValue = this.aAnimation.getUnderlyingValue();
+                if( !this.equal( aActualValue, this.aPreviousValue ) )
+                    this.aStartInterpolationValue = aActualValue;
+            }
+        }
 
-        if( this.bCumulative )
+        var aValue = this.aInterpolator( this.aStartInterpolationValue,
+                                         this.aEndValue, nModifiedTime );
+
+        // According to the SMIL spec:
+        // Because 'to' animation is defined in terms of absolute values of
+        // the target attribute, cumulative animation is not defined.
+        if( this.bCumulative && !this.bDynamicStartValue )
         {
             // aValue = this.aEndValue * nRepeatCount + aValue;
             aValue = this.add( this.scale( nRepeatCount, this.aEndValue ), aValue );
         }
 
         this.aAnimation.perform( aValue );
+
+        if( this.bDynamicStartValue )
+        {
+            this.aPreviousValue = this.aAnimation.getUnderlyingValue();
+        }
+
     };
 
     FromToByActivity.prototype.performEnd = function()


More information about the Libreoffice-commits mailing list