--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/SVGDocumentImpl.cpp Fri Oct 15 09:48:18 2010 +0100
@@ -0,0 +1,2647 @@
+/*
+* 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
+ *
+*/
+
+
+#include <utf.h>
+#include <s32mem.h>
+
+#include "SVGContentHandler.h"
+#include "Svgdecoder.h"
+
+#include "SVGDocumentImpl.h"
+#include "SVGEngineImpl.h"
+#include "SVGSvgElementImpl.h"
+#include "SVGLineElementImpl.h"
+#include "SVGRectElementImpl.h"
+#include "SVGCircleElementImpl.h"
+#include "SVGEllipseElementImpl.h"
+#include "SVGPolylineElementImpl.h"
+#include "SVGGElementImpl.h"
+#include "SVGPathElementImpl.h"
+#include "SVGMpathElementImpl.h"
+#include "SVGSchemaData.h"
+#include "SVGTextElementImpl.h"
+#include "SVGImageElementImpl.h"
+#include "SVGUseElementImpl.h"
+#include "SVGAElementImpl.h"
+#include "SVGStyleElementImpl.h"
+#include "SVGForeignObjectElementImpl.h"
+#include "SVGSetElementImpl.h"
+#include "SVGAnimateTransformElementImpl.h"
+#include "SVGAnimateElementImpl.h"
+#include "SVGAnimateMotionElementImpl.h"
+#include "SVGAnimationElementImpl.h"
+#include "SVGMetadataElementImpl.h"
+#include "SVGDescElementImpl.h"
+#include "SVGDefsElementImpl.h"
+#include "SVGTitleElementImpl.h"
+#include "SVGFontElementImpl.h"
+#include "SVGFontFaceElementImpl.h"
+#include "SVGGlyphElementImpl.h"
+#include "SVGMissingGlyphElementImpl.h"
+#include "SvgHkernelementimpl.h"
+
+#include "SVGLinearGradientElementImpl.h"
+#include "SVGRadialGradientElementImpl.h"
+#include "SvgStopElementImpl.h"
+#include "SVGDiscardElementImpl.h"
+#include "SVGScriptElementImpl.h"
+
+#include "SVGAudioElementImpl.h"
+
+//#ifdef RD_SVGT_MEDIAANIMATION_SUPPORT
+#include "SVGMediaAnimationElementImpl.h"
+//#endif
+#include "SVGTextAreaElementImpl.h"
+#include "SVGSolidColorElementImpl.h"
+
+#include "SVGFloatCssValueImpl.h"
+
+#include "SVGEventHandler.h"
+#include "SVGErrorImpl.h"
+#include "SVGFontHashMap.h"
+#include "SVGTimeContainer.h"
+#include <ezgzip.h>
+
+#include <caf/caf.h>
+#include <bautils.h>
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+CSvgDocumentImpl* CSvgDocumentImpl::NewL( CSvgBitmapFontProvider* aSvgBitmapFontProvider, const TBool aHasParent,
+ const TSvgSyncBehaviour aSyncBehavDefault,
+ const TInt32 aSyncTolDefault )
+ {
+ CSvgDocumentImpl* self = new ( ELeave ) CSvgDocumentImpl(aSvgBitmapFontProvider,
+ aHasParent, aSyncBehavDefault, aSyncTolDefault );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+CSvgDocumentImpl* CSvgDocumentImpl::NewLC( CSvgBitmapFontProvider* aSvgBitmapFontProvider, const TBool aHasParent,
+ const TSvgSyncBehaviour aSyncBehavDefault,
+ const TInt32 aSyncTolDefault )
+ {
+ CSvgDocumentImpl* self = new ( ELeave ) CSvgDocumentImpl(aSvgBitmapFontProvider,
+ aHasParent, aSyncBehavDefault, aSyncTolDefault );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+ return self;
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::ConstructL()
+ {
+ iSchemaData = CSvgSchemaData::NewL();
+
+
+ iEventHandler = CSvgEventHandler::NewL();
+
+ // create CSvgErrorImpl object
+// iSvgError = CSvgErrorImpl::NewL();
+ iIsInteractive = EFalse;
+ iHasGroupOpacity = EFalse;
+
+
+// iImageHashMap = CSvgImageHashMap::NewL();
+ iFontHashMap = CSvgFontHashMap::NewL();
+
+ iMemoryManager = CSvgMemoryManager::NewL();
+
+ iTimeForJSR226 = 0;
+ // Create the time container used for Runtime Sync
+ iTimeContainer = CSvgTimeContainer::NewL( this, iHasParent );
+
+ // Add to the time container
+ iTimeContainer->AddTimedEntityL( this );
+
+ //set media state to ready as default for document
+ iTimeContainer->TimedEntityReady( this );
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+CSvgDocumentImpl::CSvgDocumentImpl( CSvgBitmapFontProvider* aSvgBitmapFontProvider, const TBool aHasParent,
+ const TSvgSyncBehaviour aSyncBehavDefault,
+ const TInt32 aSyncTolDefault ) :
+ iInitSortList( ETrue ),
+ iReqExReqFtrSysLTested( EFalse ),
+ iFinishedParsing( EFalse ),
+ iFontHashMap( NULL ),
+ iEngine(NULL),
+ iMultipleRendering( EFalse ),
+ iHasGradientElement( EFalse ),
+ iIsThumbNailMode( EFalse ),
+ iIsDRMProtected( EFalse ),
+ iHasParent( aHasParent ),
+ iSyncBehaviorDefault(
+ aSyncBehavDefault ),
+ iSyncToleranceDefault(
+ aSyncTolDefault),
+ iSvgBitmapFontProvider(aSvgBitmapFontProvider)
+
+
+
+ {
+ SetDRMMode( ETrue );
+ SetDRMRights( ETrue );
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+CSvgDocumentImpl::~CSvgDocumentImpl()
+ {
+ if ( iTimeContainer )
+ {
+ // Stop timer and reset time
+ iTimeContainer->UserStop();
+ iTimeContainer->UserResetTime();
+ }
+
+ if (iPerfText)
+ {
+ delete iPerfText;
+ iPerfText = NULL;
+ }
+
+ if( iSchemaData )
+ {
+ delete iSchemaData;
+ iSchemaData = NULL;
+ }
+
+ if( iEventHandler )
+ {
+ delete iEventHandler;
+ iEventHandler = NULL ;
+ }
+
+// if( iSvgError )
+// {
+// delete iSvgError;
+// iSvgError = NULL;
+// }
+
+ if( iRootElement )
+ {
+ delete iRootElement;
+ iRootElement = NULL;
+ }
+
+/* if ( iImageHashMap )
+ {
+ //probably should check to verify that the image ptrs
+ //in this have had their images deleted somehow to be safe
+ delete iImageHashMap;
+ iImageHashMap = NULL;
+ } */
+
+ if ( iFontHashMap )
+ {
+ delete iFontHashMap;
+ iFontHashMap = NULL;
+ }
+ iSvgMouseListeners.Close();
+
+ iSvgAnimations.Close();
+
+ if ( iXmlHandler )
+ {
+ delete iXmlHandler;
+ }
+
+ if ( iError )
+ {
+ delete iError;
+ }
+
+ if ( iMemoryManager )
+ {
+ delete iMemoryManager;
+ }
+
+ delete iTimeContainer;
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::SetEngine( CSvgEngineImpl* aEngine )
+ {
+ iEngine = aEngine;
+ // Propogate this to all child documentsas well
+ // Only animation elements currently possess a new document
+ // Locate all the active animation elements
+ RPointerArray<CSvgElementImpl> lAnimationEleList;
+
+ FindAllElements(
+ (CSvgElementImpl* )RootElement(),
+ KSvgMediaAnimationElement, lAnimationEleList );
+ // Set the engine on the child documents associated with the animation elements as well
+ TInt lAnimationEleCnt = lAnimationEleList.Count();
+ for ( TInt lCurAnimationEle = 0; lCurAnimationEle < lAnimationEleCnt; lCurAnimationEle++ )
+ {
+ CSvgMediaAnimationElementImpl* lAnimationElement =
+ (CSvgMediaAnimationElementImpl* )lAnimationEleList[ lCurAnimationEle ];
+ CSvgDocumentImpl* lChildDoc = lAnimationElement->GetChildDocument();
+ if ( lChildDoc )
+ {
+ lChildDoc->SetEngine( aEngine );
+ }
+ }
+ lAnimationEleList.Close();
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+CSvgEngineImpl* CSvgDocumentImpl::Engine()
+ {
+ return iEngine;
+ }
+
+//***********************************************************************
+// From MXmlDocument
+//
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+MXmlElement* CSvgDocumentImpl::CreateElementL( const TDesC& aTagName )
+ {
+
+ TInt position = iSchemaData->GetSVGElementId(aTagName);
+
+ if ( position == KErrNotFound )
+ {
+ return NULL;
+ }
+
+ return CreateElementL( position );
+
+ }
+
+ // ==========================================================================
+// Need method description
+// ==========================================================================
+MXmlElement* CSvgDocumentImpl::CreateElementL(const TUint8 aTagName )
+ {
+
+ TInt position = (TInt) aTagName;
+
+ //##4 this uses the rearrangement of elements, all these elements are same as g element
+ // same constructor
+ //
+ // =====> creating fake G elements to take the place of others...
+ //
+ //need to remove G elements as place holders that is a bad idea
+
+ if( position >= KSvgAltglyphElement && position <= KSvgViewElement )
+ {
+ return ( MXmlElement * ) CSvgGElementImpl::NewL( (TUint8) position, this );
+ }
+
+ switch ( position )
+ {
+
+ case KSvgPathElement:
+ // path
+ return ( MXmlElement * ) CSvgPathElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgStopElement:
+ // stop
+ return ( MXmlElement * ) CSvgStopElementImpl::NewL((TUint8) position,this);
+
+ case KSvgLinearGradientElement:
+ // linearGradient
+ return ( MXmlElement * ) CSvgLinearGradientElementImpl::NewL((TUint8) position,this);
+
+ case KSvgRectElement:
+ // rect
+ return ( MXmlElement * ) CSvgRectElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgPolygonElement:
+ // polygon
+ return ( MXmlElement * ) CSvgPolylineElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgSvgElement:
+ // svg
+ return ( MXmlElement * ) CSvgSvgElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgRadialGradientElement:
+ // radialGradient
+ return ( MXmlElement * ) CSvgRadialGradientElementImpl::NewL((TUint8) position,this);
+
+ case KSvgCircleElement:
+ // circle
+ return ( MXmlElement * ) CSvgCircleElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgLineElement:
+ // line
+ return ( MXmlElement * ) CSvgLineElementImpl::NewL( (TUint8) position,this );
+
+ case KSvgPolylineElement:
+ // polyline
+ return ( MXmlElement * ) CSvgPolylineElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgEllipseElement:
+ // ellipse
+ return ( MXmlElement * ) CSvgEllipseElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgDefsElement:
+ // defs
+ return ( MXmlElement * ) CSvgDefsElementImpl::NewL((TUint8) position, this);
+
+ case KSvgForeignObjectElement:
+ // foreignObject
+ return ( MXmlElement * ) CSvgForeignObjectElementImpl::NewL((TUint8) position, this);
+
+ case KSvgStyleElement:
+ // style
+ return ( MXmlElement * ) CSvgStyleElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgUseElement:
+ // use
+ return ( MXmlElement * ) CSvgUseElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgImageElement:
+ // image
+ return ( MXmlElement * ) CSvgImageElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgAnimateColorElement:
+ // animateColor
+ case KSvgAnimateElement:
+ {
+ // animate
+ CSvgAnimateElementImpl* lAnimateElement = CSvgAnimateElementImpl::NewL( (TUint8) position, this );
+ iSvgAnimations.Append(lAnimateElement);
+ return ( MXmlElement * ) lAnimateElement;
+ }
+
+ case KSvgSetElement:
+ // set
+ return ( MXmlElement * ) CSvgSetElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgMpathElement:
+ // mPath
+ return ( MXmlElement * ) CSvgMpathElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgDiscardElement:
+ // discard
+ return ( MXmlElement * ) CSvgDiscardElementImpl::NewL( (TUint8) position, this );
+
+ /* case KSvgAnimationElement:
+ {
+ // animation
+ CSvgAnimationElementImpl* lAnimationElementImpl = CSvgAnimationElementImpl::NewL( (TUint8) position, this );
+ iSvgAnimations.Append( lAnimationElementImpl );
+ return ( MXmlElement * ) lAnimationElementImpl;
+ }
+*/
+ case KSvgScriptElement:
+ {
+ // script
+ return ( MXmlElement * ) CSvgScriptElementImpl::NewL((TUint8) position,this);
+ }
+
+ case KSvgSolidColorElement:
+ // solidColor
+ return ( MXmlElement * ) CSvgSolidColorElementImpl::NewL((TUint8) position,this);
+
+ case KSvgMetadataElement:
+ // metaData
+ return ( MXmlElement * ) CSvgMetadataElementImpl::NewL((TUint8) position, this);
+
+ case KSvgDescElement:
+ // desc
+ return ( MXmlElement * ) CSvgDescElementImpl::NewL((TUint8) position, this);
+
+ case KSvgTitleElement:
+ // title
+ return ( MXmlElement * ) CSvgTitleElementImpl::NewL((TUint8) position, this);
+
+ case KSvgTextElement:
+ // text
+ //add in the boolean thing here....
+ return ( MXmlElement * ) CSvgTextElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgTextAreaElement:
+ {
+ // textArea
+ return ( MXmlElement * ) CSvgTextAreaElementImpl::NewL((TUint8) position,this);
+ }
+
+ case KSvgAnimateMotionElement:
+ {
+ // animateMotion
+ CSvgAnimateMotionElementImpl* lAnimateMotionElement = CSvgAnimateMotionElementImpl::NewL( (TUint8) position, this );
+ iSvgAnimations.Append(lAnimateMotionElement);
+ return ( MXmlElement * ) lAnimateMotionElement;
+ }
+
+ case KSvgAnimateTransformElement:
+ {
+ // animateTransform
+ CSvgAnimateTransformElementImpl* lAnimateTransformElement = CSvgAnimateTransformElementImpl::NewL( (TUint8) position, this );
+ iSvgAnimations.Append(lAnimateTransformElement);
+ return ( MXmlElement * ) lAnimateTransformElement;
+ }
+
+ case KSvgGlyphElement:
+ // glyph
+#ifdef SVG_FONTS_INCLUDE
+ return ( MXmlElement * ) CSvgGlyphElementImpl::NewL( (TUint8) position, this );
+#else
+ return ( MXmlElement * ) CSvgGElementImpl::NewL( _L( "g" ),(TUint8) position, this );
+#endif
+ case KSvgFontElement:
+ // font
+#ifdef SVG_FONTS_INCLUDE
+ return ( MXmlElement * ) CSvgFontElementImpl::NewL( (TUint8) position, this );
+#else
+ return ( MXmlElement * ) CSvgGElementImpl::NewL( _L( "g" ),(TUint8) position, this );
+#endif
+
+ case KSvgAElement:
+ // a
+ return ( MXmlElement * ) CSvgAElementImpl::NewL( (TUint8) position, this );
+
+ case KSvgFontfaceElement:
+ // font-face
+#ifdef SVG_FONTS_INCLUDE
+ return ( MXmlElement * ) CSvgFontFaceElementImpl::NewL( (TUint8) position, this );
+#else
+ return ( MXmlElement * ) CSvgGElementImpl::NewL( _L( "g" )(TUint8) position, this );
+#endif
+
+ case KSvgMissingglyphElement:
+ // missing-glyph
+#ifdef SVG_FONTS_INCLUDE
+ return ( MXmlElement * ) CSvgMissingGlyphElementImpl::NewL( (TUint8) position, this );
+#else
+ return ( MXmlElement * ) CSvgGElementImpl::NewL( _L( "g" )(TUint8) position, this );
+#endif
+
+ case KSvgHkernElement:
+ // hkern
+#ifdef SVG_FONTS_INCLUDE
+ return ( MXmlElement * ) CSvgHkernElementImpl::NewL( (TUint8) position, this );
+#else
+ return ( MXmlElement * ) CSvgGElementImpl::NewL( _L( "g" )(TUint8) position, this );
+#endif
+
+ case KSvgAudioElement:
+ {
+ CSvgAudioElementImpl* lAudioElement = CSvgAudioElementImpl::NewL( (TUint8) position, this );
+ iSvgAnimations.Append(lAudioElement);
+ return ( MXmlElement * ) lAudioElement;
+ }
+//#ifdef RD_SVGT_MEDIAANIMATION_SUPPORT
+ case KSvgMediaAnimationElement:
+ {
+ CSvgMediaAnimationElementImpl* lMediaAnimationElement = CSvgMediaAnimationElementImpl::NewL( (TUint8) position, this );
+ iSvgAnimations.Append(lMediaAnimationElement);
+ return ( MXmlElement * ) lMediaAnimationElement;
+ }
+//#endif
+
+ } // for switch
+
+ return NULL;
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TInt CSvgDocumentImpl::CreateAttribute( const TDesC& /* aName */ )
+ {
+ return KErrNone;
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+MXmlElement* CSvgDocumentImpl::GetElementById( const TDesC& aElementId )
+ {
+ if(iRootElement)
+ {
+ const TDesC* myId = iRootElement->Id();
+
+ if (myId)
+ {
+ if (myId->Length() > 0)
+ {
+ if ( *myId == aElementId )
+ {
+ return iRootElement;
+ }
+ }
+ }
+
+ MXmlElement* element = SearchElementById( iRootElement, aElementId );
+
+ return element;
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TInt CSvgDocumentImpl::GetNumberOfIds(MXmlElement* aElement)
+{
+ TInt count = 0;
+
+ CSvgElementImpl* child = ( CSvgElementImpl* ) aElement->FirstChild();
+ while ( child != NULL )
+ {
+ const TDesC* lPtr = child->Id();
+
+ if (lPtr)
+ {
+ count++;
+ }
+ // search children
+ TInt inside_count = GetNumberOfIds( child );
+ if ( inside_count > 0 )
+ {
+ count = count + inside_count;
+ }
+ // search siblings
+
+ child = ( CSvgElementImpl * ) child->NextSibling();
+ }
+
+ return count;
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TDesC* CSvgDocumentImpl::GetId(TInt index)
+{
+ TDesC* id = NULL;
+ RPointerArray<TDesC> ids;
+
+ FindAllIds( (CSvgElementImpl*)RootElement(), ids );
+
+ if (index < ids.Count())
+ {
+ id = ids[index];
+ }
+
+ ids.Close();
+
+ return id;
+}
+
+// ==========================================================================
+// // Return all elements of the given type
+// ==========================================================================
+void CSvgDocumentImpl::FindAllIds( CSvgElementImpl* aStartElement, RPointerArray<TDesC>& aList )
+{
+ if ( aStartElement == NULL )
+ return;
+
+ CSvgElementImpl* child = (CSvgElementImpl*)aStartElement->FirstChild();
+ while ( child != NULL )
+ {
+ // add to list if child is found
+ const TDesC* myId = child->Id();
+
+ if ( myId )
+ aList.Append( myId );
+
+ // find in grandchildren
+ FindAllIds( child, aList );
+ child = (CSvgElementImpl*)child->NextSibling();
+ }
+}
+
+
+//***********************************************************************
+// From MSvgDocument
+//
+
+
+
+//
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TDesC& CSvgDocumentImpl::GetUrl()
+ {
+ return iUri;
+ }
+
+// ==========================================================================
+// // Returns the value of the current focus index.
+// ==========================================================================
+
+TInt32 CSvgDocumentImpl::GetCurFocusIndex()
+{
+ return iCurObjIdx;
+}
+
+
+// ==========================================================================
+// // Increment the focus index by one value
+// ==========================================================================
+
+TInt32 CSvgDocumentImpl::IncCurFocusIndex()
+{
+ return ++iCurObjIdx;
+}
+
+// ==========================================================================
+// // Decrement the focus index by one value
+// ==========================================================================
+TInt32 CSvgDocumentImpl::DecCurFocusIndex()
+{
+ return --iCurObjIdx;
+}
+
+// ==========================================================================
+// // Sets the focus index to the given value
+// ==========================================================================
+void CSvgDocumentImpl::SetCurFocusIndex(TInt32 aVal)
+{
+ iCurObjIdx = aVal;
+}
+
+// ==========================================================================
+// // Returns the current focus object
+// ==========================================================================
+CSvgElementImpl* CSvgDocumentImpl::GetCurFocusObject()
+{
+ return iCurrentFocusObject;
+}
+
+// ==========================================================================
+// // Sets the current focus element to the element specified
+// ==========================================================================
+void CSvgDocumentImpl::SetCurFocusObject(CSvgElementImpl* aElement)
+{
+ iCurrentFocusObject = aElement;
+}
+
+//
+// ==========================================================================
+// Need method description
+// ==========================================================================
+EXPORT_C MXmlElement* CSvgDocumentImpl::RootElement()
+ {
+ return iRootElement;
+ }
+
+//***********************************************************************
+//
+//
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+MXmlElement* CSvgDocumentImpl::SearchElementById( MXmlElement* aElement,
+ const TDesC& aElementId )
+ {
+ CSvgElementImpl* child = ( CSvgElementImpl* ) aElement->FirstChild();
+ while ( child != NULL )
+ {
+ const TDesC* lPtr = child->Id();
+
+ if (lPtr)
+ {
+ if ( *lPtr == aElementId )
+ {
+ return child;
+ }
+ }
+ // search children
+ MXmlElement* childrenMatch = SearchElementById( child, aElementId );
+ if ( childrenMatch != NULL )
+ {
+ return childrenMatch;
+ }
+ // search siblings
+
+ child = ( CSvgElementImpl * ) child->NextSibling();
+
+ }
+ return NULL;
+ }
+
+
+
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+MXmlElement* CSvgDocumentImpl::AppendChildL( MXmlElement* aNewChild )
+ {
+
+ if ( aNewChild && ((CXmlElementImpl*)aNewChild)->ElemID() == KSvgSvgElement )
+
+ {
+ // Set new node as the root element, if it is
+ if ( iRootElement )
+ {
+ return NULL;
+ }
+ iRootElement = (CSvgElementImpl *) aNewChild;
+
+ // Set the new node's next sibling
+ aNewChild->SetNextSibling( NULL );
+ }
+ else
+ {
+ return NULL;
+ }
+
+ return aNewChild;
+ }
+
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+CSvgSchemaData* CSvgDocumentImpl::SchemaData()
+ {
+ return iSchemaData;
+ }
+
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::SetUri( const TDesC& aUri )
+ {
+ iUri.Zero();
+ iUri.Copy(aUri);
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::GetUri( TDes& aUri )
+ {
+ aUri.Zero();
+ aUri.Copy(iUri);
+ }
+
+// ==========================================================================
+// Register an element for receiving events using the event mask
+// ==========================================================================
+void CSvgDocumentImpl::AddToEventReceiverListL( MSvgEventReceiver* aElement,
+ TUint8 aEventMask)
+ {
+ if (iEventHandler != NULL)
+ iEventHandler->AddToEventReceiverListL( aElement, aEventMask );
+ }
+
+// ==========================================================================
+// Register an element for receiving events and events using the event mask
+// ==========================================================================
+void CSvgDocumentImpl::AddToEventReceiverListL( MSvgEventReceiver* aElement,
+ TSvgEvent aEvent,
+ TUint8 aEventMask)
+ {
+ if (iEventHandler != NULL)
+ iEventHandler->AddToEventReceiverListL( aElement,aEvent,aEventMask );
+ }
+
+// ==========================================================================
+// Unregister an element for receiving events using the event mask
+// ==========================================================================
+void CSvgDocumentImpl::RemoveFromEventReceiverList( MSvgEventReceiver* aElement )
+ {
+ if (iEventHandler != NULL)
+ iEventHandler->RemoveFromEventReceiverList( aElement );
+ }
+
+// ==========================================================================
+// Provide event handler the event timing information for the
+// completion of event.
+// ==========================================================================
+void CSvgDocumentImpl::AddEventBeginTime(MSvgEventReceiver* aElement, TUint32 aTime, MSvgEventReceiver* aTargetElement )
+ {
+ if (iEventHandler != NULL)
+ iEventHandler->AddEventBeginTime( aElement, aTime, aTargetElement );
+ }
+
+// ==========================================================================
+// Sort the events in a time scale according to their absolute start
+// and finish times
+// ==========================================================================
+void CSvgDocumentImpl::SortEventList()
+ {
+ if (iEventHandler != NULL)
+ iEventHandler->SortEventList();
+ }
+
+//
+// ==========================================================================
+// Returns an element that is registered for the given event mask and
+// is the first one starting from the given index (either up or down the
+// list based on the aNext parameter)
+// ==========================================================================
+CSvgElementImpl* CSvgDocumentImpl::GetEventReceiverElement(TInt32 aIndex, TBool aNext, TUint8 aEventMask, TInt32& aNewIndex)
+ {
+ if (iEventHandler != NULL)
+ {
+ return (CSvgElementImpl*)iEventHandler->GetEventReceiver(aIndex, aNext, aEventMask, aNewIndex);
+ }
+ else
+ return NULL;
+
+ }
+
+// ==========================================================================
+// Is Animation file
+// ==========================================================================
+TBool CSvgDocumentImpl::IsAnimationFile()
+ {
+ if( (iEventHandler != NULL) && iEventHandler->Count() )
+ return ETrue;
+ else
+ return EFalse;
+ }
+
+// ==========================================================================
+// IsValidSubEventMask
+// ==========================================================================
+TBool CSvgDocumentImpl::IsValidSubEventMask(TUint16 aSubEventMask)
+ {
+ if(iEventHandler)
+ {
+ return(iEventHandler->IsValidSubEventMask(aSubEventMask));
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+// ==========================================================================
+// Set DRM Mode
+// ==========================================================================
+
+void CSvgDocumentImpl::SetDRMMode(TBool aEnable)
+ {
+ iDrmEnable = aEnable;
+ }
+// ==========================================================================
+// Set DRM Mode
+// ==========================================================================
+void CSvgDocumentImpl::Reset(MSvgEvent *aEvent)
+ {
+ if ( iAnimationResetNeeded && iEventHandler != NULL )
+ {
+ iEventHandler->Reset( aEvent );
+ iAnimationResetNeeded = EFalse;
+ }
+ }
+// ==========================================================================
+// Set DRM Mode
+// ==========================================================================
+TBool CSvgDocumentImpl::SvgElementPresent(CSvgElementImpl* aElement)
+{
+ if(iRootElement == NULL) return EFalse;
+ if ( ( ( CSvgElementImpl * ) iRootElement ) == aElement )
+ {
+ return ETrue;
+ }
+
+ return SearchByPointer(iRootElement, aElement);
+
+}
+// ==========================================================================
+// Set DRM Mode
+// ==========================================================================
+TBool CSvgDocumentImpl::SearchByPointer(CSvgElementImpl* aParent, CSvgElementImpl* aElement)
+{
+ CSvgElementImpl* child = ( CSvgElementImpl* ) aParent->FirstChild();
+ while ( child != NULL )
+ {
+
+ if ( child == aElement )
+ {
+ return ETrue;
+ }
+ // search children
+ TBool result = SearchByPointer( child, aElement );
+ if (result)
+ {
+ return ETrue;
+ }
+ // search siblings
+ child = ( CSvgElementImpl * ) child->NextSibling();
+ }
+ return EFalse;
+}
+// ==========================================================================
+// Set DRM Mode
+// ==========================================================================
+void CSvgDocumentImpl::SetFocusElement(CXmlElementImpl* aElement )
+{
+ iCurrentFocusObject = (CSvgElementImpl*)aElement;
+}
+// ==========================================================================
+// Set DRM Mode
+// ==========================================================================
+CXmlElementImpl* CSvgDocumentImpl::GetFocusElement()
+{
+ return (CXmlElementImpl*) iCurrentFocusObject;
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::ReInitialize()
+ {
+ if(iMultipleRendering)
+ {
+ if (iEventHandler != NULL)
+ iEventHandler->ReInitialize();
+ }
+ else
+ {
+ iMultipleRendering= ETrue;
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::Load( const TDesC& aFileName, CSvgErrorImpl& aError )
+{
+ aError.SetErrorCode( ESvgNoError );
+
+ RFs session;
+ OpenSession( session, aError );
+ if ( aError.HasError() )
+ return;
+
+ RFile fileHandle;
+ TInt openError = fileHandle.Open( session, aFileName, EFileRead );
+ if ( openError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, openError,
+ _L( "Fail to open file for reading: " ), aFileName );
+ session.Close();
+ return;
+ }
+ else
+ {
+ Load( fileHandle, aError );
+ session.Close();
+ }
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::Load( const TDesC8& aByteData, CSvgErrorImpl& aError, TBool aRemoveFalseSwitchElements )
+{
+ aError.SetErrorCode( ESvgNoError );
+
+ //-------------------------------------------------------------------
+ // Byte array is gzipped and/or drm:
+ // Write buffer to file:
+ // a) GZip only has filename function to unzip
+ // b) Drm only has file-handle to decrypt
+ //-------------------------------------------------------------------
+ if ( IsGzipContent( aByteData ) ||
+ ( iDrmEnable && IsDRMContent( aByteData ) ) )
+ {
+ RFs session;
+ OpenSession( session, aError );
+ if ( aError.HasError() )
+ return;
+
+ // Write byte-array to temp file
+ TFileName zippedTempFilename;
+ if ( WriteToTempFile( session, aByteData, zippedTempFilename, aError ) != KErrNone )
+ {
+ session.Close();
+ return;
+ }
+ Load( zippedTempFilename, aError );
+ session.Delete( zippedTempFilename );
+ session.Close();
+ }
+ //-------------------------------------------------------------------
+ // byte-array is neither gzipped nor DRM encrypted
+ //-------------------------------------------------------------------
+ else
+ {
+ iIsDRMProtected = EFalse;
+ iEventHandler->Reset();
+ TRAPD(error,ProcessSvgContentL( aByteData, aError, aRemoveFalseSwitchElements ));
+ if ( error != KErrNone )
+ {
+ PrepareError( aError, ESvgNoMemory, error,
+ _L( "Out of Memory: " ),
+ _L( "Instantiating Parser" ) );
+ }
+
+ iInitialDrawFlag = ETrue;
+ iFinishedParsing = ETrue;
+
+ }
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::Load( RFile& aFileHandle, CSvgErrorImpl& aError )
+{
+ aError.SetErrorCode( ESvgNoError );
+
+ RFs session;
+ OpenSession( session, aError );
+ if ( !aError.HasError() )
+ {
+ Load( session, aFileHandle, aError );
+ session.Close();
+ }
+}
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::ParentTimeContainerTick
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+//
+void CSvgDocumentImpl::ParentTimeContainerTick(
+ TSvgTick aTick ) // Current tick information
+ {
+ TBool lDoRedraw = ETrue;
+ if ( iHasParent )
+ {
+ // Do not redraw in child document to avoid
+ // double redraws.
+ lDoRedraw = EFalse;
+ }
+ // Create timer event and propogate to engine
+ TSvgTimerEvent lTimerEvent( aTick.iParentTcTick );
+ // Send to engine to process the timer event
+ TRAPD( lProcEvtErr, Engine()->ProcessEventL(
+ this, &lTimerEvent, lDoRedraw ) );
+ if ( lProcEvtErr != KErrNone )
+ {
+ // Error Processing
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::GetEntitySyncBehavior
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+//
+TSvgSyncBehaviour CSvgDocumentImpl::GetEntitySyncBehavior()
+ {
+ // Document is locked with the parent tc timeline
+ return ESvgSyncLocked;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::GetEntityCurrentTime
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+//
+void CSvgDocumentImpl::GetEntityCurrentTime( TUint32&
+ /* aEntityCurTime */) // Current Entity Time in msecs.
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::GetCnfSyncMasterStatus
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+//
+void CSvgDocumentImpl::GetCnfSyncMasterStatus(
+ TBool& aIsSyncMaster ) // Indicates whether the element is configured as
+ // Sync Master.
+ {
+ // Document can never be a sync master
+ aIsSyncMaster = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::GetCurSyncMasterStatus
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+void CSvgDocumentImpl::GetCurSyncMasterStatus(
+ TBool& aIsSyncMaster ) // Indicates whether the element is currrently
+ // Sync Master.
+ {
+ // Document can never be a sync master
+ aIsSyncMaster = EFalse;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::SetCurSyncMasterStatus
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+void CSvgDocumentImpl::SetCurSyncMasterStatus(
+ TBool /*aSyncMasterStatus */) // Indicates whether the element is
+ // currrently Sync Master.
+ {
+ // Document sync master status is always false as it can never be
+ // a sync master
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::CanGenerateTick
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+TBool CSvgDocumentImpl::CanGenerateTick()
+ {
+ // Document cannot generate tick, as it is not a inherently timed element
+ return EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::CanUseParentTick
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+TBool CSvgDocumentImpl::CanUseParentTick()
+ {
+ // Return True as document can always use parent tick to
+ // advance itself
+ return ( ETrue );
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::ResyncTimedEntity
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+void CSvgDocumentImpl::ResyncTimedEntity(
+ TUint32 /*aSynctime*/ ) // Time for resync in msecs.
+ {
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::PauseTimedEntity
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+void CSvgDocumentImpl::PauseTimedEntity()
+ {
+
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::ResumeTimedEntity
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+void CSvgDocumentImpl::ResumeTimedEntity()
+ {
+
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::StopTimedEntity
+// From MSvgTimedEntityInterface
+// -----------------------------------------------------------------------------
+void CSvgDocumentImpl::StopTimedEntity()
+ {
+ iEventHandler->ResetTimes();
+ }
+
+
+//From MSvgTimedEntityInterface
+TSvgObjectType CSvgDocumentImpl::ObjectType()
+{
+ return ESvgDocumentElement;
+}
+
+
+//returns the child time container of the element
+//used in timecontainer
+CSvgTimeContainer* CSvgDocumentImpl::GetChildTimeContainer()
+{
+ return NULL;
+}
+
+
+//if node has a child
+// visit the child call postorder on that
+//add current node
+//if there are siblings
+// visit all siblings
+void CSvgDocumentImpl::ParsePostOrderMediaElements( CSvgElementImpl* aRoot,
+ RPointerArray<CSvgElementImpl>& aPostOrderList)
+ {
+ if ( !aRoot )
+ {
+ return;
+ }
+
+ CSvgElementImpl* lNodePtr = ( CSvgElementImpl* )aRoot->FirstChild();
+ while ( lNodePtr != NULL )
+ {
+ ParsePostOrderMediaElements( lNodePtr, aPostOrderList );
+ lNodePtr = (CSvgElementImpl* )(lNodePtr->NextSibling() );
+ }
+
+ // Add only media elements, currently animation and audio
+ if ( aRoot->ElemID() == KSvgMediaAnimationElement ||
+ aRoot->ElemID() == KSvgAudioElement )
+ {
+ aPostOrderList.Append( aRoot );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::Load( RFs& aSession, RFile& aFileHandle, CSvgErrorImpl& aError )
+{
+ iEventHandler->Reset();
+
+ RFile ungzippedFile;
+ RFile* fileHandle = &aFileHandle;
+ TFileName tempFilename;
+ TBool needToDeleteTempFile = EFalse;
+ iIsDRMProtected = EFalse;
+
+ //************************************************
+ // Check for gzip format: write to temp file
+ //************************************************
+ // Ignore Gzip content due to platform security: uncompressed file must be created
+ if ( IsGzipContent( aFileHandle ) )
+ {
+ //************************************************
+ // Ungzipped content may be DRM or txt-svg or binary-svg
+ //************************************************
+ needToDeleteTempFile = ETrue;
+ if ( !ProcessGZipContent( aSession, aFileHandle, tempFilename, aError ) )
+ return;
+
+ // Open ungzipped file
+ TInt openError = ungzippedFile.Open( aSession, tempFilename, EFileRead );
+ if ( openError != KErrNone )
+ {
+ // couldn't open temp file for writing
+ PrepareError( aError, ESvgUnknown, openError,
+ _L( "Loading GZipped SVG File failed: " ),
+ _L( "Error Opening Temp File for Reading." ) );
+
+ // Delete uncompress temp file if needed
+ if ( needToDeleteTempFile )
+ aSession.Delete( tempFilename );
+ return;
+ }
+ fileHandle = &ungzippedFile;
+ }
+
+ HBufC8* svgByteArray = NULL;
+ //************************************************
+ // Decrypt DRM
+ //************************************************
+ if ( iDrmEnable && IsDRMContent( *fileHandle ) )
+ {
+ TRAPD( drmError, svgByteArray = ProcessDRMContentL( *fileHandle, aError ) );
+ if ( drmError != KErrNone )
+ {
+ PrepareError( aError, ESvgNoMemory, drmError,
+ _L( "Out of Memory: " ),
+ _L( "Instantiating DRM Decoder" ) );
+ return;
+ }
+ // drm failed, error should already be set
+ else if ( svgByteArray == NULL )
+ {
+ return;
+ }
+
+ if ( needToDeleteTempFile && ( drmError || svgByteArray == NULL ) )
+ {
+ aSession.Delete( tempFilename );
+ }
+ iIsDRMProtected = ETrue;
+ }
+ // Read Non encrypted data
+ else
+ {
+ //************************************************
+ // Read plain file: txt-svg or binary-svg
+ //************************************************
+ TInt fileLength = 0;
+ fileHandle->Size( fileLength );
+ TRAPD( error, svgByteArray = HBufC8::NewL( fileLength ) );
+ if ( error != NULL )
+ {
+ PrepareError( aError, ESvgNoMemory, error,
+ _L( "Out of Memory" ),
+ _L( "Allocating byte-array for data" ) );
+ if ( needToDeleteTempFile )
+ {
+ aSession.Delete( tempFilename );
+ }
+ return;
+ }
+ TInt pos = 0;
+ fileHandle->Seek( ESeekStart, pos );
+ TPtr8 des = svgByteArray->Des();
+ TInt readError = fileHandle->Read( des );
+ if ( readError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, readError,
+ _L( "Reading SVG File Failed." ), _L( "" ) );
+ delete svgByteArray;
+ if ( needToDeleteTempFile )
+ {
+ aSession.Delete( tempFilename );
+ }
+ return;
+ }
+ }
+
+ //************************************************
+ // Parser binary or plain svg content
+ //************************************************
+ TRAPD( svgError, ProcessSvgContentL( *svgByteArray, aError ) );
+ if ( svgError != KErrNone || ( aError.HasError() && !aError.IsWarning() ) )
+ {
+ delete svgByteArray;
+ if ( !aError.HasError() )
+ {
+ PrepareError( aError, ESvgNoMemory, svgError,
+ _L( "Out of Memory: " ),
+ _L( "Instantiating SVG ContentHandler/Decoder" ) );
+ }
+ if ( needToDeleteTempFile )
+ aSession.Delete( tempFilename );
+ return;
+ }
+
+ iInitialDrawFlag = ETrue;
+ iFinishedParsing = ETrue;
+
+ delete svgByteArray;
+
+
+ // Delete uncompress temp file if needed
+ if ( needToDeleteTempFile )
+ {
+ // Close only when file handle is for temp file
+ fileHandle->Close();
+ aSession.Delete( tempFilename );
+ }
+
+ // Prepare engine to draw document
+ LoadingCompleted();
+}
+
+// ==========================================================================
+// Need method description
+// Leaves only when allocating memory fails
+// Reports other errors
+// ==========================================================================
+void CSvgDocumentImpl::ProcessSvgContentL( const TDesC8& aByteArray, CSvgErrorImpl& aError, TBool aRemoveFalseSwitchElements )
+{
+ //************************************************
+ // Determine binary or xml svg file
+ //************************************************
+ if ( IsBinarySvg( aByteArray ) )
+ {
+ TInt error = KErrNone;
+ CSvgDecoder* decoder = CSvgDecoder::NewL( aByteArray );
+
+ TRAP( error, iRootElement = decoder->StartDecodingL( this, aError ) );
+ if ( error != KErrNone || iRootElement == NULL && !aError.HasError() )
+ {
+ if ( error != KErrNone )
+ {
+ PrepareError( aError, ESvgbFileNotValid, error,
+ _L( "Invalid binary file." ), _L( "" ) );
+ }
+ }
+ delete decoder;
+ }
+ else
+ {
+ iXmlHandler = CSvgContentHandler::NewL( aRemoveFalseSwitchElements );
+ iRootElement = iXmlHandler->ParseByteData( this, aByteArray, aError );
+ delete iXmlHandler;
+ iXmlHandler = NULL;
+ }
+}
+
+// ==========================================================================
+// JSR226 only!!
+// Allows filling of document from JSR side with 16 bit string instead of 8
+//
+// ==========================================================================
+void CSvgDocumentImpl::Load16BitString( const TDesC16& aSvgString, CSvgErrorImpl& aError, TBool aRemoveFalseSwitchElements )
+{
+ aError.SetErrorCode( ESvgNoError );
+
+ iIsDRMProtected = EFalse;
+
+ if (iEventHandler)
+ iEventHandler->Reset();
+ TRAPD(error,Process16BitSvgContentL( aSvgString, aError, aRemoveFalseSwitchElements ));
+ if ( error != KErrNone )
+ {
+ PrepareError( aError, ESvgNoMemory, error,
+ _L( "Out of Memory: " ),
+ _L( "Instantiating Parser" ) );
+ }
+
+ iInitialDrawFlag = ETrue;
+ iFinishedParsing = ETrue;
+}
+
+void CSvgDocumentImpl::Process16BitSvgContentL( const TDesC16& aSvgString, CSvgErrorImpl& aError, TBool aRemoveFalseSwitchElements )
+{
+ iXmlHandler = CSvgContentHandler::NewL( aRemoveFalseSwitchElements );
+ iRootElement = iXmlHandler->Parse16BitData( this, aSvgString, aError );
+ delete iXmlHandler;
+ iXmlHandler = NULL;
+}
+// END OF JSR226 ONLY
+// ==========================================================================
+
+// ==========================================================================
+void CSvgDocumentImpl::CancelParsing()
+ {
+ // Check if there is animation element in the parent svg
+ RPointerArray<CSvgElementImpl> lAnimationEleList;
+ FindAllElements((CSvgElementImpl* )RootElement(),
+ KSvgMediaAnimationElement, lAnimationEleList );
+ TInt lAnimationEleCnt = lAnimationEleList.Count();
+ for ( TInt lCurAnimationEle = 0;
+ lCurAnimationEle < lAnimationEleCnt; lCurAnimationEle++ )
+ {
+ CSvgMediaAnimationElementImpl* lAnimationElement =
+ (CSvgMediaAnimationElementImpl* )lAnimationEleList[ lCurAnimationEle ];
+ CSvgDocumentImpl* lChildDoc = lAnimationElement->GetChildDocument();
+ if ( lChildDoc )
+ {
+ lChildDoc->CancelParsing(); // Cancel parsing on child svg
+ }
+ }
+ lAnimationEleList.Close();
+ if ( iXmlHandler )
+ {
+ iXmlHandler->CancelParsing();
+ }
+ }
+
+// ==========================================================================
+TBool CSvgDocumentImpl::IsParsing()
+ {
+ // xml handler is set to NULL after parsing
+ return iXmlHandler != NULL;
+ }
+
+//***************************************************************************
+// The function isGroupOpacity checks to see if there is a valid opacity
+// attribute.
+//***************************************************************************
+
+TBool CSvgDocumentImpl::isGroupOpacity( CSvgElementImpl* aElement )
+{
+ TBool lReturnValue = EFalse;
+ CCssValue* lCssValue = NULL;
+
+ aElement->FindProperty( KCSS_ATTR_GROUP_OPACITY, lCssValue, aElement );
+ if ( lCssValue )
+ {
+ if ( ((CFloatCssValueImpl*)lCssValue)->Value() != KFloatFixOne )
+ {
+ // valid opacity value
+ lReturnValue = ETrue;
+ }
+ }
+
+ return lReturnValue;
+}
+
+
+// ==========================================================================
+// Pre-condition: content is DRM
+// The content of a DRM may be svg-text or svg-bin
+// Leaves only for memory allocation failure
+// ==========================================================================
+HBufC8* CSvgDocumentImpl::ProcessDRMContentL( RFile& aFileHandle, CSvgErrorImpl& aError )
+{
+ // Open File Content and Data
+ ContentAccess::CContent* content = ContentAccess::CContent::NewLC(
+ aFileHandle );
+ // Note: very important to use EView and NOT EPlay
+ ContentAccess::CData* data = content->OpenContentLC( ContentAccess::EView );
+
+ // Read Length of Content
+ TInt length = 0;
+ TRAPD( sizeError, data->DataSizeL( length ) );
+ // Cannot get length of data
+ if ( sizeError != KErrNone )
+ {
+ ProcessDRMError( sizeError, aError );
+ CleanupStack::PopAndDestroy( 2 );
+ return NULL;
+ }
+
+ // Allocate Memory for Content: no leavable command after this
+ // so, pushing onto cleanup stack not needed
+ HBufC8* buffer = HBufC8::NewL( length );
+
+ TPtr8 des = buffer->Des();
+ TInt readError = data->Read( des );
+
+ // Check for read error
+ if ( readError != KErrNone )
+ {
+ ProcessDRMError( readError, aError );
+ CleanupStack::PopAndDestroy( 2 );
+ delete buffer;
+ return NULL;
+ }
+ // Only consume rights when not in thumb nail mode
+ else if ( !iIsThumbNailMode )
+ {
+ // Do not consume drm rights if iDrmRightsConsumptionEnabled is EFalse
+ if(iDrmRightsConsumptionEnabled)
+ {
+ TInt intentError = data->ExecuteIntent( ContentAccess::EView );
+ if ( intentError != KErrNone )
+ {
+ ProcessDRMError( readError, aError );
+ aError.SetIsWarning( ETrue );
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( 2 );
+ return buffer;
+}
+
+// ==========================================================================
+// Un-gzip to a temp file and return the name of temp file
+// ==========================================================================
+TBool CSvgDocumentImpl::ProcessGZipContent( RFs& aSession,
+ RFile& aGZipFileHandle,
+ TFileName& aUnzippedFileName ,
+ CSvgErrorImpl& aError )
+{
+ // Write data to temp file: gzip does not have function to read RFile
+ TFileName gzipFilename;
+ if ( WriteToTempFile( aSession, aGZipFileHandle, gzipFilename, aError ) != KErrNone )
+ return EFalse;
+
+ TBool result = ProcessGZipContent( aSession, gzipFilename, aUnzippedFileName, aError );
+
+ // Delete temp gzipped file
+ aSession.Delete( gzipFilename );
+
+ return result;
+}
+
+// ==========================================================================
+// Uncompress to a temporary file
+// ==========================================================================
+TBool CSvgDocumentImpl::ProcessGZipContent( RFs& aSession,
+ TFileName& aZippedFileName,
+ TFileName& aUnzippedFileName ,
+ CSvgErrorImpl& aError )
+{
+ // Create ungzipped temp file
+ TFileName path;
+ GetProcessPrivatePath( aSession, path );
+ RFile gzipOutputFile;
+ TInt replaceError = gzipOutputFile.Temp( aSession, path, aUnzippedFileName, EFileWrite );
+ if ( replaceError != KErrNone )
+ {
+ // couldn't open temp file for writing
+ PrepareError( aError, ESvgUnknown, replaceError,
+ _L( "Failed to create file or unGZip: " ), aUnzippedFileName );
+ return EFalse;
+ }
+
+ // okay so far, uncompressing
+ CEZGZipToFile* uncompressor = NULL;
+ TRAPD( uncompressorError,
+ uncompressor = CEZGZipToFile::NewL( aSession, aZippedFileName, gzipOutputFile ) )
+ if ( uncompressorError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, uncompressorError,
+ _L( "Out of memory: " ),
+ _L( "Instantiating GZip decompressor" ) );
+ gzipOutputFile.Close();
+ aSession.Delete( aUnzippedFileName );
+
+ return EFalse;
+ }
+
+ // Decompress file
+ TBool done = EFalse;
+ while ( !done )
+ {
+ TRAPD( inflateError, done = !uncompressor->InflateL() );
+ if ( inflateError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, inflateError,
+ _L( "Uncompressing GZip file failed." ), _L( "" ) );
+ delete uncompressor;
+ gzipOutputFile.Close();
+ aSession.Delete( aUnzippedFileName );
+
+ return EFalse;
+ }
+ }
+
+ gzipOutputFile.Close();
+ delete uncompressor;
+
+ return ETrue;
+}
+
+// ==========================================================================
+// Error codes taken from caf/content.h
+// ==========================================================================
+void CSvgDocumentImpl::ProcessDRMError( TInt errorCode, CSvgErrorImpl& aError )
+{
+ if ( errorCode == KErrNone )
+ return;
+
+ if ( errorCode == KErrNotFound )
+ {
+ aError.SetDescription( _L( "Content Not Found" ) );
+ }
+ else if ( errorCode == KErrCAPendingRights )
+ {
+ aError.SetDescription( _L( "Rights Have Not Arrived" ) );
+ }
+ else if ( errorCode == KErrCANoPermission )
+ {
+ aError.SetDescription( _L( "No Permission to Play Content" ) );
+ }
+ else if ( errorCode == KErrCANoRights )
+ {
+ aError.SetDescription( _L( "No Rights Exists for Content" ) );
+ }
+ else if ( errorCode == KErrCANotSupported )
+ {
+ aError.SetDescription( _L( "Unable to Open Content" ) );
+ }
+ else if ( errorCode == KErrPermissionDenied )
+ {
+ aError.SetDescription( _L( "No Permission to Open Content" ) );
+ }
+ else if ( errorCode == KErrAccessDenied )
+ {
+ aError.SetDescription( _L( "Content Already in Use or No DRM Capability" ) );
+ }
+ else if ( errorCode == KErrCASizeNotDetermined )
+ {
+ aError.SetDescription( _L( "Cannot Determine Size of Content" ) );
+ }
+ else
+ {
+ aError.SetDescription( _L( "Unknown DRM Error" ) );
+ }
+ aError.SetIsWarning( EFalse );
+ aError.SetErrorCode( ESvgDRMFailure );
+ aError.SetSystemErrorCode( errorCode );
+}
+
+// ==========================================================================
+// Returns true if the first two bytes of the given file could be a gzip file.
+// This function is modified from the function in EZGZipFile class.
+// ==========================================================================
+TBool CSvgDocumentImpl::IsGzipContent( RFile& aFileHandle )
+{
+ TUint8 ids[2];
+ TPtr8 des( ids, 0, sizeof( TUint8 ) * 2 );
+
+ if ( aFileHandle.Read( des ) != KErrNone )
+ return EFalse;
+
+ // reset to start of file
+ TInt zero = 0;
+ aFileHandle.Seek( ESeekStart, zero );
+ return ( ids[0] == 31 && ids[1] == 139 );
+// return ( ids[0] == EZGZipFile::ID1 && ids[1] == EZGZipFile::ID2 );
+}
+
+// ==========================================================================
+// Returns whether the byte-array header matches a GZIP signature
+// ==========================================================================
+TBool CSvgDocumentImpl::IsGzipContent( const TDesC8& aByteArray )
+{
+ return aByteArray.Length() >= 2 &&
+ aByteArray[0] == 31 && aByteArray[1] == 139;
+// aByteArray[0] == EZGZipFile::ID1 && aByteArray[1] == EZGZipFile::ID2;
+}
+
+// ==========================================================================
+// Returns whether the byte-array header matches a SVG binary signature
+// ==========================================================================
+TBool CSvgDocumentImpl::IsBinarySvg( const TDesC8& aByteArray )
+{
+ //const TUint32 KBinaryFile = 66737868;
+ //const TUint32 KBinaryFile2 = 66737869;
+
+ if ((aByteArray.Length() >= 4 &&
+ aByteArray[0] == 0xCC && aByteArray[1] == 0x56 &&
+ aByteArray[2] == 0xFA && aByteArray[3] == 0x03) ||
+ (aByteArray.Length() >= 4 &&
+ aByteArray[0] == 0xCD && aByteArray[1] == 0x56 &&
+ aByteArray[2] == 0xFA && aByteArray[3] == 0x03) ||
+ (aByteArray.Length() >= 4 &&
+ aByteArray[0] == 0xCE && aByteArray[1] == 0x56 &&
+ aByteArray[2] == 0xFA && aByteArray[3] == 0x03) ||
+ (aByteArray.Length() >= 4 &&
+ aByteArray[0] == 0xCF && aByteArray[1] == 0x56 &&
+ aByteArray[2] == 0xFA && aByteArray[3] == 0x03) )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+}
+
+// ==========================================================================
+// Returns whether the file header matches a DRM signature
+// ==========================================================================
+TBool CSvgDocumentImpl::IsDRMContent( RFile& aFileHandle )
+{
+ TUint8 ids[2];
+ TPtr8 des( ids, 0, sizeof( TUint8 ) * 2 );
+
+ if ( aFileHandle.Read( des ) != KErrNone )
+ return EFalse;
+
+ // reset to start of file
+ TInt zero = 0;
+ aFileHandle.Seek( ESeekStart, zero );
+ return ( ids[0] == 0x01 && ids[1] == 0x0D );
+}
+
+// ==========================================================================
+// Returns whether the file header matches a DRM signature
+// ==========================================================================
+TBool CSvgDocumentImpl::IsDRMContent( const TDesC8& aByteArray )
+{
+ return ( aByteArray.Length() > 1 && aByteArray[0] == 0x01 && aByteArray[1] == 0x0D );
+}
+
+// ==========================================================================
+// Generate the "c:/private/<sid>" directory name
+// ==========================================================================
+TInt CSvgDocumentImpl::GetProcessPrivatePath( RFs& aSession, TFileName& aPath )
+{
+ aSession.PrivatePath( aPath );
+ aPath.Insert( 0, _L( "c:" ) );
+ return KErrNone;
+}
+
+// ==========================================================================
+// Create "c:/private/<sid>" directory if it does not already exist
+// ==========================================================================
+TInt CSvgDocumentImpl::CreateProcessPrivateDirectory( RFs& aSession, TFileName& aPath )
+{
+ GetProcessPrivatePath( aSession, aPath );
+ return ( !BaflUtils::FolderExists( aSession, aPath ) ) ? aSession.MkDir( aPath ) : KErrNone;
+}
+
+// ==========================================================================
+// Open a file session, error is indicated in aError
+// ==========================================================================
+void CSvgDocumentImpl::OpenSession( RFs& aSession, CSvgErrorImpl& aError )
+{
+ TInt error = aSession.Connect();
+ if ( error != KErrNone )
+ {
+ // couldn't open temp file for writing
+ PrepareError( aError, ESvgUnknown, error,
+ _L( "Connecting File Session Failed." ), _L( "" ) );
+ }
+}
+
+// ==========================================================================
+// Session must be opened successfully
+// File name of temp file is store in aFilename
+// ==========================================================================
+TInt CSvgDocumentImpl::WriteToTempFile( RFs& aSession, const TDesC8& aByteArray,
+ TFileName& aFilename, CSvgErrorImpl& aError )
+{
+ // Create temporary file for byte-array
+ TFileName path;
+ CreateProcessPrivateDirectory( aSession, path );
+ RFile writeFile;
+ TInt tempError = writeFile.Temp( aSession, path, aFilename, EFileWrite );
+ if ( tempError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, tempError,
+ _L( "Failed open temp file to write data." ), aFilename );
+ return tempError;
+ }
+
+ // Write byte-array to file
+ TInt writeError = writeFile.Write( aByteArray );
+ if ( writeError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, writeError,
+ _L( "Failed to write data to temp file." ), aFilename );
+ writeFile.Close();
+ aSession.Delete( aFilename );
+ return writeError;
+ }
+ writeFile.Flush();
+ writeFile.Close();
+
+ return KErrNone;
+}
+
+// ==========================================================================
+// Session must be opened successfully
+// File name of temp file is store in aFilename
+// ==========================================================================
+TInt CSvgDocumentImpl::WriteToTempFile( RFs& aSession, RFile& aFileHandle,
+ TFileName& aFilename, CSvgErrorImpl& aError )
+{
+ // Create temporary file for byte-array
+ TFileName path;
+ CreateProcessPrivateDirectory( aSession, path );
+ RFile writeFile;
+ TInt tempError = writeFile.Temp( aSession, path, aFilename, EFileWrite );
+ if ( tempError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, tempError,
+ _L( "Failed open temp file to write data." ), path );
+ return tempError;
+ }
+
+ // Write data to temp file
+ TInt size;
+ TInt sizeError = aFileHandle.Size( size );
+ if ( sizeError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, sizeError,
+ _L( "Failed to get data length of file." ), aFilename );
+ aSession.Delete( aFilename );
+ return sizeError;
+ }
+
+ TBuf8<1024> buffer;
+ TInt bytesCopied = 0;
+ while ( bytesCopied < size )
+ {
+ buffer.Zero();
+ TInt bytesToCopy = ( size - bytesCopied < 1024 ) ? size - bytesCopied : 1024;
+ // read data
+ TInt readError = aFileHandle.Read( buffer, bytesToCopy );
+ if ( readError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, readError,
+ _L( "Failed to read data to copy to temp file: " ), aFilename );
+ writeFile.Close();
+ aSession.Delete( aFilename );
+ return readError;
+ }
+ // write data
+ TInt writeError = writeFile.Write( buffer, bytesToCopy );
+ if ( writeError != KErrNone )
+ {
+ PrepareError( aError, ESvgUnknown, writeError,
+ _L( "Failed to write to temp file: " ), aFilename );
+ writeFile.Close();
+ aSession.Delete( aFilename );
+ return writeError;
+ }
+ bytesCopied += bytesToCopy;
+ }
+
+ writeFile.Flush();
+ writeFile.Close();
+
+ return KErrNone;
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::PrepareError( CSvgErrorImpl& aError,
+ TSvgErrorCode aSvgErrorCode,
+ TInt aSystemErrorCode,
+ const TDesC& aMsg1,
+ const TDesC& aMsg2 )
+{
+ aError.SetDescription( aMsg1, aMsg2 );
+ aError.SetErrorCode( aSvgErrorCode );
+ aError.SetSystemErrorCode( aSystemErrorCode );
+ aError.SetIsWarning( EFalse );
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::LoadingCompleted()
+{
+ if ( iEngine != NULL && iEngine->GraphicsContext() != NULL )
+ {
+ iEngine->GraphicsContext()->SetDoDithering( iHasGradientElement );
+ }
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::SetThumbNailMode( TBool aThumbNailMode )
+{
+ iIsThumbNailMode = aThumbNailMode;
+}
+
+//==========================================================================
+// CSvgDocumentImpl::SetDRMRights( TBool aEnable )
+//==========================================================================
+void CSvgDocumentImpl::SetDRMRights( TBool aEnable)
+{
+ iDrmRightsConsumptionEnabled = aEnable;
+}
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TBool CSvgDocumentImpl::IsThumbNailOnly()
+{
+ return iIsThumbNailMode && iIsDRMProtected;
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::SetWasPrepared( TBool aBool )
+{
+ iWasPrepared = aBool;
+
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TBool CSvgDocumentImpl::WasPrepared()
+{
+ return iWasPrepared;
+}
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::SetLoadingListeners( const RPointerArray<MSvgLoadingListener>* aList )
+ {
+ iLoadingListeners = aList;
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+const RPointerArray<MSvgLoadingListener>* CSvgDocumentImpl::GetLoadingListeners()
+ {
+ return iLoadingListeners;
+ }
+
+/*---------------------------MouseListener---------------------------*/
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::AddInternalMouseListener( const MSvgMouseListener* aListener )
+ {
+ TInt index = iSvgMouseListeners.Find( aListener );
+ if ( aListener != NULL && index == KErrNotFound )
+ {
+ iSvgMouseListeners.Append( aListener );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::RemoveInternalMouseListener( const MSvgMouseListener* aListener )
+ {
+ TInt index = iSvgMouseListeners.Find( aListener );
+ if ( index != KErrNotFound )
+ {
+ iSvgMouseListeners.Remove( index );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TInt CSvgDocumentImpl::MouseInternalListenerCount()
+ {
+ return iSvgMouseListeners.Count();
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyInternalMousePressed( RPointerArray<CSvgElementImpl>& aElements,
+ TInt aX, TInt aY )
+ {
+
+ for ( TInt i = 0; i < iSvgMouseListeners.Count(); i++ )
+ {
+ iSvgMouseListeners[i]->MousePressed( aElements, aX, aY );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyInternalMouseReleased( RPointerArray<CSvgElementImpl>& aElements,
+ TInt aX, TInt aY )
+ {
+
+ for ( TInt i = 0; i < iSvgMouseListeners.Count(); i++ )
+ {
+ iSvgMouseListeners[i]->MouseReleased( aElements, aX, aY );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyInternalMouseEntered( RPointerArray<CSvgElementImpl>& aElements,
+ TInt aX, TInt aY )
+ {
+
+ for ( TInt i = 0; i < iSvgMouseListeners.Count(); i++ )
+ {
+ iSvgMouseListeners[i]->MouseEntered( aElements, aX, aY );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyInternalMouseExited( RPointerArray<CSvgElementImpl>& aElements,
+ TInt aX, TInt aY )
+ {
+
+ for ( TInt i = 0; i < iSvgMouseListeners.Count(); i++ )
+ {
+ iSvgMouseListeners[i]->MouseExited( aElements, aX, aY );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyInternalMouseMoved( RPointerArray<CSvgElementImpl>& aElements,
+ TInt aX, TInt aY )
+ {
+
+ for ( TInt i = 0; i < iSvgMouseListeners.Count(); i++ )
+ {
+ iSvgMouseListeners[i]->MouseMoved( aElements, aX, aY );
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyDocumentStart()
+ {
+ if ( iLoadingListeners != NULL )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ (*iLoadingListeners)[i]->DocumentStart();
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyDocumentEnd()
+ {
+ if ( iLoadingListeners != NULL )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ (*iLoadingListeners)[i]->DocumentEnd();
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyElementStart( const TDesC& aTagName,
+ MSvgAttributeList& aAttributeList,
+ TBool aIsSvgChild )
+ {
+ // Do not send back attribute list if content was decrypted
+ // from DRM protected content.
+ if ( iLoadingListeners != NULL && !iIsDRMProtected )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ if ( aIsSvgChild || (*iLoadingListeners)[i]->ReportAllElements() )
+ {
+ (*iLoadingListeners)[i]->ElementStart( aTagName, aAttributeList );
+ }
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyElementEnd( const TDesC& aTagName, TBool aIsSvgChild )
+ {
+ if ( iLoadingListeners != NULL )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ if ( aIsSvgChild || (*iLoadingListeners)[i]->ReportAllElements() )
+ {
+ (*iLoadingListeners)[i]->ElementEnd( aTagName );
+ }
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyUnsupportedElement( const TDesC& aTagName,
+ MSvgAttributeList& aAttributeList )
+ {
+ if ( iLoadingListeners != NULL )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ (*iLoadingListeners)[i]->UnsupportedElement( aTagName, aAttributeList );
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyExternalDataRequested( const TDesC& aUri )
+ {
+ if ( iLoadingListeners != NULL )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ (*iLoadingListeners)[i]->ExternalDataRequested( aUri );
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyExternalDataReceived( const TDesC& aUri )
+ {
+ if ( iLoadingListeners != NULL )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ (*iLoadingListeners)[i]->ExternalDataReceived( aUri );
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+void CSvgDocumentImpl::NotifyExternalDataRequestFailed( const TDesC& aUri )
+ {
+ if ( iLoadingListeners != NULL )
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ (*iLoadingListeners)[i]->ExternalDataRequestFailed( aUri );
+ }
+ }
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TUint32 CSvgDocumentImpl::IsIndefiniteAnimation()
+ {
+ if ( !iCheckedAnimationDuration )
+ {
+ AnimationDuration();
+ }
+ // special value for indefinite animation
+ return ( iAnimationDuration == KIndefiniteAnimationDuration );
+ }
+
+// ==========================================================================
+// Need method description
+// ==========================================================================
+TUint32 CSvgDocumentImpl::AnimationDuration()
+ {
+ if ( iCheckedAnimationDuration )
+ {
+ return IsIndefiniteAnimation() ? 0xFFFFFFFF : iAnimationDuration;
+ }
+ else if ( iRootElement == NULL )
+ {
+ return 0;
+ }
+
+ if ( iIsInteractive )
+ {
+ // If there is interactivity in the content, set the animation
+ // duration to indefinite so that the timer continues to run.
+ iAnimationDuration = KIndefiniteAnimationDuration;
+ }
+ else
+ {
+ iAnimationDuration = SubtreeDuration( iRootElement );
+ }
+
+ iCheckedAnimationDuration = ETrue;
+ return IsIndefiniteAnimation() ? 0xFFFFFFFF : iAnimationDuration;
+ }
+
+// ==========================================================================
+// Return the longest animation in subtree
+// ==========================================================================
+TUint32 CSvgDocumentImpl::SubtreeDuration( CSvgElementImpl* aRootElement )
+ {
+ TUint dur = 0;
+
+ if ( aRootElement->IsAnimatedElement() )
+ {
+ dur = ( ( CSvgAnimationBase * ) aRootElement )->CompleteDuration();
+ }
+
+ else if ( aRootElement->ElemID() == KSvgDiscardElement )
+ {
+ dur = ((CSvgDiscardElementImpl*)aRootElement)->AbsoluteBeginTime();
+ }
+
+ // check child duration
+ TUint childDur;
+ CSvgElementImpl* child = (CSvgElementImpl*)aRootElement->FirstChild();
+ while ( child != NULL )
+ {
+ childDur = SubtreeDuration( child );
+ if ( childDur > dur )
+ {
+ dur = childDur;
+ }
+ child = (CSvgElementImpl*)child->NextSibling();
+ }
+ return dur;
+ }
+
+// ==========================================================================
+// notified from outside (AppendChild/RemoveChild)
+// ==========================================================================
+void CSvgDocumentImpl::ElementAppendedOrRemoved()
+ {
+ // Clear flag to retrieve animation duration on AnimationDuration() call
+ iCheckedAnimationDuration = EFalse;
+ }
+
+// ==========================================================================
+// Return all elements of the given type
+// or all of the elements if the type = -1
+// ==========================================================================
+void CSvgDocumentImpl::FindAllElements( CSvgElementImpl* aStartElement, TInt aElementId,
+ RPointerArray<CSvgElementImpl>& aList,
+ TSvgSearchFlags aFlags )
+ {
+ if ( aStartElement == NULL )
+ return;
+
+ CSvgElementImpl* child = (CSvgElementImpl*)aStartElement->FirstChild();
+ while ( child != NULL )
+ {
+ // add to list if child is found
+ if ( child->ElemID() == aElementId || aElementId == -1 )
+ aList.Append( child );
+
+ // find in grandchildren
+ if ( aFlags & ESvgSearchExcludeUseSubtree )
+ {
+ // If Exclude Use Subtree, ignore the subtree under use element
+ if ( child->ElemID() != KSvgUseElement )
+ {
+ FindAllElements( child, aElementId, aList, aFlags );
+ }
+ }
+ else
+ {
+ FindAllElements( child, aElementId, aList, aFlags );
+ }
+ child = (CSvgElementImpl*)child->NextSibling();
+ }
+ }
+
+// ==========================================================================
+// ImageLoadingObserver interface method
+// ==========================================================================
+void CSvgDocumentImpl::ImageLoadingCompleted( TInt aError )
+ {
+ iImageElementCnt--;
+
+ if ( iLoadingListeners != NULL && iImageElementCnt == 0)
+ {
+ TInt loadingListenersCnt = iLoadingListeners->Count();
+ for ( TInt i = 0; i < loadingListenersCnt; i++ )
+ {
+ (*iLoadingListeners)[i]->ImagesLoaded(aError);
+ }
+ }
+
+
+ }
+
+// ==========================================================================
+// Loops through the tree and prints out all of the elements
+// (almost regenerating the DOM tree)
+//
+// ==========================================================================
+void CSvgDocumentImpl::PrintAllElements( CSvgElementImpl* aStartElement )
+{
+ if ( aStartElement == NULL )
+ return;
+
+ aStartElement->Print( EFalse );
+ //===> comment the styles out to generate true SVG content
+ // aStartElement->PrintStyleProperties();
+
+ CSvgElementImpl* child = (CSvgElementImpl*)aStartElement->FirstChild();
+ PrintAllElements( child );
+
+ child = (CSvgElementImpl*)aStartElement->NextSibling();
+ PrintAllElements( child );
+}
+
+TBool CSvgDocumentImpl::HasError()
+ {
+ return iError && iError->HasError();
+ }
+
+MSvgError* CSvgDocumentImpl::GetError()
+ {
+ return iError;
+ }
+
+void CSvgDocumentImpl::SetIsWarning( TBool aIsWarning )
+{
+ if (iError)
+ {
+ iError->SetIsWarning( aIsWarning );
+ }
+}
+void CSvgDocumentImpl::SetError( TInt aErrorType, const TDesC& aMsg1, const TDesC& aMsg2 )
+ {
+ if ( !iError )
+ {
+ TRAPD( error, iError = CSvgErrorImpl::NewL() );
+ if ( error != KErrNone )
+ {
+ return;
+ }
+ PrepareError( *iError, ESvgUnknown, aErrorType, aMsg1, aMsg2 );
+ iError->SetIsWarning( ETrue );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// Accessor funciton for SyncBehaviorDefault value
+// ---------------------------------------------------------------------------
+TSvgSyncBehaviour CSvgDocumentImpl::SyncBehaviorDefault()
+ {
+ return iSyncBehaviorDefault;
+ }
+
+// ---------------------------------------------------------------------------
+// Accessor funciton for SyncBehaviorDefault value
+// ---------------------------------------------------------------------------
+TUint32 CSvgDocumentImpl::SyncToleranceDefault()
+ {
+ return iSyncToleranceDefault;
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgDocumentImpl::SetCurrentTime
+// Set Function for the document's current time
+// ---------------------------------------------------------------------------
+void CSvgDocumentImpl::SetCurrentTime( TInt32 aCurTime )
+ {
+ if ( iTimeContainer )
+ {
+ iTimeContainer->SetCurrentTime( aCurTime );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgDocumentImpl::CurrentTime
+// Accessor for the Document's current time
+// ---------------------------------------------------------------------------
+TInt32 CSvgDocumentImpl::CurrentTime()
+ {
+ if ( iTimeContainer )
+ {
+ return iTimeContainer->CurrentTime();
+ }
+ return KErrGeneral;
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgDocumentImpl::SetSyncBehavior
+// Set the Synchronised behaviour for the time container
+// ---------------------------------------------------------------------------
+void CSvgDocumentImpl::SetTCSyncBehavior( const TSvgSyncBehaviour aValue )
+ {
+ if ( iTimeContainer )
+ {
+ iTimeContainer->SetSyncBehavior( aValue );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgDocumentImpl::SetSyncTolerance
+// Set the Synchronised Tolerance for the time container
+// ---------------------------------------------------------------------------
+void CSvgDocumentImpl::SetTCSyncTolerance( const TUint32 aValue )
+ {
+ if ( iTimeContainer )
+ {
+ iTimeContainer->SetSyncTolerance( aValue );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgDocumentImpl::SetSyncMaster
+// Set the time container as Synchronised Master
+// ---------------------------------------------------------------------------
+void CSvgDocumentImpl::SetTCSyncMaster( const TBool aValue )
+ {
+ if ( iTimeContainer )
+ {
+ iTimeContainer->SetSyncMaster( aValue );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::TimeContainer
+// Accessor for time container
+// -----------------------------------------------------------------------------
+//
+CSvgTimeContainer* CSvgDocumentImpl::TimeContainer()
+ {
+ return iTimeContainer;
+ }
+
+void CSvgDocumentImpl::DocumentTransform(TGfxAffineTransform& aTr)
+ {
+ iTransformMatrix = aTr;
+ }
+
+TGfxAffineTransform CSvgDocumentImpl::GetDocumentTransform()
+ {
+ return iTransformMatrix;
+ }
+
+
+CSvgBitmapFontProvider * CSvgDocumentImpl::GetBitmapFontProvider()
+{
+ return iSvgBitmapFontProvider ;
+}
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::SvgHasAnimationElement
+// Checks if Document has Animation Element
+// -----------------------------------------------------------------------------
+
+TBool CSvgDocumentImpl::SvgHasAnimationElement()
+ {
+ RPointerArray<CSvgElementImpl> lAnimationEleList;
+ FindAllElements((CSvgElementImpl* )RootElement(),
+ KSvgMediaAnimationElement, lAnimationEleList );
+ TInt lAnimationEleCnt = lAnimationEleList.Count();
+ lAnimationEleList.Close();
+ if ( lAnimationEleCnt > 0 )
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+
+ }
+
+// -----------------------------------------------------------------------------
+// CSvgDocumentImpl::IsDocumentContentInteractive
+// Checks if Document content is InterActive
+// -----------------------------------------------------------------------------
+
+TBool CSvgDocumentImpl::IsDocumentContentInteractive()
+ {
+ RPointerArray<CSvgElementImpl> elements;
+ FindAllElements( (CSvgElementImpl* )RootElement(),
+ KSvgAElement, elements );
+ if ( elements.Count() != 0 )
+ {
+ elements.Close();
+ return ETrue;
+ }
+ elements.Close();
+
+ if ( iIsInteractive )
+ return ETrue;
+
+ // Check if animation element is there
+ RPointerArray<CSvgElementImpl> lAnimationEleList;
+ FindAllElements((CSvgElementImpl* )RootElement(),
+ KSvgMediaAnimationElement, lAnimationEleList );
+
+ // If no animation element is present then return EFalse
+ TInt lAnimationEleCnt = lAnimationEleList.Count();
+ if ( lAnimationEleCnt == 0 )
+ {
+ lAnimationEleList.Close();
+ return EFalse;
+ }
+
+ // Check all animation element and if any child svg has ..
+ // interactive content then return ETrue
+ for ( TInt lCurAnimationEle = 0;
+ lCurAnimationEle < lAnimationEleCnt; lCurAnimationEle++ )
+ {
+ CSvgMediaAnimationElementImpl* lAnimationElement =
+ (CSvgMediaAnimationElementImpl* )lAnimationEleList[ lCurAnimationEle ];
+ CSvgDocumentImpl* lChildDoc = lAnimationElement->GetChildDocument();
+ // if child svg has interavitve content then return
+ if(lChildDoc && lChildDoc->iIsInteractive)
+ {
+ lAnimationEleList.Close();
+ return ETrue;
+ }
+ }
+
+ lAnimationEleList.Close();
+ return EFalse;
+
+ }
+
+
+void CSvgDocumentImpl::SetImageElementsCount(TInt aCnt)
+ {
+ iImageElementCnt = aCnt;
+ }
+
+TInt CSvgDocumentImpl::GetImageElementsCount()
+ {
+ return iImageElementCnt;
+ }
+// End of file
+