svgtopt/SVG/SVGImpl/src/SVGAnimateMotionElementImpl.cpp
changeset 46 88edb906c587
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/SVG/SVGImpl/src/SVGAnimateMotionElementImpl.cpp	Wed Nov 03 18:56:10 2010 +0200
@@ -0,0 +1,1308 @@
+/*
+* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  SVG Implementation source file
+ *
+*/
+
+
+#if !defined(__E32BASE_H__)
+#include <e32base.h>
+#endif
+#include <e32math.h>
+
+#include "SVGAnimateMotionElementImpl.h"
+
+#include "SVGElementImpl.h"
+#include "SVGDocumentImpl.h"
+#include "SVGSchemaData.h"
+
+#include "GfxGeneralPath.h"
+#include "GfxFlatteningPathIterator.h"
+#include "SVGPathDataParser.h"
+#include "SVGPointLexer.h"
+#include "SVGStringTokenizer.h"
+
+_LIT( AUTO, "auto" );
+_LIT( AUTOREVERSE, "auto-reverse" );
+_LIT( SEMICOLON, ";" );
+
+// *******************************************************
+// Constructor/deconstructor
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateMotionElementImpl* CSvgAnimateMotionElementImpl::NewL(  const TUint8 aElemID,
+																  CSvgDocumentImpl* aDoc )
+	{
+	CSvgAnimateMotionElementImpl*   self    = new ( ELeave )
+											  CSvgAnimateMotionElementImpl( aDoc );
+	CleanupStack::PushL( self );
+	self->ConstructL(  aElemID );
+	CleanupStack::Pop();
+
+	return self;
+	}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateMotionElementImpl* CSvgAnimateMotionElementImpl::NewLC(  const TUint8 aElemID,
+																   CSvgDocumentImpl* aDoc )
+	{
+	CSvgAnimateMotionElementImpl* self = new ( ELeave )
+											  CSvgAnimateMotionElementImpl( aDoc );
+	CleanupStack::PushL( self );
+	self->ConstructL(  aElemID );
+
+	return self;
+	}
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::ConstructL(  const TUint8 aElemID )
+	{
+	CSvgAnimationBase::ConstructL( aElemID );
+
+	iMotionPath = CGfxGeneralPath::NewL();
+	iAnimTime->SetCalMode( KAnimCalcModePaced ); // animateMotion has differenr default
+	iReqAttrFlag=KSVG_AMINATEMO_ELEMFLAG;
+	}
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateMotionElementImpl::~CSvgAnimateMotionElementImpl()
+    {
+	if ( iMotionPath )
+		{
+		delete iMotionPath;
+		iMotionPath = NULL;
+		}
+	if ( iPathIterator )
+		{
+		delete iPathIterator;
+		iPathIterator = NULL;
+		}
+    }
+
+// *******************************************************
+// Private
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateMotionElementImpl::CSvgAnimateMotionElementImpl( CSvgDocumentImpl* aDoc ) : CSvgAnimationBase( aDoc ),
+                                                                                       iCurrentSeg( 0,
+                                                                                                    0,
+                                                                                                    0,
+                                                                                                    0 ),
+                                                                                       //iIsValues( EFalse ),
+                                                                                       iPrevRotate(0)
+                                                                                       
+    {
+    iAttrId = KAtrTransform;
+    }
+
+// *******************************************************
+// From SVG DOM
+
+
+// *******************************************************
+// SVG Implementation
+
+
+// *******************************************************
+// From MSvgEventReceiver
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::ResetReferenceElementL()
+    {
+    if(iTargetElement != NULL )
+    	{
+    	if( ((iTargetElement->iAnimateAttrSet == NULL) ||
+    	    (iTargetElement->iAnimateAttrSet->Find(iAttrId) == KErrNotFound) ) )
+    		{
+    		if ( iInitDone )
+    			{
+    			iCheckFirstAnim= ETrue;
+    			SetToOriginalL();
+    			if( !(iTargetElement->iAnimateAttrSet) )
+    				{
+                    iTargetElement->iAnimateAttrSet = new (ELeave) RArray<TUint32>(1);
+                    }
+                iTargetElement->iAnimateAttrSet->AppendL((TUint32)iAttrId);
+    			}
+    		}
+        }
+    }
+// *******************************************************
+// From MXmlElement
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::SetAttributeL( const TDesC& aName,
+                                                  const TDesC& aValue )
+    {
+    _LIT( KTmpAttrName, "attributeName" );
+    _LIT( KTmpPath, "path" );
+    _LIT( KTmpRotate, "rotate" );
+    _LIT( KTmpFrom, "from" );
+    _LIT( KTmpTo, "to" );
+    _LIT( KTmpValues, "values" );
+    _LIT( KTmpBy, "by" );
+
+
+    if ( aName == KTmpAttrName )
+        {
+        // Ignore 'attributeName' attribute
+        }
+    else if ( aName == KTmpPath )
+        {
+        iMotionPath->Reset();
+		TSvgPathDataParser::ParsePathData( aValue, iMotionPath );
+
+        CGfxPathIterator*   itr;
+        TFloatFixPt              tmpcoords[6];
+        iMotionPath->GetPathIteratorL( &iIdentTransform, itr );
+        CleanupStack::PushL( itr );
+
+        while ( !itr->IsDone() )
+            {
+            switch ( itr->CurrentSegment( tmpcoords ) )
+                {
+                case EGfxSegMoveTo:
+                iToFloatX = tmpcoords[0];
+                iToFloatY = tmpcoords[1];
+                break;
+                case EGfxSegLineTo:
+                iToFloatX = tmpcoords[0];
+                iToFloatY = tmpcoords[1];
+                break;
+                case EGfxSegQuadTo:
+                iToFloatX = tmpcoords[2];
+                iToFloatY = tmpcoords[3];
+                break;
+                case EGfxSegCubicTo:
+                iToFloatX = tmpcoords[4];
+                iToFloatY = tmpcoords[5];
+                break;
+                case EGfxSegClose:
+                iToFloatX = tmpcoords[0]; //.
+                iToFloatY = tmpcoords[1];
+                }
+
+            itr->NextL();
+            }
+        iPathSeen = ETrue;
+        CleanupStack::PopAndDestroy();
+		if(iReqAttrFlag == KAtrSVGAmo && (iMotionPath->PointTypeArray())->Count() != 0 )
+			{
+			iReqAttrFlag = 0;
+			}
+        }
+	else if ( aName == KTmpRotate )
+		{
+		if ( aValue == AUTO )
+			{
+			iAnimMotionRotate = KAnimMotionRotateAuto;
+			}
+		else if ( aValue == AUTOREVERSE )
+			{
+			iAnimMotionRotate = KAnimMotionRotateAutoReverse;
+			}
+		else
+			{
+			TLex    lString ( aValue );
+			if (lString.Val( iAnimMotionRotate )!= KErrNone)
+				{
+				iAnimMotionRotate= 0;
+				}
+			if ( iAnimMotionRotate < 0 )
+				{
+					// Note: A problem may occur if the value is less than -3600
+	        iAnimMotionRotate += 3600;
+				}
+			iAnimMotionRotate %= 360;
+			}
+		}
+    else if ( aName == KTmpFrom )
+	    {
+		if ( ! iHaveValues )
+			{
+			iNoFrom = EFalse;
+			iMotionPath->Reset();
+			TSvgPointLexer  svgplex ( aValue );
+			TChar           com;
+			TFloatFixPt          x, y;
+
+            svgplex.GetNextPoint( com, x, y );
+            svgplex.Cleanup();
+
+			iOrgFromFloatX = iFromFloatX = x;
+			iOrgFromFloatY = iFromFloatY = y;
+			iMotionPath->MoveToL( x, y, ETrue );  // 'from' -> MoveTo
+			}
+
+		if(iReqAttrFlag == KAtrSVGAmo)
+			{
+			iReqAttrFlag = KAtrToBy;
+			}
+		else
+			{
+			iReqAttrFlag = 0;
+			}
+		}
+    else if ( aName == KTmpBy )
+	    {
+		if ( !iHaveTo )
+			{
+			iHaveBy = ETrue;
+			if(iReqAttrFlag == KAtrSVGAmo || iReqAttrFlag == KAtrToBy)
+				{
+				iReqAttrFlag = 0;
+				}
+		    if ( !iHaveValues )
+			    {
+	               TSvgPointLexer  svgplex ( aValue );
+	            TChar           com;
+		        TFloatFixPt          x, y;
+
+                svgplex.GetNextPoint( com, x, y );
+                svgplex.Cleanup();
+
+                if ( iNoFrom )
+	                {
+		            iToFloatX = x;
+			        iToFloatY = y;
+				    iNoFrom = EFalse;
+				    // this is taken from animate transforms.
+				   iAdditive = KAdditiveSum;
+				   iAdditiveOrg = KAdditiveSum;
+					}
+                else
+	                {
+		            iToFloatX = iFromFloatX + x;
+			        iToFloatY = iFromFloatY + y;
+				    }
+
+	            CGfxPathIterator*   itr;
+		        iMotionPath->GetPathIteratorL( &iIdentTransform, itr );
+			    CleanupStack::PushL( itr );
+
+				if ( itr->IsDone() )
+					{
+					TFloatFixPt lZero;
+					// If the animation path is empty, fill with default value.
+					iMotionPath->MoveToL( lZero, lZero, ETrue );
+					}
+				CleanupStack::PopAndDestroy( 1 ); // itr
+				iMotionPath->LineToL( x, y, ETrue );  // 'by' -> LineTo
+				}
+			}
+
+		if(iReqAttrFlag == KAtrSVGAmo && (iMotionPath->PointTypeArray())->Count() != 0 )
+			{
+			iReqAttrFlag = 0;
+			}
+	    }
+	else if ( aName == KTmpTo )
+		{
+		if ( !iHaveValues )
+			{
+
+			// this is taken from animate transforms.
+			if ( iNoFrom )
+               {
+	           iAdditive = KAdditiveSum;
+			   iAdditiveOrg = KAdditiveSum;
+			   }
+			TSvgPointLexer  svgplex ( aValue );
+			TChar           com;
+			TFloatFixPt          x, y;
+			iHaveTo = ETrue;
+            svgplex.GetNextPoint( com, x, y );
+            svgplex.Cleanup();
+
+            iToFloatX = x;
+			iToFloatY = y;
+			CGfxPathIterator*   itr;
+			iMotionPath->GetPathIteratorL( &iIdentTransform, itr );
+			CleanupStack::PushL( itr );
+			if ( itr->IsDone() )
+				{
+				TFloatFixPt lZero;
+				// If the animation path is empty, fill with default value.
+				// should this default be zero or object position
+				iMotionPath->MoveToL( lZero, lZero, ETrue );
+				}
+			CleanupStack::PopAndDestroy( 1 ); // itr
+			iMotionPath->LineToL( x, y, ETrue );  // 'to' -> LineTo
+			}
+
+		if(iReqAttrFlag == KAtrSVGAmo || iReqAttrFlag == KAtrToBy)
+			{
+			iReqAttrFlag = 0;
+			}
+		}
+	else if ( aName == KTmpValues )
+		{
+		// Process only if Path values have not been seen
+		if ( !iPathSeen )
+		    {
+    		TStringTokenizer    tkn     ( aValue, SEMICOLON );
+    		TBool               first   = ETrue;
+    		iHaveValues = ETrue;
+    		iNoFrom = EFalse; //.
+    		iMotionPath->Reset();
+    		while ( tkn.HasMoreTokens() ) // 'values' is a set of coordinates
+    			{
+    			TSvgPointLexer  svgplex ( tkn.NextToken() );
+    			TChar           com;
+    			TFloatFixPt          x, y;
+                svgplex.GetNextPoint( com, x, y );
+                svgplex.Cleanup();
+
+    			if ( first )
+    				{
+    				iMotionPath->MoveToL( x, y, ETrue );
+    				iOrgFromFloatX = iFromFloatX = x; //.
+    				iOrgFromFloatY = iFromFloatY = y;
+    				first = EFalse;
+    				}
+    			else
+    				{
+    				iMotionPath->LineToL( x, y, ETrue );
+    				}
+    			iToFloatX = x; //.
+    			iToFloatY = y;
+    			}
+
+    		if(iReqAttrFlag == KAtrSVGAmo || iReqAttrFlag == KAtrToBy)
+    			{
+    			iReqAttrFlag = 0;
+    			}
+		    }
+		}
+    else
+	    {
+		return CSvgAnimationBase::SetAttributeL( aName, aValue );
+		}
+
+	return KErrNone;
+    }
+
+// ---------------------------------------------------------------------------
+// From MSvgEventReceiver
+// ---------------------------------------------------------------------------
+TBool CSvgAnimateMotionElementImpl::ReceiveEventL( MSvgEvent* aEvent )
+    {
+    return CSvgAnimationBase::ReceiveEventProcL( aEvent, this );
+    }
+
+// ---------------------------------------------------------------------------
+// From CSvgAnimationBase
+// ---------------------------------------------------------------------------
+//
+TBool CSvgAnimateMotionElementImpl::AnimProcL( MSvgTimerEvent* aEvent )
+
+    {
+
+
+  if((iAnimStatus != KAnimActive) || iDoFreeze)
+	   {
+	   if(iFill== KAnimFillFreeze && !iDoFreeze && iAnimStatus == KAnimFinished)
+	   		{
+	   		// calculate the freeze value.
+	   		}
+	   else
+		   {
+		   CSvgAnimationBase::CheckForEndTimesAndFreezeL(this);
+		   return EFalse;
+		   }
+	   }
+    if ( ( iPathIterator == NULL ) || ( iPathIterator->IsDone() ) )
+		{
+        return EFalse;  // Already end of path. Nothing to do any more.
+		}
+
+    TFloatFixPt  nextPos, diff;
+    TFloatFixPt  zero    ( 0 );
+
+    // Get next position in [0..255] range
+    TInt32  animatetime; // Not used...
+    TInt32  valix, subanimtime;
+    iAnimTime->GetAnimTime( (aEvent->Time()-iNegativeBeginTime), animatetime, valix, subanimtime );
+
+    // Get next position in actual length
+    TFloatFixPt  v2;
+    if ( valix >= iValuesFloat->Count() - 1 )
+		{
+		valix= iValuesFloat->Count() - 1;
+        v2 = ( *iValuesFloat )[valix];
+		}
+    else
+		{
+        v2 = ( *iValuesFloat )[valix + 1];
+		}
+    nextPos = CSvgAnimationBase::BlendFloat( subanimtime,
+                                             ( *iValuesFloat )[valix],
+                                             v2 );
+
+    diff = nextPos - iCurrentPos;
+    TGfxSegType SegType;
+
+    while ( iSubPos + diff > iSubLength && !iPathIterator->IsDone() )
+        {
+        if ( iSubLength < zero )
+			{
+            iSubLength = zero;
+			}
+        TFloatFixPt  tmpcoords[6];
+        diff -= iSubLength - iSubPos;
+        iPathIterator->NextL();
+        SegType = iPathIterator->CurrentSegment( tmpcoords );
+        iCurrentSeg.iX1 = iCurrentSeg.iX2;
+        iCurrentSeg.iY1 = iCurrentSeg.iY2;
+        iCurrentSeg.iX2 = tmpcoords[0];
+        iCurrentSeg.iY2 = tmpcoords[1];
+
+        if ( SegType == EGfxSegMoveTo )
+			{
+            iSubLength = zero;
+			}
+        else
+			{
+            iSubLength = iCurrentSeg.Length();
+			}
+
+        iSubPos = zero;
+        }
+    iSubPos += diff;
+
+    // Calcualate or set rotation
+    TReal32 rot = 0.0f;
+    if ( iAnimMotionRotate < 0 )
+        {
+        TFloatFixPt  dx  = iCurrentSeg.iX1 - iCurrentSeg.iX2;
+        if ( dx == zero )
+        {
+
+			if( iAnimMotionRotate == KAnimMotionRotateAuto )
+			{
+				if(iPrevRotate == 0 || iPrevRotate >= 3.1415926f)
+					rot = 3.1415926f + 1.5707963f;
+				else
+					rot = 1.5707963f; // pi/2
+			}
+			else // AutoReverse
+			{
+				if(iPrevRotate >= 0 )
+					rot = 1.5707963f;
+				else
+					rot = -1.5707963f;
+
+            }
+		}
+        else
+            {
+            TReal   atan;
+            Math::ATan( atan, ( TReal32 )( iCurrentSeg.iY1 - iCurrentSeg.iY2 ), ( TReal32 )dx );
+            rot = ( TReal32 ) atan;
+			if ( iAnimMotionRotate == KAnimMotionRotateAuto )
+				{
+				rot += 3.1415926f;
+				}
+
+			}
+		iPrevRotate = rot;
+        }
+    else
+        {
+        rot = iAnimMotionRotate * 3.1415926f / 180.0f;
+        }
+
+    // Create transform
+    MSvgTransformList*  trList;
+    TInt32              matrixIndex;
+    iTargetElement->GetTransform( trList );
+    iTargetElement->GetAttributeIntL( KAtrAnimMotionMatrixIndex, matrixIndex );
+    // new position
+    TInt32  subalpha;
+    if ( iSubLength == zero )
+		{
+        subalpha = 0;
+		}
+    else
+		{
+        subalpha = ( TInt32 ) ( iSubPos / iSubLength * TFloatFixPt( 255 ) );  // need to make sure value does not exceed 0x7fff
+		}
+    if ( subalpha > 0xff )
+		{
+        subalpha = 0xff;
+		}
+    if ( subalpha < 0 )
+		{
+        subalpha = 0;
+		}
+
+    TFloatFixPt  trnsx, trnsy;
+    trnsx = CSvgAnimationBase::BlendFloat( subalpha,
+                                           iCurrentSeg.iX1,
+                                           iCurrentSeg.iX2 );
+    trnsy = CSvgAnimationBase::BlendFloat( subalpha,
+                                           iCurrentSeg.iY1,
+                                           iCurrentSeg.iY2 );
+
+    TGfxAffineTransform deltaTr = TGfxAffineTransform::GetTranslateInstance( trnsx,
+                                                                             trnsy );
+    if ( rot != 0.0f )
+        {
+        deltaTr.Rotate( rot );
+        }
+
+    // Set transform
+
+    if ( iAccumulate == KAccumSum ) //.
+        {
+        TGfxAffineTransform accumulateDeltaTr = TGfxAffineTransform::GetTranslateInstance( iFromFloatX - iOrgFromFloatX, iFromFloatY - iOrgFromFloatY);
+        deltaTr.Concatenate( accumulateDeltaTr );
+        }
+
+    if ( iAdditive == KAdditiveSum ) //.
+        {
+        TGfxAffineTransform curMatrix = trList->GetItem( matrixIndex );
+        curMatrix.Concatenate( deltaTr );
+        trList->ReplaceItem( curMatrix, matrixIndex );
+        }
+    else
+        {
+        trList->ReplaceItem( deltaTr, matrixIndex );
+
+        }
+	if(iFill== KAnimFillFreeze)
+		{
+	 	iEndMatrix = deltaTr;
+		}
+    // update current position
+    iCurrentPos = nextPos;
+
+	 	CSvgAnimationBase::CheckForEndTimesAndFreezeL(this);
+    return ETrue;
+    }
+
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::ResetAnimationL()
+    {
+    TFloatFixPt  tmpcoords[6];
+
+    // Path iterator
+    if ( iPathIterator )
+        {
+        delete iPathIterator;
+        iPathIterator = NULL;
+        }
+
+    iPathIterator = CGfxFlatteningPathIterator::NewL( iMotionPath,
+                                                      &iIdentTransform,
+                                                      3 );
+
+
+    // path length
+    iPathIterator->CurrentSegment( tmpcoords );
+    iCurrentSeg.iX1 = tmpcoords[0];
+    iCurrentSeg.iY1 = tmpcoords[1];
+    iCurrentSeg.iX2 = tmpcoords[0];
+    iCurrentSeg.iY2 = tmpcoords[1];
+
+    iSubLength = -1;
+    iCurrentPos = 0;
+    iSubPos = 0;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::InitAnimationL()
+    {
+	if(!iTargetElement)
+		{
+		// if target element is not found then remove it.
+		((CSvgDocumentImpl*)iOwnerDocument)->RemoveFromEventReceiverList(this);
+		((CSvgDocumentImpl*)iOwnerDocument)->Engine()->UpdatePresentation(1);
+		return;
+		}
+
+    TFloatFixPt len;
+    TFloatFixPt lx, ly;
+    TFloatFixPt dx, dy, int0x7f( KMAXFLOATFIX );
+    // Create values of distance from start point on motion path
+    TFloatFixPt  tmpcoords[6];
+        {
+        CGfxGeneralPath*    path    = CGfxGeneralPath::NewLC();
+        CGfxPathIterator*   itr;
+        iMotionPath->GetPathIteratorL( &iIdentTransform, itr );
+
+        CleanupStack::PushL( itr );
+        TFloatFixPt  length;
+		iValuesFloat->Reset();
+        while ( !itr->IsDone() )
+            {
+            switch ( itr->CurrentSegment( tmpcoords ) )
+                {
+                case EGfxSegMoveTo:
+                path->MoveToL( tmpcoords[0], tmpcoords[1], ETrue );
+                lx = tmpcoords[0];
+                ly = tmpcoords[1];
+                len = TSvgPathDataParser::PathLengthL( path );
+                break;
+                case EGfxSegLineTo:
+                path->LineToL( tmpcoords[0], tmpcoords[1], ETrue );
+                dx = lx - tmpcoords[0];
+                dy = ly - tmpcoords[1];
+                if ( dx > int0x7f || dy > int0x7f )
+                    {
+                    // calculate as integer
+                    TInt32 tmplen, tx, ty;
+                    tx = ( TInt32 ) dx;
+                    ty = ( TInt32 ) dy;
+	#ifdef SVG_FLOAT_BUILD
+                    tmplen = TFloatFixPt::Sqrt(tx * tx + ty * ty);
+	#else
+                    tmplen = TFloatFixPt::FixedSqrtGeneral( tx * tx + ty * ty, 0 );
+	#endif
+                    len += TFloatFixPt( tmplen );
+                    }
+                else
+                    {
+                    // calculate as TFixPt
+	
+                    len += TFloatFixPt::Sqrt( dx * dx + dy * dy );
+                    }
+                lx = tmpcoords[0];
+                ly = tmpcoords[1];
+
+                break;
+                case EGfxSegQuadTo:
+                path->QuadToL( tmpcoords[0],
+                               tmpcoords[1],
+                               tmpcoords[2],
+                               tmpcoords[3],
+                               ETrue );
+                len = TSvgPathDataParser::PathLengthL( path );
+                break;
+                case EGfxSegCubicTo:
+                path->CubicToL( tmpcoords[0],
+                                tmpcoords[1],
+                                tmpcoords[2],
+                                tmpcoords[3],
+                                tmpcoords[4],
+                                tmpcoords[5],
+                                ETrue );
+                len = TSvgPathDataParser::PathLengthL( path );
+                break;
+                case EGfxSegClose:
+                path->LineToL( tmpcoords[0], tmpcoords[1], ETrue );
+                len = TSvgPathDataParser::PathLengthL( path );
+				break;
+                }
+
+            length = len;
+            //length = TSvgPathDataParser::PathLengthL( path );
+            iValuesFloat->AppendL( length );
+            itr->NextL();
+            }
+        CleanupStack::PopAndDestroy( 2 ); // path, itr
+        }
+
+    CSvgAnimationBase::InitAnimationL();
+    if(!iKeyTimesPresent)
+    iAnimTime->CreateKeyTime( iMotionPath->PointTypeArray()->Count() );
+    iAnimTime->PrepareTimeL( iValuesFloat );
+	SetFillValueL();
+    this->ResetAnimationL();
+    }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetFillValueL()
+    {
+    iPrevRotate = 0;
+    MSvgTransformList* trList = NULL;
+    if ( iTargetElement )
+        {
+        ((CSvgElementImpl*)iTargetElement)->GetTransform( trList );
+        TInt32 matrixIndex = -1;
+        iTargetElement->GetAttributeIntL( KAtrAnimMotionMatrixIndex, matrixIndex );
+        ((CSvgElementImpl*)iTargetElement)->GetTransform( trList );
+        if ( trList && matrixIndex != -1 )
+            {
+            iFillMatrix = trList->GetItem(matrixIndex);
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetToOriginalL()
+    {
+    MSvgTransformList*  trList;
+    TInt32              matrixIndex;
+	if (iTargetElement == NULL)
+		{
+		return;
+		}
+    iTargetElement->GetAttributeIntL( KAtrAnimMotionMatrixIndex, matrixIndex );
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+
+
+        trList->ReplaceItem( iFillMatrix, matrixIndex );
+
+
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetToInitialValueL()
+    {
+    MSvgTransformList*  trList;
+    TInt32              matrixIndex;
+    iTargetElement->GetAttributeIntL( KAtrAnimMotionMatrixIndex, matrixIndex );
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+
+    if( iAdditive == KAdditiveSum)
+    	{
+        TGfxAffineTransform curMatrix = trList->GetItem( matrixIndex );
+        curMatrix.Concatenate(iFillMatrix);
+       	trList->ReplaceItem( curMatrix, matrixIndex );
+    	}
+    else
+    	{
+         trList->ReplaceItem( iFillMatrix, matrixIndex );
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetToEndValueL()
+    {
+    MSvgTransformList*  trList;
+    TInt32              matrixIndex;
+    iTargetElement->GetAttributeIntL( KAtrAnimMotionMatrixIndex, matrixIndex );
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+
+	 if( iAdditive == KAdditiveSum)
+    	{
+        TGfxAffineTransform curMatrix = trList->GetItem( matrixIndex );
+        curMatrix.Concatenate(iEndMatrix);
+       	trList->ReplaceItem( curMatrix, matrixIndex );
+    	}
+    else
+    	{
+         trList->ReplaceItem( iEndMatrix, matrixIndex );
+    	}
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetAccumulateValues()
+    {
+    TFloatFixPt              lDelta;
+	if(iHaveBy)
+		{
+
+		lDelta = iToFloatX - iFromFloatX;
+	    iToFloatX = iToFloatX + lDelta;
+	    iFromFloatX = iFromFloatX + lDelta;
+
+	    lDelta = iToFloatY - iFromFloatY;
+	    iToFloatY = iToFloatY + lDelta;
+	    iFromFloatY = iFromFloatY + lDelta;
+
+		}
+	else
+		{
+	    lDelta = iToFloatX - iFromFloatX;
+	    iFromFloatX = iToFloatX + iOrgFromFloatX;
+	    iToFloatX = iFromFloatX + lDelta;
+
+	    lDelta = iToFloatY - iFromFloatY;
+	    iFromFloatY = iToFloatY + iOrgFromFloatY;
+	    iToFloatY = iFromFloatY + lDelta;
+	    }
+    }
+
+// ---------------------------------------------------------------------------
+// From MXmlElementOpt
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::GetAttributePath( const TInt /* aNameId */,
+                                                     CGfxGeneralPath*& /* aValue */ )
+    {
+    return KErrNoAttribute;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::SetAttributePathL( const TInt aNameId,
+                                                      CGfxGeneralPath* aValue )
+    {
+    if ( aNameId == KAtrData )
+        {
+        iMotionPath->Reset();
+        CGfxPathIterator*   lIter   = NULL;
+        aValue->GetPathIteratorL( &iIdentTransform, lIter );
+        CleanupStack::PushL( lIter );
+        iMotionPath->AppendL( lIter );
+        CleanupStack::PopAndDestroy( 1 ); //lIter
+        }
+
+    return KErrNone;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::SetAttributePathRef( const TInt aNameId,
+                                              CGfxGeneralPath*&  aValue  )
+    {
+	iIsMotionPath= EFalse;
+    if ( aNameId == KAtrAnimateMotion )
+        {
+		if(iMotionPath)
+			{
+			delete iMotionPath;
+			iMotionPath= NULL;
+			}
+		iMotionPath= aValue;
+
+		if((iMotionPath->PointTypeArray())->Count() != 0 )
+			{
+			CGfxPathIterator*   itr = NULL;
+			TFloatFixPt              tmpcoords[6];
+			TRAPD( error,iMotionPath->GetPathIteratorL( &iIdentTransform, itr ) );
+			if (error!= KErrNone)
+				{
+				return error;
+				}
+
+
+
+			while ( !itr->IsDone() )
+				{
+				switch ( itr->CurrentSegment( tmpcoords ) )
+					{
+					case EGfxSegMoveTo:
+					iToFloatX = tmpcoords[0];
+					iToFloatY = tmpcoords[1];
+					break;
+					case EGfxSegLineTo:
+					iToFloatX = tmpcoords[0];
+					iToFloatY = tmpcoords[1];
+					break;
+					case EGfxSegQuadTo:
+					iToFloatX = tmpcoords[2];
+					iToFloatY = tmpcoords[3];
+					break;
+					case EGfxSegCubicTo:
+					iToFloatX = tmpcoords[4];
+					iToFloatY = tmpcoords[5];
+					break;
+					case EGfxSegClose:
+					iToFloatX = tmpcoords[0];
+					iToFloatY = tmpcoords[1];
+                    }
+
+                TRAPD( error, itr->NextL() );
+                if ( error != KErrNone )
+                    {
+                    delete itr;
+                    return KErrNone;
+                    }
+                }
+
+            delete itr;
+            itr= NULL;
+
+
+     		RArray<TFloatFixPt>* lArrayFix;
+			lArrayFix= iMotionPath->PointCoordsArrayAll();
+			if (lArrayFix)
+				{
+				iOrgFromFloatX = iFromFloatX = lArrayFix->operator[](0);
+				iOrgFromFloatY = iFromFloatY = lArrayFix->operator[](1);
+				}
+
+			}
+		}
+
+    else
+        {
+        return KErrNoAttribute;
+        }
+
+    return KErrNone;
+    }
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetAnimRotate(TInt16 aRotate)
+	{
+	iAnimMotionRotate= aRotate;
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::SetAttributeIntL( const TInt aNameId, const TInt32 aValue)
+{
+	if(aNameId == KAtrRotate)
+		{
+		iAnimMotionRotate = (TInt16)aValue;
+		return KErrNone;
+		}
+	return CSvgAnimationBase::SetAttributeIntL(aNameId,aValue);
+}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::GetAttributeIntL( const TInt aNameId, TInt32& aValue )
+{
+	if(aNameId == KAtrRotate)
+		{
+		aValue = (TInt)(iAnimMotionRotate);
+		return KErrNone;
+		}
+	return CSvgAnimationBase::GetAttributeIntL(aNameId,aValue);
+}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::SetAttributeFloatL(const TInt aNameId, TFloatFixPt aValue )
+{
+	return CSvgAnimationBase::SetAttributeFloatL(aNameId,aValue);
+}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateMotionElementImpl::GetAttributeFloat(const TInt aNameId, TFloatFixPt& aValue )
+{
+	return CSvgAnimationBase::GetAttributeFloat(aNameId,aValue);
+}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::ReInitializeAnimation()
+    {
+
+	if ( iAttrId == 0xffff )
+        return;
+
+	if( iCurrentRepeatCount > 0 && iAccumulate == KAccumSum )
+		{
+		iFromFloatX= iOrgFromFloatX;
+		iFromFloatY= iOrgFromFloatY;
+		iToFloatX= iOrgToFloatX;
+		iToFloatY= iOrgToFloatY;
+		}
+
+    CSvgAnimationBase::ReInitializeAnimation();
+
+	iCurrentSeg.iX1 = (TFloatFixPt) 0;
+	iCurrentSeg.iX2 = (TFloatFixPt) 0;
+	iCurrentSeg.iY1 = (TFloatFixPt) 0;
+	iCurrentSeg.iY2 = (TFloatFixPt) 0;
+	MSvgTransformList*  trList;
+	TInt32              matrixIndex = 0;
+
+	if (iTargetElement)
+		{
+		TRAPD(error ,iTargetElement->GetAttributeIntL( KAtrAnimMotionMatrixIndex, matrixIndex ));
+		if ( error != KErrNone )
+		   {
+		   // ignore trap error
+	      }
+		( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+		if( trList && (trList->NumberOfItems() >  matrixIndex) )
+			{
+			trList->ReplaceItem( TGfxAffineTransform(), matrixIndex );
+
+			trList->SetAdditive( iAdditive, matrixIndex );
+			}
+		}
+	iFillMatrix= TGfxAffineTransform();
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void  CSvgAnimateMotionElementImpl::SetOriginalValues_DOMReuse()
+	{
+	iOrgToFloatX= iToFloatX;
+	iOrgToFloatY= iToFloatY;
+    // calling base class function.
+	CSvgAnimationBase::SetOriginalValues_DOMReuse();
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+CGfxGeneralPath* CSvgAnimateMotionElementImpl::GetPathAttribute(TInt aAttributeId)
+	{
+	if(aAttributeId == KAtrPath)
+		{
+		return iMotionPath;
+		}
+	else
+		{
+		return CSvgAnimationBase::GetPathAttribute(aAttributeId);
+		}
+	}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetPathAttribute(TInt aAttributeId, CGfxGeneralPath* aPathHandle)
+{
+
+	if(aAttributeId == KAtrPath)
+		{
+		if(iMotionPath == aPathHandle)
+			{
+			return;
+			}
+		delete iMotionPath;
+		iMotionPath = aPathHandle;
+
+		CGfxPathIterator*   itr = NULL;
+        TFloatFixPt              tmpcoords[6];
+        TRAPD(error ,iMotionPath->GetPathIteratorL( &iIdentTransform, itr ));
+        if ( error != KErrNone )
+		   {
+		   // ignore trap error
+	       }
+
+		if(itr)
+			{
+        while ( !itr->IsDone() )
+            {
+            switch ( itr->CurrentSegment( tmpcoords ) )
+                {
+                case EGfxSegMoveTo:
+                iToFloatX = tmpcoords[0];
+                iToFloatY = tmpcoords[1];
+                break;
+                case EGfxSegLineTo:
+                iToFloatX = tmpcoords[0];
+                iToFloatY = tmpcoords[1];
+                break;
+                case EGfxSegQuadTo:
+                iToFloatX = tmpcoords[2];
+                iToFloatY = tmpcoords[3];
+                break;
+                case EGfxSegCubicTo:
+                iToFloatX = tmpcoords[4];
+                iToFloatY = tmpcoords[5];
+                break;
+                case EGfxSegClose:
+                iToFloatX = tmpcoords[0]; //.
+                iToFloatY = tmpcoords[1];
+                    }
+                TRAPD( error, itr->NextL() );
+                if ( error != KErrNone )
+                    {
+                    delete itr;
+                    return;
+                    }
+                }
+
+			delete itr;
+			}
+
+		RArray<TFloatFixPt>* lArrayFix;
+		lArrayFix= iMotionPath->PointCoordsArrayAll();
+		if (lArrayFix)
+			{
+			iOrgFromFloatX = iFromFloatX = lArrayFix->operator[](0);
+			iOrgFromFloatY = iFromFloatY = lArrayFix->operator[](1);
+			}
+
+		}
+	else
+		{
+		CSvgAnimationBase::SetPathAttribute(aAttributeId, aPathHandle);
+		}
+}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::Reset(MSvgEvent* aEvent)
+{
+	iIsUserSeek = ETrue;
+	// first call the animation base function.
+	TSvgTimerEvent* timerEvent  = ( TSvgTimerEvent* ) aEvent;
+	if((TInt32)timerEvent->Time() < iAbsoluteBeginTime)
+		{
+		// let it come to initial position.
+		((CSvgDocumentImpl*)iOwnerDocument)->iInitialDrawFlag = ETrue;
+		ReInitializeAnimation();
+		return;
+		}
+	TRAPD(error,CSvgAnimationBase::ResetL( aEvent, this));
+
+	if (error != KErrNone)
+	{
+		// error processing not processed
+		return;
+	}
+}
+
+
+/////////////////////////////////////////////
+MXmlElement* CSvgAnimateMotionElementImpl::CloneL(MXmlElement*
+aParentElement)
+	{
+	CSvgAnimateMotionElementImpl* newElement = CSvgAnimateMotionElementImpl::NewL(  this->ElemID(),
+																((CSvgDocumentImpl*)iOwnerDocument) );
+	CleanupStack::PushL( newElement );
+	newElement->iParentNode = aParentElement;
+	// copy the data
+	// end copying data from this class.
+	// this will get cloned setting the parent element to aParentElement;
+	newElement->iOwnerDocument = this->iOwnerDocument;
+	// set the target element this needs to be modified.
+	newElement->iTargetElement = (CSvgElementImpl*)aParentElement;
+	this->CopyL(newElement);
+	CleanupStack::Pop();
+	return newElement;
+	}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::CopyL(CSvgAnimateMotionElementImpl* aDestElement )
+    {
+	if(aDestElement)
+	{
+
+
+    // copy stuff from superclass
+    this->CSvgAnimationBase::CopyL(aDestElement);
+
+    // copy the reference to idoc (CSvgDocumentImpl)
+    aDestElement->iOwnerDocument = this->iOwnerDocument;
+
+    /*Need to check Test whether Copying is proper*/
+
+	aDestElement->iFillMatrix = this->iFillMatrix;
+	if(this->iMotionPath)
+		{
+		/*Motion Path and iPathIterator assignment needs to be checked.*/
+        aDestElement->iMotionPath->Reset();
+        aDestElement->iMotionPath->SetPointCoordsArrayL(this->iMotionPath->PointCoordsArrayAll());
+        aDestElement->iMotionPath->SetPointTypeArrayL(this->iMotionPath->PointTypeArray());
+        }
+	aDestElement->iIdentTransform = this->iIdentTransform;
+    aDestElement->iSubLength = this->iSubLength;
+    aDestElement->iCurrentPos = this->iCurrentPos;
+    aDestElement->iSubPos = this->iSubPos;
+    aDestElement->iCurrentSeg = this->iCurrentSeg;
+    aDestElement->iAnimMotionRotate = this->iAnimMotionRotate;
+    aDestElement->iEndMatrix = this->iEndMatrix;
+    //aDestElement->iIsValues = this->iIsValues;
+    aDestElement->iToFloatX = this->iToFloatX;
+    aDestElement->iToFloatY = this->iToFloatY;
+    aDestElement->iFromFloatX = this->iFromFloatX;
+    aDestElement->iFromFloatY = this->iFromFloatY;
+    aDestElement->iOrgFromFloatX = this->iOrgFromFloatX;
+    aDestElement->iOrgFromFloatY = this->iOrgFromFloatY;
+		// for DOM Reuse
+	aDestElement->iOrgToFloatX = this->iOrgToFloatX;
+    aDestElement->iOrgToFloatY = this->iOrgToFloatY;
+	aDestElement->iIsMotionPath = this->iIsMotionPath;
+
+	if(this->iPathIterator)
+		{
+		aDestElement->ResetAnimationL();
+		}
+	}
+   }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::DeactivateAnimation()
+{
+CSvgAnimationBase::DeactivateAnimation(this);
+}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimateMotionElementImpl::DoAnimProcL(MSvgEvent* aEvent)
+{
+return this->AnimProcL((MSvgTimerEvent*)aEvent);
+}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::SetAccumulateValuesForSetMediaTime()
+{
+if(iAccumulate == KAccumSum )
+		{
+		iFromFloatX= iOrgFromFloatX;
+		iFromFloatY= iOrgFromFloatY;
+		iToFloatX= iOrgToFloatX;
+		iToFloatY= iOrgToFloatY;
+
+		TInt i=0;
+		while(i < iCurrentRepeatCount )
+			{
+			SetAccumulateValues();
+			i++;
+			}
+		}
+}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateMotionElementImpl::Print( TBool aIsEncodeOn )
+{
+	if (!aIsEncodeOn)
+	{
+		#ifdef _DEBUG
+		RDebug::Printf("<animateMotion calcMode=\"hmm\" xlink:href=\"hmm\" path=\"hmm\" keyPoints=\"hmm\" rotate=\"%d\"/>",
+		/*Href(),*/ (int)iAnimMotionRotate);
+		#endif
+	}
+}
+
+