--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/svgtopt/SVG/SVGImpl/src/SVGImageElementImpl.cpp Thu Jan 07 16:19:02 2010 +0200
@@ -0,0 +1,1543 @@
+/*
+* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: SVG Implementation source file
+ *
+*/
+
+
+#if !defined(__E32BASE_H__)
+#include <e32base.h>
+#endif
+
+#include "SVGImageElementImpl.h"
+#include "SVGDocumentImpl.h"
+#include "SVGEngineImpl.h"
+#include "SVGSchemaData.h"
+
+#include "GfxAffineTransform.h"
+
+#include <imcvcodc.h>
+
+#include <caf/caf.h>
+
+const TInt KErrNoAttributeSet = -1;
+#define KSVGWAITFORIMAGEDOWNLOAD 1
+
+#define PERIODIC_DELAY 300000
+#define PERIODIC_INTERVAL 1000000
+
+_LIT( KSvg, ".svg" );
+_LIT( KSvgb, ".svgb" );
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl* CSvgImageElementImpl::NewL( const TUint8 aElemID,
+ CSvgDocumentImpl* aDoc )
+ {
+ CSvgImageElementImpl* self = new ( ELeave )
+ CSvgImageElementImpl( aDoc );
+ CleanupStack::PushL( self );
+ self->ConstructL( aElemID, aDoc );
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl* CSvgImageElementImpl::NewLC( const TUint8 aElemID,
+ CSvgDocumentImpl* aDoc )
+ {
+ CSvgImageElementImpl* self = new ( ELeave )
+ CSvgImageElementImpl( aDoc );
+ CleanupStack::PushL( self );
+ self->ConstructL( aElemID,aDoc );
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::ConstructL( const TUint8 aElemID,
+ CSvgDocumentImpl* /* aDoc */ )
+ {
+ CSvgElementImpl::InitializeL( aElemID );
+
+
+ iUsedImage = EFalse;
+// iBitmap = new ( ELeave ) CFbsBitmap();
+ iReqAttrFlag=KSVG_IMAGE_ELEMFLAG;
+
+ iSvgStyleProperties = new(ELeave) RPointerArray<CCssValue>(KCSS_MAX_ATTR);
+ User::LeaveIfError( iSvgStyleProperties->Append( NULL ) );
+ iSvgStyleProperties->Remove( 0 );
+ iSvgTransformable = CSvgTransformableImpl::NewL();
+ iSvgUriReferenceImpl = CSvgUriReferenceImpl::NewL();
+
+ iBitmapLoadCalled = EFalse;
+
+ iImgRect.iHeight = TFloatFixPt(-1);
+ iImgRect.iWidth = TFloatFixPt(-1);
+
+ iIsBase64 = EFalse;
+ }
+
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::~CSvgImageElementImpl()
+ {
+ // Reset the notifiers first.
+ NotifyResetReference();
+
+ // Check whether there this element refers to an image element.
+ // This would be the case when use is used to refer to a parent
+ // image element.
+ if ( iRefElement )
+ {
+ iRefElement->RemoveImageElementListener( this );
+ iRefElement = NULL;
+ }
+
+ if ( iImageLoader )
+ {
+ delete iImageLoader;
+ iImageLoader = NULL;
+ }
+
+ if ( !iUsedImage )
+ {
+ delete iBitmap;
+ delete iMask;
+ }
+ if ( !iUsedImage && iPar )
+ {
+ if ( iPar )
+ {
+ delete iPar;
+ iPar = NULL;
+ }
+ }
+
+ if ( iImageData )
+ {
+ delete iImageData;
+ iImageData = NULL;
+ }
+
+ if ( iSvgUriReferenceImpl )
+ {
+ delete iSvgUriReferenceImpl;
+ iSvgUriReferenceImpl = NULL;
+ }
+
+
+ if ( iSvgStyleProperties )
+ {
+ iSvgStyleProperties->Close();
+ delete iSvgStyleProperties;
+ iSvgStyleProperties = NULL;
+ }
+
+ iImageElementListeners.Close();
+
+ if ( iSessionConnected )
+ {
+ iSession.Close();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::GetBBox( TGfxRectangle2D& aBbox )
+ {
+ iImgRect.GetBounds( GetCTM(), aBbox );
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox )
+ {
+ TGfxAffineTransform identityTx;
+ iImgRect.GetBounds( identityTx, aBbox );
+ }
+
+// *******************************************************
+// From SVG DOM
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::X()
+ {
+ return iImgRect.iX;
+ }
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::Y()
+ {
+ return iImgRect.iY;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::Width()
+ {
+ if (iImgRect.iWidth == TFloatFixPt(-1))
+ {
+ return TFloatFixPt(0);
+ }
+
+ return iImgRect.iWidth;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TFloatFixPt CSvgImageElementImpl::Height()
+ {
+ if (iImgRect.iHeight == TFloatFixPt(-1) )
+ {
+ return TFloatFixPt(0);
+ }
+
+ return iImgRect.iHeight;
+ }
+
+// *******************************************************
+// SVG Implementation
+
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetWidth( TFloatFixPt aWidth )
+ {
+ iRenderImage = !(aWidth <= TFloatFixPt(0));
+
+ iImgRect.iWidth = aWidth;
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetHeight( TFloatFixPt aHeight )
+ {
+ iRenderImage = !(aHeight <= TFloatFixPt(0));
+
+ iImgRect.iHeight = aHeight;
+
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetParL( const TDesC& aName )
+ {
+ iPar = aName.AllocL();
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+const TDesC& CSvgImageElementImpl::Par()
+ {
+ if ( iPar )
+ return *iPar;
+ else
+ return KNullDesC;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetUriL( const TDesC& aUri )
+ {
+ // Indicate that the Uri is set. This is used to decide whether
+ // to indicate an error if xlink:href attribute was not specified
+ // on the image element.
+ iIsUriSet = ETrue;
+ _LIT( KXlinkHref, "xlink:href" );
+ SetXlinkAttributeL(KXlinkHref, aUri);
+ CheckRequiredAttributes();
+
+ if ( Href().Length() == 0)
+ {
+ //empty URI string...do nothing
+ //JSR 226 tests start out with empty string
+ return;
+ }
+
+ //We have to be careful in this method searching the entire string
+ //because we can get the entire
+ //base64 encoded image coming through this call
+
+ // Verify xlink for JavaInterface
+ CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+ //if ( document && aUri.Length() > 0)
+ if ( document )
+ {
+ // Check for local URI (#uri)
+ //if ( aUri.Locate( '#' ) != KErrNotFound || aUri.Length() == 0)
+ if ( Href().Left(1) == _L("#") )
+ {
+ document->SetError( KErrNotFound, _L( "Usage of local URI in <image>: " ), aUri );
+ }
+ else
+ {
+ _LIT( KHttp, "http://" );
+ _LIT( KData, "data:");
+
+ if ( ( Href().Length() >= 7 ) && ( Href().Left( 7 ) == KHttp ) )
+ {
+ //using an http address for the image
+ return;
+ }
+ else if ( ( Href().Length() >= 5 ) && ( Href().Left( 5 ) == KData ) )
+ {
+ //this is a base 64 image
+ iIsBase64 = ETrue;
+ return;
+ }
+ else
+ {
+ _LIT( KJpgFile, ".jpg");
+ _LIT( KPngFile, ".png");
+ _LIT( KSvgFile, ".svg");
+
+ // Check for relative URI
+ if ( aUri.Locate( '/' ) == KErrNotFound)
+ {
+ //plain image used...but is this relative?!?
+ //does JSR 226 need an error thrown on this?
+ //i.e. image.jpg
+ if (aUri.Right(4) == KJpgFile)
+ {
+ //this is a plain image.jpg
+ return;
+ }
+ else if (aUri.Right(4) == KPngFile)
+ {
+ //this is a plain image.png file
+ return;
+ }
+ else if (aUri.Right(4) == KSvgFile)
+ {
+ //this is a filename.svg file
+ document->SetError(KErrNotFound, _L("Usage of SVG file in xlink-href:"), aUri);
+ }
+ return;
+ }
+ /*if ( aUri.Find( KFile ) != 1 || !TChar( aUri[0] ).IsAlpha() )
+ {
+ document->SetError( KErrNotFound, _L( "Usage of relative URI in <image>: " ), aUri );
+ }
+ else
+ {
+ //this is an absolute image
+ //i.e. c:/folder/image.jpg
+ }*/
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::LoadUriL()
+ {
+ if ( Href().Length() == 0 )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgImageElementImpl::LoadUriL()--iUri is NULL or empty.");
+ #endif
+ return;
+ }
+ iBitmapLoadCalled = ETrue;
+ iSessionConnected = EFalse;
+
+ // Cannot continue without SvgEngine instance or
+ // MSvgRequestObserver is not set
+
+ CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+ if ( document == NULL )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgImageElementImpl::LoadUriL--document handle null");
+ #endif
+ return;
+ }
+
+ // Request
+ if ( ( Href().Length() >= 4 && Href().Right( 4 ) == KSvg ) ||
+ ( Href().Length() >= 5 && Href().Right( 5 ) == KSvgb ) )
+ {
+ iIsSvgFile = ETrue;
+ }
+
+ // Don't call LoadUriL if LoadingListener exists and LoadingListener::WillAssignImageData returns ETrue
+ if ( document )
+ {
+ const RPointerArray<MSvgLoadingListener>* listeners = document->GetLoadingListeners();
+ if ( listeners && listeners->Count() > 0 )
+ {
+ if ( (*listeners)[0]->WillAssignImageData() )
+ {
+ (*listeners)[0]->ImageDataReference( Href() );
+ return;
+ }
+ }
+ }
+
+ // Embedded image
+ if ( ( Href().Length() >= 5 ) && ( Href().Left( 5 ) == _L( "data:" ) ) )
+ {
+ ProcessEncodedImageL( Href() );
+ return;
+ }
+
+ iBitmapOrgReady = EFalse;
+ iBitmapReady = EFalse;
+
+ CSvgEngineImpl* engine = document->Engine();
+ if ( engine == NULL || engine->iRequestObserver == NULL )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgImageElementImpl::LoadUriL--engine handle null");
+ #endif
+ return;
+ }
+
+ // Connect session
+ RFile fileHandle;
+ if ( iSession.Connect() != KErrNone )
+ {
+ return;
+ }
+ iSessionConnected = ETrue;
+ TInt status = engine->iRequestObserver->FetchImage( Href(), iSession, fileHandle );
+ if ( status == KErrNone )
+ {
+ // prevent division by zero (DrawL) when image fails to load
+ CFbsBitmap* aBitmap = new ( ELeave ) CFbsBitmap();
+ CleanupStack::PushL( aBitmap );
+ TInt lCreateErr = aBitmap->Create( TSize( 1, 1 ), EColor64K );
+ if ( lCreateErr != KErrNone )
+ {
+ // Error in creation, destroy the bitmap and return
+ CleanupStack::PopAndDestroy( aBitmap );
+ return;
+ }
+ // Ownership is about to be tranferred to Image Element
+ CleanupStack::Pop( aBitmap );
+ TInt lDecodeErr = StartImageDecoding( fileHandle, aBitmap, ETrue );
+ if ( lDecodeErr != KErrNone )
+ {
+ // No error Processing
+ }
+ }
+ else
+ {
+ iSession.Close();
+ iSessionConnected = EFalse;
+ }
+ }
+
+void CSvgImageElementImpl::PrepareImageFromSvgFile(const TDesC8& aImageData)
+ {
+ CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+ if ( !document )
+ {
+ return;
+ }
+
+ CSvgEngineImpl* engine = document->Engine();
+ if ( !engine )
+ {
+ return;
+ }
+ TSize bitmapSize( (TInt32)Width(), (TInt32)Height() );
+ if ( !iBitmap )
+ {
+ iBitmap = new CFbsBitmap();
+ }
+ if(!iMask)
+ {
+ iMask = new CFbsBitmap();
+ }
+ if(iMask)
+ {
+ iMask->Create( bitmapSize, EGray256);
+ }
+ // Can't use ELeave because this function can't leave
+ // Using ELeave but didn't handle (no trap or propagate to parents) causes more confusing.
+ // Check for NULL is good enough.
+ // Ignore CodeScanner error (Code Review Guide)
+ if (iBitmap)
+ {
+ iBitmap->Create( bitmapSize, EColor16MU );
+
+ TBool preserveRatio = !( iPar != NULL && *iPar == _L( "none" ) );
+ // RenderFileToBuffer if uri is a svg file
+ TInt err = engine->RenderFileToBuffer( aImageData, iBitmap,iMask, preserveRatio );
+ ImageLoadingCompleted(err);
+ }
+ iSession.Close();
+ }
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+
+void CSvgImageElementImpl::ProcessEncodedImageL( const TDesC& aXlinkHrefValue )
+ {
+ // find positions for ';' and ',' to determine encoding, mimetype
+ TInt startIndex = aXlinkHrefValue.Locate( ';' );
+ TInt endIndex = aXlinkHrefValue.Locate( ',' );
+
+ // mimetype is after 'data:' : xlink:href="data:image/png;base64,
+ // ignore mimetype extraction, decode will detect mimetype from decoded data.
+
+ if ( startIndex != KErrNotFound && endIndex != KErrNotFound &&
+ startIndex < endIndex )
+ {
+ // extract encoding type
+ TPtrC encoding( aXlinkHrefValue.Left( endIndex ).Right( endIndex - startIndex - 1 ) );
+ // handle Base64 encoding
+ _LIT( KEncodingBase64, "base64" );
+ if ( encoding == KEncodingBase64 )
+ {
+ // find index of first character after white-space
+ TInt index = endIndex + 1;
+ while ( index < aXlinkHrefValue.Length() && TChar( aXlinkHrefValue[index] ).IsSpace() )
+ index++;
+
+ // must be 8-bit
+ TInt length = aXlinkHrefValue.Length() - index;
+ HBufC8* encoded = HBufC8::NewLC( length );
+ encoded->Des().Copy( aXlinkHrefValue.Right( length ) );
+
+ // Assign to member variable to destroy after image is process.
+ iImageData = HBufC8::NewL( length );
+ TPtr8 decodedDes = iImageData->Des();
+
+ // decode
+ TImCodecB64 encodingBase64;
+ TInt decodeError = encodingBase64.Decode( *encoded, decodedDes );
+ CleanupStack::PopAndDestroy( encoded );
+
+ if ( decodeError == KErrNone )
+ {
+ // prevent division by zero (DrawL) when image fails to load
+ CFbsBitmap* lBitmap = new ( ELeave ) CFbsBitmap();
+ CleanupStack::PushL( lBitmap );
+ TInt lCreateErr = lBitmap->Create( TSize( 1, 1 ), EColor64K );
+ if ( lCreateErr != KErrNone )
+ {
+ // Error creating bitmap, delete bitmap and return
+ CleanupStack::PopAndDestroy( lBitmap );
+ return;
+ }
+ // Ownership of aBitmap is about to be transferred to image
+ // element
+ CleanupStack::Pop( lBitmap );
+ // If bitmap was already present, release it
+ if ( iBitmap )
+ {
+ delete iBitmap;
+ iBitmap = NULL;
+ }
+ iBitmap = lBitmap;
+ TInt lImgDecErr = StartImageDecoding( *iImageData,
+ ETrue ); // ETrue means Synchronous Loading
+ if ( lImgDecErr != KErrNone )
+ {
+ // No Error Processing
+ }
+ }
+ }
+ }
+ }
+
+// *******************************************************
+// From MXmlElement
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::SetAttributeL( const TDesC& aName,
+ const TDesC& aValue )
+ {
+ _LIT( KTmpUri, "xlink:href" );
+ _LIT( KTmpPreserveAspectRatio, "preserveAspectRatio" );
+
+ if ( this->SetXlinkAttributeL( aName, aValue ) )
+ {
+ if ( aName == KTmpUri )
+ {
+ SetUriL( aValue );
+ CheckRequiredAttributes();
+ }
+ return KErrNone;
+ }
+
+
+ CSvgElementImpl::SetAttributeL(aName,aValue);
+
+ if ( aName == KTmpPreserveAspectRatio )
+ {
+ SetParL( aValue );
+ }
+
+ return KErrNoAttributeSet;
+ }
+
+
+
+// From MXmlElementOpt
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::GetAttributeFloat( const TInt aNameId,
+ TFloatFixPt& aValue )
+ {
+ switch ( aNameId )
+ {
+ case KAtrX:
+ case KAtrRefX:
+ aValue = X();
+ break;
+ case KAtrY:
+ case KAtrRefY:
+ aValue = Y();
+ break;
+ case KAtrHeight:
+ aValue = Height();
+ break;
+ case KAtrWidth:
+ aValue = Width();
+ break;
+ default:
+ return CSvgElementImpl::GetAttributeFloat( aNameId, aValue );
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::SetAttributeFloatL( const TInt aNameId,
+ const TFloatFixPt aValue )
+ {
+ switch ( aNameId )
+ {
+ case KAtrX:
+ iImgRect.iX = aValue;
+ break;
+ case KAtrY:
+ iImgRect.iY = aValue;
+ break;
+
+ case KAtrHeight:
+ SetHeight( aValue );
+ CheckRequiredAttributes();
+ break;
+
+ case KAtrWidth:
+ SetWidth( aValue );
+ CheckRequiredAttributes();
+ break;
+
+ default:
+ return CSvgElementImpl::SetAttributeFloatL( aNameId, aValue );
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::SetAttributeDesL( const TInt aNameId,
+ const TDesC& aValue )
+ {
+ switch ( aNameId )
+ {
+ case KAtrXlinkhref:
+ SetUriL( aValue );
+ CheckRequiredAttributes();
+ break;
+ default:
+ return CSvgElementImpl::SetAttributeDesL( aNameId, aValue );
+ }
+ return KErrNone;
+ }
+
+void CSvgImageElementImpl::ImageLoadingCompleted( TInt aError )
+ {
+ iBitmapReady = aError != KErrCancel;
+ if ( aError == KErrNone )
+ {
+
+ PrepareImageWithMask();
+ iBitmapOrgReady = ETrue;
+ // Notify clones that the bitmap is ready.
+
+
+ NotifyImageDecoded();
+
+ // The redraw needs to be done once the image element is decoded,
+ // so that the image is rendered in place in the content.
+ // If the decoding is done asynchronously, the client does not know
+ // when the decoding was completed hence it cannot perform a redraw()
+ // In such a scenario, the image element itself triggers a redraw.
+
+ if(iImageLoader && !(iImageLoader->IsSynchronousLoading()))
+ {
+ CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+ if(document)
+ {
+ CSvgEngineImpl* engine =document->Engine();
+ if(engine)
+ {
+ engine->ImageLoadingCompleted(aError);
+ }
+ }
+ }
+ } // if ( aError == KErrNone )
+ CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+ if(document)
+ {
+ document->ImageLoadingCompleted(aError);
+ }
+
+
+
+
+ if ( iSessionConnected )
+ {
+ iSession.Close();
+ iSessionConnected = EFalse;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// void CSvgImageElementImpl::PrepareImageWithMask()
+// Combines mask information into main bitmap for use with OpenVG
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::PrepareImageWithMask()
+ {
+ if ( iBitmap && iMask )
+ {
+ TSize size = iMask->SizeInPixels();
+ // If size of bitmap and mask do not match, cannot process mask
+ if ( size != iBitmap->SizeInPixels() )
+ {
+ return;
+ }
+ iBitmap->LockHeap();
+ iMask->LockHeap();
+
+ TUint32* bitmapData = (TUint32*)iBitmap->DataAddress();
+ TUint8* maskData = (TUint8*)iMask->DataAddress();
+
+ TInt lBmpSLLen = CFbsBitmap::ScanLineLength( size.iWidth,
+ iBitmap->DisplayMode() );
+
+ TInt lMaskSLLen = CFbsBitmap::ScanLineLength( size.iWidth,
+ iMask->DisplayMode() );
+
+ TInt count = size.iWidth * size.iHeight;
+ TUint32* lBitmapCurPtr = bitmapData;
+ TUint8* lMaskCurPtr = maskData;
+
+ for ( TInt lIndex = 1; lIndex < count; lIndex++ )
+ {
+ // Converting from ARGB to RGBA8888
+ *lBitmapCurPtr = ( *lBitmapCurPtr & 0x00FFFFFF ) << 8 | *lMaskCurPtr;
+ // Check if one row is complete
+ if ( lIndex % size.iWidth == 0 )
+ {
+ // One row of pixels is complete. Now reposition the
+ // lBitmapCurPtr, lMaskCurPtr to point to beginning of new row.
+ // Current row is given by (index/widthMask)
+ //
+ // In order to get offset to first pixel, we need to
+ // perform following
+ // BasePtr + Current row * (row width in bytes)
+ lBitmapCurPtr =(TUint32*)((TUint8*)bitmapData + ( ( lIndex / size.iWidth )
+ * lBmpSLLen ));
+ lMaskCurPtr = maskData + ( ( lIndex / size.iWidth )
+ * lMaskSLLen );
+ }
+ else
+ {
+ // Still within the row, keep incrementing
+ lBitmapCurPtr++;
+ lMaskCurPtr++;
+ }
+ }
+ iMask->UnlockHeap();
+ iBitmap->UnlockHeap();
+ }
+ }
+
+// *******************************************************
+// From CSvgElementImpl
+
+// perform a deep clone of this object
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+MXmlElement* CSvgImageElementImpl::CloneL(MXmlElement* aParentElement)
+ {
+ CSvgImageElementImpl* newElement = CSvgImageElementImpl::NewL( this->ElemID(), ((CSvgDocumentImpl*)iOwnerDocument) );
+
+ CleanupStack::PushL(newElement);
+ newElement->iParentNode = aParentElement;
+ // copy everything over
+ this->CopyL(newElement);
+ CleanupStack::Pop();
+ // Add the cloned element to image decode notification list.
+ // This is done to ensure that the image is decoded only once.
+ AddImageElementListener( newElement );
+ newElement->SetReferenceElement( this );
+ return newElement;
+ }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+TBool CSvgImageElementImpl::DrawL( CGfx2dGc* aGc, CSvgElementImpl* aElement )
+ {
+ // Set Gc
+ this->DrawShapeL( aGc, aElement );
+
+ if ( iBitmap == NULL )
+ return ETrue;
+ TSize imageSize = iBitmap->SizeInPixels(); //.
+ if ( imageSize.iWidth == 0 || imageSize.iHeight == 0 )
+ return ETrue;
+
+ const TGfxAffineTransform& currentTM = GetCTM();
+
+ aGc->SetTransform( currentTM );
+
+ if ( iBitmapReady && iRenderImage && iBitmap )
+ {
+ aGc->DrawImage( iBitmap, iImgRect, iMask != NULL );
+ }
+ else if ( iBitmapOrgReady && iRenderImage )
+ {
+ aGc->SetForegroundColor( TGfxColor( 0xaaaaaa ) );
+ aGc->SetPaint( NULL );
+ aGc->DrawL( &iImgRect );
+ }
+ return ETrue;
+ }
+
+// *******************************************************
+// Private
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageElementImpl( CSvgDocumentImpl* aDoc ) :
+ iRenderImage ( ETrue ),
+ iIsUriSet( EFalse ),
+ iImageDecodingDone(EFalse),
+ iBitmapReady( EFalse )
+ {
+ SetOwnerDocument(aDoc);
+ iBitmap = NULL;
+ iMask = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// perform a deep copy of this object
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CopyL( CSvgImageElementImpl* aDestElement )
+ {
+ if(aDestElement)
+ {
+ // copy stuff from superclass
+ this->CSvgElementImpl::CopyL(aDestElement);
+
+ // copy items special to CSvgImageElementImpl
+ aDestElement->iUsedImage = ETrue; // this is not original image
+ delete aDestElement->iBitmap; // delete old
+ aDestElement->iBitmap = this->iBitmap; // borrow new
+ aDestElement->iImgRect = this->iImgRect;
+ aDestElement->iPar = this->iPar;
+ aDestElement->iBitmapOrgReady = ETrue;
+ aDestElement->iBitmapReady = ETrue;
+ aDestElement->iRenderImage = ETrue;
+ aDestElement->iIsBase64 = this->iIsBase64;
+
+ // copy the reference to idoc (CSvgDocumentImpl)
+ aDestElement->iOwnerDocument = this->iOwnerDocument;
+ }
+
+
+ }
+
+/********************* Helping Class **************************/
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil* CSvgImageElementImpl::CSvgImageLoaderUtil::NewL(
+ MSVGImageLoadingObserver* aObserver,
+ RFile& aFileHandle,
+ TBool aSyncLoading )
+ {
+ CSvgImageLoaderUtil* self = new ( ELeave ) CSvgImageLoaderUtil( );
+ CleanupStack::PushL( self );
+ self->ConstructL( aObserver, aFileHandle, aSyncLoading );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil* CSvgImageElementImpl::CSvgImageLoaderUtil::NewL(
+ MSVGImageLoadingObserver* aObserver,
+ const TDesC8& aEncodedData,
+ TBool aSyncLoading )
+ {
+ CSvgImageLoaderUtil* self = new ( ELeave ) CSvgImageLoaderUtil( );
+ CleanupStack::PushL( self );
+ self->ConstructL( aObserver, aEncodedData, aSyncLoading );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil::~CSvgImageLoaderUtil()
+ {
+ Cancel();
+ if(iImageDecoder)
+ {
+ delete iImageDecoder;
+ iImageDecoder = NULL;
+ }
+ if ( iActiveSchedulerWait )
+ {
+ delete iActiveSchedulerWait;
+ }
+ if(iImageByteData)
+ {
+ delete iImageByteData;
+ iImageByteData=NULL;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Set the display mode (color mode), the default value is EColor64K.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::SetDisplayMode( TDisplayMode aDisplayMode )
+ {
+ iDisplayMode = aDisplayMode;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns the FrameInfo of Image
+// ---------------------------------------------------------------------------
+TFrameInfo CSvgImageElementImpl::CSvgImageLoaderUtil::GetFrameInfo()
+ {
+ return iImageDecoder->FrameInfo();
+ }
+
+
+// ---------------------------------------------------------------------------
+// Request asynchronously for the image, sized to the image size.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::RequestForImageL( CFbsBitmap& aBitmap,
+ CFbsBitmap& aMask,
+ TBool aHasAlpha,
+ TFrameInfo aFrameInfo )
+ {
+ if ( iImageDecoder != NULL )
+ {
+ if ( aHasAlpha )
+ {
+ User::LeaveIfError( aMask.Create( aFrameInfo.iOverallSizeInPixels, EGray256 ) );
+ User::LeaveIfError( aBitmap.Create( aFrameInfo.iOverallSizeInPixels, EColor16MU ) );
+ iImageDecoder->Convert( &iStatus, aBitmap, aMask, 0 );
+ }
+ else
+ {
+ User::LeaveIfError( aBitmap.Create( aFrameInfo.iOverallSizeInPixels, EColor64K ) );
+ iImageDecoder->Convert( &iStatus, aBitmap, 0 );
+ }
+
+ SetActive();
+ if ( iActiveSchedulerWait )
+ {
+ iActiveSchedulerWait->Start();
+ }
+ }
+ else
+ {
+ iObserver->ImageLoadingCompleted( KErrNotFound );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Override method from CActive, called upon successful completion of request
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::RunL()
+ {
+ if ( iActiveSchedulerWait )
+ {
+ iActiveSchedulerWait->AsyncStop();
+ }
+ if ( iObserver )
+ {
+ iObserver->ImageLoadingCompleted( iStatus.Int() );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Override method from CActive, called upon a cancel of request
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::DoCancel()
+ {
+ if ( iImageDecoder != NULL )
+ {
+ iImageDecoder->Cancel();
+ }
+
+ // must delete decoder immediate or exception occurs in destructor.
+ delete iImageDecoder;
+ iImageDecoder = NULL;
+ iObserver->ImageLoadingCompleted( KErrCancel );
+ }
+
+// ---------------------------------------------------------------------------
+// Override method from CActive, called upon an error from request
+// ---------------------------------------------------------------------------
+TInt CSvgImageElementImpl::CSvgImageLoaderUtil::RunError( TInt aError )
+ {
+ // must delete decoder immediate or exception occurs in destructor.
+ delete iImageDecoder;
+ iImageDecoder = NULL;
+ iObserver->ImageLoadingCompleted( aError );
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl::CSvgImageLoaderUtil::CSvgImageLoaderUtil() : CActive( EPriorityNormal )
+ {
+ SetDisplayMode( EColor64K );
+ CActiveScheduler::Add( this );
+ }
+
+// ---------------------------------------------------------------------------
+// Second phase Construction
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::CSvgImageLoaderUtil::ConstructL(
+ MSVGImageLoadingObserver* aObserver,
+ RFile& aFileHandle,
+ TBool aSyncLoading )
+ {
+ iObserver = aObserver;
+ iIsSyncLoading=aSyncLoading;
+
+ // Reset to start of file
+ TInt zero = 0;
+ aFileHandle.Seek( ESeekStart, zero );
+
+ TInt fileSize = 0;
+ TInt sizeError = aFileHandle.Size( fileSize );
+ if ( sizeError != KErrNone )
+ {
+
+ return;
+ }
+
+
+ iImageByteData = HBufC8::New ( fileSize );
+
+ if (!iImageByteData)
+ {
+
+ return;
+ }
+
+ TPtr8 binaryBufferPtr = iImageByteData->Des();
+
+ // Read the image data into a buffer.
+ TInt readError = aFileHandle.Read(binaryBufferPtr, fileSize);
+ if ( readError != KErrNone )
+ {
+ delete iImageByteData;
+ iImageByteData = NULL;
+ return;
+ }
+ // Unused parameter
+ RFs session;
+ iImageDecoder = CImageDecoder::DataNewL( session, *iImageByteData, CImageDecoder::TOptions( CImageDecoder::EAllowGeneratedMask |
+ CImageDecoder::EOptionAlwaysThread ));
+ iImageDecoder->SetDecoderThreadPriority( EPriorityNormal );
+
+ if ( aSyncLoading )
+ {
+ iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait();
+ }
+ }
+
+void CSvgImageElementImpl::CSvgImageLoaderUtil::ConstructL( MSVGImageLoadingObserver* aObserver,
+ const TDesC8& aEncodedData,
+ TBool aSyncLoading )
+ {
+ iObserver = aObserver;
+ iIsSyncLoading=aSyncLoading;
+ // Unused parameter
+ RFs session;
+ iImageDecoder = CImageDecoder::DataNewL( session, aEncodedData, CImageDecoder::TOptions( CImageDecoder::EAllowGeneratedMask |
+ CImageDecoder::EOptionAlwaysThread ));
+ iImageDecoder->SetDecoderThreadPriority( EPriorityNormal );
+ if ( aSyncLoading )
+ {
+ iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait();
+ }
+ }
+
+TInt CSvgImageElementImpl::GetAttributeDes( const TInt aNameId,
+ TPtrC16& aValue )
+{
+ if(aNameId == KAtrPreserveAspectRatio)
+ {
+ aValue.Set( Par() );
+ return KErrNone;
+ }
+ // added for updation of Get/Set
+ if( aNameId == KAtrXlinkhref )
+ {
+ aValue.Set( Href() );
+ return KErrNone;
+ }
+ return CSvgElementImpl::GetAttributeDes( aNameId, aValue );
+
+}
+
+// MSvgImageDecodingRequester method
+TInt CSvgImageElementImpl::StartImageDecoding( const TDesC8& aImageData,
+ TBool aSyncLoading )
+ {
+ if ( iBitmap != NULL )
+ {
+
+ if( iIsSvgFile )
+ {
+ // SVG files are decoded by engine and do not follow the ImageDecoder Path
+ PrepareImageFromSvgFile(aImageData);
+ return KErrNone;
+ }
+ if( iImageDecodingDone )
+ {
+ CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+ if(document)
+ {
+ TInt incCnt = document->GetImageElementsCount() + 1;
+ document->SetImageElementsCount(incCnt);
+ }
+
+ }
+ else
+ {
+ iImageDecodingDone = ETrue;
+ }
+ // Check if the iImageLoader already exists for the ImageElement
+ TInt err = KErrNone;
+
+ if( iImageLoader == NULL )
+ {
+ TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this,
+ aImageData,
+ aSyncLoading )); // EFalse means Asynchronous decoding
+ }
+ else
+ {
+ // Cancel the currently active request if the request is pending.
+ if( iImageLoader)
+ {
+ delete iImageLoader;
+ iImageLoader = NULL;
+ }
+
+ TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this,
+ aImageData,
+ aSyncLoading )); // EFalse means Asynchronous decoding
+ }
+
+ if ( err != KErrNone || !iImageLoader )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgImageElementImpl::StartImageDecoding failed");
+ #endif
+ ImageLoadingCompleted(err);
+ return err;
+ }
+
+ TFrameInfo lFrameInfo( iImageLoader->GetFrameInfo() );
+ TBool lHasAlpha = (lFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
+
+ if( lHasAlpha )
+ {
+ if( iMask )
+ {
+ delete iMask;
+ iMask = NULL;
+ }
+
+ iMask = new (ELeave) CFbsBitmap();
+ }
+
+ TRAPD(err2, iImageLoader->RequestForImageL( *iBitmap, *iMask, lHasAlpha, lFrameInfo ));
+ if ( err2 != KErrNone )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgImageElementImpl::StartImageDecoding RequestForImageL() failed");
+ #endif
+ ImageLoadingCompleted(err2);
+ return err2;
+ }
+ }
+ return KErrNone;
+ }
+
+
+TInt CSvgImageElementImpl::StartImageDecoding( RFile& aImageFile,
+ CFbsBitmap* aBitmap,
+ TBool aSyncLoading )
+ {
+ if ( iBitmap )
+ {
+ // Destroy the existing bitmap
+ delete iBitmap;
+ }
+ // Take ownership of the bitmap
+ iBitmap = aBitmap;
+
+ if ( iBitmap != NULL )
+ {
+ if( iIsSvgFile )
+ {
+
+ TInt length;
+ aImageFile.Size(length);
+
+ HBufC8 *aImageData = HBufC8::NewL( length );
+ TPtr8 des = aImageData->Des();
+
+ TInt readError = aImageFile.Read( des );
+ if ( readError != KErrNone )
+ {
+ delete aImageData;
+ return KErrGeneral;
+ }
+ else
+ {
+ // SVG files are decoded by engine and do not follow the ImageDecoder Path
+ PrepareImageFromSvgFile(des);
+ return KErrNone;
+ }
+ }
+ if( iImageDecodingDone )
+ {
+ CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
+ if(document)
+ {
+ TInt incCnt = document->GetImageElementsCount() + 1;
+ document->SetImageElementsCount(incCnt);
+ }
+
+ }
+ else
+ {
+ iImageDecodingDone = ETrue;
+ }
+
+ TInt err = KErrNone;
+ // Check if the iImageLoader already exists for the ImageElement
+ if( iImageLoader == NULL )
+ {
+ TRAP( err, iImageLoader = CSvgImageLoaderUtil::NewL( this,
+ aImageFile,
+ aSyncLoading )); // EFalse means Asynchronous decoding
+ }
+ else
+ {
+ // Cancel the currently active request if the request is pending.
+ if( iImageLoader)
+ {
+ delete iImageLoader;
+ iImageLoader = NULL;
+ }
+
+ TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this,
+ aImageFile,
+ aSyncLoading )); // EFalse means Asynchronous decoding
+ }
+
+ if ( err != KErrNone || !iImageLoader )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgImageElementImpl::StartImageDecoding failed");
+ #endif
+ ImageLoadingCompleted(err);
+ return err;
+ }
+ // Get the Frame info and based on it create the iMask if required.
+ TFrameInfo lFrameInfo( iImageLoader->GetFrameInfo() );
+ TBool lHasAlpha = (lFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
+
+ if( lHasAlpha )
+ {
+ if( iMask )
+ {
+ delete iMask;
+ iMask = NULL;
+ }
+
+ iMask = new (ELeave) CFbsBitmap();
+ }
+
+
+ TRAPD(err2, iImageLoader->RequestForImageL( *iBitmap, *iMask, lHasAlpha, lFrameInfo ));
+
+ if ( err2 != KErrNone )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("CSvgImageElementImpl::StartImageDecoding RequestForImageL() failed");
+ #endif
+ ImageLoadingCompleted(err);
+ return err2;
+ }
+ }
+ return KErrNone;
+ }
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::SetReferenceElement
+// Informs the image element that it is referring to a particular image
+// element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::SetReferenceElement( CSvgImageElementImpl*
+ aImageElement )
+ {
+ iRefElement = aImageElement;
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::GetReferenceElement
+// Get Function for reference element
+// ---------------------------------------------------------------------------
+CSvgImageElementImpl* CSvgImageElementImpl::ReferenceElement()
+ {
+ return iRefElement;
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::AddImageElementListener
+// Adds an image element listener - used in the case of cloning of image
+// element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::AddImageElementListener(
+ MSvgImageElementListener* aListener )
+ {
+ if ( iImageElementListeners.Find( aListener ) != KErrNotFound )
+ {
+ return;
+ }
+ if ( iImageElementListeners.Append( aListener ) != KErrNone )
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("iImageElementListeners.Append failed");
+ #endif
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::RemoveImageElementListener
+// Removes an image element listener - used in the case of cloning of image
+// element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::RemoveImageElementListener(
+ MSvgImageElementListener* aListener )
+ {
+ TInt index = iImageElementListeners.Find( aListener );
+ if ( index == KErrNotFound )
+ {
+ return;
+ }
+ iImageElementListeners.Remove( index );
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::BitmapDecoded
+// This is the callback implementation for updating the decoded image
+// and mask from referenced image element.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::BitmapDecoded( CFbsBitmap* aBitmap,
+ CFbsBitmap* aMask )
+ {
+ // Save the pointers to the decoded bitmap in this element,
+ // this can be used in subsequent draw.
+ // Note: Both the bitmap and mask are not owned by this element.
+ // It is owned by the reference element.
+ iBitmap = aBitmap;
+ iMask = aMask;
+
+ iBitmapReady = iBitmap != NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::ResetReference
+// This is the callback implementation for resetting reference element
+// pointer
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::ResetReference()
+ {
+ // Stop referring to the reference element.
+ iRefElement = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::NotifyImageDecoded
+// Notify listeners that image has been decoded.
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::NotifyImageDecoded()
+ {
+ TInt imageEleListenersCnt = iImageElementListeners.Count();
+ for ( TInt i = 0; i < imageEleListenersCnt; i++ )
+ {
+ iImageElementListeners[i]->BitmapDecoded( iBitmap, iMask );
+ }
+}
+
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::ResetReference
+// Notify listeners to reset their reference element pointers
+// ---------------------------------------------------------------------------
+void CSvgImageElementImpl::NotifyResetReference()
+ {
+ TInt imageEleListenersCnt = iImageElementListeners.Count();
+ for ( TInt i = 0; i < imageEleListenersCnt; i++ )
+ {
+ iImageElementListeners[i]->ResetReference();
+ }
+}
+
+void CSvgImageElementImpl::Print( TBool aIsEncodeOn )
+{
+ if (!aIsEncodeOn)
+ {
+ #ifdef _DEBUG
+ RDebug::Printf("<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xlink:href=\"hmm\" \\>", (int)X(), (int)Y(), (int)Width(), (int)Height()/*, Href()*/);
+ #endif
+ }
+}
+
+CFbsBitmap* CSvgImageElementImpl::GetBitmap()
+ {
+ return iBitmap;
+ }
+
+void CSvgImageElementImpl::SetBitmap( CFbsBitmap* aBitmap )
+ {
+ if ( iBitmap )
+ {
+ delete iBitmap;
+ iBitmap = NULL;
+ }
+ iBitmap = aBitmap;
+ }
+
+void CSvgImageElementImpl::AssignImageData( HBufC8* aData )
+ {
+ if(iImageData)
+ {
+ delete iImageData;
+ iImageData = NULL;
+ }
+ iImageData = aData;
+ }
+
+TInt CSvgImageElementImpl::CheckRequiredAttributes()
+{
+ if ( !( iImgRect.iHeight >= TFloatFixPt(0) ) )
+ {
+ //need a height
+ iReqAttrFlag = KAtrHeight;
+ return iReqAttrFlag;
+ }
+
+ if ( !( iImgRect.iWidth >= TFloatFixPt(0)) )
+ {
+ iReqAttrFlag = KAtrWidth;
+ return iReqAttrFlag;
+ }
+
+
+ if ( !iIsUriSet )
+ {
+ iReqAttrFlag = KAtrXlinkhref;
+ return iReqAttrFlag;
+ }
+
+ iReqAttrFlag = 0;
+
+ // check if the diplay property is turned off programatically
+ if( WasTurnedOff() )
+ {
+ _LIT(KInline, "inline");
+ // turn it on. this means all the required attributes Are present and
+ // hence we can render it.
+ CSvgElementImpl::SetPropertyL(KCSS_ATTR_DISPLAY, KInline);
+ SetTurnOff( EFalse );
+ }
+
+ return 0;
+}
+// ---------------------------------------------------------------------------
+// CSvgImageElementImpl::IsSynchronousLoading
+// Returns whether the image decoding was synchronous or not
+// ---------------------------------------------------------------------------
+TBool CSvgImageElementImpl::CSvgImageLoaderUtil::IsSynchronousLoading()
+ {
+ return iIsSyncLoading;
+ }