# HG changeset patch # User markw # Date 1287132498 -3600 # Node ID 90e0261ad33cc95fdd1282ed1482aadb32ac2276 # Parent 6d38c548573fee9c290509211b97c79d23f3dc2e Adding files needed to break SVGEngine dependency on MediaClientAudio.dll. diff -r 6d38c548573f -r 90e0261ad33c breakdeps/SVGDocumentImpl.cpp --- /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 +#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) +{ + TDesC* id = NULL; + RPointerArray 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& 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 + diff -r 6d38c548573f -r 90e0261ad33c breakdeps/SVGEngine.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/breakdeps/SVGEngine.mmp Fri Oct 15 09:48:18 2010 +0100 @@ -0,0 +1,285 @@ +/* +* Copyright (c) 2002 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: This mmp file generates makefile for SVG Engine +* +*/ + + +#include + +ALWAYS_BUILD_AS_ARM +OPTION_REPLACE ARMCC --cpu 5T -O3 -Otime +TARGET SVGEngine.dll +TARGETTYPE dll + + +VENDORID VID_DEFAULT + +UID 0x1000008D 0x101F856E + + + #if defined( ARMCC ) + deffile ../eabi/SVGENGINE-OpenVG.def + #elif defined( WINSCW ) + deffile ../BWINSCW/SVGENGINE-OpenVG.def + #elif defined( WINS ) + deffile ../bwins/SVGENGINE-OpenVG.def + #else + deffile ../bmarm/SVGENGINE-OpenVG.def + #endif + +CAPABILITY CAP_GENERAL_DLL DRM + +SOURCEPATH ../src + +//SOURCE SVGEngineMain.cpp +SOURCE SVGEngineImpl.cpp +SOURCE SVGEngineInterfaceImpl.cpp +SOURCE SVGTimer.cpp +SOURCE SVGEventHandler.cpp +SOURCE SVGEvent.cpp +SOURCE SVGContentHandler.cpp +SOURCE SvgBitmapFontProvider.cpp +//SOURCE SVGXmlParser.cpp +SOURCE SVGAttributeVerifier.cpp +SOURCE SVGErrorImpl.cpp +SOURCE Svgdecoder.cpp +SOURCE SVGFourPointRect.cpp + +SOURCEPATH ../../SVGImpl/src + +SOURCE SVGElementImpl.cpp +SOURCE SVGDocumentImpl.cpp +SOURCE SVGDOMImplementationImpl.cpp + +// Structure Elements +SOURCE Svgsvgelementimpl.cpp +SOURCE SVGGElementImpl.cpp +SOURCE SVGUseElementImpl.cpp +SOURCE SVGStyleElementImpl.cpp +SOURCE SVGForeignObjectElementImpl.cpp +SOURCE SVGTitleElementImpl.cpp +SOURCE SVGMetadataElementImpl.cpp +SOURCE SVGDefsElementImpl.cpp +SOURCE SVGDescElementImpl.cpp + +// Hyper linking +SOURCE SVGAElementImpl.cpp +SOURCE SVGUriReferenceImpl.cpp + +// Basic Shape Elements +SOURCE SVGLineElementImpl.cpp +SOURCE SVGRectElementImpl.cpp +SOURCE SVGCircleElementImpl.cpp +SOURCE SVGEllipseElementImpl.cpp +SOURCE SVGPolylineElementImpl.cpp +SOURCE SVGPathElementImpl.cpp +SOURCE SVGMpathElementImpl.cpp + +// Text and Image Elements +SOURCE SVGTextElementImpl.cpp +SOURCE SVGTextAreaElementImpl.cpp +SOURCE SVGImageElementImpl.cpp + +//Font Elements +SOURCE SVGFontElementImpl.cpp +SOURCE SVGFontFaceElementImpl.cpp +SOURCE SVGGlyphElementImpl.cpp +SOURCE SVGMissingGlyphElementImpl.cpp +SOURCE SvgHkernelementimpl.cpp + +// Animation Elements +SOURCE SVGAnimationBase.cpp +SOURCE SVGSetElementImpl.cpp +SOURCE SVGAnimateElementImpl.cpp +SOURCE SVGAnimateTransformElementImpl.cpp +SOURCE SVGAnimateMotionElementImpl.cpp +SOURCE SVGDiscardElementImpl.cpp +SOURCE SVGAnimationElementImpl.cpp + +// Gradient Elements +SOURCE SVGLinearGradientElementImpl.cpp +SOURCE SVGGradientElementImpl.cpp +SOURCE SVGRadialGradientElementImpl.cpp +SOURCE SVGStopElementImpl.cpp + +SOURCE SVGSolidColorElementImpl.cpp +SOURCE SVGScriptElementImpl.cpp + +// CSS Classes +SOURCE SVGClrCssValueImpl.cpp +SOURCE SVGPaintCssValueImpl.cpp +SOURCE SVGIntCssValueImpl.cpp +SOURCE SVGFloatCssValueImpl.cpp +SOURCE SVGStrCssValueImpl.cpp +SOURCE SVGVectorCssValueImpl.cpp +//SOURCE SVGCssStyleDeclarationImpl.cpp +SOURCE SVGEventAttributes.cpp + +// Transform Classes +SOURCE SVGTransformListImpl.cpp +SOURCE SVGTransformableImpl.cpp + +// Switch Related Classes +SOURCE SVGTestsImpl.cpp + +// XML Language Space Class +SOURCE SVGLangSpaceImpl.cpp + +// Viewbox Classes +SOURCE SVGFitToViewBoxImpl.cpp +SOURCE SVGPreserveAspectRatioImpl.cpp + +// Utility Classes +SOURCE SVGPointLexer.cpp +SOURCE SVGSchemaData.cpp +SOURCE SVGPathDataParser.cpp +SOURCE SVGAnimTimeController.cpp +SOURCE SVGStringTokenizer.cpp +SOURCE SVGRelToAbsPath.cpp +SOURCE SVGAnimTimingParser.cpp +SOURCE SVGImageHashMap.cpp +SOURCE SVGFontHashMap.cpp +SOURCE SVGMemoryManager.cpp +SOURCE SVGColor.cpp +SOURCE SVGTokenizer.cpp + +// Media Element Classes +SOURCE SVGAudioElementImpl.cpp +SOURCE SVGMediaAnimationElementImpl.cpp +SOURCE SVGMediaElementBase.cpp +SOURCE SVGTimeContainer.cpp +SOURCE SVGLockedRealTimeEntity.cpp + +SOURCEPATH ../../Xmldomimpl/src + +SOURCE SVGXmlElementImpl.cpp + + +USERINCLUDE ../inc +USERINCLUDE ../../Xmldomimpl/inc +USERINCLUDE ../../SVGImpl/inc/SVGDOM +USERINCLUDE ../../SVGImpl/inc +USERINCLUDE ../../../VGRenderer/inc + +// This is a SYSTEMINCLUDE macro containing the middleware +// layer specific include directories +MW_LAYER_SYSTEMINCLUDE + +SYSTEMINCLUDE /epoc32/include/libc + +APP_LAYER_SYSTEMINCLUDE + +LIBRARY cone.lib +LIBRARY euser.lib +LIBRARY bafl.lib +LIBRARY efsrv.lib +LIBRARY fbscli.lib +LIBRARY estor.lib +LIBRARY gdi.lib + +// Library for image converter utilities +//LIBRARY MediaClientImage.lib +LIBRARY ImageConversion.lib + +// Library for XML Parser utilities +LIBRARY XMLINTERFACE.lib + + +// CXML parser +//LIBRARY CXMLParser.lib +// For CnvUtfConverter class +LIBRARY charconv.lib + +//#include +//#if !defined(__DRM_FULL) + +//LIBRARY DrmParsers.lib DrmDcf.lib DrmRights.lib DrmServerInterfaces.lib +//LIBRARY DRMCommon.lib + +LIBRARY estlib.lib +//#endif + +// Base64 Encoding +LIBRARY imut.lib + +// GZip library +LIBRARY EZLib.lib + +// CAF library: for DRM +LIBRARY caf.lib + +LIBRARY mediaclientaudio.lib +// Added for localized bidirectional textArea wrapping support +LIBRARY avkon.lib + +//-------------------------------------------- +// Graphics library Information-------- +//LIBRARY Gfx2D.lib +//-------------------------------------------- +SOURCEPATH ../../../gfx2d/src +SOURCE GfxMath.c +SOURCE GfxFloatFixPt.cpp +SOURCE Gfxtrignometric.cpp +/* this file is needed for ADS, RVCT, or GCC builds (mem operation wrappers) */ +SOURCE RastSymbianWrapper.cpp + +// GFXGC source files +SOURCEPATH ../../../gfx2d/src/GfxGc +SOURCE GfxStroke.cpp +SOURCE GfxColor.cpp +SOURCE GfxRenderingHints.cpp +SOURCE GfxGradientPaint.cpp +SOURCE Gfx2dGcOpenVG.cpp +SOURCE Gfx2dGc.cpp + + +// GFXGEOM source files +SOURCEPATH ../../../gfx2d/src/GfxGeom +SOURCE GfxEllipse2D.cpp +SOURCE GfxEllipseIteratorP.cpp +SOURCE GfxFlatteningPathIterator.cpp +SOURCE GfxGeneralPath.cpp +SOURCE GfxGeneralPathIteratorP.cpp +SOURCE GfxRectangle2D.cpp +SOURCE GfxRectangleIteratorP.cpp +SOURCE GfxRectangularShape.cpp +SOURCE GfxRoundRectangle2D.cpp +SOURCE GfxRoundRectangleIteratorP.cpp +SOURCE GfxLine2D.cpp +SOURCE GfxLineIteratorP.cpp +SOURCE GfxAffineTransform.cpp +SOURCE GfxPoint2D.cpp + +// GFXIMAGE source files +SOURCEPATH ../../../gfx2d/src/GfxImage +SOURCE GfxImageTransformer.cpp + +// Internal Rendering Engine source files +SOURCEPATH ../../../gfx2d/src/GfxRenderer +SOURCE GfxRendererInfoP.cpp + + +USERINCLUDE ../../../gfx2d/inc + + +LIBRARY VGRenderer.lib + + +LIBRARY eikcore.lib +LIBRARY bitgdi.lib +LIBRARY hal.lib +//-------------------------------------------- +// End of Graphics library Information-------- +//-------------------------------------------- diff -r 6d38c548573f -r 90e0261ad33c breakdeps/SVGEngineImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/breakdeps/SVGEngineImpl.cpp Fri Oct 15 09:48:18 2010 +0100 @@ -0,0 +1,3190 @@ +/* +* 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 Engine source file + * +*/ + + + + +#if !defined(__E32BASE_H__) +#include +#endif + +#include +#include + +#include "SVGDOMImplementationImpl.h" +#include "SVGElementImpl.h" +#include "SVGDocumentImpl.h" +#include "SVGSvgElementImpl.h" +#include "SVGUseElementImpl.h" +#include "SVGAnimationElementImpl.h" +#include "SVGTextElementImpl.h" + +#include "SVGAudioElementImpl.h" + + +#include "Gfx2dGcOpenVG.h" + +#include "SVGSchemaData.h" +#include "SVGPathElementImpl.h" +#include "SVGAnimationBase.h" +#include "SVGElementTimeControl.h" + +#include "SVGRequestObserver.h" +#include "SVGHyperlinkListener.h" +#include "SVGListener.h" +#include "SVGAnimationListener.h" +#include "SVGAElementImpl.h" +#include "SVGTextAreaElementImpl.h" + +#include "SVGTimer.h" +#include "SVGEventHandler.h" +#include "SVGEngineImpl.h" +#include "SVGErrorImpl.h" + +#include "SVGFloatCssValueImpl.h" +#include "SVGTimeContainer.h" +#include "SVGMediaAnimationElementImpl.h" + +// Constants +// length of +const TInt KClosingTextTagLength = 7; +// Length of +const TInt KClosingTextAreaTagLength = 11; +// Length of < +const TInt KClosingBracesLength = 1; +// Number of chars to be converted at a time to Unicode +const TInt KMaxConversionChars = 20; +_LIT(KClosingTextTag,""); +_LIT(KClosingTextAreaTag,""); +_LIT(KClosingBraces,">"); + +// --------------------------------------------------------------------------- +// Two phase constructor for this class +// JSR 226 API +// --------------------------------------------------------------------------- +CSvgEngineImpl* CSvgEngineImpl::NewL(CSvgBitmapFontProvider *aSvgBitmapFontProvider) + { + CSvgEngineImpl* self = new ( ELeave ) CSvgEngineImpl(); + CleanupStack::PushL( self ); + self->ConstructL(aSvgBitmapFontProvider); + CleanupStack::Pop(); + return self; + } + + +// -------------------------------------------------------------------------- +// CSvgEngineImpl* CSvgEngineImpl::NewLC() +// --------------------------------------------------------------------------- +CSvgEngineImpl* CSvgEngineImpl::NewLC(CSvgBitmapFontProvider *aSvgBitmapFontProvider) + { + CSvgEngineImpl* self = new ( ELeave ) CSvgEngineImpl(); + CleanupStack::PushL( self ); + self->ConstructL(aSvgBitmapFontProvider); + return self; + } + +// -------------------------------------------------------------------------- +// CSvgEngineImpl::CSvgEngineImpl() : iTextAreaHandle( NULL ), +// --------------------------------------------------------------------------- +CSvgEngineImpl::CSvgEngineImpl() : iTextAreaHandle( NULL ), + iRequestObserver( NULL ), + iFrameBuffer( NULL ), + iFrameBufferSize(TSize(0,0)), + iFontHashMap ( NULL ), + iSvgDocument( NULL ), + iBackgroundColor(0x00000000), + iShowDebugInfo( EFalse ), + iSvgEngineState(ESVGEngineNotStarted), + iTimeoutSeconds( 0 ), + iRenderQuality(2), // Set To Rendering quality "high" + iCustomOption( ETrue ), + iFrameBufferOverridesViewport( EFalse ), + iClientDefinedViewPort(EFalse) + + { + } + + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::ConstructL() +// --------------------------------------------------------------------------- +void CSvgEngineImpl::ConstructL(CSvgBitmapFontProvider *aSvgBitmapFontProvider) + { + iGfxContext = NULL; + + iSvgBitmapFontProvider = aSvgBitmapFontProvider ; + // create CSvgErrorImpl object + iSvgError = CSvgErrorImpl::NewL(); + + iFontHashMap = CSvgFontHashMap::NewL(); + + SetIgnoreUpdateScreen( EFalse ); + + // The iCustomOption need to be initialized for JSR + + iCustomOption = ETrue; + + } + + + +// --------------------------------------------------------------------------- +// Two phase constructor for this class +// Accepts a frame buffer and a MSvgRequestObserver object from the client +// Buffer is used for rasterization of SVG content +// Observer object, if provided, is used for notifying the client on updates +// --------------------------------------------------------------------------- +CSvgEngineImpl* CSvgEngineImpl::NewL( CFbsBitmap* aFrameBuffer, + MSvgRequestObserver* aReqObserver, TFontSpec& aFontSpec, CSvgBitmapFontProvider* aSvgBitmapFontProvider ) + { + CSvgEngineImpl* self = new ( ELeave ) CSvgEngineImpl( aFrameBuffer, + aReqObserver ); + CleanupStack::PushL( self ); + self->ConstructL(aFontSpec, aSvgBitmapFontProvider); + CleanupStack::Pop(); + + return self; + } + + +// --------------------------------------------------------------------------- +// Two phase constructor for this class +// Accepts a frame buffer and a MSvgRequestObserver object from the client +// Buffer is used for rasterization of SVG content +// Observer object, if provided, is used for notifying the client on updates +// --------------------------------------------------------------------------- +CSvgEngineImpl* CSvgEngineImpl::NewLC( CFbsBitmap* aFrameBuffer, + MSvgRequestObserver* aReqObserver, TFontSpec& aFontSpec, CSvgBitmapFontProvider* aSvgBitmapFontProvider ) + { + CSvgEngineImpl* self = new ( ELeave ) CSvgEngineImpl( aFrameBuffer, aReqObserver ); + CleanupStack::PushL( self ); + self->ConstructL(aFontSpec, aSvgBitmapFontProvider); + + return self; + } + +// --------------------------------------------------------------------------- +// Symbian style private method that is used to construct heap objects +// Builds the Graphics device objects with the client's frame buffer info +// Builds the event handler object +// --------------------------------------------------------------------------- +void CSvgEngineImpl::ConstructL( TFontSpec& aFontSpec, CSvgBitmapFontProvider* aSvgBitmapFontProvider) + { + iBitmapFontSpec = aFontSpec; +// iGfxContext is created through CSvgEngineInterfaceImpl::ConstructL + // iGfxContext = CGfx2dGcVGR::NewL( iFrameBuffer->SizeInPixels(), iBitmapFontSpec ); + iSvgBitmapFontProvider = aSvgBitmapFontProvider ; + + iGfxContext = CGfx2dGcOpenVG::NewL( iFrameBuffer->SizeInPixels(), iBitmapFontSpec, iSvgBitmapFontProvider ); + // create CSvgErrorImpl object + iSvgError = CSvgErrorImpl::NewL(); + iFontHashMap = CSvgFontHashMap::NewL(); + iSvgNames = new (ELeave) CDesC16ArrayFlat(5); + } + +// --------------------------------------------------------------------------- +CSvgEngineImpl* CSvgEngineImpl::NewL( CFbsBitmap* aFrameBuffer, + MSvgRequestObserver* aReqObserver, TFontSpec& aFontSpec, CSvgBitmapFontProvider* aSvgBitmapFontProvider ,SVGRendererId aRendererType) + { + CSvgEngineImpl* self = new ( ELeave ) CSvgEngineImpl( aFrameBuffer, + aReqObserver ); + CleanupStack::PushL( self ); + self->ConstructL(aFontSpec, aSvgBitmapFontProvider,aRendererType); + CleanupStack::Pop(); + + return self; + } + + +// --------------------------------------------------------------------------- +// Two phase constructor for this class +// Accepts a frame buffer and a MSvgRequestObserver object from the client +// Buffer is used for rasterization of SVG content +// Observer object, if provided, is used for notifying the client on updates. +//This contains the renderer selector parameter +// --------------------------------------------------------------------------- +CSvgEngineImpl* CSvgEngineImpl::NewLC( CFbsBitmap* aFrameBuffer, + MSvgRequestObserver* aReqObserver, TFontSpec& aFontSpec, CSvgBitmapFontProvider* aSvgBitmapFontProvider,SVGRendererId aRendererType ) + { + CSvgEngineImpl* self = new ( ELeave ) CSvgEngineImpl( aFrameBuffer, aReqObserver ); + CleanupStack::PushL( self ); + self->ConstructL(aFontSpec, aSvgBitmapFontProvider,aRendererType); + + return self; + } + +// --------------------------------------------------------------------------- +// Symbian style private method that is used to construct heap objects +// Builds the Graphics device objects with the client's frame buffer info +// Builds the event handler object. +//This contains the renderer selector parameter NGA +// --------------------------------------------------------------------------- +void CSvgEngineImpl::ConstructL( TFontSpec& aFontSpec, CSvgBitmapFontProvider* aSvgBitmapFontProvider,SVGRendererId aRendererType) + { + iBitmapFontSpec = aFontSpec; +// iGfxContext is created through CSvgEngineInterfaceImpl::ConstructL + // iGfxContext = CGfx2dGcVGR::NewL( iFrameBuffer->SizeInPixels(), iBitmapFontSpec ); + iSvgBitmapFontProvider = aSvgBitmapFontProvider ; + + iGfxContext = CGfx2dGcOpenVG::NewL( iFrameBufferSize, iBitmapFontSpec, iSvgBitmapFontProvider ,aRendererType); + // create CSvgErrorImpl object + iSvgError = CSvgErrorImpl::NewL(); + iFontHashMap = CSvgFontHashMap::NewL(); + iSvgNames = new (ELeave) CDesC16ArrayFlat(5); + } + + +// --------------------------------------------------------------------------- +// Private constructor +// Initializes private attributes +// --------------------------------------------------------------------------- +CSvgEngineImpl::CSvgEngineImpl( CFbsBitmap* aFrameBuffer, + MSvgRequestObserver* aReqObserver ) : iTextAreaHandle( NULL ), + iRequestObserver( aReqObserver ), + iFrameBuffer( aFrameBuffer ), + iFrameBufferSize(TSize(0,0)), + iFontHashMap ( NULL), + iSvgDocument( NULL ), + iBackgroundColor(0x00000000), + iShowDebugInfo( EFalse ), + iSvgEngineState(ESVGEngineNotStarted), + iCustomOption( ETrue ), + iFrameBufferOverridesViewport( EFalse ) + + + { + if(aFrameBuffer && aFrameBuffer->Handle()>0) + { + iFrameBufferSize = aFrameBuffer->SizeInPixels(); + } + } + +// --------------------------------------------------------------------------- +// Destructor +// --------------------------------------------------------------------------- +CSvgEngineImpl::~CSvgEngineImpl() + { + Destroy(); + + if ( iFontHashMap ) + { + delete iFontHashMap; + iFontHashMap = NULL; + } + + iSvgTextBoundingBoxes.ResetAndDestroy(); + iSvgTextBoundingBoxes.Close(); + + if ( iGfxContext ) + { + delete iGfxContext; + iGfxContext = NULL; + } + if ( iSvgError ) + { + delete iSvgError; + iSvgError = NULL; + } + if (iTextAreaHandle) + { + delete iTextAreaHandle; + iTextAreaHandle = NULL; + } + + iTextAreaListeners.Close(); + iTextListeners.Close(); + iHyperlinkListeners.Close(); + iAnimationListeners.Close(); + iSvgMouseListeners.Close(); + iInteractiveElementListeners.Close(); + delete iSvgNames; + } + +// --------------------------------------------------------------------------- +// Draws aRootElement and calls itself for children. +// Handles switch element differently, as it only draws one of its children. +// --------------------------------------------------------------------------- + +void CSvgEngineImpl::DrawElementsL( CSvgElementImpl* aRootElement) + { + if ( aRootElement != NULL) + { + TInt32 displayValue = 0; + // while we have next elements + CSvgElementImpl* newElement = aRootElement; + while( newElement != NULL ) + { + if(newElement->GetAttributeIntL( KCSS_ATTR_DISPLAY, displayValue ) == KErrNoAttribute) + { + newElement = ( CSvgElementImpl* ) newElement->FirstChild(); + while ( newElement != NULL ) + { + DrawElementsL( newElement ); + newElement = ( CSvgElementImpl * ) newElement->NextSibling(); + } + return; + } + + if(displayValue != KDisplayEnumNone) // is it a hidden element + { + CCssValue* CssValue = NULL; + TReal32 opacity = 1; + + // check visisbility + TInt32 visbilityValue = 0; + TInt visibility = newElement->GetAttributeIntL( KCSS_ATTR_VISIBILITY, visbilityValue ); + + newElement->FindProperty( KCSS_ATTR_GROUP_OPACITY, CssValue, newElement ); + if ( CssValue ) + { + opacity = ((CFloatCssValueImpl*)CssValue)->Value(); + } + + if( opacity != 1 && !newElement->IsInherited( KCSS_ATTR_GROUP_OPACITY ) ) + { + iGfxContext->BindToImageL(); + // Group opacity + if ( newElement->ElemID() == KSvgGElement && newElement->FirstChild() ) + { + // recurse with right context. + DrawElementsL( ( CSvgElementImpl* )newElement->FirstChild()); + } + // Element opacity + else + { + TBool canDraw = ETrue; + if( (visibility == KErrNone) && (visbilityValue == 0) ) + { + canDraw = newElement->DrawL( iGfxContext, NULL ) ; + } + if( canDraw && newElement->FirstChild() ) + { + DrawElementsL( ( CSvgElementImpl* )newElement->FirstChild() ); + } + } + + // Blend opacity context buffer with parent's gfx context buffer + iGfxContext->UnbindFromImageL( opacity ); + } + else // no opacity or is inherited from above.... + { + TBool canDraw = ETrue; + if( (visibility == KErrNone) && (visbilityValue == 0) ) + { + canDraw = newElement->DrawL(iGfxContext, NULL ); + } + if( canDraw && newElement->FirstChild() ) + { + DrawElementsL( ( CSvgElementImpl* )newElement->FirstChild()); + } + } + } + newElement = ( CSvgElementImpl * )newElement->NextSibling(); + + }// end while.... + } + } + +//-------------------------------------------------------------------- +//CFbsBitmap* CSvgEngineImpl::CreateOpacityFrameBufferL() +//-------------------------------------------------------------------- +CFbsBitmap* CSvgEngineImpl::CreateOpacityFrameBufferL() +{ + CFbsBitmap* bitmap = new ( ELeave ) CFbsBitmap(); + + if ( iFrameBuffer != NULL ) + { +/*NGA reverse*/if ( bitmap->Create( iFrameBufferSize, EColor16MU ) != KErrNone ) + { + delete bitmap; + bitmap = NULL; + } + } + return bitmap; + } + +// --------------------------------------------------------------------------- +// Copy 32-bit buffer +// --------------------------------------------------------------------------- + +void CSvgEngineImpl::CopyBuffer( TUint32* aSrc, TUint32* aDest, const TSize aSize ) + { + if ( aSrc && aDest ) + { + Mem::Copy( aDest, aSrc, aSize.iWidth * aSize.iHeight * sizeof( TUint32 ) ); + } + } + +// --------------------------------------------------------------------------- +// Positions the root element and calls itself (recursively) for all the +// descendant elements +// CTM stands for 'Current Transformation Matrix'. +// --------------------------------------------------------------------------- +void CSvgEngineImpl::UpdateCTM(CSvgDocumentImpl* aSvgDocument) + { + + if (aSvgDocument) + { + ((CSvgElementImpl*)aSvgDocument->RootElement())->UpdateCTM(); + } + + + } + +// --------------------------------------------------------------------------- +// Initializes the SVG Engine primarily with width and height informtion +// This is based on the attribute specifications for the root 'svg' element +// --------------------------------------------------------------------------- +void CSvgEngineImpl::InitializeEngineL() + { + // VIEWBOX + // If x, y, w, h of outmost svg not defined, then put default values: 0 0 100% 100% + // return; + // Set locale, so that there is no thousands separator + + if( !iSvgDocument ) + return; + + iSvgDocument->iInitialDrawFlag = ETrue; + if(!((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iIsWidthSet) + { + ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iIsWidthSet = ETrue; + } + if(!((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iIsHeightSet) + { + ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iIsHeightSet = ETrue; + } + + TLocale locale; // locale object + locale.SetCurrencyTriadsAllowed( EFalse ); // change setting + TSize lSize = GetSize(); + iSvgDocument->iReqExReqFtrSysLTested = EFalse; + if ( iSvgDocument->RootElement() != NULL && + ((CSvgElementImpl*)iSvgDocument->RootElement())->ElemID() == KSvgSvgElement ) + + { + // Scale width & height to fit to screen size + CSvgSvgElementImpl* el = ( CSvgSvgElementImpl* ) + (iSvgDocument->RootElement()); + TFloatFixPt width, height; + TInt widthInt, heightInt; + TFloatFixPt scrnW( lSize.iWidth ), scrnH( lSize.iHeight ); + TFloatFixPt zero ( 0 ); + + if ( iFrameBufferOverridesViewport ) + { + //special case for Aknicon + //the don't care what the contents viewport is they just want it to scale to the framebuffer's size + width = scrnW; + height= scrnH; + } + else + { + //bitmap from the client overrides width height specified in svg + + if(iViewPortListener != NULL) + { + TInt tempWidth=0,tempHeight=0; + iViewPortListener->GetViewPort( + ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iWidthInUserCoordinate, + ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iHeightInUserCoordinate, + ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iWidthInPercentage, + ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iHeightInPercentage, + tempWidth, + tempHeight); + + width = (TFloatFixPt) tempWidth; + height = (TFloatFixPt) tempHeight; + + //used in SetWindowViewportTrans of svgSvgElementImpl + iClientDefinedViewPort = ETrue; + + } + else + { + + TReal32 per = 100; + if(((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iWidthInPercentage) + { + width = ( TFloatFixPt ) (( lSize.iWidth/per ) * ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iWidthInUserCoordinate); + } + else + { + width = (TFloatFixPt) (((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iWidthInUserCoordinate); + } + + if(((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iHeightInPercentage) + { + height = ( TFloatFixPt ) (( lSize.iHeight/per ) * ((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iHeightInUserCoordinate); + } + else + { + height = (TFloatFixPt) (((CSvgSvgElementImpl *)(iSvgDocument->RootElement()))->iHeightInUserCoordinate); + } + + //default to XmidYmid_meet + TSvgPreserveAspectAlignType lPreserverAspectAlignment = ESvgPreserveAspectRatio_XmidYmid; + TSvgMeetOrSliceType lMeetOrSlice = ESvgMeetOrSlice_Meet; + + MSvgPreserveAspectRatio* aPreserveAspectRatio; + el->GetPreserveAspectRatio(aPreserveAspectRatio); + + if (aPreserveAspectRatio) + { + lPreserverAspectAlignment = aPreserveAspectRatio->GetAlign(); + lMeetOrSlice = aPreserveAspectRatio->GetMeetOrSlice(); + + //el->SetPreserveAspectRatioL( lPreserverAspectAlignment, lMeetOrSlice); + if( lPreserverAspectAlignment == ESvgPreserveAspectRatio_None && lMeetOrSlice == ESvgMeetOrSlice_Meet ) + { + width = scrnW; + height = scrnH; + } + } + + if( lMeetOrSlice == ESvgMeetOrSlice_Meet && !(lPreserverAspectAlignment == ESvgPreserveAspectRatio_None) ) + { + widthInt = ( TInt ) width; + heightInt = ( TInt ) height; + + // to avoid division by zero. + TInt rh = lSize.iWidth ; + if (widthInt != 0) + { + rh = heightInt* lSize.iWidth / widthInt; + } + + if ( rh <= lSize.iHeight ) + { + width = scrnW; + height = TFloatFixPt( rh ); + } + else + { + // to avoid division by zero. + if (heightInt != 0) + { + width = TFloatFixPt( ((TReal32)(widthInt * lSize.iHeight)) / heightInt ); + } + height = scrnH; + } + } + else if( lMeetOrSlice == ESvgMeetOrSlice_Slice ) + { + widthInt = ( TInt ) width; + heightInt = ( TInt ) height; + + // to avoid division by zero. + TInt rh = lSize.iWidth ; + if (widthInt != 0) + { + rh = heightInt* lSize.iWidth / widthInt; + } + + if ( rh <= lSize.iHeight ) + { + // to avoid division by zero. + if (heightInt != 0) + { + width = TFloatFixPt( ((TReal32)(widthInt * lSize.iHeight)) / heightInt ); + } + height = scrnH; + + } + else + { + width = scrnW; + height = TFloatFixPt( rh ); + } + } + else + { + } + }//Normal viewer| end of else + } + + if ( ( width <= zero ) || ( height <= zero ) ) //. + { + width = 0; + height = 0; + return; + } + // Set initial viewport + el->SetAttributeFloatL( KAtrX, zero ); + el->SetAttributeFloatL( KAtrY, zero ); + el->SetAttributeFloatL( KAtrWidth, width ); + el->SetAttributeFloatL( KAtrHeight, height ); + } + } + + + + + +// --------------------------------------------------------------------------- +// This method is called after the SVG file is read and all elements are +// constructed +// It also looks for rendering properties such as Anti Aliasing at this +// point +// It calibrates the system for rasterization quality based on contents +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::StartFrameLoopL() + { + if( iRequestObserver != NULL ) + { + if(iSvgDocument != NULL && iSvgDocument->iEventHandler != NULL) + { + iRequestObserver->UpdatePresentation( + iSvgDocument->iEventHandler->AnimationElementsCount()); + } + } + if(iSvgDocument != NULL) + { + if ( iSvgDocument->RootElement() ) + { + InitializeEngineL(); // set the viewport and viewbox + return ETrue; + } + } + return EFalse; + } +// --------------------------------------------------------------------------- +// UpdatePresentation() +// --------------------------------------------------------------------------- +void CSvgEngineImpl::UpdatePresentation(const TInt32& aParam) + { + if( iRequestObserver != NULL ) + { + iRequestObserver->UpdatePresentation (aParam); + } + } + + +//--------------------------------------------------------------------------- +// SetRenderingQuality +// +// @param : aRenderQuality +// The function is called from JSR226 API. Specific to M2G/JSR226 only. +//--------------------------------------------------------------------------- +void CSvgEngineImpl::SetRenderingQuality( const TInt32 aRenderQuality) +{ + // Bydefault iRenderQuality is set to 2 i.e. Rendering Quality high. + + if( iRenderQuality != aRenderQuality ) + { + iRenderQuality = aRenderQuality; + + if( iGfxContext ) + { + iGfxContext->SetAntialiasingMode( iRenderQuality ); + } + } +} + + +// --------------------------------------------------------------------------- +// Invalidate the current raster (and frame buffer) and +// update the buffer with new raster. +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RedrawL() + { + // Clear the frame buffer + if( iGfxContext && iSvgDocument) + { + // Set Clipping rectangle + CSvgSvgElementImpl* el = ( CSvgSvgElementImpl* ) (iSvgDocument->RootElement()); + if ( !el ) + { + return; // No DOM tree, nothing to draw. + } + + + + // If viewBox has been set and width or height is zero + // Do not render the content + TGfxRectangle2D viewBoxRect; + if(el->GetViewBox(viewBoxRect)) + { + if(viewBoxRect.iWidth == TFloatFixPt(0) || + viewBoxRect.iHeight == TFloatFixPt(0)) + { + return; + } + } + + iGfxContext->SetupContextL(); + iGfxContext->Clear(iBackgroundColor); + iGfxContext->SetFillOpacity( 1.0f ); + iGfxContext->SetStrokeOpacity( 1.0f ); + + TFloatFixPt width, height; + el->GetAttributeFloat( KAtrWidth, width ); + el->GetAttributeFloat( KAtrHeight, height ); + TGfxRectangle2D clipRect ( 0, 0, width, height ); + iGfxContext->SetClip( clipRect ); + iClipRect = clipRect; + + UpdateCTM(iSvgDocument); + + iSvgDocument->iIsRendering = ETrue; + DrawElementsL( (CSvgElementImpl*)iSvgDocument->RootElement()); + iSvgDocument->iIsRendering = EFalse; + + iGfxContext->Flush(); + + // Get the redering result onto CFbsBitmap. + if(iFrameBufferSize.iWidth > 0) + iGfxContext->UpdateFramebufferL( iFrameBuffer, iMask,iFrameBufferSize,iRenderDspMode,iMaskDspMode ); + else + iGfxContext->UpdateFramebufferL( iFrameBuffer, iMask ); + + if ( !iIgnoreUpdateScreen && iRequestObserver != NULL ) + { + iRequestObserver->UpdateScreen(); + } + if ( iSvgDocument->iInitSortList ) + { + iSvgDocument->SortEventList(); + } + else + { + iSvgDocument->iInitSortList=EFalse; + } + } + } + +// --------------------------------------------------------------------------- +// Delete the objects associated with the last loaded SVG file +// --------------------------------------------------------------------------- +void CSvgEngineImpl::Destroy() + { + //if ( iSvgDocument ) + // { + // Stop timer and reset time + // iSvgDocument->TimeContainer()->UserStop(); + // iSvgDocument->TimeContainer()->UserResetTime(); + // } + } + + +// --------------------------------------------------------------------------- +// Set the URI information +// --------------------------------------------------------------------------- +void CSvgEngineImpl::LinkRequest( const TDesC& aUri ) + { + iLinkUri.Set( aUri ); + } +// --------------------------------------------------------------------------- +// Set the Link:Show information +// --------------------------------------------------------------------------- + + +void CSvgEngineImpl::LinkRequestWithShow(const TDesC& aUri ,const TDesC& aLinkShow ) + { + iLinkUri.Set( aUri ); + iLinkShow.Set( aLinkShow ); + } + +// --------------------------------------------------------------------------- +// Initiate the process of getting an svg font from the client +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::FetchFont( const TDesC& aUri, RFs& aSession, RFile& aFileHandle ) + { + if ( iRequestObserver == NULL ) + { + return EFalse; + } + else + { + if (iRequestObserver->FetchFont( aUri, aSession, aFileHandle ) == KErrNone) + { + return ETrue; + } + return EFalse; + } + } + +// --------------------------------------------------------------------------- +// Initiate the process of getting an embedded image from the client +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::FetchImage( const TDesC& aUri, RFs& aSession, RFile& aFileHandle ) + { + if ( iRequestObserver == NULL ) + { + return EFalse; + } + else + { + if (iRequestObserver->FetchImage( aUri, aSession, aFileHandle ) == KErrNone) + { + return ETrue; + } + return EFalse; + } + } + +// --------------------------------------------------------------------------- +// Accessor for Graphics Context object +// --------------------------------------------------------------------------- +CGfx2dGc* CSvgEngineImpl::GraphicsContext() + { + return iGfxContext; + } + +// --------------------------------------------------------------------------- +// Accessor for the Engine's current time +// --------------------------------------------------------------------------- +TInt32 CSvgEngineImpl::CurrentTIme() + { + if ( iSvgDocument ) + { + return iSvgDocument->CurrentTime(); + } + return KErrGeneral; + } + + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::ImageLoadingCompleted( TInt /* aErrorStatus */ ) +// --------------------------------------------------------------------------- +// ImageLoadingObserver interface +void CSvgEngineImpl::ImageLoadingCompleted( TInt /* aErrorStatus */ ) +{ + TRAP_IGNORE(RedrawL()); + //aErrorStatus = 0; +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::UpdatePath( CGfxGeneralPath* hPath, CSvgElementImpl* hElement ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::UpdatePath( CGfxGeneralPath* hPath, CSvgElementImpl* hElement ) +{ + if ((hElement != NULL) && (hElement->ElemID() == KSvgPathElement)) + { + TRAPD(error,hElement->SetAttributePathL(KAtrData, hPath)); + if ( error != KErrNone ) + { + // Error Processing + return; + } + } + +} + +// --------------------------------------------------------------------------- +// Accessor for the document object for the currently loaded SVG source +// --------------------------------------------------------------------------- +CSvgDocumentImpl* CSvgEngineImpl::Document() + { + return iSvgDocument; + } + +// --------------------------------------------------------------------------- +// Restrict Thumbnail documents +// Do not render to frame buffer when is in thumbnail mode and +// frame buffer size width or height is larger than 80x80. +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::PassesThumbNailRestriction() +{ + if ( iSvgDocument && iFrameBuffer && iSvgDocument->IsThumbNailOnly() ) + { + TSize size = iFrameBuffer->SizeInPixels(); + if ( size.iWidth > 80 || size.iHeight > 80 ) + { + return EFalse; + } + } + return ETrue; +} + +//*************************************************************** +// Event handling +// --------------------------------------------------------------------------- +// Initiate the process of handling an event from the client for the +// SVG source +// --------------------------------------------------------------------------- +void CSvgEngineImpl::ProcessEventL( CSvgDocumentImpl* aSvgDocument, + MSvgEvent* aEvent, TBool aRedraw ) + { + // Check for Thumbnail restrictions + if ( !PassesThumbNailRestriction() ) + { + return; + } + + // Timer event + //if(!aEvent || !iGfxContext) + if(!aEvent) + return; + if ( aEvent->EventType() == ESvgEngineEventTimer ) + { + // Update current time + if ( aSvgDocument ) + { + aSvgDocument->SetCurrentTime( + ( ( MSvgTimerEvent * ) aEvent )->Time() ); + } + } + + if( aSvgDocument && aSvgDocument->iEventHandler) + { + if (( aSvgDocument->iEventHandler->ProcessEventL( aEvent ) || + aSvgDocument->iInitialDrawFlag) && aEvent->EventType() == ESvgEngineEventTimer ) + { + + if(aSvgDocument->iInitSortList) + { + aSvgDocument->SortEventList(); + aSvgDocument->iInitSortList = EFalse; + } + aSvgDocument->iInitialDrawFlag = EFalse; + aSvgDocument->iEventHandler->DoAnimProcL(aEvent); + + if (aRedraw) + { + // Redraw is performed for iSvgDocument + RedrawL(); + } + } + else + { + // this is to keep the dom in its final state. + if(aEvent->EventType() == ESvgEngineEventTimer) + { + aSvgDocument->iEventHandler->DoAnimProcL(aEvent); + } + + } + + // Process Link + if ( aEvent->EventMask() == KSvgEventMaskExternalUI ) + { + if ( iLinkUri.Length() > 0 ) + { + DoHyperLinkingL(); + // reset link description + iLinkUri.Set( NullString ); + } + } + } + +// Show FPS debug info. note. only write data to STI port +#ifdef _DEBUG + + if ( aEvent->EventType() == ESvgEngineInternalEvent ) + { + MSvgInternalEvent* evt = ( MSvgInternalEvent* ) aEvent; + if (evt->SvgEvent() == ESvgEventEndEvent) + { + iAnimationState = KAnimFinished; + return; + } + else + if (evt->SvgEvent() == ESvgEventBeginEvent) + { + iAnimationState = KAnimActive; + return; + } + + } + + // time display for debug + if ( iShowDebugInfo && iGfxContext && aEvent->EventType() == ESvgEngineEventTimer + && iAnimationState != KAnimFinished /*&& iTimer*/) + { + TInt fps = iSvgDocument->TimeContainer()->UserFps() / 10; //iTimer->Fps() / 10; + _LIT(msg, "\n%3d.%d\n"); + RDebug::Print(msg, fps, iSvgDocument->TimeContainer()->UserFps() + - fps * 10 ); + + } +#endif //_DEBUG + + } + + +// --------------------------------------------------------------------------- +// This method is for future extension, in which an external script engine +// could be used to evaluate a script description. +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::ScriptCall( const TDesC& aScript, + CSvgElementImpl* aCallerElement ) + { + if ( iRequestObserver == NULL ) + { + return EFalse; + } + else + { + return iRequestObserver->ScriptCall( aScript, aCallerElement ); + } + } + + +//*************************************************************** +// +// --------------------------------------------------------------------------- +// Obtain the longest duration for an animation given document +// NULL will assume the attached document. +// --------------------------------------------------------------------------- +TUint32 CSvgEngineImpl::Duration( CSvgDocumentImpl* aDocument ) + { + if ( aDocument == NULL ) + { + if ( iSvgDocument == NULL ) + { + return 0; + } + return iSvgDocument->AnimationDuration(); + } + return aDocument->AnimationDuration(); + } + +//*******************************************************/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::SwitchDebugInfo() +// --------------------------------------------------------------------------- +void CSvgEngineImpl::SwitchDebugInfo(TBool debug) + { + iShowDebugInfo = debug; + } + +void CSvgEngineImpl::CustomOption(TBool aCustomOption ) + { + iCustomOption = aCustomOption; + delete iGfxContext; + iGfxContext = NULL; + +/*NGA reverse*/ TRAP_IGNORE( iGfxContext = CGfx2dGcOpenVG::NewL( iFrameBufferSize, iBitmapFontSpec, iSvgBitmapFontProvider )); + + + } + + + + +// --------------------------------------------------------------------------- +// Initiate the process of opening and reading an embedded hyperlink +// --------------------------------------------------------------------------- +void CSvgEngineImpl::DoHyperLinkingL() + { + + if( iSvgDocument == NULL ) + return; + + // Not full support of XPointer + + _LIT( KTmpHttp, "http:" ); + _LIT( KTmpFile, "file:" ); + _LIT( KTmpHash, "#" ); + _LIT( KTmpSvgView, "SvgView" ); + if ( iLinkUri.Left( 1 ) == KTmpHash ) + { + // internal linking + // Extract id + TLex lex ( iLinkUri ); + lex.Inc(); // skip '#' + lex.Mark(); + while ( !lex.Eos() && lex.Peek().IsAlpha() ) + lex.Inc(); + TPtrC targetId = lex.MarkedToken(); + if ( targetId == KTmpSvgView ) + { + // need to parse next token = {viewBoxSpec| preserveAspectRatioSpec + // |transformSpec|zoomAndPanSpec|viewTargetSpec} + + // Not yet supported + } + else + { + + CSvgElementImpl*targetElement = ( CSvgElementImpl* ) + iSvgDocument->GetElementById( targetId ); + if ( targetElement == NULL ) + return; + + if ( targetElement->IsAnimatedElement( ) ) + { + // start animation + ( ( CSvgAnimationBase * ) targetElement )->BeginElementL(); + } + else + { + } + } + } + else if ( iLinkUri.Length() >= 5 ) + { + if ( iLinkUri.Left( 5 ) == KTmpHttp || iLinkUri.Left( 5 ) == KTmpFile ) + { + // notify observer of desire to follow http link + NotifyHyperlinkActivated( iLinkUri ); + } + else + { + // notify observer of desire to follow link + if ( iLinkShow.Length() > 0 ) + NotifyHyperlinkActivatedWithShow( iLinkUri, iLinkShow ); + else + NotifyHyperlinkActivated( iLinkUri ); + } + } + else if ( iLinkUri.Length() > 0 ) + { + // notify observer of desire to follow link + if ( iLinkShow.Length() > 0 ) + NotifyHyperlinkActivatedWithShow( iLinkUri, iLinkShow ); + else + NotifyHyperlinkActivated( iLinkUri ); + } + } + +// --------------------------------------------------------------------------- +// Dump a completed raster to the off screen buffer provided by the +// client +// --------------------------------------------------------------------------- +TInt CSvgEngineImpl::RenderFileToBuffer( const TDesC8& aSvgData, + CFbsBitmap* aFrameBuffer, + CFbsBitmap* aMask, + TBool aPreserveAspectRatio ) + { + if ( !iGfxContext ) + { + return EFalse; + } + + CFbsBitmap* OrgFrameBuffer; + CFbsBitmap* OrgMask; + OrgFrameBuffer = iFrameBuffer; + OrgMask = iMask; + CSvgDocumentImpl* lsvgorgdoc = iSvgDocument; + // We have moved all the leaving functions into RenderFileL + TRAPD(err,RenderFileL(aSvgData,aFrameBuffer,aMask,aPreserveAspectRatio)); + // No matter what...whether the RenderFileL returns properly or leave we need to set the + //GDI context back to the original frame buffer and mask... and set back the engine to + //how it was before all this happened.. + + SetDocument(lsvgorgdoc); + lsvgorgdoc->SetEngine(this); + // the setGDIContextL error is a very serious error and if it occurs then + // there is no way of recovery. + TRAP_IGNORE(SetGdiContextL(OrgFrameBuffer,OrgMask)); + //So we are propagating the more probable error of the two which is the leaving of + // RenderFileL. + return err; + } + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// Helper leaving function for the function RenderFileToBuffer. +// The actual rendering happens in this function..while the calling function uses this to +// render the file. +// --------------------------------------------------------------------------- + + +void CSvgEngineImpl::RenderFileL( const TDesC8& aSvgData, + CFbsBitmap* aFrameBuffer, + CFbsBitmap* aMask, + TBool aPreserveAspectRatio) + +{ + CFont *lFont = iGfxContext->Font(); + TFontSpec lFontSpec = lFont->FontSpecInTwips(); + + TSize imageSize; + imageSize = aFrameBuffer->SizeInPixels(); + //iFrameBuffer = aFrameBuffer; + + SetGdiContextL(aFrameBuffer, aMask); + CSvgDocumentImpl* lSvgDocument = CSvgDocumentImpl::NewLC(iSvgBitmapFontProvider); + SetDocument(lSvgDocument); + lSvgDocument->SetEngine(this); + + // fileHandle is valid from client + lSvgDocument->Load( aSvgData, *iSvgError ); + if ( iSvgError->HasError() && !iSvgError->IsWarning() ) + { + CleanupStack::PopAndDestroy(1); + return; + } + + StartFrameLoopL(); + CSvgSvgElementImpl* lRoot = (CSvgSvgElementImpl*)lSvgDocument->RootElement(); + _LIT( KPreserveAspectRatio, "preserveAspectRatio" ); + + if(lRoot) + { + if ( aPreserveAspectRatio ) + { + _LIT( KXMidYMid, "xMidYMid" ); + lRoot->SetAttributeL( KPreserveAspectRatio, KXMidYMid ); + lRoot->SetWidth( imageSize.iWidth ); + lRoot->SetHeight( imageSize.iHeight ); + } + else { + _LIT( KNone, "none" ); + lRoot->SetAttributeL( KPreserveAspectRatio, KNone ); + lRoot->SetWidth( imageSize.iWidth ); + lRoot->SetHeight( imageSize.iHeight ); + } + RedrawL(); + } + CleanupStack::PopAndDestroy( 1 ); +} + + +// --------------------------------------------------------------------------- +// --------------------------------------------------------------------------- +// Generate a mask bitmap from alpha channel of the framebuffer. +// --------------------------------------------------------------------------- +void CSvgEngineImpl::GenerateMask(CFbsBitmap* aMask) + { + if ( iGfxContext ) + { + iGfxContext->GenerateMask( aMask ); + } + } + +// +// --------------------------------------------------------------------------- +// set background color +// --------------------------------------------------------------------------- +void CSvgEngineImpl::SetBackgroundColor(TUint32 aRGBA8888Color) + { + iBackgroundColor = aRGBA8888Color; + } + +// +// --------------------------------------------------------------------------- +// Get Size of render buffer +// --------------------------------------------------------------------------- +TSize CSvgEngineImpl::GetSize() + { + return iFrameBufferSize; + + + + } + + +// +// --------------------------------------------------------------------------- +// Return SVG Engine State +// --------------------------------------------------------------------------- + +TSvgEngineState CSvgEngineImpl::SVGEngineState() + { + return iSvgEngineState; + } + +// +// --------------------------------------------------------------------------- +// Set SVG Engine State +// --------------------------------------------------------------------------- + +void CSvgEngineImpl::SetSVGEngineState(TSvgEngineState aState) + { + iSvgEngineState = aState; + if( iSvgEngineState == ESVGEnginePaused ) + { + if ( iSvgDocument ) + { + iSvgDocument->TimeContainer()->UserPause(); + NotifyAnimationPaused(); + } + } + else if( iSvgEngineState == ESVGEngineRunning ) + { + if (iSvgDocument && iSvgDocument->IsAnimationFile()) + { + iSvgDocument->TimeContainer()->UserResume(); + } + } + else if(iSvgEngineState == ESVGEngineStopped ) + { + if ( iSvgDocument ) + { + iSvgDocument->TimeContainer()->UserStop(); + } + + } + } + +void CSvgEngineImpl::SeekEngine( TUint32 aTime) + { + iSvgEngineState = ESVGEngineRunning; + if ( iSvgDocument ) + { + iSvgDocument->TimeContainer()->UserSeek( aTime ); + } + } + +void CSvgEngineImpl::ResetTimer() + { + if ( iSvgDocument ) + { + iSvgDocument->TimeContainer()->UserResetTime(); + } + } + +// --------------------------------------------------------------------------- +// SetGdiContext File +// --------------------------------------------------------------------------- + +void CSvgEngineImpl::SetGdiContextL(CFbsBitmap* aCurrentBitmap, CFbsBitmap* aMask) + { + // Handle for both Non-NULL and NULL parameter + iFrameBuffer = aCurrentBitmap; + iMask = aMask; + + if ( aCurrentBitmap ) + { + if ( !iGfxContext ) + { + iGfxContext = CGfx2dGcOpenVG::NewL( iFrameBuffer->SizeInPixels(), iBitmapFontSpec, iSvgBitmapFontProvider ); + + // The API is called Only in case of JSR226. Incase if the midlet developer + // has changed the RedenderQuality of the midlet.ByDefualt the value of + // iRenderQuality is 2 i.e. VG_RENDERING_QUALITY_BETTER. + iGfxContext->SetAntialiasingMode( iRenderQuality ); + } + else + { + iGfxContext->ChangeBufferSizeL( iFrameBuffer->SizeInPixels() ); + } + } + else if ( iGfxContext ) + { + iGfxContext->ChangeBufferSizeL( TSize( 0,0 ) ); + } + } + +// --------------------------------------------------------------------------- +// void CSvgEngineImpl::StartEngine(CSvgErrorImpl* aError) +// --------------------------------------------------------------------------- + +void CSvgEngineImpl::StartEngine(CSvgErrorImpl* aError) + { + if ( !iFrameBuffer || !iSvgDocument ) + { + return; + } + + iMouseoverElement = NULL; + if ( ((iFrameBufferSize.iHeight <= 0 )||(iFrameBufferSize.iWidth <= 0 )) &&(( iFrameBuffer->SizeInPixels().iWidth == 0 ) || + ( iFrameBuffer->SizeInPixels().iHeight == 0) )) + { + return; + } + + TBool initialized = EFalse; + + TRAPD( initError, initialized = StartFrameLoopL() ); + + if ( initError != KErrNone || !initialized ) + { + return; + } + + // Get the Engine State to Running + SetSVGEngineState(ESVGEngineRunning); + + // Document is an animation + if( iSvgDocument->IsAnimationFile() ) + { + { // Atleast first frame should get drawn + TRAPD(error, RedrawL() ); + { + if ( error != KErrNone && aError != NULL ) + { + if( error == KErrNoMemory ) + { + CSvgDocumentImpl::PrepareError( *aError, ESvgNoMemory, error, + _L( "Unable to Draw: " ), + _L( "" ) ); + return; + } + + CSvgDocumentImpl::PrepareError( *aError, ESvgUnknown, error, + _L( "Unable to Draw: " ), + _L( "" ) ); + return; + } + } + + } + + iSvgDocument->TimeContainer()->UserPlay(); + iSvgDocument->iAnimationResetNeeded = ETrue; + } + // Static svg file + else + { + TRAPD(error, RedrawL() ); + { + if ( error != KErrNone && aError != NULL ) + { + if( error == KErrNoMemory ) + { + CSvgDocumentImpl::PrepareError( *aError, ESvgNoMemory, error, + _L( "Unable to Draw: " ), + _L( "" ) ); + return; + } + + CSvgDocumentImpl::PrepareError( *aError, ESvgUnknown, error, + _L( "Unable to Draw: " ), + _L( "" ) ); + return; + } + } + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::RenderFrame( TUint aCurrentTime ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RenderFrame( TUint aCurrentTime ) + { + if ( !iFrameBuffer || !iSvgDocument || + iFrameBuffer->SizeInPixels().iWidth == 0 || iFrameBuffer->SizeInPixels().iHeight == 0 ) + { + return; + } + + if ( aCurrentTime == 0 ) + { + SeekEngine( 0 ); + } + + iMouseoverElement = NULL; + + CSvgSvgElementImpl* rootElement = (CSvgSvgElementImpl*)iSvgDocument->RootElement(); + + if (rootElement == NULL) + { + return; + } + + TGfxRectangle2D viewBoxRect; + if (rootElement->GetViewBox(viewBoxRect)) + { + //viewbox has been defined or set already + if (viewBoxRect.iWidth == TFloatFixPt(0) || viewBoxRect.iHeight == TFloatFixPt(0)) + { + //viewbox has no area so dont render + return; + } + } + + if( iRequestObserver && iSvgDocument->iEventHandler ) + { + iRequestObserver->UpdatePresentation( iSvgDocument->iEventHandler->AnimationElementsCount() ); + } + + iSvgDocument->iInitialDrawFlag = ETrue; + + // Fix for animation element for testApp + TSvgTick lTick; + lTick.iRealTimeTick = aCurrentTime; + lTick.iParentTcTick = 0; + iSvgDocument->TimeContainer()->ParentTimeContainerTick(lTick) ; + // Fix for animation element for testApp + } + + +// --------------------------------------------------------------------------- +// Set SvgEngine Document +// --------------------------------------------------------------------------- +void CSvgEngineImpl::SetDocument(CSvgDocumentImpl* aDocument) + { + iSvgDocument = aDocument; + } + + +// --------------------------------------------------------------------------- +// Change the duration of the timer +// --------------------------------------------------------------------------- +void CSvgEngineImpl::ChangeDuration( TUint32 aTimerDuration ) + { + if ( iSvgDocument ) + { + iSvgDocument->TimeContainer()->UserChangeFrameDuration( + aTimerDuration ); + + // Check if there is animation element in the parent svg + RPointerArray lAnimationEleList; + iSvgDocument->FindAllElements((CSvgElementImpl* )iSvgDocument->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->TimeContainer()->UserChangeFrameDuration( + aTimerDuration ); // Change Frame duration for child svg + } + } + lAnimationEleList.Close(); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::Resume(TInt32 aTime) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::Resume(TInt32 aTime) + { + if ( iSvgDocument ) + { + iSvgDocument->TimeContainer()->UserResume( aTime ); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::FindBBoxesForRotatedText( const TDesC& aSearchString, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::FindBBoxesForRotatedText( const TDesC& aSearchString, + RPointerArray& aBoundingBoxes, + RArray& aTexts, + RArray& aElementIds, + TBool aCaseSensitive ) +{ + if ( iSvgDocument == NULL ) + return; + + if ( iSvgTextBoundingBoxes.Count() > 0 ) + { + iSvgTextBoundingBoxes.ResetAndDestroy(); + } + + // Find all text elements + HBufC* searchStr = aSearchString.AllocLC(); + TPtr searchStrPtr = searchStr->Des(); + RPointerArray textElements; + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgTextElement, textElements ); + // Himanshu: Find all animation elements + RPointerArray lAllAnimationElements; + iSvgDocument->FindAllElements( (CSvgElementImpl*)iSvgDocument->RootElement(), + KSvgMediaAnimationElement, + lAllAnimationElements ); + TInt lAllAnimationEleCnt = lAllAnimationElements.Count(); + for ( TInt i = 0; i < lAllAnimationEleCnt; i++ ) + { + CSvgMediaAnimationElementImpl* element = (CSvgMediaAnimationElementImpl*)lAllAnimationElements[i]; + CSvgDocumentImpl* ldoc = element->GetChildDocument(); + if(ldoc) + { + // Find all text elements in child document + ldoc->FindAllElements( (CSvgElementImpl*)ldoc->RootElement(), + KSvgTextElement, + textElements ); + } + + } + lAllAnimationElements.Close(); + + TSvgFourPointRect boundingBox; + TInt textEleCnt = textElements.Count(); + for ( TInt i = 0; i < textEleCnt; i++ ) + { + CSvgTextElementImpl* textElement = (CSvgTextElementImpl*)textElements[i]; + TPtrC remainder( textElement->GetText() ); + + TInt index = ( aCaseSensitive ) ? remainder.Find( aSearchString ) : + remainder.FindF( aSearchString ); + + // continue to next element if nothing found + if ( index == KErrNotFound ) + continue; + + searchStrPtr.Copy( remainder.Mid(index,aSearchString.Length()) ); + // Get the bounding box for the whole text element + textElement->GetFourPointBBox( boundingBox ); + + // Get bounding box for every occurrence + TReal32 textAdvance = (TReal32)(textElement->TextAdvance( *searchStr, index )); + TReal32 leftAdvance = 0.0f; + //TReal32 aHeight = textElement->Ascent() + textElement->Descent(); + + while ( index != KErrNotFound ) + { + // Calculate boundingbox for searched-text + // indeterminate results with a string only one character long + leftAdvance = leftAdvance + (TReal32)(textElement->TextAdvance( remainder.Left( index ))); + + // need to setup slope calculation here to determine where the new + // four point rect should be for partial pieces of text + + // need to do something for both vertical and horizontal text 0 and na slopes + + TReal32 dy = (TReal32)boundingBox.iPoint2.iY - (TReal32)boundingBox.iPoint1.iY; + TReal32 dx = (TReal32)boundingBox.iPoint2.iX - (TReal32)boundingBox.iPoint1.iX; + + double aSlopeRan; + Math::ATan(aSlopeRan, dy, dx); + + double aSinVal; + Math::Sin(aSinVal, aSlopeRan); + + double aCosVal; + Math::Cos(aCosVal, aSlopeRan); + + + TReal32 x1 = aCosVal * leftAdvance + (TReal32)boundingBox.iPoint1.iX; + TReal32 x3 = aCosVal * leftAdvance + (TReal32)boundingBox.iPoint3.iX; + TReal32 y1 = aSinVal * leftAdvance + (TReal32)boundingBox.iPoint1.iY; + TReal32 y3 = aSinVal * leftAdvance + (TReal32)boundingBox.iPoint3.iY; + + TReal32 x2 = aCosVal * textAdvance + x1; + TReal32 x4 = aCosVal * textAdvance + x3; + + TReal32 y2 = aSinVal * textAdvance + y1; + TReal32 y4 = aSinVal * textAdvance + y3; + + TSvgFourPointRect* bbox = NULL; + + TRAP_IGNORE( bbox = new (ELeave) TSvgFourPointRect( TPoint(x1, y1), + TPoint(x2, y2), + TPoint(x3, y3), + TPoint(x4, y4)) ); + + if ( !bbox ) + { + #ifdef _DEBUG + RDebug::Printf("Four Point Rect Failed: Out of Memory"); + #endif + return; + } + + // store bound box pointers to go back to client + aBoundingBoxes.Append( (MRect*)bbox ); + + iSvgTextBoundingBoxes.Append( bbox ); + + // store point to text + aTexts.Append( TPtrC( textElement->GetText() ) ); + aElementIds.Append( (TInt)textElement ); + + remainder.Set( remainder.Right( remainder.Length() - index - aSearchString.Length() ) ); + leftAdvance = leftAdvance + textAdvance; + index = ( aCaseSensitive ) ? remainder.Find( aSearchString ) : + remainder.FindF( aSearchString ); + } + } + CleanupStack::PopAndDestroy(searchStr); + textElements.Close(); +} + +//this is the old 2point rect way that only works for horizontal text +/*void CSvgEngineImpl::FindBBoxesForHorizontalText( const TDesC& aSearchString, + RArray& aBoundingBoxes, + RArray& aTexts, + RArray& aElementIds, + TBool aCaseSensitive ) +{ + if ( iSvgDocument == NULL ) + return; + + // Find all text elements + RPointerArray textElements; + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgTextElement, textElements ); + + TGfxRectangle2D boundingBox; + for ( TInt i = 0; i < textElements.Count(); i++ ) + { + CSvgTextElementImpl* textElement = (CSvgTextElementImpl*)textElements[i]; + TPtrC remainder( textElement->GetText() ); + + TInt index = ( aCaseSensitive ) ? remainder.Find( aSearchString ) : + remainder.FindF( aSearchString ); + + // continue to next element if nothing found + if ( index == KErrNotFound ) + continue; + + // Get the bounding box for the whole text element + textElement->GetBBox( boundingBox ); + + // Get bounding box for every occurrence + TFloatFixPt textAdvance = textElement->TextAdvance( aSearchString, index ); + TFloatFixPt leftAdvance = 0.0f; + while ( index != KErrNotFound ) + { + // Calculate boundingbox for searched-text + leftAdvance = leftAdvance + textElement->TextAdvance( remainder.Left( index ), index ); + + TRect bbox( (TInt)boundingBox.iX + (TInt)leftAdvance, + (TInt)boundingBox.iY, + (TInt)boundingBox.iX + (TInt)leftAdvance + (TInt)textAdvance, + (TInt)boundingBox.iY + (TInt)boundingBox.iHeight ); + + // store bound box + aBoundingBoxes.Append( bbox ); + + // store point to text + aTexts.Append( TPtrC( textElement->GetText() ) ); + aElementIds.Append( (TInt)textElement ); + + remainder.Set( remainder.Right( remainder.Length() - index - aSearchString.Length() ) ); + leftAdvance = leftAdvance + textAdvance; + index = ( aCaseSensitive ) ? remainder.Find( aSearchString ) : + remainder.FindF( aSearchString ); + } + } + textElements.Close(); +} +*/ + +/************************ HyperLinking Functions ***********************/ + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::CheckForHyperlinkMouseover( TInt aX, TInt aY ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::CheckForHyperlinkMouseover( TInt aX, TInt aY ) +{ + if ( iHyperlinkListeners.Count() == 0 ) + return; + + if ( iSvgDocument == NULL ) + return; + + // Gather elements if first time + RPointerArray iAElementList; + if ( iAElementList.Count() == 0 ) + { + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAElement, iAElementList ); + } + + // find the bounding box containing point + TGfxPoint2D point( aX, aY ); + TGfxRectangle2D boundingBox; + TInt aEleListCnt = iAElementList.Count(); + for ( TInt i = 0; i < aEleListCnt; i++ ) + { + CSvgElementImpl* element = iAElementList[i]; + CSvgGElementImpl::GetGroupBounding( boundingBox, element ); + if ( boundingBox.Contains( point ) ) + { + // no existing mouse over element: notify HyperlinkEntered + if ( iMouseoverElement == NULL ) + { + NotifyHyperlinkEntered( element->Href() ); + } + // otherwise: notify HyperlinkExited, HyperlinkEntered + else if ( iMouseoverElement != element ) + { + NotifyHyperlinkExited( iMouseoverElement->Href() ); + NotifyHyperlinkEntered( element->Href() ); + } + iMouseoverElement = element; + return; + } + } + + // no bounding box containing point: notify HyperlinkExited + if ( iMouseoverElement != NULL ) + { + NotifyHyperlinkExited( iMouseoverElement->Href() ); + iMouseoverElement = NULL; + } + + iAElementList.Close(); +} + +/*-------------------------Animation Listeners-----------------------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::AddAnimationListener( MSvgAnimationListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::AddAnimationListener( MSvgAnimationListener* aListener ) +{ + if ( aListener != NULL && iAnimationListeners.Find( aListener ) == KErrNotFound ) + iAnimationListeners.Append( aListener ); + +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::RemoveAnimationListener( MSvgAnimationListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RemoveAnimationListener( MSvgAnimationListener* aListener ) +{ + TInt index = iAnimationListeners.Find( aListener ); + if ( index != KErrNotFound ) + iAnimationListeners.Remove( index ); +} + +/*-------------------------Animation listener notification to client-------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyAnimationStarted() +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyAnimationStarted() +{ + + TBool isAnimationIndefinite = EFalse; + if ( ( iSvgDocument == NULL ) || ( iSvgDocument->RootElement() == NULL ) || + ( iAnimationListeners.Count() == 0 ) ) + { + return; + } + + RPointerArray AnimationElementList; + + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgSetElement, AnimationElementList ); + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateElement, AnimationElementList ); + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateMotionElement, AnimationElementList ); + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateTransformElement, AnimationElementList ); + iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateColorElement, AnimationElementList ); + + if ( AnimationElementList.Count() != 0 ) + { + TInt animationEleListCnt = AnimationElementList.Count(); + for ( TInt i=0; i < animationEleListCnt; i++ ) + { + CSvgElementImpl * element = AnimationElementList[i]; + if ( ((CSvgAnimationBase *)element)->CompleteDuration() == KTimeIndefinite ) + { + isAnimationIndefinite = ETrue; + break; + } + } + + } + AnimationElementList.Close(); + + TInt animationListenersCnt = iAnimationListeners.Count(); + for ( TInt i = 0; i < animationListenersCnt; i++ ) + iAnimationListeners[i]->AnimationStarted( isAnimationIndefinite ); + + +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyAnimationPaused() +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyAnimationPaused() +{ + TInt animationListenersCnt = iAnimationListeners.Count(); + for ( TInt i = 0; i < animationListenersCnt; i++ ) + iAnimationListeners[i]->AnimationPaused(); +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyAnimationEnded() +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyAnimationEnded() +{ + if ( ( iSvgDocument == NULL ) || ( iSvgDocument->RootElement() == NULL ) || + ( iAnimationListeners.Count() == 0 ) ) + { + return; + } + #if 0 + RPointerArray AnimationElementList; + + FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgSetElement, AnimationElementList ); + FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateElement, AnimationElementList ); + FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateMotionElement, AnimationElementList ); + FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateTransformElement, AnimationElementList ); + FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAnimateColorElement, AnimationElementList ); + + if ( AnimationElementList.Count() != 0 ) + { + TInt animationEleListCnt = AnimationElementList.Count(); + for ( TInt i=0; i < animationEleListCnt; i++ ) + { + CSvgElementImpl * element = AnimationElementList[i]; + if ( ((CSvgAnimationBase *)element)->iAnimStatus == KAnimActive ) + { + AnimationElementList.Close(); + return; + } + } + + } + AnimationElementList.Close(); +#endif + + TInt animationListenersCnt = iAnimationListeners.Count(); + for ( TInt i = 0; i < animationListenersCnt; i++ ) + iAnimationListeners[i]->AnimationEnded(); + +} + +/*------------------Register Client Text Area listeners----------------------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::AddTextAreaListener( MSvgTextAreaListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::AddTextAreaListener( MSvgTextAreaListener* aListener ) +{ + if ( aListener != NULL && iTextAreaListeners.Find( aListener ) == KErrNotFound ) + { + iTextAreaListeners.Append( aListener ); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::RemoveTextAreaListener( MSvgTextAreaListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RemoveTextAreaListener( MSvgTextAreaListener* aListener ) +{ + TInt index = iTextAreaListeners.Find( aListener ); + if ( index != KErrNotFound ) + { + iTextAreaListeners.Remove( index ); + } +} + +/*----------------Text Area listener notification to client--------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyTextAreaEntered( CSvgTextAreaElementImpl* aTextAreaHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyTextAreaEntered( CSvgTextAreaElementImpl* aTextAreaHandle ) +{ + TInt textAreaListenersCnt = iTextAreaListeners.Count(); + for (TInt i=0; i < textAreaListenersCnt; i++) + { + iTextAreaListeners[i]->TextAreaEntered( (TInt)aTextAreaHandle); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyTextAreaExited( CSvgTextAreaElementImpl* aTextAreaHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyTextAreaExited( CSvgTextAreaElementImpl* aTextAreaHandle ) +{ + TInt textAreaListenersCnt = iTextAreaListeners.Count(); + for (TInt i=0; i < textAreaListenersCnt; i++) + { + iTextAreaListeners[i]->TextAreaExited( (TInt)aTextAreaHandle); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyTextAreaActivated( CSvgTextAreaElementImpl* aTextAreaHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyTextAreaActivated( CSvgTextAreaElementImpl* aTextAreaHandle ) +{ + TInt textAreaListenersCnt = iTextAreaListeners.Count(); + for (TInt i=0; i < textAreaListenersCnt; i++) + { + iTextAreaListeners[i]->TextAreaActivated( (TInt)aTextAreaHandle ); + } +} + +/*------------------Register Client Text listeners----------------------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::AddTextListener( MSvgTextListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::AddTextListener( MSvgTextListener* aListener ) +{ + if ( aListener != NULL && iTextListeners.Find( aListener ) == KErrNotFound ) + { + iTextListeners.Append( aListener ); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::RemoveTextListener( MSvgTextListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RemoveTextListener( MSvgTextListener* aListener ) +{ + TInt index = iTextListeners.Find( aListener ); + if ( index != KErrNotFound ) + { + iTextListeners.Remove( index ); + } +} + +/*----------------Text listener notification to client--------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyTextEntered( CSvgTextElementImpl* aTextHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyTextEntered( CSvgTextElementImpl* aTextHandle ) +{ + TInt textListenersCnt = iTextListeners.Count(); + for (TInt i=0; i < textListenersCnt; i++) + { + iTextListeners[i]->TextEntered( (TInt)aTextHandle); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyTextExited( CSvgTextElementImpl* aTextHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyTextExited( CSvgTextElementImpl* aTextHandle ) +{ + TInt textListenersCnt = iTextListeners.Count(); + for (TInt i=0; i < textListenersCnt; i++) + { + iTextListeners[i]->TextExited( (TInt)aTextHandle); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyTextActivated( CSvgTextElementImpl* aTextHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyTextActivated( CSvgTextElementImpl* aTextHandle ) +{ + TInt textListenersCnt = iTextListeners.Count(); + for (TInt i=0; i < textListenersCnt; i++) + { + iTextListeners[i]->TextActivated( (TInt)aTextHandle ); + } +} + +/*---------------------Register Client Hyperlink listeners----------------------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::AddHyperlinkListener( MSvgHyperlinkListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::AddHyperlinkListener( MSvgHyperlinkListener* aListener ) +{ + if ( aListener != NULL && iHyperlinkListeners.Find( aListener ) == KErrNotFound ) + iHyperlinkListeners.Append( aListener ); +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::RemoveHyperlinkListener( MSvgHyperlinkListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RemoveHyperlinkListener( MSvgHyperlinkListener* aListener ) +{ + TInt index = iHyperlinkListeners.Find( aListener ); + if ( index != KErrNotFound ) + iHyperlinkListeners.Remove( index ); +} + +void CSvgEngineImpl::AddViewPortListener(MSvgViewPortListener* aListener) +{ + if ( aListener != NULL ) + { + iViewPortListener = aListener ; + } + +} + + +void CSvgEngineImpl::RemoveViewPortListener(MSvgViewPortListener* + /* aListener */ ) +{ + if(iViewPortListener != NULL) + { + iViewPortListener = NULL; + } +} +/*----------------Hyperlink listener notification to client--------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyHyperlinkEntered( CSvgAElementImpl* aAElementHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyHyperlinkEntered( CSvgAElementImpl* aAElementHandle ) +{ + TInt hyperLinkListenersCnt = iHyperlinkListeners.Count(); + for ( TInt i = 0; i < hyperLinkListenersCnt; i++ ) + { + if (aAElementHandle) + { + iHyperlinkListeners[i]->LinkEntered( aAElementHandle->Href() ); + } + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyHyperlinkEntered( const TDesC& aUri ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyHyperlinkEntered( const TDesC& aUri ) +{ + TInt hyperLinkListenersCnt = iHyperlinkListeners.Count(); + for ( TInt i = 0; i < hyperLinkListenersCnt; i++ ) + { + iHyperlinkListeners[i]->LinkEntered( aUri ); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyHyperlinkExited( CSvgAElementImpl* aAElementHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyHyperlinkExited( CSvgAElementImpl* aAElementHandle ) +{ + TInt hyperLinkListenersCnt = iHyperlinkListeners.Count(); + for ( TInt i = 0; i < hyperLinkListenersCnt; i++ ) + { + if (aAElementHandle) + { + iHyperlinkListeners[i]->LinkExited( aAElementHandle->Href() ); + } + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyHyperlinkExited( const TDesC& aUri ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyHyperlinkExited( const TDesC& aUri ) +{ + TInt hyperLinkListenersCnt = iHyperlinkListeners.Count(); + for ( TInt i = 0; i < hyperLinkListenersCnt; i++ ) + { + iHyperlinkListeners[i]->LinkExited( aUri ); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyHyperlinkActivated( CSvgAElementImpl* aAElementHandle ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyHyperlinkActivated( CSvgAElementImpl* aAElementHandle ) +{ + if ( !aAElementHandle || + aAElementHandle->Href().Length() == 0 || + aAElementHandle->Href()[0] == '#' ) + { + return; + } + + TInt hyperLinkListenersCnt = iHyperlinkListeners.Count(); + for ( TInt i = 0; i < hyperLinkListenersCnt; i++ ) + { + iHyperlinkListeners[i]->LinkActivated( aAElementHandle->Href() ); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyHyperlinkActivated( const TDesC& aUri ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyHyperlinkActivated( const TDesC& aUri ) +{ + TInt hyperLinkListenersCnt = iHyperlinkListeners.Count(); + for ( TInt i = 0; i < hyperLinkListenersCnt; i++ ) + { + iHyperlinkListeners[i]->LinkActivated( aUri ); + } +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyHyperlinkActivatedWithShow( const TDesC& aUri, const TDesC& aShow ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyHyperlinkActivatedWithShow( const TDesC& aUri, const TDesC& aShow ) +{ + TInt hyperLinkListenersCnt = iHyperlinkListeners.Count(); + for ( TInt i = 0; i < hyperLinkListenersCnt; i++ ) + iHyperlinkListeners[i]->LinkActivatedWithShow( aUri, aShow ); +} + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyElementActivatedLinkEntered( CSvgElementImpl* aElement) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyElementActivatedLinkEntered( CSvgElementImpl* aElement) + { + if(iMouseoverElement == NULL) + { + const TDesC* myId = aElement->Id(); + + if (myId) + NotifyHyperlinkEntered( *(myId)); + iMouseoverElement = aElement; + } + } +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyElementActivatedLinkExited( CSvgElementImpl* aElement) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyElementActivatedLinkExited( CSvgElementImpl* aElement) + { + if(iMouseoverElement == aElement ) + { + const TDesC* myId = aElement->Id(); + + if (myId) + NotifyHyperlinkExited( *(myId)); + iMouseoverElement = NULL; + } + } +void CSvgEngineImpl::GetViewPort(TInt getWidth, TInt getHeight, TBool isWidthInPer, TBool isHeightInPer, TInt &setWidth, TInt &setHeight) +{ + if(iViewPortListener != NULL) + { + iViewPortListener->GetViewPort(getWidth, getHeight, isWidthInPer, isHeightInPer, setWidth, setHeight); + } +} + +/*------------------Register Client Interactive Element listeners------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::AddInteractiveElementListener( +// MSvgInteractiveElementListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::AddInteractiveElementListener( + MSvgInteractiveElementListener* aListener ) + { + if ( + aListener != NULL && + iInteractiveElementListeners.Find( aListener ) == KErrNotFound ) + { + iInteractiveElementListeners.Append( aListener ); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::RemoveInteractiveElementListener( +// MSvgInteractiveElementListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RemoveInteractiveElementListener( + MSvgInteractiveElementListener* aListener ) + { + TInt index = iInteractiveElementListeners.Find( aListener ); + if ( index != KErrNotFound ) + { + iInteractiveElementListeners.Remove( index ); + } + } + +/*-----------Interactive Element listener notification to client------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyInteractiveElementEntered(CSvgElementImpl* aElement) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyInteractiveElementEntered( + CSvgElementImpl* aElement) + { + TUint16 lsubeventmask=0; + TBool linteractivity; + linteractivity=this->iSvgDocument->iEventHandler-> + CheckInteractivityAndGetSubEventMask(aElement,lsubeventmask); + if(linteractivity) + { + TInt linteractiveElementListenersCnt = iInteractiveElementListeners.Count(); + for ( TInt i = 0; i < linteractiveElementListenersCnt; i++ ) + { + const TDesC* myId = aElement->Id(); + TPtrC16 ptr; + if(myId) + { + ptr.Set(*myId); + } + else + { + _LIT(KEmptyString,""); + ptr.Set( KEmptyString); + } + iInteractiveElementListeners[i]->InteractiveElementEntered( + ptr,lsubeventmask ); + } + } + } +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyInteractiveElementExited(CSvgElementImpl* aElement) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyInteractiveElementExited(CSvgElementImpl* aElement) + { + TInt linteractiveElementListenersCnt = iInteractiveElementListeners.Count(); + for ( TInt i = 0; i < linteractiveElementListenersCnt; i++ ) + { + const TDesC* myId = aElement->Id(); + TPtrC16 ptr; + if(myId) + { + ptr.Set(*myId); + } + else + { + _LIT(KEmptyString,""); + ptr.Set(KEmptyString); + } + iInteractiveElementListeners[i]->InteractiveElementExited(ptr); + } + } + +// --------------------------------------------------------------------------- +// Set SVG Dimension to frame buffer size +// --------------------------------------------------------------------------- +void CSvgEngineImpl::SetSvgDimensionToFrameBufferL(TUint aWidth, TUint aHeight) + { + if (iSvgDocument == NULL ) return; + if (iSvgDocument->RootElement() != NULL) + { + CSvgElementImpl* theElement = (CSvgElementImpl*)(iSvgDocument->RootElement()); + ((CSvgSvgElementImpl*)theElement)->iWidthInUserCoordinate = 0; + ((CSvgSvgElementImpl*)theElement)->iHeightInUserCoordinate = 0; + TFloatFixPt wFix( (TInt)aWidth ); + TFloatFixPt hFix( (TInt)aHeight ); + theElement->SetAttributeFloatL(KAtrWidth, wFix ); + theElement->SetAttributeFloatL(KAtrHeight, hFix ); + } + + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::SetMediaTime(TUint32 aTimeInMilliSeconds) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::SetMediaTime(TUint32 aTimeInMilliSeconds) + { + // Set Current Time in the document + if(iSvgDocument != NULL) + { + //iSvgDocument->SetCurrentTime( aTimeInMilliSeconds ); + + iSvgDocument->iAnimationResetNeeded = ETrue; + } + if(this->iSvgDocument && this->iSvgDocument->iEventHandler) + { + this->iSvgDocument->iEventHandler->SetCurrentTime(aTimeInMilliSeconds); + } + // Find all animation elements in the document + RPointerArray lAnimationEleList; + if(iSvgDocument) + { + iSvgDocument->FindAllElements((CSvgElementImpl* )iSvgDocument->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->iAnimationResetNeeded = ETrue; + if ( lChildDoc->iEventHandler ) + { + lChildDoc->iEventHandler->SetCurrentTime(aTimeInMilliSeconds); + } + + } + } + lAnimationEleList.Close(); + + } + this->SetSVGEngineState(ESVGEnginePaused); + this->SeekEngine(aTimeInMilliSeconds); + + } + +// -------------------------------------------------------------------------- +// TBool CSvgEngineImpl::IsElementVisible( TInt aElementId ) +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::IsElementVisible( TInt aElementId ) + { + if ( aElementId == 0 || iFrameBuffer == NULL ) + { + return EFalse; + } + + CSvgElementImpl* element = (CSvgElementImpl*)aElementId; + + TInt32 visibleAttribute = -1; + + TRAPD(error,element->GetAttributeIntL( KCSS_ATTR_VISIBILITY, visibleAttribute )); + if (error != KErrNone) + { + // error processing + } + + + return visibleAttribute == 0; + } + +// Set whether to call request observer's UpdateScreen method +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::SetIgnoreUpdateScreen( TBool aBool ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::SetIgnoreUpdateScreen( TBool aBool ) +{ + iIgnoreUpdateScreen = aBool; +} + +/*---------------------------MouseListener---------------------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::AddMouseListener( const MSvgMouseListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::AddMouseListener( const MSvgMouseListener* aListener ) + { + TInt index = iSvgMouseListeners.Find( aListener ); + if ( aListener != NULL && index == KErrNotFound ) + { + iSvgMouseListeners.Append( aListener ); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::RemoveMouseListener( const MSvgMouseListener* aListener ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::RemoveMouseListener( const MSvgMouseListener* aListener ) + { + TInt index = iSvgMouseListeners.Find( aListener ); + if ( index != KErrNotFound ) + { + iSvgMouseListeners.Remove( index ); + } + } + +// -------------------------------------------------------------------------- +// TInt CSvgEngineImpl::MouseListenerCount() +// --------------------------------------------------------------------------- +TInt CSvgEngineImpl::MouseListenerCount() + { + return iSvgMouseListeners.Count(); + } + +/*-------------MouseListener Notifications back to client---------------------------*/ +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyMousePressed( RPointerArray& aElements, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyMousePressed( RPointerArray& aElements, + TInt aX, TInt aY ) + { + TInt svgMouseListenersCnt = iSvgMouseListeners.Count(); + for ( TInt i = 0; i < svgMouseListenersCnt; i++ ) + { + iSvgMouseListeners[i]->MousePressed( aElements, aX, aY ); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyMouseReleased( RPointerArray& aElements, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyMouseReleased( RPointerArray& aElements, + TInt aX, TInt aY ) + { + TInt svgMouseListenersCnt = iSvgMouseListeners.Count(); + for ( TInt i = 0; i < svgMouseListenersCnt; i++ ) + { + iSvgMouseListeners[i]->MouseReleased( aElements, aX, aY ); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyMouseEntered( RPointerArray& aElements, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyMouseEntered( RPointerArray& aElements, + TInt aX, TInt aY ) + { + TInt svgMouseListenersCnt = iSvgMouseListeners.Count(); + for ( TInt i = 0; i < svgMouseListenersCnt; i++ ) + { + iSvgMouseListeners[i]->MouseEntered( aElements, aX, aY ); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyMouseExited( RPointerArray& aElements, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyMouseExited( RPointerArray& aElements, + TInt aX, TInt aY ) + { + TInt svgMouseListenersCnt = iSvgMouseListeners.Count(); + for ( TInt i = 0; i < svgMouseListenersCnt; i++ ) + { + iSvgMouseListeners[i]->MouseExited( aElements, aX, aY ); + } + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::NotifyMouseMoved( RPointerArray& aElements, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::NotifyMouseMoved( RPointerArray& aElements, + TInt aX, TInt aY ) + { + TInt svgMouseListenersCnt = iSvgMouseListeners.Count(); + for ( TInt i = 0; i < svgMouseListenersCnt; i++ ) + { + iSvgMouseListeners[i]->MouseMoved( aElements, aX, aY ); + } + } + +/*---------------------------------------------------------------------*/ + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::GetViewableElementsAtPoint( RPointerArray& aElements, TInt aX, TInt aY ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::GetViewableElementsAtPoint( CSvgDocumentImpl* aSvgDocument, RPointerArray& aElements, TInt aX, TInt aY ) + { + if ( aSvgDocument == NULL ) + return; + + //JSR226 Change this could slow down event handling but it seems to be required to work + UpdateCTM(aSvgDocument); + + // Gather all "viewable" elements + RPointerArray iViewableElementList; + if ( iViewableElementList.Count() == 0 ) + { + FindAllViewableElements( (CSvgElementImpl* )aSvgDocument->RootElement(), + iViewableElementList ); + } + + // find the bounding box containing point + TGfxPoint2D point( aX, aY ); + TGfxRectangle2D boundingBox; + TInt viewableEleListCnt = iViewableElementList.Count(); + for ( TInt i = 0; i < viewableEleListCnt; i++ ) + { + CSvgElementImpl* element = iViewableElementList[i]; + element->GetBBox( boundingBox ); + if ( boundingBox.Contains( point ) ) + { + aElements.Append( element ); + } + } + // Display of list + iViewableElementList.Close(); + } + +// Return all viewable elements +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::FindAllViewableElements( CSvgElementImpl* aStartElement, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::FindAllViewableElements( CSvgElementImpl* aStartElement, + RPointerArray& iElementList ) + { + if ( aStartElement == NULL ) + return; + // The child elements of the defs element should not be viewable. skip the + // tree traversing if the element id is defs element + if(aStartElement->ElemID() == KSvgDefsElement) + return; + + CSvgElementImpl* child = (CSvgElementImpl*)aStartElement->FirstChild(); + while ( child != NULL ) + { + // add to list if child is found + TInt32 displayValue = 0; + TRAP_IGNORE(child->GetAttributeIntL( KCSS_ATTR_DISPLAY, displayValue )); + if ( child->IsViewable() && child->IsVisible() && displayValue != KDisplayEnumNone ) + { + //JSR226 CHANGE do we care if multiple signals are sent to some elements - would be faster without this check + if ( iElementList.Find( child ) == KErrNotFound ) + { + iElementList.Append( child ); + } + } + // find in grandchildren + FindAllViewableElements( child, iElementList ); + child = (CSvgElementImpl*)child->NextSibling(); + } + } + +// Return all non-viewable elements +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::FindAllNonViewableElements( CSvgElementImpl* aStartElement, +// --------------------------------------------------------------------------- +void CSvgEngineImpl::FindAllNonViewableElements( CSvgElementImpl* aStartElement, + RPointerArray& iElementList ) + { + if ( aStartElement == NULL ) + return; + + CSvgElementImpl* child = (CSvgElementImpl*)aStartElement->FirstChild(); + while ( child != NULL ) + { + // add to list if child is found + if ( !child->IsViewable() && !child->IsVisible() ) + iElementList.Append( child ); + + // find in grandchildren + FindAllNonViewableElements( child, iElementList ); + child = (CSvgElementImpl*)child->NextSibling(); + } + } + +/** + * Return the data pointed to by the given URI string, + * from an external source. + */ +// -------------------------------------------------------------------------- +// HBufC8* CSvgEngineImpl::FetchExternalDataL( const TDesC& aUri ) +// --------------------------------------------------------------------------- +HBufC8* CSvgEngineImpl::FetchExternalDataL( const TDesC& aUri ) + { + if ( iRequestObserver == NULL ) + { + #ifdef _DEBUG + RDebug::Printf("CSvgEngineImpl::FetchExternalData--requestobserver is NULL\n"); + #endif //_DEBUG + return NULL; + } + // Connect session + RFs session; + TInt connectError = session.Connect(); + if ( connectError != KErrNone ) + { + #ifdef _DEBUG + RDebug::Printf("CSvgEngineImpl::FetchExternalData--session.Connect() failed: %d\n", connectError ); + #endif //_DEBUG + return NULL; + } + + RFile fileHandle; + // Check for FetchImage error code + TInt fetchError = iRequestObserver->FetchImage( aUri, session, fileHandle ); + if ( fetchError != KErrNone ) + { + #ifdef _DEBUG + RDebug::Printf("CSvgEngineImpl::FetchExternalData--FetchImage error: %d\n", fetchError ); + #endif //_DEBUG + session.Close(); + return NULL; + } + + // Read file size + TInt fileSize = 0; + TInt sizeError = fileHandle.Size( fileSize ); + if ( sizeError != KErrNone ) + { + #ifdef _DEBUG + RDebug::Printf("CSvgEngineImpl::FetchExternalData--fileHandle.Size error: %d\n", sizeError ); + #endif //_DEBUG + session.Close(); + return NULL; + } + + // Allocate memory for file + HBufC8* data = HBufC8::NewL( fileSize ); + TPtr8 des = data->Des(); + TInt readError = fileHandle.Read( des ); + if ( readError != KErrNone ) + { + #ifdef _DEBUG + RDebug::Printf("CSvgEngineImpl::FetchExternalData--fileHandle.Read error: %d\n", readError ); + #endif //_DEBUG + session.Close(); + delete data; + return NULL; + } + + // Successful + session.Close(); + return data; + } +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::SetAudioVolume( TInt aPercentage ); +// -------------------------------------------------------------------------- +void CSvgEngineImpl::SetAudioVolume( TInt aPercentage ) + { + + if ( !iSvgDocument ) + { + return; + } + // Locate all the active audio elements + RPointerArray lAudioElementList; + + iSvgDocument->FindAllElements( + (CSvgElementImpl* )iSvgDocument->RootElement(), + KSvgAudioElement, lAudioElementList ); + // Set the volume on each audio element + TInt lAudEleCnt = lAudioElementList.Count(); + for ( TInt lCurAudioEle = 0; lCurAudioEle < lAudEleCnt; lCurAudioEle++ ) + { + CSvgAudioElementImpl* lAudioElement = (CSvgAudioElementImpl*)lAudioElementList[ lCurAudioEle ]; + lAudioElement->SetVolume( aPercentage ); + } + lAudioElementList.Close(); + } + +// -------------------------------------------------------------------------- +// TBool CSvgEngineImpl::ReadyToRender() +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::ReadyToRender() + { + return iSvgDocument != NULL; + } + +// -------------------------------------------------------------------------- +// TBool CSvgEngineImpl::IsEndedWithCompleteTextTag( TDes &BufferPtr, +// TInt EndOffset) +// --------------------------------------------------------------------------- +TBool CSvgEngineImpl::IsEndedWithCompleteTextTag(TDes &aBufferPtr,TInt aEndOffset) + { + TChar KOpeningBrace = '<'; + TChar KSlash = '/'; + + // This function searches the buffer in reverse order from the end offset + // to check whether the last element had a complete text tag. + // eg. of complete text tags + // Hello + // + // eg. of an incomplete text tag + // + + TPtrC currentSelectionPtr = aBufferPtr.Left( aEndOffset ); + TInt OpeningBracePos = currentSelectionPtr.LocateReverse( KOpeningBrace ); + TInt SlashPos = currentSelectionPtr.LocateReverse( KSlash ); + TBool retVal = EFalse; + + // In case of a complete text tag the opening brace is one position behind + // slash. + if ( SlashPos == ( OpeningBracePos + 1 ) ) + { + retVal = ETrue; + } + + return retVal; + } + +// -------------------------------------------------------------------------- +// void CSvgEngineImpl::SaveSvgL( const TDesC& aFileName ) +// --------------------------------------------------------------------------- +void CSvgEngineImpl::SaveSvgL( const TDesC& aFileName ) + { + RFs lFs; + RFileWriteStream lStream; + TInt error ; + TChar KOpeningBrace = '<'; + TChar KSlash = '/'; + // Connect to File Server to write the changed content to a file + CleanupClosePushL(lFs); + User::LeaveIfError(lFs.Connect() ); + + TBool isOpened = EFalse; + error = lFs.IsFileOpen( aFileName, isOpened ) ; + // dont leave if file doesnt exist or there is no error + if(error!= KErrNone && error!=KErrNotFound) + { + //usually will come here with KErrNotFound + //since file wont exist + User::Leave(error); + } + + if ( isOpened ) + { + #ifdef _DEBUG + RDebug::Printf( "Cannot SaveSvgL: File is still opened: "); + RDebug::RawPrint( aFileName ); + #endif + CleanupStack::PopAndDestroy(1); + return; + } + + // Try to create the write stream using the file name + if ( lStream.Create( lFs, aFileName, EFileWrite ) != KErrNone ) + { + // If creation fails, file exists already, try to open the + // existing file + User::LeaveIfError( lStream.Open(lFs, aFileName, EFileWrite) ); + } + CleanupClosePushL(lStream); + + // Array to store list of all editable elements + RPointerArray lTextElementList; + + FindEditableElements( (CSvgElementImpl* )iSvgDocument->RootElement(), + lTextElementList ); + CleanupClosePushL(lTextElementList); + TInt index=0, startoffset = 0, endoffset = 0; + + // The content of the file is stored in the root node + HBufC* lBufferContent = ((CSvgSvgElementImpl* )iSvgDocument->RootElement())->iContent; + + + + // While there are remaining editable elements do + while(index < lTextElementList.Count()) + { + TBool EndedWithCompleteTextTag= true; + TInt OrgLength; + + if ( lTextElementList[index]->ElemID() == KSvgTextElement ) + { + // If the element is a element invoke element specific function + // to retrieve the offset and original length + endoffset = ((CSvgTextElementImpl *)lTextElementList[index])->iOffset; + OrgLength = ((CSvgTextElementImpl *)lTextElementList[index])->GetOrgLength(); + } + else + { + // If the element is a