--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/SVG/SVGImpl/src/SVGAnimationBase.cpp Wed Nov 03 18:56:10 2010 +0200
@@ -0,0 +1,5371 @@
+/*
+* 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 "SVGAnimationBase.h"
+#include "SVGElementImpl.h"
+#include "SVGDocumentImpl.h"
+#include "SVGStringTokenizer.h"
+#include "SVGPointLexer.h"
+#include "SVGPathDataParser.h"
+#include "SVGAnimTimingParser.h"
+#include "SVGPaintCssValueImpl.h"
+#include "SVGIntCssValueImpl.h"
+
+//CONSTANTS
+_LIT(KSEMICOLON, ";");
+
+// ---------------------------------------------------------------------------
+// No NewL or NewLC because this is abstract class
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::ConstructL( const TUint8 aElemID )
+ {
+ CSvgElementImpl::InitializeL( aElemID );
+
+ iAnimTime = CSvgAnimTimeController::NewL();
+ iValuesFloat = new ( ELeave ) RArray<TFloatFixPt>( 1 );
+ iValuesInt = new ( ELeave ) RArray<TInt32>( 1 );
+ iValuesPath = new ( ELeave ) RPointerArray<CGfxGeneralPath>( 1 );
+ // viewBox
+ iValuesViewBox = new ( ELeave ) RArray<TGfxRectangle2D>( 1 );
+ iEventList = new ( ELeave )CArrayFixFlat<TEventListItem>( 1 );
+ iEndTimeList = new ( ELeave )CArrayFixFlat<TEventListItem>( 1 );
+ /*Added to Support forward referencing*/
+ iSvgUriReferenceImpl = CSvgUriReferenceImpl::NewL();
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL(
+ this, KSvgEventMaskTimer );
+ }
+
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+
+CSvgAnimationBase::CSvgAnimationBase( CSvgDocumentImpl* aDoc ) :
+ iAnimStatus( KAnimNotActive ),
+ iTargetElement( NULL ),
+ iEndOffset( 0 ),
+ iRepeatCount( 1 ),
+ iRepeatEndValue ( 0 ) ,
+ iAbsoluteBeginTime ( 0 ),
+ iBeginTimeIndex( 0 ) ,
+ // iEndAccessKeyCode( 0 ),
+ iCurrentRepeatCount( 0 ),
+ iAttrId( 0xffff ),
+ iInitDone( EFalse ),
+ iTargetSet( EFalse ),
+ iNoFrom( ETrue ),
+ iHaveTo( EFalse ),
+ iHaveBy( EFalse ),
+ iHaveValues (EFalse),
+ iFill( KAnimFillRemove ),
+ iHadBegun( EFalse ),
+ iAnimRestart( KRestartAlways ),
+ iAccumulate( KAccumNone ),
+ iAdditive( KAdditivePass ),
+ iAdditiveOrg( KAdditiveReplace ),
+ iOverrideTime ( EFalse ),
+ iRepeatCountSet ( EFalse ),
+ iKeyTimesPresent(EFalse),
+ // iEndReferenceElemeId(NULL),
+ iIsUserSeek(EFalse),
+ iEndTimeIndex(0)
+
+
+ {
+ SetOwnerDocument(aDoc);
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgAnimationBase::~CSvgAnimationBase()
+ {
+ if ( iAnimTime )
+ {
+ delete iAnimTime;
+ iAnimTime = NULL;
+ }
+
+
+ if (iRepeatId)
+ {
+ delete iRepeatId;
+ iRepeatId = NULL;
+ }
+
+ if ( iValuesInt )
+ {
+ iValuesInt->Close();
+ delete iValuesInt;
+ iValuesInt = NULL;
+ }
+
+ if ( iValuesViewBox )
+ {
+ iValuesViewBox->Close();
+ delete iValuesViewBox;
+ iValuesViewBox = NULL;
+ }
+
+ if ( iValuesFloat )
+ {
+ iValuesFloat->Close();
+ delete iValuesFloat;
+ iValuesFloat = NULL;
+ }
+
+ if ( iOrgPath )
+ {
+ delete iOrgPath;
+ iOrgPath = NULL;
+ }
+
+ if ( iEndPath )
+ {
+ delete iEndPath;
+ iEndPath = NULL;
+ }
+
+ if ( iOrgFromPath )
+ {
+ delete iOrgFromPath;
+ iOrgFromPath = NULL;
+ }
+
+ if ( iFromPath )
+ {
+ delete iFromPath;
+ iFromPath = NULL;
+ }
+
+ if ( iToPath )
+ {
+ delete iToPath;
+ iToPath = NULL;
+ }
+
+ if ( iValuesPath )
+ {
+ iValuesPath->ResetAndDestroy();
+ iValuesPath->Close();
+ delete iValuesPath;
+ iValuesPath = NULL;
+ }
+
+ if ( iSvgUriReferenceImpl )
+ {
+ delete iSvgUriReferenceImpl;
+ iSvgUriReferenceImpl = NULL;
+ }
+
+
+ if ( iEventList )
+ {
+ TInt lCount = iEventList->Count();
+ for(TInt i= 0; i< lCount; i++)
+ {
+ if(iEventList->operator[](i).iReferenceElemeId)
+ {
+ delete iEventList->operator[](i).iReferenceElemeId;
+ iEventList->operator[](i).iReferenceElemeId = NULL;
+ }
+ }
+ delete iEventList;
+ iEventList = NULL;
+ }
+
+ if ( iEndTimeList )
+ {
+ TInt lCount2 = iEndTimeList->Count();
+ for(TInt i= 0; i< lCount2; i++)
+ {
+ if(iEndTimeList->operator[](i).iReferenceElemeId)
+ {
+ delete iEndTimeList->operator[](i).iReferenceElemeId;
+ iEndTimeList->operator[](i).iReferenceElemeId = NULL;
+ }
+ }
+
+ delete iEndTimeList;
+ iEndTimeList = NULL;
+ }
+
+ //remove this from the animation list
+ CSvgDocumentImpl* lOwnerDocument = (CSvgDocumentImpl*)iOwnerDocument;
+ if (lOwnerDocument)
+ {
+ TInt index = lOwnerDocument->iSvgAnimations.Find(this);
+
+ if (index != KErrNotFound)
+ {
+ lOwnerDocument->iSvgAnimations.Remove( index );
+ }
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TUint32 CSvgAnimationBase::SimpleDuration()
+ {
+ TUint32 lEndTime= KTimeIndefinite;
+ TUint32 lDur= KTimeIndefinite;
+
+ if(iAbsoluteBeginTime == (TInt32)KTimeIndefinite)
+ {
+ return KTimeIndefinite;
+ }
+ if ( iAnimTime->DurationTime() == 0 )
+ {
+ // If the animation's dur is specified as 0, then the Simple duration
+ // of this animation is 0. This is done so that the animation should not happen
+ return 0;
+ }
+
+ lEndTime = iAnimTime->EndTime();
+ if ( lEndTime <= iAnimTime->BeginTime() )
+ {
+ lEndTime= KTimeIndefinite;
+ }
+
+ if ( iRepeatCount == KRepeatCountMax )
+ {
+ if ( iAnimTime->RepeatDurationTime() == KTimeIndefinite )
+ {
+ lDur= KTimeIndefinite; // Neither are specified
+ }
+ else // RepeatDur was specified.
+ {
+ lDur= iAbsoluteBeginTime + iAnimTime->RepeatDurationTime();
+ }
+ }
+
+ else if( (iAnimTime->DurationTime() == KTimeIndefinite || iAnimTime->DurationTime() == KIndefiniteAnimationDuration)
+ && ( this->ElemID() != KSvgSetElement ) )
+ {
+ lDur= KTimeIndefinite;
+ return lDur;
+ }
+ else // RepeatCount was specified.
+ {
+ if ( iAnimTime->RepeatDurationTime() == KTimeIndefinite )
+ {
+ lDur= (TUint32) (iAbsoluteBeginTime + iAnimTime->DurationTime() * iRepeatCount);
+ }
+ else // Both are specified. Return the minimum time.
+ {
+ if ( iAnimTime->RepeatDurationTime() < ( iAnimTime->DurationTime() * iRepeatCount ) )
+ {
+ lDur= iAbsoluteBeginTime + iAnimTime->RepeatDurationTime();
+ }
+ else
+ {
+ lDur= (TUint32) (iAbsoluteBeginTime + iAnimTime->DurationTime() * iRepeatCount);
+ }
+ }
+ }
+
+ // should return the Minimum of end time and calculated duration
+ if(lDur <= lEndTime)
+ return lDur;
+ else
+ return lEndTime;
+
+
+ }
+TUint32 CSvgAnimationBase::CompleteDuration()
+ {
+ TUint32 lDur= KTimeIndefinite;
+
+ TUint32 lEndTime = iAnimTime->LastEndTime();
+ TUint32 lBeginTime = iAnimTime->LastBeginTime();
+
+ if(lBeginTime == (TInt32)KTimeIndefinite)
+ {
+ return KTimeIndefinite;
+ }
+ if ( iAnimTime->DurationTime() == 0 )
+ {
+ // If the animation's dur is specified as 0, then the Simple duration
+ // of this animation is 0. This is done so that the animation should not happen
+ return 0;
+ }
+
+
+ if ( lEndTime <= lBeginTime)
+ {
+ // When animation's end time is <= its begin time, it means that the
+ // animation should be treated as an indefinite animation and animation
+ // never becomes active
+ lEndTime = KTimeIndefinite;
+
+ }
+
+ if ( iRepeatCount == KRepeatCountMax )
+ {
+ if ( iAnimTime->RepeatDurationTime() == KTimeIndefinite )
+ {
+ lDur= KTimeIndefinite; // Neither are specified
+ }
+ else // RepeatDur was specified.
+ {
+ lDur= lBeginTime + iAnimTime->RepeatDurationTime();
+ }
+ }
+
+ else if( (iAnimTime->DurationTime() == KTimeIndefinite || iAnimTime->DurationTime() == KIndefiniteAnimationDuration)
+ && ( this->ElemID() != KSvgSetElement ) )
+ {
+ lDur= KTimeIndefinite;
+ return lDur;
+ }
+ else // RepeatCount was specified.
+ {
+ if ( iAnimTime->RepeatDurationTime() == KTimeIndefinite )
+ {
+ lDur= (TUint32) (lBeginTime + iAnimTime->DurationTime() * iRepeatCount);
+ }
+ else // Both are specified. Return the minimum time.
+ {
+ if ( iAnimTime->RepeatDurationTime() < ( iAnimTime->DurationTime() * iRepeatCount ) )
+ {
+ lDur= lBeginTime + iAnimTime->RepeatDurationTime();
+ }
+ else
+ {
+ lDur= (TUint32) (lBeginTime + iAnimTime->DurationTime() * iRepeatCount);
+ }
+ }
+ }
+
+ // should return the Minimum of end time and calculated duration
+ if(lDur <= lEndTime)
+ return lDur;
+ else
+ return lEndTime;
+
+
+ }
+
+
+// From SVG DOM / MElementTimeControl
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimationBase::BeginElementL()
+ {
+
+ SetBeginByEventL( this, ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() );
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimationBase::BeginElementAtL( TFloatFixPt aOffset )
+ {
+ TInt32 offset = aOffset.RawData() / KBeginElementOffsetRatio /* *1000/65536 */;
+ SetBeginByEventL( this, ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() + offset );
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimationBase::EndElement()
+ {
+ SetEndByEvent( this, ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() );
+
+
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimationBase::EndElementAt( TFloatFixPt aOffset )
+ {
+ TInt32 offset = aOffset.RawData() / 66 /* *1000/65536 */;
+
+ SetEndByEvent( this, ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() + offset );
+
+
+ return EFalse;
+ }
+
+
+// *******************************************************
+// SVG Implementation
+
+
+// *******************************************************
+// From MXmlElement
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgAnimationBase::SetAttributeL( const TDesC& aName, const TDesC& aValue )
+ {
+
+ // Before anything else set the target to parent
+ if ( !iTargetSet )
+ {
+ iTargetElement = ( CSvgElementImpl * ) ParentNode();// default is parent element
+ if (iTargetElement)
+ {
+ iTargetSet = ETrue;
+ }
+ }
+
+ _LIT( KTmpAttrName, "attributeName" );
+ _LIT( KTmpXlinkHref, "xlink:href" );
+ _LIT( KTmpBegin, "begin" );
+ _LIT( KTmpDur, "dur" );
+ _LIT( KTmpRepeatDur, "repeatDur" );
+ _LIT( KTmpEnd, "end" );
+ _LIT( KTmpFrom, "from" );
+ _LIT( KTmpTo, "to" );
+ _LIT( KTmpBy, "by" );
+ _LIT( KTmpFill, "fill" );
+ _LIT( KTmpRestart, "restart" );
+ _LIT( KTmpRepeatCount, "repeatCount" );
+ _LIT( KTmpAccumulate, "accumulate" );
+ _LIT( KTmpAdditive, "additive" );
+
+ _LIT( KTmpValues, "values" );
+ _LIT( KTmpCalcMode, "calcMode" );
+ _LIT( KTmpKeyTimes, "keyTimes" );
+ _LIT( KTmpKeySplines, "keySplines" );
+
+ _LIT( KTmpIndefinite, "indefinite" );
+
+
+ if ( SetIdandXmlbaseL( aName, aValue ) )
+ {
+ return KErrNone;
+ }
+
+
+ if ( aName == KTmpXlinkHref )
+ {
+ // STEP 1 - Get the reference element
+ // If the first char is '#' then remove it
+ // This is possible if coming from cXML parser and not CVG Decoder
+ TInt pos = aValue.Locate( '#' );
+ if ( pos != KErrNotFound && pos == 0 )
+ {
+ HBufC* tBufC = HBufC::NewLC( aValue.Length() );
+ TPtr tPtr = tBufC->Des();
+ tPtr.Copy( aValue );
+ tPtr.Delete( pos, 1 );
+ CSvgElementImpl *lElement = ( CSvgElementImpl * )
+ ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( tPtr );
+ if(this->SetXlinkAttributeL( aName, tPtr ))
+ {
+ if(lElement)
+ {
+ SetTarget(lElement);
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( 1 );
+ return KErrAnimateReferenceElementNotFound;
+ }
+ }
+ CleanupStack::PopAndDestroy( 1 );
+ }
+
+ if ( !iTargetElement )
+ {
+ iAttrId = 0xffff;
+ return KErrNoAttribute;
+ }
+ else if(( iTargetElement->ElemID() == KSvgRadialGradientElement
+ || iTargetElement->ElemID() == KSvgLinearGradientElement)
+ && (iAttrId == KAtrGradientTransform))
+ {
+ iAttrId = KAtrTransform;
+ }
+ GetAttrValueL();
+ return KErrNone;
+ }
+
+ if ( aName == KTmpAttrName )
+ {
+ iReqAttrFlag = 0;
+
+ iAnimStatus = KAnimNotActive;
+
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+ }
+
+ if ( !IsElementAttrs( aValue ) && !IsPresentationAttrs( aValue ) )
+ {
+ iAttrId = 0xffff; // Not supported attribute.
+ }
+ else
+ {
+ if(!iTargetElement)
+ {
+ iAttrId = 0xffff;
+ return KErrNoAttribute;
+ }
+ GetAttrValueL();
+ }
+ }
+ else if ( aName == KTmpBegin )
+ {
+ iIsBeginSet= ETrue;
+ if ( aValue == KTmpIndefinite )
+ {
+ iAnimTime->SetBeginTime( KTimeIndefinite );
+ iAbsoluteBeginTime = KTimeIndefinite;
+ }
+
+ else
+ {
+ TStringTokenizer tkn ( aValue, KSEMICOLON );
+ while ( tkn.HasMoreTokens() )
+ {
+ TPtrC lToken = tkn.NextToken();
+ CSvgAnimTimingParser* atParser = CSvgAnimTimingParser::NewLC( lToken, this );
+ TInt32 clockValue;
+ HBufC* lBeginSyncElementId = HBufC::NewL(lToken.Length());
+ TSvgEvent lBeginReferenceEvent;
+ TReal32 lRepeatBeginValue;
+ TPtr ptr = lBeginSyncElementId->Des();
+ atParser->Parse( ptr,
+ lBeginReferenceEvent,
+ clockValue,
+ lRepeatBeginValue,
+ ETrue);
+
+ TEventListItem tmp;
+ if ( lBeginSyncElementId->Length() <= 0 )
+ {
+ tmp.iTargetElement = iTargetElement;
+ tmp.iReferenceElemeId= NULL;
+ }
+ else
+ {
+ // get element by id and append its pointer.
+
+ // there can be an issue if the id is not found. in case of forward reference.
+ // for this we will store the id if it is not found at this time.
+ tmp.iTargetElement = ( CSvgElementImpl * )
+ ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( *lBeginSyncElementId );
+
+ if( tmp.iTargetElement == NULL)
+ {
+ // this indicates that this is a forward reference in case of begin.
+
+ tmp.iReferenceElemeId = lBeginSyncElementId->AllocL();
+ }
+ else
+ {
+ // otherwise the element is found and we
+ // do not need to keep iBeginReferenceElemeId so
+ // make it NULL;
+ tmp.iReferenceElemeId = NULL;
+ }
+ }
+ if ( clockValue < 0 ) // Himanshu:to check the negative begin value
+ {
+ iNegativeBeginTime = clockValue;
+
+ // adjusting the duration time if already set before
+ TInt32 aNewDurationTime = iAnimTime->GetDurationTime();
+ if ( aNewDurationTime != KTimeIndefinite )
+ {
+ aNewDurationTime += clockValue;
+ iAnimTime->SetDurationTime(aNewDurationTime);
+ }
+ // adjusting the end time if already set before
+ TInt32 aNewEndTime = iAnimTime->GetEndTime();
+ if ( aNewEndTime > 0 && aNewEndTime < KTimeIndefinite )
+ {
+ aNewEndTime += clockValue;
+ iAnimTime->SetEndTime(aNewEndTime);
+ }
+
+ clockValue = 0; // set clockValue to 0 if negative begin
+ }
+
+ tmp.iEvent = lBeginReferenceEvent;
+ tmp.iTime = clockValue;
+
+ switch ( lBeginReferenceEvent )
+ {
+ case ESvgEventKey:
+ {
+ iAnimTime->SetBeginTime( KTimeIndefinite );
+ iAbsoluteBeginTime = KTimeIndefinite;
+ tmp.iAccessKeyCode = atParser->AccekeyValue();
+ tmp.iOffset = clockValue;
+ tmp.iTargetElement = NULL;
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL( this,
+ KSvgEventMaskExternalUI );
+ }
+ break;
+ case ESvgEventWallClock:
+ {
+ // not supported yet
+ }
+ break;
+
+ case ESvgEventNone:
+ {
+ // Simple Offset-value
+ iAnimTime->AddBeginTime( clockValue );
+ iAbsoluteBeginTime = clockValue;
+ tmp.iTargetElement = NULL;
+ }
+ break;
+
+ case ESvgEventRepeatEvent:
+ {
+ iAnimTime->SetBeginTime( KTimeIndefinite );
+ iAbsoluteBeginTime = KTimeIndefinite;
+
+ tmp.iOffset = clockValue;
+ tmp.iRepeatValue = lRepeatBeginValue;
+ }
+ break;
+ default:
+ {
+ iAnimTime->SetBeginTime( KTimeIndefinite );
+ iAbsoluteBeginTime = KTimeIndefinite;
+ tmp.iTime = KTimeIndefinite;
+ tmp.iOffset = clockValue;
+
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL( this,
+ KSvgEventMaskInternal );
+ }
+ break;
+ }
+ delete lBeginSyncElementId;
+ iEventList->AppendL(tmp);
+ CleanupStack::PopAndDestroy( 1 ); // atParser
+ }
+ iAnimTime->SaveBeginTime();
+ }
+
+ if ( ( ((CSvgDocumentImpl*)iOwnerDocument)->Engine() && iAnimTime && ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() >= iAnimTime->BeginTime() )
+ || ( iAnimTime && ((CSvgDocumentImpl*)iOwnerDocument)->iTimeForJSR226 >= iAnimTime->BeginTime() ) )
+ {
+ iTargetElement->SetIsAnimating( ETrue );
+ SetIsAnimating( ETrue );
+ }
+
+ }
+ else if ( aName == KTmpDur )
+ {
+ if ( aValue == KTmpIndefinite )
+ {
+ iAnimTime->SetDurationTime( KTimeIndefinite );
+ }
+ else
+ {
+ CSvgAnimTimingParser* atParser = CSvgAnimTimingParser::NewLC( aValue, this );
+ TInt32 clockValue;
+ TLex lex ( aValue );
+ atParser->ParseClockValue( lex, clockValue );
+ CleanupStack::PopAndDestroy( 1 ); // atParser
+
+ if (clockValue >= 0)
+ {
+ if ( iNegativeBeginTime < 0 ) //Himanshu: adjusting the duration if negative begin time is given
+ {
+ clockValue += iNegativeBeginTime;
+ }
+ iAnimTime->SetDurationTime( clockValue );
+ }
+ else
+ {
+ iAnimTime->SetDurationTime( KTimeIndefinite );
+
+ if ( !iAnimTime->BeginTime() )
+ {
+ iAnimTime->SetBeginTime( KTimeIndefinite );
+ }
+ }
+ }
+ }
+ else if ( aName == KTmpRepeatDur )
+ {
+ if ( aValue == KTmpIndefinite )
+ {
+ iAnimTime->SetRepeatDurationTime( KTimeIndefinite );
+ // Set Repeat Count to max if not set
+ if ( ! iRepeatCountSet )
+ {
+ iRepeatCount = KRepeatCountMax;
+ }
+ }
+ else
+ {
+ CSvgAnimTimingParser* atParser = CSvgAnimTimingParser::NewLC( aValue, this );
+ TInt32 clockValue;
+ TLex lex ( aValue );
+ atParser->ParseClockValue( lex, clockValue );
+ CleanupStack::PopAndDestroy( 1 ); // atParser
+ // Set the repeat duration time only if the clock value
+ // is valid
+ if( clockValue != KTimeIndefinite )
+ {
+ iAnimTime->SetRepeatDurationTime( clockValue );
+
+ // Set Repeat Count to max if not set
+ if ( ! iRepeatCountSet )
+ {
+ iRepeatCount = KRepeatCountMax;
+ }
+ }
+ }
+ }
+ else if ( aName == KTmpEnd )
+ {
+ if ( aValue == KTmpIndefinite )
+ {
+ iAnimTime->SetEndTime( KTimeIndefinite );
+ }
+ else
+ {
+ TStringTokenizer tkn ( aValue, KSEMICOLON );
+ while ( tkn.HasMoreTokens() )
+ {
+ TPtrC lToken = tkn.NextToken();
+ CSvgAnimTimingParser* atParser = CSvgAnimTimingParser::NewLC( lToken, this );
+ TInt32 clockValue;
+
+
+ TBuf<28> lEndSyncElementId;
+
+ TSvgEvent lEndReferenceEvent;
+ TReal32 lRepeatEndValue;
+ atParser->Parse( lEndSyncElementId,
+ lEndReferenceEvent,
+ clockValue,
+ lRepeatEndValue,
+ EFalse);
+ TEventListItem tmp;
+
+ if ( iNegativeBeginTime < 0 ) //Himanshu: adjusting the end time if negative begin is given
+ {
+ clockValue += iNegativeBeginTime;
+ }
+ if ( lEndSyncElementId.Length() <= 0 )
+ {
+ tmp.iTargetElement = iTargetElement;
+ tmp.iReferenceElemeId= NULL;
+ }
+ else
+ {
+ // get element by id and append its pointer.
+
+ // there can be an issue if the id is not found. in case of forward reference.
+ // for this we will store the id if it is not found at this time.
+ tmp.iTargetElement = ( CSvgElementImpl * )
+ ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( lEndSyncElementId );
+
+ if( tmp.iTargetElement == NULL)
+ {
+ // this indicates that this is a forward reference in case of begin.
+
+ tmp.iReferenceElemeId = lEndSyncElementId.AllocL();
+ }
+ else
+ {
+ // otherwise the element is found and we
+ // do not need to keep iReferenceElemeId so
+ // make it NULL;
+ tmp.iReferenceElemeId = NULL;
+ }
+ }
+ tmp.iEvent = lEndReferenceEvent;
+ tmp.iTime = clockValue;
+ tmp.iRepeatValue = lRepeatEndValue;
+
+
+ switch ( lEndReferenceEvent )
+ {
+ case ESvgEventKey:
+ //iAnimTime->SetEndTime( KTimeIndefinite ); // same as indefinite
+ tmp.iAccessKeyCode = atParser->AccekeyValue();
+ tmp.iOffset = clockValue;
+ tmp.iTargetElement = NULL;
+
+ /*iEndAccessKeyCode = atParser->AccekeyValue(); */
+
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL( this,
+ KSvgEventMaskExternalUI );
+ break;
+
+ case ESvgEventWallClock:
+ // not supported yet
+ break;
+
+ case ESvgEventNone:
+ // Simple Offset-value
+ iAnimTime->AddEndTime( clockValue );
+ tmp.iTargetElement = NULL;
+ break;
+
+ default:
+ // <id>.<event> +/- <offeset>
+ //iAnimTime->SetEndTime( KTimeIndefinite ); // same as indifinite
+ /* iEndOffset = clockValue;*/
+
+ tmp.iTime = KTimeIndefinite;
+ tmp.iOffset = clockValue;
+
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL( this,
+ KSvgEventMaskInternal );
+ }
+ iEndTimeList->AppendL(tmp);
+ CleanupStack::PopAndDestroy( 1 ); // atParser
+ }
+ iAnimTime->SaveEndTime();
+ }
+
+ if ( ( ((CSvgDocumentImpl*)iOwnerDocument)->Engine() && iAnimTime && ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() > iAnimTime->EndTime() )
+ || ( iAnimTime && ((CSvgDocumentImpl*)iOwnerDocument)->iTimeForJSR226 > iAnimTime->EndTime() ) )
+ {
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+ }
+ }
+ else if ( aName == KTmpFrom )
+ {
+ iNoFrom = EFalse;
+ // parser needed
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ {
+
+ TBool lPercentage = EFalse;
+ if (aValue.Locate('%') != KErrNotFound)
+ {
+ lPercentage = ETrue;
+ }
+
+ TLex lString ( aValue );
+ TReal32 lVal;
+ if (lString.Val( lVal, '.' ) != KErrNone)
+ {
+ lVal=1;
+ }
+
+ if (lPercentage)
+ {
+ lVal = lVal / TReal32(100);
+ }
+
+ if(lVal>1)
+ {
+ lVal=1;
+ }
+ if(lVal<0)
+ {
+ lVal=0;
+ }
+ iOrgFromFloat = iFromFloat = lVal;
+ }
+ break;
+ case KSvgTypeGradientUnits:
+ {
+ if(aValue == _L("objectBoundingBox"))
+ {
+ iOrgFromInt = iFromInt = 1;
+ }
+ else if(aValue == _L("userSpaceOnUse"))
+ {
+ iOrgFromInt = iFromInt = 0;
+ }
+ }
+ break;
+ case KSvgTypeLength:
+ {
+ TLex string ( aValue );
+ TReal32 val;
+ if( string.Val( val, '.' ) != KErrNone)
+ {
+ val = 0;
+ }
+ iOrgFromFloat = iFromFloat = val;
+ }
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ {
+ if ( iOrgFromPath )
+ {
+ delete iOrgFromPath;
+ iOrgFromPath = NULL;
+ }
+ iOrgFromPath = CGfxGeneralPath::NewL();
+
+ // Destroy iFromPath first, because it was built before during init
+ if ( iFromPath )
+ {
+ delete iFromPath;
+ iFromPath = NULL;
+ }
+ iFromPath = CGfxGeneralPath::NewL();
+
+ if ( iAttrId == KAtrPoints ) //.
+ {
+ TSvgPathDataParser::ParsePointDataL( aValue, iOrgFromPath );
+ TSvgPathDataParser::ParsePointDataL( aValue, iFromPath );
+ }
+ else
+ {
+ TSvgPathDataParser::ParsePathData( aValue, iOrgFromPath );
+ TSvgPathDataParser::ParsePathData( aValue, iFromPath );
+ }
+ }
+ break;
+ case KSvgTypeSpreadMethod:
+ {
+ TInt pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindSpreadMethod(aValue);
+ if(pos != KErrNotFound)
+ {
+ iOrgFromInt = iFromInt = pos;
+ }
+ else
+ {
+ iOrgFromInt = iFromInt = 0;// default pad
+ }
+ }
+ break;
+ case KSvgTypeColor:
+ {
+ TLex lex ( aValue );
+ TInt32 colorValue;
+ if ( lex.Val( colorValue ) != KErrNone )
+ {
+ // means we have a URL color definition
+ iFromPaint = ((CSvgDocumentImpl*)iOwnerDocument)->iMemoryManager->GetCssPaintObjectL(aValue, ((CSvgElementImpl*)((CSvgDocumentImpl*)iOwnerDocument)->RootElement()));
+
+ if (iFromPaint)
+ {
+ MGfxPaint* lVal = iFromPaint->Value();
+ if (lVal)
+ {
+ iOrgFromInt = iFromInt = lVal->GetColor();
+ }
+ }
+ break;
+ }
+ }
+ // fall through for other color values.
+ case KSvgTypeInteger:
+ {
+ TLex lString ( aValue );
+ TInt32 lVal;
+ if (lString.Val( lVal ) != KErrNone)
+ {
+ lVal=0;
+ }
+ iOrgFromInt = iFromInt = lVal;
+ }
+ break;
+ case KSvgTypeDisplay:
+ {
+ if ( aValue == _L( "inline" ) )
+ {
+ iOrgFromInt = iFromInt = 0;
+ }
+ else if ( aValue == _L( "none" ) )
+ {
+ iOrgFromInt = iFromInt = 16;
+ }
+ else
+ {
+ //assume inherit on everything else
+ iOrgFromInt = iFromInt = (TInt32) KEnumInherit;
+ }
+ }
+ break;
+
+ case KSvgTypeTextAnchor:
+ {
+ TInt pos;
+ pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindTextAnchorEnum(aValue);
+ if(pos!= -1)
+ {
+ iOrgFromInt = iFromInt = pos ;
+ }
+ }
+ break;
+
+ case KSvgTypeVisibility:
+ {
+ if ( aValue == _L( "visible" ) )
+ {
+ iOrgFromInt = iFromInt = 0;
+ }
+ else if ( aValue == _L( "hidden" ) )
+ {
+ iOrgFromInt = iFromInt = 1;
+ }
+ }
+ break;
+
+ // viewBox
+ case KSvgTypeViewBox:
+ {
+ ParseViewBoxValue(aValue, iOrgFromViewBox);
+ iFromViewBox = iOrgFromViewBox;
+ }
+ break;
+ }
+ }
+ else if ( aName == KTmpTo )
+ {
+ iHaveTo = ETrue;
+ // parser needed
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ {
+ TBool lPercentage = EFalse;
+ if (aValue.Locate('%') != KErrNotFound)
+ {
+ lPercentage = ETrue;
+ }
+
+ TLex lString ( aValue );
+ TReal32 lVal;
+ if (lString.Val( lVal, '.' ) != KErrNone)
+ {
+ lVal=1;
+ }
+
+ if (lPercentage)
+ {
+ lVal = lVal / TReal32(100);
+ }
+
+ if(lVal>1)
+ {
+ lVal=1;
+ }
+ if(lVal<0)
+ {
+ lVal=0;
+ }
+ iToFloat = lVal;
+ break;
+ }
+ case KSvgTypeGradientUnits:
+ {
+ if(aValue == _L("objectBoundingBox"))
+ {
+ iToInt= 1;
+ }
+ else if(aValue == _L("userSpaceOnUse"))
+ {
+ iToInt = 0;
+ }
+ }
+ break;
+
+ case KSvgTypeTextAnchor:
+ {
+ TInt pos;
+ pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindTextAnchorEnum(aValue);
+ if(pos!= -1)
+ {
+ iToInt = pos ;
+ }
+ }
+ break;
+
+ case KSvgTypeLength:
+ {
+ TLex string ( aValue );
+ TReal32 val;
+ if( string.Val( val, '.' ) != KErrNone )
+ {
+ val = 0;
+ }
+ iToFloat = val;
+ }
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ {
+ CGfxPathIterator* itr1;
+ CGfxPathIterator* itr2;
+ TGfxAffineTransform idenTransform;
+
+ if ( iToPath )
+ {
+ delete iToPath;
+ iToPath = NULL;
+ }
+ iToPath = CGfxGeneralPath::NewL();
+
+ // Build a new path
+
+ if ( iAttrId == KAtrPoints )
+ {
+ TSvgPathDataParser::ParsePointDataL( aValue, iToPath );
+ }
+ else
+ {
+ TSvgPathDataParser::ParsePathData( aValue, iToPath );
+ }
+
+ iToPath->GetPathIteratorL( &idenTransform, itr1 );
+ CleanupStack::PushL( itr1 );
+
+ if ( iNoFrom )
+ {
+ iOrgPath->GetPathIteratorL( &idenTransform, itr2 );
+ }
+ else
+ {
+ iFromPath->GetPathIteratorL( &idenTransform, itr2 );
+ }
+ CleanupStack::PushL( itr2 );
+
+
+ TFloatFixPt tmpcoords1[6];
+ TFloatFixPt tmpcoords2[6];
+ while ( !itr1->IsDone() && !itr2->IsDone() )
+ {
+ TGfxSegType type1 = itr1->CurrentSegment( tmpcoords1 );
+ TGfxSegType type2 = itr2->CurrentSegment( tmpcoords2 );
+ if ( type1 != type2 )
+ {
+ // MISMATCH
+ // SHOULD END ANIMATION
+ break;
+ }
+
+ itr1->NextL();
+ itr2->NextL();
+ }
+ }
+ CleanupStack::PopAndDestroy( 2 ); // destroy itr1 & itr2
+ break;
+ case KSvgTypeSpreadMethod:
+ {
+ TInt pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindSpreadMethod(aValue);
+ if(pos != KErrNotFound)
+ {
+ iToInt = pos;
+ }
+ else
+ {
+ iToInt= 0;// default pad
+ }
+ }
+ break;
+
+ case KSvgTypeColor:
+ {
+ TLex lex ( aValue );
+ TInt32 colorValue;
+ if ( lex.Val( colorValue ) != KErrNone )
+ {
+ // means we have a URL color definition
+ iToPaint = ((CSvgDocumentImpl*)iOwnerDocument)->iMemoryManager->GetCssPaintObjectL(aValue, ((CSvgElementImpl*)((CSvgDocumentImpl*)iOwnerDocument)->RootElement()));
+
+ if (iToPaint)
+ {
+ MGfxPaint* lVal = iToPaint->Value();
+ if (lVal)
+ {
+ iToInt = lVal->GetColor();
+ }
+ }
+ break;
+ }
+ }
+ // fall through for rgb values
+ case KSvgTypeInteger:
+ {
+ TLex lString ( aValue );
+ TInt32 lVal;
+ if (lString.Val( lVal ) != KErrNone)
+ {
+ lVal=0;
+ }
+ iToInt = lVal;
+ }
+ break;
+ case KSvgTypeDisplay:
+ {
+ if ( aValue == _L( "inline" ) )
+ {
+ iToInt = 0;
+ }
+ else if ( aValue == _L( "none" ) )
+ {
+ iToInt = 16;
+ }
+ else
+ {
+ //assume inherit on everything else
+ iToInt = (TInt32) KEnumInherit;
+ }
+ }
+ break;
+ case KSvgTypeVisibility:
+ {
+ if ( aValue == _L( "visible" ) )
+ {
+ iToInt = 0;
+ }
+ else if ( aValue == _L( "hidden" ) )
+ {
+ iToInt = 1;
+ }
+ }
+ break;
+
+ // viewBox
+ case KSvgTypeViewBox:
+ {
+ ParseViewBoxValue(aValue, iToViewBox);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else if ( aName == KTmpBy )
+ {
+ iHaveBy = ETrue;
+
+ if(!iHaveTo)
+ {
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ {
+
+ TBool lPercentage = EFalse;
+ if (aValue.Locate('%') != KErrNotFound)
+ {
+ lPercentage = ETrue;
+ }
+
+ TLex lString ( aValue );
+ TReal32 lVal;
+ if (lString.Val( lVal, '.' ) != KErrNone)
+ {
+ lVal=1;
+ }
+
+ if (lPercentage)
+ {
+ lVal = lVal / TReal32(100);
+ }
+
+ if(lVal>1)
+ {
+ lVal=1;
+ }
+ if(lVal<0)
+ {
+ lVal=0;
+ }
+ if ( iNoFrom )
+ {
+ iAdditive = KAdditiveSum;
+ iAdditiveOrg = KAdditiveSum;
+ iToFloat = iFromFloat + TFloatFixPt( lVal );
+ iNoFrom = EFalse;
+ iOrgFromFloat = iFromFloat = (TReal32)0;
+ }
+ else
+ {
+ iToFloat = iFromFloat + TFloatFixPt( lVal );
+ }
+ break;
+ }
+ case KSvgTypeLength:
+ {
+ TLex string ( aValue );
+ TReal32 val;
+
+ if( string.Val( val, '.' ) != KErrNone )
+ {
+ val = 0;
+ }
+
+ if ( iNoFrom )
+ {
+ iAdditive = KAdditiveSum;
+ iAdditiveOrg = KAdditiveSum;
+ iToFloat = iFromFloat + TFloatFixPt( val );
+ iNoFrom = EFalse;
+ iOrgFromFloat = iFromFloat = (TReal32)0;
+ }
+ else
+ {
+ iToFloat = iFromFloat + TFloatFixPt( val );
+ }
+ }
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ {
+ if ( iToPath )
+ {
+ delete iToPath;
+ iToPath = NULL;
+ }
+ iToPath = CGfxGeneralPath::NewL();
+
+ if ( iAttrId == KAtrPoints ) //.
+ {
+ TSvgPathDataParser::ParsePointDataL( aValue, iToPath );
+ }
+ else
+ {
+ TSvgPathDataParser::ParsePathData( aValue, iToPath );
+ }
+ CGfxGeneralPath*lCurPath = CGfxGeneralPath::NewLC();
+ RArray<TFloatFixPt>* fromPoints;
+ RArray<TFloatFixPt>* toPoints = iToPath->PointCoordsArrayAll();
+
+ if ( iNoFrom )
+ {
+ fromPoints = iOrgPath->PointCoordsArrayAll();
+ lCurPath->SetPointTypeArrayL( iOrgPath->PointTypeArray() );
+ }
+ else
+ {
+ fromPoints = iFromPath->PointCoordsArrayAll();
+ lCurPath->SetPointTypeArrayL( iFromPath->PointTypeArray() );
+ }
+ TInt i = 0;
+ TInt fromCount = fromPoints->Count();
+ TInt toCount = toPoints->Count();
+
+ while ( i < fromCount && i < toCount)
+ {
+ toPoints->operator[]( i ) = fromPoints->operator[]( i ) +
+ toPoints->operator[]( i );
+ i++;
+ }
+ CleanupStack::PopAndDestroy( 1 ); // lCurPath
+ return ETrue;
+ }
+ case KSvgTypeColor:
+ {
+ TLex lString ( aValue );
+ TInt32 lVal;
+ if (lString.Val( lVal ) != KErrNone)
+ {
+ lVal=0;
+ }
+
+ if ( iNoFrom )
+ {
+ iToInt = lVal;
+ iToInt = AddColor( iPropInt, lVal);
+ iOrgFromInt = iFromInt = (TInt32) 0;
+ }
+ else
+ {
+ iToInt = AddColor( iFromInt, lVal);
+ }
+ }
+ break;
+ case KSvgTypeSpreadMethod:
+ {
+ TInt pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindSpreadMethod(aValue);
+ if(pos != KErrNotFound)
+ {
+ iToInt = pos;
+ }
+ else
+ {
+ iToInt= 0;// default pad
+ }
+
+ if ( iNoFrom )
+ {
+ iAdditive = KAdditiveSum;
+ iAdditiveOrg = KAdditiveSum;
+ iNoFrom = EFalse;
+ iOrgFromInt = iFromInt = (TInt32) 0;
+ }
+ // by here has no meaning just take the absolute value
+ }
+ break;
+ case KSvgTypeGradientUnits:
+ {
+ if(aValue == _L("objectBoundingBox"))
+ {
+ iToInt= 1;
+ }
+ else if(aValue == _L("userSpaceOnUse"))
+ {
+ iToInt = 0;
+ }
+ if ( iNoFrom )
+ {
+ iAdditive = KAdditiveSum;
+ iAdditiveOrg = KAdditiveSum;
+ iNoFrom = EFalse;
+ iOrgFromInt = iFromInt = (TInt32) 0;
+ }
+ // by here has no meaning just take the absolute value
+ }
+ break;
+ case KSvgTypeInteger:
+ {
+ TLex lString ( aValue );
+ TInt32 lVal;
+ if (lString.Val( lVal ) != KErrNone)
+ {
+ lVal=0;
+ }
+
+ if ( iNoFrom )
+ {
+ iAdditive = KAdditiveSum;
+ iAdditiveOrg = KAdditiveSum;
+ iToInt = lVal;
+ iNoFrom = EFalse;
+ iOrgFromInt = iFromInt = (TInt32) 0;
+ }
+ else
+ {
+ iToInt = iFromInt + lVal;
+ }
+ }
+ break;
+ case KSvgTypeVisibility:
+ {
+ if ( aValue == _L( "visible" ) )
+ {
+ iToInt = 0;
+ }
+ else if ( aValue == _L( "hidden" ) )
+ {
+ iToInt = 1;
+ }
+ }
+ break;
+ case KSvgTypeTextAnchor:
+ {
+ TInt pos;
+ pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindTextAnchorEnum(aValue);
+ if(pos!= -1)
+ {
+ iToInt = pos ;
+ }
+ }
+ break;
+ case KSvgTypeDisplay:
+ {
+ if ( aValue == _L( "inline" ) )
+ {
+ iToInt = 0;
+ }
+ else if ( aValue == _L( "none" ) )
+ {
+ iToInt = 16;
+ }
+ else
+ {
+ //assume inherit on everything else
+ iToInt = (TInt32) KEnumInherit;
+ }
+
+ }
+ break;
+
+ // viewBox
+ case KSvgTypeViewBox:
+ {
+
+ TGfxRectangle2D lVal;
+ ParseViewBoxValue(aValue, lVal);
+
+ TReal32 lX=0;
+ TReal32 lY=0;
+ TReal32 lW=0;
+ TReal32 lH=0;
+ lX = lVal.iX + iFromViewBox.iX;
+ lY = lVal.iY + iFromViewBox.iY;
+ lW = lVal.iWidth + iFromViewBox.iWidth;
+ lH = lVal.iHeight + iFromViewBox.iHeight;
+
+ TGfxRectangle2D result = TGfxRectangle2D( lX, lY, lW, lH );
+
+ if ( iNoFrom )
+ {
+ iAdditive = KAdditiveSum;
+ iAdditiveOrg = KAdditiveSum;
+ iToViewBox = result;
+ iNoFrom = EFalse;
+ iOrgFromViewBox = iFromViewBox = TGfxRectangle2D( 0, 0, 0, 0 );
+ }
+ else
+ {
+ iToViewBox = result;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ // repeatCount : numeric value | "indefinite"
+ // Specifies the number of iterations of the animation function. It can have the following attribute
+ // values:
+ // * numeric value
+ // This is a (base 10) "floating point" numeric value that specifies the number of iterations.
+ // It can include partial iterations expressed as fraction values. A fractional value describes a
+ // portion of the simple duration. Values must be greater than 0.
+ // * "indefinite"
+ // The animation is defined to repeat indefinitely (i.e. until the document ends).
+ else if ( aName == KTmpRepeatCount )
+ {
+ iRepeatCountSet = ETrue;
+ if ( aValue == KTmpIndefinite )
+ {
+ iRepeatCount = KRepeatCountMax;
+ }
+ else
+ {
+ TLex lexer ( aValue );
+ TReal32 val = 1.0f;
+ // Check for invalid number string or negative value
+ // Also check for value value followed by other characters, i.e ("6-4" or "3abd"
+ // Starting and ending whitespaces are chopped by lexer.
+ if ( lexer.Val( val, '.' ) != KErrNone || val <= 0 || lexer.Remainder().Length() > 0 )
+ {
+ val = 1.0f;
+ }
+ iRepeatCount = val;
+ }
+ }
+ else if ( aName == KTmpFill )
+ {
+ if ( aValue == _L( "freeze" ) )
+ {
+ iFill = KAnimFillFreeze;
+ }
+ }
+ else if ( aName == KTmpRestart )
+ {
+ if ( aValue == _L( "whenNotActive" ) )
+ {
+ iAnimRestart = KRestartWhenNotActive; //KAnimFillFreeze;
+ }
+ else if ( aValue == _L( "never" ) )
+ {
+ iAnimRestart = KRestartNever;
+ }
+ // Default is 'always'
+
+ }
+ else if ( aName == KTmpValues )
+ {
+ iHaveValues = ETrue;
+ iNoFrom = EFalse;
+
+ switch ( iDataType )
+ {
+
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ iValuesFloat->Reset();
+ break;
+
+ case KSvgTypeList:
+ case KSvgTypePath:
+ iValuesFloat->Reset();
+ iValuesPath->Reset(); // could be ResetAndDestroy()
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeColor:
+ case KSvgTypeInteger:
+ case KSvgTypeVisibility:
+ case KSvgTypeDisplay:
+ iValuesFloat->Reset();
+ iValuesInt->Reset();
+ break;
+
+ case KSvgTypeViewBox:
+ iValuesFloat->Reset();
+ iValuesViewBox->Reset();
+ break;
+
+ default:
+ break;
+ }
+
+ TStringTokenizer tkn ( aValue, KSEMICOLON );
+ while ( tkn.HasMoreTokens() )
+ {
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ {
+ TFloatFixPt KZero;
+ TFloatFixPt KOne( KFloatFixOne );
+ TFloatFixPt opacity;
+
+ TPtrC lToken = tkn.NextToken();
+
+ if ( TFloatFixPt::ConvertString( lToken, opacity ) != KErrNone )
+ {
+ opacity = KOne;
+ }
+ else
+ {
+
+ if ( lToken.Locate('%') != KErrNotFound )
+ {
+ opacity = opacity / TFloatFixPt(100);
+ }
+
+ if ( opacity < KZero )
+ opacity = KZero;
+ else if ( opacity > KOne )
+ opacity = KOne;
+ }
+ User::LeaveIfError( iValuesFloat->Append( opacity ) );
+ }
+ break;
+
+ case KSvgTypeLength:
+ User::LeaveIfError(iValuesFloat->Append( TFloatFixPt::ConvertString( tkn.NextToken() ) ));
+ break;
+
+ case KSvgTypeList:
+ case KSvgTypePath:
+ {
+ CGfxGeneralPath*tPath = CGfxGeneralPath::NewL();
+ CleanupStack::PushL(tPath);
+ if ( iAttrId == KAtrPoints ) //.
+ {
+ TSvgPathDataParser::ParsePointDataL( tkn.NextToken(), tPath );
+ }
+ else
+ {
+ TSvgPathDataParser::ParsePathData( tkn.NextToken(),
+ tPath );
+ }
+ User::LeaveIfError(iValuesPath->Append( tPath ));
+ CleanupStack::Pop();
+ }
+
+ break;
+ case KSvgTypeColor:
+ {
+ TSvgColor tColor ( KGfxColorNull );
+ TUint32 tempVal;
+
+
+
+
+ TBool col = tColor.GetStringL( tkn.NextToken(), tempVal );
+
+ if(!col)
+ {
+
+ tempVal = 0x000000; // set the default to black,
+ }
+ User::LeaveIfError(iValuesInt->Append( tempVal ));
+ }
+ break;
+
+ case KSvgTypeSpreadMethod:
+ {
+ TInt pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindSpreadMethod(tkn.NextToken() );
+ if(pos != KErrNotFound)
+ {
+ User::LeaveIfError(iValuesInt->Append( pos ));
+ }
+ else
+ {
+ User::LeaveIfError(iValuesInt->Append( 0));// default pad
+ }
+ }
+ break;
+
+ case KSvgTypeInteger:
+ User::LeaveIfError(iValuesInt->Append( TFloatFixPt::ConvertString( tkn.NextToken() ) ));
+ break;
+
+ case KSvgTypeVisibility:
+ {
+ TPtrC tmptk = tkn.NextToken();
+
+ if (tmptk.Find(_L( "visible" )) != KErrNotFound)
+ {
+ User::LeaveIfError(iValuesInt->Append( 0 ));
+ }
+ else if (tmptk.Find(_L( "hidden" )) != KErrNotFound)
+ {
+ User::LeaveIfError(iValuesInt->Append( 1 ));
+ }
+ else if ( tmptk.Find(_L("inherit")) != KErrNotFound )
+ {
+ User::LeaveIfError(iValuesInt->Append(KInherit));
+ }
+
+
+ }
+ break;
+ case KSvgTypeGradientUnits:
+ {
+ TPtrC tmptk = tkn.NextToken();
+ if (tmptk.Find(_L( "objectBoundingBox" )) != KErrNotFound)
+ {
+ User::LeaveIfError(iValuesInt->Append( 1));
+ }
+ else if (tmptk.Find(_L( "userSpaceOnUse" )) != KErrNotFound)
+ {
+ User::LeaveIfError(iValuesInt->Append( 0));
+ }
+
+ }
+ break;
+ case KSvgTypeDisplay:
+ {
+ TPtrC tmptk = tkn.NextToken();
+
+ if (tmptk.Find(_L( "inline" )) != KErrNotFound)
+ {
+ //found inline
+ User::LeaveIfError(iValuesInt->Append( 0 ));
+ }
+ else if (tmptk.Find(_L( "none" )) != KErrNotFound)
+ {
+ User::LeaveIfError(iValuesInt->Append( 16 ));
+ }
+ else
+ {
+ //assume inherit on everything else
+ User::LeaveIfError(iValuesInt->Append( (TInt32) KEnumInherit ));
+ //iValuesInt->Append( 0 );
+ }
+
+ }
+ break;
+
+ case KSvgTypeTextAnchor:
+ {
+
+ TInt pos;
+
+ pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->FindTextAnchorEnum(tkn.NextToken());
+
+ if(pos!= -1)
+ {
+ User::LeaveIfError(iValuesInt->Append( pos ));
+ }
+ }
+ break;
+
+ // viewBox attribute
+ case KSvgTypeViewBox:
+ {
+ TGfxRectangle2D lVal;
+ ParseViewBoxValue( tkn.NextToken(), lVal);
+ User::LeaveIfError(iValuesViewBox->Append( lVal ));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ else if ( aName == KTmpCalcMode )
+ {
+ if ( aValue == _L( "discrete" ) )
+ {
+ iAnimTime->SetCalMode( KAnimCalcModeDiscrete );
+ }
+ else if ( aValue == _L( "paced" ) )
+ {
+ iAnimTime->SetCalMode( KAnimCalcModePaced );
+ }
+ else if ( aValue == _L( "spline" ) )
+ {
+ iAnimTime->SetCalMode( KAnimCalcModeSpline );
+ // Indicate to the anim timing controller that
+ // the Spline mode is set
+ iAnimTime->SetIsSplineCalcMode( ETrue );
+ TPtrC lSplineValue( iAnimTime->SplineValue() );
+ if ( lSplineValue.Length() > 0 )
+ {
+ TStringTokenizer tkn2 (lSplineValue, KSEMICOLON);
+ iAnimTime->PrepareTimeL( NULL );
+
+ while ( tkn2.HasMoreTokens() )
+ {
+ TSvgPointLexer svgplex ( tkn2.NextToken() );
+ TChar com; // ingnor this
+ TFloatFixPt x1, y1, x2, y2;
+ svgplex.GetNextPoint( com, x1, y1 );
+ svgplex.GetNextPoint( com, x2, y2 );
+ svgplex.Cleanup();
+
+ TFloatFixPt tmpZero = TFloatFixPt(0);
+ TFloatFixPt tmpOne = TFloatFixPt(1);
+
+#ifdef SVG_FLOAT_BUILD
+ if ( ( x1 < ( tmpZero ) ) || ( x1 > ( tmpOne ) ) )
+ {
+ x1 = tmpZero;
+ }
+
+ if ( ( y1 < ( tmpZero ) ) || ( y1 > ( tmpOne ) ) )
+ {
+ y1 = tmpZero;
+ }
+
+ if ( ( x2 < ( tmpZero ) ) || ( x2 > ( tmpOne ) ) )
+ {
+ x2 = tmpOne;
+ }
+
+ if ( ( y2 < ( tmpZero ) ) || ( y2 > ( tmpOne ) ) )
+ {
+ y2 = tmpOne;
+ }
+#else
+ if ( ( x1.operator < ( tmpZero ) ) || ( x1.operator > ( tmpOne ) ) )
+ {
+ x1 = tmpZero;
+ }
+
+ if ( ( y1.operator < ( tmpZero ) ) || ( y1.operator > ( tmpOne ) ) )
+ {
+ y1 = tmpZero;
+ }
+
+ if ( ( x2.operator < ( tmpZero ) ) || ( x2.operator > ( tmpOne ) ) )
+ {
+ x2 = tmpOne;
+ }
+
+ if ( ( y2.operator < ( tmpZero ) ) || ( y2.operator > ( tmpOne ) ) )
+ {
+ y2 = tmpOne;
+ }
+#endif
+ iAnimTime->AddKeySplineL( x1, y1, x2, y2 );
+ }
+ }
+ }
+ else
+ {
+ iAnimTime->SetCalMode( KAnimCalcModeLinear );
+ }
+ }
+ else if ( aName == KTmpKeyTimes )
+ {
+ // if paced spec says we ignore keyTimes
+ if(iAnimTime->CalMode() != KAnimCalcModePaced)
+ {
+ iKeyTimesPresent = ETrue;
+ iAnimTime->ResetKeyTime();
+ TStringTokenizer tkn ( aValue, KSEMICOLON );
+ TInt32 first = 1;
+
+ TFloatFixPt current_time;
+
+ while ( tkn.HasMoreTokens() )
+ {
+ current_time = TFloatFixPt::ConvertString( tkn.NextToken() );
+
+ if( (first && current_time != (TFloatFixPt) 0.0f) ||
+ current_time < (TFloatFixPt) 0.0f ||
+ current_time > (TFloatFixPt) 1.0f)
+ { // put on this keyframe animation
+ // Spec says freeze on errors, but it
+ // also says ignore keytimes on error
+
+ iAnimTime->ResetKeyTime();
+ iKeyTimesPresent = EFalse;
+
+ break;
+ }
+
+ first = 0;
+ iAnimTime->AddKeyTime( current_time );
+ }
+
+ // last keytime value should be 1 for calcmode= linear or spline
+ if( (current_time != (TFloatFixPt)1.0f) &&
+ (iAnimTime->CalMode() != KAnimCalcModeDiscrete) )
+ {
+ iAnimTime->ResetKeyTime();
+ }
+ }
+ }
+ else if ( aName == KTmpKeySplines )
+ {
+ // Count number of splines
+ TInt32 splines = 0;
+ TStringTokenizer tkn1 ( aValue, KSEMICOLON );
+ while ( tkn1.HasMoreTokens() )
+ {
+ tkn1.NextToken();
+ splines++;
+ }
+ if(!iKeyTimesPresent)
+ iAnimTime->CreateKeyTime( splines + 1 );
+ if( iAnimTime->IsSplineCalcMode() )
+ {
+ iAnimTime->PrepareTimeL( NULL );
+ TStringTokenizer tkn2 ( aValue, KSEMICOLON );
+
+ while ( tkn2.HasMoreTokens() )
+ {
+ TSvgPointLexer svgplex ( tkn2.NextToken() );
+ TChar com; // ingnor this
+ TFloatFixPt x1, y1, x2, y2;
+ svgplex.GetNextPoint( com, x1, y1 );
+ svgplex.GetNextPoint( com, x2, y2 );
+ svgplex.Cleanup();
+
+ TFloatFixPt tmpZero = TFloatFixPt(0);
+ TFloatFixPt tmpOne = TFloatFixPt(1);
+
+#ifdef SVG_FLOAT_BUILD
+ if ( ( x1 < ( tmpZero ) ) || ( x1 > ( tmpOne ) ) )
+ {
+ x1 = tmpZero;
+ }
+
+ if ( ( y1 < ( tmpZero ) ) || ( y1 > ( tmpOne ) ) )
+ {
+ y1 = tmpZero;
+ }
+
+ if ( ( x2 < ( tmpZero ) ) || ( x2 > ( tmpOne ) ) )
+ {
+ x2 = tmpOne;
+ }
+
+ if ( ( y2 < ( tmpZero ) ) || ( y2 > ( tmpOne ) ) )
+ {
+ y2 = tmpOne;
+ }
+#else
+ if ( ( x1.operator < ( tmpZero ) ) || ( x1.operator > ( tmpOne ) ) )
+ {
+ x1 = tmpZero;
+ }
+
+ if ( ( y1.operator < ( tmpZero ) ) || ( y1.operator > ( tmpOne ) ) )
+ {
+ y1 = tmpZero;
+ }
+
+ if ( ( x2.operator < ( tmpZero ) ) || ( x2.operator > ( tmpOne ) ) )
+ {
+ x2 = tmpOne;
+ }
+
+ if ( ( y2.operator < ( tmpZero ) ) || ( y2.operator > ( tmpOne ) ) )
+ {
+ y2 = tmpOne;
+ }
+#endif
+ iAnimTime->AddKeySplineL( x1, y1, x2, y2 );
+ }
+ }
+ else
+ {
+ iAnimTime->SetSplineValueL( aValue );
+ }
+ }
+ else if ( aName == KTmpAccumulate )
+ {
+ if ( aValue == _L( "sum" ) )
+ {
+ iAccumulate = KAccumSum;
+ }
+ }
+ else if ( aName == KTmpAdditive )
+ {
+ if ( aValue == _L( "sum" ) )
+ {
+ iAdditive = KAdditiveSum;
+ iAdditiveOrg = KAdditiveSum;
+ }
+ }
+ else
+ {
+ if ( this->SetTestAttributeL( aName, aValue ) )
+ {
+ return KErrNone;
+ }
+ }
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From CSvgElementImpl
+// perform a deep clone of this object
+// ---------------------------------------------------------------------------
+MXmlElement* CSvgAnimationBase::CloneL(MXmlElement*)
+ {
+ return NULL;
+ }
+
+
+// ---------------------------------------------------------------------------
+// Animation specific common methods
+// ---------------------------------------------------------------------------
+TBool CSvgAnimationBase::ReceiveEventProcL( MSvgEvent* aEvent,
+ CSvgAnimationBase* aAnimElement )
+ {
+ if ( CSvgElementImpl::IsSVGEnginePaused() )
+ {
+ return EFalse;
+ }
+ TBool lGetTimerEvent = EFalse;
+ TInt32 lEngineTime =0;
+
+ TInt32 lCurTime = ((CSvgDocumentImpl *)(iOwnerDocument))->CurrentTime();
+ // Check if target attribute is valid
+ if ( iAttrId == 0xffff )
+ {
+ ((CSvgDocumentImpl*)iOwnerDocument)->RemoveFromEventReceiverList(this );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->UpdatePresentation(1);
+ return EFalse;
+ }
+
+ if ( !iInitDone )
+ {
+ iInitDone = ETrue;
+ aAnimElement->InitAnimationL();
+ if ( aAnimElement->iTargetElement == NULL )
+ {
+ return EFalse;
+ }
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddEventBeginTime( aAnimElement, iAbsoluteBeginTime, aAnimElement->iTargetElement );
+ }
+ else if ( aAnimElement->iTargetElement == NULL )
+ {
+ return EFalse;
+ }
+
+ // select event type
+ switch ( aEvent->EventType() )
+ {
+ case ESvgEngineEventTimerPrep :
+ return EFalse;
+
+
+ case ESvgEngineInternalEvent:
+ {
+ MSvgInternalEvent* event = ( MSvgInternalEvent* ) aEvent;
+ CSvgElementImpl* leventElement = (CSvgElementImpl*) ( event->ObjectAddress() );
+
+ CSvgAnimationBase* ltargetElement = (CSvgAnimationBase*)event->ObjectAddress();
+ TInt i;
+ TInt lCount = iEventList->Count();
+
+ if (event->SvgEvent() == ESvgEventRepeatEvent )
+ {
+ CSvgElementImpl* lElement = event->ObjectAddress();
+
+ if (lElement)
+ {
+ // NotifyAnimationsRepeatingOnThisOneL( lElement->Id(), ltargetElement);
+ }
+
+ }
+
+ for (i = 0; i < lCount; i++ )
+ {
+ if ( (iEventList->operator[](i)).iEvent != ESvgEventNone &&
+ (iEventList->operator[](i)).iEvent == event->SvgEvent() )
+ {
+ if ( leventElement == (iEventList->operator[](i)).iTargetElement )
+ {
+ switch(event->SvgEvent())
+ {
+ case ESvgEventRepeatEvent:
+ // Check whether the target element has repeated as many times
+ // as is defined for the begin of this element.
+ if ( ltargetElement->iCurrentRepeatCount == (TInt32) (iEventList->operator[](i)).iRepeatValue )
+ {
+ TReal32 lFractionalTime = (iEventList->operator[](i)).iRepeatValue - ((TInt32) (iEventList->operator[](i)).iRepeatValue);
+
+ SetBeginByEventL( aAnimElement,
+ (TInt32) (lCurTime +
+ (iEventList->operator[](i)).iOffset +
+ ltargetElement->Duration()*lFractionalTime), ETrue);
+
+ // Get THhe Engine's Current Media Time.
+ lEngineTime = ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme();
+
+ // calculate the start time.
+ TInt32 lStartTimeForThis = (TInt32) (lCurTime +
+ (iEventList->operator[](i)).iOffset +
+ ltargetElement->Duration()*lFractionalTime) ;
+
+ //compare BOTH.
+ if(lStartTimeForThis <= lEngineTime )
+ {
+ // indicates that this element should get the last timer
+ // event.
+ lGetTimerEvent = ETrue;
+ }
+
+ }
+ break;
+
+ default :
+ {
+
+ SetBeginByEventL( aAnimElement, lCurTime + (iEventList->operator[](i)).iOffset , ETrue);
+ // calculate the start time.
+ TInt32 lStartTimeForThis = (lCurTime + (iEventList->operator[](i)).iOffset ) ;
+
+ // see the Engine's Current media time.
+ lEngineTime = ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme();
+
+ // Compare BOTH.
+ /* if(lStartTimeForThis <= lEngineTime )
+ {
+ // indicates that this element should get the last timer
+ // event.
+ lGetTimerEvent = ETrue;
+ }*/
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ TInt lCount2 = iEndTimeList->Count();
+ for (i = 0; i < lCount2; i++ )
+ {
+
+ if ( (iEndTimeList->operator[](i)).iEvent != ESvgEventNone &&
+ (iEndTimeList->operator[](i)).iEvent == event->SvgEvent() )
+ {
+ if ( leventElement == (iEndTimeList->operator[](i)).iTargetElement )
+ {
+ switch(event->SvgEvent())
+ {
+ case ESvgEventRepeatEvent:
+ if ( ltargetElement->iCurrentRepeatCount == (TInt32) (iEndTimeList->operator[](i)).iRepeatValue )
+ {
+ TReal32 lFractionalTime = (iEndTimeList->operator[](i)).iRepeatValue - ((TInt32) (iEndTimeList->operator[](i)).iRepeatValue);
+
+ SetEndByEvent( aAnimElement,
+ (TInt32) (lCurTime +
+ (iEndTimeList->operator[](i)).iOffset +
+ ltargetElement->Duration()*lFractionalTime) );
+
+ }
+ break;
+
+ default :
+ {
+ SetEndByEvent( aAnimElement, lCurTime + (iEndTimeList->operator[](i)).iOffset );
+ }
+ break;
+ }
+ }
+ }
+
+ }
+
+ }
+ if(lGetTimerEvent)
+ {
+ // NO return this means that the Element should get the Last timer event.
+ break;
+ }
+ else
+ {
+ // this should not get the last timer event.
+ return EFalse;
+ }
+
+
+ case ESvgEngineEventKeyPress:
+ {
+ MSvgUiKeyEvent* event = ( MSvgUiKeyEvent* ) aEvent;
+ TInt i;
+
+ TInt lCount = iEventList->Count();
+ for (i = 0; i < lCount; i++ )
+ {
+
+ if ( (iEventList->operator[](i)).iEvent == ESvgEventKey &&
+ (iEventList->operator[](i)).iAccessKeyCode == event->KeyCode() )
+ {
+ SetBeginByEventL( aAnimElement, lCurTime + (iEventList->operator[](i)).iOffset, ETrue );
+ }
+ }
+ TInt lEndTimesCount = iEndTimeList->Count();
+ for (i = 0; i < lEndTimesCount; i++ )
+ {
+ if ( (iEndTimeList->operator[](i)).iEvent == ESvgEventKey &&
+ (iEndTimeList->operator[](i)).iAccessKeyCode == event->KeyCode() )
+ {
+ SetEndByEvent( aAnimElement, lCurTime + (iEndTimeList->operator[](i)).iOffset );
+ }
+ }
+
+ }
+ return EFalse;
+
+
+ case ESvgEngineEventTimer:
+ break;
+
+ default:
+ // mouse event is ignored here
+ return EFalse;
+ }
+
+
+ // Only timer event come thorugh after here
+ TSvgTimerEvent* timerEvent = ( TSvgTimerEvent* ) aEvent;
+ TSvgTimerEvent lLastEventTime(lEngineTime);
+
+ // this is treated as
+ if(lGetTimerEvent)
+ {
+ // send the last timer event.
+ timerEvent = &lLastEventTime;
+ }
+
+ // if( (!iOverrideTime) )
+ {
+ // This condition would not be satisfied for animations having one begin time
+ // E.g begin='5s' moves on to check if iAnimStatus is NotActive
+ if ( (iBeginTimeIndex+1 < iAnimTime->BeginTimesCount() ) && ( timerEvent->Time() >= iAnimTime->GetBeginTime( iBeginTimeIndex + 1 )))
+ {
+
+ if ( iAnimRestart == KRestartWhenNotActive && iAnimStatus == KAnimActive )
+ {
+ return ETrue; // Not start when active and restart="whenNotActive"
+ }
+ if ( iAnimRestart == KRestartNever && iHadBegun )
+ {
+ return ETrue; // Not start when anim had begun and if restart="never"
+ }
+ iBeginTimeIndex++;
+ iAnimTime->SetBeginTime( iAnimTime->GetBeginTime( iBeginTimeIndex ));
+ // added for setting proper end time
+ iAbsoluteBeginTime= iAnimTime->GetBeginTime( iBeginTimeIndex );
+ iAnimStatus = KAnimNotActive;
+
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+ }
+ iAnimTime->GetNextEndTime(iAnimTime->BeginTime());
+
+ TUint32 lSimpleDur= SimpleDuration();
+ if(lSimpleDur != KTimeIndefinite)
+ {
+ iAnimTime->SetEndTime( lSimpleDur );
+ }
+
+ // in case of multiple begin times we need to sort the list again.
+ ((CSvgDocumentImpl*)iOwnerDocument)->iInitSortList=ETrue;
+ }
+ }
+
+ if ( iAnimStatus == KAnimNotActive )
+ {
+ // Animation element becomes active only if current time exceeds
+ // the anim's begin time and its duration is not indefinite
+ if ( timerEvent->Time() >= iAnimTime->BeginTime() )
+ {
+ // iHasEnded = EFalse;
+ // start animation
+ iAnimStatus = KAnimActive;
+ iDoFreeze = EFalse;
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( ETrue );
+ SetIsAnimating( ETrue );
+ }
+ if ((this->ElemID() == KSvgAnimateElement) ||
+ (this->ElemID() == KSvgAudioElement) ||
+ (this->ElemID() == KSvgMediaAnimationElement ))
+ {
+ // this will be used to calculate the from values again
+ iHadBegun = EFalse;
+ }
+ else
+ {
+ iHadBegun = ETrue;
+ }
+ iAdditive = iAdditiveOrg;
+ iCurrentRepeatCount= 0;
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->NotifyAnimationStarted();
+
+ //Triggers internal begin event so that animations dependent on this would get the events
+ TSvgInternalEvent event ( ESvgEventBeginEvent, this,iAnimTime->BeginTime() );
+
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &event );
+
+ }
+ else
+ {
+ iAdditive = KAdditivePass;
+ }
+ }
+
+ if ( iAnimStatus == KAnimActive )
+ {
+ // if end time less than the simple duration
+
+ // DurationTime() shall return the duration set in svg
+ // E.g begin="0s" dur="10s" repeatCount='3' returns DurationTime() 10000,
+ // repeating of the animation would be handled while checking done
+ // before setting iAnimStatus to KAnimFinished. (see if ( iAnimStatus == KAnimEnd ))
+ if ( iAnimTime->DurationTime() != KTimeIndefinite
+ && timerEvent->Time() >= iAnimTime->BeginTime() + iAnimTime->DurationTime() )
+ {
+ // end animation
+ iAnimStatus = KAnimEnd;
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+
+ }
+ }
+ // any endtime got from simpleDuration, EndTime values in svg content, event based endtimes
+ // E.g begin="0s" dur="10s" repeatCount='3' returns EndTime() 30000,
+ if ( timerEvent->Time() >= iAnimTime->EndTime() )
+ {
+ // end animation
+ iAnimStatus = KAnimEnd;
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+ }
+ }
+
+ }
+
+ if ( iAnimStatus == KAnimEnd )
+ {
+
+ //Check if animation is finished
+ // Check 1. repeatcount reached
+ // 2. Repeatduration valid and reached
+ // 3. Endtime reached
+ if (( ( iCurrentRepeatCount >= iRepeatCount )||
+
+ ( ( iAnimTime->RepeatDurationTime() != KTimeIndefinite )&&
+ ( iRepeatCount == KRepeatCountMax )&&
+ ( timerEvent->Time() >= iAbsoluteBeginTime + iAnimTime->RepeatDurationTime() ) ) )
+
+ || timerEvent->Time() >= iAnimTime->EndTime()
+ )
+ {
+ iEndTimeIndex++;
+ TInt32 LEndTIme = lCurTime;
+
+ iAnimTime->SetEndTime(KTimeIndefinite);
+ iAnimStatus = KAnimFinished;
+
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+ }
+
+ iOverrideTime = EFalse;
+
+ // if its begin depends on its end than it might create a problem.
+ if(!iIsEndEventSent || IsSelfDependentForBegin())
+ {
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->NotifyAnimationEnded();
+ TSvgInternalEvent event ( ESvgEventEndEvent, this,LEndTIme );
+ TSvgInternalEvent event1 ( ESvgEventRepeatEvent, this,LEndTIme );
+ //repeatCount Event is also generated
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &event1 );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &event );
+ // Update presentation should be called only if the animation gets finished
+ // Check for the multiple begin values to make sure that the animation ended completely.
+ if ( (iBeginTimeIndex+1 >= iAnimTime->BeginTimesCount() ) || ( iAnimTime->GetBeginTime( iBeginTimeIndex + 1 ) <= timerEvent->Time()))
+ {
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->UpdatePresentation(1);
+ }
+ return ETrue; // so that draw happens if begin depends on its own end event
+ }
+ else
+ {
+ iIsEndEventSent = EFalse;
+ }
+
+ }
+
+ else
+ {
+ // E.g begin="0s" dur="10s" repeatCount='3'
+ //in such case if curtime < 30s and iAnimStatus is End then animation would repeat
+ iCurrentRepeatCount++;
+ if ( iAccumulate == KAccumSum )
+ {
+ aAnimElement->SetAccumulateValues();
+ }
+ aAnimElement->ResetAnimationL();
+ iAnimTime->ResetBeginTime( iAnimTime->BeginTime() +
+ iAnimTime->DurationTime() );
+ iAnimStatus = KAnimActive;
+
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( ETrue );
+ SetIsAnimating( ETrue );
+ }
+
+ iOverrideTime = EFalse;
+ // Generates repeatEvent
+ //Triggers internal repeat event so that animations dependent on this would get the events
+
+ TInt32 lRepeatTime = iAbsoluteBeginTime + iCurrentRepeatCount*iAnimTime->DurationTime();
+
+ TSvgInternalEvent event ( ESvgEventRepeatEvent, this,lRepeatTime );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &event );
+ }
+ }
+
+ // do not redraw.
+ if(iAnimStatus == KAnimNotActive || (iAnimStatus == KAnimFinished && iDoFreeze))
+ {
+ // this will avoid going in to the draw again.
+ return EFalse;
+ }
+ return ETrue;
+
+ }
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetFillValueL()
+ {
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ iTargetElement->GetAttributeFloat( iAttrId, iPropFloat );
+ if ( ( iFill == KAnimFillFreeze ) && iNoFrom )
+ {
+ iFromFloat = iPropFloat;
+ }
+ break;
+
+ case KSvgTypeList:
+ case KSvgTypePath:
+ break;
+
+ case KSvgTypeColor:
+ if ( iAttributeFlag && !iCurrentRepeatCount )
+ {
+ iTargetElement->GetAttributeIntL( iAttrId, iPropInt );
+
+ }
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeInteger:
+ case KSvgTypeDisplay:
+ case KSvgTypeVisibility:
+ if ( iAttributeFlag )
+ {
+ iTargetElement->GetAttributeIntL( iAttrId, iPropInt );
+ }
+ break;
+
+ // viewBox
+ case KSvgTypeViewBox:
+ {
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ ((CSvgSvgElementImpl*)iTargetElement)->GetViewBox( iOrgViewBox );
+ if ( ( iFill == KAnimFillFreeze ) && iNoFrom )
+ {
+ iFromViewBox = iOrgViewBox;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetToOriginalL()
+ {
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ iTargetElement->SetAttributeFloatL( iAttrId, iPropFloat );
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ iTargetElement->SetAttributePathL( iAttrId, iOrgPath );
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeColor:
+ case KSvgTypeInteger:
+ case KSvgTypeDisplay:
+ case KSvgTypeVisibility:
+ if ( iAttributeFlag )
+ {
+ iTargetElement->SetAttributeIntL( iAttrId, iPropInt );
+ }
+ break;
+
+ //viewBox
+ case KSvgTypeViewBox:
+ {
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ ((CSvgSvgElementImpl*)iTargetElement)->SetViewBoxL( iOrgViewBox );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetToInitialValueL()
+ {
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ iTargetElement->SetAttributeFloatL( iAttrId, iPropFloat );
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ iTargetElement->SetAttributePathL( iAttrId, iOrgPath );
+ break;
+ case KSvgTypeColor:
+ if ( iAttributeFlag )
+ {
+ iTargetElement->SetAttributeIntL( iAttrId, iPropInt );
+ }
+ else
+ {
+ if( iAttrId == KCSS_ATTR_VISIBILITY ||
+ iAttrId == KCSS_ATTR_FILL ||
+ iAttrId == KCSS_ATTR_STROKE )
+ {
+ iTargetElement->RemoveAttribute(iAttrId);
+ }
+
+ }
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeInteger:
+ case KSvgTypeDisplay:
+ case KSvgTypeVisibility:
+ if ( iAttributeFlag )
+ {
+ iTargetElement->SetAttributeIntL( iAttrId, iPropInt );
+ }
+ else
+ {
+ if( iAttrId == KCSS_ATTR_VISIBILITY ||
+ iAttrId == KCSS_ATTR_FILL ||
+ iAttrId == KCSS_ATTR_STROKE )
+ {
+ iTargetElement->RemoveAttribute(iAttrId);
+ }
+
+ }
+ break;
+
+ //viewBox
+ case KSvgTypeViewBox:
+ {
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ ((CSvgSvgElementImpl*)iTargetElement)->SetViewBoxL( iOrgViewBox );
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+ }
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetToEndValueL()
+ {
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ if( iAdditive == KAdditiveSum && !iNoFrom && (this->ElemID() == KSvgAnimateElement ))
+ {
+ TFloatFixPt lCurValue;
+ iTargetElement->GetAttributeFloat( iAttrId, lCurValue );
+ iTargetElement->SetAttributeFloatL(iAttrId, lCurValue + iEndFloat );
+ }
+ else
+ {
+ iTargetElement->SetAttributeFloatL( iAttrId, iEndFloat );
+ }
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ {
+ iTargetElement->SetAttributePathL( iAttrId, iEndPath );
+ }
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeInteger:
+ case KSvgTypeDisplay:
+ case KSvgTypeVisibility:
+ {
+ if ( iAttributeFlag )
+ {
+ iTargetElement->SetAttributeIntL( iAttrId, iEndInt );
+ }
+ }
+ break;
+
+ case KSvgTypeColor:
+ {
+ // fix for accum_addit_7
+ if( iAttributeFlag )
+ {
+ if( iAdditive == KAdditiveSum && !iNoFrom )
+ {
+
+ TInt32 lCurValue;
+ iTargetElement->GetAttributeIntL( iAttrId, lCurValue );
+
+
+ lCurValue = AddColor( iEndInt, lCurValue );
+ iTargetElement->SetAttributeIntL( iAttrId, lCurValue );
+ }
+
+ else
+ {
+ iTargetElement->SetAttributeIntL( iAttrId, iEndInt );
+ }
+ }
+ }
+ break;
+
+ //viewBox
+ case KSvgTypeViewBox:
+ {
+ if( iAdditive == KAdditiveSum && !iNoFrom && (this->ElemID() == KSvgAnimateElement ))
+ {
+ TGfxRectangle2D lCurValue;
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ ((CSvgSvgElementImpl*)iTargetElement)->GetViewBox( lCurValue );
+ }
+
+ lCurValue.iX += iEndViewBox.iX ;
+ lCurValue.iY += iEndViewBox.iY ;
+ lCurValue.iWidth += iEndViewBox.iWidth ;
+ lCurValue.iHeight += iEndViewBox.iHeight ;
+
+
+ // set the vlue to the target element.
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ ((CSvgSvgElementImpl*)iTargetElement)->SetViewBoxL( lCurValue );
+ }
+ }
+
+ else
+ {
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ ((CSvgSvgElementImpl*)iTargetElement)->SetViewBoxL( iEndViewBox );
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// Initialization before start of animation
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::InitAnimationL()
+ {
+ // 1. Create keytimes if no keytime but values available
+ // 2. Set animation time according to calcMode
+ //
+ // Also, add target element to event receiver list for mouse event
+ //Set the First Begin Time
+
+
+
+ if( iAnimTime->BeginTimesCount() > 0 )
+ {
+ iAnimTime->SetBeginTime( iAnimTime->GetBeginTime(0));
+ iAbsoluteBeginTime = iAnimTime->GetBeginTime(0);
+ }
+
+
+ if( iAnimTime->RepeatDurationTime() != KTimeIndefinite )
+ {
+ iAnimTime->CalculateAnimTimes();
+ }
+
+
+
+
+ iOverrideTime = ETrue;
+
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ if ( iNoFrom )
+ {
+ iOrgFromFloat = iFromFloat = iPropFloat;
+ }
+ iAnimTime->CreateKeyTime( iValuesFloat->Count() );
+ iAnimTime->PrepareTimeL( iValuesFloat );
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ {
+
+ if ( iOrgFromPath )
+ {
+ delete iOrgFromPath;
+ iOrgFromPath = NULL;
+ }
+ iOrgFromPath = CGfxGeneralPath::NewL();
+
+ CGfxGeneralPath* parentPath = NULL;
+ iTargetElement->GetAttributePath( iAttrId, parentPath );
+ CGfxPathIterator* itr;
+ TGfxAffineTransform affineTransform;
+
+ if (parentPath != NULL)
+ {
+ parentPath->GetPathIteratorL( &affineTransform, itr );
+ CleanupStack::PushL( itr );
+
+ iOrgFromPath->AppendL( itr );
+ CleanupStack::PopAndDestroy( 1 ); // destroy itr
+ }
+ // Set keytime
+
+ iValuesFloat->Reset();
+ TInt lCount = iValuesPath->Count();
+ for ( TInt i = 0; i < lCount ; i++ )
+ {
+ User::LeaveIfError(iValuesFloat->Append( TFloatFixPt( i ) )); // create dummy scalar array
+ }
+ iAnimTime->CreateKeyTime( iValuesFloat->Count() );
+ iAnimTime->PrepareTimeL( iValuesFloat );
+ }
+ break;
+
+ case KSvgTypeColor:
+ {
+ // Set keytime
+ iValuesFloat->Reset();
+ // Compute the colour distance in iValuesFloat
+ FindColorDistanceL();
+ iAnimTime->CreateKeyTime( iValuesFloat->Count() );
+ iAnimTime->PrepareTimeL( iValuesFloat );
+ }
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeVisibility:
+ case KSvgTypeDisplay:
+ case KSvgTypeInteger:
+ iAnimTime->CreateKeyTimeForEnumeration( iValuesInt->Count() );
+ iAnimTime->PrepareTimeL( ( RArray<TFloatFixPt>* ) iValuesInt );
+ break;
+
+ // viewBox
+ case KSvgTypeViewBox:
+ {
+ if ( iNoFrom )
+ {
+ iOrgFromViewBox = iFromViewBox = iOrgViewBox;
+ }
+ // Set keytime
+ iValuesFloat->Reset();
+ TInt lCount = iValuesViewBox->Count();
+ for ( TInt i = 0; i < lCount ; i++ )
+ User::LeaveIfError(iValuesFloat->Append( TFloatFixPt( i ) )); // create dummy scalar array
+ iAnimTime->CreateKeyTime( iValuesFloat->Count() );
+ iAnimTime->PrepareTimeL( iValuesFloat );
+ }
+ break;
+
+ default:
+ // Text
+ break;
+ }
+
+ TUint32 lSimpleDuration = SimpleDuration();
+ if( lSimpleDuration != KTimeIndefinite)
+ {
+ iAnimTime->SetEndTime(lSimpleDuration);
+ iAnimTime->SetModifiedEndTime(lSimpleDuration);
+ }
+
+ if(this->ElemID() == KSvgAnimateColorElement)
+
+ {
+
+ // this Is to check that the animateColor is not applied to anything
+ // other than color.
+
+ switch(iDataType )
+ {
+ case KSvgTypeColor:
+ break;
+ default :
+ ((CSvgDocumentImpl*)iOwnerDocument)->RemoveFromEventReceiverList(this );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->UpdatePresentation(1);
+ break;
+ }
+
+ }
+
+ // Add to event receiver list
+ // Also need to look end event...
+ CSvgElementImpl* targetElement = NULL;
+
+
+ // this is for forward reference.
+ // first find the count this can be more than one
+ // for multiple BeginTimes.
+ TInt lCount = iEventList->Count();
+ for (TInt i=0; i< lCount; i++)
+ {
+
+ if ( (iEventList->operator[](i)).iTargetElement != NULL )
+ {
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL(
+ (iEventList->operator[](i)).iTargetElement,
+ (iEventList->operator[](i)).iEvent,
+ KSvgEventMaskExternalUI );
+ }
+
+ // check that this is not NULL;
+ // NULL means Begin time is absolute.
+ if(iEventList->operator[](i).iReferenceElemeId != NULL)
+ {
+
+ // find the element.
+ targetElement = ( CSvgElementImpl * )
+ ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById(
+ iEventList->operator[](i).iReferenceElemeId->Des());
+ if(targetElement != NULL)
+ {
+
+ // Add to Event receiver list.
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL(
+ targetElement ,(iEventList->operator[](i)).iEvent, KSvgEventMaskExternalUI );
+
+ // update the pointer to the target element.
+ iEventList->operator[](i).iTargetElement = targetElement;
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ }
+
+ delete iEventList->operator[](i).iReferenceElemeId;
+ iEventList->operator[](i).iReferenceElemeId = NULL;
+
+ }
+
+ }
+
+ // add the end sync element so that it receives mouse events
+
+ if( iEndTimeList->Count() > 0 )
+ {
+
+ // this is for forward reference.
+ // first find the count this can be more than one
+ // for multiple BeginTimes.
+ TInt lCount2 = iEndTimeList->Count();
+ for (TInt i=0; i< lCount2; i++)
+ {
+
+ if ( (iEndTimeList->operator[](i)).iTargetElement != NULL )
+ {
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL(
+ (iEndTimeList->operator[](i)).iTargetElement,
+ (iEndTimeList->operator[](i)).iEvent,
+ KSvgEventMaskExternalUI );
+ }
+
+ // check that this is not NULL;
+ // NULL means Begin time is absolute.
+ if(iEndTimeList->operator[](i).iReferenceElemeId != NULL)
+ {
+
+ // find the element.
+ targetElement = ( CSvgElementImpl * )
+ ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById(
+ iEndTimeList->operator[](i).iReferenceElemeId->Des());
+ if(targetElement != NULL)
+ {
+
+ // Add to Event receiver list.
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL(
+ targetElement ,
+ (iEndTimeList->operator[](0)).iEvent,
+ KSvgEventMaskExternalUI );
+
+ // update the pointer to the target element.
+ iEndTimeList->operator[](i).iTargetElement = targetElement;
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ }
+
+ delete iEndTimeList->operator[](i).iReferenceElemeId;
+ iEndTimeList->operator[](i).iReferenceElemeId = NULL;
+
+ }
+
+ }
+
+ }
+
+ }
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetAccumulateValues()
+ {
+ /* switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ case KSvgTypeList:
+ case KSvgTypePath:
+ break;
+
+ case KSvgTypeColor:
+ break;
+
+ case KSvgTypeInteger:
+ break;
+
+ default:
+ // Descriptor
+ ;
+ }*/
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimationBase::IsElementAttrs( const TDesC& aAttrName )
+ {
+ TInt pos = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->GetSVGTAttributeId(aAttrName);
+
+ if ( pos == KErrNotFound)
+ {
+ // Did not find the attribute name
+ return EFalse;
+ }
+ else
+ {
+ iAttrId= (TUint16) pos;
+ if(iAttrId <= KSvgCoordAttrEndIndex || iAttrId == KAtrFy || iAttrId == KAtrFx )
+ {
+ iDataType = KSvgTypeLength;
+ }
+ else
+ {
+ switch(iAttrId)
+ {
+ case KAtrGradientUnits:
+ iDataType = KSvgTypeGradientUnits;
+ break;
+ case KAtrSpreadMethods:
+ iDataType = KSvgTypeSpreadMethod;
+ break;
+
+ case KAtrStopColor:
+ iDataType= KSvgTypeColor;
+ break;
+
+ case KAtrPoints:
+ case KAtrD:
+ iDataType = KSvgTypePath;
+ break;
+
+ case KAtrOffset: // Always need to be between 0 - 1 , thus treating same as opacity.
+ case KAtrStopOpacity:
+ iDataType= KSvgTypeOpacity;
+ break;
+
+ case KAtrViewBox:
+ iDataType= KSvgTypeViewBox;
+ break;
+
+ default:
+ return EFalse;
+ }
+ }
+ }
+
+ return ETrue;
+ }
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgAnimationBase::IsPresentationAttrs( const TDesC& aAttrName )
+ {
+ TInt ret;
+ ret = ((CSvgDocumentImpl*)iOwnerDocument)->SchemaData()->GetPresentationAttributeId( aAttrName);
+ if ( ret == KErrNotFound )
+ {
+ // Did not find the attribute name
+ return EFalse;
+ }
+ else
+ {
+ switch ( ret )
+ {
+ case KCSS_ATTR_FILL:
+ // fill
+ iAttrId = KCSS_ATTR_FILL;
+ iDataType = KSvgTypeColor;
+ break;
+ case KCSS_ATTR_STROKE:
+ // stroke
+ iAttrId = KCSS_ATTR_STROKE;
+ iDataType = KSvgTypeColor;
+ break;
+ case KCSS_ATTR_STROKEWIDTH:
+ // stroke-width
+ iAttrId = KCSS_ATTR_STROKEWIDTH;
+ iDataType = KSvgTypeLength;
+ break;
+ case KCSS_ATTR_STROKE_DASHOFFSET:
+ iAttrId = KCSS_ATTR_STROKE_DASHOFFSET;
+ iDataType = KSvgTypeLength;
+ break;
+ case KCSS_ATTR_VISIBILITY:
+ // visibility
+ iAttrId = KCSS_ATTR_VISIBILITY;
+ iDataType = KSvgTypeVisibility;
+ break;
+ case KCSS_ATTR_COLOR:
+ // color
+ iAttrId = KCSS_ATTR_COLOR;
+ iDataType = KSvgTypeColor;
+ break;
+ case KCSS_ATTR_FONTSIZE:
+ // font-size
+ iAttrId = KCSS_ATTR_FONTSIZE;
+ iDataType = KSvgTypeLength;
+ break;
+ case KCSS_ATTR_DISPLAY:
+ // display
+ iAttrId = KCSS_ATTR_DISPLAY;
+ iDataType = KSvgTypeDisplay;
+ break;
+ case KCSS_ATTR_TEXTANCHOR:
+ iAttrId = KCSS_ATTR_TEXTANCHOR;
+ iDataType = KSvgTypeTextAnchor;
+ break;
+ case KCSS_ATTR_FILL_OPACITY:
+ iAttrId = KCSS_ATTR_FILL_OPACITY;
+ iDataType = KSvgTypeOpacity;
+ break;
+ case KCSS_ATTR_STROKE_OPACITY:
+ iAttrId = KCSS_ATTR_STROKE_OPACITY;
+ iDataType = KSvgTypeOpacity;
+ break;
+ case KCSS_ATTR_GROUP_OPACITY:
+ iAttrId = KCSS_ATTR_GROUP_OPACITY;
+ iDataType = KSvgTypeOpacity;
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ return ETrue;
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::GetAttrValueL()
+ {
+ iAttributeFlag = 1;
+ switch ( iDataType )
+ {
+ case KSvgTypeLength:
+ case KSvgTypeNumber:
+ iTargetElement->GetAttributeFloat( iAttrId, iPropFloat );
+ iTargetElement->GetAttributeFloat( iAttrId, iOrgFloat );
+ break;
+ case KSvgTypeOpacity:
+ iTargetElement->GetAttributeFloat( iAttrId, iPropFloat );
+ iTargetElement->GetAttributeFloat( iAttrId, iOrgFloat );
+ break;
+ case KSvgTypeList:
+ case KSvgTypePath:
+ {
+ // copy parent -> iOrgPath
+ CGfxGeneralPath*parentPath = NULL;
+
+ if ( iOrgPath )
+ {
+ delete iOrgPath;
+ iOrgPath = NULL;
+ }
+
+ if ( iEndPath )
+ {
+ delete iEndPath;
+ iEndPath = NULL;
+ }
+
+ iOrgPath = CGfxGeneralPath::NewL();
+ iEndPath = CGfxGeneralPath::NewL();
+
+ iTargetElement->GetAttributePath( iAttrId, parentPath );
+
+ if(parentPath != NULL)
+ {
+ CGfxPathIterator* itr;
+ TGfxAffineTransform affineTransform;
+ parentPath->GetPathIteratorL( &affineTransform, itr );
+ CleanupStack::PushL( itr );
+ iOrgPath->AppendL( itr );
+ CleanupStack::PopAndDestroy( 1 ); // destroy itr
+
+ iTargetElement->GetAttributePath( iAttrId, parentPath );
+ CGfxPathIterator* itr1;
+ TGfxAffineTransform affineTransform1;
+ parentPath->GetPathIteratorL( &affineTransform1, itr1 );
+ CleanupStack::PushL( itr1 );
+ iEndPath->AppendL( itr1 );
+ CleanupStack::PopAndDestroy( 1 ); // destroy itr
+ }
+ }
+ break;
+ case KSvgTypeColor:
+ {
+ TInt32 col;
+
+ if ( iTargetElement->GetAttributeIntL( iAttrId, col ) ==
+ KErrNoAttribute )
+ {
+ iPropInt = 0;
+ iAttributeFlag = 0;
+ }
+ else
+ {
+ // convert the color to openVG color
+ iPropInt = col;
+ iAttributeFlag = 1;
+ }
+ iTargetElement->GetAttributeIntL( iAttrId, iOrgInt );
+ }
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeInteger:
+ iTargetElement->GetAttributeIntL( iAttrId, iPropInt );
+ iTargetElement->GetAttributeIntL( iAttrId, iOrgInt );
+ break;
+ case KSvgTypeVisibility:
+ iTargetElement->GetAttributeIntL( iAttrId, iOrgInt );
+ if ( iTargetElement->GetAttributeIntL( iAttrId, iPropInt ) == KErrNoAttribute )
+ {
+ iPropInt = 0;
+ iAttributeFlag = 0;
+ }
+ else
+ {
+ iAttributeFlag = 1;
+ }
+ break;
+ case KSvgTypeDisplay:
+ iTargetElement->GetAttributeIntL( iAttrId, iPropInt );
+ iTargetElement->GetAttributeIntL( iAttrId, iOrgInt );
+ break;
+
+
+ // viewBox
+ case KSvgTypeViewBox:
+ {
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ ((CSvgSvgElementImpl*)iTargetElement)->GetViewBox( iOrgViewBox );
+ }
+ }
+ break;
+
+ default:
+ iTargetElement->GetAttributeIntL( iAttrId, iOrgInt );
+ iTargetElement->GetAttributeIntL( iAttrId, iPropInt );
+ break;
+ }
+ }
+
+
+void CSvgAnimationBase::ResetAttrValueL()
+ {
+
+ if (!iTargetElement)
+ {
+ return;
+ }
+
+ switch ( iDataType )
+ {
+ case KSvgTypeLength:
+ case KSvgTypeNumber:
+ iTargetElement->SetAttributeFloatL( iAttrId, iOrgFloat );
+ break;
+ case KSvgTypeOpacity:
+ iTargetElement->SetAttributeFloatL( iAttrId, iOrgFloat );
+ break;
+ case KSvgTypeColor:
+ iTargetElement->SetAttributeIntL( iAttrId, iOrgInt );
+ break;
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeInteger:
+ iTargetElement->SetAttributeIntL( iAttrId, iOrgInt );
+ break;
+ case KSvgTypeVisibility:
+ iTargetElement->SetAttributeIntL( iAttrId, iOrgInt );
+ break;
+ case KSvgTypeDisplay:
+ iTargetElement->SetAttributeIntL( iAttrId, iOrgInt );
+ break;
+ default:
+ iTargetElement->SetAttributeIntL( iAttrId, iOrgInt );
+ break;
+ }
+ }
+
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetTarget( CSvgElementImpl* aTarget )
+ {
+ if (aTarget)
+ {
+ iTargetSet = ETrue;
+ // Before anything else set the target to parent
+ iTargetElement = aTarget;
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ }
+ }
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetBeginByEventL( CSvgAnimationBase* aAnimElement,
+ TInt32 aBeginTime, TBool aAddTime )
+ {
+ if ( iAnimRestart == KRestartWhenNotActive && iAnimStatus == KAnimActive )
+ {
+ return; // Not start when active and restart="whenNotActive"
+ }
+ if ( iAnimRestart == KRestartNever && iHadBegun )
+ {
+ return; // Not start when anim had begun and if restart="never"
+ }
+
+
+ aAnimElement->ResetAnimationL();
+
+ if ( aAddTime )
+ {
+ iAnimTime->AddBeginTime( aBeginTime );
+ }
+ else
+ {
+ iAnimTime->ResetBeginTime( aBeginTime );
+ }
+
+ iAnimStatus = KAnimNotActive;
+
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+ }
+ iOverrideTime = ETrue;
+ TInt32 lCurTime = ((CSvgDocumentImpl*)(iOwnerDocument))->CurrentTime();
+ iAnimTime->SetNextBeginTime(lCurTime);
+ iAbsoluteBeginTime = iAnimTime->BeginTime();
+
+ if(iAnimTime->GetOriginalEndTime() == KTimeIndefinite)
+ {
+ iAnimTime->SetEndTime(KTimeIndefinite);
+ }
+
+ TUint32 lSimpleDuration = SimpleDuration();
+ if( lSimpleDuration != KTimeIndefinite)
+ {
+ iAnimTime->SetEndTime(lSimpleDuration);
+ }
+
+ ((CSvgDocumentImpl*)iOwnerDocument)->AddEventBeginTime( aAnimElement, iAbsoluteBeginTime, aAnimElement->iTargetElement );
+ ((CSvgDocumentImpl*)iOwnerDocument)->iInitSortList=ETrue;
+
+
+ }
+
+
+//
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::SetEndByEvent( CSvgAnimationBase* /* aAnimElement */,
+ TInt32 aEndTime )
+ {
+ iAnimTime->AddEndTime( aEndTime );
+
+ iAnimTime->GetNextEndTime(iAnimTime->BeginTime());
+ TUint32 lSimpleDur= SimpleDuration();
+ if(lSimpleDur != KTimeIndefinite)
+ {
+ iAnimTime->SetEndTime( lSimpleDur );
+ }
+
+ iIsEndEventSent = EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// Blending methods aAlpha must be [0 - 255]
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgAnimationBase::BlendFloat( TInt32 aAlpha, TFloatFixPt aV1, TFloatFixPt aV2 )
+ {
+ #ifdef SVG_FLOAT_BUILD
+ TFloatFixPt percent = ((float)aAlpha)/255.0f;
+ TFloatFixPt percentValue = ( aV2 - aV1 ) * percent;
+ return aV1 + percentValue;
+ #else
+ TUint32 v1 = aV1.RawData() >> 8;
+ TUint32 v2 = aV2.RawData() >> 8;
+ return TFloatFixPt( BlendInt( aAlpha, v1, v2 ) << 8, ETrue );
+#endif
+ }
+
+// ---------------------------------------------------------------------------
+// Blending methods aAlpha must be [0 - 255]
+// ---------------------------------------------------------------------------
+TInt32 CSvgAnimationBase::BlendInt( TInt32 aAlpha, TInt32 aV1, TInt32 aV2 )
+ {
+ return ( (aV2 - aV1) * (((TReal32)aAlpha)/((TReal32)255)) ) + aV1 ;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TUint32 CSvgAnimationBase::BlendColor( TInt32 aAlpha, // Interpolation factor
+ // between [0-255]
+ TUint32 aV1, // Initial Colour value in RGB format
+ TUint32 aV2 ) // Final Colour value
+ {
+ TUint32 r, g, b;
+ TInt32 c1, c2;
+
+ // aAlpha is a value between 0-255 which indicates current interpolated
+ // value of the animation.
+ // Since colour value is divided by 256 (for optimisation - bit shift
+ // by 8 bits) alpha is set to 256 when it is 255.
+ if( 255 == aAlpha )
+ {
+ aAlpha = 256;
+ }
+
+ // Compute Red component
+ c1 = aV2 & KRmask;
+ c2 = aV1 & KRmask;
+ r = ( ( ( c1 - c2 ) * aAlpha + c2 * 256 ) >> 8 ) & KRmask;
+
+ // Compute Green Component
+ c1 = aV2 & KGmask;
+ c2 = aV1 & KGmask;
+ g = ( ( ( c1 - c2 ) * aAlpha + c2 * 256 ) >> 8 ) & KGmask;
+
+ // Compute Blue component
+ c1 = aV2 & KBmask;
+ c2 = aV1 & KBmask;
+ b = ( ( ( c1 - c2 ) * aAlpha + c2 * 256 ) >> 8 ) & KBmask;
+
+ // Combine r,g,b and return
+ return r | g | b;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TUint32 CSvgAnimationBase::AddColor( TUint32 aV1, TUint32 aV2 )
+ {
+ TInt32 r, g, b;
+ TInt32 r1, r2, g1, g2, b1, b2;
+ TUint sign1, sign2;
+
+ // WARNING, spare high order bits store sign of 8 bit components
+ // on input values only the use is limited in scope to
+ // SetAccumulateValues method
+ // return value is unsigned & clamped
+ // MSB better be blank for normal use
+
+ sign1 = (TInt32)( aV1 & 0xff000000) >> 24;
+ sign2 = (TInt32)( aV2 & 0xff000000) >> 24;
+ r1 = (aV1 & 0x00ff0000) >> 16;
+ r2 = (aV2 & 0x00ff0000) >> 16;
+ g1 = (aV1 & 0x0000ff00) >> 8;
+ g2 = (aV2 & 0x0000ff00) >> 8;
+ b1 = (aV1 & 0x000000ff);
+ b2 = (aV2 & 0x000000ff);
+
+ if(sign1 & 0x04)
+ {
+ r1 *= -1;
+ }
+ if(sign1 & 0x02)
+ {
+ g1 *= -1;
+ }
+ if(sign1 & 0x01)
+ {
+ b1 *= -1;
+ }
+ if(sign2 & 0x04)
+ {
+ r2 *= -1;
+ }
+ if(sign2 & 0x02)
+ {
+ g2 *= -1;
+ }
+ if(sign2 & 0x01)
+ {
+ b2 *= -1;
+ }
+
+ r = ( ( r1 + r2 ) );
+ g = ( ( g1 + g2 ) );
+ b = ( ( b1 + b2 ) );
+
+ // clamp for overflow & underflow
+ if ( r > 255 )
+ {
+ r = 255;
+ }
+ if ( g > 255 )
+ {
+ g = 255;
+ }
+ if ( b > 255 )
+ {
+ b = 255;
+ }
+
+ if ( r < 0 )
+ {
+ r = 0;
+ }
+ if ( g < 0 )
+ {
+ g = 0;
+ }
+
+ if ( b < 0 )
+ {
+ b = 0;
+ }
+ return ( ( ( r & 0xFF ) << 16 ) | ( ( g & 0xFF ) << 8 ) | ( b & 0xFF ) );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TUint32 CSvgAnimationBase::SubtractColor( TUint32 aV1, TUint32 aV2 )
+ {
+ TInt32 r, g, b;
+ TInt32 r1, r2, g1, g2, b1, b2;
+ TUint sign = 0x0;
+
+ // WARNING, spare high order bits store sign of 8 bit components
+ // the use is limited in scope to SetAccumulateValues method
+ // the commented code would handle signed input but this isn't
+ // used by calling code
+ // output components are not clamped
+ r1 = (aV1 & 0x00ff0000) >> 16;
+ r2 = (aV2 & 0x00ff0000) >> 16;
+ g1 = (aV1 & 0x0000ff00) >> 8;
+ g2 = (aV2 & 0x0000ff00) >> 8;
+ b1 = (aV1 & 0x000000ff);
+ b2 = (aV2 & 0x000000ff);
+
+ r = ( ( r1 - r2 ) );
+ g = ( ( g1 - g2 ) );
+ b = ( ( b1 - b2 ) );
+
+ if ( r < 0 )
+ {
+ sign = 0x04;
+ r *= -1;
+ }
+
+ if ( g < 0 )
+ {
+ sign |= 0x02;
+ g *= -1;
+ }
+
+ if ( b < 0 )
+ {
+ sign |= 0x01;
+ b *= -1;
+ }
+ return ( ( ( r & 0xFF ) << 16 ) | ( ( g & 0xFF ) << 8 ) | ( b & 0xFF ) );
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt32 CSvgAnimationBase::GetNumberOfEvents(const TDesC& aValue)
+ {
+ TInt32 result=1;
+ TStringTokenizer tkn ( aValue, KSEMICOLON );
+ while( tkn.HasMoreTokens() )
+ {
+ tkn.NextToken( );
+ result++;
+ }
+ return result;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+
+TInt32 CSvgAnimationBase::Duration()
+ {
+ return (TInt32)iAnimTime->DurationTime();
+ }
+
+
+void CSvgAnimationBase::SaveBeginTimeToList(TInt aTimeInMilliseconds)
+ {
+ iAnimTime->AddToInitialList(aTimeInMilliseconds);
+ }
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+
+void CSvgAnimationBase::ReInitializeAnimation()
+ {
+
+
+ iHadBegun= EFalse;
+ iBeginTimeIndex = 0 ;
+ iCurrentRepeatCount= 0;
+ iInitDone = EFalse;
+ iOverrideTime = EFalse;
+ iAnimStatus = KAnimNotActive;
+
+ if (iTargetElement)
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ iTargetElement->SetIsAnimating( EFalse );
+ SetIsAnimating( EFalse );
+ }
+
+ //JSR226 Change in question
+// if (iOwnerDocument && ((CSvgDocumentImpl*)iOwnerDocument)->Engine() && iTargetElement )
+// {
+ //hope these are parrallel vectors
+ //for (TInt i=0; i < iAnimTime->BeginTimesCount(); i++)
+ //{
+// if ( (iAnimTime->BeginTime() <= ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() )
+// && ( iAnimTime->EndTime() >= ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme() ) )
+// {
+// iTargetElement->iAnimating = ETrue;
+// iAnimating = ETrue;
+// }
+ //}
+// }
+ //--end of change in question
+//
+ if(iAdditiveOrg == KAdditiveReplace)
+ {
+ iAdditive= KAdditivePass;
+ }
+
+
+ if (iAnimTime)
+ {
+ if (iIsUserSeek)
+ iAnimTime->ReInitializeForSeek();
+ else
+ iAnimTime->ReInitialize();
+
+ if( iAnimTime->BeginTimesCount()== 0 )
+ {
+ if(iIsBeginSet ) // begin on events
+ {
+ if(!iIsUserSeek)// for DOM Reusage only
+ {
+ iAnimTime->SetBeginTime(KTimeIndefinite);
+ iAbsoluteBeginTime = KTimeIndefinite ;
+ }
+ else
+ {
+ // if begin depends on event and repeat is there,
+ //then iAbsoluteBeginTime != iBeginTime.
+ if((TUint32)iAbsoluteBeginTime != iAnimTime->BeginTime() )
+ iAnimTime->SetBeginTime(iAbsoluteBeginTime);
+ }
+
+ }
+ else
+ {
+ iAnimTime->SetBeginTime(0);
+ iAbsoluteBeginTime = 0 ;
+ }
+ }
+
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Functions used by Decoder
+// ---------------------------------------------------------------------------
+
+
+void CSvgAnimationBase::SetAttributeId(const TUint16 aAtrId)
+ {
+ iAttrId= aAtrId;
+ }
+
+void CSvgAnimationBase::SetAttributeType(const TUint8 aAtrType)
+ {
+ iDataType= (TUint16) aAtrType;
+ }
+
+void CSvgAnimationBase::SetBeginTimeList(RArray<TInt32>*& aList)
+ {
+ if (iAnimTime)
+ {
+ iAnimTime->SetBeginTimeList(aList);
+ }
+ }
+
+void CSvgAnimationBase::SetBeginTime(TInt32 aTime)
+ {
+ if (iAnimTime)
+ {
+ iAnimTime->SetBeginTime(aTime);
+ }
+ }
+
+void CSvgAnimationBase::SetAbsoluteBeginTime(TInt32 aTime)
+ {
+ iAbsoluteBeginTime= aTime;
+ iIsBeginSet = ETrue;
+ }
+
+void CSvgAnimationBase::SetEventList(CArrayFixFlat<TEventListItem>*& aEventList)
+ {
+ if (iEventList)
+ {
+ iEventList->Reset();
+ delete iEventList;
+ iEventList= NULL;
+ }
+ iEventList= aEventList;
+ }
+
+void CSvgAnimationBase::SetEndTimeList(CArrayFixFlat<TEventListItem>*& aTimeList)
+ {
+ if (iEndTimeList)
+ {
+ iEndTimeList->Reset();
+ delete iEndTimeList;
+ iEndTimeList= NULL;
+ }
+ iEndTimeList= aTimeList;
+ }
+
+void CSvgAnimationBase::SetDurationTime(TInt32 aTime)
+ {
+ if (iAnimTime)
+ {
+ iAnimTime->SetDurationTime(aTime);
+ }
+ }
+
+void CSvgAnimationBase::SetFromFlag()
+ {
+ iNoFrom= EFalse;
+ }
+
+void CSvgAnimationBase::SetFromInt(TInt32 aValue)
+ {
+ iFromInt= aValue;
+ iOrgFromInt= aValue;
+ }
+
+void CSvgAnimationBase::SetFromFloat(TFloatFixPt aValue)
+ {
+ iFromFloat= aValue;
+ iOrgFromFloat= aValue;
+ }
+
+void CSvgAnimationBase::SetFromViewBox(TGfxRectangle2D aValue)
+ {
+ iFromViewBox= aValue;
+ iOrgFromViewBox= aValue;
+ }
+
+void CSvgAnimationBase::SetFromPathL(CGfxGeneralPath*& aPath)
+ {
+ if (iFromPath)
+ {
+ delete iFromPath;
+ iFromPath= NULL;
+ }
+ iFromPath= aPath;
+
+ if ( iOrgFromPath )
+ {
+ delete iOrgFromPath;
+ iOrgFromPath = NULL;
+ }
+
+ iOrgFromPath = CGfxGeneralPath::NewL();
+ iOrgFromPath->SetPointTypeArrayL(aPath->PointTypeArray());
+ iOrgFromPath->SetPointCoordsArrayL(aPath->PointCoordsArrayAll());
+ }
+
+void CSvgAnimationBase::SetToFlag()
+ {
+ iHaveTo= ETrue;
+ }
+
+void CSvgAnimationBase:: SetToInt(TInt32 aValue)
+ {
+ iToInt= aValue;
+ }
+
+void CSvgAnimationBase:: SetToFloat(TFloatFixPt aValue)
+ {
+ iToFloat= aValue;
+ }
+
+void CSvgAnimationBase::SetToPath(CGfxGeneralPath*& aPath)
+ {
+ iToPath= aPath;
+ }
+
+void CSvgAnimationBase::SetToViewBox(TGfxRectangle2D aValue)
+ {
+ iToViewBox= aValue;
+ }
+
+CSvgElementImpl*& CSvgAnimationBase::GetTargetElem()
+ {
+ return iTargetElement;
+ }
+
+void CSvgAnimationBase::SetAnimFreeze()
+ {
+ iFill= KAnimFillFreeze;
+ }
+
+void CSvgAnimationBase::SetValuesFlag()
+ {
+ iHaveValues = ETrue;
+ }
+
+void CSvgAnimationBase::SetIntValuesArray( RArray<TInt32>*& aArray)
+ {
+ if (iValuesInt)
+ {
+ iValuesInt->Close();
+ delete iValuesInt;
+ }
+ iValuesInt= aArray;
+ }
+
+void CSvgAnimationBase::SetFloatValuesArray( RArray<TFloatFixPt>*& aArray)
+ {
+ if (iValuesFloat)
+ {
+ iValuesFloat->Close();
+ delete iValuesFloat;
+ }
+
+ iValuesFloat= aArray;
+ }
+
+void CSvgAnimationBase::SetViewBoxValuesArray( RArray<TGfxRectangle2D>*& aArray)
+ {
+ if (iValuesViewBox)
+ {
+ iValuesViewBox->Close();
+ delete iValuesViewBox;
+ }
+
+ iValuesViewBox= aArray;
+ }
+
+void CSvgAnimationBase::SetPathValuesArray( RPointerArray<CGfxGeneralPath>*& aArray)
+ {
+ if (iValuesPath)
+ {
+ iValuesPath->Close();
+ delete iValuesPath;
+ }
+
+ iValuesPath= aArray;
+ }
+
+void CSvgAnimationBase::ResetFloatValuesArray()
+ {
+ if (iValuesFloat)
+ {
+ iValuesFloat->Reset();
+ }
+ }
+
+void CSvgAnimationBase::SetRepeatCount(TReal32 aCount)
+ {
+ // fix for repeatCount
+ if(aCount <= 0)
+ {
+ iRepeatCount = 1;
+ }
+ else
+ {
+ iRepeatCount= aCount;
+ }
+ iRepeatCountSet = ETrue;
+
+ }
+
+void CSvgAnimationBase::SetRepeatDuration(TUint32 aDur)
+ {
+ if(!iRepeatCountSet)
+ {
+ iRepeatCount = KRepeatCountMax;
+ }
+
+ if (iAnimTime)
+ {
+ iAnimTime->SetRepeatDurationTime(aDur);
+ }
+ }
+
+
+void CSvgAnimationBase::SetEndTime(TInt32 aTime)
+ {
+ if(iAnimTime)
+ {
+ iAnimTime->SetEndTime(aTime);
+ }
+ }
+
+void CSvgAnimationBase::SetRestartMode(TRestartMode aMode)
+ {
+ iAnimRestart= aMode;
+ }
+
+void CSvgAnimationBase::SetAccumulate(TAccumulate aValue)
+ {
+ iAccumulate= aValue;
+ }
+
+void CSvgAnimationBase::SetAdditive(TAdditive aValue)
+ {
+ iAdditive= aValue;
+ iAdditiveOrg= aValue;
+ }
+
+void CSvgAnimationBase::SetCalcMode(TAnimCalcMode aMode)
+ {
+ if (iAnimTime)
+ {
+ iAnimTime->SetCalMode(aMode);
+ }
+ }
+
+void CSvgAnimationBase::SetKeyTimeArray(RArray<CSvgAnimTimeController::TKeyTime>*& aArray)
+ {
+ if (iAnimTime)
+ {
+ iAnimTime->SetKeyTimeArray(aArray);
+ }
+ }
+
+void CSvgAnimationBase::SetAnimTimeArray(RArray<TUint32>*& aArray)
+ {
+ if (iAnimTime)
+ {
+ iAnimTime->SetAnimTimeArray(aArray);
+ }
+ }
+
+void CSvgAnimationBase::SetByFlag()
+ {
+ iHaveBy= ETrue;
+ }
+
+TBool CSvgAnimationBase:: GetFromFlag()
+ {
+ return iNoFrom;
+ }
+
+TUint16 CSvgAnimationBase::GetAttributeId()
+ {
+ return iAttrId;
+ }
+
+void CSvgAnimationBase::SetKeyTimeFlag()
+ {
+ iKeyTimesPresent= ETrue;
+ }
+
+TInt CSvgAnimationBase::GetAttributeFloat( const TInt aNameId,
+ TFloatFixPt& aValue )
+ {
+ switch(aNameId)
+ {
+ case KAtrAttributeName:
+ {
+ aValue = (TFloatFixPt)(TInt)(iAttrId);
+ break;
+ }
+ case KAtrBegin:
+ {
+ aValue = (TInt32)iAnimTime->GetBeginTime( iBeginTimeIndex );
+ break;
+ }
+ case KAtrDur:
+ {
+ aValue = (TFloatFixPt)(TInt) (iAnimTime->DurationTime());
+ break;
+ }
+ case KAtrRepeatCount:
+ {
+ aValue = (TInt)iRepeatCount;
+ break;
+ }
+ case KAtrRepeatDur:
+ {
+ aValue = (TInt32) iAnimTime->RepeatDurationTime();
+ break;
+ }
+ case KAtrEnd:
+ {
+ aValue = (TInt32)iAnimTime->EndTime();
+ break;
+ }
+ case KAtrFrom:
+ {
+ if(! iNoFrom)
+ {
+ switch(iDataType)
+ { // Length float.
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ {
+ aValue = iFromFloat;
+ break;
+ }
+ default: break;
+ }
+ }
+ }
+ break;
+ case KAtrTo:
+ {
+ if(iHaveTo)
+ {
+ switch(iDataType)
+ { // Length float.
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ {
+ aValue = iToFloat;
+ break;
+ }
+ default: break;
+
+ }
+ }
+ }
+ break;
+ case KAtrBy:
+ {
+ if(iHaveBy)
+ {
+ switch(iDataType)
+ { // Length float.
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ {
+ aValue = iToFloat - iFromFloat;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ //this is for the JSR because it wants the original value returned instead of the animated
+ //version that element would return if it gets down to the default of this case statement
+ if (aNameId == iAttrId)
+ {
+ aValue = iOrgFloat;
+ return KErrNone;
+ }
+ else
+ {
+ return CSvgElementImpl::GetAttributeFloat( aNameId,aValue );
+ }
+ }
+ return KErrNone;
+ }
+
+TInt CSvgAnimationBase::SetAttributeFloatL( const TInt aNameId,
+ const TFloatFixPt aValue )
+{
+ switch(aNameId)
+ {
+ case KAtrAttributeName:
+ {
+ iAttrId = (TUint16)(TInt32)aValue;
+ break;
+ }
+ case KAtrBegin:
+ {
+ iAnimTime->SetBeginTime( aValue );
+ break;
+ }
+ case KAtrDur:
+ {
+ iAnimTime->SetDurationTime( aValue );
+ break;
+ }
+
+ case KAtrRepeatCount:
+ {
+ if((TInt32)aValue <= 0)
+ {
+ iRepeatCount = 1;
+ }
+ else
+ {
+ iRepeatCount= (TUint16) (TInt32)aValue;
+ }
+ iRepeatCountSet = ETrue;
+ break;
+ }
+
+ case KAtrRepeatDur:
+
+ {
+ iAnimTime->SetRepeatDurationTime( (TInt32)aValue );
+ break;
+ }
+ case KAtrEnd:
+ {
+ iAnimTime->SetEndTime( aValue );
+ break;
+ }
+ case KAtrFrom:
+ {
+
+ switch(iDataType)
+ { // Length float.
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ {
+ iFromFloat = aValue;
+ break;
+ }
+ default:
+ break;
+ }
+
+ }
+ break;
+ case KAtrTo:
+ {
+
+ switch(iDataType)
+ { // Length float.
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ {
+ iToFloat= aValue ;
+ break;
+ }
+ default:
+ break;
+ // color and integer values.
+
+ }
+
+ }
+ break;
+ case KAtrBy:
+ {
+ switch(iDataType)
+ { // Length float.
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ {
+ iToFloat = iFromFloat + aValue;
+ break;
+ }
+ default:
+ break;
+ }
+
+ }
+ break;
+ default:
+ {
+ //JSR226 change in question. This is so you can set the original value from the JSR226 side.
+ if (aNameId == iAttrId)
+ {
+ iOrgFloat = aValue;
+ }
+
+ return CSvgElementImpl::SetAttributeFloatL( aNameId,aValue );
+ }
+ }
+ return KErrNone;
+
+ }
+
+TInt CSvgAnimationBase::SetAttributeIntL( const TInt aNameId,
+ const TInt32 aValue )
+ {
+ switch(aNameId)
+ {
+ case KAtrFrom:
+ {
+ switch(iDataType)
+ {
+ case KSvgTypeTextAnchor:
+ case KSvgTypeColor:
+ case KSvgTypeVisibility:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeDisplay:
+ iFromInt = aValue;
+ iNoFrom = EFalse;
+ break;
+
+ default:return KErrNotFound;
+ }
+ }
+ break;
+ case KAtrTo:
+ {
+ switch(iDataType)
+ {
+ // only these are supported as Int
+ case KSvgTypeTextAnchor:
+ case KSvgTypeColor:
+ case KSvgTypeVisibility:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeDisplay:
+ iToInt = aValue;
+ iHaveTo = ETrue;
+ break;
+ default:return KErrNotFound;
+ }
+ }
+ break;
+ case KAtrBy:
+ {
+ // By is not supported.
+ if(iDataType == KSvgTypeColor)
+ {
+ iToInt = (TInt32 ) AddColor( iFromInt, (TInt32)aValue);
+ break;
+ }
+ }
+ break;
+ case KAtrAdditive:
+ {
+ iAdditive = (TUint8)aValue;
+ iAdditiveOrg = (TUint8)aValue;
+ break;
+ }
+
+ case KAtrAccumulate:
+ {
+ iAccumulate = (TUint8)aValue;
+ break;
+ }
+
+ case KAtrCalcMode:
+ {
+ iAnimTime->SetCalMode( (TUint8)aValue );
+ break;
+ }
+
+ case KAtrRestart:
+ {
+ iAnimRestart = (TUint8) aValue;
+ break;
+ }
+
+ // this is confusing but in case of animation
+ // elements the style attributes really do not matter.
+ case KCSS_ATTR_FILL:
+ {
+ iFill = (TUint8) aValue;
+ break;
+ }
+
+ default:
+ return CSvgElementImpl::SetAttributeIntL( aNameId, aValue );
+ }
+ return KErrNone;
+}
+
+TInt CSvgAnimationBase::GetAttributeIntL( const TInt aNameId,
+ TInt32& aValue )
+{
+switch(aNameId)
+ {
+ case KAtrFrom:
+ {
+ if(!iNoFrom)
+ {
+ switch(iDataType)
+ {
+ case KSvgTypeTextAnchor:
+ case KSvgTypeColor:
+ case KSvgTypeVisibility:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeDisplay:
+ aValue = iFromInt;
+ break;
+
+ default:return KErrNotFound;
+ }
+ }
+ }
+ break;
+ case KAtrTo:
+ {
+ if(iHaveTo)
+ {
+ switch(iDataType)
+ {
+ case KSvgTypeTextAnchor:
+ case KSvgTypeColor:
+ case KSvgTypeVisibility:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeDisplay:
+ aValue = iToInt;
+ break;
+ default:return KErrNotFound;
+ }
+ }
+ }
+ break;
+ case KAtrBy:
+ {
+ // By is not supported.
+ if(iDataType == KSvgTypeColor)
+ {
+ aValue = (TInt32 ) SubtractColor( iToInt, iFromInt );
+ }
+ }
+ break;
+ case KAtrAdditive:
+ {
+ aValue = iAdditive ;
+ break;
+ }
+
+ case KAtrAccumulate:
+ {
+ aValue = iAccumulate ;
+ break;
+ }
+ case KAtrCalcMode:
+ {
+ aValue = iAnimTime->CalMode();
+ break;
+ }
+ case KAtrRestart:
+ {
+ aValue = iAnimRestart ;
+ break;
+ }
+ case KCSS_ATTR_FILL:
+ {
+ aValue = iFill ;
+ break;
+ }
+ default:
+ return CSvgElementImpl::GetAttributeIntL( aNameId, aValue );
+ }
+ return KErrNone;
+ }
+
+void CSvgAnimationBase::ResetL(MSvgEvent* aEvent, CSvgAnimationBase* aAnimElement)
+ {
+
+ TSvgTimerEvent* timerEvent = ( TSvgTimerEvent* ) aEvent;
+ TInt32 lCurrentTime = timerEvent->Time();
+ iAnimTime->Reset();
+ TInt32 lBeginTime = iAbsoluteBeginTime;
+
+ //If Stop was called Dynamic endtime list(iEndTimeList) was reset to iInitialEndTimesList
+ // This needs recalculation of iEndTime inside animTimeController
+ TInt32 lSimpleDur = SimpleDuration();
+ if( lSimpleDur != KTimeIndefinite)
+ {
+ iAnimTime->SetEndTime(lSimpleDur);
+ }
+
+ TInt32 lDuration = iAnimTime->DurationTime();
+
+ // reset back to the original values.
+ aAnimElement->ResetReferenceElementL();
+
+ // Set the Additive;
+ iAdditive = iAdditiveOrg;
+
+ if(lCurrentTime >= lBeginTime && lCurrentTime < lSimpleDur)
+ {
+ // set the new status.
+ iAnimStatus = KAnimActive;
+ iHadBegun = ETrue;
+
+ // calculate the CurrentRepeatCount.
+ if(lDuration> 0)
+ {
+ iCurrentRepeatCount = (TUint16)((lCurrentTime - lBeginTime ) / lDuration);
+
+ // check it if it is bigger than the allowed repeatCount.
+ if(iCurrentRepeatCount > iRepeatCount)
+ {
+ // truncate the repeatCount
+ iCurrentRepeatCount = (TUint16)iRepeatCount;
+ }
+ }
+ else
+ {
+ // No duration means repeatCount is ignored.
+ iCurrentRepeatCount = 0;
+ }
+
+ if(aAnimElement->ElemID()== KSvgAnimateTransformElement ||aAnimElement->ElemID()== KSvgAnimateMotionElement )
+ {
+ if(aAnimElement->ElemID() == KSvgAnimateMotionElement)
+ {
+ aAnimElement->ResetAnimationL();
+ }
+ aAnimElement->SetAccumulateValuesForSetMediaTime();
+ }
+ // set the begin time.
+ iAnimTime->SetBeginTime(lBeginTime + (iCurrentRepeatCount*lDuration));
+
+ // Send the begin event.
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->NotifyAnimationStarted();
+ TSvgInternalEvent Beginevent ( ESvgEventBeginEvent, this, lBeginTime );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &Beginevent );
+
+
+ // Send Repeat Events.
+ if(iAnimTime->DurationTime() != KTimeIndefinite)
+ {
+ TUint16 lTotalRepeatEvents = (TUint16)iCurrentRepeatCount;
+ for(TUint16 i= 0; i < lTotalRepeatEvents; i++)
+ {
+ TUint32 lDur = (TUint32)iAnimTime->DurationTime();
+ TInt lCount = (TUint16)(i+1);
+ TInt32 lRepeatTime = lBeginTime + (TInt32)(lDur*lCount);
+ TSvgInternalEvent Repeatevent ( ESvgEventRepeatEvent, this, lRepeatTime );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &Repeatevent );
+ }
+ }
+ }
+ else if(lCurrentTime >= lSimpleDur)
+ {
+ // made active to calculate the freeze value.
+ iAnimStatus = KAnimActive;
+ iHadBegun = ETrue;
+ TBool lAcuumulate = EFalse;
+ if(lDuration> 0)
+ {
+ iCurrentRepeatCount = (TUint16)((lCurrentTime - lBeginTime ) / lDuration);
+
+ // check below is for the correct repeatCount setting this is
+ // necessary for accumulate values calculation.
+ if(iCurrentRepeatCount >= iRepeatCount || iRepeatCount == KRepeatCountMax)
+ {
+ // this means that the repeatCount was not specified so it is not supposed to send the
+ // repeatEvents.
+ if(iRepeatCount == 1)
+ {
+ iCurrentRepeatCount = 0;
+ }
+ else
+ {
+ if(iRepeatCountSet)
+ {
+ // repeatCount was specified.
+ if(iRepeatCount != KRepeatCountMax)
+ {
+ // repeatCount is not "indefinite"
+ iCurrentRepeatCount = (TUint16) iRepeatCount;
+ }
+ }
+ else
+ {
+ // what if repeatDuration was specified.
+ if(KTimeIndefinite != iAnimTime->RepeatDurationTime())
+ {
+ // repeatDuration is not "indefinite"
+ iCurrentRepeatCount = (iAnimTime->RepeatDurationTime()) / lDuration;
+ }
+ }
+ lAcuumulate = ETrue;
+ }
+ }
+ }
+ else
+ {
+ iCurrentRepeatCount = 0;
+ }
+ //take the last begin time so that accumulation happens correctly.
+ // if "end" needs to be checked
+ TInt32 lEnd = iAnimTime->GetOriginalEndTime();
+ TInt count =0;
+ TBool lChangeRepeatCount = EFalse;
+ if(KTimeIndefinite != lEnd)
+ {
+ for(; count <= iCurrentRepeatCount; count++)
+ {
+ // check is the repaetCount is more than the valid range.
+ // depending on the end time.
+ if((lBeginTime+(count*lDuration)) < lEnd)
+ {
+
+ }
+ else
+ {
+ // original end time must be grater than the begin time to be valid.
+ if(lEnd > lBeginTime)
+ {
+ // repeatCount needs to be changed.
+ lChangeRepeatCount = ETrue;
+ }
+ break;
+
+ }
+ }
+ }
+ if(lChangeRepeatCount)
+ {
+ if(count >0)
+ {
+ iCurrentRepeatCount = count - 1;
+ }
+ else
+ {
+ iCurrentRepeatCount = 0;
+ }
+ }
+ iAnimTime->SetBeginTime(lBeginTime + (iCurrentRepeatCount)*lDuration);
+
+ // Decrement the repeatCount; this is because the accumulate will give
+ //additional one repeatCouont for seeking beyond the end time.
+ TReal32 RealRepeatCount = iCurrentRepeatCount;
+ if(iCurrentRepeatCount > 0 && ( RealRepeatCount == iRepeatCount || iRepeatCount == KRepeatCountMax))
+ {
+ iCurrentRepeatCount--;
+ }
+
+ // check for animateTransforms and animateMotion for iAccumulate
+ // which means that these need to accumulate separately.
+ if(aAnimElement->ElemID()== KSvgAnimateTransformElement ||aAnimElement->ElemID()== KSvgAnimateMotionElement )
+ {
+ if(iAccumulate == KAccumSum && lAcuumulate)
+ {
+ // if it is animateMotion reset the current path indicaters.
+ if(aAnimElement->ElemID() == KSvgAnimateMotionElement)
+ {
+ aAnimElement->ResetAnimationL();
+ }
+ // accumulate.
+ aAnimElement->SetAccumulateValuesForSetMediaTime();
+ }
+ }
+
+ // send the begin
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->NotifyAnimationStarted();
+ TSvgInternalEvent Beginevent ( ESvgEventBeginEvent, this, lBeginTime );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &Beginevent );
+ // send the begin, repeat, and end Events.
+ if(iAnimTime->DurationTime() != KTimeIndefinite)
+ {
+ TUint16 lTotalRepeatEvents = (TUint16)iCurrentRepeatCount;
+ for(TUint16 i= 0; i < lTotalRepeatEvents; i++)
+ {
+ TUint32 lDur = (TUint32)iAnimTime->DurationTime();
+ TInt lCount = (TUint16)(i+1);
+ TInt32 lRepeatTime = lBeginTime + (TInt32)(lDur*lCount);
+ TSvgInternalEvent Repeatevent ( ESvgEventRepeatEvent, this, lRepeatTime );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &Repeatevent );
+ }
+ }
+
+ // send end events.
+ if(lSimpleDur != (TInt32)KTimeIndefinite)
+ {
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->NotifyAnimationEnded();
+ TSvgInternalEvent Endevent ( ESvgEventEndEvent, this, lSimpleDur );
+ ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->ProcessEventL(
+ ( CSvgDocumentImpl* ) OwnerDocument(), &Endevent );
+ TSvgTimerEvent lEndTime1(lSimpleDur);
+ iIsEndEventSent = ETrue;
+ // calculate the freeze values.
+ if(iFill == KAnimFillFreeze)
+ {
+ // if it has to freeze than calculate the final values.
+ aAnimElement->AnimProcL(&lEndTime1);
+
+ // this is to avoid it going in the AnimProcL again. Which will change
+ // the freeze values.
+ // THIS MUST BE DONE ONLY WHEN THE repeatCount is fractional.
+ TReal32 lFractReapeatDur = 0;
+ if(KTimeIndefinite != iAnimTime->RepeatDurationTime())
+ {
+ // this is to check whether this matches a fractional repeatCount.
+ lFractReapeatDur = iAnimTime->RepeatDurationTime();
+ lFractReapeatDur = (lFractReapeatDur - (lDuration*(iCurrentRepeatCount+1))) ;
+ }
+ if((iRepeatCount - TInt(iRepeatCount)>0 || lFractReapeatDur > 0 )
+ || ((iAnimTime->BeginTime() + iAnimTime->DurationTime()) > lSimpleDur &&
+ iAnimTime->BeginTime()!= lSimpleDur))
+ {
+ // do not go to AnimProcL only once.
+ iDoFreeze = ETrue;
+ }
+ }
+ else
+ {
+ // this should be ok . But how do we get the initial value.
+ aAnimElement->SetToInitialValueL();
+ // do not go to animProcL;
+ iDoFreeze = ETrue;
+ }
+ }
+ }
+ }
+
+void CSvgAnimationBase::SetOriginalValues_DOMReuse()
+ {
+
+ if(iAnimTime)
+ {
+ iAnimTime->SetOriginalValues_DOMReuse();
+ }
+ }
+CGfxGeneralPath* CSvgAnimationBase::GetPathAttribute(TInt aAttributeId)
+{
+if(iDataType == KSvgTypePath)
+ {
+ switch(aAttributeId)
+ {
+ case KAtrTo: return iToPath;
+ case KAtrFrom: return iOrgFromPath;
+ default :
+ return NULL;
+ }
+ }
+return NULL;
+}
+void CSvgAnimationBase::SetPathAttribute(TInt aAttributeId, CGfxGeneralPath* aPathHandle)
+{
+ if(iDataType == KSvgTypePath)
+ {
+ switch(aAttributeId)
+ {
+ case KAtrTo:
+ {
+ if(iToPath == aPathHandle)
+ {
+ return;
+ }
+ delete iToPath;
+ iToPath = aPathHandle;
+ }
+ break;
+ case KAtrFrom:
+ {
+
+ if(iOrgFromPath == aPathHandle)
+ {
+ return;
+ }
+
+ delete iOrgFromPath;
+ iOrgFromPath = aPathHandle;
+
+ // clone it .
+ delete iFromPath;
+ iFromPath = NULL;
+
+ /************************************/
+ TRAPD(error ,iFromPath = CGfxGeneralPath::NewL());
+ if(error == KErrNone)
+ {
+ RArray<TUint32>* lTypes = aPathHandle->PointTypeArray();
+ RArray<TFloatFixPt>* lCoords = aPathHandle->PointCoordsArrayAll();
+ TRAP_IGNORE( iFromPath->SetPointTypeArrayL(lTypes) );
+ TRAP_IGNORE( iFromPath->SetPointCoordsArrayL(lCoords) );
+ }
+ /************************************/
+
+ }
+ break;
+ default :
+ break;
+ }
+ }
+
+}
+
+
+TUint8 CSvgAnimationBase::GetAnimStatus()
+{
+ return iAnimStatus;
+}
+
+// added for forward referencing
+TInt CSvgAnimationBase::SetRefElemById(const TDesC& aName)
+ {
+ //If iTargetElement is Set to Null means that some junk Href was given
+ iTargetElement = ( CSvgElementImpl*)((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( aName );
+
+ if(iTargetElement==NULL)
+ {
+ return KErrNotFound;
+ }
+ else
+ {
+ iTargetElement->iHasAnimationBase = (TInt)this;
+ TRAPD(lError,GetAttrValueL());
+ if ( lError != KErrNone )
+ {
+ // ignore trap error
+ }
+ return KErrNone;
+ }
+ }
+
+void CSvgAnimationBase::CopyL(CSvgAnimationBase* newElement)
+ {
+ if(newElement)
+ {
+
+ // copy this pointer.
+ this->iAnimTime->CopyL(newElement->iAnimTime);
+
+ if(iEndPath)
+ {
+ newElement->iEndPath = CGfxGeneralPath::NewL();
+
+ RArray<TUint32>* lTypes = this->iEndPath->PointTypeArray();
+ RArray<TFloatFixPt>* lCoords = this->iEndPath->PointCoordsArrayAll();
+ newElement->iEndPath->SetPointTypeArrayL(lTypes);
+ newElement->iEndPath->SetPointCoordsArrayL(lCoords);
+ }
+ if(iOrgPath)
+ {
+ newElement->iOrgPath = CGfxGeneralPath::NewL();
+
+ RArray<TUint32>* lTypes = this->iOrgPath->PointTypeArray();
+ RArray<TFloatFixPt>* lCoords = this->iOrgPath->PointCoordsArrayAll();
+ newElement->iOrgPath->SetPointTypeArrayL(lTypes);
+ newElement->iOrgPath->SetPointCoordsArrayL(lCoords);
+ }
+ if(iFromPath)
+ {
+ newElement->iFromPath = CGfxGeneralPath::NewL();
+
+ RArray<TUint32>* lTypes = this->iFromPath->PointTypeArray();
+ RArray<TFloatFixPt>* lCoords = this->iFromPath->PointCoordsArrayAll();
+ newElement->iFromPath->SetPointTypeArrayL(lTypes);
+ newElement->iFromPath->SetPointCoordsArrayL(lCoords);
+ }
+ if(iToPath)
+ {
+ newElement->iToPath = CGfxGeneralPath::NewL();
+
+ RArray<TUint32>* lTypes = this->iToPath->PointTypeArray();
+ RArray<TFloatFixPt>* lCoords = this->iToPath->PointCoordsArrayAll();
+ newElement->iToPath->SetPointTypeArrayL(lTypes);
+ newElement->iToPath->SetPointCoordsArrayL(lCoords);
+ }
+ if(iOrgFromPath)
+ {
+ newElement->iOrgFromPath = CGfxGeneralPath::NewL();
+
+ RArray<TUint32>* lTypes = this->iOrgFromPath->PointTypeArray();
+ RArray<TFloatFixPt>* lCoords = this->iOrgFromPath->PointCoordsArrayAll();
+ newElement->iOrgFromPath->SetPointTypeArrayL(lTypes);
+ newElement->iOrgFromPath->SetPointCoordsArrayL(lCoords);
+ }
+ if(iValuesFloat)
+ {
+
+ TInt lCount = iValuesFloat->Count();
+ newElement->iValuesFloat->Reset();
+ for(TInt i=0; i<lCount; i++)
+ {
+ newElement->iValuesFloat->AppendL(iValuesFloat->operator[](i));
+ }
+ }
+ if(iValuesInt)
+ {
+ TInt lCount = iValuesInt->Count();
+ newElement->iValuesInt->Reset();
+ for(TInt i=0; i<lCount; i++)
+ {
+ User::LeaveIfError(newElement->iValuesInt->Append(iValuesInt->operator[](i)));
+ }
+ }
+
+ //iValuesPath
+ if(iValuesPath)
+ {
+ TInt lCount = iValuesPath->Count();
+ newElement->iValuesPath->Reset();
+ for(TInt i=0; i<lCount; i++)
+ {
+ CGfxGeneralPath* lOrgPath = (this->iValuesPath)->operator[](i);
+ RArray<TUint32>* lTypes = lOrgPath->PointTypeArray();
+ RArray<TFloatFixPt>* lCoords = lOrgPath->PointCoordsArrayAll();
+
+ CGfxGeneralPath* lClonePath = CGfxGeneralPath::NewL();
+ CleanupStack::PushL(lClonePath);
+ lClonePath->SetPointTypeArrayL(lTypes);
+ lClonePath->SetPointCoordsArrayL(lCoords);
+ newElement->iValuesPath->AppendL((CGfxGeneralPath*)lClonePath);
+ CleanupStack::Pop(lClonePath);
+ }
+ }
+
+ //iValuesViewBox
+ if(iValuesViewBox)
+ {
+ TInt lCount = iValuesViewBox->Count();
+ newElement->iValuesViewBox->Reset();
+ for(TInt i=0; i<lCount; i++)
+ {
+ User::LeaveIfError(newElement->iValuesViewBox->Append(iValuesViewBox->operator[](i)));
+ }
+ }
+
+ newElement->iEndOffset = iEndOffset;
+ newElement->iRepeatCount = iRepeatCount;
+ newElement->iRepeatEndValue = iRepeatEndValue;
+ newElement->iAbsoluteBeginTime = iAbsoluteBeginTime;
+ newElement->iAttributeFlag = iAttributeFlag;
+ newElement->iEndInt = iEndInt;
+ newElement->iPropInt = iPropInt;
+ newElement->iOrgInt = iOrgInt;
+ newElement->iFromInt = iFromInt;
+ newElement->iToInt = iToInt;
+ newElement->iOrgFromInt = iOrgFromInt;
+ newElement->iIsBeginSet = iIsBeginSet;
+ newElement->iPropFloat = iPropFloat;
+ newElement->iOrgFloat = iOrgFloat;
+ newElement->iFromFloat = iFromFloat;
+ newElement->iToFloat = iToFloat;
+ newElement->iOrgFromFloat = iOrgFromFloat;
+ newElement->iEndFloat = iEndFloat;
+ newElement->iBeginTimeIndex = iBeginTimeIndex;
+ //newElement->iEndAccessKeyCode = iEndAccessKeyCode;
+ newElement->iCurrentRepeatCount = iCurrentRepeatCount;
+ newElement->iAttrId = iAttrId;
+ newElement->iDataType = iDataType;
+ newElement->iInitDone = iInitDone;
+ newElement->iTargetSet = iTargetSet;
+ newElement->iNoFrom = iNoFrom;
+ newElement->iHaveTo = iHaveTo;
+ newElement->iHaveBy = iHaveBy;
+ newElement->iHaveValues = iHaveValues;
+ newElement->iAnimStatus = iAnimStatus;
+
+ //viewBox
+ newElement->iOrgViewBox = iOrgViewBox;
+ newElement->iFromViewBox = iFromViewBox;
+ newElement->iToViewBox = iToViewBox;
+ newElement->iOrgFromViewBox = iOrgFromViewBox;
+ newElement->iEndViewBox = iEndViewBox;
+
+// newElement->iEndReferenceEvent = iEndReferenceEvent;
+ //////////////////////////////
+ newElement->iAnimStatus = iAnimStatus;
+ newElement->iFill = iFill;
+ newElement->iHadBegun = iHadBegun;
+ newElement->iAnimRestart = iAnimRestart;
+ newElement->iAccumulate = iAccumulate;
+ newElement->iAdditive = iAdditive;
+ newElement->iAdditiveOrg = iAdditiveOrg;
+ newElement->iOverrideTime = iOverrideTime;
+ newElement->iRepeatCountSet = iRepeatCountSet;
+ newElement->iDoFreeze = iDoFreeze;
+ newElement->iKeyTimesPresent = iKeyTimesPresent;
+ newElement->iCheckFirstAnim = iCheckFirstAnim;
+
+ newElement->iIsUserSeek = EFalse;
+
+
+
+
+ if(iEventList)
+ {
+ TInt lCount = iEventList->Count();
+
+
+ newElement->iEventList->Reset();
+ for(TInt i=0;i<lCount;i++ )
+ {
+ newElement->iEventList->AppendL(iEventList->operator[](i));
+ (newElement->iEventList->operator[](i)).iReferenceElemeId = NULL;
+ if(iEventList->operator[](i).iReferenceElemeId)
+ {
+ (newElement->iEventList->operator[](i)).iReferenceElemeId = (iEventList->operator[](i).iReferenceElemeId)->AllocL();
+ }
+ else
+ {
+ (newElement->iEventList->operator[](i)).iReferenceElemeId = NULL;
+ }
+ }
+ }
+
+
+ if(iEndTimeList)
+ {
+ TInt lCount = iEndTimeList->Count();
+ newElement->iEndTimeList->Reset();
+ for(TInt i=0;i<lCount;i++ )
+ {
+ newElement->iEndTimeList->AppendL(iEndTimeList->operator[](i));
+ (newElement->iEndTimeList->operator[](i)).iReferenceElemeId = NULL;
+ if(iEndTimeList->operator[](i).iReferenceElemeId)
+ {
+ (newElement->iEndTimeList->operator[](i)).iReferenceElemeId = (iEndTimeList->operator[](i).iReferenceElemeId)->AllocL();
+ }
+ else
+ {
+ (newElement->iEndTimeList->operator[](i)).iReferenceElemeId = NULL;
+ }
+ }
+ }
+ }
+
+ }
+// Call stack on Stop and Play
+// CSvgEngineInterfaceImpl::Replay
+// CSvgEngineImpl::SetMediaTime
+// CSvgEngineImpl::SeekEngine
+// CSvgTimeContainer::UserSeek
+// CSvgDocumentImpl::Reset
+// CSvgEventHandler::Reset
+// CSvgEventHandler::DeactivateAnimations
+// CSvgAnimateElementImpl::DeactivateAnimation
+void CSvgAnimationBase::DeactivateAnimation(CSvgAnimationBase* aElement)
+{
+ if(!aElement)return;
+
+ iDoFreeze = EFalse;
+
+ // this should work for multiple begins.
+ if(iEventList->Count()> 0)
+ {
+ if(iEventList->operator[](0).iEvent != ESvgEventNone || iEventList->Count() > 1)
+ {
+ // if it is not absolute.
+ // reset this to initials.
+ iAbsoluteBeginTime = KTimeIndefinite;
+ iHadBegun= EFalse;
+ iBeginTimeIndex = 0 ;
+ iCurrentRepeatCount= 0;
+ iInitDone = EFalse;
+ iOverrideTime = EFalse;
+ iAnimStatus = KAnimNotActive;
+ iAnimTime->SetBeginTime(KTimeIndefinite);
+
+ // reset the time related stuffs.
+ iAnimTime->ReInitialize();
+
+ // this is necessary.
+ if(iAdditiveOrg == KAdditiveReplace)
+ {
+ iAdditive= KAdditivePass;
+ }
+ // this is a virtual function.
+ aElement->ReInitializeAnimation();
+ }
+ }
+
+ // Set the end times to indefinite.
+ if(iEndTimeList->Count()> 0 )
+ {
+ if(iEndTimeList->operator[](0).iEvent != ESvgEventNone )
+ {
+ iAnimTime->SetEndTimesIndefinite();
+ }
+ }
+}
+
+TBool CSvgAnimationBase::ParseViewBoxValue(const TDesC& aValue, TGfxRectangle2D& aRect)
+ {
+
+ TLex input( aValue );
+ TReal32 vBoxX=0;
+ TReal32 vBoxY=0;
+ TReal32 vBoxW=0;
+ TReal32 vBoxH=0;
+
+ input.SkipSpace();
+ if (input.Val( vBoxX, '.' ) != KErrNone)
+ vBoxX= 0;
+
+ if( input.Peek() == ',' )
+ input.Inc();
+ input.SkipSpace();
+ if( input.Peek() == ',' )
+ input.Inc();
+
+ if (input.Val( vBoxY, '.' ) != KErrNone)
+ vBoxY= 0;
+
+
+ if( input.Peek() == ',' )
+ input.Inc();
+ input.SkipSpace();
+ if( input.Peek() == ',' )
+ input.Inc();
+
+ if (input.Val( vBoxW, '.' ) != KErrNone)
+ vBoxW= 0;
+
+ if( input.Peek() == ',' )
+ input.Inc();
+ input.SkipSpace();
+ if( input.Peek() == ',' )
+ input.Inc();
+
+ if (input.Val( vBoxH, '.' ) != KErrNone)
+ vBoxH= 0;
+
+ aRect= TGfxRectangle2D( vBoxX, vBoxY, vBoxW, vBoxH );
+ return ETrue;
+ }
+void CSvgAnimationBase::CheckForEndTimesAndFreezeL(CSvgAnimationBase* aElement)
+{
+ if(iAnimStatus == KAnimFinished) // KAnimFinished
+ {
+ if(!iDoFreeze)
+ {
+ iDoFreeze = ETrue;
+ return;
+ }
+ if ( iFill == KAnimFillFreeze )
+ {
+ aElement->SetToEndValueL();
+ }
+
+ }
+}
+
+// function for decoder
+void CSvgAnimationBase::AddEndTime( TInt32 aEndTime )
+ {
+ if(iAnimTime)
+ iAnimTime->AddEndTime(aEndTime);
+ }
+
+void CSvgAnimationBase::SetAccumulateValuesForSetMediaTime()
+{
+}
+
+TBool CSvgAnimationBase::IsSelfDependentForBegin()
+{
+
+ /*********************************************************************
+
+ This is used only after setmediaTime is done on the svg DOCUMENT.
+ This function is to tell whether the elements begin depends on its end.
+
+ *********************************************************************/
+
+ if(iEventList->Count()> 0)
+ {
+ TInt lCount = iEventList->Count();
+ for(TInt i=0; i< lCount; i++)
+ {
+ if(iEventList->operator[](i).iTargetElement == this &&
+ iEventList->operator[](i).iEvent == ESvgEventEndEvent)
+ {
+ return ETrue;
+ }
+ }
+ }
+
+ return EFalse;
+}
+ void CSvgAnimationBase::SetFromValuesL()
+{
+ /*
+ * this is to make sure that the iOrg values do not get modified once set.
+ */
+ switch ( iDataType )
+ {
+ case KSvgTypeOpacity:
+ case KSvgTypeLength:
+ {
+ // This is to handle all cases, was only fill="freeze" cases.
+ if (iNoFrom)
+ {
+ TFloatFixPt lTempValue;
+ iTargetElement->GetAttributeFloat( iAttrId, lTempValue );
+ iFromFloat = lTempValue;
+ }
+ }
+ break;
+
+ case KSvgTypeList:
+ case KSvgTypePath:
+
+ {
+
+ if (iNoFrom )
+ {
+ if ( iFromPath )
+ {
+ delete iFromPath;
+ iFromPath = NULL;
+ }
+ CGfxGeneralPath*parentPath;
+ iFromPath = CGfxGeneralPath::NewL();
+ iTargetElement->GetAttributePath( iAttrId, parentPath );
+ CGfxPathIterator* itr;
+ TGfxAffineTransform affineTransform;
+ parentPath->GetPathIteratorL( &affineTransform, itr );
+ CleanupStack::PushL( itr );
+ iFromPath->AppendL( itr );
+ CleanupStack::PopAndDestroy( 1 ); // destroy itr
+ }
+
+ }
+ break;
+ /*
+ * The above algorithm can be applicable to color as well.
+ * Results are not same as adobe.
+ */
+ case KSvgTypeColor:
+
+ break;
+
+ // following are all strings data types.
+ case KSvgTypeTextAnchor:
+ case KSvgTypeGradientUnits:
+ case KSvgTypeSpreadMethod:
+ case KSvgTypeInteger:
+ case KSvgTypeDisplay:
+ case KSvgTypeVisibility:
+ if (iAttributeFlag)
+ if ( iNoFrom )
+ {
+ iTargetElement->GetAttributeIntL( iAttrId, iFromInt);
+ }
+ break;
+
+ // viewBox
+ case KSvgTypeViewBox:
+ {
+ if(iTargetElement->ElemID() == KSvgSvgElement)
+ {
+ if (iNoFrom)
+ {
+ TGfxRectangle2D lTempVierwBox;
+ ((CSvgSvgElementImpl*)iTargetElement)->GetViewBox( lTempVierwBox );
+ iFromViewBox = lTempVierwBox;
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+TInt32 CSvgAnimationBase::GetAbsoluteBeginTime()
+ {
+ return iAbsoluteBeginTime;
+ }
+
+TInt32 CSvgAnimationBase::GetEndTime()
+ {
+ return iAnimTime->EndTime();
+ }
+
+
+void CSvgAnimationBase::CheckBeginTime()
+ {
+
+ if (iAnimTime->BeginTimesCount() == 0 && iAnimTime->BeginTime() == 0)
+ {
+ iAnimTime->AddBeginTime(0);
+ iAnimTime->AddToInitialList(0);
+ }
+ }
+
+void CSvgAnimationBase::StoreRepeatId( const TDesC& aValue, TBool aRepeatWasInBeginAtt )
+{
+ if (iRepeatId)
+ {
+ delete iRepeatId;
+ iRepeatId = NULL;
+ }
+
+ iRepeatInBegin = aRepeatWasInBeginAtt;
+ TRAPD( error, iRepeatId = aValue.AllocL() );
+ if ( error != KErrNone )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgAnimationBase::StoreRepeatId: iRepeatId = aValue.AllocL() leaves");
+ #endif
+ }
+}
+
+void CSvgAnimationBase::NotifyAnimationsRepeatingOnThisOneL( const TDesC* aId )
+{
+ // Get THhe Engine's Current Media Time.
+ CSvgDocumentImpl* lDocument = ((CSvgDocumentImpl*)iOwnerDocument);
+
+ if ( !aId || aId->Length() == 0 )
+ return;
+
+ TInt32 lEngineTime = ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->CurrentTIme();
+
+ TInt lAnimationCount = lDocument->iSvgAnimations.Count();
+ for (TInt i=0; i < lAnimationCount; i++)
+ {
+ CSvgAnimationBase* lAnimatingElement = lDocument->iSvgAnimations[i];
+ if ( lAnimatingElement->iRepeatId && (lAnimatingElement->iRepeatId->CompareF(*aId) == 0 ) )
+ {
+ if (lAnimatingElement->iRepeatInBegin)
+ {
+ lAnimatingElement->SetBeginByEventL( lAnimatingElement,lEngineTime, ETrue );
+ }
+ else
+ {
+ //it must have been in an end attribute
+ lAnimatingElement->SetEndByEvent(lAnimatingElement, lEngineTime );
+ }
+
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+// void CSvgAnimationBase::FindColorDistanceL()
+// This function computes the distance between colours for the purpose
+// of animateColor element. Colours are treated as a 3D point
+// with r, g, b acting as axes. It modifies the iValuesFloat array and each
+// index contains the cummulative length(from start colour) of the segment
+// with same index
+// ---------------------------------------------------------------------------
+void CSvgAnimationBase::FindColorDistanceL()
+ {
+ TInt lcount = iValuesInt->Count();
+
+ //Fix for MLIO-743FRR:check whether "values" attribute is present
+ if ( lcount > 0 )
+ {
+ iValuesFloat->AppendL( 0 );
+ }
+
+ TFloatFixPt len = 0;
+
+ for(TInt i = 1; i < lcount; i++)
+ {
+ TInt c1 = (*iValuesInt)[i-1];
+ TInt c2 = (*iValuesInt)[i];
+ TInt r1 = c1 & 0x00FF0000;
+ r1 = r1 >> 16;
+ TInt g1 = c1 & 0x0000FF00;
+ g1 = g1 >> 8;
+ TInt b1 = c1 & 0x000000FF;
+
+ TInt r2 = c2 & 0x00FF0000;
+ r2 = r2 >> 16;
+ TInt g2 = c2 & 0x0000FF00;
+ g2 = g2 >> 8;
+ TInt b2 = c2 & 0x000000FF;
+
+ TInt dr = r1 - r2;
+ TInt dg = g1 - g2;
+ TInt db = b1 - b2;
+
+ TFloatFixPt length = TFloatFixPt::Sqrt( dr * dr + dg * dg + db * db );
+ //TFloatFixPt length = Math::Sqrt( dr * dr + dg * dg + db * db );
+ len += length;
+ iValuesFloat->AppendL( len );
+ }
+ }
+
+TBool CSvgAnimationBase::IsFillFreeze()
+ {
+ if ( iFill == KAnimFillFreeze )
+ return ETrue;
+ else
+ return EFalse;
+ }
+void CSvgAnimationBase::ResetTimes()
+ {
+ iAnimTime->ResetBeginTime();
+ iAnimTime->ResetEndTime();
+ }
+
+// End of file