diff -r 000000000000 -r 88edb906c587 svgtopt/SVG/SVGImpl/src/SVGAnimateMotionElementImpl.cpp --- /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 +#endif +#include + +#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(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* 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* 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("", + /*Href(),*/ (int)iAnimMotionRotate); + #endif + } +} + +