diff -r 000000000000 -r d46562c3d99d svgtopt/SVG/SVGImpl/src/SVGDocumentImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/SVG/SVGImpl/src/SVGDocumentImpl.cpp Thu Jan 07 16:19:02 2010 +0200 @@ -0,0 +1,2646 @@ +/* +* 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 +#include + +#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 + +#include +#include + +// ========================================================================== +// 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 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) +{ + RPointerArray ids; + + FindAllIds( (CSvgElementImpl*)RootElement(), ids ); + + if (index < ids.Count()) + { + return (ids[index]); + } + + ids.Close(); + + return NULL; +} + +// ========================================================================== +// // Return all elements of the given type +// ========================================================================== +void CSvgDocumentImpl::FindAllIds( CSvgElementImpl* aStartElement, RPointerArray& 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& 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 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/" directory name +// ========================================================================== +TInt CSvgDocumentImpl::GetProcessPrivatePath( RFs& aSession, TFileName& aPath ) +{ + aSession.PrivatePath( aPath ); + aPath.Insert( 0, _L( "c:" ) ); + return KErrNone; +} + +// ========================================================================== +// Create "c:/private/" 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* aList ) + { + iLoadingListeners = aList; + } + +// ========================================================================== +// Need method description +// ========================================================================== +const RPointerArray* 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& 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& 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& 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& 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& 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& 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 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 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 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 +