diff -r 000000000000 -r 88edb906c587 svgtopt/SVG/SVGImpl/src/SVGAnimationBase.cpp --- /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 +#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( 1 ); + iValuesInt = new ( ELeave ) RArray( 1 ); + iValuesPath = new ( ELeave ) RPointerArray( 1 ); + // viewBox + iValuesViewBox = new ( ELeave ) RArray( 1 ); + iEventList = new ( ELeave )CArrayFixFlat( 1 ); + iEndTimeList = new ( ELeave )CArrayFixFlat( 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: + // . +/- + //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* fromPoints; + RArray* 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* ) 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*& 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*& aEventList) + { + if (iEventList) + { + iEventList->Reset(); + delete iEventList; + iEventList= NULL; + } + iEventList= aEventList; + } + +void CSvgAnimationBase::SetEndTimeList(CArrayFixFlat*& 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*& aArray) + { + if (iValuesInt) + { + iValuesInt->Close(); + delete iValuesInt; + } + iValuesInt= aArray; + } + +void CSvgAnimationBase::SetFloatValuesArray( RArray*& aArray) + { + if (iValuesFloat) + { + iValuesFloat->Close(); + delete iValuesFloat; + } + + iValuesFloat= aArray; + } + +void CSvgAnimationBase::SetViewBoxValuesArray( RArray*& aArray) + { + if (iValuesViewBox) + { + iValuesViewBox->Close(); + delete iValuesViewBox; + } + + iValuesViewBox= aArray; + } + +void CSvgAnimationBase::SetPathValuesArray( RPointerArray*& 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*& aArray) + { + if (iAnimTime) + { + iAnimTime->SetKeyTimeArray(aArray); + } + } + +void CSvgAnimationBase::SetAnimTimeArray(RArray*& 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* lTypes = aPathHandle->PointTypeArray(); + RArray* 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* lTypes = this->iEndPath->PointTypeArray(); + RArray* lCoords = this->iEndPath->PointCoordsArrayAll(); + newElement->iEndPath->SetPointTypeArrayL(lTypes); + newElement->iEndPath->SetPointCoordsArrayL(lCoords); + } + if(iOrgPath) + { + newElement->iOrgPath = CGfxGeneralPath::NewL(); + + RArray* lTypes = this->iOrgPath->PointTypeArray(); + RArray* lCoords = this->iOrgPath->PointCoordsArrayAll(); + newElement->iOrgPath->SetPointTypeArrayL(lTypes); + newElement->iOrgPath->SetPointCoordsArrayL(lCoords); + } + if(iFromPath) + { + newElement->iFromPath = CGfxGeneralPath::NewL(); + + RArray* lTypes = this->iFromPath->PointTypeArray(); + RArray* lCoords = this->iFromPath->PointCoordsArrayAll(); + newElement->iFromPath->SetPointTypeArrayL(lTypes); + newElement->iFromPath->SetPointCoordsArrayL(lCoords); + } + if(iToPath) + { + newElement->iToPath = CGfxGeneralPath::NewL(); + + RArray* lTypes = this->iToPath->PointTypeArray(); + RArray* lCoords = this->iToPath->PointCoordsArrayAll(); + newElement->iToPath->SetPointTypeArrayL(lTypes); + newElement->iToPath->SetPointCoordsArrayL(lCoords); + } + if(iOrgFromPath) + { + newElement->iOrgFromPath = CGfxGeneralPath::NewL(); + + RArray* lTypes = this->iOrgFromPath->PointTypeArray(); + RArray* 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; iiValuesFloat->AppendL(iValuesFloat->operator[](i)); + } + } + if(iValuesInt) + { + TInt lCount = iValuesInt->Count(); + newElement->iValuesInt->Reset(); + for(TInt i=0; iiValuesInt->Append(iValuesInt->operator[](i))); + } + } + + //iValuesPath + if(iValuesPath) + { + TInt lCount = iValuesPath->Count(); + newElement->iValuesPath->Reset(); + for(TInt i=0; iiValuesPath)->operator[](i); + RArray* lTypes = lOrgPath->PointTypeArray(); + RArray* 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; iiValuesViewBox->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;iiEventList->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;iiEndTimeList->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