javauis/lcdui_akn/lcdgr/src/LcdFbsImageCache.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2005 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:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "LcdFbsImageCache.h"
       
    20 #include "CMIDImage.h"
       
    21 #include "CMIDBitmapImage.h"
       
    22 #include "LcdImage.h"
       
    23 
       
    24 /**
       
    25  * Copy bitmap data from (aColorBitmap,aAlphaBitmap) to aFbsImage.
       
    26  */
       
    27 extern void CopyBitmapsL
       
    28 (
       
    29     CLcdGraphicsDriver& aDriver,
       
    30     CLcdFbsImage&       aFbsImage,
       
    31     CFbsBitmap*         aColorBitmap,
       
    32     CFbsBitmap*         aAlphaBitmap,
       
    33     TBool               aInvertMask
       
    34 );
       
    35 
       
    36 TInt CompareImageAddress(const TLcdFbsImageEntry& aLhs, const TLcdFbsImageEntry& aRhs)
       
    37 {
       
    38     return (aLhs.iImage - aRhs.iImage);
       
    39 }
       
    40 
       
    41 TBool MatchEntry(const TLcdFbsImageEntry& aLhs, const TLcdFbsImageEntry& aRhs)
       
    42 {
       
    43     return aLhs.iImage       == aRhs.iImage     &&
       
    44            aLhs.iColorMode  == aRhs.iColorMode &&
       
    45            aLhs.iAlphaMode  == aRhs.iAlphaMode &&
       
    46            aLhs.iInvertMask == aRhs.iInvertMask;
       
    47 }
       
    48 
       
    49 CLcdFbsImageCache* CLcdFbsImageCache::NewL(CLcdGraphicsDriver& aDriver, TDisplayMode aDefaultColorMode, TDisplayMode aDefaultAlphaMode, TBool aDefaultInverted)
       
    50 {
       
    51     CLcdFbsImageCache* cache = new(ELeave) CLcdFbsImageCache(aDriver);
       
    52     cache->iDefaultColorMode = aDefaultColorMode;
       
    53     cache->iDefaultAlphaMode = aDefaultAlphaMode;
       
    54     cache->iDefaultInverted = aDefaultInverted;
       
    55     return cache;
       
    56 }
       
    57 
       
    58 CLcdFbsImageCache::CLcdFbsImageCache(CLcdGraphicsDriver& aDriver)
       
    59         : iDriver(aDriver)
       
    60         , iEntries(8, _FOFF(TLcdFbsImageEntry, iImage))
       
    61         , iOrder(CompareImageAddress)
       
    62 {
       
    63 }
       
    64 
       
    65 CLcdFbsImageCache::~CLcdFbsImageCache()
       
    66 {
       
    67     for (TInt i = iEntries.Count(); --i>=0;)
       
    68     {
       
    69         RemoveEntry(i);
       
    70     }
       
    71     iEntries.Reset();
       
    72     iEntries.Close();
       
    73 }
       
    74 
       
    75 TDisplayMode ValidateMode(TInt aMode, TDisplayMode aDefault)
       
    76 {
       
    77     if (aMode == MMIDBitmapImage::EDefaultDisplayMode)
       
    78     {
       
    79         return aDefault;
       
    80     }
       
    81     return (TDisplayMode)aMode;
       
    82 }
       
    83 
       
    84 
       
    85 /**
       
    86  * Gets the primary bitmap representation of this image.
       
    87  */
       
    88 MMIDBitmapImage* CLcdFbsImageCache::GetBitmapImage(MMIDImage* aImage)
       
    89 {
       
    90     TLcdFbsImageEntry example;
       
    91     example.iImage      = aImage;
       
    92     example.iPrimary    = ETrue;    // not used in Find.
       
    93     example.iColorMode  = ENone;
       
    94     example.iAlphaMode  = ENone;
       
    95     example.iInvertMask = EFalse;
       
    96     example.iBitmapRep  = NULL;
       
    97 
       
    98     //
       
    99     // Get a start point for the search. Assuming that FindInOrder
       
   100     // does a binary search of some sort, then it will probably
       
   101     // end up in the middle of the range of entries corresponding
       
   102     // to aImage. Note that iEntries is sorted by aImage address.
       
   103     //
       
   104     TInt start = iEntries.FindInOrder(example, iOrder);
       
   105     TInt count = iEntries.Count();
       
   106     TInt index;
       
   107 
       
   108     ASSERT(start >= 0);
       
   109 
       
   110     //
       
   111     // Search backwards from start point
       
   112     //
       
   113     for (index=start; index>=0; --index)
       
   114     {
       
   115         TLcdFbsImageEntry& entry = iEntries[index];
       
   116         if (entry.iImage != aImage)
       
   117         {
       
   118             break;
       
   119         }
       
   120         if (entry.iPrimary)
       
   121         {
       
   122             entry.iBitmapRep->AddRef();
       
   123             return entry.iBitmapRep;
       
   124         }
       
   125     }
       
   126 
       
   127     //
       
   128     // We didn't find it searching backwards - try forwards
       
   129     //
       
   130     for (index=start+1; index<count; index++)
       
   131     {
       
   132         TLcdFbsImageEntry& entry = iEntries[index];
       
   133         if (entry.iImage != aImage)
       
   134         {
       
   135             break;
       
   136         }
       
   137         if (entry.iPrimary)
       
   138         {
       
   139             entry.iBitmapRep->AddRef();
       
   140             return entry.iBitmapRep;
       
   141         }
       
   142     }
       
   143 
       
   144     return NULL;
       
   145 }
       
   146 
       
   147 /**
       
   148  * Find A bitmap image representation of aImage with color bitmap in displaymode aColorMode, and alpha
       
   149  * bitmap (if present) in displaymode aAlphaMode. If aColorMode or aAlphaMode are EDefaultDisplayMode,
       
   150  * then this method will select a mode based on the default image pixel format.
       
   151  *
       
   152  *@return a bitmap image or NULL if no appropriate bitmap representation of aImage exists.
       
   153  */
       
   154 MMIDBitmapImage* CLcdFbsImageCache::GetBitmapImage(MMIDImage* aImage, TInt aColorMode, TInt aAlphaMode, TBool aInvertMask)
       
   155 {
       
   156     TDisplayMode defaultAlphaMode = (aImage->TransparencyType() == MMIDImage::ENone ? ENone : iDefaultAlphaMode);
       
   157 
       
   158     TIdentityRelation<TLcdFbsImageEntry> relation(MatchEntry);
       
   159     TLcdFbsImageEntry entry;
       
   160 
       
   161     entry.iImage      = aImage;
       
   162     entry.iColorMode  = ValidateMode(aColorMode, iDefaultColorMode);;
       
   163     entry.iAlphaMode  = ValidateMode(aAlphaMode, defaultAlphaMode);
       
   164     entry.iInvertMask = aInvertMask;
       
   165     entry.iPrimary    = EFalse;
       
   166     entry.iBitmapRep  = NULL;
       
   167 
       
   168     // linear search starting at
       
   169     TInt index = iEntries.Find(entry, relation);
       
   170     if (index >= 0)
       
   171     {
       
   172         MMIDBitmapImage* bitmapRep = iEntries[index].iBitmapRep;
       
   173         bitmapRep->AddRef();
       
   174         return bitmapRep;
       
   175     }
       
   176 
       
   177     return NULL;
       
   178 }
       
   179 
       
   180 
       
   181 /**
       
   182  * Find or create a bitmap image representation of aImage with a color bitmap in displaymode aColorMode and
       
   183  * alpha bitmap (if present) in displaymode  aAlphaMode.
       
   184  *
       
   185  *@return a bitmap image representation.
       
   186  *
       
   187  * Will leave with one of the system error codes if a bitmap representation does not exist and one cannot
       
   188  * be created.
       
   189  */
       
   190 MMIDBitmapImage* CLcdFbsImageCache::GetBitmapImageL(MMIDImage* aImage, TInt aColorMode, TInt aAlphaMode, TBool aInvertMask)
       
   191 {
       
   192     TDisplayMode colorMode = ValidateMode(aColorMode, iDefaultColorMode);
       
   193 
       
   194     TDisplayMode defaultAlphaMode = (aImage->TransparencyType() == MMIDImage::ENone ? ENone : iDefaultAlphaMode);
       
   195 
       
   196     TDisplayMode alphaMode = ValidateMode(aAlphaMode, defaultAlphaMode);
       
   197 
       
   198     MMIDBitmapImage* image = GetBitmapImage(aImage, colorMode, alphaMode, aInvertMask);
       
   199     if (NULL == image)
       
   200     {
       
   201         image = CreateBitmapImageRepLC(*aImage, colorMode, alphaMode, aInvertMask);
       
   202         TLcdFbsImageEntry entry;
       
   203         entry.iImage      = aImage;
       
   204         entry.iPrimary    = EFalse;
       
   205         entry.iColorMode  = colorMode;
       
   206         entry.iAlphaMode  = alphaMode;
       
   207         entry.iInvertMask = aInvertMask;
       
   208         entry.iBitmapRep  = image;
       
   209         iEntries.InsertInOrderAllowRepeatsL(entry, iOrder);
       
   210         image->AddRef();        // 1 for the cache
       
   211         CleanupStack::Pop();    // image
       
   212         image->AddRef();        // 1 for the caller
       
   213     }
       
   214 
       
   215     ASSERT(image);
       
   216     return image;
       
   217 }
       
   218 
       
   219 TDisplayMode BitmapMode(CFbsBitmap* aBitmapOrNull)
       
   220 {
       
   221     TDisplayMode mode = ENone;
       
   222     if (aBitmapOrNull)
       
   223     {
       
   224         mode = aBitmapOrNull->DisplayMode();
       
   225     }
       
   226     return mode;
       
   227 }
       
   228 
       
   229 void CLcdFbsImageCache::RegisterL(MMIDImage* aImage, TBool aInverted, MMIDBitmapImage* aBitmapImageRep)
       
   230 {
       
   231     TLcdFbsImageEntry entry;
       
   232     entry.iImage      = aImage;
       
   233     entry.iPrimary    = ETrue;
       
   234     entry.iColorMode  = BitmapMode(aBitmapImageRep->ColorBitmap());
       
   235     entry.iAlphaMode  = BitmapMode(aBitmapImageRep->AlphaBitmap());
       
   236     entry.iInvertMask = aInverted;
       
   237     entry.iBitmapRep  = aBitmapImageRep;
       
   238     iEntries.InsertInOrderAllowRepeatsL(entry, iOrder);
       
   239     aBitmapImageRep->AddRef();
       
   240 }
       
   241 
       
   242 //
       
   243 // purge all entries corresponding to aImage.
       
   244 //
       
   245 void CLcdFbsImageCache::Purge(MMIDImage* aImage)
       
   246 {
       
   247     TLcdFbsImageEntry entry;
       
   248     entry.iImage = aImage;
       
   249     TInt index;
       
   250     while ((index = iEntries.FindInOrder(entry, iOrder)) >= 0)
       
   251     {
       
   252         RemoveEntry(index);
       
   253     }
       
   254 }
       
   255 
       
   256 void CLcdFbsImageCache::RemoveEntry(TInt aIndex)
       
   257 {
       
   258     iEntries[aIndex].iBitmapRep->RemoveRef();
       
   259     iEntries.Remove(aIndex);
       
   260 }
       
   261 
       
   262 MMIDBitmapImage* CLcdFbsImageCache::CreateBitmapImageRepLC(MMIDImage& aImage, TDisplayMode aColorMode, TDisplayMode aAlphaMode, TBool aInvertMask)
       
   263 {
       
   264     MMIDBitmapImage* bitmapImage = aImage.BitmapImage();
       
   265     if (!bitmapImage)
       
   266     {
       
   267         User::Leave(KErrGeneral);
       
   268     }
       
   269 
       
   270     CMIDImage& proxy = static_cast<CMIDImage&>(aImage);
       
   271     CLcdImage& image = proxy.Image();
       
   272     const TSize size = proxy.Size();
       
   273     ASSERT(aColorMode != ENone);
       
   274 
       
   275     CMIDBitmapImage* bitmapRep = NULL;
       
   276 
       
   277     CLcdFbsImage* fbsImage = CLcdFbsImage::NewL(size, aColorMode, aAlphaMode);
       
   278     CleanupStack::PushL(fbsImage);
       
   279     CopyBitmapsL(iDriver, *fbsImage, bitmapImage->ColorBitmap(), bitmapImage->AlphaBitmap(), aInvertMask);
       
   280     bitmapRep = new(ELeave) CMIDBitmapImage(*fbsImage);
       
   281     CleanupStack::Pop(fbsImage);
       
   282     CleanupStack::PushL(bitmapRep);
       
   283 
       
   284     return bitmapRep;
       
   285 }