filter/source/svg/presentation_engine.js |  231 ++++++++++++++++++++++++++++++-
 1 file changed, 226 insertions(+), 5 deletions(-)

New commits:
commit 3170a77121aed419cb5a606ee8e7bce7e9c275ac
Author:     Marco Cecchetti <marco.cecche...@collabora.com>
AuthorDate: Mon May 23 12:22:19 2022 +0200
Commit:     Aron Budea <aron.bu...@collabora.com>
CommitDate: Thu Jul 7 05:40:03 2022 +0200

    svg filter: transform animations: support for scale and translate
    
    Now the emphasis grow and shrink animation is supported.
    Now the animation engine is able to handle array of values instead of
    single value param when computing the next animation state.
    
    Change-Id: Ic200103c6c26a63de8eecc37dcd36ba1a2f0d391
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134870
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Andras Timar <andras.ti...@collabora.com>
    (cherry picked from commit a6ed16394c4a95cf204f38c30cb025bc99f00027)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136418
    Tested-by: Jenkins
    Reviewed-by: Aron Budea <aron.bu...@collabora.com>

diff --git a/filter/source/svg/presentation_engine.js 
b/filter/source/svg/presentation_engine.js
index c98e93de7b7a..6473963f8e76 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -7033,6 +7033,8 @@ function matrixToString( aSVGMatrix )
 // eslint-disable-next-line no-unused-vars
 function numberParser( sValue )
 {
+    if( typeof sValue !== 'string' )
+        return undefined;
     if( sValue === '.' )
         return undefined;
     var reFloatNumber = /^[+-]?[0-9]*[.]?[0-9]*$/;
@@ -7045,6 +7047,9 @@ function numberParser( sValue )
 
 function booleanParser( sValue )
 {
+    if( typeof sValue !== 'string' )
+        return undefined;
+
     sValue = sValue.toLowerCase();
     if( sValue === 'true' )
         return true;
@@ -7056,6 +7061,9 @@ function booleanParser( sValue )
 
 function colorParser( sValue )
 {
+    if( typeof sValue !== 'string' )
+        return undefined;
+
     // The following 3 color functions are used in evaluating sValue string
     // so don't remove them.
 
@@ -7989,6 +7997,7 @@ var ENUM_PROPERTY           = 2;
 var COLOR_PROPERTY          = 3;
 var STRING_PROPERTY         = 4;
 var BOOL_PROPERTY           = 5;
+var TUPLE_NUMBER_PROPERTY   = 6;
 
 var aValueTypeOutMap = [ 'unknown', 'number', 'enum', 'color', 'string', 
'boolean' ];
 
@@ -8006,6 +8015,14 @@ var aAttributeMap =
                                 'get':          'getOpacity',
                                 'set':          'setOpacity'                   
 },
 
+        'scale':           {   'type':          TUPLE_NUMBER_PROPERTY,
+                                'get':          'getSize',
+                                'set':          'setSize'                      
 },
+
+        'translate':       {   'type':          TUPLE_NUMBER_PROPERTY,
+                                'get':          'getPos',
+                                'set':          'setPos'                       
 },
+
         'rotate':           {   'type':         NUMBER_PROPERTY,
                                 'get':          'getRotationAngle',
                                 'set':          'setRotationAngle'             
 },
@@ -11615,10 +11632,21 @@ AnimationTransformNode.prototype.createActivity = 
function()
     var aActivityParamSet = this.fillActivityParams();
     var aAnimation;
 
-    aAnimation = createPropertyAnimation( this.getAttributeName(),
-                                          this.getAnimatedElement(),
-                                          this.aNodeContext.aSlideWidth,
-                                          this.aNodeContext.aSlideHeight );
+    if( this.getAttributeName() === 'scale' || this.getAttributeName() === 
'translate' )
+    {
+        aAnimation = createPairPropertyAnimation( this.getAttributeName(),
+                                                  this.getAnimatedElement(),
+                                                  
this.aNodeContext.aSlideWidth,
+                                                  
this.aNodeContext.aSlideHeight );
+
+    }
+    else
+    {
+        aAnimation = createPropertyAnimation( this.getAttributeName(),
+                                              this.getAnimatedElement(),
+                                              this.aNodeContext.aSlideWidth,
+                                              this.aNodeContext.aSlideHeight );
+    }
 
     var aInterpolator = null;  // createActivity will compute it;
     return createActivity( aActivityParamSet, this, aAnimation, aInterpolator 
);
@@ -12049,6 +12077,41 @@ function createPropertyAnimation( sAttrName, 
aAnimatedElement, nWidth, nHeight )
 
 
 
+function createPairPropertyAnimation( sTransformType, aAnimatedElement, 
nWidth, nHeight )
+{
+    var aFunctorSet = aAttributeMap[ sTransformType ];
+    var sGetValueMethod = aFunctorSet.get;
+    var sSetValueMethod = aFunctorSet.set;
+
+    var aDefaultValue = [];
+    var aSizeReference = [];
+    if( sTransformType === 'scale' )
+    {
+        aDefaultValue[0] = aSizeReference[0] = 
aAnimatedElement.getBaseBBox().width;
+        aDefaultValue[1] = aSizeReference[1] = 
aAnimatedElement.getBaseBBox().height;
+    }
+    else if( sTransformType === 'translate' )
+    {
+        aDefaultValue[0] = aAnimatedElement.getBaseCenterX();
+        aDefaultValue[1] = aAnimatedElement.getBaseCenterY();
+        aSizeReference[0] = nWidth;
+        aSizeReference[1] = nHeight;
+    }
+    else
+    {
+        log( 'createPairPropertyAnimation: transform type is not handled' );
+        return null;
+    }
+
+    return new TupleAnimation( bind( aAnimatedElement, aAnimatedElement[ 
sGetValueMethod ] ),
+                               bind( aAnimatedElement, aAnimatedElement[ 
sSetValueMethod ] ),
+                               aDefaultValue,
+                               aSizeReference );
+}
+
+
+
+
 /** createShapeTransition
  *
  *  @param aActivityParamSet
@@ -12248,6 +12311,45 @@ GenericAnimation.prototype.getUnderlyingValue = 
function()
 
 
 
+function TupleAnimation( aGetValueFunc, aSetValueFunc, aDefaultValue, 
aReferenceSize )
+{
+    TupleAnimation.superclass.constructor.call( this, aGetValueFunc, 
aSetValueFunc );
+    assert( aDefaultValue && aReferenceSize,
+            'TupleAnimation constructor: default value functor and/or 
reference size are not valid' );
+
+    this.aDefaultValue = aDefaultValue;
+    this.aReferenceSize = aReferenceSize;
+}
+extend( TupleAnimation, GenericAnimation );
+
+TupleAnimation.prototype.perform = function( aNormValue )
+{
+    assert(aNormValue.length === this.aReferenceSize.length);
+
+    var aValue = [];
+    for( var i = 0; i < aNormValue.length; ++i )
+    {
+        aValue.push( aNormValue[i] * this.aReferenceSize[i] );
+    }
+
+    this.aSetValueFunc( aValue );
+};
+
+TupleAnimation.prototype.getUnderlyingValue = function()
+{
+    var aValue = this.aGetValueFunc();
+    assert(aValue.length === this.aReferenceSize.length);
+
+    var aNormValue = [];
+    for( var i = 0; i < aValue.length; ++i )
+    {
+        aNormValue.push( aValue[i] / this.aReferenceSize[i] );
+    }
+
+    return aNormValue;
+};
+
+
 
 function HSLAnimationWrapper( aColorAnimation )
 {
@@ -14565,6 +14667,11 @@ AnimatedElement.prototype.getY = function()
     return this.nCenterY;
 };
 
+AnimatedElement.prototype.getPos = function()
+{
+    return [this.getX(), this.getY()];
+};
+
 AnimatedElement.prototype.getWidth = function()
 {
     return this.nScaleFactorX * this.getBaseBBox().width;
@@ -14575,6 +14682,11 @@ AnimatedElement.prototype.getHeight = function()
     return this.nScaleFactorY * this.getBaseBBox().height;
 };
 
+AnimatedElement.prototype.getSize = function()
+{
+    return [this.getWidth(), this.getHeight()];
+};
+
 AnimatedElement.prototype.updateTransformAttribute = function()
 {
     this.aTransformAttrList = this.aActiveElement.transform.baseVal;
@@ -14604,12 +14716,27 @@ AnimatedElement.prototype.setY = function( 
nNewCenterY )
     this.nCenterY = nNewCenterY;
 };
 
+AnimatedElement.prototype.setPos = function( aNewPos )
+{
+    var nNewCenterX = aNewPos[0];
+    var nNewCenterY = aNewPos[1];
+
+    if( nNewCenterX === this.nCenterX && nNewCenterY === this.nCenterY ) 
return;
+
+    this.aTransformAttrList = this.aActiveElement.transform.baseVal;
+    this.aTransformAttr = this.aTransformAttrList.getItem( 0 );
+    this.aTMatrix = this.aTransformAttr.matrix.translate( nNewCenterX - 
this.nCenterX, nNewCenterY - this.nCenterY );
+    this.aTransformAttr.setMatrix( this.aTMatrix );
+    this.nCenterX = nNewCenterX;
+    this.nCenterY = nNewCenterY;
+};
+
 AnimatedElement.prototype.setWidth = function( nNewWidth )
 {
     ANIMDBG.print( 'AnimatedElement.setWidth: nNewWidth = ' + nNewWidth );
     if( nNewWidth < 0 )
     {
-        log('AnimatedElement(' + this.getId() + ').setWidth: negative 
height!');
+        log('AnimatedElement(' + this.getId() + ').setWidth: negative width!');
         nNewWidth = 0;
     }
 
@@ -14654,6 +14781,43 @@ AnimatedElement.prototype.setHeight = function( 
nNewHeight )
     this.nScaleFactorY = nScaleFactorY;
 };
 
+AnimatedElement.prototype.setSize= function( aNewSize )
+{
+    var nNewWidth = aNewSize[0];
+    var nNewHeight = aNewSize[1];
+    ANIMDBG.print( 'AnimatedElement.setSize:  = [' + nNewWidth + ',' + 
nNewHeight + ']');
+    if( nNewWidth < 0 )
+    {
+        log('AnimatedElement(' + this.getId() + ').setSize: negative width!');
+        nNewWidth = 0;
+    }
+    if( nNewHeight < 0 )
+    {
+        log('AnimatedElement(' + this.getId() + ').setSize: negative height!');
+        nNewHeight = 0;
+    }
+
+    var nBaseWidth = this.getBaseBBox().width;
+    var nScaleFactorX = nNewWidth / nBaseWidth;
+    if( nScaleFactorX < 1e-5 ) nScaleFactorX = 1e-5;
+
+    var nBaseHeight = this.getBaseBBox().height;
+    var nScaleFactorY = nNewHeight / nBaseHeight;
+    if( nScaleFactorY < 1e-5 ) nScaleFactorY = 1e-5;
+
+    if( nScaleFactorX == this.nScaleFactorX && nScaleFactorY == 
this.nScaleFactorY ) return;
+
+    this.aTMatrix = document.documentElement.createSVGMatrix()
+        .translate( this.nCenterX, this.nCenterY )
+        .rotate(this.nRotationAngle)
+        .scaleNonUniform( nScaleFactorX, nScaleFactorY )
+        .translate( -this.nBaseCenterX, -this.nBaseCenterY );
+    this.updateTransformAttribute();
+
+    this.nScaleFactorX = nScaleFactorX;
+    this.nScaleFactorY = nScaleFactorY;
+};
+
 AnimatedElement.prototype.getOpacity = function()
 {
     return this.aActiveElement.getAttribute( 'opacity' );
@@ -16387,6 +16551,17 @@ aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR 
][ COLOR_PROPERTY ][ COLO
                 };
     };
 
+aInterpolatorHandler.aLerpFunctorMap[ CALC_MODE_LINEAR ][ 
TUPLE_NUMBER_PROPERTY ] =
+    function ( aFrom, aTo, nT )
+    {
+        var aRes = [];
+        for( var i = 0; i < aFrom.length; ++i )
+        {
+            aRes.push( ( 1.0 - nT )* aFrom[i] + nT * aTo[i] );
+        }
+        return aRes;
+    };
+
 
 
 
@@ -16554,6 +16729,36 @@ aOperatorSetMap[ STRING_PROPERTY ] = aOperatorSetMap[ 
ENUM_PROPERTY ];
 // bool operators
 aOperatorSetMap[ BOOL_PROPERTY ] = aOperatorSetMap[ ENUM_PROPERTY ];
 
+// tuple number operators
+aOperatorSetMap[ TUPLE_NUMBER_PROPERTY ] = {};
+
+aOperatorSetMap[ TUPLE_NUMBER_PROPERTY ].equal = function( a, b )
+{
+    assert( a.length === b.length, 'Tuples length mismatch.' );
+    return ( a.toString() === b.toString() );
+};
+
+aOperatorSetMap[ TUPLE_NUMBER_PROPERTY ].add = function( a, b )
+{
+    assert( a.length === b.length, 'Tuples length mismatch.' );
+    var r = [];
+    for( var i = 0; i < a.length; ++i )
+    {
+        r.push(a[i] + b[i]);
+    }
+    return r;
+};
+
+aOperatorSetMap[ TUPLE_NUMBER_PROPERTY ].scale = function( k, v )
+{
+    var r = [];
+    for( var i = 0; i < v.length; ++i )
+    {
+        r.push(k * v[i]);
+    }
+    return r;
+};
+
 
 
 
@@ -17963,6 +18168,22 @@ function extractAttributeValues( eValueType, 
aValueList, aValueSet, aBBox, nSlid
                 aValueList.push( aValue );
             }
             break;
+        case TUPLE_NUMBER_PROPERTY :
+            for( i = 0; i < aValueSet.length; ++i )
+            {
+                if( typeof aValueSet[i] === 'string' )
+                {
+                    var aTuple = aValueSet[i].split(',');
+                    aValue = [];
+                    evalValuesAttribute(aValue, aTuple, aBBox, nSlideWidth, 
nSlideHeight);
+                    aValueList.push(aValue);
+                }
+                else
+                {
+                    aValueList.push( undefined );
+                }
+            }
+            break;
         default:
             log( 'createValueListActivity: unexpected value type: ' + 
eValueType );
     }

Reply via email to