diff -r 000000000000 -r 88edb906c587 svgtopt/SVG/SVGImpl/src/SVGAnimationElementImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/SVG/SVGImpl/src/SVGAnimationElementImpl.cpp Wed Nov 03 18:56:10 2010 +0200 @@ -0,0 +1,745 @@ +/* +* Copyright (c) 2005 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 + * +*/ + + +// INCLUDE FILES +#include "SVGAnimationElementImpl.h" +#include "SVGDocumentImpl.h" +#include "SVGSchemaData.h" +#include "SVGAnimationBase.h" +#include "SVGEvent.h" +#include "SVGEventHandler.h" + +#if !defined(__E32BASE_H__) +#include +#endif + + +// ============================= LOCAL FUNCTIONS =============================== + +// Setter functions + +// ----------------------------------------------------------------------------- +// SetRecursionVariable: Set aIsRecursion to indicate that the element has been +// cloned or not. +// +// Returns: TFloatFixPt +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::SetRecursionVariable(TBool aIsRecursion) + { + iUseInRecursion = aIsRecursion; + } + + + +// ============================ MEMBER FUNCTIONS =============================== + +// Getter functions + +// ----------------------------------------------------------------------------- +// X: returns iX +// +// Returns: TFloatFixPt +// ----------------------------------------------------------------------------- +// +TFloatFixPt CSvgAnimationElementImpl::X() + { + return iX; + } + + +// ----------------------------------------------------------------------------- +// Y: returns iY +// +// Returns: TFloatFixPt +// ----------------------------------------------------------------------------- +// +TFloatFixPt CSvgAnimationElementImpl::Y() + { + return iY; + } + + +// ----------------------------------------------------------------------------- +// Width: returns iWidth +// +// Returns: TFloatFixPt +// ----------------------------------------------------------------------------- +// +TFloatFixPt CSvgAnimationElementImpl::Width() + { + return iWidth; + } + + +// ----------------------------------------------------------------------------- +// Height: return iHeight +// +// Returns: TFloatFixPt +// ----------------------------------------------------------------------------- +// +TFloatFixPt CSvgAnimationElementImpl::Height() + { + return iHeight; + } + + +// ----------------------------------------------------------------------------- +// PreservRatio: Returns the PreserveAspecRatio's setting. Mainly used by encoder. +// +// Returns: Descriptor of PreserveAspecRatio value +// ----------------------------------------------------------------------------- +// +const TDesC& CSvgAnimationElementImpl::PreservRatio() + { + return (TDesC&) *iPreservRatio; + } + + +// ----------------------------------------------------------------------------- +// SetAttributeL: Called by Contenthandler or decoder to set attributes +// +// Returns: TInt error code +// ----------------------------------------------------------------------------- +// +TInt CSvgAnimationElementImpl::SetAttributeL( const TDesC& aName, + const TDesC& aValue ) + { + _LIT( KXlink, "xlink:href" ); + _LIT( KPreserveAspectRatio, "preserveAspectRatio" ); + + if ( aName == KXlink ) + { + // 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 ); + + if ( this->SetXlinkAttributeL( aName, tPtr ) ) + { + iReferencedElement = ( CSvgElementImpl * ) + ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( tPtr ); + + if(iReferencedElement == NULL) + { + // failure in finding the referenced element + CleanupStack::PopAndDestroy( 1 ); // tBufC + return KErrReferencedElementNotFound; + } + } + + CleanupStack::PopAndDestroy( 1 ); // tBufC + } + } + else if ( aName == KPreserveAspectRatio ) + { + iPreservRatio = aValue.AllocL(); + } + else + { + CSvgAnimationBase::SetAttributeL(aName, aValue); + } + + return KErrNone; + } + + +// ----------------------------------------------------------------------------- +// SetAttributeFloatL: Called by Contenthandler or decoder to set attributes +// +// Returns: TInt error code +// ----------------------------------------------------------------------------- +// +TInt CSvgAnimationElementImpl::SetAttributeFloatL( const TInt aNameId, + const TFloatFixPt aValue ) + { + switch ( aNameId ) + { + case KAtrX: + iX = aValue; + break; + + case KAtrY: + iY = aValue; + break; + + case KAtrWidth: + iWidth = aValue; + break; + + case KAtrHeight: + iHeight = aValue; + break; + + default: + return CSvgElementImpl::SetAttributeFloatL( aNameId, aValue ); + } + return KErrNone; + } + + +// ----------------------------------------------------------------------------- +// GetAttributeFloat: returns value of the floating attribute +// +// Returns: TInt error code +// ----------------------------------------------------------------------------- +// +TInt CSvgAnimationElementImpl::GetAttributeFloat( const TInt aNameId, TFloatFixPt& aValue ) + { + switch ( aNameId ) + { + case KAtrX: + aValue = iX ; + break; + + case KAtrY: + aValue = iY ; + break; + + case KAtrWidth: + aValue = iWidth ; + break; + + case KAtrHeight: + aValue = iHeight ; + break; + + default: + return CSvgElementImpl::GetAttributeFloat( aNameId, aValue ); + } + return KErrNone; + } + + + +// ----------------------------------------------------------------------------- +// GetUriRefId: Get the id of reference target id +// +// Returns: TDesC& id +// ----------------------------------------------------------------------------- +// +//const TDesC& CSvgAnimationElementImpl::GetUriRefId() +// { +// return (TDesC&) (iReferencedElement->Id()); +// } + + +// ----------------------------------------------------------------------------- +// IsUriRefSet: Return true or not if uri is set +// +// Returns: TBool +// ----------------------------------------------------------------------------- +// +TBool CSvgAnimationElementImpl::IsUriRefSet() + { + if(iReferencedElement) + { + return ETrue; + } + else + { + return EFalse; + } + } + + + +// ----------------------------------------------------------------------------- +// ReceiveEventL: The implemented function will be called whenever subscribed +// events are received. +// +// From MSvgEventReceiver +// +// Return: TBool ETrue if redraw is needed +// EFalse if redraw is not needed +// ----------------------------------------------------------------------------- +// +TBool CSvgAnimationElementImpl::ReceiveEventL( MSvgEvent* aEvent ) + { + // Processing events after begin time + if( CSvgElementImpl::IsSVGEnginePaused()) + { + return EFalse; + } + CSvgEngineImpl* engine = ((CSvgDocumentImpl*)iOwnerDocument)->Engine(); + if (engine == NULL) + { + return EFalse; + } + + TInt32 lEngineCurrentTime = engine->CurrentTIme(); + + if ( lEngineCurrentTime < iAbsoluteBeginTime) + { + // not begin yet. + return ETrue; + } + else + { + // rewrite engine time to simulate different timer + if ( aEvent->EventType() == ESvgEngineEventTimer ) + { + ((MSvgTimerEvent*)aEvent)->SetTime( (TInt32)(lEngineCurrentTime + - iAbsoluteBeginTime )); + } + } + + // Basically forward received events to all its children as if they receive + // event from DocumentImpl. + if ( iAnimationEventHandler->ProcessEventL( aEvent )) + { + if (iInitSortList) + { + iAnimationEventHandler->SortEventList(); + iInitSortList = EFalse; + } + iAnimationEventHandler->DoAnimProcL(aEvent); + engine->RedrawL(); + } + else + { + // this is to keep the dom in its final state. + if(aEvent->EventType() == ESvgEngineEventTimer) + { + iAnimationEventHandler->DoAnimProcL(aEvent); + } + } + + // Process key event separately. + if (aEvent->EventType() == ESvgEngineEventKeyPress) + { + } + + // return true to be redrawn + return ETrue; + } + + +// ----------------------------------------------------------------------------- +// RecursionVariable: Getter function that could be called by Contenthandler or +// decoder to determine if the element has been cloned. +// elements +// +// Return: TBool ETrue if the element is cloned already +// ----------------------------------------------------------------------------- +// +TBool CSvgAnimationElementImpl::RecursionVariable() + { + return iUseInRecursion; + } + + +// ----------------------------------------------------------------------------- +// SetRefElemById: Called by Contenthandler or decoder to set referenced +// elements +// +// Return: none +// ----------------------------------------------------------------------------- +// +TInt CSvgAnimationElementImpl::SetRefElemById(const TDesC& aName) + { + iReferencedElement = ( CSvgElementImpl * ) + ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById( aName ); + if( iReferencedElement == NULL ) + { + return KErrNotFound; + } + else + { + return KErrNone; + } + + } + + +// ----------------------------------------------------------------------------- +// SetReferenceElementL: Called by Contenthandler or decoder to clone referenced +// element which has been determined in SetRefElemById(...). +// +// Return: none +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::SetReferenceElementL() + { + _LIT( KPreserveAspectRatio, "preserveAspectRatio" ); + + if(!RecursionVariable()) + { + if( iReferencedElement != NULL ) + { + // Setting iUseInRecursion to True so that the Call to CloneL + // is not called to this instance of use in this recursion + SetRecursionVariable(ETrue); + + CSvgElementImpl* theElement = (CSvgElementImpl *)iReferencedElement->CloneL((MXmlElement*)this); + CleanupStack::PushL(theElement); + this->CXmlElementImpl::AppendChildL(theElement); + CleanupStack::Pop(); + if(!RecursionVariable()) + { + // The Recursion variable is set to false only when the Cloning + // goes into loop. + // Using this information and then Setting the Recursion variable + // back to True to use the information to set error code in + // StartElementL in Content Handler + // + SetRecursionVariable(ETrue); + } + else // Normal CloneL loop exit + { + // Setting iUseInRecursion back to False + SetRecursionVariable(EFalse); + } + + CSvgDocumentImpl* doc = ( CSvgDocumentImpl* ) OwnerDocument(); + CSvgSvgElementImpl* lSvgRoot = (CSvgSvgElementImpl*) doc->RootElement(); + if (iPreservRatio != NULL) + { + lSvgRoot->SetAttributeL( KPreserveAspectRatio, iPreservRatio->Des() ); + } + lSvgRoot->SetWidth( iX ); + lSvgRoot->SetHeight( iY ); + + } + } + } + + + +// ----------------------------------------------------------------------------- +// ResetEventListener: Reset event listeners for it's children +// +// Returns: none +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::ResetEventListener() + { + FindAllAnimationElements( (CSvgElementImpl* )this, iMyAnimationElementList ); + + // Remove event listening for every animation elements that are child of + // this Animation element. This is to implement a separated time container + // + // Instead, register event linstening to the event handler of this element. + // + TInt myAnimationEleListCnt = iMyAnimationElementList->Count(); + for (int i=0; ioperator[](i); + // Removing... + ((CSvgDocumentImpl*)iOwnerDocument)->RemoveFromEventReceiverList(lCurElem); + + // Adding... + TUint8 eventMask = iAnimationEventHandler->EventMask(lCurElem); + TRAPD(err, iAnimationEventHandler->AddToEventReceiverListL( lCurElem, eventMask )); + if (err != KErrNone) + { + #ifdef _DEBUG + _LIT(msg, "CSvgAnimationElementImpl::ResetEventListener():Can't add myself to event receiverList"); + RDebug::Print(msg); + #endif //_DEBUG + } + } + } + + + +// ----------------------------------------------------------------------------- +// RemoveEventListener: Remove event listeners for it's children +// +// Returns: none +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::RemoveEventListener() + { + FindAllAnimationElements( (CSvgElementImpl* )this, iMyAnimationElementList ); + + // Remove event listening for every animation elements that are child of + // this Animation element. This is to implement a separated time container + // + // Instead, register event linstening to the event handler of this element. + // + for (int i=0; iCount(); i++) + { + CSvgElementImpl* lCurElem = + (CSvgElementImpl*)iMyAnimationElementList->operator[](i); + // Removing... + iAnimationEventHandler->RemoveFromEventReceiverList( lCurElem ); + } + } + + + + +// ----------------------------------------------------------------------------- +// CSvgAnimationElementImpl: Find all animation elements and save it to aList +// +// Returns: none +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::FindAllAnimationElements( + CSvgElementImpl* aElement, + RPointerArray* aList ) + { + CSvgElementImpl* child = (CSvgElementImpl*)aElement->FirstChild(); + while ( child != NULL ) + { + if ( IsAnimationElement(child) ) + { + aList->Append( child ); + } + FindAllAnimationElements( child, aList ); + child = (CSvgElementImpl*)child->NextSibling(); + } + } + + + +// ----------------------------------------------------------------------------- +// IsAnimationElement: A utility function that check if the element +// is an animation element. +// +// Returns: TBool ETrue if the element is a animation element. +// EFalse if the element is not an animation element. +// ----------------------------------------------------------------------------- +// +TBool CSvgAnimationElementImpl::IsAnimationElement(CSvgElementImpl* aElement) + { + + TInt id = aElement->ElemID(); + + return (( id == KSvgAnimateElement ) || + ( id == KSvgAnimateMotionElement ) || + ( id == KSvgAnimateTransformElement ) || + ( id == KSvgSetElement ) || + ( id == KSvgAnimateColorElement )); + } + + +// ----------------------------------------------------------------------------- +// ResetAnimationL: Actions to reset the animation +// +// Returns: none +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::ResetAnimationL() + { + } + + +// ----------------------------------------------------------------------------- +// AnimProcL: Actions to reset the animation +// +// Returns: none +// ----------------------------------------------------------------------------- +// +TBool CSvgAnimationElementImpl::AnimProcL( MSvgTimerEvent* aEvent ) + { + if (aEvent->EventType() == ESvgEngineEventKeyPress) + { + } + + return EFalse; + } + + + +// ----------------------------------------------------------------------------- +// CloneL: Perform a deep clone of this object +// +// Returns: MXmlElement pointer to the newly created element. +// ----------------------------------------------------------------------------- +// +MXmlElement* CSvgAnimationElementImpl::CloneL(MXmlElement* aParentElement) + { + + if(RecursionVariable()) + { + SetRecursionVariable(EFalse); + return NULL; + } + + CSvgAnimationElementImpl* newElement = CSvgAnimationElementImpl::NewL( this->ElemID(), + ((CSvgDocumentImpl*)iOwnerDocument) ); + CleanupStack::PushL(newElement); + newElement->iParentNode = aParentElement; + + // copy everything over + this->CopyL(newElement); + CleanupStack::Pop(); + + return newElement; + } + + +// ----------------------------------------------------------------------------- +// CopyL: Perform a deep copy of this object +// +// Returns: none +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::CopyL( CSvgAnimationElementImpl* aDestElement ) + { + if(aDestElement) + { + aDestElement->iX = this->iX; + aDestElement->iY = this->iY; + aDestElement->iHeight = this->iHeight; + aDestElement->iWidth = this->iWidth; + aDestElement->iReferencedElement = this->iReferencedElement; + + aDestElement->SetRecursionVariable(this->RecursionVariable()); + aDestElement->iOwnerDocument = this->iOwnerDocument; + // copy stuff from superclass + this->CSvgElementImpl::CopyL(aDestElement); + } + } + + +// ----------------------------------------------------------------------------- +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSvgAnimationElementImpl* CSvgAnimationElementImpl::NewL( const TUint8 aElemID, + CSvgDocumentImpl* aDoc) + { + CSvgAnimationElementImpl* self = new (ELeave)CSvgAnimationElementImpl(aDoc); + CleanupStack::PushL( self ); + self->ConstructL( aElemID ); + CleanupStack::Pop(); + + return self; + } + + +// ----------------------------------------------------------------------------- +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSvgAnimationElementImpl* CSvgAnimationElementImpl::NewLC( const TUint8 aElemID, + CSvgDocumentImpl* aDoc) + { + CSvgAnimationElementImpl* self = new (ELeave) CSvgAnimationElementImpl(aDoc); + CleanupStack::PushL( self ); + self->ConstructL( aElemID ); + + return self; + } + + +// ----------------------------------------------------------------------------- +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CSvgAnimationElementImpl::CSvgAnimationElementImpl( CSvgDocumentImpl* aDoc ) + : CSvgAnimationBase( aDoc ) + { + iInitSortList = ETrue; //True indicates that the soring has not been done. + } + + +// ----------------------------------------------------------------------------- +// Symbian default constructor that can leave. +// ----------------------------------------------------------------------------- +// +void CSvgAnimationElementImpl::ConstructL( const TUint8 aElemID ) + { + CSvgAnimationBase::ConstructL( aElemID ); + + iSvgStyleProperties = new(ELeave) RPointerArray(KCSS_MAX_ATTR); + User::LeaveIfError( iSvgStyleProperties->Append( NULL ) ); + iSvgStyleProperties->Remove( 0 ); + + iMyAnimationElementList = new (ELeave)RPointerArray (1); + iMyAnimationElementList->Reset(); + + iSvgTransformable = CSvgTransformableImpl::NewL(); + + #ifdef SVG_FLOAT_BUILD + iX = ( 0 ); + iY = ( 0 ); + #else + iX.operator = ( 0 ); + iY.operator = ( 0 ); + #endif + + iUseInRecursion = EFalse; + + iAnimationEventHandler = CSvgEventHandler::NewL(); + +// ((CSvgDocumentImpl*) +// iOwnerDocument)->AddToEventReceiverListL(this, KSvgEventMaskTimer | +// KSvgEventMaskInternal | KSvgEventMaskExternalUI); + } + + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +// +CSvgAnimationElementImpl::~CSvgAnimationElementImpl() + { + + // unregister event listening for all childs. + RemoveEventListener(); + + if( iAnimationEventHandler ) + { + delete iAnimationEventHandler; + iAnimationEventHandler = NULL ; + } + + + if ( iSvgStyleProperties ) + { + iSvgStyleProperties->Close(); + delete iSvgStyleProperties; + iSvgStyleProperties = NULL; + } + + if ( iMyAnimationElementList ) + { + iMyAnimationElementList->Reset(); + iMyAnimationElementList->Close(); + delete iMyAnimationElementList; + } + + if ( iPreservRatio ) + { + delete iPreservRatio; + } + + } + +void CSvgAnimationElementImpl::Print( TBool aIsEncodeOn ) +{ + if (!aIsEncodeOn) + { + #ifdef _DEBUG + RDebug::Printf("", + (int)iX, (int)iY, (int)iWidth, (int)iHeight/*, Href(), PreservRatio()*/); + #endif + } +} +// End of File