diff options
Diffstat (limited to 'filter/source/svg/presentation_engine.js')
-rw-r--r-- | filter/source/svg/presentation_engine.js | 291 |
1 files changed, 283 insertions, 8 deletions
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js index 0babb0083cc8..8906825126fe 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' }, @@ -11574,6 +11591,70 @@ PropertyAnimationNode.prototype.createActivity = function() +function isValidTransformation( sType ) +{ + return ( sType === 'translate' || sType === 'scale' || sType === 'rotate' + || sType === 'skewX' || sType === 'skewY' ); +} + +function AnimationTransformNode( aAnimElem, aParentNode, aNodeContext ) +{ + AnimationTransformNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); + + this.sClassName = 'AnimationTransformNode'; +} +extend( AnimationTransformNode, AnimationBaseNode3 ); + + +AnimationTransformNode.prototype.parseElement = function() +{ + var bRet = AnimationTransformNode.superclass.parseElement.call(this); + + var aAnimElem = this.aElement; + + // transformation type + var sTransformType = aAnimElem.getAttribute( 'svg:type' ); + if( !isValidTransformation( sTransformType ) ) + { + this.eCurrentState = INVALID_NODE; + log( 'AnimationTransformNode.parseElement: transformation type not found: ' + sTransformType ); + } + else + { + this.sAttributeName = sTransformType; + } + + return bRet; +} + +AnimationTransformNode.prototype.createActivity = function() +{ + var aActivityParamSet = this.fillActivityParams(); + var aAnimation; + + 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 ); +}; + + + + function AnimationSetNode( aAnimElem, aParentNode, aNodeContext ) { AnimationSetNode.superclass.constructor.call( this, aAnimElem, aParentNode, aNodeContext ); @@ -11872,10 +11953,8 @@ function createAnimationNode( aElement, aParentNode, aNodeContext ) aCreatedNode = new AnimationColorNode( aElement, aParentNode, aNodeContext ); break; case ANIMATION_NODE_ANIMATETRANSFORM: - //aCreatedNode = new AnimationTransformNode( aElement, aParentNode, aNodeContext ); - //break; - log( 'createAnimationNode: ANIMATETRANSFORM not implemented' ); - return null; + aCreatedNode = new AnimationTransformNode( aElement, aParentNode, aNodeContext ); + break; case ANIMATION_NODE_TRANSITIONFILTER: aCreatedNode = new AnimationTransitionFilterNode( aElement, aParentNode, aNodeContext ); break; @@ -11998,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 @@ -12197,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 ) { @@ -14514,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; @@ -14524,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; @@ -14553,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; } @@ -14603,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' ); @@ -16336,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; + }; + @@ -16503,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; +}; + @@ -17912,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 ); } @@ -17934,9 +18206,12 @@ function evalValuesAttribute( aValueList, aValueSet, aBBox, nSlideWidth, nSlideH for( var i = 0; i < aValueSet.length; ++i ) { var sValue = aValueSet[i]; - sValue = sValue.replace(reMath, 'Math.$&'); - sValue = sValue.replace(/pi(?!\w)/g, 'Math.PI'); - sValue = sValue.replace(/e(?!\w)/g, 'Math.E'); + if(sValue) + { + sValue = sValue.replace(reMath, 'Math.$&'); + sValue = sValue.replace(/pi(?!\w)/g, 'Math.PI'); + sValue = sValue.replace(/e(?!\w)/g, 'Math.E'); + } var aValue = eval( sValue ); aValueList.push( aValue ); } |