diff options
author | Marco Cecchetti <marco.cecchetti@collabora.com> | 2015-12-11 16:29:38 +0100 |
---|---|---|
committer | Marco Cecchetti <marco.cecchetti@collabora.com> | 2015-12-14 21:51:18 +0100 |
commit | b42ae0c72d1d8dabfe5fe4be671919420e504e1c (patch) | |
tree | 58131d5f9bf98851b5378446c8c748f300e052e6 /filter | |
parent | 6b4cffc4593f8137f1820069296e882df357fb51 (diff) |
svg export: added support for random bar and dissolve transitions
Change-Id: Ib5e303599b04b031d7eefed56603bce0d1e1e570
Diffstat (limited to 'filter')
-rw-r--r-- | filter/source/svg/presentation_engine.js | 177 |
1 files changed, 169 insertions, 8 deletions
diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js index c1cc82b41458..c1e464563d62 100644 --- a/filter/source/svg/presentation_engine.js +++ b/filter/source/svg/presentation_engine.js @@ -1077,6 +1077,17 @@ function getSafeIndex( nIndex, nMin, nMax ) return nIndex; } +/** getRandomInt + * + * @param nMax + * @returns {number} + * an integer in [0,nMax[ + */ +function getRandomInt( nMax ) +{ + return Math.floor( Math.random() * nMax ); +} + function isTextFieldElement( aElement ) { var sClassName = aElement.getAttribute( 'class' ); @@ -3627,7 +3638,7 @@ SVGPathElement.prototype.changeOrientation = function() var aMovePathSeg = this.createSVGPathSegMovetoAbs( nCurrentX, nCurrentY ); aPathSegList.insertItemBefore( aMovePathSeg, 0 ); -} +}; /** matrixTransform and changeOrientation * We implement these methods for each path segment type still present @@ -4120,11 +4131,13 @@ 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 -CHECKERBOARDWIPE_TRANSITION = 10; // 39 +RANDOMBARWIPE_TRANSITION = 10 // 38 +CHECKERBOARDWIPE_TRANSITION = 11; // 39 +DISSOLVE_TRANSITION = 12; // 40 aTransitionTypeInMap = { 'barWipe' : BARWIPE_TRANSITION, @@ -4136,12 +4149,14 @@ aTransitionTypeInMap = { 'pushWipe' : PUSHWIPE_TRANSITION, 'slideWipe' : SLIDEWIPE_TRANSITION, 'fade' : FADE_TRANSITION, - 'checkerBoardWipe' : CHECKERBOARDWIPE_TRANSITION + 'randomBarWipe' : RANDOMBARWIPE_TRANSITION, + 'checkerBoardWipe' : CHECKERBOARDWIPE_TRANSITION, + 'dissolve' : DISSOLVE_TRANSITION }; aTransitionTypeOutMap = [ '', 'barWipe', 'boxWipe', 'fourBoxWipe', 'ellipseWipe', 'clockWipe', 'pinWheelWipe', 'pushWipe', 'slideWipe', - 'fade', 'checkerBoardWipe' ]; + 'fade', 'randomBarWipe', 'checkerBoardWipe', 'dissolve' ]; // Transition Subtypes @@ -4175,6 +4190,7 @@ ONEBLADE_TRANS_SUBTYPE = 26; // 107 ACROSS_TRANS_SUBTYPE = 27; aTransitionSubtypeInMap = { + 'default' : DEFAULT_TRANS_SUBTYPE, 'leftToRight' : LEFTTORIGHT_TRANS_SUBTYPE, 'topToBottom' : TOPTOBOTTOM_TRANS_SUBTYPE, 'cornersIn' : CORNERSIN_TRANS_SUBTYPE, @@ -4444,6 +4460,29 @@ aTransitionInfoTable[FADE_TRANSITION][FADEOVERCOLOR_TRANS_SUBTYPE] = 'scaleIsotropically' : false }; + +aTransitionInfoTable[RANDOMBARWIPE_TRANSITION] = {}; +aTransitionInfoTable[RANDOMBARWIPE_TRANSITION][VERTICAL_TRANS_SUBTYPE] = +{ + 'class' : TRANSITION_CLIP_POLYPOLYGON, + 'rotationAngle' : 90.0, + 'scaleX' : 1.0, + 'scaleY' : 1.0, + 'reverseMethod' : REVERSEMETHOD_IGNORE, + 'outInvertsSweep' : true, + 'scaleIsotropically' : false +}; +aTransitionInfoTable[RANDOMBARWIPE_TRANSITION][HORIZONTAL_TRANS_SUBTYPE] = +{ + 'class' : TRANSITION_CLIP_POLYPOLYGON, + 'rotationAngle' : 0.0, + 'scaleX' : 1.0, + 'scaleY' : 1.0, + 'reverseMethod' : REVERSEMETHOD_IGNORE, + 'outInvertsSweep' : true, + 'scaleIsotropically' : false +}; + aTransitionInfoTable[CHECKERBOARDWIPE_TRANSITION] = {}; aTransitionInfoTable[CHECKERBOARDWIPE_TRANSITION][DOWN_TRANS_SUBTYPE] = { @@ -4466,6 +4505,18 @@ aTransitionInfoTable[CHECKERBOARDWIPE_TRANSITION][ACROSS_TRANS_SUBTYPE] = 'scaleIsotropically' : false }; +aTransitionInfoTable[DISSOLVE_TRANSITION] = {}; +aTransitionInfoTable[DISSOLVE_TRANSITION][DEFAULT_TRANS_SUBTYPE] = +{ + 'class' : TRANSITION_CLIP_POLYPOLYGON, + 'rotationAngle' : 0.0, + 'scaleX' : 1.0, + 'scaleY' : 1.0, + 'reverseMethod' : REVERSEMETHOD_IGNORE, + 'outInvertsSweep' : true, + 'scaleIsotropically' : true +}; + // Transition tables @@ -5615,7 +5666,7 @@ function AnimationBaseNode( aAnimElem, aParentNode, aNodeContext ) this.sClassName = 'AnimationBaseNode'; this.bIsContainer = false; this.aTargetElement = null; - this.bIsTargetTextElement = false + this.bIsTargetTextElement = false; this.aAnimatedElement = null; this.aActivity = null; @@ -6974,7 +7025,9 @@ AnimationTransitionFilterNode.prototype.parseElement = function() // subtype attribute this.eTransitionSubType = undefined; var sSubTypeAttr = aAnimElem.getAttributeNS( NSS['smil'], 'subtype' ); - if( sSubTypeAttr && aTransitionSubtypeInMap[ sSubTypeAttr ] ) + if( sSubTypeAttr === null ) + sSubTypeAttr = 'default'; + if( sSubTypeAttr && ( aTransitionSubtypeInMap[ sSubTypeAttr ] !== undefined ) ) { this.eTransitionSubType = aTransitionSubtypeInMap[ sSubTypeAttr ]; } @@ -8016,8 +8069,12 @@ function createClipPolyPolygon( nType, nSubtype ) return null; } return new PinWheelWipePath( nBlades ); + case RANDOMBARWIPE_TRANSITION: + return new RandomWipePath( 128, true /* bars */ ); case CHECKERBOARDWIPE_TRANSITION: return new CheckerBoardWipePath( 10 ); + case DISSOLVE_TRANSITION: + return new RandomWipePath( 16 * 16, false /* dissolve */ ); } } @@ -8032,6 +8089,14 @@ function createUnitSquarePath() return aPath; } +function createEmptyPath() +{ + var aPath = document.createElementNS( NSS['svg'], 'path' ); + var sD = 'M 0 0 L 0 0'; + aPath.setAttribute( 'd', sD ); + return aPath; +} + function pruneScaleValue( nVal ) { if( nVal < 0.0 ) @@ -8329,6 +8394,100 @@ CheckerBoardWipePath.prototype.perform = function( nT ) +/** Class RandomWipePath + * + * @param nElements + * The number of bars or cells to be used. + * @param bRandomBars + * true: generates a horizontal random bar wipe + * false: generates a dissolve wipe + */ +function RandomWipePath( nElements, bRandomBars ) +{ + this.nElements = nElements; + this.aBasePath = createUnitSquarePath(); + this.aPositionArray = new Array( nElements ); + this.aClipPath = createEmptyPath(); + this.nAlreadyAppendedElements = 0; + + if( bRandomBars ) // random bar wipe + { + var fEdgeLength = 1.0 / nElements; + var nPos; + for( nPos = 0; nPos < nElements; ++nPos ) + { + this.aPositionArray[nPos] = { x: 0.0, y: pruneScaleValue( nPos * fEdgeLength ) } + } + var aTransform = SVGIdentityMatrix.scaleNonUniform( 1.0, pruneScaleValue( fEdgeLength ) ); + } + else // dissolve wipe + { + var nSqrtElements = Math.round( Math.sqrt( nElements ) ); + var fEdgeLength = 1.0 / nSqrtElements; + var nPos; + for( nPos = 0; nPos < nElements; ++nPos ) + { + this.aPositionArray[nPos] = { + x: pruneScaleValue( ( nPos % nSqrtElements ) * fEdgeLength ), + y: pruneScaleValue( ( nPos / nSqrtElements ) * fEdgeLength ) } + } + var aTransform = SVGIdentityMatrix.scale( pruneScaleValue( fEdgeLength ) ); + } + this.aBasePath.matrixTransform( aTransform ); + + var nPos1, nPos2; + var tmp; + for( nPos1 = nElements - 1; nPos1 > 0; --nPos1 ) + { + nPos2 = getRandomInt( nPos1 + 1 ); + tmp = this.aPositionArray[nPos1]; + this.aPositionArray[nPos1] = this.aPositionArray[nPos2]; + this.aPositionArray[nPos2] = tmp; + } +} + +/** perform + * + * @param nT + * A parameter in [0,1] representing the width of the generated bars or squares. + * @return {SVGPathElement} + * A svg <path> element representing a multi bars or a multi squared cells. + */ +RandomWipePath.prototype.perform = function( nT ) +{ + var aPolyPath = createEmptyPath(); + var aPoint; + var aPath; + var aTransform; + var nElements = Math.round( nT * this.nElements ); + if( nElements === 0 ) + { + return aPolyPath; + } + // check if we need to reset the clip path + if( this.nAlreadyAppendedElements >= nElements ) + { + this.nAlreadyAppendedElements = 0; + this.aClipPath = createEmptyPath(); + } + var nPos; + for( nPos = this.nAlreadyAppendedElements; nPos < nElements; ++nPos ) + { + aPoint = this.aPositionArray[nPos]; + aPath = this.aBasePath.cloneNode( true ); + aTransform = SVGIdentityMatrix.translate( aPoint.x, aPoint.y ); + aPath.matrixTransform( aTransform ); + aPolyPath.appendPath( aPath ); + } + + this.nAlreadyAppendedElements = nElements; + this.aClipPath.appendPath( aPolyPath ); + + return this.aClipPath.cloneNode( true ); +}; + + + /** Class AnimatedSlide * This class handle a slide element during a slide transition. * @@ -9603,7 +9762,9 @@ SlideTransition.prototype.parseElement = function() // subtype attribute this.eTransitionSubType = undefined; var sSubTypeAttr = aAnimElem.getAttributeNS( NSS['smil'], 'subtype' ); - if( sSubTypeAttr && aTransitionSubtypeInMap[ sSubTypeAttr ] ) + if( sSubTypeAttr === null ) + sSubTypeAttr = 'default'; + if( sSubTypeAttr && ( aTransitionSubtypeInMap[ sSubTypeAttr ] !== undefined ) ) { this.eTransitionSubType = aTransitionSubtypeInMap[ sSubTypeAttr ]; this.bIsValid = true; |