--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/SVG/SVGImpl/src/SVGAnimateMotionElementImpl.cpp Thu Jan 07 16:19:02 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
+ }
+}
+
+