diff -r 000000000000 -r d46562c3d99d svgtopt/SVG/SVGImpl/src/SVGDiscardElementImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/SVG/SVGImpl/src/SVGDiscardElementImpl.cpp Thu Jan 07 16:19:02 2010 +0200 @@ -0,0 +1,858 @@ +/* +* 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 "SVGDiscardElementImpl.h" +#include "SVGDocumentImpl.h" +#include "SVGSchemaData.h" +#include "SVGAnimTimingParser.h" +#include "SVGEngineImpl.h" +#include "SVGAnimationBase.h" +#include "SVGRectElementImpl.h" +#include "SVGEvent.h" + +#if !defined(__E32BASE_H__) +#include +#endif + + +// ============================= LOCAL FUNCTIONS =============================== + + +// ----------------------------------------------------------------------------- +// RemoveTargetElement: A utility function that renmoves target element. +// Remove target element and all its child from its parent level. +// Allocated Style properties of the target elements have to be deleted here. +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::RemoveTargetElement() + { + + if (iTargetElement!= NULL) + { + CSvgElementImpl* lParent = (CSvgElementImpl*)iTargetElement->ParentNode(); + if ( lParent != NULL ) + { + lParent->RemoveChild(iTargetElement); + } + else if ( iTargetElement->ElemID() == KSvgSvgElement ) + { + // remove all children + CSvgElementImpl* child = (CSvgElementImpl*)iTargetElement->FirstChild(); + CSvgElementImpl* sib = (CSvgElementImpl*) NULL; + while ( (child != NULL ) || sib != (CSvgElementImpl*) NULL ) + { + sib = (CSvgElementImpl*)child->NextSibling(); + // remove myself later + if (child != this) + { + iTargetElement->RemoveChild(child); + delete child; + } + child = sib; + } + } + + // make sure that the target element is not root + if ( iTargetElement->ElemID() != KSvgSvgElement ) + { + delete iTargetElement; + iTargetElement = NULL; + } + iRemoveMyself = ETrue; + } + } + +// ----------------------------------------------------------------------------- +// FindTargetElementL: A utility function that finds target element +// and adjust the begin time. +// +// Returns: TBool ETrue if target is set. +// EFalse if target is not found. +// ----------------------------------------------------------------------------- +// +TBool CSvgDiscardElementImpl::FindTargetElementL() + { + if (iTargetElement) + return ETrue; + + // Target could be set from one of the following ways: + // 1) Defined as SyncBased value. ==> get element + // 2) xlink-href defined. ==> get element + // 3) Invalid element id ==> Ignore + // 4) No specified xlink-href nor other element id. ==> Use parent + + if ( iHrefValueDefined ) + { + // Case 2 & 3 + TPtrC lPtr = iTargetId->Des(); + iTargetElement = ( CSvgElementImpl * ) + ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById(lPtr); + if (iTargetElement == NULL) + { + // Case 3 + // Ignore and remove myself later. + iRemoveMyself = ETrue; + return EFalse; + } + } + else // Case 4 + { + // Set parent to target only when the parent is an animation element + iTargetElement = ( CSvgElementImpl * ) ParentNode(); + } + + // Target element should be determined by now. + + + // Check to see if the target element is animatable. + // If not, remove myself. + // Calculate begin time. + + if ( iSyncValueDefined ) + { + // Get reference target element + iRefTargetElement = ( CSvgElementImpl * ) + ((CSvgDocumentImpl*)iOwnerDocument)->GetElementById(iBeginSyncElementId); + + // Only Syncbased begin time + if (!iEventValueDefined) + { + // If specified element doesn't exist or the element is not animated, + // remove myself. + if ((iRefTargetElement == NULL) /*|| !IsAnimationElement(iRefTargetElement)*/) + { + // No referenced element or not animatable element (no begin/end attr) + // ==> Ignore and remove myself later. + iRemoveMyself = ETrue; + return EFalse; + } + + // re-calculate begin time. e.g. id1.start+5s + if (iBeginReferenceEvent == ESvgEventBeginEvent) + { + iAbsoluteBeginTime += + ((CSvgAnimationBase*)iRefTargetElement)->GetAbsoluteBeginTime(); + } + else if (iBeginReferenceEvent == ESvgEventEndEvent) + { + iAbsoluteBeginTime += + ((CSvgAnimationBase*)iRefTargetElement)->GetEndTime(); + } + } + else // iEventValueDefined is TRUE + { + // Listen external events + ((CSvgDocumentImpl*) + iOwnerDocument)->AddToEventReceiverListL(iRefTargetElement, + KSvgEventMaskExternalUI); + } + } + else if (iEventValueDefined) + { + // Listen external events + ((CSvgDocumentImpl*) + iOwnerDocument)->AddToEventReceiverListL(iTargetElement, + KSvgEventMaskExternalUI); + } + + return ETrue; // Set Target element + } + + + +// ----------------------------------------------------------------------------- +// HasAnimationElements: A utility function that check if the element +// contains animation element(s). +// +// Returns: TBool ETrue if the element contains animation element(s) +// EFalse if the element doesn't animated. +// ----------------------------------------------------------------------------- +// +/* +TBool CSvgDiscardElementImpl::HasAnimationElements(CSvgElementImpl* aElement) + { + TBool lFound = EFalse; + + // Return immediately if the target element is already an animation element. + if (IsAnimationElement(aElement)) + return ETrue; + + // Look through childs + CSvgElementImpl* child = (CSvgElementImpl*)aElement->FirstChild(); + while ( child != NULL ) + { + if ( IsAnimationElement(child) ) + { + lFound = ETrue; + break; + } + child = (CSvgElementImpl*)child->NextSibling(); + } + if (lFound) + return ETrue; + + return EFalse; + } +*/ + + +// ----------------------------------------------------------------------------- +// 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 CSvgDiscardElementImpl::IsAnimationElement(CSvgElementImpl* aElement) + { + + TInt id = aElement->ElemID(); + + return (( id == KSvgAnimateElement ) || + ( id == KSvgAnimateMotionElement ) || + ( id == KSvgAnimateTransformElement ) || + ( id == KSvgSetElement ) || + ( id == KSvgAnimateColorElement )); + } +*/ + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// SetAttributeL: The implemented function will be called from CSvgContentHandler. +// +// From CSvgElementImpl +// +// There will be two attributes been set: begin and xlink:href. +// If xlink:href is not specified, the target element will be parent element +// If begin time is not specifid, the target element will be remove immdeiately. +// +// Returns: ETrue always in this case. +// ----------------------------------------------------------------------------- +// +TInt CSvgDiscardElementImpl::SetAttributeL( const TDesC& aName, + const TDesC& aValue ) + { + _LIT( KTmpXlinkHref, "xlink:href" ); + _LIT( KTmpBegin, "begin" ); + + // If not xlink:href, it must be attribute "begin" + 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 the Decoder + iHrefValueDefined = ETrue; + TInt pos = aValue.Locate( '#' ); + if ( pos == 0 ) + { + if (iTargetId) + { + delete iTargetId; + iTargetId = NULL; + } + iTargetId = aValue.AllocL(); + TPtr tPtr = iTargetId->Des(); + tPtr.Delete(pos, 1); + } + } + else if ( aName == KTmpBegin ) + { + CSvgAnimTimingParser* atParser = CSvgAnimTimingParser::NewLC( aValue, this ); + TInt32 clockValue; + TReal32 lRepeatBeginValue; + atParser->Parse( iBeginSyncElementId, + iBeginReferenceEvent, + clockValue, + lRepeatBeginValue, + ETrue); + + iAbsoluteBeginTime = clockValue; + + if ( iBeginSyncElementId.Size() != 0 ) + { + iSyncValueDefined = ETrue; + } + + if ( iBeginReferenceEvent != ESvgEventNone ) + { + iEventValueDefined = ETrue; + iRefBeginTime = clockValue; + iAbsoluteBeginTime = KTimeIndefinite; + if (iBeginReferenceEvent == ESvgEventKey) + { + iKeyValue = atParser->AccekeyValue(); + } + } + + + CleanupStack::PopAndDestroy( 1 ); // atParser + } + + CSvgElementImpl::SetAttributeL(aName,aValue); + + return KErrNone; + } + + + + +// ----------------------------------------------------------------------------- +// 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 CSvgDiscardElementImpl::ReceiveEventL( MSvgEvent* aEvent ) + { + + if (iRemoveMyself) + { + // Two reasons to remove myself. + // 1) when discard element is not sepcified inside of the target + // element so the object is not removed automatically along with + // target element. + // 2) Invalid begin time + iTargetElement = ( CSvgElementImpl * ) ParentNode(); + iTargetElement->RemoveChild(this); + delete this; + return EFalse; + } + + // Looking for target as soon as first event received. Also adject time + // according to timeing attribute. + if (!FindTargetElementL()) + { + // Target not found, exit and remove myself next time + return EFalse; + } + + // Target element should be identified by now. + + CSvgEngineImpl* engine = ((CSvgDocumentImpl*)iOwnerDocument)->Engine(); + if (engine == NULL) + { + return EFalse; + } + + TInt32 lEngineCurrentTime = engine->CurrentTIme(); + + // User input event + if (aEvent->EventType() == ESvgEngineEventKeyPress) + { + MSvgUiKeyEvent* evt = ( MSvgUiKeyEvent* ) aEvent; + if (evt->KeyCode() == iKeyValue) + { + // Remove target immediately + RemoveTargetElement(); + engine->RedrawL(); + return ETrue; + } + return EFalse; + } + // Timer event + if (aEvent->EventMask() == KSvgEventMaskTimer) + { + + if (lEngineCurrentTime >= iAbsoluteBeginTime) + { + // Time to remove target + RemoveTargetElement(); + } + } + // Internal event + else if ((aEvent->EventMask() == KSvgEventMaskInternal ) + && (!iRefBeginTimeSet)) + { + MSvgInternalEvent* evt = ( MSvgInternalEvent* ) aEvent; + TSvgEvent s_evt = evt->SvgEvent(); + if (s_evt == iBeginReferenceEvent) + { + + // Event other than AccessKey + // Check to see if there is a clock associated with the event. + if (s_evt == iBeginReferenceEvent) + { + // This is some form of event+(-)clock so delay removing + // Note that once the reference time is set, the absolutetime + // can't be changed with other events. + if (iRefTargetElement != NULL) + { + // This is a syncbased event + if (evt->ObjectAddress() == iRefTargetElement) + { + iAbsoluteBeginTime = lEngineCurrentTime + iRefBeginTime; + iRefBeginTimeSet = ETrue; + return EFalse; + } + } + else + { + // Not syncbased event + if (evt->ObjectAddress() == iTargetElement) + { + iAbsoluteBeginTime = lEngineCurrentTime + iRefBeginTime; + iRefBeginTimeSet = ETrue; + return EFalse; + } + } + } // if (s_evt == iBeginReferenceEvent)... + else + { + // No clock assoicated with the event. + if (iRefTargetElement != NULL) + { + // This is a syncbased event + if (evt->ObjectAddress() == iRefTargetElement) + { + // Remove target immediately + RemoveTargetElement(); + } + } + // Not syncbased event + else if (evt->ObjectAddress() == iTargetElement) + { + // Remove target immediately + RemoveTargetElement(); + } + } + } // if (s_evt == iBeginReferenceEvent)... + } //if ((aEvent->EventMask() == KSvgEventMaskInte... + else + { + // Not interested event + return EFalse; + } + + // return true to be redrawn + return ETrue; + } + + +// Setter functions + +// ----------------------------------------------------------------------------- +// SetTargetId: Set iTargetId to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetTargetId(const TDesC& aTargetId) + { + delete iTargetId; + iTargetId = NULL; + TRAPD(err, iTargetId = aTargetId.AllocL()); + if (err != KErrNone) + { + // Only display error message. If this failed, iTargetId can safely to be null. + #ifdef _DEBUG + RDebug::Printf("CSvgDiscardElementImpl::SetTargetId Error: memory allocation failed."); + #endif + } + } + + +// ----------------------------------------------------------------------------- +// SetSyncValueDefined: Set iSyncValueDefined to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetSyncValueDefined(TBool aSyncValueDefined) + { + iSyncValueDefined = aSyncValueDefined; + } + + + +// ----------------------------------------------------------------------------- +// SetEventValueDefined: Set iEventValueDefined to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetEventValueDefined(TBool aEventValueDefined) + { + iEventValueDefined = aEventValueDefined; + } + + +// ----------------------------------------------------------------------------- +// SetHrefValueDefined: Set iHrefValueDefined to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetHrefValueDefined(TBool aHrefValueDefined) + { + iHrefValueDefined = aHrefValueDefined; + } + + +// ----------------------------------------------------------------------------- +// SetBeginSyncElementId: Set aBeginSyncElementId to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetBeginSyncElementId(const TDesC& aBeginSyncElementId) + { + iBeginSyncElementId.SetLength(0); + iBeginSyncElementId.Append(aBeginSyncElementId); + } + + +// ----------------------------------------------------------------------------- +// SetAbsoluteBeginTime: Set iAbsoluteBeginTime to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetAbsoluteBeginTime(TInt aAbsoluteBeginTime) + { + if (aAbsoluteBeginTime == -1) + { + iAbsoluteBeginTime = KTimeIndefinite; + } + else + { + iAbsoluteBeginTime = aAbsoluteBeginTime; + } + } + + + +// ----------------------------------------------------------------------------- +// SetRefBeginTime: Set aRefBeginTime to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetRefBeginTime(TInt aRefBeginTime) + { + iRefBeginTime = aRefBeginTime; + } + + + +// ----------------------------------------------------------------------------- +// SetKeyValue: Set aKeyValue to the object. Mainly used by decoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetKeyValue(TInt aKeyValue) + { + iKeyValue = aKeyValue; + } + + + +// ----------------------------------------------------------------------------- +// TargetId: Returns iBeginReferenceEvent that is specified in begin attribute. +// Mainly used by encoder. +// +// Returns: void +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::SetBeginReferenceEvent(TSvgEvent aBeginReferenceEvent) + { + iBeginReferenceEvent = aBeginReferenceEvent; + } + + +// Getter functions + +// ----------------------------------------------------------------------------- +// TargetId: Returns the target element's id. Mainly used by encoder. +// +// Returns: Descriptor of target element's id +// ----------------------------------------------------------------------------- +// +const TDesC& CSvgDiscardElementImpl::TargetId() + { + return (TDesC&) *iTargetId; + } + + + +// ----------------------------------------------------------------------------- +// BeginSyncElementId: Returns element's id that is specified in begin attribute. +// Mainly used by encoder. +// +// Returns: Descriptor of the element's id +// ----------------------------------------------------------------------------- +// +const TDesC& CSvgDiscardElementImpl::BeginSyncElementId() + { + return iBeginSyncElementId; + } + + + +// ----------------------------------------------------------------------------- +// AbsoluteBeginTime: Returns the absolute begin time that is identified in +// SetAttribute. The begin time may be changed when using with SyncBase or +// EventBased attribute. +// +// Mainly used by encoder. +// +// Returns: TInt AbsoluteBeginTime +// ----------------------------------------------------------------------------- +// +TInt CSvgDiscardElementImpl::AbsoluteBeginTime() + { + if (iAbsoluteBeginTime == KTimeIndefinite) + { + // write -1 in case both encorder and decoder understand. + return -1; + } + else + { + return iAbsoluteBeginTime; + } + } + + +// ----------------------------------------------------------------------------- +// IsSyncValueDefined: Returns the flag iSyncValueDefined that was set in +// SetAttribute. +// +// Mainly used by encoder. +// +// Returns: TBool iSyncValueDefined +// ----------------------------------------------------------------------------- +// +TBool CSvgDiscardElementImpl::IsSyncValueDefined() + { + return iSyncValueDefined; + } + + +// ----------------------------------------------------------------------------- +// IsEventValueDefined: Returns the flag iEventValueDefined that was set in +// SetAttribute. +// +// Mainly used by encoder. +// +// Returns: TBool iEventValueDefined +// ----------------------------------------------------------------------------- +// +TBool CSvgDiscardElementImpl::IsEventValueDefined() + { + return iEventValueDefined; + } + + +// ----------------------------------------------------------------------------- +// IsHrefValueDefined: Returns the flag iHrefValueDefined that was set in +// SetAttribute. +// +// Mainly used by encoder. +// +// Returns: TBool iHrefValueDefined +// ----------------------------------------------------------------------------- +// +TBool CSvgDiscardElementImpl::IsHrefValueDefined() + { + return iHrefValueDefined; + } + + +// ----------------------------------------------------------------------------- +// RefBeginTime: Returns the reference begin time that was set in +// SetAttribute. +// +// Mainly used by encoder. +// +// Returns: TInt iRefBeginTime +// ----------------------------------------------------------------------------- +// +TInt CSvgDiscardElementImpl::RefBeginTime() + { + return iRefBeginTime; + } + + +// ----------------------------------------------------------------------------- +// KeyValue: Returns the key value (scan code) that was set in +// SetAttribute. +// +// Mainly used by encoder. +// +// Returns: TInt iKeyValue +// ----------------------------------------------------------------------------- +// +TInt CSvgDiscardElementImpl::KeyValue() + { + return iKeyValue; + } + + +// ----------------------------------------------------------------------------- +// KeyValue: Returns the iBeginReferenceEvent that was set in +// SetAttribute. +// +// Mainly used by encoder. +// +// Returns: TSvgEvent iBeginReferenceEvent +// ----------------------------------------------------------------------------- +// +TSvgEvent CSvgDiscardElementImpl::BeginReferenceEvent() + { + return iBeginReferenceEvent; + } + + + +// ----------------------------------------------------------------------------- +// CloneL: Perform a deep clone of this object +// +// Returns: MXmlElement pointer to the newly created element. +// ----------------------------------------------------------------------------- +// +MXmlElement* CSvgDiscardElementImpl::CloneL(MXmlElement* aParentElement) + { + CSvgDiscardElementImpl* newElement = CSvgDiscardElementImpl::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 CSvgDiscardElementImpl::CopyL( CSvgDiscardElementImpl* aDestElement ) + { + if(aDestElement) + { + aDestElement->iOwnerDocument = this->iOwnerDocument; + // copy stuff from superclass + this->CSvgElementImpl::CopyL(aDestElement); + } + } + +// ----------------------------------------------------------------------------- +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSvgDiscardElementImpl* CSvgDiscardElementImpl::NewL( const TUint8 aElemID, + CSvgDocumentImpl* aDoc) + { + CSvgDiscardElementImpl* self = new (ELeave)CSvgDiscardElementImpl(aDoc); + CleanupStack::PushL( self ); + self->ConstructL( aElemID ); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSvgDiscardElementImpl* CSvgDiscardElementImpl::NewLC( const TUint8 aElemID, + CSvgDocumentImpl* aDoc) + { + CSvgDiscardElementImpl* self = new (ELeave) CSvgDiscardElementImpl(aDoc); + CleanupStack::PushL( self ); + self->ConstructL( aElemID ); + + return self; + } + +// ----------------------------------------------------------------------------- +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CSvgDiscardElementImpl::CSvgDiscardElementImpl( CSvgDocumentImpl* aDoc ) + { + SetOwnerDocument(aDoc); + } + + +// ----------------------------------------------------------------------------- +// Symbian default constructor that can leave. +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::ConstructL( const TUint8 aElemID ) + { + CXmlElementImpl::InitializeL( aElemID ); + + iTargetElement = NULL; + iTargetId = HBufC::NewL(0); + iAbsoluteBeginTime = 0; + iRemoveMyself = EFalse; + iHrefValueDefined = EFalse; + iBeginReferenceEvent = (TSvgEvent)NULL; + iSyncValueDefined = EFalse; + iEventValueDefined = EFalse; + iRefBeginTime = 0; + iRefTargetElement = NULL; + iRefBeginTimeSet = EFalse; + iKeyValue = 0; + iBeginSyncElementId.SetLength(0); + + ((CSvgDocumentImpl*) + iOwnerDocument)->AddToEventReceiverListL(this, KSvgEventMaskTimer | + KSvgEventMaskInternal | KSvgEventMaskExternalUI); + } + + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +// +CSvgDiscardElementImpl::~CSvgDiscardElementImpl() + { + delete iTargetId; + } + +// ----------------------------------------------------------------------------- +// Print +// ----------------------------------------------------------------------------- +// +void CSvgDiscardElementImpl::Print( TBool aIsEncodeOn ) +{ + if (!aIsEncodeOn) + { + #ifdef _DEBUG + RDebug::Printf("", /*Href(),*/ (int)iAbsoluteBeginTime); + #endif + } +} + +// End of File