resourcepool/src/alfresourcepoolimpl.cpp
changeset 17 3eca7e70b1b8
parent 3 4526337fb576
equal deleted inserted replaced
3:4526337fb576 17:3eca7e70b1b8
     1 /*
       
     2 * Copyright (c) 2008 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:  Implementation of the resource pool
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // From this component
       
    20 #include "alfresourcepoolimpl.h"
       
    21 
       
    22 // From the same subsystem
       
    23 #include <osn/osnnew.h>
       
    24 #include <alf/alfimageloaderutil.h>
       
    25 #include <alf/alfutil.h>
       
    26 #include <alf/alfdisplay.h>
       
    27 #include <alf/alfwidgetenvextension.h>
       
    28 
       
    29 // Outside the same subsystem
       
    30 #include <AknsItemID.h>
       
    31 #include <utf.h>
       
    32 
       
    33 // standard C++/STL
       
    34 #include <algorithm>
       
    35 #include <cstdlib>
       
    36 #include <stdexcept>
       
    37 
       
    38 namespace Alf 
       
    39 {
       
    40 
       
    41 #define KResourcePoolHexadecimalPrefix "0x"
       
    42 
       
    43 const unsigned int INITIAL_IMAGE_WIDTH = 0; // no magic
       
    44 const unsigned int INITIAL_IMAGE_HEIGHT = 0; // no magic
       
    45 
       
    46 const TAlfTextureFlags IMAGE_RESOURCE_DEFAULT_TEXTURE_FLAGS = TAlfTextureFlags(EAlfTextureFlagAutoSize);
       
    47 const TAlfTextureFlags IMAGE_RESOURCE_SKINNED_TEXTURE_FLAGS = TAlfTextureFlags(EAlfTextureFlagAutoSize | EAlfTextureFlagSkinContent);
       
    48 
       
    49 // Function is Not used.
       
    50 /**********************************
       
    51 Utf8* alloc8BitBuffer( const Utf8* aSource )
       
    52     {
       
    53     int length( 0 );
       
    54     while ( aSource && aSource[length] != '\0' )
       
    55         {
       
    56         length++;
       
    57         }
       
    58     length++; // for the NULL characher
       
    59     
       
    60     Utf8* result = new (EMM) Utf8[ length ];
       
    61     
       
    62     for ( int c = 0; c < ( length - 1 ); c++ )
       
    63         {
       
    64         result[c] = aSource[c];
       
    65         }
       
    66         
       
    67     result[length - 1] = '\0'; // add the NULL character at the end
       
    68     return result;
       
    69     }
       
    70 ********************************************/    
       
    71  
       
    72 Utf8* allocLowerCase( const Utf8* aTag )
       
    73     {
       
    74     const unsigned int length = aTag ? strlen(aTag) : 0;
       
    75     Utf8* result = new (EMM) Utf8[ length+1 ];
       
    76     for ( int s = 0 ; s < length ; s++ )
       
    77         {
       
    78         result[s] = tolower( aTag[s]);
       
    79         }
       
    80     result[length] = '\0'; // add the NULL character at the end
       
    81     return result;
       
    82     }
       
    83     
       
    84 TInt RoundFloatToInt(TReal32 aVal)
       
    85 	{
       
    86 	return (aVal < 0 ? (TInt)(aVal - 0.5f) : (TInt)(aVal + 0.5f));
       
    87 	}
       
    88 
       
    89 // ======== MEMBER FUNCTIONS ========
       
    90 
       
    91 ResourcePoolImpl::ImageResource::ImageResource()
       
    92 : mTag(0), mAspectRatio( ResourcePool::aspectRatioPreserved ), mReferenceCount(1)
       
    93     {
       
    94     mInitialSizeHint.iX.iMagnitude = INITIAL_IMAGE_WIDTH;
       
    95     mInitialSizeHint.iX.iUnit = EAlfUnitPixel;
       
    96     mInitialSizeHint.iY.iMagnitude = INITIAL_IMAGE_HEIGHT;
       
    97     mInitialSizeHint.iY.iUnit = EAlfUnitPixel;
       
    98     }
       
    99     
       
   100 ResourcePoolImpl::ImageResource::~ImageResource()
       
   101     {
       
   102     delete mTag;
       
   103     }
       
   104 
       
   105 // ---------------------------------------------------------------------------
       
   106 // ?description_if_needed
       
   107 // ---------------------------------------------------------------------------
       
   108 //
       
   109 ResourcePoolImpl::ResourcePoolImpl( 
       
   110     CAlfTextureManager& aTextureManager,
       
   111     ResourcePool* aParentPool )
       
   112  : mTextureManager( aTextureManager ),
       
   113    mParentPool( aParentPool )
       
   114     {
       
   115     //This may throw an exception leading to object creation failure.
       
   116     
       
   117     }
       
   118 
       
   119 // ---------------------------------------------------------------------------
       
   120 // ?description_if_needed
       
   121 // ---------------------------------------------------------------------------
       
   122 //
       
   123 ResourcePoolImpl::~ResourcePoolImpl()
       
   124     {
       
   125 
       
   126   
       
   127     // delete the texture instances
       
   128     for ( int resourceIndex = 0 ; resourceIndex < mResources.count() ; resourceIndex++ )
       
   129         {
       
   130         ImageResource* resource = mResources[resourceIndex];
       
   131         for ( int textureIndex = 0 ; textureIndex < resource->mLoadedTextures.count() ; textureIndex++ )
       
   132             {
       
   133             const CAlfTexture* texture = mTextureManager.Texture( resource->mLoadedTextures[textureIndex]->mTextureId);
       
   134             if ( texture->Id() == resource->mLoadedTextures[textureIndex]->mTextureId )
       
   135                 {
       
   136                 // make sure we do not delete blank texure
       
   137                 delete texture;
       
   138 
       
   139                 if (resource->mLoadedTextures[textureIndex]->mAutoSizeTexture)
       
   140                     {
       
   141                     mTextureManager.RemoveAutoSizeObserver(resource->mLoadedTextures[textureIndex]->mImageLoaderUtil);        
       
   142                     }            
       
   143                 }
       
   144             }
       
   145         }
       
   146     // items in mResources will be automatically deleted in the destructor of
       
   147     // the AlfPtrVector 
       
   148     }
       
   149 
       
   150 
       
   151 void ResourcePoolImpl::createLogicalImageResource( const Utf8* aTag )
       
   152     {
       
   153     }
       
   154 
       
   155 void ResourcePoolImpl::createThemeImageResource(
       
   156     const Utf8* aTag,
       
   157     const UString& aThemeDefinition )
       
   158     {
       
   159     	
       
   160     	
       
   161     }
       
   162     
       
   163 void ResourcePoolImpl::createFileImageResource( 
       
   164     const Utf8* aTag,
       
   165     const UString& aFileName , TAlfTextureFlags aFlag)
       
   166     {
       
   167     if ( !aTag ) 
       
   168         {
       
   169         throw invalid_argument("NULL ptr");
       
   170         }
       
   171     auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aTag ) );
       
   172     
       
   173     ImageResource* existingResource = findResource( lowerCaseTag.get() );
       
   174     if ( existingResource )
       
   175         {
       
   176         existingResource->mReferenceCount++;
       
   177         return;
       
   178         }
       
   179         
       
   180     // : check that the file exists.
       
   181     
       
   182     auto_ptr<FileImageResource> newFileResource( new (EMM) FileImageResource );
       
   183     newFileResource->mTag = lowerCaseTag.get();
       
   184     lowerCaseTag.release();
       
   185     newFileResource->mType = imageResourceTypeFileOther;
       
   186     newFileResource->mFileName = aFileName;
       
   187     newFileResource->mFlag = aFlag;
       
   188     // check the .svg prefix
       
   189     const long length = aFileName.getCharLength();
       
   190     if ( length > 4 )
       
   191         {
       
   192         auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aFileName.getUtf8() ) );
       
   193         if ( lowerCaseTag.get()[length-4] == '.' &&
       
   194              lowerCaseTag.get()[length-3] == 's' &&
       
   195              lowerCaseTag.get()[length-2] == 'v' &&
       
   196              lowerCaseTag.get()[length-1] == 'g' )
       
   197             {
       
   198             newFileResource->mType = imageResourceTypeFileSVG;
       
   199             }
       
   200         }
       
   201     
       
   202     mResources.resize(mResources.count()+1);
       
   203     mResources.insert(mResources.count(),newFileResource.get());
       
   204     newFileResource.release();
       
   205     }
       
   206 
       
   207 
       
   208 // ---------------------------------------------------------------------------
       
   209 // ?implementation_description
       
   210 // ---------------------------------------------------------------------------
       
   211 //    
       
   212 void ResourcePoolImpl::deleteImageResource( const Utf8* aTag )
       
   213     {
       
   214     auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aTag ) );
       
   215     
       
   216     ImageResource* existingResource = findResource( lowerCaseTag.get() );
       
   217     if ( !existingResource )
       
   218         {
       
   219         return;
       
   220         }
       
   221     
       
   222     existingResource->mReferenceCount--;
       
   223     if ( existingResource->mReferenceCount > 0 )
       
   224         {
       
   225         // not time to delete yet.
       
   226         return;
       
   227         }
       
   228     
       
   229     const int resouceIndex = findResourceIndex( lowerCaseTag.get() );
       
   230 
       
   231     // delete CAlfTexture instances created by this resource
       
   232     if ( resouceIndex != -1 )
       
   233        {
       
   234        ImageResource* resource = mResources[resouceIndex];
       
   235         for ( int textureIndex = 0 ; textureIndex < resource->mLoadedTextures.count() ; textureIndex++ )
       
   236             {
       
   237             const CAlfTexture* texture = mTextureManager.Texture( resource->mLoadedTextures[textureIndex]->mTextureId);
       
   238             if ( texture->Id() == resource->mLoadedTextures[textureIndex]->mTextureId )
       
   239                 {
       
   240                 // make sure we do not delete blank texure
       
   241                 delete texture;
       
   242                 
       
   243                 if (resource->mLoadedTextures[textureIndex]->mAutoSizeTexture)
       
   244                     {
       
   245                     mTextureManager.RemoveAutoSizeObserver(resource->mLoadedTextures[textureIndex]->mImageLoaderUtil);        
       
   246                     }            
       
   247                 }
       
   248             }
       
   249         
       
   250         mResources.remove( resouceIndex );
       
   251        }
       
   252     }
       
   253 
       
   254 // ---------------------------------------------------------------------------
       
   255 // ?implementation_description
       
   256 // ---------------------------------------------------------------------------
       
   257 //    
       
   258 bool ResourcePoolImpl::hasImageResource( const Utf8* aTag ) const
       
   259     {
       
   260     auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aTag ) );
       
   261     int resouceIndex = findResourceIndex( lowerCaseTag.get() );
       
   262     if ( resouceIndex != -1 )
       
   263         {
       
   264         return true;
       
   265         }
       
   266         
       
   267     return false;
       
   268     }
       
   269 
       
   270 // ---------------------------------------------------------------------------
       
   271 // ?implementation_description
       
   272 // ---------------------------------------------------------------------------
       
   273 //      
       
   274 void ResourcePoolImpl::setInitialSize( 
       
   275     const Utf8* aTag, 
       
   276     const TAlfXYMetric& aInitialSizeHint )
       
   277     {
       
   278     auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aTag ) );
       
   279     ImageResource* imageResource = findResource( lowerCaseTag.get() );
       
   280     if ( imageResource )
       
   281         {
       
   282         imageResource->mInitialSizeHint = aInitialSizeHint;
       
   283         }
       
   284     }
       
   285     
       
   286 // ---------------------------------------------------------------------------
       
   287 // ?implementation_description
       
   288 // ---------------------------------------------------------------------------
       
   289 //     
       
   290 void ResourcePoolImpl::setAspectRatio( 
       
   291         const Utf8* aTag, 
       
   292         ResourcePool::AspectRatio aAspectRatio )
       
   293     {
       
   294     auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aTag ) );
       
   295     ImageResource* imageResource = findResource( lowerCaseTag.get() );
       
   296     if ( imageResource )
       
   297         {
       
   298         imageResource->mAspectRatio = aAspectRatio;
       
   299         }
       
   300     }
       
   301 
       
   302 // ---------------------------------------------------------------------------
       
   303 // ?implementation_description
       
   304 // ---------------------------------------------------------------------------
       
   305 //
       
   306 TAlfImage ResourcePoolImpl::getImageResource( const Utf8* aTag )
       
   307     {
       
   308     auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aTag ) );
       
   309     ImageResource* imageResource = findResource( lowerCaseTag.get() );
       
   310     if ( imageResource )
       
   311         {
       
   312         return getImageResource( 
       
   313             lowerCaseTag.get() , 
       
   314             imageResource->mInitialSizeHint );
       
   315         }
       
   316     return TAlfImage(); // return empty
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // ?implementation_description
       
   321 // ---------------------------------------------------------------------------
       
   322 //
       
   323 TAlfImage ResourcePoolImpl::getImageResource( 
       
   324     const Utf8* aTag, 
       
   325     const TAlfXYMetric& aSizeHint )
       
   326     {
       
   327     auto_ptr<Utf8> lowerCaseTag( allocLowerCase( aTag ) );
       
   328     
       
   329     ImageResource* imageResource = findResource( lowerCaseTag.get() );
       
   330     if ( imageResource )
       
   331         {
       
   332         // check if the texture ID with the given size hint is already generated
       
   333         if ( imageResource->mLoadedTextures.count() )
       
   334             {
       
   335             const TSize requestedSize( determineSizeInPixels(aSizeHint) );
       
   336             const CAlfTexture* texture = NULL;
       
   337             for ( TInt idIndex = 0 ; idIndex < imageResource->mLoadedTextures.count() ; idIndex++ )
       
   338                 {
       
   339                 texture = mTextureManager.Texture(imageResource->mLoadedTextures[idIndex]->mTextureId);
       
   340                 if ( texture->Id() != imageResource->mLoadedTextures[idIndex]->mTextureId )
       
   341                     {
       
   342                     // if the texture manager returns blank, return empty.
       
   343                     return TAlfImage(); // return empty
       
   344                     }
       
   345                 TSize textureSize( const_cast<CAlfTexture*>(texture)->MaxTextureSize() );
       
   346                 if ( textureSize.iWidth == 0 || textureSize.iHeight == 0 )
       
   347                     {
       
   348                     // texture loaded directly with the size, use that.
       
   349                     textureSize = texture->Size();
       
   350                     }
       
   351                 
       
   352                 const bool autosize = imageResource->mLoadedTextures[idIndex]->mAutoSizeTexture;
       
   353                 if ( requestedSize == TSize(0,0) && autosize )
       
   354                     {
       
   355                     // if zero size is requested, we think autosizing image is requested
       
   356                     // and if we find one autosizing texture we return it.
       
   357                     return TAlfImage( *texture );                        
       
   358                     }
       
   359                 else if ( areSizesCloseEnough( requestedSize, textureSize ) && !autosize )
       
   360                     {
       
   361                     // we found existing texure -> use that
       
   362                     return TAlfImage( *texture );
       
   363                     }
       
   364                 }
       
   365             }
       
   366             
       
   367         // If we have not found a suitable resource, create one.    
       
   368         TAlfImage result;
       
   369         TRAPD( sError , 
       
   370             {
       
   371                 
       
   372             // Create new one.
       
   373             switch( imageResource->mType )
       
   374                 {
       
   375                 case imageResourceTypeSkin:
       
   376                     result = CreateSkinImageResourceL( 
       
   377                         static_cast<SkinImageResource&>( *imageResource ), aSizeHint );
       
   378                     break;
       
   379                     
       
   380                 case imageResourceTypeFileOther:
       
   381                     result = CreateFileImageResourceL( 
       
   382                         static_cast<FileImageResource&>( *imageResource ), aSizeHint , imageResource->mFlag );
       
   383                     break;
       
   384                     
       
   385                 case imageResourceTypeFileSVG:
       
   386                     result = CreateSVGImageResourceL( 
       
   387                         static_cast<FileImageResource&>( *imageResource ), aSizeHint );
       
   388                     break;
       
   389                     
       
   390                 default:
       
   391                     break;
       
   392                 }
       
   393             }); // TRAP
       
   394                 
       
   395         if ( sError != KErrNone  )
       
   396             {
       
   397             throw invalid_argument("cannot create image resource");
       
   398             }
       
   399         return result;
       
   400         }
       
   401     else
       
   402         {
       
   403         // this pool does not contain the resource, check the parent pool
       
   404         if ( mParentPool )
       
   405             {
       
   406             return mParentPool->getImageResource( lowerCaseTag.get(), aSizeHint );
       
   407             }
       
   408         }
       
   409     
       
   410     return TAlfImage(); // return empty
       
   411     }
       
   412 
       
   413 // ---------------------------------------------------------------------------
       
   414 // ?implementation_description
       
   415 // ---------------------------------------------------------------------------
       
   416 //
       
   417 ResourcePoolImpl::ImageResource* ResourcePoolImpl::findResource( const Utf8* aTag ) const
       
   418     {
       
   419     const int index = findResourceIndex( aTag );
       
   420     if ( index != -1 )
       
   421         {
       
   422         return mResources.at(index);
       
   423         }
       
   424     return NULL;
       
   425     }
       
   426 
       
   427 // ---------------------------------------------------------------------------
       
   428 // ?implementation_description
       
   429 // ---------------------------------------------------------------------------
       
   430 //    
       
   431 int ResourcePoolImpl::findResourceIndex( const Utf8* aTag ) const
       
   432     {
       
   433     for ( int i = 0 ; i < mResources.count() ; i++ )
       
   434         {
       
   435         // : find a better way to compare
       
   436         int c = 0;
       
   437         while ( mResources.at(i)->mTag[c] != '\0' )
       
   438             {
       
   439             if ( mResources.at(i)->mTag[c] != aTag[c] )
       
   440                 {
       
   441                 break;
       
   442                 }
       
   443             c++;
       
   444             }
       
   445             
       
   446         if ( mResources.at(i)->mTag[c] == '\0' && aTag[c] == '\0' )
       
   447             {
       
   448             return i;
       
   449             }
       
   450         }
       
   451     return -1;
       
   452     }
       
   453 
       
   454 // ---------------------------------------------------------------------------
       
   455 // ?implementation_description
       
   456 // ---------------------------------------------------------------------------
       
   457 //
       
   458 void ResourcePoolImpl::DetermineSkinInstanceL( 
       
   459     const Utf8* aTag, TAknsItemID& aSkinItemID ) const
       
   460     {
       
   461     }
       
   462 
       
   463 // ---------------------------------------------------------------------------
       
   464 // ?implementation_description
       
   465 // ---------------------------------------------------------------------------
       
   466 //
       
   467 TSize ResourcePoolImpl::determineSizeInPixels( const TAlfXYMetric& aSize )
       
   468     {
       
   469     TSize result(0,0);
       
   470     TRect displayRect(0,0,0,0);
       
   471     
       
   472     // check X
       
   473     if ( aSize.iX.iUnit == EAlfUnitPixel )
       
   474         {
       
   475         result.iWidth = aSize.iX.iMagnitude;
       
   476         }
       
   477     else if ( aSize.iX.iUnit == EAlfUnitDisplaySize )
       
   478         {
       
   479         // check the primary display
       
   480         if ( mTextureManager.Env().DisplayCount() )
       
   481             {
       
   482             const CAlfDisplay& display = mTextureManager.Env().PrimaryDisplay();
       
   483             displayRect = display.VisibleArea();
       
   484             result.iWidth = RoundFloatToInt( TReal32(displayRect.Width())*aSize.iX.iUnit );
       
   485             }
       
   486         }
       
   487         
       
   488     // check Y
       
   489     if ( aSize.iY.iUnit == EAlfUnitPixel )
       
   490         {
       
   491         result.iHeight = aSize.iY.iMagnitude;
       
   492         }
       
   493     else if ( aSize.iY.iUnit == EAlfUnitDisplaySize )
       
   494         {
       
   495         // check the primary display (if not checked already
       
   496         if ( !displayRect.Height() && mTextureManager.Env().DisplayCount() )
       
   497             {
       
   498             const CAlfDisplay& display = mTextureManager.Env().PrimaryDisplay();
       
   499             displayRect = display.VisibleArea();
       
   500             }
       
   501         result.iHeight = RoundFloatToInt( TReal32(displayRect.Height())*aSize.iY.iUnit );
       
   502         }
       
   503         
       
   504     return result;
       
   505     }
       
   506 
       
   507 // ---------------------------------------------------------------------------
       
   508 // ?implementation_description
       
   509 // ---------------------------------------------------------------------------
       
   510 //
       
   511 void ResourcePoolImpl::determineSkinId( const UString& aNumberString, int& aSkinItem )
       
   512     {
       
   513     aSkinItem = -1;
       
   514     
       
   515     const unsigned int charLength = aNumberString.getCharLength();
       
   516     if ( charLength )
       
   517         {
       
   518         // there is something
       
   519         // check if we are dealing with hexadecimal entry
       
   520         const string strNumber = aNumberString.getUtf8();
       
   521         if ( charLength > 3 && strNumber.substr(0,2).compare( KResourcePoolHexadecimalPrefix ) == 0 )
       
   522             {
       
   523             // hexa it is
       
   524             aSkinItem = strtol( aNumberString.getUtf8(), NULL, 16 );
       
   525             }
       
   526         else
       
   527             {
       
   528             // try normal decimal number
       
   529             aSkinItem = atoi( aNumberString.getUtf8() );
       
   530             // if the 'atoi' returns 0, make sure it is that
       
   531             if ( aSkinItem == 0 )
       
   532                 {
       
   533                 if ( aNumberString.getUtf8()[0] != '0' )
       
   534                     {
       
   535                     aSkinItem = -1;
       
   536                     }
       
   537                 }
       
   538             }
       
   539         }
       
   540     }
       
   541 
       
   542 
       
   543 // ---------------------------------------------------------------------------
       
   544 // ?implementation_description
       
   545 // ---------------------------------------------------------------------------
       
   546 //
       
   547 TAlfImage ResourcePoolImpl::CreateSkinImageResourceL(
       
   548     SkinImageResource& aSkinImageResource, 
       
   549     const TAlfXYMetric& aSizeHint)
       
   550     {
       
   551     CAlfAutoSizeImageLoaderUtil* imageLoaderUtil = new (ELeave) CAlfAutoSizeImageLoaderUtil;
       
   552     CleanupStack::PushL( imageLoaderUtil );
       
   553     CAlfTexture* texture = NULL;
       
   554     MAlfBitmapProvider* bitmapProvider = NULL;
       
   555 
       
   556     TAknsItemID skinId;
       
   557     skinId.Set( aSkinImageResource.mSkinIdMajor, aSkinImageResource.mSkinIdMinor );
       
   558 
       
   559     TSize size( determineSizeInPixels(aSizeHint) );
       
   560     imageLoaderUtil->SetSize( size, static_cast<TScaleMode>(aSkinImageResource.mAspectRatio));
       
   561     
       
   562     TInt textureFlags = IMAGE_RESOURCE_SKINNED_TEXTURE_FLAGS;        
       
   563     if (size != TSize(0,0))
       
   564         {
       
   565         // If sizehint was provided, turn autosize off at least for now.
       
   566         textureFlags &= ~EAlfTextureFlagAutoSize;          
       
   567         }
       
   568             
       
   569     if ( aSkinImageResource.mFallBackFileName.getCharLength() )
       
   570         {    
       
   571         HBufC* sUnicodeBuffer = 
       
   572             CnvUtfConverter::ConvertToUnicodeFromUtf8L(
       
   573                 TPtrC8((TUint8*)aSkinImageResource.mFallBackFileName.getUtf8()));
       
   574         CleanupStack::PushL( sUnicodeBuffer );
       
   575         bitmapProvider =   
       
   576             imageLoaderUtil->CreateImageLoaderL( 
       
   577                 skinId, 
       
   578                 *sUnicodeBuffer, 
       
   579                 aSkinImageResource.mFallBackIndex,
       
   580                 aSkinImageResource.mFallBackMaskIndex );
       
   581         CleanupStack::PopAndDestroy( sUnicodeBuffer );
       
   582         }
       
   583     else
       
   584         {
       
   585         bitmapProvider =  
       
   586             imageLoaderUtil->CreateImageLoaderL( 
       
   587                 skinId, 
       
   588                 KNullDesC(), 
       
   589                 -1,
       
   590                 -1 );
       
   591         }
       
   592         
       
   593     texture = &mTextureManager.CreateTextureL( KAlfAutoGeneratedTextureId, bitmapProvider, TAlfTextureFlags(textureFlags));
       
   594     CleanupStack::PushL( texture );
       
   595     
       
   596     // Enable ref counting
       
   597     texture->EnableRefCounting();
       
   598 
       
   599     // store texture ID and create image
       
   600     ResourceInstanceData* newResourceInstance = new (ELeave) ResourceInstanceData;
       
   601     newResourceInstance->mTextureId = texture->Id();
       
   602     newResourceInstance->mImageLoaderUtil = imageLoaderUtil;
       
   603     newResourceInstance->mAutoSizeTexture = (textureFlags & EAlfTextureFlagAutoSize);
       
   604     
       
   605     try 
       
   606         {
       
   607         aSkinImageResource.mLoadedTextures.resize(aSkinImageResource.mLoadedTextures.count()+1);
       
   608         aSkinImageResource.mLoadedTextures.insert(aSkinImageResource.mLoadedTextures.count(),newResourceInstance);
       
   609         }
       
   610     catch ( ... )
       
   611         {
       
   612         delete newResourceInstance;
       
   613         User::Leave( KErrNoMemory );
       
   614         }
       
   615     CleanupStack::Pop( texture );
       
   616     CleanupStack::Pop( imageLoaderUtil ); // mLoadedTextures has taken the ownership
       
   617 
       
   618     if (textureFlags & EAlfTextureFlagAutoSize)
       
   619         {
       
   620         mTextureManager.AddAutoSizeObserverL(imageLoaderUtil);    
       
   621         }    
       
   622 
       
   623     return TAlfImage( *texture );
       
   624     }
       
   625 
       
   626 // ---------------------------------------------------------------------------
       
   627 // ?implementation_description
       
   628 // ---------------------------------------------------------------------------
       
   629 //
       
   630 TAlfImage ResourcePoolImpl::CreateFileImageResourceL(
       
   631     FileImageResource& aFileImageResource, 
       
   632     const TAlfXYMetric& aSizeHint ,  TAlfTextureFlags aFlag)
       
   633     {
       
   634     CAlfTexture* texture = NULL;
       
   635    
       
   636     HBufC* sUnicodeBuffer = 
       
   637         CnvUtfConverter::ConvertToUnicodeFromUtf8L(
       
   638             TPtrC8((TUint8*)aFileImageResource.mFileName.getUtf8()));
       
   639     CleanupStack::PushL( sUnicodeBuffer );
       
   640     TSize size(determineSizeInPixels( aSizeHint ) );
       
   641     
       
   642     TInt textureFlags = IMAGE_RESOURCE_DEFAULT_TEXTURE_FLAGS;
       
   643     textureFlags |= aFlag;
       
   644     if (size != TSize(0,0))
       
   645         {
       
   646         // If sizehint was provided, turn autosize off at least for now.
       
   647         textureFlags &= ~EAlfTextureFlagAutoSize;          
       
   648         }
       
   649 
       
   650     if ( size.iWidth && size.iHeight )
       
   651         {
       
   652         texture = &mTextureManager.LoadTextureL( 
       
   653             *sUnicodeBuffer,
       
   654             size, 
       
   655             TAlfTextureFlags(textureFlags), 
       
   656             KAlfAutoGeneratedTextureId );
       
   657         }
       
   658     else
       
   659         {
       
   660         texture = &mTextureManager.LoadTextureL( 
       
   661             *sUnicodeBuffer, 
       
   662             TAlfTextureFlags(textureFlags), 
       
   663             KAlfAutoGeneratedTextureId );
       
   664         }
       
   665     CleanupStack::PopAndDestroy( sUnicodeBuffer );
       
   666     CleanupStack::PushL( texture );
       
   667 
       
   668     // Enable ref counting
       
   669     texture->EnableRefCounting();
       
   670 
       
   671     // store texture ID and create image
       
   672     ResourceInstanceData* newResourceInstance = new (ELeave) ResourceInstanceData;
       
   673     newResourceInstance->mTextureId = texture->Id();
       
   674     newResourceInstance->mAutoSizeTexture = (textureFlags & EAlfTextureFlagAutoSize);
       
   675     
       
   676     try 
       
   677         {
       
   678         aFileImageResource.mLoadedTextures.resize(aFileImageResource.mLoadedTextures.count()+1);
       
   679         aFileImageResource.mLoadedTextures.insert(aFileImageResource.mLoadedTextures.count(),newResourceInstance);
       
   680         }
       
   681     catch ( ... )
       
   682         {
       
   683         delete newResourceInstance;
       
   684         User::Leave( KErrNoMemory );
       
   685         }
       
   686     
       
   687     CleanupStack::Pop( texture );
       
   688     return TAlfImage( *texture );
       
   689     }
       
   690 
       
   691 // ---------------------------------------------------------------------------
       
   692 // ?implementation_description
       
   693 // ---------------------------------------------------------------------------
       
   694 //
       
   695 TAlfImage ResourcePoolImpl::CreateSVGImageResourceL(
       
   696     FileImageResource& aSVGImageResource, 
       
   697     const TAlfXYMetric& aSizeHint)
       
   698     {        
       
   699     CAlfAutoSizeImageLoaderUtil* imageLoaderUtil = new (ELeave) CAlfAutoSizeImageLoaderUtil;
       
   700     CleanupStack::PushL( imageLoaderUtil );
       
   701     MAlfBitmapProvider* bitmapProvider = NULL;
       
   702     CAlfTexture* texture = NULL;
       
   703 
       
   704     TSize size( determineSizeInPixels(aSizeHint) );
       
   705     imageLoaderUtil->SetSize( size, static_cast<TScaleMode>(aSVGImageResource.mAspectRatio) );
       
   706 
       
   707     TInt textureFlags = IMAGE_RESOURCE_SKINNED_TEXTURE_FLAGS;
       
   708     if (size != TSize(0,0))
       
   709         {
       
   710         // If sizehint was provided, turn autosize off at least for now.
       
   711         textureFlags &= ~EAlfTextureFlagAutoSize;          
       
   712         }
       
   713             
       
   714     HBufC* sUnicodeBuffer = 
       
   715         CnvUtfConverter::ConvertToUnicodeFromUtf8L(
       
   716             TPtrC8((TUint8*)aSVGImageResource.mFileName.getUtf8()));
       
   717     CleanupStack::PushL( sUnicodeBuffer );
       
   718     bitmapProvider = imageLoaderUtil->CreateSVGImageLoaderL( *sUnicodeBuffer );
       
   719     CleanupStack::PopAndDestroy( sUnicodeBuffer );
       
   720     
       
   721     texture = &mTextureManager.CreateTextureL( KAlfAutoGeneratedTextureId, bitmapProvider, TAlfTextureFlags(textureFlags));
       
   722     CleanupStack::PushL( texture );
       
   723     
       
   724     // Enable ref counting
       
   725     texture->EnableRefCounting();
       
   726     
       
   727     // store texture ID and create image
       
   728     ResourceInstanceData* newResourceInstance = new (ELeave) ResourceInstanceData;
       
   729     newResourceInstance->mTextureId = texture->Id();
       
   730     newResourceInstance->mImageLoaderUtil = imageLoaderUtil;
       
   731     newResourceInstance->mAutoSizeTexture = (textureFlags & EAlfTextureFlagAutoSize);
       
   732     
       
   733     try 
       
   734         {
       
   735         aSVGImageResource.mLoadedTextures.resize(aSVGImageResource.mLoadedTextures.count()+1);
       
   736         aSVGImageResource.mLoadedTextures.insert(aSVGImageResource.mLoadedTextures.count(),newResourceInstance);
       
   737         }
       
   738     catch ( ... )
       
   739         {
       
   740         delete newResourceInstance;
       
   741         User::Leave( KErrNoMemory );
       
   742         }
       
   743     CleanupStack::Pop( texture );
       
   744     CleanupStack::Pop( imageLoaderUtil ); // mLoadedTextures has taken the ownership 
       
   745 
       
   746     if (textureFlags & EAlfTextureFlagAutoSize)
       
   747         {
       
   748         mTextureManager.AddAutoSizeObserverL(imageLoaderUtil);    
       
   749         }    
       
   750 
       
   751     return TAlfImage( *texture );
       
   752     }
       
   753     
       
   754 bool ResourcePoolImpl::areSizesCloseEnough( const TSize& aSize1, const TSize& aSize2 )
       
   755     {
       
   756     // this is the inteligent part:)
       
   757     // the function tries to determine do we need to rasterize a new texture or use the existing one.
       
   758    
       
   759     // check if the other one is zero size
       
   760     if ( !aSize1.iWidth || !aSize1.iHeight || !aSize2.iWidth || !aSize2.iHeight )
       
   761         {
       
   762         return false;
       
   763         }
       
   764         
       
   765     // check if both are smaller than 10px
       
   766     if ( aSize1.iWidth < 10 && aSize1.iHeight < 10 && aSize2.iWidth < 10 && aSize2.iHeight < 10 )
       
   767         {
       
   768         return true;
       
   769         }
       
   770         
       
   771     // check if both dimensions fit in 10% range.
       
   772     bool result = false;
       
   773     // check width
       
   774     if ( aSize1.iWidth <= aSize2.iWidth*1.1f && aSize1.iWidth >= aSize2.iWidth*0.9f )
       
   775         {
       
   776         // width in the range, chech height
       
   777         if ( aSize1.iHeight <= aSize2.iHeight*1.1f && aSize1.iHeight >= aSize2.iHeight*0.9f )
       
   778             {
       
   779             // height in the range
       
   780             result = true;
       
   781             }
       
   782         }
       
   783     
       
   784     return result;
       
   785     }
       
   786     
       
   787 } // namespace Alf
       
   788