Add support for "slim", which is "stem" + removal of some exports and checking of import details
For this to work, the static_dependencies.txt file needs to contain the augmented dependency information.
To help with this, it can now consume a mixture of both rom_content.csv lines and static_dependencies.txt lines: the
best way to update the information would be something like
(edit rom_content.csv to add "slim" to XXX.dll)
findstr /i "xxx.dll" rom_content.csv > slim.txt
findstr /i "xxx.dll" static_dependencies.txt >> slim.txt
perl ..\tools\static_dependencies.pl -u static_dependencies.txt slim.txt > new_dependencies.txt
This will notice the "slim" marking for xxx.dll, and record the detailed import and export lists for
xxx.dll and everything which links to it. The new information will look something like
sys\bin\xxx.dll /epoc32/release/armv5/urel/stem_xxx.dll exports=1-98.100-102:euser[100039e5].dll
sys\bin\yyy.dll /epoc32/release/armv5/urel/yyy.dll euser[100039e5].dll:xxx[102750c7].dll@2.4-5.77.104-106:scppnwdl.dll
sys\bin\zzz.dll /epoc32/release/armv5/urel/zzz.dll euser[100039e5].dll:xxx[102750c7].dll@23.25.74-77:scppnwdl.dll
Only executables for which there is a "slim" marking will have this level of detail.
The filtering script now does the detailed cross-checking of imports to exports for "slim" executables.
In this case, it will observe the stem_xxx.dll does not export ordinal 104, and so the filtering will include
deleting sys\bin\yyy.dll (xxx.dll Missing ordinal 104)
sys\bin\zzz.dll will be acceptable, because it only uses ordinals which are still present in stem_xxx.dll
/*
* 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 <e32base.h>
#endif
#include <utf.h>
#include <s32mem.h>
#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 </text>
const TInt KClosingTextTagLength = 7;
// Length of </textArea>
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,"</text>");
_LIT(KClosingTextAreaTag,"</textArea>");
_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<CSvgElementImpl> 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<MRect>& aBoundingBoxes,
RArray<TPtrC>& aTexts,
RArray<TInt>& 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<CSvgElementImpl> textElements;
iSvgDocument->FindAllElements( (CSvgElementImpl* )iSvgDocument->RootElement(),
KSvgTextElement, textElements );
// Himanshu: Find all animation elements
RPointerArray<CSvgElementImpl> 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<TRect>& aBoundingBoxes,
RArray<TPtrC>& aTexts,
RArray<TInt>& aElementIds,
TBool aCaseSensitive )
{
if ( iSvgDocument == NULL )
return;
// Find all text elements
RPointerArray<CSvgElementImpl> 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 <a> elements if first time
RPointerArray<CSvgElementImpl> 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<CSvgElementImpl> 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<CSvgElementImpl> 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<CSvgElementImpl> 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<CSvgElementImpl>& aElements,
// ---------------------------------------------------------------------------
void CSvgEngineImpl::NotifyMousePressed( RPointerArray<CSvgElementImpl>& 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<CSvgElementImpl>& aElements,
// ---------------------------------------------------------------------------
void CSvgEngineImpl::NotifyMouseReleased( RPointerArray<CSvgElementImpl>& 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<CSvgElementImpl>& aElements,
// ---------------------------------------------------------------------------
void CSvgEngineImpl::NotifyMouseEntered( RPointerArray<CSvgElementImpl>& 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<CSvgElementImpl>& aElements,
// ---------------------------------------------------------------------------
void CSvgEngineImpl::NotifyMouseExited( RPointerArray<CSvgElementImpl>& 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<CSvgElementImpl>& aElements,
// ---------------------------------------------------------------------------
void CSvgEngineImpl::NotifyMouseMoved( RPointerArray<CSvgElementImpl>& 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<CSvgElementImpl>& aElements, TInt aX, TInt aY )
// ---------------------------------------------------------------------------
void CSvgEngineImpl::GetViewableElementsAtPoint( CSvgDocumentImpl* aSvgDocument, RPointerArray<CSvgElementImpl>& 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<CSvgElementImpl> 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<CSvgElementImpl>& 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<CSvgElementImpl>& 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 0
if ( !iSvgDocument )
{
return;
}
// Locate all the active audio elements
RPointerArray<CSvgElementImpl> 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();
#endif
}
// --------------------------------------------------------------------------
// 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
// <text>Hello</text>
// <text></text>
// eg. of an incomplete text tag
// <text />
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<CSvgElementImpl> 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 <svg> 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 <text> 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 <textArea> element invoke element specific function
// to retrieve the offset and original length
endoffset = ((CSvgTextAreaElementImpl *)lTextElementList[index])->iOffset;
OrgLength = ((CSvgTextAreaElementImpl *)lTextElementList[index])->GetOrgLength();
}
// These are the cases which have to be processed
// a. Text Element: No Closing Tag: <text ... />
// b. Text Element: No CData : <text ...></text>
// c. Text Element: CData : <text ...>Sample Text</text>
// d. TextArea Element: No Closing Tag: <textArea ... />
// e. TextArea Element: No CData: <textArea ...></textArea>
// f. TextArea Element: CData: <textArea ...>Sample TextArea</textArea>
// -> for a,b,d,e the endoffset represents the offset after the closing braces.
// for e.g. <text ... />
// ^
// <text></text>
// ^
// -> for c,f the EndOffset represents the offset to the first character in
// content.
// <text>Hello</text>
//
// ^
if(!OrgLength)
{
//case a,b,d,e
TPtr BufferPtr=lBufferContent->Des();
EndedWithCompleteTextTag = IsEndedWithCompleteTextTag(BufferPtr,endoffset);
if ( EndedWithCompleteTextTag )
{
// case b,e
if(endoffset < startoffset)
{
User::Leave(KErrNotFound);
}
TPtrC lPtrtoPresentText = lBufferContent->Mid( startoffset, ( endoffset - startoffset ) );
//end offset modified ot point to <text></text>
// ^
endoffset = startoffset + lPtrtoPresentText.LocateReverse( KOpeningBrace );
}
else
{
//case a,d
if(endoffset < startoffset)
{
User::Leave(KErrNotFound);
}
TPtrC lPtrtoPresentText = lBufferContent->Mid( startoffset, ( endoffset - startoffset ) );
endoffset = startoffset + lPtrtoPresentText.LocateReverse( KSlash );
//end offset modified ot point to <text/>
// ^
}
}
if(endoffset < startoffset)
{
User::Leave(KErrNotFound);
}
TPtrC lPtrtoWrBuffer = lBufferContent->Mid( startoffset, ( endoffset - startoffset ) );
TInt lWrBufLength = lPtrtoWrBuffer .Length();
User::LeaveIfError(WriteToStream(lStream,lPtrtoWrBuffer));
// If it was a text element ...
if ( lTextElementList[index]->ElemID() == KSvgTextElement )
{
HBufC *lBufTextContent= NULL;
//make startoffset point to opening tag '<' or '/' in case of a,d
TPtrC lPtrtoTextContent= ( (CSvgTextElementImpl* ) lTextElementList[ index ] )->GetText();
startoffset = endoffset + ( (CSvgTextElementImpl* ) lTextElementList[ index ] )->iOrgLength;
lBufTextContent = TextTagProcessingL(&lPtrtoTextContent,
startoffset,OrgLength,EndedWithCompleteTextTag);
CleanupStack::PushL(lBufTextContent);
TPtr lTempPtr(lBufTextContent->Des());
lPtrtoTextContent.Set(lTempPtr);
User::LeaveIfError(WriteToStream(lStream,lPtrtoTextContent));
CleanupStack::PopAndDestroy(lBufTextContent);
}
else
{
HBufC *lBufTextAreaContent= NULL;
HBufC* lBufPresentText = NULL;
TInt textlength = ((CSvgTextAreaElementImpl *)lTextElementList[index])->GetLength();
lBufTextAreaContent = HBufC::NewLC( textlength );
TPtr lPtrtoGetTextAreaContent = lBufTextAreaContent->Des();
((CSvgTextAreaElementImpl *)lTextElementList[index])->GetText( lPtrtoGetTextAreaContent );
TPtrC lPtrtoTextAreaContent=lPtrtoGetTextAreaContent;
startoffset = endoffset + ((CSvgTextAreaElementImpl *)lTextElementList[index])->iOrgLength;
lBufPresentText = TextAreaTagProcessingL(&lPtrtoTextAreaContent,startoffset,OrgLength,EndedWithCompleteTextTag);
CleanupStack::PushL(lBufPresentText);
TPtr lTempPtr(lBufPresentText->Des());
lPtrtoTextAreaContent.Set(lTempPtr);
User::LeaveIfError(WriteToStream(lStream,lPtrtoTextAreaContent));
CleanupStack::PopAndDestroy(lBufPresentText);
CleanupStack::PopAndDestroy(lBufTextAreaContent);
}
index++;
}
// Done using the list, close the list to avoid a memory leak
CleanupStack::PopAndDestroy(&lTextElementList);
// After processing all the editable text elements, are there any characters in the buffer
if( startoffset < lBufferContent->Length() )
{
TPtrC lPtrtoRemainText = lBufferContent->Mid(startoffset,(lBufferContent->Length()-startoffset));
User::LeaveIfError(WriteToStream(lStream,lPtrtoRemainText));
}
// Close the stream
CleanupStack::PopAndDestroy(&lStream);
// Close the file server session
CleanupStack::PopAndDestroy(&lFs);
}
//-----------------------------------------------------------------------------
//Function to process the text and add tags at the end
//HBufC* CSvgEngineImpl::TextTagProcessing(TPtr* aCData, TInt aStartOffset, TInt aOrgLength,
// TBool aEndingWithTag)
//-----------------------------------------------------------------------------
HBufC* CSvgEngineImpl::TextTagProcessingL(TPtrC* aCData,
TInt &aStartOffset, TInt aOrgLength,TBool aEndingWithTag)
{
HBufC * lTextContentBuffer = NULL;
TPtrC lPtrToTextContent(*aCData) ;
//Ending with complete text tag and original length is 0
if( aEndingWithTag && aOrgLength == 0 )
{//case b
lTextContentBuffer = HBufC::NewLC(aCData->Length()
+ KClosingTextTagLength );
TPtr lPtrToTempBuf(lTextContentBuffer->Des());//point to buffer
lPtrToTempBuf.Append(*aCData);//append cdata
lPtrToTempBuf.Append(KClosingTextTag);//append closing text tag
aStartOffset += KClosingTextTagLength;
}
else if( !aEndingWithTag && aOrgLength == 0 )
{//case a
lTextContentBuffer = HBufC::NewLC(aCData->Length()
+ KClosingTextTagLength
+ KClosingBracesLength );
TPtr lPtrToTempBuf(lTextContentBuffer->Des());//point to buffer
lPtrToTempBuf.Append(KClosingBraces);
lPtrToTempBuf.Append(*aCData);//append cdata
lPtrToTempBuf.Append(KClosingTextTag);//append closing text tag
aStartOffset += 2;// the length of /> which is 2 characters.
}
else if(aEndingWithTag && aOrgLength!= 0)
{
lTextContentBuffer = HBufC::NewLC(aCData->Length()
+ KClosingTextTagLength );
TPtr lPtrToTempBuf(lTextContentBuffer->Des());//point to buffer
lPtrToTempBuf.Append(*aCData);//append cdata
lPtrToTempBuf.Append(KClosingTextTag);//append closing text tag
aStartOffset += KClosingTextTagLength ;
}
else
{
//i.e !aEndingWithTag && OrgLength!=0
//this case should never occur
//becoz there is no possibility of
//the quoted kind of text content definition in xml as shown below
//"<text /> this is a text content"
}
// Pop the buffer from the cleanup stack as ownership is transferred
// to caller
CleanupStack::Pop(lTextContentBuffer);
return lTextContentBuffer;
}
//-----------------------------------------------------------------------------
//Function to process the text and add tags at the end
//HBufC* CSvgEngineImpl::TextAreaTagProcessing(TPtr* aCData, TInt aStartOffset, TInt aOrgLength,
// TBool aEndingWithTag)
//-----------------------------------------------------------------------------
HBufC* CSvgEngineImpl::TextAreaTagProcessingL(TPtrC* aCData, TInt &aStartOffset, TInt aOrgLength,
TBool aEndingWithTag)
{
HBufC * lTextAreaContentBuffer = NULL;
TPtrC lPtrToTextAreaContent(*aCData) ;
//Ending with complete text tag and original length is 0
if( aEndingWithTag && aOrgLength == 0 )
{//case e
lTextAreaContentBuffer = HBufC::NewLC(aCData->Length()
+ KClosingTextAreaTagLength);
TPtr lPtrToTempBuf(lTextAreaContentBuffer->Des());//point to buffer
lPtrToTempBuf.Append(*aCData);//append cdata
lPtrToTempBuf.Append(KClosingTextAreaTag);//append closing text tag
aStartOffset += KClosingTextAreaTagLength;
}
else if( !aEndingWithTag && aOrgLength == 0 )
{//case d
lTextAreaContentBuffer = HBufC::NewLC(aCData->Length()
+ KClosingBracesLength
+ KClosingTextAreaTagLength );
TPtr lPtrToTempBuf(lTextAreaContentBuffer->Des());//point to buffer
lPtrToTempBuf.Append(KClosingBraces);
lPtrToTempBuf.Append(*aCData);//append cdata
lPtrToTempBuf.Append(KClosingTextAreaTag);//append closing text tag
aStartOffset += 2;// the length of /> which is 2 characters.
}
else if(aEndingWithTag && aOrgLength!= 0)
{//case f
lTextAreaContentBuffer = HBufC::NewLC(aCData->Length()
+ KClosingTextAreaTagLength );
TPtr lPtrToTempBuf(lTextAreaContentBuffer->Des());//point to buffer
lPtrToTempBuf.Append(*aCData);//append cdata
lPtrToTempBuf.Append(KClosingTextAreaTag);//append closing text tag
aStartOffset += KClosingTextAreaTagLength;
}
else
{
//i.e !aEndingWithTag && OrgLength!=0
//this case should never occur
//becoz there is no possibility of
//the quoted kind of text content definition in xml as shown below
//"<textArea /> this is a text content"
}
// Pop the buffer from the cleanup stack as ownership is transferred
// to caller
CleanupStack::Pop(lTextAreaContentBuffer);
return lTextAreaContentBuffer;
}
//-----------------------------------------------------------------------------
//Function to Write the buffer to the stream.
//In SaveSVGL while editing text - used to write partial buffers into the stream.
//TInt CSvgEngineImpl::WriteToStream(RFileWriteStream* aStream,TPtrC aWriteBuffer)
//-----------------------------------------------------------------------------
TInt CSvgEngineImpl::WriteToStream(RFileWriteStream &aStream,TPtrC aWriteBuffer)
{
// Create a small output buffer
TBuf8<KMaxConversionChars> outputBuffer;
for(;;) // conversion loop
{
// Start conversion. When the output buffer is full, return the
// number of characters that were not converted
const TInt returnValue = CnvUtfConverter::ConvertFromUnicodeToUtf8(
outputBuffer, // Destination
aWriteBuffer ); // Source
// check to see that the descriptor isn’t corrupt - return with
// err if it is
if ( returnValue == CnvUtfConverter::EErrorIllFormedInput )
{
return( KErrCorrupt );
}
else
{
if ( returnValue < 0 ) // future-proof against "TError" expanding
{
return( KErrGeneral );
}
}
// Store the converted contents of the output buffer into the stream
TRAPD( err1, aStream.WriteL( outputBuffer ) );
if ( err1 )
{
#ifdef _DEBUG
RDebug::Printf("CSvgEngineImpl::WriteToStream error trapped=%d", err1);
return err1;
#endif
}
// Finish conversion if there are no unconverted characters in the
// remainder buffer
if ( returnValue == 0 )
{
break;
}
// Remove the converted source text from the remainder buffer.
// The remainder buffer is then fed back into loop
aWriteBuffer.Set( aWriteBuffer.Right( returnValue ));
}
return KErrNone;
}
// --------------------------------------------------------------------------
// void CSvgEngineImpl::FindEditableElements( CSvgElementImpl* aStartElement,
// ---------------------------------------------------------------------------
void CSvgEngineImpl::FindEditableElements( CSvgElementImpl* aStartElement,
RPointerArray<CSvgElementImpl>& aList )
{
if ( aStartElement == NULL )
{
return;
}
CSvgElementImpl* child = (CSvgElementImpl*)aStartElement->FirstChild();
while ( child != NULL )
{
// add to list if child is found
if ( child->ElemID() == KSvgTextElement || child->ElemID() == KSvgTextAreaElement )
aList.Append( child );
// find in grandchildren if element is not a textArea
if ( child->ElemID() != KSvgTextAreaElement )
{
FindEditableElements( child, aList );
}
child = (CSvgElementImpl*)child->NextSibling();
}
}
TBool CSvgEngineImpl::IsSVGEnginePaused()
{
return (iSvgEngineState == ESVGEnginePaused );
}
// --------------------------------------------------------------------------
// void CSvgEngineImpl::ResetContext()
// ---------------------------------------------------------------------------
void CSvgEngineImpl::ResetContext()
{
if( iGfxContext )
{
iGfxContext->DestroyContext();
}
}
void CSvgEngineImpl::SetBitmapHeader(const TDesC* aHeaderData)
{
if (iGfxContext)
{
((CGfx2dGcOpenVG *)iGfxContext)->SetBitmapHeader(aHeaderData);
}
}
//NGA
// ---------------------------------------------------------------------------
// SetGdiContext File
// ---------------------------------------------------------------------------
void CSvgEngineImpl::SetGdiContextL(CFbsBitmap* aCurrentBitmap, CFbsBitmap* aMask,TSize aCurrentBitmapSize,TDisplayMode aRenderDspMode,TDisplayMode aMaskDspMode)
{
// Handle for both Non-NULL and NULL parameter
iFrameBufferSize = aCurrentBitmapSize;
iRenderDspMode = aRenderDspMode;
iMaskDspMode = aMaskDspMode;
iFrameBuffer = aCurrentBitmap;
iMask = aMask;
if ( aCurrentBitmapSize.iWidth > 0 && aCurrentBitmapSize.iHeight > 0 )
{
if ( !iGfxContext )
{
iGfxContext = CGfx2dGcOpenVG::NewL( aCurrentBitmapSize, iBitmapFontSpec, iSvgBitmapFontProvider,1 );
}
else
{
iGfxContext->ChangeBufferSizeL( aCurrentBitmapSize );
}
}
else if ( iGfxContext )
{
iGfxContext->ChangeBufferSizeL( TSize( 1, 1 ) );
}
}
const TPtrC8 CSvgEngineImpl::TLVEncodedData() const
{
return (iGfxContext->TLVEncodedData());
}