svgtopt/SVG/SVGImpl/src/SVGAnimateTransformElementImpl.cpp
changeset 0 d46562c3d99d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/SVG/SVGImpl/src/SVGAnimateTransformElementImpl.cpp	Thu Jan 07 16:19:02 2010 +0200
@@ -0,0 +1,1175 @@
+/*
+* 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 "SVGAnimateTransformElementImpl.h"
+
+#include "SVGElementImpl.h"
+#include "SVGDocumentImpl.h"
+#include "SVGSchemaData.h"
+
+#include "SVGPointLexer.h"
+#include "SVGStringTokenizer.h"
+
+#include "GfxAffineTransform.h"
+
+_LIT( SEMICOLON, ";" );
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateTransformElementImpl* CSvgAnimateTransformElementImpl::NewL(  const TUint8 aElemID,
+																		CSvgDocumentImpl* aDoc )
+	{
+	CSvgAnimateTransformElementImpl*self    = new ( ELeave )
+											  CSvgAnimateTransformElementImpl( aDoc );
+
+	CleanupStack::PushL( self );
+	self->ConstructL(  aElemID );
+	CleanupStack::Pop();
+
+	return self;
+	}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateTransformElementImpl* CSvgAnimateTransformElementImpl::NewLC(  const TUint8 aElemID,
+																		 CSvgDocumentImpl* aDoc )
+	{
+	CSvgAnimateTransformElementImpl*self    = new ( ELeave )
+											  CSvgAnimateTransformElementImpl( aDoc );
+
+	CleanupStack::PushL( self );
+	self->ConstructL(  aElemID );
+
+	return self;
+	}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::ConstructL(  const TUint8 aElemID)
+	{
+	CSvgAnimationBase::ConstructL( aElemID );
+
+	// Initial length of values is 2 (from and to)
+	iTransformValues = new ( ELeave ) RArray<TMatrixData>( 2 );
+    TMatrixData mtrx;
+    iTransformValues->AppendL( mtrx );
+    iTransformValues->AppendL( mtrx );
+
+    iOrgTransformValues = new ( ELeave ) RArray<TMatrixData>( 2 );
+
+    iOrgTransformValues->AppendL( mtrx );
+    iOrgTransformValues->AppendL( mtrx );
+
+
+	iAccumMatrixData.iData[0] = 0;
+	iAccumMatrixData.iData[1] = 0;
+	iAccumMatrixData.iData[2] = 0;
+
+	iReqAttrFlag=KSVG_ANIMATETRANSFORM_ELEMFLAG;
+
+
+
+	}
+
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateTransformElementImpl::~CSvgAnimateTransformElementImpl()
+    {
+    if ( iTransformValues )
+		{
+        iTransformValues->Close();
+	    delete iTransformValues;
+	    iTransformValues = NULL;
+		}
+	if ( iOrgTransformValues )
+		{
+        iOrgTransformValues->Close();
+	    delete iOrgTransformValues;
+	    iOrgTransformValues = NULL;
+
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// Private
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimateTransformElementImpl::CSvgAnimateTransformElementImpl( CSvgDocumentImpl* aDoc ) : CSvgAnimationBase( aDoc ),
+
+                                                                                             iMatrixDataSize( 2 ),
+																							 iMultipleRendering (EFalse)
+    {
+    iDataType = KSvgTypeTranslate;
+    }
+
+// ---------------------------------------------------------------------------
+// From MSvgEventReceiver
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::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 CSvgAnimateTransformElementImpl::SetAttributeL( const TDesC& aName,
+                                                     const TDesC& aValue )
+    {
+    _LIT( KTmpAttrName, "attributeName" );
+    _LIT( KTmpTransform, "transform" );
+    _LIT( KTmpFrom, "from" );
+    _LIT( KTmpTo, "to" );
+    _LIT( KTmpBy, "by" );
+    _LIT( KTmpType, "type" );
+    _LIT( KTmpScale, "scale" );
+    _LIT( KTmpRotate, "rotate" );
+    _LIT( KTmpSkewX, "skewX" );
+    _LIT( KTmpSkewY, "skewY" );
+    _LIT( KTmpValues, "values" );
+    _LIT( KTmpGradientTransform, "gradientTransform");
+
+    	if ( !iTargetSet )
+			{
+			iTargetElement = ( CSvgElementImpl * ) ParentNode();// default is parent element
+			iTargetSet = ETrue;
+			}
+		   	TUint16 lElementId = 0;
+		if (iTargetElement)
+		    lElementId = iTargetElement->ElemID();
+       if ( aName == KTmpAttrName )
+	        {
+
+			if(iReqAttrFlag == KAtrSVGTrf)
+				{
+				iReqAttrFlag = KAtrType;
+				}
+			else
+				{
+				iReqAttrFlag = 0;
+				}
+	    	if( aValue == KTmpTransform &&
+				!(lElementId == KSvgRadialGradientElement || lElementId
+				 == KSvgLinearGradientElement)
+				 )
+				{
+				iAttrId = KAtrAnimateTransformAttrId;
+	       		return KErrNone;
+				}
+			else if (aValue == KTmpGradientTransform &&
+				(lElementId == KSvgRadialGradientElement || lElementId
+				 == KSvgLinearGradientElement))
+				{
+				 iAttrId = KAtrAnimateTransformAttrId;
+	       		 return KErrNone;
+				}
+			else if(aValue == KTmpGradientTransform) // Specifically for Xlink:href case
+				{
+				 iAttrId = KAtrGradientTransform;
+				 return KErrNone;
+				}
+			else
+	            {
+	            // value must be not be 'transform'
+	            iAttrId = 0xffff;
+	            return KErrNone;
+	            }
+	        }
+    else if ( aName == KTmpType )
+        {
+
+		if(iReqAttrFlag == KAtrSVGTrf)
+			{
+			iReqAttrFlag = KAtrAttributeName;
+			}
+		else
+			{
+			iReqAttrFlag = 0;
+			}
+
+        // Use iDataType to keep transformation type
+        if ( aValue == KTmpScale )
+            {
+            iDataType = KSvgTypeScale;
+            iMatrixDataSize = 2;
+            }
+        else if ( aValue == KTmpRotate )
+            {
+            iDataType = KSvgTypeRotate;
+            iMatrixDataSize = 3;
+            }
+        else if ( aValue == KTmpSkewX )
+            {
+            iDataType = KSvgTypeSkewX;
+            iMatrixDataSize = 1;
+            }
+        else if ( aValue == KTmpSkewY )
+            {
+            iDataType = KSvgTypeSkewY;
+            iMatrixDataSize = 1;
+            }
+        else
+            {
+            iDataType = KSvgTypeTranslate;  // default transformation
+            iMatrixDataSize = 2;
+            }
+        return KErrNone;
+        }
+    else if ( aName == KTmpFrom )
+        {
+        iNoFrom = EFalse;
+        // Processing for semi-colon separated data is needed
+        DesToMatrixData( aValue, ( *iTransformValues )[0] );
+        return KErrNone;
+        }
+    else if ( aName == KTmpTo )
+        {
+        iHaveTo = ETrue;
+
+        if ( iNoFrom )
+            {
+            iAdditive = KAdditiveSum;
+            iAdditiveOrg = KAdditiveSum;
+            }
+
+        // Processing for semi-colon separated data is needed
+        DesToMatrixData( aValue, ( *iTransformValues )[1] );
+		iAccumMatrixData.iData[0] = (*iTransformValues)[1].iData[0];
+		iAccumMatrixData.iData[1] = (*iTransformValues)[1].iData[1];
+		iAccumMatrixData.iData[2] = (*iTransformValues)[1].iData[2];
+        return KErrNone;
+        }
+    else if ( aName == KTmpBy )
+        {
+        if ( !iHaveTo )
+            {
+            TInt32  i;
+            DesToMatrixData( aValue, ( *iTransformValues )[1] );
+            iHaveBy = ETrue;
+
+            if(iNoFrom)
+                {
+                iAdditive = KAdditiveSum;
+                iAdditiveOrg = KAdditiveSum;
+                }
+            for ( i = 0; i < 3; i++ )
+                {
+                ( *iTransformValues )[1].iData[i] = ( *iTransformValues )[1].iData[i] +
+                                                    ( *iTransformValues )[0].iData[i];
+                }
+
+            }
+        return KErrNone;
+        }
+    else if ( aName == KTmpValues )
+        {
+        TStringTokenizer    tkn ( aValue, SEMICOLON );
+        iTransformValues->Reset();
+
+   		iHaveValues = ETrue;
+
+        iNoFrom = EFalse;
+
+        while ( tkn.HasMoreTokens() )
+            {
+            TMatrixData mtrx;
+            DesToMatrixData( tkn.NextToken(), mtrx );
+            iTransformValues->AppendL( mtrx );
+            }
+        TInt lTransformValuesCount = iTransformValues->Count();
+		if(lTransformValuesCount > 0)
+			{
+			iAccumMatrixData.iData[0] = (*iTransformValues)[lTransformValuesCount - 1].iData[0];
+			iAccumMatrixData.iData[1] = (*iTransformValues)[lTransformValuesCount - 1].iData[1];
+			iAccumMatrixData.iData[2] = (*iTransformValues)[lTransformValuesCount - 1].iData[2];
+			}
+
+        return KErrNone;
+        }
+
+    return CSvgAnimationBase::SetAttributeL( aName, aValue );
+    }
+
+// ---------------------------------------------------------------------------
+// From MSvgEventReceiver
+// ---------------------------------------------------------------------------
+TBool CSvgAnimateTransformElementImpl::ReceiveEventL( MSvgEvent* aEvent )
+    {
+    return CSvgAnimationBase::ReceiveEventProcL( aEvent, this );
+    }
+
+// ---------------------------------------------------------------------------
+// From CSvgAnimationBase
+// ---------------------------------------------------------------------------
+
+TBool CSvgAnimateTransformElementImpl::AnimProcL( MSvgTimerEvent* aEvent )
+
+    {
+
+
+  if((iAnimStatus != KAnimActive) || iDoFreeze)
+	   {
+	   if(iFill== KAnimFillFreeze && !iDoFreeze && iAnimStatus == KAnimFinished)
+	   		{
+
+	   		}
+	   else
+		   {
+		   CSvgAnimationBase::CheckForEndTimesAndFreezeL(this );
+		   return EFalse;
+		   }
+	   }
+    // No animation if 'from' or 'to' is not available
+    if ( iTransformValues->Count() < 2 )
+		{
+        return EFalse;
+		}
+
+    // Calc alpha from time [0-255]
+    TInt32  alpha;
+    TInt32  valix1, valix2, subanimtime;
+    TMatrixData mdata;
+
+    iAnimTime->GetAnimTime((aEvent->Time()-iNegativeBeginTime), alpha, valix1, subanimtime );
+
+ // check for the range of valix
+	if ( valix1 >= iTransformValues->Count() )
+		{
+        valix1 = iTransformValues->Count() - 1;
+		}
+
+
+    if ( iNoFrom && !iHaveBy ) //. This is to emulate Adobe.
+        {
+        if ( alpha > ( KTimeMax >> 1 ) )
+            {
+            subanimtime = KTimeMax;
+            }
+        else
+            {
+            subanimtime = 0;
+            return ETrue;
+            }
+        }
+
+    if ( valix1 >= iTransformValues->Count() - 1 )
+		{
+        valix2 = valix1;
+		}
+
+    else
+		{
+        valix2 = valix1 + 1;
+		}
+
+	mdata.iData[0] = BlendFloat( subanimtime,
+							   ( *iTransformValues )[valix1].iData[0],
+							   ( *iTransformValues )[valix2].iData[0] );
+	mdata.iData[1] = BlendFloat( subanimtime,
+							   ( *iTransformValues )[valix1].iData[1],
+							   ( *iTransformValues )[valix2].iData[1] );
+	mdata.iData[2] = BlendFloat( subanimtime,
+							   ( *iTransformValues )[valix1].iData[2],
+							   ( *iTransformValues )[valix2].iData[2] );
+    // Additive
+    /*
+     * !!!! Additive="replace" is not supported
+     * !!!! Additional implementation needed in MSvgTransformList
+     */
+
+    // Set value
+    TGfxAffineTransform deltaTr;
+    switch ( iDataType )
+        {
+        case KSvgTypeTranslate:
+        deltaTr = TGfxAffineTransform::GetTranslateInstance( mdata.iData[0],
+                                                             mdata.iData[1] );
+        break;
+        case KSvgTypeScale:
+        deltaTr = TGfxAffineTransform::GetScaleInstance( mdata.iData[0],
+                                                         mdata.iData[1] );
+        break;
+        case KSvgTypeRotate:
+        deltaTr = TGfxAffineTransform::GetRotateInstance( ( TReal32 )
+                                                          mdata.iData[0] * 3.1415926f /
+                                                          180.0f,
+                                                          mdata.iData[1],
+                                                          mdata.iData[2] );
+        break;
+        case KSvgTypeSkewX:
+        deltaTr = TGfxAffineTransform::GetShearInstance( ( TReal32 )
+                                                         mdata.iData[0]* 3.1415926f /
+                                                         180.0f,
+                                                         0.0f );
+        break;
+        case KSvgTypeSkewY:
+        deltaTr = TGfxAffineTransform::GetShearInstance( 0.0f,
+                                                         ( TReal32 )
+                                                         mdata.iData[0]* 3.1415926f /
+                                                         180.0f );
+        break;
+        }
+    MSvgTransformList*  trList;
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+    TInt32 matrixIndex;
+    ( ( CSvgElementImpl * ) iTargetElement )->GetAttributeIntL( KAtrAnimTransformMatrixIndex, matrixIndex );
+   if ( iAdditive == KAdditiveSum ) //.
+        {
+        if(iNoFrom && subanimtime == KTimeMax && !iHaveBy)
+	        {
+	        iTargetElement->SetOverwriteTransforms( ETrue );
+	        }
+		/*else
+	        {
+	        //if additive = sum and there is a from or a by then dont overwrite the transform
+	        iTargetElement->iOverwriteTransforms = EFalse;
+	        }*/
+	    if(iHaveTo && iNoFrom)
+	    {
+	    	iTargetElement->SetOverwriteTransforms(ETrue);
+	    	trList->ReplaceItem(deltaTr, matrixIndex);
+	    }
+	    else 
+	    {
+        TGfxAffineTransform curMatrix = trList->GetItem( matrixIndex );
+        curMatrix.Concatenate( deltaTr );
+        trList->ReplaceItem( curMatrix, matrixIndex );
+	    }
+
+        }
+    else
+        {
+        iTargetElement->SetOverwriteTransforms( ETrue );
+        trList->ReplaceItem( deltaTr, matrixIndex );
+
+        }
+    if(iFill == KAnimFillFreeze)
+	    {
+	    iEndMatrix = deltaTr;
+	    }
+	CSvgAnimationBase::CheckForEndTimesAndFreezeL(this );
+    return ETrue;
+    }
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::SetFillValueL()
+    {
+    MSvgTransformList*  trList;
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+     TInt32              matrixIndex;
+     iTargetElement->GetAttributeIntL( KAtrAnimTransformMatrixIndex, matrixIndex );
+    iFillMatrix = trList->GetItem(matrixIndex);
+    }
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::SetToOriginalL()
+    {
+    MSvgTransformList*  trList;
+	TInt32 matrixIndex;
+	iTargetElement->GetAttributeIntL( KAtrAnimTransformMatrixIndex, matrixIndex );
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+
+    trList->ReplaceItem( iFillMatrix /*TGfxAffineTransform()*/,
+                             matrixIndex );
+    iTargetElement->SetOverwriteTransforms( EFalse );
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::SetToInitialValueL()
+    {
+    MSvgTransformList*  trList;
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+    TInt32 matrixIndex;
+    iTargetElement->GetAttributeIntL( KAtrAnimTransformMatrixIndex, matrixIndex );
+
+    if( iAdditive == KAdditiveSum)
+    	{
+
+        TGfxAffineTransform curMatrix = trList->GetItem( matrixIndex );
+        curMatrix.Concatenate(iFillMatrix);
+       	trList->ReplaceItem( curMatrix, matrixIndex );
+    	}
+    else
+    	{
+    //	iTargetElement->iOverwriteTransforms = ETrue;
+         trList->ReplaceItem( iFillMatrix, matrixIndex );
+    	}
+
+
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::SetToEndValueL()
+    {
+    MSvgTransformList*  trList;
+    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+    TInt32 matrixIndex;
+ 	iTargetElement->GetAttributeIntL( KAtrAnimTransformMatrixIndex, matrixIndex );
+
+	 if( iAdditive == KAdditiveSum)
+    	{
+		if(iNoFrom &&  !iHaveBy)
+	        {
+	        iTargetElement->SetOverwriteTransforms( ETrue );
+	        }
+	        if(iHaveTo && iNoFrom)
+	        {
+	        	iTargetElement->SetOverwriteTransforms(ETrue);
+	        	trList->ReplaceItem(iEndMatrix, matrixIndex);
+	        }
+            else 
+            {
+        TGfxAffineTransform curMatrix = trList->GetItem( matrixIndex );
+        curMatrix.Concatenate(iEndMatrix);
+       	trList->ReplaceItem( curMatrix, matrixIndex );
+            }
+    	}
+    else
+    	{
+    	iTargetElement->SetOverwriteTransforms( ETrue );
+        trList->ReplaceItem( iEndMatrix, matrixIndex );
+    	}
+
+  }
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::InitAnimationL()
+    {
+
+    if(!iTargetElement)
+		{
+		// if target element is not found then remove it.
+		((CSvgDocumentImpl*)iOwnerDocument)->RemoveFromEventReceiverList(this);
+		((CSvgDocumentImpl*)iOwnerDocument)->Engine()->UpdatePresentation(1);
+		return;
+		}
+
+	if (!iHaveValues)
+		{
+		if (!iHaveTo && !iHaveBy)
+			{
+			((CSvgDocumentImpl*)iOwnerDocument)->RemoveFromEventReceiverList(this );
+            ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->UpdatePresentation(1);
+			}
+		}
+
+
+    CSvgAnimationBase::InitAnimationL();
+
+	if(iMultipleRendering)
+		{
+		return;
+		}
+
+    // Set keytime
+	iValuesFloat->Reset();
+    TInt count = iTransformValues->Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        iValuesFloat->AppendL( TFloatFixPt( i ) ); // create dummy scalar array
+        }
+    if(!iKeyTimesPresent)
+    iAnimTime->CreateKeyTime( iValuesFloat->Count() );
+    iAnimTime->PrepareTimeL( iValuesFloat );
+	SetFillValueL();
+
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::SetAccumulateValues()
+    {
+
+	if ( !iNoFrom)
+        {
+
+        if (  iHaveBy )
+	        {
+	        TMatrixData delta;
+
+			//0
+	        delta.iData[0] = ( *iTransformValues )[1].iData[0] -
+	                             ( *iTransformValues )[0].iData[0];
+
+	        ( *iTransformValues )[0].iData[0] = ( *iTransformValues )[1].iData[0];
+
+	        ( *iTransformValues )[1].iData[0] += delta.iData[0];
+
+			//1
+	        delta.iData[1] = ( *iTransformValues )[1].iData[1] -
+	                             ( *iTransformValues )[0].iData[1];
+
+	        ( *iTransformValues )[0].iData[1] = ( *iTransformValues )[1].iData[1];
+
+	        ( *iTransformValues )[1].iData[1] += delta.iData[1];
+
+			//2
+	        delta.iData[2] = ( *iTransformValues )[1].iData[2] -
+	                             ( *iTransformValues )[0].iData[2];
+
+	        ( *iTransformValues )[0].iData[2] = ( *iTransformValues )[1].iData[2];
+
+	        ( *iTransformValues )[1].iData[2] += delta.iData[2];
+
+	        }
+	        else
+		        {
+				TInt lTransformValuesCount = (*iTransformValues).Count();
+				for(int i=0;i<lTransformValuesCount;i++)
+					{
+					(*iTransformValues)[i].iData[0] += iAccumMatrixData.iData[0];
+					(*iTransformValues)[i].iData[1] += iAccumMatrixData.iData[1];
+					(*iTransformValues)[i].iData[2] += iAccumMatrixData.iData[2];
+					}
+				}
+        }
+	else
+		{
+		if (  iHaveBy )
+	        {
+	        TMatrixData delta;
+
+			//0
+	        delta.iData[0] = ( *iTransformValues )[1].iData[0] -
+	                             ( *iTransformValues )[0].iData[0];
+
+	        ( *iTransformValues )[0].iData[0] = ( *iTransformValues )[1].iData[0];
+
+	        ( *iTransformValues )[1].iData[0] += delta.iData[0];
+
+			//1
+	        delta.iData[1] = ( *iTransformValues )[1].iData[1] -
+	                             ( *iTransformValues )[0].iData[1];
+
+	        ( *iTransformValues )[0].iData[1] = ( *iTransformValues )[1].iData[1];
+
+	        ( *iTransformValues )[1].iData[1] += delta.iData[1];
+
+			//2
+	        delta.iData[2] = ( *iTransformValues )[1].iData[2] -
+	                             ( *iTransformValues )[0].iData[2];
+
+	        ( *iTransformValues )[0].iData[2] = ( *iTransformValues )[1].iData[2];
+
+	        ( *iTransformValues )[1].iData[2] += delta.iData[2];
+
+	        }
+
+		}
+
+    }
+
+
+// *******************************************************
+// AnimateTransformElementImpl specific methods
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::DesToMatrixData( const TDesC& aDes,
+                                                       TMatrixData& aMatrixData )
+    {
+    TSvgPointLexer  svgplex ( aDes );
+    TInt            i       = 0;
+
+    while ( !svgplex.IsDone() && i < 3 )
+        {
+        TChar   com;
+        TFloatFixPt  data;
+        TInt32  rslt    = svgplex.GetNext( com, data );
+        if ( rslt != KErrNone )
+            break;
+        aMatrixData.iData[i] = data;
+        i++;
+        }
+    svgplex.Cleanup();
+
+    // Support shortened data expression
+    if ( i < iMatrixDataSize )
+        {
+        TFloatFixPt  zero    ( 0 );
+        switch ( iDataType )
+            {
+            case KSvgTypeTranslate:
+            aMatrixData.iData[1] = zero;
+            break;
+            case KSvgTypeScale:
+            aMatrixData.iData[1] = aMatrixData.iData[0];
+            break;
+            case KSvgTypeRotate:
+
+            if ( (i + 1) < iMatrixDataSize )
+				{
+                aMatrixData.iData[1] = zero;
+				}
+
+            aMatrixData.iData[2] = zero;
+            break;
+            }
+        }
+     if( i > iMatrixDataSize)
+     	{
+     	// reset back everything. this is invalid value.
+     	TFloatFixPt  zero    ( 0 );
+     	aMatrixData.iData[0] = zero;
+     	aMatrixData.iData[1] = zero;
+     	aMatrixData.iData[2] = zero;
+     	}
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::ResetAnimationL()
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+
+void  CSvgAnimateTransformElementImpl::SetMatrixDataSize(TUint8 aValue)
+	{
+	iMatrixDataSize= aValue;
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TBool  CSvgAnimateTransformElementImpl::SetMatrixData( TInt aIndex, TMatrixData& aMatrix)
+	{
+	if ( iTransformValues && aIndex < iTransformValues->Count() )
+		{
+		for (TInt i=0; i<3; i++)
+			{
+			(iTransformValues->operator[](aIndex)).iData[i]= aMatrix.iData[i];
+			}
+		return ETrue;
+		}
+	else
+		{
+		return EFalse;
+		}
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+void  CSvgAnimateTransformElementImpl::SetTransformValues(RArray<TMatrixData>*&	aValues)
+	{
+	if (iTransformValues)
+		{
+		iTransformValues->Close();
+		delete iTransformValues;
+		iTransformValues= NULL;
+		}
+	iTransformValues= aValues;
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateTransformElementImpl::SetAttributeIntL( const TInt aNameId,const TInt32 aValue )
+	{
+	if(aNameId == KAtrType)
+		{
+		if ( aValue == KSvgTypeScale )
+            {
+            iDataType = KSvgTypeScale;
+            iMatrixDataSize = 2;
+            }
+        else if ( aValue == KSvgTypeRotate )
+            {
+            iDataType = KSvgTypeRotate;
+            iMatrixDataSize = 3;
+            }
+        else if ( aValue == KSvgTypeSkewX )
+            {
+            iDataType = KSvgTypeSkewX;
+            iMatrixDataSize = 1;
+            }
+        else if ( aValue == KSvgTypeSkewY )
+            {
+            iDataType = KSvgTypeSkewY;
+            iMatrixDataSize = 1;
+            }
+        else
+            {
+            iDataType = KSvgTypeTranslate;  // default transformation
+            iMatrixDataSize = 2;
+            }
+		return KErrNone;
+		}
+	return CSvgAnimationBase::SetAttributeIntL(aNameId,aValue);
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateTransformElementImpl::GetAttributeIntL( const TInt aNameId, TInt32& aValue )
+	{
+	if(aNameId == KAtrType)
+		{
+		aValue = iDataType;
+		return KErrNone;
+		}
+	return CSvgAnimationBase::GetAttributeIntL(aNameId,aValue);
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateTransformElementImpl::GetAttributeFloat(const TInt aNameId,TFloatFixPt& aValue )
+{
+	return CSvgAnimationBase::GetAttributeFloat(aNameId,aValue);
+}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+TInt CSvgAnimateTransformElementImpl::SetAttributeFloatL(const TInt aNameId,TFloatFixPt aValue )
+{
+	return CSvgAnimationBase::SetAttributeFloatL(aNameId,aValue);
+}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+// this function is for binary discrepancies
+void CSvgAnimateTransformElementImpl::SetAccumMatrix()
+{
+	if(iHaveTo)
+		{
+		iAccumMatrixData.iData[0] = (*iTransformValues)[1].iData[0];
+		iAccumMatrixData.iData[1] = (*iTransformValues)[1].iData[1];
+		iAccumMatrixData.iData[2] = (*iTransformValues)[1].iData[2];
+		}
+	else
+		{
+		if(!iNoFrom)
+			{
+			TInt lTransformValuesCount = iTransformValues->Count();
+			if(lTransformValuesCount > 0)
+				{
+				iAccumMatrixData.iData[0] = (*iTransformValues)[lTransformValuesCount - 1].iData[0];
+				iAccumMatrixData.iData[1] = (*iTransformValues)[lTransformValuesCount - 1].iData[1];
+				iAccumMatrixData.iData[2] = (*iTransformValues)[lTransformValuesCount - 1].iData[2];
+				}
+			}
+		}
+}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::ReInitializeAnimation()
+    {
+
+	if ( iAttrId == 0xffff )
+        return;
+
+    // Do not set Multiple Rendering flag if animation is not
+    // initialised. This allows the Key Times array in the anim
+    // time controller to be set correctly so that the 
+    // interpolation happens correctly.
+    if ( iInitDone )
+        {
+	    iMultipleRendering=  ETrue;        
+        }
+
+	if( iCurrentRepeatCount > 0 && iAccumulate == KAccumSum )
+		{
+		SetTransValues_DOMReuse();
+		}
+
+
+	CSvgAnimationBase::ReInitializeAnimation();
+
+    if(iTargetElement)
+	{
+		TInt32 matrixIndex = -1;
+		MSvgTransformList*  trList;
+		( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+
+		TGfxAffineTransform affineTransform;
+ 		TRAPD(error,iTargetElement->GetAttributeIntL( KAtrAnimTransformMatrixIndex, matrixIndex ));
+	    if(error == KErrNone)
+		    {
+		    ( ( CSvgElementImpl * ) iTargetElement )->GetTransform( trList );
+			if( trList && (trList->NumberOfItems() >  matrixIndex) )
+				{
+				trList->ReplaceItem(affineTransform,matrixIndex);
+				}
+			}
+
+		}
+
+		iFillMatrix= TGfxAffineTransform();
+
+	}
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void  CSvgAnimateTransformElementImpl::SetTransValues_DOMReuse()
+	{
+	if(iOrgTransformValues && iTransformValues)
+		{
+        iTransformValues->Reset();
+        
+        TInt orgTransformValCnt = iOrgTransformValues->Count();
+		for(TInt i=0; i<orgTransformValCnt; i++)
+			{
+			 TMatrixData lMatrix;
+			lMatrix.iData[0] = (*iOrgTransformValues)[i].iData[0];
+     		lMatrix.iData[1] = (*iOrgTransformValues)[i].iData[1];
+			lMatrix.iData[2] = (*iOrgTransformValues)[i].iData[2];
+
+			iTransformValues->Append((TMatrixData) lMatrix);
+			}
+		}
+	}
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+void  CSvgAnimateTransformElementImpl::SetOriginalValues_DOMReuse()
+	{
+
+	if(  iAccumulate == KAccumSum )
+		{
+		if(iTransformValues && iOrgTransformValues)
+			{
+			iOrgTransformValues->Reset();
+			
+			TInt transformValCnt = iTransformValues->Count();
+			for(TInt i=0; i<transformValCnt; i++)
+				{
+				 TMatrixData lMatrix;
+				lMatrix.iData[0] = (*iTransformValues)[i].iData[0];
+     			lMatrix.iData[1] = (*iTransformValues)[i].iData[1];
+				lMatrix.iData[2] = (*iTransformValues)[i].iData[2];
+
+				iOrgTransformValues->Append((TMatrixData) lMatrix);
+				}
+			}
+		}
+
+    // calling base class function.
+	CSvgAnimationBase::SetOriginalValues_DOMReuse();
+	}
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CGfxGeneralPath* CSvgAnimateTransformElementImpl::GetPathAttribute(TInt aAttributeId)
+	{
+	return CSvgAnimationBase::GetPathAttribute(aAttributeId);
+
+	}
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::SetPathAttribute(TInt aAttributeId, CGfxGeneralPath* aPathHandle)
+{
+
+		CSvgAnimationBase::SetPathAttribute(aAttributeId, aPathHandle);
+
+}
+// ---------------------------------------------------------------------------
+// Set the values in the dom .
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::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* CSvgAnimateTransformElementImpl::CloneL(MXmlElement*
+aParentElement)
+	{
+
+		CSvgAnimateTransformElementImpl* newElement = CSvgAnimateTransformElementImpl::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 CSvgAnimateTransformElementImpl::CopyL(CSvgAnimateTransformElementImpl* aDestElement )
+    {
+    // copy stuff from superclass
+    if(aDestElement)
+    {
+
+
+    this->CSvgAnimationBase::CopyL(aDestElement);
+    // copy the reference to idoc (CSvgDocumentImpl)
+    aDestElement->iOwnerDocument = this->iOwnerDocument;
+
+	aDestElement->iMultipleRendering = this->iMultipleRendering;
+	aDestElement->iMatrixDataSize = this->iMatrixDataSize;
+	aDestElement->iFillMatrix = this->iFillMatrix;
+	aDestElement->iEndMatrix = this->iEndMatrix;
+	TMatrixData lTemp;
+
+	TInt count = this->iTransformValues->Count() ;
+	aDestElement->iTransformValues->Reset();
+	for(TInt i=0; i<count; i++)
+		{
+        aDestElement->iTransformValues->AppendL(lTemp);
+		aDestElement->iTransformValues->operator[](i).iData[0] =
+this->iTransformValues->operator[](i).iData[0];
+		aDestElement->iTransformValues->operator[](i).iData[1] =
+this->iTransformValues->operator[](i).iData[1];
+		aDestElement->iTransformValues->operator[](i).iData[2] =
+this->iTransformValues->operator[](i).iData[2];
+		}
+	TInt count2 = this->iOrgTransformValues->Count();
+	aDestElement->iOrgTransformValues->Reset();
+	for(TInt i=0; i<count2; i++)
+        {
+        aDestElement->iOrgTransformValues->AppendL(lTemp);
+        aDestElement->iOrgTransformValues->operator[](i).iData[0] =
+this->iOrgTransformValues->operator[](i).iData[0];
+		aDestElement->iOrgTransformValues->operator[](i).iData[1] =
+this->iOrgTransformValues->operator[](i).iData[1];
+		aDestElement->iOrgTransformValues->operator[](i).iData[2] =
+this->iOrgTransformValues->operator[](i).iData[2];
+		}
+	aDestElement->iAccumMatrixData.iData[0] = this->iAccumMatrixData.iData[0];
+	aDestElement->iAccumMatrixData.iData[1] = this->iAccumMatrixData.iData[1];
+	aDestElement->iAccumMatrixData.iData[2] = this->iAccumMatrixData.iData[2];
+    }
+   }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::DeactivateAnimation()
+{
+CSvgAnimationBase::DeactivateAnimation(this);
+}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimateTransformElementImpl::DoAnimProcL(MSvgEvent* aEvent)
+{
+return this->AnimProcL((MSvgTimerEvent*)aEvent);
+}
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimateTransformElementImpl::SetAccumulateValuesForSetMediaTime()
+{
+if(iAccumulate == KAccumSum )
+		{
+
+		SetTransValues_DOMReuse();
+
+		SetAccumMatrix();
+		TInt i=0;
+		while(i < iCurrentRepeatCount )
+			{
+			// take care of the accum = sum.
+			SetAccumulateValues();
+			i++;
+			}
+		}
+}
+
+void CSvgAnimateTransformElementImpl::Print( TBool aIsEncodeOn )
+{
+	if (!aIsEncodeOn)
+	{
+		#ifdef _DEBUG
+		RDebug::Printf("<animateTransform attributeName=\"hmm\" attributeType=\"hmm\" type=\"%d\" from=\"%d\" to=\"%d\" dur=\"hmm\" additive=\"hmm\" />",
+		/*iDataType,*/ (int)iFromFloat, (int)iToFloat /*,iAccumulate*/);
+		#endif
+	}
+}