svgtopt/SVG/SVGImpl/src/SVGAnimationElementImpl.cpp
changeset 0 d46562c3d99d
child 17 db5c883ad1c5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/SVG/SVGImpl/src/SVGAnimationElementImpl.cpp	Thu Jan 07 16:19:02 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 <e32base.h>
+#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; i<myAnimationEleListCnt; i++)
+    	{
+		CSvgElementImpl* lCurElem =
+		    (CSvgElementImpl*)iMyAnimationElementList->operator[](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; i<iMyAnimationElementList->Count(); 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<CSvgElementImpl>* 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<CCssValue>(KCSS_MAX_ATTR);
+	User::LeaveIfError( iSvgStyleProperties->Append( NULL ) );
+	iSvgStyleProperties->Remove( 0 );
+
+    iMyAnimationElementList = new (ELeave)RPointerArray<CSvgElementImpl> (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("<animation x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xlink:href=\"hmm\" preserveAspectRatio=\"hmm\" />",
+	 	(int)iX, (int)iY, (int)iWidth, (int)iHeight/*, Href(), PreservRatio()*/);
+		#endif
+	}
+}
+//  End of File