svgtopt/SVG/SVGImpl/src/SVGImageElementImpl.cpp
changeset 46 88edb906c587
child 27 2cc5318a4e7d
equal deleted inserted replaced
-1:000000000000 46:88edb906c587
       
     1 /*
       
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  SVG Implementation source file
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #if !defined(__E32BASE_H__)
       
    20 #include <e32base.h>
       
    21 #endif
       
    22 
       
    23 #include "SVGImageElementImpl.h"
       
    24 #include "SVGDocumentImpl.h"
       
    25 #include "SVGEngineImpl.h"
       
    26 #include "SVGSchemaData.h"
       
    27 
       
    28 #include "GfxAffineTransform.h"
       
    29 
       
    30 #include <imcvcodc.h>
       
    31 
       
    32 #include <caf/caf.h>
       
    33 
       
    34 const TInt  KErrNoAttributeSet  = -1;
       
    35 #define KSVGWAITFORIMAGEDOWNLOAD 1
       
    36 
       
    37 #define PERIODIC_DELAY    300000
       
    38 #define PERIODIC_INTERVAL 1000000
       
    39 
       
    40 _LIT( KSvg,  ".svg" );
       
    41 _LIT( KSvgb, ".svgb" );
       
    42 
       
    43 
       
    44 
       
    45 // ---------------------------------------------------------------------------
       
    46 //
       
    47 // ---------------------------------------------------------------------------
       
    48 CSvgImageElementImpl* CSvgImageElementImpl::NewL(  const TUint8 aElemID,
       
    49                                                   CSvgDocumentImpl* aDoc )
       
    50     {
       
    51     CSvgImageElementImpl*   self    = new ( ELeave )
       
    52                                       CSvgImageElementImpl( aDoc );
       
    53     CleanupStack::PushL( self );
       
    54     self->ConstructL(  aElemID, aDoc );
       
    55     CleanupStack::Pop();
       
    56 
       
    57     return self;
       
    58     }
       
    59 
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 // ---------------------------------------------------------------------------
       
    63 CSvgImageElementImpl* CSvgImageElementImpl::NewLC(  const TUint8 aElemID,
       
    64                                                    CSvgDocumentImpl* aDoc )
       
    65     {
       
    66     CSvgImageElementImpl*   self    = new ( ELeave )
       
    67                                       CSvgImageElementImpl( aDoc );
       
    68     CleanupStack::PushL( self );
       
    69     self->ConstructL(  aElemID,aDoc );
       
    70 
       
    71     return self;
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 //
       
    76 // ---------------------------------------------------------------------------
       
    77 void CSvgImageElementImpl::ConstructL(  const TUint8 aElemID,
       
    78                                        CSvgDocumentImpl* /* aDoc */ )
       
    79     {
       
    80     CSvgElementImpl::InitializeL(  aElemID );
       
    81 
       
    82 
       
    83     iUsedImage = EFalse;
       
    84 //    iBitmap = new ( ELeave ) CFbsBitmap();
       
    85     iReqAttrFlag=KSVG_IMAGE_ELEMFLAG;
       
    86 
       
    87     iSvgStyleProperties = new(ELeave) RPointerArray<CCssValue>(KCSS_MAX_ATTR);
       
    88     User::LeaveIfError( iSvgStyleProperties->Append( NULL ) );
       
    89     iSvgStyleProperties->Remove( 0 );
       
    90     iSvgTransformable = CSvgTransformableImpl::NewL();
       
    91     iSvgUriReferenceImpl = CSvgUriReferenceImpl::NewL();
       
    92 
       
    93     iBitmapLoadCalled = EFalse;
       
    94 
       
    95     iImgRect.iHeight = TFloatFixPt(-1);
       
    96     iImgRect.iWidth = TFloatFixPt(-1);
       
    97 
       
    98     iIsBase64 = EFalse;
       
    99     }
       
   100 
       
   101 
       
   102 
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 // ---------------------------------------------------------------------------
       
   106 CSvgImageElementImpl::~CSvgImageElementImpl()
       
   107     {
       
   108     // Reset the notifiers first.
       
   109     NotifyResetReference();
       
   110 
       
   111     // Check whether there this element refers to an image element.
       
   112     // This would be the case when use is used to refer to a parent 
       
   113     // image element.
       
   114     if ( iRefElement )
       
   115         {
       
   116         iRefElement->RemoveImageElementListener( this );
       
   117         iRefElement = NULL;
       
   118         }
       
   119         
       
   120     if ( iImageLoader )
       
   121         {
       
   122         delete iImageLoader;
       
   123         iImageLoader = NULL;
       
   124         }
       
   125 
       
   126     if ( !iUsedImage )
       
   127         {
       
   128         delete iBitmap;
       
   129         delete iMask;
       
   130         }
       
   131     if ( !iUsedImage && iPar )
       
   132         {
       
   133         if ( iPar )
       
   134             {
       
   135             delete iPar;
       
   136             iPar = NULL;
       
   137             }
       
   138         }
       
   139 
       
   140     if ( iImageData )
       
   141         {
       
   142         delete iImageData;
       
   143         iImageData = NULL;
       
   144         }
       
   145 
       
   146     if ( iSvgUriReferenceImpl )
       
   147         {
       
   148         delete iSvgUriReferenceImpl;
       
   149         iSvgUriReferenceImpl = NULL;
       
   150         }
       
   151 
       
   152 
       
   153     if ( iSvgStyleProperties )
       
   154         {
       
   155         iSvgStyleProperties->Close();
       
   156         delete iSvgStyleProperties;
       
   157         iSvgStyleProperties = NULL;
       
   158         }
       
   159 
       
   160     iImageElementListeners.Close();
       
   161 
       
   162     if ( iSessionConnected )
       
   163         {
       
   164         iSession.Close();
       
   165         }
       
   166     }
       
   167 
       
   168 // ---------------------------------------------------------------------------
       
   169 //
       
   170 // ---------------------------------------------------------------------------
       
   171 void CSvgImageElementImpl::GetBBox( TGfxRectangle2D& aBbox )
       
   172     {
       
   173     iImgRect.GetBounds( GetCTM(), aBbox );
       
   174     }
       
   175 
       
   176 // ---------------------------------------------------------------------------
       
   177 //
       
   178 // ---------------------------------------------------------------------------
       
   179 void CSvgImageElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox )
       
   180     {
       
   181     TGfxAffineTransform identityTx;
       
   182     iImgRect.GetBounds( identityTx, aBbox );
       
   183     }
       
   184 
       
   185 // *******************************************************
       
   186 // From SVG DOM
       
   187 
       
   188 // ---------------------------------------------------------------------------
       
   189 //
       
   190 // ---------------------------------------------------------------------------
       
   191 TFloatFixPt CSvgImageElementImpl::X()
       
   192     {
       
   193     return iImgRect.iX;
       
   194     }
       
   195 
       
   196 
       
   197 // ---------------------------------------------------------------------------
       
   198 //
       
   199 // ---------------------------------------------------------------------------
       
   200 TFloatFixPt CSvgImageElementImpl::Y()
       
   201     {
       
   202     return iImgRect.iY;
       
   203     }
       
   204 
       
   205 // ---------------------------------------------------------------------------
       
   206 //
       
   207 // ---------------------------------------------------------------------------
       
   208 TFloatFixPt CSvgImageElementImpl::Width()
       
   209     {
       
   210     	if (iImgRect.iWidth == TFloatFixPt(-1))
       
   211     	{
       
   212     		return TFloatFixPt(0);
       
   213     	}
       
   214 
       
   215     	return iImgRect.iWidth;
       
   216     }
       
   217 
       
   218 // ---------------------------------------------------------------------------
       
   219 //
       
   220 // ---------------------------------------------------------------------------
       
   221 TFloatFixPt CSvgImageElementImpl::Height()
       
   222     {
       
   223     	if (iImgRect.iHeight == TFloatFixPt(-1) )
       
   224     	{
       
   225     		return TFloatFixPt(0);
       
   226     	}
       
   227 
       
   228     	return iImgRect.iHeight;
       
   229     }
       
   230 
       
   231 // *******************************************************
       
   232 // SVG Implementation
       
   233 
       
   234 
       
   235 // ---------------------------------------------------------------------------
       
   236 //
       
   237 // ---------------------------------------------------------------------------
       
   238 void CSvgImageElementImpl::SetWidth( TFloatFixPt aWidth )
       
   239     {
       
   240     iRenderImage = !(aWidth <= TFloatFixPt(0));
       
   241     
       
   242     iImgRect.iWidth = aWidth;
       
   243 
       
   244     }
       
   245 
       
   246 // ---------------------------------------------------------------------------
       
   247 //
       
   248 // ---------------------------------------------------------------------------
       
   249 void CSvgImageElementImpl::SetHeight( TFloatFixPt aHeight )
       
   250     {
       
   251     iRenderImage = !(aHeight <= TFloatFixPt(0));
       
   252     
       
   253     iImgRect.iHeight = aHeight;
       
   254     
       
   255     }
       
   256 
       
   257 // ---------------------------------------------------------------------------
       
   258 //
       
   259 // ---------------------------------------------------------------------------
       
   260 void CSvgImageElementImpl::SetParL( const TDesC& aName )
       
   261     {
       
   262     iPar = aName.AllocL();
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 //
       
   267 // ---------------------------------------------------------------------------
       
   268 const TDesC& CSvgImageElementImpl::Par()
       
   269     {
       
   270     if ( iPar )
       
   271         return *iPar;
       
   272     else
       
   273         return KNullDesC;
       
   274     }
       
   275 
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 // ---------------------------------------------------------------------------
       
   279 void CSvgImageElementImpl::SetUriL( const TDesC& aUri )
       
   280     {
       
   281     // Indicate that the Uri is set. This is used to decide whether 
       
   282     // to indicate an error if xlink:href attribute was not specified
       
   283     // on the image element.
       
   284     iIsUriSet = ETrue;
       
   285     _LIT( KXlinkHref, "xlink:href" );
       
   286     SetXlinkAttributeL(KXlinkHref, aUri);
       
   287     CheckRequiredAttributes();
       
   288 
       
   289 	if ( Href().Length() == 0)
       
   290 	{
       
   291 		//empty URI string...do nothing
       
   292 		//JSR 226 tests start out with empty string
       
   293 		return;
       
   294 	}
       
   295 
       
   296 	//We have to be careful in this method searching the entire string
       
   297 	//because we can get the entire
       
   298 	//base64 encoded image coming through this call
       
   299 
       
   300     // Verify xlink for JavaInterface
       
   301     CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
       
   302     //if ( document && aUri.Length() > 0)
       
   303     if ( document )
       
   304         {
       
   305         // Check for local URI (#uri)
       
   306         //if ( aUri.Locate( '#' ) != KErrNotFound || aUri.Length() == 0)
       
   307           if ( Href().Left(1) == _L("#") )
       
   308             {
       
   309             document->SetError( KErrNotFound, _L( "Usage of local URI in <image>: " ), aUri );
       
   310             }
       
   311           else
       
   312             {
       
   313             _LIT( KHttp, "http://" );
       
   314             _LIT( KData, "data:");
       
   315 
       
   316             if ( ( Href().Length() >= 7 ) && ( Href().Left( 7 ) == KHttp ) )
       
   317                 {
       
   318                 //using an http address for the image
       
   319                 return;
       
   320                 }
       
   321             else if ( ( Href().Length() >= 5 ) && ( Href().Left( 5 ) == KData ) )
       
   322             	{
       
   323             	//this is a base 64 image
       
   324             	iIsBase64 = ETrue;
       
   325             	return;
       
   326             	}
       
   327             else
       
   328                 {
       
   329                 _LIT( KJpgFile, ".jpg");
       
   330                 _LIT( KPngFile, ".png");
       
   331                 _LIT( KSvgFile, ".svg");
       
   332 
       
   333                 // Check for relative URI
       
   334           		if ( aUri.Locate( '/' ) == KErrNotFound)
       
   335           		{
       
   336           			//plain image used...but is this relative?!?
       
   337           			//does JSR 226 need an error thrown on this?
       
   338           			//i.e. image.jpg
       
   339           			if (aUri.Right(4) == KJpgFile)
       
   340           			{
       
   341           				//this is a plain image.jpg
       
   342           				return;
       
   343           			}
       
   344           			else if (aUri.Right(4) == KPngFile)
       
   345           			{
       
   346           				//this is a plain image.png file
       
   347           				return;
       
   348           			}
       
   349           			else if (aUri.Right(4) == KSvgFile)
       
   350           			{
       
   351           				//this is a filename.svg file
       
   352           				document->SetError(KErrNotFound, _L("Usage of SVG file in xlink-href:"), aUri);
       
   353           			}
       
   354           			return;
       
   355           		}
       
   356                 /*if ( aUri.Find( KFile ) != 1 || !TChar( aUri[0] ).IsAlpha() )
       
   357                     {
       
   358                     document->SetError( KErrNotFound, _L( "Usage of relative URI in <image>: " ), aUri );
       
   359                     }
       
   360                 else
       
   361                 	{
       
   362                 		//this is an absolute image
       
   363                 		//i.e. c:/folder/image.jpg
       
   364                 	}*/
       
   365                 }
       
   366             }
       
   367         }
       
   368     }
       
   369 
       
   370 // ---------------------------------------------------------------------------
       
   371 //
       
   372 // ---------------------------------------------------------------------------
       
   373 void CSvgImageElementImpl::LoadUriL()
       
   374     {
       
   375     if ( Href().Length() == 0 )
       
   376         {
       
   377         #ifdef _DEBUG
       
   378         RDebug::Printf("CSvgImageElementImpl::LoadUriL()--iUri is NULL or empty.");
       
   379         #endif
       
   380         return;
       
   381         }
       
   382     iBitmapLoadCalled = ETrue;
       
   383     iSessionConnected = EFalse;
       
   384 
       
   385     // Cannot continue without SvgEngine instance or
       
   386     // MSvgRequestObserver is not set
       
   387 
       
   388     CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
       
   389     if ( document == NULL )
       
   390         {
       
   391         #ifdef _DEBUG
       
   392         RDebug::Printf("CSvgImageElementImpl::LoadUriL--document handle null");
       
   393         #endif
       
   394         return;
       
   395         }
       
   396 
       
   397     // Request
       
   398     if ( ( Href().Length() >= 4 && Href().Right( 4 ) == KSvg ) ||
       
   399          ( Href().Length() >= 5 && Href().Right( 5 ) == KSvgb ) )
       
   400         {
       
   401         iIsSvgFile = ETrue;
       
   402         }
       
   403 
       
   404     // Don't call LoadUriL if LoadingListener exists and LoadingListener::WillAssignImageData returns ETrue
       
   405     if ( document )
       
   406         {
       
   407         const RPointerArray<MSvgLoadingListener>* listeners = document->GetLoadingListeners();
       
   408         if ( listeners && listeners->Count() > 0 )
       
   409             {
       
   410             if ( (*listeners)[0]->WillAssignImageData() )
       
   411                 {
       
   412                 (*listeners)[0]->ImageDataReference( Href() );
       
   413                 return;
       
   414                 }
       
   415             }
       
   416         }
       
   417 
       
   418     // Embedded image
       
   419     if ( ( Href().Length() >= 5 ) && ( Href().Left( 5 ) == _L( "data:" ) ) )
       
   420         {
       
   421         ProcessEncodedImageL( Href() );
       
   422         return;
       
   423         }
       
   424 
       
   425     iBitmapOrgReady = EFalse;
       
   426     iBitmapReady = EFalse;
       
   427 
       
   428     CSvgEngineImpl* engine  = document->Engine();
       
   429     if ( engine == NULL || engine->iRequestObserver == NULL )
       
   430         {
       
   431         #ifdef _DEBUG
       
   432         RDebug::Printf("CSvgImageElementImpl::LoadUriL--engine handle null");
       
   433         #endif
       
   434         return;
       
   435         }
       
   436     
       
   437     // Connect session
       
   438     RFile fileHandle;
       
   439     if ( iSession.Connect() != KErrNone )
       
   440         {
       
   441         return;
       
   442         }
       
   443     iSessionConnected = ETrue;
       
   444     TInt status = engine->iRequestObserver->FetchImage( Href(), iSession, fileHandle );
       
   445     if ( status == KErrNone )
       
   446         {
       
   447         // prevent division by zero (DrawL) when image fails to load
       
   448         CFbsBitmap* aBitmap = new ( ELeave ) CFbsBitmap();
       
   449         CleanupStack::PushL( aBitmap );
       
   450         TInt lCreateErr = aBitmap->Create( TSize( 1, 1 ), EColor64K );
       
   451         if ( lCreateErr != KErrNone )
       
   452             {
       
   453             // Error in creation, destroy the bitmap and return
       
   454             CleanupStack::PopAndDestroy( aBitmap );
       
   455             return;
       
   456             }
       
   457         // Ownership is about to be tranferred to Image Element
       
   458         CleanupStack::Pop( aBitmap );
       
   459         TInt lDecodeErr = StartImageDecoding( fileHandle, aBitmap, ETrue );
       
   460         if ( lDecodeErr != KErrNone )
       
   461             {
       
   462             // No error Processing
       
   463             }
       
   464         }
       
   465     else
       
   466         {
       
   467         iSession.Close();
       
   468         iSessionConnected = EFalse;
       
   469         }
       
   470     }
       
   471 
       
   472 void CSvgImageElementImpl::PrepareImageFromSvgFile(const TDesC8& aImageData)
       
   473     {
       
   474     CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
       
   475     if ( !document )
       
   476         {
       
   477         return;
       
   478         }
       
   479 
       
   480     CSvgEngineImpl* engine  = document->Engine();
       
   481     if ( !engine )
       
   482         {
       
   483         return;
       
   484         }
       
   485     TSize bitmapSize( (TInt32)Width(), (TInt32)Height() );
       
   486     if ( !iBitmap )
       
   487         {
       
   488         iBitmap = new CFbsBitmap();
       
   489         }
       
   490     if(!iMask)
       
   491 	    {
       
   492 		iMask = new CFbsBitmap();        	
       
   493 	    }
       
   494     if(iMask)
       
   495         {
       
   496 		iMask->Create( bitmapSize, EGray256);        	
       
   497         }
       
   498     // Can't use ELeave because this function can't leave
       
   499     // Using ELeave but didn't handle (no trap or propagate to parents) causes more confusing.
       
   500     // Check for NULL is good enough.
       
   501     // Ignore CodeScanner error (Code Review Guide)
       
   502     if (iBitmap)
       
   503         {
       
   504 	    iBitmap->Create( bitmapSize, EColor16MU );
       
   505         
       
   506         TBool preserveRatio = !( iPar != NULL && *iPar == _L( "none" ) );
       
   507         // RenderFileToBuffer if uri is a svg file
       
   508         TInt err = engine->RenderFileToBuffer( aImageData, iBitmap,iMask, preserveRatio );
       
   509         ImageLoadingCompleted(err);
       
   510         }
       
   511     iSession.Close();
       
   512     }
       
   513 // ---------------------------------------------------------------------------
       
   514 //
       
   515 // ---------------------------------------------------------------------------
       
   516 
       
   517 void CSvgImageElementImpl::ProcessEncodedImageL( const TDesC& aXlinkHrefValue )
       
   518     {
       
   519     // find positions for ';' and ',' to determine encoding, mimetype
       
   520     TInt startIndex = aXlinkHrefValue.Locate( ';' );
       
   521     TInt endIndex = aXlinkHrefValue.Locate( ',' );
       
   522 
       
   523     // mimetype is after 'data:' : xlink:href="data:image/png;base64,
       
   524     // ignore mimetype extraction, decode will detect mimetype from decoded data.
       
   525 
       
   526     if ( startIndex != KErrNotFound && endIndex != KErrNotFound &&
       
   527          startIndex < endIndex )
       
   528         {
       
   529         // extract encoding type
       
   530         TPtrC encoding( aXlinkHrefValue.Left( endIndex ).Right( endIndex - startIndex - 1 ) );
       
   531         // handle Base64 encoding
       
   532         _LIT( KEncodingBase64, "base64" );
       
   533         if ( encoding == KEncodingBase64 )
       
   534             {
       
   535             // find index of first character after white-space
       
   536             TInt index = endIndex + 1;
       
   537             while ( index < aXlinkHrefValue.Length() && TChar( aXlinkHrefValue[index] ).IsSpace() )
       
   538                 index++;
       
   539 
       
   540             // must be 8-bit
       
   541             TInt length = aXlinkHrefValue.Length() - index;
       
   542             HBufC8* encoded = HBufC8::NewLC( length );
       
   543             encoded->Des().Copy( aXlinkHrefValue.Right( length ) );
       
   544 
       
   545             // Assign to member variable to destroy after image is process.
       
   546             iImageData = HBufC8::NewL( length );
       
   547             TPtr8 decodedDes = iImageData->Des();
       
   548 
       
   549             // decode
       
   550             TImCodecB64 encodingBase64;
       
   551             TInt decodeError = encodingBase64.Decode( *encoded, decodedDes );
       
   552             CleanupStack::PopAndDestroy( encoded );
       
   553 
       
   554             if ( decodeError == KErrNone )
       
   555                 {
       
   556                 // prevent division by zero (DrawL) when image fails to load
       
   557                 CFbsBitmap* lBitmap = new ( ELeave ) CFbsBitmap();
       
   558                 CleanupStack::PushL( lBitmap );
       
   559                 TInt lCreateErr = lBitmap->Create( TSize( 1, 1 ), EColor64K );
       
   560                 if ( lCreateErr != KErrNone )
       
   561                     {
       
   562                     // Error creating bitmap, delete bitmap and return
       
   563                     CleanupStack::PopAndDestroy( lBitmap );
       
   564                     return;
       
   565                     }
       
   566                 // Ownership of aBitmap is about to be transferred to image
       
   567                 // element
       
   568                 CleanupStack::Pop( lBitmap );
       
   569                 // If bitmap was already present, release it
       
   570                 if ( iBitmap )
       
   571                     {
       
   572                 	delete iBitmap;
       
   573                 	iBitmap = NULL;
       
   574                     }
       
   575                 iBitmap = lBitmap;
       
   576                 TInt lImgDecErr = StartImageDecoding( *iImageData,  
       
   577                         ETrue ); // ETrue means Synchronous Loading
       
   578                 if ( lImgDecErr != KErrNone )
       
   579                     {
       
   580                     // No Error Processing
       
   581                     }
       
   582                 }
       
   583             }
       
   584         }
       
   585     }
       
   586 
       
   587 // *******************************************************
       
   588 // From MXmlElement
       
   589 
       
   590 // ---------------------------------------------------------------------------
       
   591 //
       
   592 // ---------------------------------------------------------------------------
       
   593 TInt CSvgImageElementImpl::SetAttributeL( const TDesC& aName,
       
   594                                           const TDesC& aValue )
       
   595     {
       
   596     _LIT( KTmpUri, "xlink:href" );
       
   597     _LIT( KTmpPreserveAspectRatio, "preserveAspectRatio" );
       
   598 
       
   599     if ( this->SetXlinkAttributeL( aName, aValue ) )
       
   600         {
       
   601         if ( aName == KTmpUri )
       
   602             {
       
   603             SetUriL( aValue );
       
   604             CheckRequiredAttributes();
       
   605             }
       
   606         return KErrNone;
       
   607         }
       
   608 
       
   609 
       
   610     CSvgElementImpl::SetAttributeL(aName,aValue);
       
   611 
       
   612     if ( aName == KTmpPreserveAspectRatio )
       
   613         {
       
   614         SetParL( aValue );
       
   615         }
       
   616 
       
   617     return KErrNoAttributeSet;
       
   618     }
       
   619 
       
   620 
       
   621 
       
   622 // From MXmlElementOpt
       
   623 
       
   624 // ---------------------------------------------------------------------------
       
   625 //
       
   626 // ---------------------------------------------------------------------------
       
   627 TInt CSvgImageElementImpl::GetAttributeFloat( const TInt aNameId,
       
   628                                               TFloatFixPt& aValue )
       
   629     {
       
   630     switch ( aNameId )
       
   631         {
       
   632         case KAtrX:
       
   633         case KAtrRefX:
       
   634         aValue = X();
       
   635         break;
       
   636         case KAtrY:
       
   637         case KAtrRefY:
       
   638         aValue = Y();
       
   639         break;
       
   640         case KAtrHeight:
       
   641         aValue = Height();
       
   642         break;
       
   643         case KAtrWidth:
       
   644         aValue = Width();
       
   645         break;
       
   646         default:
       
   647         return CSvgElementImpl::GetAttributeFloat( aNameId, aValue );
       
   648         }
       
   649 
       
   650     return KErrNone;
       
   651     }
       
   652 
       
   653 // ---------------------------------------------------------------------------
       
   654 //
       
   655 // ---------------------------------------------------------------------------
       
   656 TInt CSvgImageElementImpl::SetAttributeFloatL( const TInt aNameId,
       
   657                                                const TFloatFixPt aValue )
       
   658     {
       
   659     switch ( aNameId )
       
   660         {
       
   661         case KAtrX:
       
   662         iImgRect.iX = aValue;
       
   663         break;
       
   664         case KAtrY:
       
   665         iImgRect.iY = aValue;
       
   666         break;
       
   667 
       
   668         case KAtrHeight:
       
   669         SetHeight( aValue );
       
   670         CheckRequiredAttributes();
       
   671         break;
       
   672 
       
   673         case KAtrWidth:
       
   674         SetWidth( aValue );
       
   675         CheckRequiredAttributes();
       
   676         break;
       
   677 
       
   678         default:
       
   679         return CSvgElementImpl::SetAttributeFloatL( aNameId, aValue );
       
   680         }
       
   681 
       
   682     return KErrNone;
       
   683     }
       
   684 
       
   685 // ---------------------------------------------------------------------------
       
   686 //
       
   687 // ---------------------------------------------------------------------------
       
   688 TInt CSvgImageElementImpl::SetAttributeDesL( const TInt aNameId,
       
   689                                              const TDesC& aValue )
       
   690     {
       
   691     switch ( aNameId )
       
   692         {
       
   693         case KAtrXlinkhref:
       
   694         SetUriL( aValue );
       
   695         CheckRequiredAttributes();
       
   696         break;
       
   697         default:
       
   698         return CSvgElementImpl::SetAttributeDesL( aNameId, aValue );
       
   699         }
       
   700     return KErrNone;
       
   701     }
       
   702 
       
   703 void CSvgImageElementImpl::ImageLoadingCompleted( TInt aError )
       
   704     {
       
   705  	iBitmapReady = aError != KErrCancel;    
       
   706     if ( aError == KErrNone )
       
   707         {
       
   708         
       
   709 	    PrepareImageWithMask();
       
   710         iBitmapOrgReady = ETrue;
       
   711         // Notify clones that the bitmap is ready.
       
   712    
       
   713    
       
   714         NotifyImageDecoded();
       
   715         
       
   716    		// The redraw needs to be done once the image element is decoded, 
       
   717    		// so that the image is rendered in place in the content.
       
   718    		// If the decoding is done asynchronously, the client does not know
       
   719    		// when the decoding was completed hence it cannot perform a redraw()
       
   720    		// In such a scenario, the image element itself triggers a redraw.
       
   721 
       
   722     	if(iImageLoader && !(iImageLoader->IsSynchronousLoading()))
       
   723     		{
       
   724     		CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
       
   725     		if(document)
       
   726     			{
       
   727     			CSvgEngineImpl* engine  =document->Engine();
       
   728         		if(engine)
       
   729         			{
       
   730         			engine->ImageLoadingCompleted(aError);
       
   731         			}
       
   732     			}	
       
   733     		}
       
   734          } // if ( aError == KErrNone )
       
   735     CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
       
   736     if(document)
       
   737         {
       
   738         document->ImageLoadingCompleted(aError);    
       
   739         }
       
   740 
       
   741     
       
   742    
       
   743    
       
   744     if ( iSessionConnected )
       
   745         {
       
   746         iSession.Close();
       
   747         iSessionConnected = EFalse;
       
   748         }
       
   749     }
       
   750 
       
   751 // ---------------------------------------------------------------------------
       
   752 // void CSvgImageElementImpl::PrepareImageWithMask()
       
   753 //  Combines mask information into main bitmap for use with OpenVG
       
   754 // ---------------------------------------------------------------------------
       
   755 void CSvgImageElementImpl::PrepareImageWithMask()
       
   756     {
       
   757     if ( iBitmap && iMask )
       
   758         {
       
   759         TSize size = iMask->SizeInPixels();
       
   760         // If size of bitmap and mask do not match, cannot process mask
       
   761         if ( size != iBitmap->SizeInPixels() )
       
   762             {
       
   763             return;
       
   764             }
       
   765         iBitmap->LockHeap();
       
   766         iMask->LockHeap();
       
   767         
       
   768         TUint32* bitmapData = (TUint32*)iBitmap->DataAddress();
       
   769         TUint8* maskData = (TUint8*)iMask->DataAddress();
       
   770         
       
   771         TInt lBmpSLLen = CFbsBitmap::ScanLineLength( size.iWidth,
       
   772         iBitmap->DisplayMode() ); 
       
   773         
       
   774         TInt lMaskSLLen = CFbsBitmap::ScanLineLength( size.iWidth, 
       
   775                 iMask->DisplayMode() );
       
   776                 
       
   777         TInt count = size.iWidth * size.iHeight;
       
   778         TUint32* lBitmapCurPtr = bitmapData; 
       
   779         TUint8* lMaskCurPtr = maskData; 
       
   780         
       
   781         for ( TInt lIndex = 1; lIndex < count; lIndex++ )
       
   782             {
       
   783              // Converting from ARGB to RGBA8888
       
   784             *lBitmapCurPtr = ( *lBitmapCurPtr & 0x00FFFFFF ) << 8 | *lMaskCurPtr;
       
   785             // Check if one row is complete
       
   786             if ( lIndex % size.iWidth == 0 )
       
   787                 {
       
   788                 // One row of pixels is complete. Now reposition the 
       
   789                 // lBitmapCurPtr, lMaskCurPtr to point to beginning of new row. 
       
   790                 // Current row is given by (index/widthMask) 
       
   791                 // 
       
   792                 // In order to get offset to first pixel, we need to 
       
   793                 // perform following 
       
   794                 //     BasePtr + Current row * (row width in bytes) 
       
   795                 lBitmapCurPtr =(TUint32*)((TUint8*)bitmapData + ( ( lIndex / size.iWidth ) 
       
   796                         * lBmpSLLen ));
       
   797                 lMaskCurPtr = maskData + ( ( lIndex  / size.iWidth ) 
       
   798                         * lMaskSLLen ); 
       
   799                 } 
       
   800           else 
       
   801                 { 
       
   802                 // Still within the row, keep incrementing 
       
   803                 lBitmapCurPtr++; 
       
   804                 lMaskCurPtr++; 
       
   805                 } 
       
   806             }
       
   807         iMask->UnlockHeap();
       
   808         iBitmap->UnlockHeap();
       
   809         }
       
   810     }
       
   811 
       
   812 // *******************************************************
       
   813 // From CSvgElementImpl
       
   814 
       
   815 // perform a deep clone of this object
       
   816 // ---------------------------------------------------------------------------
       
   817 //
       
   818 // ---------------------------------------------------------------------------
       
   819 MXmlElement* CSvgImageElementImpl::CloneL(MXmlElement* aParentElement)
       
   820     {
       
   821     CSvgImageElementImpl* newElement = CSvgImageElementImpl::NewL(  this->ElemID(), ((CSvgDocumentImpl*)iOwnerDocument) );
       
   822 
       
   823     CleanupStack::PushL(newElement);
       
   824     newElement->iParentNode = aParentElement;
       
   825     // copy everything over
       
   826     this->CopyL(newElement);
       
   827     CleanupStack::Pop();
       
   828     // Add the cloned element to image decode notification list. 
       
   829     // This is done to ensure that the image is decoded only once.
       
   830     AddImageElementListener( newElement );
       
   831     newElement->SetReferenceElement( this );
       
   832     return newElement;
       
   833     }
       
   834 
       
   835 // ---------------------------------------------------------------------------
       
   836 //
       
   837 // ---------------------------------------------------------------------------
       
   838 TBool CSvgImageElementImpl::DrawL( CGfx2dGc* aGc, CSvgElementImpl* aElement )
       
   839     {
       
   840     // Set Gc
       
   841     this->DrawShapeL( aGc, aElement );
       
   842 
       
   843     if ( iBitmap == NULL )
       
   844         return ETrue;
       
   845     TSize imageSize = iBitmap->SizeInPixels(); //.
       
   846     if ( imageSize.iWidth == 0 || imageSize.iHeight == 0 )
       
   847         return ETrue;
       
   848 
       
   849     const TGfxAffineTransform& currentTM = GetCTM();
       
   850 
       
   851     aGc->SetTransform( currentTM );
       
   852 
       
   853     if ( iBitmapReady && iRenderImage && iBitmap )
       
   854         {
       
   855         aGc->DrawImage( iBitmap, iImgRect, iMask != NULL );
       
   856         }
       
   857     else if ( iBitmapOrgReady && iRenderImage )
       
   858         {
       
   859         aGc->SetForegroundColor( TGfxColor( 0xaaaaaa ) );
       
   860         aGc->SetPaint( NULL );
       
   861         aGc->DrawL( &iImgRect );
       
   862         }
       
   863     return ETrue;
       
   864     }
       
   865 
       
   866 // *******************************************************
       
   867 // Private
       
   868 
       
   869 // ---------------------------------------------------------------------------
       
   870 //
       
   871 // ---------------------------------------------------------------------------
       
   872 CSvgImageElementImpl::CSvgImageElementImpl( CSvgDocumentImpl* aDoc ) :  
       
   873     iRenderImage ( ETrue ),
       
   874     iIsUriSet( EFalse ),
       
   875     iImageDecodingDone(EFalse),
       
   876     iBitmapReady( EFalse )
       
   877     {
       
   878     SetOwnerDocument(aDoc);
       
   879     iBitmap = NULL;
       
   880     iMask   = NULL;
       
   881     }
       
   882 
       
   883 // ---------------------------------------------------------------------------
       
   884 // perform a deep copy of this object
       
   885 // ---------------------------------------------------------------------------
       
   886 void CSvgImageElementImpl::CopyL( CSvgImageElementImpl* aDestElement )
       
   887     {
       
   888     if(aDestElement)
       
   889         {
       
   890           // copy stuff from superclass
       
   891         this->CSvgElementImpl::CopyL(aDestElement);
       
   892 
       
   893         // copy items special to CSvgImageElementImpl
       
   894         aDestElement->iUsedImage      = ETrue;          // this is not original image
       
   895         delete aDestElement->iBitmap;                  // delete old
       
   896         aDestElement->iBitmap         = this->iBitmap; // borrow new
       
   897         aDestElement->iImgRect        = this->iImgRect;
       
   898         aDestElement->iPar            = this->iPar;
       
   899         aDestElement->iBitmapOrgReady = ETrue;
       
   900         aDestElement->iBitmapReady    = ETrue;
       
   901         aDestElement->iRenderImage    = ETrue;
       
   902 		aDestElement->iIsBase64 = this->iIsBase64;
       
   903 
       
   904         // copy the reference to idoc (CSvgDocumentImpl)
       
   905         aDestElement->iOwnerDocument = this->iOwnerDocument;
       
   906         }
       
   907 
       
   908 
       
   909     }
       
   910 
       
   911 /********************* Helping Class **************************/
       
   912 
       
   913 // ---------------------------------------------------------------------------
       
   914 // Two-phased constructor
       
   915 // ---------------------------------------------------------------------------
       
   916 CSvgImageElementImpl::CSvgImageLoaderUtil* CSvgImageElementImpl::CSvgImageLoaderUtil::NewL( 
       
   917     MSVGImageLoadingObserver* aObserver,
       
   918     RFile& aFileHandle,
       
   919     TBool aSyncLoading )
       
   920     {
       
   921     CSvgImageLoaderUtil* self = new ( ELeave ) CSvgImageLoaderUtil( );
       
   922     CleanupStack::PushL( self );
       
   923     self->ConstructL( aObserver, aFileHandle, aSyncLoading );
       
   924     CleanupStack::Pop();
       
   925     return self;
       
   926     }
       
   927 
       
   928 // ---------------------------------------------------------------------------
       
   929 // Two-phased constructor
       
   930 // ---------------------------------------------------------------------------
       
   931 CSvgImageElementImpl::CSvgImageLoaderUtil* CSvgImageElementImpl::CSvgImageLoaderUtil::NewL( 
       
   932     MSVGImageLoadingObserver* aObserver,
       
   933     const TDesC8& aEncodedData,
       
   934     TBool aSyncLoading )
       
   935     {
       
   936     CSvgImageLoaderUtil* self = new ( ELeave ) CSvgImageLoaderUtil( );
       
   937     CleanupStack::PushL( self );
       
   938     self->ConstructL( aObserver, aEncodedData, aSyncLoading );
       
   939     CleanupStack::Pop();
       
   940     return self;
       
   941     }
       
   942 
       
   943 // ---------------------------------------------------------------------------
       
   944 // Destructor
       
   945 // ---------------------------------------------------------------------------
       
   946 CSvgImageElementImpl::CSvgImageLoaderUtil::~CSvgImageLoaderUtil()
       
   947     {
       
   948     Cancel();
       
   949     if(iImageDecoder)
       
   950         {
       
   951         delete iImageDecoder;
       
   952         iImageDecoder = NULL;
       
   953         }
       
   954     if ( iActiveSchedulerWait )
       
   955         {
       
   956         delete iActiveSchedulerWait;
       
   957         }
       
   958     if(iImageByteData)
       
   959     	{
       
   960     	delete iImageByteData;
       
   961     	iImageByteData=NULL;
       
   962     	}
       
   963     }
       
   964 
       
   965 // ---------------------------------------------------------------------------
       
   966 // Set the display mode (color mode), the default value is EColor64K.
       
   967 // ---------------------------------------------------------------------------
       
   968 void CSvgImageElementImpl::CSvgImageLoaderUtil::SetDisplayMode( TDisplayMode aDisplayMode )
       
   969     {
       
   970     iDisplayMode = aDisplayMode;
       
   971     }
       
   972 
       
   973 // ---------------------------------------------------------------------------
       
   974 // Returns the FrameInfo of Image
       
   975 // ---------------------------------------------------------------------------
       
   976 TFrameInfo CSvgImageElementImpl::CSvgImageLoaderUtil::GetFrameInfo()
       
   977     {
       
   978 	return iImageDecoder->FrameInfo(); 
       
   979     }
       
   980 
       
   981 
       
   982 // ---------------------------------------------------------------------------
       
   983 // Request asynchronously for the image, sized to the image size.
       
   984 // ---------------------------------------------------------------------------
       
   985 void CSvgImageElementImpl::CSvgImageLoaderUtil::RequestForImageL( CFbsBitmap& aBitmap,
       
   986                                                                   CFbsBitmap& aMask,
       
   987                                                                   TBool       aHasAlpha,
       
   988                                                                   TFrameInfo  aFrameInfo )
       
   989     {
       
   990     if ( iImageDecoder != NULL )
       
   991         {
       
   992         if ( aHasAlpha )
       
   993             {
       
   994             User::LeaveIfError( aMask.Create( aFrameInfo.iOverallSizeInPixels, EGray256 ) );
       
   995             User::LeaveIfError( aBitmap.Create( aFrameInfo.iOverallSizeInPixels, EColor16MU ) );
       
   996             iImageDecoder->Convert( &iStatus, aBitmap, aMask, 0 );
       
   997             }
       
   998         else
       
   999             {
       
  1000             User::LeaveIfError( aBitmap.Create( aFrameInfo.iOverallSizeInPixels, EColor64K ) );
       
  1001             iImageDecoder->Convert( &iStatus, aBitmap, 0 );
       
  1002             }
       
  1003 
       
  1004         SetActive();
       
  1005         if ( iActiveSchedulerWait )
       
  1006             {
       
  1007             iActiveSchedulerWait->Start();
       
  1008             }
       
  1009         }
       
  1010     else
       
  1011         {
       
  1012         iObserver->ImageLoadingCompleted( KErrNotFound );
       
  1013         }
       
  1014     }
       
  1015 
       
  1016 // ---------------------------------------------------------------------------
       
  1017 // Override method from CActive, called upon successful completion of request
       
  1018 // ---------------------------------------------------------------------------
       
  1019 void CSvgImageElementImpl::CSvgImageLoaderUtil::RunL()
       
  1020     {
       
  1021     if ( iActiveSchedulerWait )
       
  1022         {
       
  1023         iActiveSchedulerWait->AsyncStop();
       
  1024         }
       
  1025     if ( iObserver )
       
  1026         {
       
  1027         iObserver->ImageLoadingCompleted( iStatus.Int() );
       
  1028         }
       
  1029     }
       
  1030 
       
  1031 // ---------------------------------------------------------------------------
       
  1032 // Override method from CActive, called upon a cancel of request
       
  1033 // ---------------------------------------------------------------------------
       
  1034 void CSvgImageElementImpl::CSvgImageLoaderUtil::DoCancel()
       
  1035     {
       
  1036     if ( iImageDecoder != NULL )
       
  1037         {
       
  1038         iImageDecoder->Cancel();
       
  1039         }
       
  1040     
       
  1041     // must delete decoder immediate or exception occurs in destructor.
       
  1042     delete iImageDecoder;
       
  1043     iImageDecoder = NULL;
       
  1044     iObserver->ImageLoadingCompleted( KErrCancel );
       
  1045     }
       
  1046 
       
  1047 // ---------------------------------------------------------------------------
       
  1048 // Override method from CActive, called upon an error from request
       
  1049 // ---------------------------------------------------------------------------
       
  1050 TInt CSvgImageElementImpl::CSvgImageLoaderUtil::RunError( TInt aError )
       
  1051     {
       
  1052     // must delete decoder immediate or exception occurs in destructor.
       
  1053     delete iImageDecoder;
       
  1054     iImageDecoder = NULL;
       
  1055     iObserver->ImageLoadingCompleted( aError );
       
  1056     return KErrNone;
       
  1057     }
       
  1058 
       
  1059 // ---------------------------------------------------------------------------
       
  1060 // Constructor
       
  1061 // ---------------------------------------------------------------------------
       
  1062 CSvgImageElementImpl::CSvgImageLoaderUtil::CSvgImageLoaderUtil() : CActive( EPriorityNormal )
       
  1063     {
       
  1064     SetDisplayMode( EColor64K );
       
  1065     CActiveScheduler::Add( this );
       
  1066     }
       
  1067 
       
  1068 // ---------------------------------------------------------------------------
       
  1069 // Second phase Construction
       
  1070 // ---------------------------------------------------------------------------
       
  1071 void CSvgImageElementImpl::CSvgImageLoaderUtil::ConstructL( 
       
  1072     MSVGImageLoadingObserver* aObserver, 
       
  1073     RFile& aFileHandle,
       
  1074     TBool aSyncLoading )
       
  1075     {
       
  1076     iObserver = aObserver;
       
  1077     iIsSyncLoading=aSyncLoading;
       
  1078     
       
  1079     // Reset to start of file
       
  1080     TInt zero = 0;
       
  1081     aFileHandle.Seek( ESeekStart, zero );
       
  1082 
       
  1083     TInt fileSize = 0;
       
  1084     TInt sizeError = aFileHandle.Size( fileSize );
       
  1085     if ( sizeError != KErrNone )
       
  1086     	{
       
  1087       
       
  1088      	return;
       
  1089        	}
       
  1090 
       
  1091  	
       
  1092 	iImageByteData = HBufC8::New ( fileSize );
       
  1093 
       
  1094 	 if (!iImageByteData)
       
  1095     	{
       
  1096         
       
  1097        	return;
       
  1098        	}
       
  1099 	
       
  1100 	TPtr8 binaryBufferPtr = iImageByteData->Des();
       
  1101 	
       
  1102 	// Read the image data into a buffer.
       
  1103 	TInt readError = aFileHandle.Read(binaryBufferPtr, fileSize);
       
  1104 	if ( readError != KErrNone )
       
  1105     	{
       
  1106         delete iImageByteData;
       
  1107         iImageByteData = NULL;
       
  1108         return;
       
  1109     	}
       
  1110     // Unused parameter	
       
  1111     RFs session;
       
  1112     iImageDecoder = CImageDecoder::DataNewL( session, *iImageByteData, CImageDecoder::TOptions( CImageDecoder::EAllowGeneratedMask | 
       
  1113         CImageDecoder::EOptionAlwaysThread )); 
       
  1114     iImageDecoder->SetDecoderThreadPriority( EPriorityNormal );
       
  1115 	
       
  1116     if ( aSyncLoading )
       
  1117         {
       
  1118         iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait();
       
  1119         }
       
  1120     }
       
  1121 
       
  1122 void CSvgImageElementImpl::CSvgImageLoaderUtil::ConstructL( MSVGImageLoadingObserver* aObserver,
       
  1123                                                             const TDesC8& aEncodedData,
       
  1124                                                             TBool aSyncLoading )
       
  1125     {
       
  1126     iObserver = aObserver;
       
  1127     iIsSyncLoading=aSyncLoading;
       
  1128     // Unused parameter
       
  1129     RFs session;
       
  1130     iImageDecoder = CImageDecoder::DataNewL( session, aEncodedData, CImageDecoder::TOptions( CImageDecoder::EAllowGeneratedMask | 
       
  1131         CImageDecoder::EOptionAlwaysThread ));
       
  1132     iImageDecoder->SetDecoderThreadPriority( EPriorityNormal );
       
  1133     if ( aSyncLoading )
       
  1134         {
       
  1135         iActiveSchedulerWait = new (ELeave) CActiveSchedulerWait();
       
  1136         }
       
  1137     }
       
  1138 
       
  1139 TInt CSvgImageElementImpl::GetAttributeDes( const TInt aNameId,
       
  1140                                                      TPtrC16& aValue )
       
  1141 {
       
  1142  if(aNameId == KAtrPreserveAspectRatio)
       
  1143      {
       
  1144      aValue.Set( Par() );
       
  1145      return KErrNone;
       
  1146      }
       
  1147  // added for updation of Get/Set
       
  1148  if( aNameId == KAtrXlinkhref )
       
  1149     {
       
  1150      aValue.Set( Href() );
       
  1151      return KErrNone;
       
  1152     }
       
  1153  return CSvgElementImpl::GetAttributeDes( aNameId, aValue );
       
  1154 
       
  1155 }
       
  1156 
       
  1157 // MSvgImageDecodingRequester method
       
  1158 TInt CSvgImageElementImpl::StartImageDecoding( const TDesC8& aImageData,
       
  1159                                                TBool aSyncLoading )
       
  1160     {
       
  1161     if ( iBitmap != NULL )
       
  1162         {
       
  1163         
       
  1164         if( iIsSvgFile )
       
  1165             {
       
  1166         	// SVG files are decoded by engine and do not follow the ImageDecoder Path
       
  1167         	PrepareImageFromSvgFile(aImageData);             
       
  1168             return KErrNone;
       
  1169             }
       
  1170     	if( iImageDecodingDone )
       
  1171     	    {
       
  1172     	    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
       
  1173     	    if(document)
       
  1174     	        {
       
  1175     	        TInt incCnt = document->GetImageElementsCount() + 1;
       
  1176         	    document->SetImageElementsCount(incCnt);
       
  1177                 }
       
  1178             
       
  1179     	    }
       
  1180     	else
       
  1181     	    {
       
  1182     	    iImageDecodingDone = ETrue;
       
  1183     	    }
       
  1184         // Check if the iImageLoader already exists for the ImageElement
       
  1185         TInt err = KErrNone;
       
  1186         
       
  1187         if( iImageLoader == NULL )
       
  1188         {
       
  1189         	TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
       
  1190             aImageData,
       
  1191             aSyncLoading ));  // EFalse means Asynchronous decoding	
       
  1192         }
       
  1193         else
       
  1194         {
       
  1195         	// Cancel the currently active request if the request is pending.
       
  1196         	if( iImageLoader)
       
  1197         	{
       
  1198         		delete iImageLoader;
       
  1199         		iImageLoader = NULL;
       
  1200         	}
       
  1201         	
       
  1202         	TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
       
  1203             aImageData,
       
  1204             aSyncLoading ));  // EFalse means Asynchronous decoding	
       
  1205         }
       
  1206         
       
  1207         if ( err != KErrNone || !iImageLoader )
       
  1208             {
       
  1209             #ifdef _DEBUG
       
  1210             RDebug::Printf("CSvgImageElementImpl::StartImageDecoding failed");
       
  1211             #endif
       
  1212             ImageLoadingCompleted(err);
       
  1213             return err;
       
  1214             }
       
  1215 
       
  1216         TFrameInfo lFrameInfo( iImageLoader->GetFrameInfo() );
       
  1217 		TBool      lHasAlpha = (lFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
       
  1218        
       
  1219         if( lHasAlpha )
       
  1220             {
       
  1221         	if( iMask )
       
  1222         	    {
       
  1223         		delete iMask;
       
  1224         		iMask = NULL;
       
  1225         	    }
       
  1226         	
       
  1227         	iMask = new (ELeave) CFbsBitmap();
       
  1228             }
       
  1229         
       
  1230         TRAPD(err2, iImageLoader->RequestForImageL( *iBitmap, *iMask, lHasAlpha, lFrameInfo ));
       
  1231         if ( err2 != KErrNone )
       
  1232             {
       
  1233             #ifdef _DEBUG
       
  1234             RDebug::Printf("CSvgImageElementImpl::StartImageDecoding RequestForImageL() failed");
       
  1235             #endif
       
  1236             ImageLoadingCompleted(err2);
       
  1237             return err2;
       
  1238             }
       
  1239         }
       
  1240     return KErrNone;
       
  1241     }
       
  1242 
       
  1243 
       
  1244 TInt CSvgImageElementImpl::StartImageDecoding( RFile& aImageFile,
       
  1245                                                CFbsBitmap* aBitmap,
       
  1246                                                TBool aSyncLoading )
       
  1247     {
       
  1248     if ( iBitmap )
       
  1249         {
       
  1250         // Destroy the existing bitmap
       
  1251         delete iBitmap;
       
  1252         }
       
  1253     // Take ownership of the bitmap
       
  1254     iBitmap = aBitmap;
       
  1255 
       
  1256     if ( iBitmap != NULL )
       
  1257         {
       
  1258         if( iIsSvgFile )
       
  1259             {
       
  1260                	
       
  1261         	TInt length;
       
  1262         	aImageFile.Size(length);
       
  1263         	
       
  1264         	HBufC8 *aImageData = HBufC8::NewL( length );
       
  1265            	TPtr8 des = aImageData->Des();
       
  1266         	
       
  1267         	TInt readError = aImageFile.Read( des );
       
  1268         	if ( readError != KErrNone )
       
  1269         		{
       
  1270             	delete aImageData;
       
  1271         		return KErrGeneral;
       
  1272         		}
       
  1273         	else
       
  1274         		{
       
  1275         		// SVG files are decoded by engine and do not follow the ImageDecoder Path
       
  1276         		PrepareImageFromSvgFile(des);             
       
  1277             	return KErrNone;
       
  1278         		}        	
       
  1279             }
       
  1280     	if( iImageDecodingDone )
       
  1281     	    {
       
  1282     	    CSvgDocumentImpl* document = (CSvgDocumentImpl*)OwnerDocument();
       
  1283     	    if(document)
       
  1284     	        {
       
  1285     	        TInt incCnt = document->GetImageElementsCount() + 1;
       
  1286         	    document->SetImageElementsCount(incCnt);
       
  1287                 }
       
  1288             
       
  1289     	    }
       
  1290     	else
       
  1291     	    {
       
  1292     	    iImageDecodingDone = ETrue;
       
  1293     	    }
       
  1294         
       
  1295         TInt err = KErrNone;
       
  1296         // Check if the iImageLoader already exists for the ImageElement
       
  1297         if( iImageLoader == NULL )
       
  1298             {
       
  1299         	TRAP( err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
       
  1300             aImageFile,
       
  1301             aSyncLoading ));  // EFalse means Asynchronous decoding	
       
  1302             }
       
  1303         else
       
  1304             {
       
  1305         	// Cancel the currently active request if the request is pending.
       
  1306         	if( iImageLoader)
       
  1307         	   {
       
  1308         	   delete iImageLoader;
       
  1309         	   iImageLoader = NULL;
       
  1310         	   }
       
  1311         	
       
  1312         	TRAP(err, iImageLoader = CSvgImageLoaderUtil::NewL( this, 
       
  1313             aImageFile,
       
  1314             aSyncLoading ));  // EFalse means Asynchronous decoding	
       
  1315             }
       
  1316         
       
  1317         if ( err != KErrNone || !iImageLoader )
       
  1318             {
       
  1319             #ifdef _DEBUG
       
  1320             RDebug::Printf("CSvgImageElementImpl::StartImageDecoding failed");
       
  1321             #endif
       
  1322             ImageLoadingCompleted(err);
       
  1323             return err;
       
  1324             }
       
  1325         // Get the Frame info and based on it create the iMask if required.
       
  1326         TFrameInfo lFrameInfo( iImageLoader->GetFrameInfo() );
       
  1327 		TBool      lHasAlpha = (lFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
       
  1328        
       
  1329         if( lHasAlpha )
       
  1330             {
       
  1331         	if( iMask )
       
  1332         	    {
       
  1333         		delete iMask;
       
  1334         		iMask = NULL;
       
  1335         	    }
       
  1336         	
       
  1337         	iMask = new (ELeave) CFbsBitmap();
       
  1338             }
       
  1339             
       
  1340             
       
  1341         TRAPD(err2, iImageLoader->RequestForImageL( *iBitmap, *iMask, lHasAlpha, lFrameInfo ));
       
  1342         
       
  1343         if ( err2 != KErrNone )
       
  1344             {
       
  1345             #ifdef _DEBUG
       
  1346             RDebug::Printf("CSvgImageElementImpl::StartImageDecoding RequestForImageL() failed");
       
  1347             #endif
       
  1348             ImageLoadingCompleted(err);
       
  1349             return err2;
       
  1350             }
       
  1351         }
       
  1352     return KErrNone;
       
  1353     }
       
  1354 // ---------------------------------------------------------------------------
       
  1355 // CSvgImageElementImpl::SetReferenceElement
       
  1356 //  Informs the image element that it is referring to a particular image 
       
  1357 //  element.
       
  1358 // ---------------------------------------------------------------------------
       
  1359 void CSvgImageElementImpl::SetReferenceElement( CSvgImageElementImpl* 
       
  1360     aImageElement )
       
  1361     {
       
  1362     iRefElement = aImageElement;
       
  1363     }
       
  1364 
       
  1365 // ---------------------------------------------------------------------------
       
  1366 // CSvgImageElementImpl::GetReferenceElement
       
  1367 //  Get Function for reference element
       
  1368 // ---------------------------------------------------------------------------
       
  1369 CSvgImageElementImpl* CSvgImageElementImpl::ReferenceElement()
       
  1370     {
       
  1371     return iRefElement;
       
  1372     }
       
  1373 
       
  1374 // ---------------------------------------------------------------------------
       
  1375 // CSvgImageElementImpl::AddImageElementListener
       
  1376 //  Adds an image element listener - used in the case of cloning of image 
       
  1377 //  element.
       
  1378 // ---------------------------------------------------------------------------
       
  1379 void CSvgImageElementImpl::AddImageElementListener( 
       
  1380     MSvgImageElementListener* aListener )
       
  1381     {
       
  1382     if ( iImageElementListeners.Find( aListener ) != KErrNotFound )
       
  1383         {
       
  1384         return;
       
  1385         }
       
  1386     if ( iImageElementListeners.Append( aListener ) != KErrNone )
       
  1387         {
       
  1388         #ifdef _DEBUG
       
  1389         RDebug::Printf("iImageElementListeners.Append failed");
       
  1390         #endif
       
  1391         }
       
  1392     }
       
  1393 
       
  1394 // ---------------------------------------------------------------------------
       
  1395 // CSvgImageElementImpl::RemoveImageElementListener
       
  1396 //  Removes an image element listener - used in the case of cloning of image 
       
  1397 //  element.
       
  1398 // ---------------------------------------------------------------------------
       
  1399 void CSvgImageElementImpl::RemoveImageElementListener( 
       
  1400     MSvgImageElementListener* aListener )
       
  1401     {
       
  1402     TInt index = iImageElementListeners.Find( aListener );
       
  1403     if ( index == KErrNotFound )
       
  1404         {
       
  1405         return;
       
  1406         }
       
  1407     iImageElementListeners.Remove( index );
       
  1408     }
       
  1409 
       
  1410 // ---------------------------------------------------------------------------
       
  1411 // CSvgImageElementImpl::BitmapDecoded
       
  1412 //  This is the callback implementation for updating the decoded image 
       
  1413 //  and mask from referenced image element.
       
  1414 // ---------------------------------------------------------------------------
       
  1415 void CSvgImageElementImpl::BitmapDecoded( CFbsBitmap* aBitmap, 
       
  1416     CFbsBitmap* aMask )
       
  1417     {
       
  1418     // Save the pointers to the decoded bitmap in this element,
       
  1419     // this can be used in subsequent draw.
       
  1420     // Note: Both the bitmap and mask are not owned by this element.
       
  1421     // It is owned by the reference element.
       
  1422     iBitmap = aBitmap;
       
  1423     iMask = aMask;
       
  1424 
       
  1425     iBitmapReady = iBitmap != NULL;
       
  1426     }
       
  1427 
       
  1428 // ---------------------------------------------------------------------------
       
  1429 // CSvgImageElementImpl::ResetReference
       
  1430 //  This is the callback implementation for resetting reference element 
       
  1431 //  pointer
       
  1432 // ---------------------------------------------------------------------------
       
  1433 void CSvgImageElementImpl::ResetReference()
       
  1434     {
       
  1435     // Stop referring to the reference element.
       
  1436     iRefElement = NULL;
       
  1437     }
       
  1438 
       
  1439 // ---------------------------------------------------------------------------
       
  1440 // CSvgImageElementImpl::NotifyImageDecoded
       
  1441 //  Notify listeners that image has been decoded.
       
  1442 // ---------------------------------------------------------------------------
       
  1443 void CSvgImageElementImpl::NotifyImageDecoded()
       
  1444     {
       
  1445     TInt imageEleListenersCnt = iImageElementListeners.Count();
       
  1446     for ( TInt i = 0; i < imageEleListenersCnt; i++ )
       
  1447         {
       
  1448         iImageElementListeners[i]->BitmapDecoded( iBitmap, iMask );
       
  1449         }
       
  1450 }
       
  1451 
       
  1452 // ---------------------------------------------------------------------------
       
  1453 // CSvgImageElementImpl::ResetReference
       
  1454 //  Notify listeners to reset their reference element pointers
       
  1455 // ---------------------------------------------------------------------------
       
  1456 void CSvgImageElementImpl::NotifyResetReference()
       
  1457     {
       
  1458     TInt imageEleListenersCnt = iImageElementListeners.Count();
       
  1459     for ( TInt i = 0; i < imageEleListenersCnt; i++ )
       
  1460         {
       
  1461         iImageElementListeners[i]->ResetReference();
       
  1462         }
       
  1463 }
       
  1464 
       
  1465 void CSvgImageElementImpl::Print( TBool aIsEncodeOn )
       
  1466 {
       
  1467 	if (!aIsEncodeOn)
       
  1468 	{
       
  1469 		#ifdef _DEBUG
       
  1470 		RDebug::Printf("<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xlink:href=\"hmm\" \\>", (int)X(), (int)Y(), (int)Width(), (int)Height()/*, Href()*/);
       
  1471 		#endif
       
  1472 	}
       
  1473 }
       
  1474 
       
  1475 CFbsBitmap* CSvgImageElementImpl::GetBitmap()
       
  1476     {
       
  1477     return iBitmap;
       
  1478     }
       
  1479 
       
  1480 void CSvgImageElementImpl::SetBitmap( CFbsBitmap* aBitmap )    
       
  1481     {
       
  1482     if ( iBitmap )
       
  1483         {
       
  1484     	delete iBitmap;
       
  1485     	iBitmap = NULL;
       
  1486         }
       
  1487 	iBitmap = aBitmap;
       
  1488     }
       
  1489 
       
  1490 void CSvgImageElementImpl::AssignImageData( HBufC8* aData )
       
  1491     {
       
  1492     if(iImageData)
       
  1493         {
       
  1494         delete iImageData;
       
  1495         iImageData = NULL;
       
  1496         }
       
  1497     iImageData = aData;
       
  1498     }
       
  1499 
       
  1500 TInt CSvgImageElementImpl::CheckRequiredAttributes()
       
  1501 {
       
  1502 	if ( !( iImgRect.iHeight >= TFloatFixPt(0) ) )
       
  1503 	{
       
  1504 		//need a height
       
  1505 		iReqAttrFlag = KAtrHeight;
       
  1506 		return iReqAttrFlag;
       
  1507 	}
       
  1508 
       
  1509 	if ( !( iImgRect.iWidth >= TFloatFixPt(0)) )
       
  1510 	{
       
  1511 		iReqAttrFlag = KAtrWidth;
       
  1512 		return iReqAttrFlag;
       
  1513 	}
       
  1514 
       
  1515 	
       
  1516 	if ( !iIsUriSet )
       
  1517 	{
       
  1518 		iReqAttrFlag = KAtrXlinkhref;
       
  1519 		return iReqAttrFlag;
       
  1520 	}
       
  1521 
       
  1522 	iReqAttrFlag = 0;
       
  1523 	
       
  1524 	// check if the diplay property is turned off programatically
       
  1525 	if( WasTurnedOff() )
       
  1526 	{
       
  1527 	    _LIT(KInline, "inline");
       
  1528 	    // turn it on. this means all the required attributes Are present and
       
  1529 	    // hence we can render it.
       
  1530 	    CSvgElementImpl::SetPropertyL(KCSS_ATTR_DISPLAY, KInline);
       
  1531 	    SetTurnOff( EFalse );
       
  1532 	}
       
  1533 	
       
  1534 	return 0;
       
  1535 }
       
  1536 // ---------------------------------------------------------------------------
       
  1537 // CSvgImageElementImpl::IsSynchronousLoading
       
  1538 // Returns whether the image decoding was synchronous or not
       
  1539 // ---------------------------------------------------------------------------
       
  1540 TBool CSvgImageElementImpl::CSvgImageLoaderUtil::IsSynchronousLoading()
       
  1541 	{
       
  1542 	return iIsSyncLoading;
       
  1543 	}