javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtimage.cpp
branchRCL_3
changeset 19 04becd199f91
child 60 6c158198356e
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved. This program and the accompanying materials
       
     4  * are made available under the terms of the Eclipse Public License v1.0
       
     5  * which accompanies this distribution, and is available at
       
     6  * http://www.eclipse.org/legal/epl-v10.html
       
     7  *
       
     8  * Contributors:
       
     9  *     Nokia Corporation - S60 implementation
       
    10  *******************************************************************************/
       
    11 
       
    12 
       
    13 #include "swtimage.h"
       
    14 #include "swtgrimagedata.h"
       
    15 #include "swtgrpalettedata.h"
       
    16 #include "swtcontrolhelper.h"
       
    17 #include "swtdisplay.h" // needed for macro definitions
       
    18 
       
    19 
       
    20 // Look-up table for the bit-reversed value of a byte.
       
    21 static const TUint8 KBitReverseTable[256] =
       
    22 {
       
    23     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
       
    24     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
       
    25     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
       
    26     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
       
    27     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
       
    28     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
       
    29     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
       
    30     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
       
    31     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
       
    32     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
       
    33     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
       
    34     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
       
    35     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
       
    36     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
       
    37     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
       
    38     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
       
    39     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
       
    40     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
       
    41     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
       
    42     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
       
    43     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
       
    44     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
       
    45     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
       
    46     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
       
    47     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
       
    48     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
       
    49     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
       
    50     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
       
    51     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
       
    52     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
       
    53     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
       
    54     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
       
    55 };
       
    56 
       
    57 
       
    58 // ======== MEMBER FUNCTIONS ========
       
    59 
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // CSwtImage::NewL
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CSwtImage* CSwtImage::NewL(MSwtDevice& aDevice, const TSize& aSize,
       
    66                            MSwtDisplay& aDisplay, TDisplayMode aMode /*=ENone*/)
       
    67 {
       
    68     CSwtImage* self = new(ELeave) CSwtImage(&aDevice, &aDisplay);
       
    69     CleanupStack::PushL(self);
       
    70     self->ConstructL(aSize, aMode);
       
    71     CleanupStack::Pop(self);
       
    72     return self;
       
    73 }
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // CSwtImage::NewL
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 CSwtImage* CSwtImage::NewL(MSwtDevice* aDevice, const MSwtImageData& aData,
       
    80                            MSwtDisplay* aDisplay)
       
    81 {
       
    82     CSwtImage* self = new(ELeave) CSwtImage(aDevice, aDisplay);
       
    83     CleanupStack::PushL(self);
       
    84     self->ConstructL(aData);
       
    85     CleanupStack::Pop(self);
       
    86     return self;
       
    87 }
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // CSwtImage::NewL
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 CSwtImage* CSwtImage::NewL(CFbsBitmap& aBitmap, CFbsBitmap* aMask,
       
    94                            const TPoint& aTopLeft, TInt aDelayTime, TSwtGifDisposal aDisposalMethod)
       
    95 {
       
    96     CSwtImage* self = new(ELeave) CSwtImage(NULL, NULL);
       
    97     CleanupStack::PushL(self);
       
    98     self->ConstructL(aBitmap, aMask, aTopLeft, aDelayTime, aDisposalMethod);
       
    99     CleanupStack::Pop(self);
       
   100     return self;
       
   101 }
       
   102 
       
   103 // ---------------------------------------------------------------------------
       
   104 // CSwtImage::CSwtImage
       
   105 // ---------------------------------------------------------------------------
       
   106 //
       
   107 inline CSwtImage::CSwtImage(MSwtDevice* aDevice, MSwtDisplay* aDisplay)
       
   108         : iDevice(aDevice)
       
   109         , iMaskType(ENoMask)
       
   110         , iDisplay(aDisplay)
       
   111 {
       
   112 }
       
   113 
       
   114 // ---------------------------------------------------------------------------
       
   115 // CSwtImage::~CSwtImage
       
   116 // ---------------------------------------------------------------------------
       
   117 //
       
   118 CSwtImage::~CSwtImage()
       
   119 {
       
   120     iScaledMasks.ResetAndDestroy();
       
   121     iScaledMasksInverted.ResetAndDestroy();
       
   122     iScaledBitmaps.ResetAndDestroy();
       
   123     iScaledBitmapRefs.Close();
       
   124     delete iColorKey;
       
   125     if (!iOwnExternally)
       
   126     {
       
   127         delete iMask;
       
   128         delete iBitmap;
       
   129     }
       
   130     delete iMaskInverted;
       
   131     delete iBitmapDevice;
       
   132     if (iDisplay)
       
   133     {
       
   134         iDisplay->RemoveResourceChangeObserver(this);
       
   135     }
       
   136 }
       
   137 
       
   138 // ---------------------------------------------------------------------------
       
   139 // CSwtImage::ConstructL
       
   140 // ---------------------------------------------------------------------------
       
   141 //
       
   142 void CSwtImage::ConstructL(const TSize& aSize, TDisplayMode aMode)
       
   143 {
       
   144     ASSERT(iDevice);
       
   145     ASSERT(iDisplay);
       
   146 
       
   147     // Create the bitmap
       
   148     iBitmap = new(ELeave) CFbsBitmap;
       
   149 
       
   150     // By default set the image color depth to that of the device.
       
   151     TDisplayMode mode = (aMode != ENone) ? aMode :
       
   152                         iDisplay->CoeEnv()->ScreenDevice()->DisplayMode();
       
   153 
       
   154     // 12-bit images aren't handled by SWT, neither will we
       
   155     if (mode == EColor4K)
       
   156     {
       
   157         mode = iDisplay->CoeEnv()->ScreenDevice()->DisplayMode();
       
   158     }
       
   159 
       
   160     User::LeaveIfError(iBitmap->Create(aSize, mode));
       
   161 
       
   162     // We have to set twips size of bitmap because this is used in order to get
       
   163     // best sized fonts if a GC is created on this bitmap ( if we don't then
       
   164     // HAL will be used and maybe this could return wrong values if device
       
   165     // resolution has changed )
       
   166     iBitmap->SetSizeInTwips(&(iDevice->GraphicsDevice()));
       
   167     iDisplay->AddResourceChangeObserverL(this);
       
   168 
       
   169     // Create the bitmap device
       
   170     iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap);
       
   171 
       
   172     // Initialise the image information
       
   173     iInfo.iSize = aSize;
       
   174     iInfo.iDepth = BitDepth(mode);
       
   175     iInfo.iScanlinePad = ScanlinePadding(iInfo.iDepth);
       
   176     iInfo.iBytesPerLine = BytesPerLine(iInfo.iSize.iWidth, iInfo.iDepth,
       
   177                                        iInfo.iScanlinePad);
       
   178     iInfo.iTransparentPixel = -1;
       
   179     iInfo.iMaskPad =  0;
       
   180     iInfo.iAlpha = -1;
       
   181     iInfo.iType = ESwtImagePng;
       
   182     iInfo.iTopLeft = TPoint(0, 0);
       
   183     iInfo.iDisposalMethod = KSwtDisposalUnspecified;
       
   184     iInfo.iDelayTime = 0;
       
   185 }
       
   186 
       
   187 // ---------------------------------------------------------------------------
       
   188 // CSwtImage::ConstructL
       
   189 // ---------------------------------------------------------------------------
       
   190 //
       
   191 void CSwtImage::ConstructL(const MSwtImageData& aData)
       
   192 {
       
   193     TDisplayMode mode(DisplayMode(aData));
       
   194     if (mode == ENone)
       
   195     {
       
   196         User::Leave(ESwtErrorUnsupportedDepth);
       
   197     }
       
   198 
       
   199     iInfo = aData.Info();
       
   200 
       
   201     // Create the bitmap and its device
       
   202     iBitmap = new(ELeave) CFbsBitmap;
       
   203     User::LeaveIfError(iBitmap->Create(iInfo.iSize, mode));
       
   204     iBitmapDevice = CFbsBitmapDevice::NewL(iBitmap);
       
   205 
       
   206     // Fill the bitmap
       
   207     if (aData.PixelBuffer().Length() != 0)
       
   208     {
       
   209         CopyData(*iBitmap, aData.PixelBuffer(), iInfo.iSize.iHeight,
       
   210                  iInfo.iDepth, iInfo.iBytesPerLine, &(aData.Palette()));
       
   211     }
       
   212     else
       
   213     {
       
   214         FillBitmapL(*iBitmapDevice, KRgbBlack, TRect(iInfo.iSize));
       
   215     }
       
   216 
       
   217     if (iInfo.iAlpha != -1)
       
   218     {
       
   219         // Global alpha value, causes alphaData to be ignored.
       
   220         iMaskType = EAlphaMask;
       
   221         iMask = new(ELeave) CFbsBitmap;
       
   222         User::LeaveIfError(iMask->Create(iInfo.iSize, EGray256));
       
   223 
       
   224         iMask->LockHeap();
       
   225         Mem::Fill(iMask->DataAddress(),
       
   226                   iInfo.iSize.iWidth * iInfo.iSize.iHeight, iInfo.iAlpha);
       
   227         iMask->UnlockHeap();
       
   228     }
       
   229     else
       
   230     {
       
   231         // Binary mask
       
   232         if (aData.MaskBuffer())
       
   233         {
       
   234             iMaskType = EBinaryMask;
       
   235             iMask = new(ELeave) CFbsBitmap;
       
   236             User::LeaveIfError(iMask->Create(iInfo.iSize, EGray2));
       
   237             TInt bpl = BytesPerLine(iInfo.iSize.iWidth, 1, iInfo.iMaskPad);
       
   238             CopyData(*iMask, *aData.MaskBuffer(), iInfo.iSize.iHeight, 1, bpl, NULL);
       
   239         }
       
   240         // Colour key mask, binary mask
       
   241         else if (iInfo.iTransparentPixel != -1)
       
   242         {
       
   243             iMaskType = EDirtyColorKey;
       
   244             iMask = new(ELeave) CFbsBitmap;
       
   245             User::LeaveIfError(iMask->Create(iInfo.iSize, EGray2));
       
   246             SetColorKeyL(aData);
       
   247             ComputeColorKeyMask();
       
   248         }
       
   249         // Alpha mask
       
   250         else if (aData.AlphaBuffer())
       
   251         {
       
   252             iMaskType = EAlphaMask;
       
   253             iMask = new(ELeave) CFbsBitmap;
       
   254             User::LeaveIfError(iMask->Create(iInfo.iSize, EGray256));
       
   255             CopyData(*iMask, *aData.AlphaBuffer(), iInfo.iSize.iHeight, 8,
       
   256                      iInfo.iSize.iWidth, NULL);
       
   257         }
       
   258     }
       
   259 }
       
   260 
       
   261 // ---------------------------------------------------------------------------
       
   262 // CSwtImage::ConstructL
       
   263 // ---------------------------------------------------------------------------
       
   264 //
       
   265 void CSwtImage::ConstructL(CFbsBitmap& aBitmap, CFbsBitmap* aMask,
       
   266                            const TPoint& aTopLeft, TInt aDelayTime, TSwtGifDisposal aDisposalMethod)
       
   267 {
       
   268     // Caution: when using this constructor you depend on the external bitmap's lifetime
       
   269     iOwnExternally = ETrue;
       
   270 
       
   271     iBitmap = &aBitmap;
       
   272     iMask = aMask;
       
   273 
       
   274     TDisplayMode mode = iBitmap->DisplayMode();
       
   275     if (mode == ENone || mode == EColor4K)
       
   276     {
       
   277         // 12-bit images aren't handled by SWT, neither will we
       
   278         User::Leave(ESwtErrorUnsupportedDepth);
       
   279     }
       
   280 
       
   281     iInfo.iSize = iBitmap->SizeInPixels();
       
   282     iInfo.iDepth = BitDepth(mode);
       
   283     iInfo.iScanlinePad = ScanlinePadding(iInfo.iDepth);
       
   284     iInfo.iBytesPerLine = BytesPerLine(iInfo.iSize.iWidth, iInfo.iDepth, iInfo.iScanlinePad);
       
   285     iInfo.iTransparentPixel = -1;
       
   286     iInfo.iMaskPad = 0;
       
   287     iInfo.iAlpha = -1;
       
   288     iInfo.iType = ESwtImagePng;
       
   289     iInfo.iTopLeft = aTopLeft;
       
   290     iInfo.iDisposalMethod = aDisposalMethod;
       
   291     iInfo.iDelayTime = aDelayTime;
       
   292 
       
   293     if (iMask)
       
   294     {
       
   295         if (iMask->DisplayMode() == EGray2)
       
   296         {
       
   297             iMaskType = EBinaryMask;
       
   298         }
       
   299         else
       
   300         {
       
   301             iMaskType = EAlphaMask;
       
   302         }
       
   303     }
       
   304 }
       
   305 
       
   306 // ---------------------------------------------------------------------------
       
   307 // CSwtImage::SetColorKeyL
       
   308 // ---------------------------------------------------------------------------
       
   309 //
       
   310 void CSwtImage::SetColorKeyL(const MSwtImageData& aData)
       
   311 {
       
   312     ASSERT(!iColorKey);
       
   313 
       
   314     iColorKey = new(ELeave) TRgb;
       
   315 
       
   316     const MSwtPaletteData& palette = aData.Palette();
       
   317     const MSwtImageData::TInfo& info = aData.Info();
       
   318 
       
   319     if (palette.IsDirect())
       
   320     {
       
   321         switch (info.iDepth)
       
   322         {
       
   323             // Monochrome, the transparent pixel is either black or white
       
   324         case 1:
       
   325             *iColorKey = (info.iTransparentPixel == 0) ?
       
   326                          TRgb(0, 0, 0) : TRgb(255u, 255u, 255u);
       
   327             break;
       
   328             // Direct colour, extract components
       
   329         case 16:
       
   330         case 24:
       
   331         case 32:
       
   332             *iColorKey = GetRgb(info.iTransparentPixel,
       
   333                                 palette.DirectData());
       
   334             break;
       
   335         default:
       
   336             User::Leave(KErrNotSupported);
       
   337             break;
       
   338         }
       
   339     }
       
   340     else
       
   341     {
       
   342         switch (aData.Info().iDepth)
       
   343         {
       
   344             // Look up the transparent pixel in the palette
       
   345         case 1:
       
   346         case 2:
       
   347         case 4:
       
   348         case 8:
       
   349             *iColorKey = palette.IndirectData()->GetEntry(
       
   350                              info.iTransparentPixel);
       
   351             break;
       
   352         default:
       
   353             User::Leave(KErrNotSupported);
       
   354             break;
       
   355         }
       
   356     }
       
   357 }
       
   358 
       
   359 
       
   360 // ---------------------------------------------------------------------------
       
   361 // CSwtImage::EnsureMaskIsUpToDate
       
   362 // ---------------------------------------------------------------------------
       
   363 //
       
   364 void CSwtImage::EnsureMaskIsUpToDate() const
       
   365 {
       
   366     if (iMaskType == EDirtyColorKey)
       
   367     {
       
   368         const_cast<CSwtImage*>(this)->ComputeColorKeyMask();
       
   369     }
       
   370 }
       
   371 
       
   372 // ---------------------------------------------------------------------------
       
   373 // CSwtImage::ComputeColorKeyMask
       
   374 // ---------------------------------------------------------------------------
       
   375 //
       
   376 void CSwtImage::ComputeColorKeyMask()
       
   377 {
       
   378     ASSERT(iBitmap);
       
   379     ASSERT(iMask && iMask->DisplayMode() == EGray2);
       
   380     ASSERT(iColorKey);
       
   381     ASSERT(iMaskType == EDirtyColorKey);
       
   382 
       
   383     iMask->LockHeap(EFalse);
       
   384     TUint32* maskPtr = iMask->DataAddress();
       
   385 
       
   386     const TSize size(iBitmap->SizeInPixels());
       
   387     const TInt wordsPerMaskLine = CFbsBitmap::ScanLineLength(size.iWidth, EGray2) / 4;
       
   388 
       
   389     TRgb pixel;
       
   390     for (TInt y = 0; y < size.iHeight; ++y)
       
   391     {
       
   392         TUint32 word32 = 0;
       
   393         TInt bitsInWord = 0;
       
   394         TInt wordsWritten = 0;
       
   395 
       
   396         for (TInt x = 0; x < size.iWidth; ++x)
       
   397         {
       
   398             iBitmap->GetPixel(pixel, TPoint(x, y));
       
   399             word32 >>= 1;
       
   400             word32 |= (pixel == *iColorKey) ? 0 : 0x80000000;
       
   401             if (++bitsInWord == 32)
       
   402             {
       
   403                 maskPtr[wordsWritten++] = word32;
       
   404                 bitsInWord = 0;
       
   405             }
       
   406         }
       
   407 
       
   408         if (bitsInWord != 0)
       
   409         {
       
   410             maskPtr[wordsWritten] = word32 >> (32 - bitsInWord);
       
   411         }
       
   412 
       
   413         maskPtr += wordsPerMaskLine;
       
   414     }
       
   415 
       
   416     iMask->UnlockHeap();
       
   417     iMaskType = EColorKey;
       
   418 }
       
   419 
       
   420 // ---------------------------------------------------------------------------
       
   421 // CSwtImage::IsGrayscale
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 TBool CSwtImage::IsGrayscale() const
       
   425 {
       
   426     switch (iBitmap->DisplayMode())
       
   427     {
       
   428     case EGray2:
       
   429     case EGray4:
       
   430     case EGray16:
       
   431     case EGray256:
       
   432         return ETrue;
       
   433     default:
       
   434         return EFalse;
       
   435     }
       
   436 }
       
   437 
       
   438 // ---------------------------------------------------------------------------
       
   439 // CSwtImage::GetPaletteDataL
       
   440 // ---------------------------------------------------------------------------
       
   441 //
       
   442 CSwtGrPaletteData* CSwtImage::GetPaletteDataL() const
       
   443 {
       
   444     TDisplayMode mode(iBitmap->DisplayMode());
       
   445 
       
   446     // Decide whether the palette is direct or indirect
       
   447     TBool isDirect;
       
   448     switch (mode)
       
   449     {
       
   450     case EGray2:
       
   451     case EGray4:
       
   452     case EGray16:
       
   453     case EGray256:
       
   454         isDirect = EFalse;
       
   455         break;
       
   456     case EColor64K:
       
   457     case EColor16M:
       
   458     case EColor16MU:
       
   459     case EColor16MA:
       
   460     case EColor16MAP:
       
   461         isDirect = ETrue;
       
   462         break;
       
   463     default:
       
   464         ASSERT(EFalse);
       
   465         return NULL;
       
   466     }
       
   467 
       
   468     // Create and fill the palette data
       
   469     CSwtGrPaletteData* data = CSwtGrPaletteData::NewL(isDirect);
       
   470     if (isDirect)
       
   471     {
       
   472         CSwtGrPaletteData::TDirectData directData;
       
   473         if (mode == EColor64K)
       
   474         {
       
   475             // 16-bit Symbian bitmaps are stored as [rrrrrggg gggbbbbb] ( binary )
       
   476             directData.iRedMask = 0xF800;   // [11111000 00000000] binary
       
   477             directData.iGreenMask = 0x07E0; // [00000111 11100000] binary
       
   478             directData.iBlueMask = 0x001F;  // [00000000 00011111] binary
       
   479             directData.iRedShift = -8;
       
   480             directData.iGreenShift = -3;
       
   481             directData.iBlueShift =  3;
       
   482         }
       
   483         else if (mode == EColor16M)
       
   484         {
       
   485             // 24-bit Symbian bitmaps are stored in BGR order; 24-bit SWT images
       
   486             // are stored in MSB first order, this yields a pixel format of 0xbbggrr
       
   487             directData.iRedMask = 0x0000FF;
       
   488             directData.iGreenMask = 0x00FF00;
       
   489             directData.iBlueMask = 0xFF0000;
       
   490             directData.iRedShift = 0;
       
   491             directData.iGreenShift = -8;
       
   492             directData.iBlueShift = -16;
       
   493         }
       
   494         else
       
   495         {
       
   496             // EColor16MU, EColor16MA or EColor16MAP
       
   497             // 32-bit Symbian bitmaps are stored in BGR order; 32-bit SWT images
       
   498             // are stored in MSB first order, this yields a pixel format of 0xbbggrraa
       
   499             directData.iRedMask = 0x0000FF00;
       
   500             directData.iGreenMask = 0x00FF0000;
       
   501             directData.iBlueMask = 0xFF000000;
       
   502             directData.iRedShift = -8;
       
   503             directData.iGreenShift = -16;
       
   504             directData.iBlueShift = -24;
       
   505         }
       
   506         data->SetDirectData(directData);
       
   507     }
       
   508     else
       
   509     {
       
   510         data->SetIndirectData(NewGrayPaletteL(mode));
       
   511     }
       
   512 
       
   513     return data;
       
   514 }
       
   515 
       
   516 // ---------------------------------------------------------------------------
       
   517 // CSwtImage::PaletteGrayMode
       
   518 // ---------------------------------------------------------------------------
       
   519 //
       
   520 TDisplayMode CSwtImage::PaletteGrayMode(TInt aDepth, const CPalette& aPalette)
       
   521 {
       
   522     TDisplayMode mode;
       
   523 
       
   524     // Find the mode by looking at the bit depth
       
   525     switch (aDepth)
       
   526     {
       
   527     case 8:
       
   528         mode = EGray256;
       
   529         break;
       
   530     case 4:
       
   531         mode = EGray16;
       
   532         break;
       
   533     case 2:
       
   534         mode = EGray4;
       
   535         break;
       
   536     case 1:
       
   537         mode = EGray2;
       
   538         break;
       
   539     default:
       
   540         mode = ENone;
       
   541         break;
       
   542     }
       
   543 
       
   544     // Check the colours
       
   545     if (mode != ENone)
       
   546     {
       
   547         // Check the number of colours is 2^depth
       
   548         const TInt count = aPalette.Entries();
       
   549         if (count != (1 << aDepth))
       
   550         {
       
   551             return ENone;
       
   552         }
       
   553 
       
   554         // Check the colours are indeed gray and evenly scattered
       
   555         for (TInt i = 0; i<count; ++i)
       
   556         {
       
   557             TInt l = (i*255) / (count - 1);
       
   558             if (aPalette.GetEntry(i) != TRgb(l, l, l))
       
   559             {
       
   560                 return ENone;
       
   561             }
       
   562         }
       
   563     }
       
   564 
       
   565     return mode;
       
   566 }
       
   567 
       
   568 // ---------------------------------------------------------------------------
       
   569 // CSwtImage::DisplayMode
       
   570 // ---------------------------------------------------------------------------
       
   571 //
       
   572 TDisplayMode CSwtImage::DisplayMode(const MSwtImageData& aData)
       
   573 {
       
   574     TDisplayMode mode(ENone);
       
   575 
       
   576     const MSwtPaletteData& palette = aData.Palette();
       
   577     const MSwtImageData::TInfo& info = aData.Info();
       
   578 
       
   579     // Non paletted modes
       
   580     if (palette.IsDirect())
       
   581     {
       
   582         switch (info.iDepth)
       
   583         {
       
   584         case 1:
       
   585             mode = EGray2;
       
   586             break;
       
   587         case 16:
       
   588             mode = EColor64K;
       
   589             break;
       
   590         case 8:
       
   591         case 24:
       
   592             mode = EColor16M;
       
   593             break;
       
   594         case 32:
       
   595             mode = EColor16MU;
       
   596             break;
       
   597         default:
       
   598             break;
       
   599         }
       
   600     }
       
   601     // Paletted modes
       
   602     else
       
   603     {
       
   604         // For some reason, CFbsBitmap::SetPalette() is implemented as empty.
       
   605         // The result is that paletted modes are not handled correctly. The
       
   606         // workaround is to convert all colour paletted modes to 24 bits, we
       
   607         // waste a lot of memory but at least it works.
       
   608         TDisplayMode grayMode(PaletteGrayMode(info.iDepth,
       
   609                                               *(palette.IndirectData())));
       
   610         mode = (grayMode != ENone) ? grayMode : EColor16MU;
       
   611     }
       
   612 
       
   613     return mode;
       
   614 }
       
   615 
       
   616 // ---------------------------------------------------------------------------
       
   617 // CSwtImage::BitDepth
       
   618 // ---------------------------------------------------------------------------
       
   619 //
       
   620 TInt CSwtImage::BitDepth(TDisplayMode aMode)
       
   621 {
       
   622     return TDisplayModeUtils::NumDisplayModeBitsPerPixel(aMode);
       
   623 }
       
   624 
       
   625 // ---------------------------------------------------------------------------
       
   626 // CSwtImage::ImageDepth
       
   627 // ---------------------------------------------------------------------------
       
   628 //
       
   629 TInt CSwtImage::ImageDepth() const
       
   630 {
       
   631     switch (iBitmap->DisplayMode())
       
   632     {
       
   633     case EGray2:
       
   634         return 1;
       
   635     case EGray4:
       
   636         return 2;
       
   637     case EGray16:
       
   638         return 4;
       
   639     case EGray256:
       
   640         return 8;
       
   641     case EColor16:
       
   642         return 4;
       
   643     case EColor256:
       
   644         return 8;
       
   645     case EColor64K:
       
   646         return 16;
       
   647     case EColor16M:
       
   648         return 24;
       
   649     case EColor16MU:
       
   650         return 32;
       
   651     case EColor16MA:
       
   652         return 32;
       
   653     case EColor16MAP:
       
   654         return 32;
       
   655     case ERgb:
       
   656         return 24;
       
   657     case EColor4K:
       
   658         return 12;
       
   659 
       
   660     default:
       
   661     case ENone:
       
   662     case EColorLast:
       
   663         ASSERT(EFalse);
       
   664         return 0;
       
   665     }
       
   666 }
       
   667 
       
   668 // ---------------------------------------------------------------------------
       
   669 // CSwtImage::ScanlinePadding
       
   670 // ---------------------------------------------------------------------------
       
   671 //
       
   672 TInt CSwtImage::ScanlinePadding(TInt aBitDepth)
       
   673 {
       
   674     switch (aBitDepth)
       
   675     {
       
   676     case 1:
       
   677     case 2:
       
   678     case 4:
       
   679     case 16:
       
   680     case 24:
       
   681     case 32:
       
   682         return 4;
       
   683     case 8:
       
   684         // This is because of alpha data which is not supposed to have padding
       
   685         return 1;
       
   686     default:
       
   687         ASSERT(EFalse);
       
   688         return 0;
       
   689     }
       
   690 }
       
   691 
       
   692 // ---------------------------------------------------------------------------
       
   693 // CSwtImage::BytesPerLine
       
   694 // ---------------------------------------------------------------------------
       
   695 //
       
   696 TInt CSwtImage::BytesPerLine(TInt aPixelsPerLine, TInt aBitsPerPixel,
       
   697                              TInt aPadding)
       
   698 {
       
   699     TInt byteCount = (aPixelsPerLine * aBitsPerPixel + 7) / 8;
       
   700     TInt remainder = byteCount % aPadding;
       
   701     TInt extra = (remainder != 0) ? aPadding-remainder : 0;
       
   702     return byteCount + extra;
       
   703 }
       
   704 
       
   705 // ---------------------------------------------------------------------------
       
   706 // CSwtImage::FillBitmapL
       
   707 // ---------------------------------------------------------------------------
       
   708 //
       
   709 void CSwtImage::FillBitmapL(CFbsBitmapDevice& aDevice, const TRgb& aColor,
       
   710                             const TRect& aRect)
       
   711 {
       
   712     CFbsBitGc* gc = CFbsBitGc::NewL();
       
   713     gc->Activate(&aDevice);
       
   714 
       
   715     gc->SetPenStyle(CGraphicsContext::ENullPen);
       
   716     gc->SetBrushStyle(CGraphicsContext::ESolidBrush);
       
   717     gc->SetBrushColor(aColor);
       
   718     gc->DrawRect(aRect);
       
   719 
       
   720     delete gc;
       
   721 }
       
   722 
       
   723 // ---------------------------------------------------------------------------
       
   724 // CSwtImage::BitBltBitmapL
       
   725 // ---------------------------------------------------------------------------
       
   726 //
       
   727 void CSwtImage::BitBltBitmapL(CFbsBitmapDevice& aDevice, const CFbsBitmap& aBitmap)
       
   728 {
       
   729     CFbsBitGc* gc = CFbsBitGc::NewL();
       
   730     gc->Activate(&aDevice);
       
   731     gc->BitBlt(TPoint(0,0), &aBitmap);
       
   732     delete gc;
       
   733 }
       
   734 
       
   735 
       
   736 // ---------------------------------------------------------------------------
       
   737 // CSwtImage::FillBitmapL
       
   738 // ---------------------------------------------------------------------------
       
   739 //
       
   740 void CSwtImage::FillBitmapL(CFbsBitmap& aBitmap, const TRgb& aColor,
       
   741                             const TRect& aRect)
       
   742 {
       
   743     CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(&aBitmap);
       
   744     CleanupStack::PushL(device);
       
   745     FillBitmapL(*device, aColor, aRect);
       
   746     CleanupStack::PopAndDestroy(device);
       
   747 }
       
   748 
       
   749 // ---------------------------------------------------------------------------
       
   750 // CSwtImage::NewGrayPaletteL
       
   751 // ---------------------------------------------------------------------------
       
   752 //
       
   753 CPalette* CSwtImage::NewGrayPaletteL(TDisplayMode aMode)
       
   754 {
       
   755     TInt count;
       
   756 
       
   757     switch (aMode)
       
   758     {
       
   759     case EGray2:
       
   760         count = 2;
       
   761         break;
       
   762     case EGray4:
       
   763         count = 4;
       
   764         break;
       
   765     case EGray16:
       
   766         count = 16;
       
   767         break;
       
   768     case EGray256:
       
   769         count = 256;
       
   770         break;
       
   771     default:
       
   772         ASSERT(EFalse);
       
   773         return NULL;
       
   774     }
       
   775 
       
   776     CPalette* palette = CPalette::NewL(count);
       
   777     for (TInt i = 0; i < count; ++i)
       
   778     {
       
   779         TInt shade = (i*255) / (count-1);
       
   780         palette->SetEntry(i, TRgb(shade, shade, shade));
       
   781     }
       
   782 
       
   783     return palette;
       
   784 }
       
   785 
       
   786 // ---------------------------------------------------------------------------
       
   787 // CSwtImage::BitShift
       
   788 // ---------------------------------------------------------------------------
       
   789 //
       
   790 inline TUint CSwtImage::BitShift(TUint aValue, TInt aShift)
       
   791 {
       
   792     return (aShift >= 0) ? (aValue << aShift) : (aValue >> -aShift);
       
   793 }
       
   794 
       
   795 // ---------------------------------------------------------------------------
       
   796 // CSwtImage::GetRed
       
   797 // ---------------------------------------------------------------------------
       
   798 //
       
   799 inline TUint CSwtImage::GetRed(TUint aPixel,
       
   800                                const MSwtPaletteData::TDirectData& aPalette)
       
   801 {
       
   802     return BitShift(aPixel & aPalette.iRedMask, aPalette.iRedShift);
       
   803 }
       
   804 
       
   805 // ---------------------------------------------------------------------------
       
   806 // CSwtImage::GetGreen
       
   807 // ---------------------------------------------------------------------------
       
   808 //
       
   809 inline TUint CSwtImage::GetGreen(TUint aPixel,
       
   810                                  const MSwtPaletteData::TDirectData& aPalette)
       
   811 {
       
   812     return BitShift(aPixel & aPalette.iGreenMask, aPalette.iGreenShift);
       
   813 }
       
   814 
       
   815 // ---------------------------------------------------------------------------
       
   816 // CSwtImage::GetBlue
       
   817 // ---------------------------------------------------------------------------
       
   818 //
       
   819 inline TUint CSwtImage::GetBlue(TUint aPixel,
       
   820                                 const MSwtPaletteData::TDirectData& aPalette)
       
   821 {
       
   822     return BitShift(aPixel & aPalette.iBlueMask, aPalette.iBlueShift);
       
   823 }
       
   824 
       
   825 // ---------------------------------------------------------------------------
       
   826 // CSwtImage::GetBlue
       
   827 // ---------------------------------------------------------------------------
       
   828 //
       
   829 inline TRgb CSwtImage::GetRgb(TUint aPixel,
       
   830                               const MSwtPaletteData::TDirectData& aPalette)
       
   831 {
       
   832     return TRgb(GetRed(aPixel, aPalette), GetGreen(aPixel, aPalette), GetBlue(aPixel, aPalette));
       
   833 }
       
   834 
       
   835 // ---------------------------------------------------------------------------
       
   836 // CSwtImage::WritePixel16
       
   837 // ---------------------------------------------------------------------------
       
   838 //
       
   839 inline void CSwtImage::WritePixel16(TUint8*& aPtr, TUint aPixel,
       
   840                                     const MSwtPaletteData::TDirectData& aPalette)
       
   841 {
       
   842     TUint pixel16;
       
   843     pixel16  = (GetRed(aPixel, aPalette) & 0xF8) << 8;
       
   844     pixel16 |= (GetGreen(aPixel, aPalette) & 0xFC) << 3;
       
   845     pixel16 |= (GetBlue(aPixel, aPalette)) >> 3;
       
   846 
       
   847     *reinterpret_cast<TUint16*&>(aPtr)++ = static_cast<TUint16>(pixel16);
       
   848 }
       
   849 
       
   850 // ---------------------------------------------------------------------------
       
   851 // CSwtImage::WritePixelTrueColor
       
   852 // ---------------------------------------------------------------------------
       
   853 //
       
   854 inline void CSwtImage::WritePixelTrueColor(TUint8*& aPtr, const TRgb& aColor, TBool a24Bit)
       
   855 {
       
   856     *aPtr++ = static_cast<TUint8>(aColor.Blue());
       
   857     *aPtr++ = static_cast<TUint8>(aColor.Green());
       
   858     *aPtr++ = static_cast<TUint8>(aColor.Red());
       
   859 
       
   860     if (!a24Bit)
       
   861     {
       
   862         // Since we don't get any alpha channel data for the 32-bit pixel,
       
   863         // set it opaque.
       
   864         *aPtr++ = 0xFF;
       
   865     }
       
   866 }
       
   867 
       
   868 
       
   869 // ---------------------------------------------------------------------------
       
   870 // CSwtImage::WritePixelTrueColor
       
   871 // ---------------------------------------------------------------------------
       
   872 //
       
   873 inline void CSwtImage::WritePixelTrueColor(TUint8*& aPtr, TUint aPixel,
       
   874         const MSwtPaletteData::TDirectData& aPalette, TBool a24Bit)
       
   875 {
       
   876     if (a24Bit)
       
   877     {
       
   878         *aPtr++ = static_cast<TUint8>(GetBlue(aPixel, aPalette));
       
   879         *aPtr++ = static_cast<TUint8>(GetGreen(aPixel, aPalette));
       
   880         *aPtr++ = static_cast<TUint8>(GetRed(aPixel, aPalette));
       
   881     }
       
   882     else
       
   883     {
       
   884         *aPtr++ = static_cast<TUint8>(GetBlue(aPixel, aPalette));
       
   885         *aPtr++ = static_cast<TUint8>(GetGreen(aPixel, aPalette));
       
   886         *aPtr++ = static_cast<TUint8>(GetRed(aPixel, aPalette));
       
   887         // Alpha value is the last byte of the pixel.
       
   888         *aPtr++ = static_cast<TUint8>(aPixel & 0xFF);
       
   889     }
       
   890 }
       
   891 
       
   892 
       
   893 // ---------------------------------------------------------------------------
       
   894 // CSwtImage::CopyData
       
   895 // ---------------------------------------------------------------------------
       
   896 //
       
   897 void CSwtImage::CopyData(const CFbsBitmap& aBitmap, const TDesC8& aData,
       
   898                          TInt aLineCount, TInt aDepth, TInt aBytesPerLine,
       
   899                          const MSwtPaletteData* aPalette)
       
   900 {
       
   901     aBitmap.LockHeap(EFalse);
       
   902 
       
   903     const TUint8* srce = aData.Ptr();
       
   904     TUint8* dest = reinterpret_cast<TUint8*>(aBitmap.DataAddress());
       
   905 
       
   906     TDisplayMode mode(aBitmap.DisplayMode());
       
   907     TInt destBytesPerLine = CFbsBitmap::ScanLineLength(
       
   908                                 aBitmap.SizeInPixels().iWidth, mode);
       
   909 
       
   910     switch (mode)
       
   911     {
       
   912     case EGray2:
       
   913         Copy1(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount);
       
   914         break;
       
   915     case EGray4:
       
   916         Copy2(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount);
       
   917         break;
       
   918     case EGray16:
       
   919         Copy4(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount);
       
   920         break;
       
   921     case EGray256:
       
   922         Copy8(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount);
       
   923         break;
       
   924     case EColor64K:
       
   925         ASSERT(aPalette);
       
   926         Copy16(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount,
       
   927                aPalette->DirectData());
       
   928         break;
       
   929     case EColor16M:
       
   930     case EColor16MU:
       
   931     case EColor16MA:
       
   932     case EColor16MAP:
       
   933         ASSERT(aPalette);
       
   934         switch (aDepth)
       
   935         {
       
   936         case 1:
       
   937             Copy1ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine,
       
   938                              aLineCount, *aPalette->IndirectData(), mode == EColor16M);
       
   939             break;
       
   940         case 2:
       
   941             Copy2ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine,
       
   942                              aLineCount, *aPalette->IndirectData(), mode == EColor16M);
       
   943             break;
       
   944         case 4:
       
   945             Copy4ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine,
       
   946                              aLineCount, *aPalette->IndirectData(), mode == EColor16M);
       
   947             break;
       
   948         case 8:
       
   949             if (aPalette->IsDirect())
       
   950             {
       
   951                 Copy8ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine,
       
   952                                  aLineCount, aPalette->DirectData(), mode == EColor16M);
       
   953             }
       
   954             else
       
   955             {
       
   956                 Copy8ToTrueColor(dest, destBytesPerLine, srce, aBytesPerLine,
       
   957                                  aLineCount, *aPalette->IndirectData(), mode == EColor16M);
       
   958             }
       
   959             break;
       
   960         case 24:
       
   961             Copy24(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount,
       
   962                    aPalette->DirectData());
       
   963             break;
       
   964         case 32:
       
   965             Copy32(dest, destBytesPerLine, srce, aBytesPerLine, aLineCount,
       
   966                    aPalette->DirectData());
       
   967             break;
       
   968         default:
       
   969             ASSERT(EFalse);
       
   970             break;
       
   971         }
       
   972         break;
       
   973     default:
       
   974         ASSERT(EFalse);
       
   975         break;
       
   976     }
       
   977 
       
   978     aBitmap.UnlockHeap();
       
   979 }
       
   980 
       
   981 
       
   982 // ---------------------------------------------------------------------------
       
   983 // CSwtImage::CopyDataWithAlpha
       
   984 // ---------------------------------------------------------------------------
       
   985 //
       
   986 void CSwtImage::AddMaskToAlphaChannel(const CFbsBitmap& aBitmap, const CFbsBitmap& aMask)
       
   987 {
       
   988 
       
   989     ASSERT(aBitmap.DisplayMode() == EColor16MA
       
   990            || aBitmap.DisplayMode() == EColor16MAP);
       
   991     ASSERT(aMask.DisplayMode() == EGray256);
       
   992 
       
   993     aBitmap.LockHeap(EFalse);
       
   994     TUint8* dest = reinterpret_cast<TUint8*>(aBitmap.DataAddress());
       
   995 
       
   996     TUint8* srce = reinterpret_cast<TUint8*>(aMask.DataAddress());
       
   997 
       
   998 
       
   999 
       
  1000     for (TInt i = 0; i < aMask.SizeInPixels().iHeight * aMask.SizeInPixels().iWidth; ++i)
       
  1001     {
       
  1002         // 1 byte = B; 2 byte = G; 3 byte = R; 4 byte = alpha
       
  1003         // skip rgb byte
       
  1004         dest++; // skip b
       
  1005         dest++; // skip g
       
  1006         dest++; // skip r
       
  1007 
       
  1008         // copy alpha vaule
       
  1009         *dest = *srce;
       
  1010 
       
  1011         // go next byte
       
  1012         srce++;
       
  1013         dest++;
       
  1014     }
       
  1015 
       
  1016     aBitmap.UnlockHeap();
       
  1017 }
       
  1018 
       
  1019 // ---------------------------------------------------------------------------
       
  1020 // CSwtImage::Copy1
       
  1021 // ---------------------------------------------------------------------------
       
  1022 //
       
  1023 void CSwtImage::Copy1(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1024                       TInt aBytesPerSrceLine, TInt aLineCount)
       
  1025 {
       
  1026     ASSERT(aDest);
       
  1027     ASSERT(aSrce);
       
  1028 
       
  1029     const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine);
       
  1030 
       
  1031     for (TInt y = 0; y < aLineCount; ++y)
       
  1032     {
       
  1033         for (TInt x = 0; x < bytesToCopyPerLine; ++x)
       
  1034         {
       
  1035             aDest[x] = KBitReverseTable[aSrce[x]];
       
  1036         }
       
  1037         aDest += aBytesPerDestLine;
       
  1038         aSrce += aBytesPerSrceLine;
       
  1039     }
       
  1040 }
       
  1041 
       
  1042 // ---------------------------------------------------------------------------
       
  1043 // CSwtImage::Copy2
       
  1044 // ---------------------------------------------------------------------------
       
  1045 //
       
  1046 void CSwtImage::Copy2(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1047                       TInt aBytesPerSrceLine, TInt aLineCount)
       
  1048 {
       
  1049     ASSERT(aDest);
       
  1050     ASSERT(aSrce);
       
  1051 
       
  1052     const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine);
       
  1053 
       
  1054     for (TInt y = 0; y < aLineCount; ++y)
       
  1055     {
       
  1056         for (TInt x = 0; x < bytesToCopyPerLine; ++x)
       
  1057         {
       
  1058             TUint byte = aSrce[x];
       
  1059             aDest[x] = static_cast<TUint8>
       
  1060                        ((byte >> 6) |
       
  1061                         ((byte >> 2) & 0x0C) |
       
  1062                         ((byte << 2) & 0x30) |
       
  1063                         (byte << 6));
       
  1064         }
       
  1065         aDest += aBytesPerDestLine;
       
  1066         aSrce += aBytesPerSrceLine;
       
  1067     }
       
  1068 }
       
  1069 
       
  1070 // ---------------------------------------------------------------------------
       
  1071 // CSwtImage::Copy4
       
  1072 // ---------------------------------------------------------------------------
       
  1073 //
       
  1074 void CSwtImage::Copy4(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1075                       TInt aBytesPerSrceLine, TInt aLineCount)
       
  1076 {
       
  1077     ASSERT(aDest);
       
  1078     ASSERT(aSrce);
       
  1079 
       
  1080     const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine);
       
  1081 
       
  1082     for (TInt y = 0; y < aLineCount; ++y)
       
  1083     {
       
  1084         for (TInt x = 0; x < bytesToCopyPerLine; ++x)
       
  1085         {
       
  1086             TUint byte = aSrce[x];
       
  1087             aDest[x] = static_cast<TUint8>(byte >> 4 | byte << 4);
       
  1088         }
       
  1089         aDest += aBytesPerDestLine;
       
  1090         aSrce += aBytesPerSrceLine;
       
  1091     }
       
  1092 }
       
  1093 
       
  1094 // ---------------------------------------------------------------------------
       
  1095 // CSwtImage::Copy8
       
  1096 // ---------------------------------------------------------------------------
       
  1097 //
       
  1098 void CSwtImage::Copy8(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1099                       TInt aBytesPerSrceLine, TInt aLineCount)
       
  1100 {
       
  1101     ASSERT(aDest);
       
  1102     ASSERT(aSrce);
       
  1103 
       
  1104     const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine);
       
  1105 
       
  1106     for (TInt y = 0; y < aLineCount; ++y)
       
  1107     {
       
  1108         Mem::Copy(aDest, aSrce, bytesToCopyPerLine);
       
  1109         aDest += aBytesPerDestLine;
       
  1110         aSrce += aBytesPerSrceLine;
       
  1111     }
       
  1112 }
       
  1113 
       
  1114 // ---------------------------------------------------------------------------
       
  1115 // CSwtImage::Copy16
       
  1116 // ---------------------------------------------------------------------------
       
  1117 //
       
  1118 void CSwtImage::Copy16(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1119                        TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette)
       
  1120 {
       
  1121     ASSERT(aDest);
       
  1122     ASSERT(aSrce);
       
  1123 
       
  1124     const TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine) & ~0x1;
       
  1125 
       
  1126     for (TInt y = 0; y < aLineCount; ++y)
       
  1127     {
       
  1128         TUint8* ptr = aDest;
       
  1129 
       
  1130         for (TInt x = 0; x < bytesToCopyPerLine; x+=2)
       
  1131         {
       
  1132             // Data in source buffer in stored LSB first
       
  1133             TUint pixel;
       
  1134             pixel  = static_cast<TUint>(aSrce[x]);
       
  1135             pixel |= static_cast<TUint>(aSrce[x+1]) << 8;
       
  1136 
       
  1137             WritePixel16(ptr, pixel, aPalette);
       
  1138         }
       
  1139 
       
  1140         aDest += aBytesPerDestLine;
       
  1141         aSrce += aBytesPerSrceLine;
       
  1142     }
       
  1143 }
       
  1144 
       
  1145 // ---------------------------------------------------------------------------
       
  1146 // CSwtImage::Copy1To24
       
  1147 // ---------------------------------------------------------------------------
       
  1148 //
       
  1149 void CSwtImage::Copy1ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1150                                  TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit)
       
  1151 {
       
  1152     ASSERT(aDest);
       
  1153     ASSERT(aSrce);
       
  1154 
       
  1155     const TInt bytesPerPixel = a24Bit ? 3 : 4;
       
  1156     const TInt pixelsToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel,
       
  1157                                          aBytesPerSrceLine * 8);
       
  1158     const TInt bytesToCopyPerLine  = (pixelsToCopyPerLine + 7) / 8;
       
  1159 
       
  1160     for (TInt y = 0; y < aLineCount; ++y)
       
  1161     {
       
  1162         TUint8* ptr = aDest;
       
  1163 
       
  1164         TInt bitsLeftInLine = pixelsToCopyPerLine;
       
  1165         for (TInt x = 0; x < bytesToCopyPerLine; ++x)
       
  1166         {
       
  1167             TUint8 byte = aSrce[x];
       
  1168             TInt bitsToCopy = Min(bitsLeftInLine, 8);
       
  1169             for (TInt i = 0; i < bitsToCopy; ++i)
       
  1170             {
       
  1171                 WritePixelTrueColor(ptr, aPalette.GetEntry(byte >> 7), a24Bit);
       
  1172                 byte <<= 1;
       
  1173             }
       
  1174             bitsLeftInLine -= 8;
       
  1175         }
       
  1176 
       
  1177         aDest += aBytesPerDestLine;
       
  1178         aSrce += aBytesPerSrceLine;
       
  1179     }
       
  1180 }
       
  1181 
       
  1182 // ---------------------------------------------------------------------------
       
  1183 // CSwtImage::Copy2To24
       
  1184 // ---------------------------------------------------------------------------
       
  1185 //
       
  1186 void CSwtImage::Copy2ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1187                                  TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit)
       
  1188 {
       
  1189     ASSERT(aDest);
       
  1190     ASSERT(aSrce);
       
  1191 
       
  1192     const TInt bytesPerPixel = a24Bit ? 3 : 4;
       
  1193     const TInt pixelsToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel,
       
  1194                                          aBytesPerSrceLine*4);
       
  1195     const TInt bytesToCopyPerLine  = (pixelsToCopyPerLine + bytesPerPixel) / 4;
       
  1196 
       
  1197     for (TInt y = 0; y < aLineCount; ++y)
       
  1198     {
       
  1199         TUint8* ptr = aDest;
       
  1200 
       
  1201         TInt bitsLeftInLine = pixelsToCopyPerLine * 2;
       
  1202         for (TInt x = 0; x < bytesToCopyPerLine; ++x)
       
  1203         {
       
  1204             TUint8 byte = aSrce[x];
       
  1205             TInt bitsToCopy = Min(bitsLeftInLine, 8);
       
  1206             for (TInt i = 0; i < bitsToCopy; i += 2)
       
  1207             {
       
  1208                 WritePixelTrueColor(ptr, aPalette.GetEntry(byte >> 6), a24Bit);
       
  1209                 byte <<= 2;
       
  1210             }
       
  1211             bitsLeftInLine -= 8;
       
  1212         }
       
  1213 
       
  1214         aDest += aBytesPerDestLine;
       
  1215         aSrce += aBytesPerSrceLine;
       
  1216     }
       
  1217 }
       
  1218 
       
  1219 // ---------------------------------------------------------------------------
       
  1220 // CSwtImage::Copy4To24
       
  1221 // ---------------------------------------------------------------------------
       
  1222 //
       
  1223 void CSwtImage::Copy4ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1224                                  TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit)
       
  1225 {
       
  1226     ASSERT(aDest);
       
  1227     ASSERT(aSrce);
       
  1228 
       
  1229     const TInt bytesPerPixel = a24Bit ? 3 : 4;
       
  1230     const TInt pixelsToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel,
       
  1231                                          aBytesPerSrceLine * 2);
       
  1232     const TInt bytesToCopyPerLine = pixelsToCopyPerLine / 2;
       
  1233     const TInt remainderPerLine = pixelsToCopyPerLine % 2;
       
  1234 
       
  1235     for (TInt y = 0; y < aLineCount; ++y)
       
  1236     {
       
  1237         TUint8* ptr = aDest;
       
  1238         TInt x;
       
  1239         for (x = 0; x < bytesToCopyPerLine; ++x)
       
  1240         {
       
  1241             TUint8 byte = aSrce[x];
       
  1242             WritePixelTrueColor(ptr, aPalette.GetEntry(byte >> 4), a24Bit);
       
  1243             WritePixelTrueColor(ptr, aPalette.GetEntry(byte & 0x0F), a24Bit);
       
  1244         }
       
  1245 
       
  1246         if (remainderPerLine != 0)
       
  1247         {
       
  1248             WritePixelTrueColor(ptr, aPalette.GetEntry(aSrce[x] >> 4), a24Bit);
       
  1249         }
       
  1250 
       
  1251         aDest += aBytesPerDestLine;
       
  1252         aSrce += aBytesPerSrceLine;
       
  1253     }
       
  1254 }
       
  1255 
       
  1256 // ---------------------------------------------------------------------------
       
  1257 // CSwtImage::Copy8To24
       
  1258 // ---------------------------------------------------------------------------
       
  1259 //
       
  1260 void CSwtImage::Copy8ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1261                                  TInt aBytesPerSrceLine, TInt aLineCount, const CPalette& aPalette, TBool a24Bit)
       
  1262 {
       
  1263     ASSERT(aDest);
       
  1264     ASSERT(aSrce);
       
  1265 
       
  1266     const TInt bytesPerPixel = a24Bit ? 3 : 4;
       
  1267     const TInt bytesToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel,
       
  1268                                         aBytesPerSrceLine);
       
  1269 
       
  1270     for (TInt y = 0; y < aLineCount; ++y)
       
  1271     {
       
  1272         TUint8* ptr = aDest;
       
  1273 
       
  1274         for (TInt x = 0; x < bytesToCopyPerLine; ++x)
       
  1275         {
       
  1276             WritePixelTrueColor(ptr, aPalette.GetEntry(aSrce[x]), a24Bit);
       
  1277         }
       
  1278 
       
  1279         aDest += aBytesPerDestLine;
       
  1280         aSrce += aBytesPerSrceLine;
       
  1281     }
       
  1282 }
       
  1283 
       
  1284 // ---------------------------------------------------------------------------
       
  1285 // CSwtImage::Copy8To24
       
  1286 // ---------------------------------------------------------------------------
       
  1287 //
       
  1288 void CSwtImage::Copy8ToTrueColor(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1289                                  TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette,
       
  1290                                  TBool a24Bit)
       
  1291 {
       
  1292     ASSERT(aDest);
       
  1293     ASSERT(aSrce);
       
  1294 
       
  1295     const TInt bytesPerPixel = a24Bit ? 3 : 4;
       
  1296     const TInt bytesToCopyPerLine = Min(aBytesPerDestLine / bytesPerPixel,
       
  1297                                         aBytesPerSrceLine);
       
  1298 
       
  1299     const TUint redMax = BitShift(aPalette.iRedMask,  aPalette.iRedShift);
       
  1300     const TUint greenMax = BitShift(aPalette.iGreenMask, aPalette.iGreenShift);
       
  1301     const TUint blueMax = BitShift(aPalette.iBlueMask, aPalette.iBlueShift);
       
  1302 
       
  1303     for (TInt y = 0; y < aLineCount; ++y)
       
  1304     {
       
  1305         TUint8* ptr = aDest;
       
  1306 
       
  1307         for (TInt x = 0; x < bytesToCopyPerLine; ++x)
       
  1308         {
       
  1309             TUint red = (GetRed(aSrce[x], aPalette) * 255u) / redMax;
       
  1310             TUint green = (GetGreen(aSrce[x], aPalette) * 255u) / greenMax;
       
  1311             TUint blue = (GetBlue(aSrce[x], aPalette) * 255u) / blueMax;
       
  1312 
       
  1313             TRgb color(red, green, blue);
       
  1314             WritePixelTrueColor(ptr, color, a24Bit);
       
  1315         }
       
  1316 
       
  1317         aDest += aBytesPerDestLine;
       
  1318         aSrce += aBytesPerSrceLine;
       
  1319     }
       
  1320 }
       
  1321 
       
  1322 // ---------------------------------------------------------------------------
       
  1323 // CSwtImage::Copy24
       
  1324 // ---------------------------------------------------------------------------
       
  1325 //
       
  1326 void CSwtImage::Copy24(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1327                        TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette)
       
  1328 {
       
  1329     ASSERT(aDest);
       
  1330     ASSERT(aSrce);
       
  1331 
       
  1332     TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine);
       
  1333     bytesToCopyPerLine -= bytesToCopyPerLine % 3; // In order to have an integer number of pixels
       
  1334 
       
  1335     for (TInt y = 0; y < aLineCount; ++y)
       
  1336     {
       
  1337         TUint8* ptrDest = aDest;
       
  1338 
       
  1339         for (TInt x = 0; x < bytesToCopyPerLine; x += 3)
       
  1340         {
       
  1341             // Data in source buffer in stored MSB first
       
  1342             TUint pixel;
       
  1343             pixel = static_cast<TUint>(aSrce[x]) << 16;
       
  1344             pixel |= static_cast<TUint>(aSrce[x+1]) << 8;
       
  1345             pixel |= static_cast<TUint>(aSrce[x+2]);
       
  1346 
       
  1347             WritePixelTrueColor(ptrDest, pixel, aPalette, ETrue);
       
  1348         }
       
  1349 
       
  1350         aDest += aBytesPerDestLine;
       
  1351         aSrce += aBytesPerSrceLine;
       
  1352     }
       
  1353 }
       
  1354 
       
  1355 // ---------------------------------------------------------------------------
       
  1356 // CSwtImage::Copy32
       
  1357 // ---------------------------------------------------------------------------
       
  1358 //
       
  1359 void CSwtImage::Copy32(TUint8* aDest, TInt aBytesPerDestLine, const TUint8* aSrce,
       
  1360                        TInt aBytesPerSrceLine, TInt aLineCount, const MSwtPaletteData::TDirectData& aPalette)
       
  1361 {
       
  1362     ASSERT(aDest);
       
  1363     ASSERT(aSrce);
       
  1364 
       
  1365     TInt bytesToCopyPerLine = Min(aBytesPerDestLine, aBytesPerSrceLine);
       
  1366     bytesToCopyPerLine -= bytesToCopyPerLine % 4; // In order to have an integer number of pixels
       
  1367 
       
  1368     for (TInt y = 0; y < aLineCount; ++y)
       
  1369     {
       
  1370         TUint8* ptrDest = aDest;
       
  1371 
       
  1372         for (TInt x = 0; x < bytesToCopyPerLine; x += 4)
       
  1373         {
       
  1374             TUint pixel = 0;
       
  1375 
       
  1376             // Data in source buffer in stored MSB first
       
  1377             pixel = static_cast<TUint>(aSrce[x]) << 24;
       
  1378             pixel |= static_cast<TUint>(aSrce[x+1]) << 16;
       
  1379             pixel |= static_cast<TUint>(aSrce[x+2]) << 8;
       
  1380             pixel |= static_cast<TUint>(aSrce[x+3]);
       
  1381 
       
  1382             WritePixelTrueColor(ptrDest, pixel, aPalette, EFalse);
       
  1383         }
       
  1384 
       
  1385         aDest += aBytesPerDestLine;
       
  1386         aSrce += aBytesPerSrceLine;
       
  1387     }
       
  1388 }
       
  1389 
       
  1390 
       
  1391 // ---------------------------------------------------------------------------
       
  1392 // CSwtImage::GetPixelDataLC
       
  1393 // ---------------------------------------------------------------------------
       
  1394 //
       
  1395 HBufC8* CSwtImage::GetPixelDataLC(const CFbsBitmap& aBitmap)
       
  1396 {
       
  1397     TSize size(aBitmap.SizeInPixels());
       
  1398     TDisplayMode mode(aBitmap.DisplayMode());
       
  1399     TInt depth = BitDepth(mode);
       
  1400     TInt bplSrce = CFbsBitmap::ScanLineLength(size.iWidth, mode);
       
  1401     TInt bplDest = BytesPerLine(size.iWidth, depth, ScanlinePadding(depth));
       
  1402     TInt bufLength = bplDest * size.iHeight;
       
  1403 
       
  1404     HBufC8* buffer = HBufC8::NewLC(bufLength);
       
  1405     TPtr8 des(buffer->Des());
       
  1406     des.SetLength(bufLength);
       
  1407     TUint8* dest = const_cast<TUint8*>(des.Ptr());
       
  1408     Mem::FillZ(dest, bufLength);
       
  1409 
       
  1410     aBitmap.LockHeapLC(ETrue);
       
  1411     const TUint8* srce = reinterpret_cast<TUint8*>(aBitmap.DataAddress());
       
  1412 
       
  1413     switch (mode)
       
  1414     {
       
  1415     case EGray2:
       
  1416         Copy1(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1417         break;
       
  1418     case EGray4:
       
  1419         Copy2(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1420         break;
       
  1421     case EGray16:
       
  1422         Copy4(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1423         break;
       
  1424     case EGray256:
       
  1425         /* This is workaround for case that the image width is not mutliple of four.
       
  1426            The symbian function CFbsBitmap::ScanLineLength() returns muplitple of
       
  1427            four and not the correct size. On the other hand BytesPerLine() returns
       
  1428            the correct size. When using the incorrect size the image is skewed.
       
  1429                Problem occured only on alpha bitmap with PNG images. This is the
       
  1430            reason, why this fix is present only in this switch. Also it does not
       
  1431            occur in 3.2 */
       
  1432 #if defined( RD_SCALABLE_UI_V2 )
       
  1433         bplSrce = bplDest;
       
  1434 #endif // RD_SCALABLE_UI_V2
       
  1435         Copy8(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1436         break;
       
  1437     case EColor64K:
       
  1438         GetPixels16(dest, bplDest, srce, bplSrce, size);
       
  1439         break;
       
  1440     case EColor16M:
       
  1441         Copy8(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1442         break;
       
  1443     case EColor16MU:
       
  1444         Copy8(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1445         break;
       
  1446     case EColor16MA:
       
  1447         Copy8(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1448         break;
       
  1449     case EColor16MAP:
       
  1450         Copy8(dest, bplDest, srce, bplSrce, size.iHeight);
       
  1451         break;
       
  1452     default:
       
  1453         __DEBUGGER();
       
  1454         User::Leave(KErrNotSupported);
       
  1455         break;
       
  1456     };
       
  1457 
       
  1458     CleanupStack::PopAndDestroy(); // LockHeap
       
  1459 
       
  1460     return buffer;
       
  1461 }
       
  1462 
       
  1463 // ---------------------------------------------------------------------------
       
  1464 // CSwtImage::GetPixels16
       
  1465 // ---------------------------------------------------------------------------
       
  1466 //
       
  1467 void CSwtImage::GetPixels16(TUint8* aDest, TInt aBytesPerDestLine,
       
  1468                             const TUint8* aSrce, TInt aBytesPerSrceLine, const TSize& aSize)
       
  1469 {
       
  1470     ASSERT(aDest);
       
  1471     ASSERT(aSrce);
       
  1472 
       
  1473     for (TInt y = 0; y<aSize.iHeight; ++y)
       
  1474     {
       
  1475         const TUint16* ptrSrce = reinterpret_cast<const TUint16*>(aSrce);
       
  1476         TUint8* ptrDest = aDest;
       
  1477 
       
  1478         TInt x;
       
  1479         for (x = 0; x<aSize.iWidth; ++x)
       
  1480         {
       
  1481             TUint16 pixel = *ptrSrce++;
       
  1482 
       
  1483             // Data in dest buffer in stored LSB first
       
  1484             *ptrDest++ = static_cast<TUint8>(pixel & 0x00FF);
       
  1485             *ptrDest++ = static_cast<TUint8>(pixel >> 8);
       
  1486         }
       
  1487 
       
  1488         aDest += aBytesPerDestLine;
       
  1489         aSrce += aBytesPerSrceLine;
       
  1490     }
       
  1491 }
       
  1492 
       
  1493 // ---------------------------------------------------------------------------
       
  1494 // CSwtImage::NewGcL
       
  1495 // From MSwtBitmapDrawable
       
  1496 // ---------------------------------------------------------------------------
       
  1497 //
       
  1498 MSwtGc* CSwtImage::NewGcL()
       
  1499 {
       
  1500     ASSERT(iDevice);
       
  1501     ASSERT(iDisplay);
       
  1502 
       
  1503     CFbsBitGc* nativeGc = CFbsBitGc::NewL();
       
  1504     nativeGc->Activate(iBitmapDevice);
       
  1505 
       
  1506     return iDisplay->Factory().NewBitmapGcL(*this, nativeGc,
       
  1507                                             DestroyNativeGc, KRgbBlack, KRgbWhite, *iDevice->GetSystemFont());
       
  1508 }
       
  1509 
       
  1510 // ---------------------------------------------------------------------------
       
  1511 // CSwtImage::GraphicsDevice
       
  1512 // From MSwtBitmapDrawable
       
  1513 // ---------------------------------------------------------------------------
       
  1514 //
       
  1515 CBitmapDevice& CSwtImage::GraphicsDevice()
       
  1516 {
       
  1517     return *iBitmapDevice;
       
  1518 }
       
  1519 
       
  1520 // ---------------------------------------------------------------------------
       
  1521 // CSwtImage::GraphicsDevice
       
  1522 // From MSwtBitmapDrawable
       
  1523 // ---------------------------------------------------------------------------
       
  1524 //
       
  1525 void CSwtImage::HandleUpdate()
       
  1526 {
       
  1527     if (iMaskType == EColorKey)
       
  1528     {
       
  1529         iMaskType = EDirtyColorKey;
       
  1530     }
       
  1531 }
       
  1532 
       
  1533 // ---------------------------------------------------------------------------
       
  1534 // CSwtImage::DestroyNativeGc
       
  1535 // From MSwtBitmapDrawable
       
  1536 // ---------------------------------------------------------------------------
       
  1537 //
       
  1538 void CSwtImage::DestroyNativeGc(CBitmapContext* aGc)
       
  1539 {
       
  1540     delete aGc;
       
  1541 }
       
  1542 
       
  1543 // ---------------------------------------------------------------------------
       
  1544 // CSwtImage::GetBitmap
       
  1545 // From MSwtImage
       
  1546 // ---------------------------------------------------------------------------
       
  1547 //
       
  1548 CFbsBitmap& CSwtImage::GetBitmap() const
       
  1549 {
       
  1550     return *iBitmap;
       
  1551 }
       
  1552 
       
  1553 // ---------------------------------------------------------------------------
       
  1554 // CSwtImage::GetSubBitmap
       
  1555 // From MSwtImage
       
  1556 // ---------------------------------------------------------------------------
       
  1557 //
       
  1558 CFbsBitmap& CSwtImage::GetSubBitmap(const TSize& aSize) const
       
  1559 {
       
  1560     ASSERT(iBitmap);
       
  1561 
       
  1562     // For the original size return the main bitmap
       
  1563     if (iBitmap->SizeInPixels() == aSize)
       
  1564     {
       
  1565         return GetBitmap();
       
  1566     }
       
  1567 
       
  1568     // Search scaled bitmap copy
       
  1569     CFbsBitmap* bmp = NULL;
       
  1570     TInt count = iScaledBitmaps.Count();
       
  1571     for (TInt i = 0; i < count; i++)
       
  1572     {
       
  1573         bmp = iScaledBitmaps[i];
       
  1574         if (bmp->SizeInPixels() == aSize)
       
  1575         {
       
  1576             return *bmp;
       
  1577         }
       
  1578     }
       
  1579 
       
  1580     // Scaled bitmap copy not found, create one for aSize
       
  1581     TRAP_IGNORE(bmp = SwtControlHelper::GetCopyOfBitmapL(iBitmap, aSize));
       
  1582     if (bmp)
       
  1583     {
       
  1584         // Create also scaled mask copy for aSize
       
  1585         CFbsBitmap* mask = NULL;
       
  1586         CFbsBitmap* maski = NULL;
       
  1587         if (iMask)
       
  1588         {
       
  1589             TRAP_IGNORE(mask = SwtControlHelper::GetCopyOfBitmapL(iMask, aSize));
       
  1590             if (iMask->IsMonochrome())
       
  1591             {
       
  1592                 TRAP_IGNORE(maski = SwtControlHelper::GetInvertedCopyOfMonoBitmapL(iMask, aSize));
       
  1593             }
       
  1594         }
       
  1595 
       
  1596         // Update arrays
       
  1597 
       
  1598         // NOTE! iScaledBitmapRefs, iScaledBitmaps, iScaledMasks and
       
  1599         // iScaledMasksInverted must always have the same number of entries.
       
  1600         // NOTE! iScaledMasksInverted entries are valid only if
       
  1601         // the main mask is monochrome. Otherwise they are NULL
       
  1602         // and iScaledMasks entries should be used instead.
       
  1603         iScaledBitmapRefs.Append(0);
       
  1604         iScaledBitmaps.Append(bmp);
       
  1605         iScaledMasks.Append(mask);
       
  1606         iScaledMasksInverted.Append(maski);
       
  1607     }
       
  1608     else
       
  1609     {
       
  1610         // In the case of no memory or whatever
       
  1611         ASSERT(EFalse);
       
  1612         bmp = &GetBitmap();
       
  1613     }
       
  1614 
       
  1615     return *bmp;
       
  1616 }
       
  1617 
       
  1618 // ---------------------------------------------------------------------------
       
  1619 // CSwtImage::Dispose
       
  1620 // From MSwtImage
       
  1621 // ---------------------------------------------------------------------------
       
  1622 //
       
  1623 void CSwtImage::Dispose()
       
  1624 {
       
  1625     // Likely reasons for this assertion to fail:
       
  1626     //  - The SWT program disposing of its images before the objects that
       
  1627     //    reference them;
       
  1628     //  - Memory leak in one of the objects referencing the image ( AddRef() was
       
  1629     //    called but not RemoveRef() ).
       
  1630 #ifdef ESWT_EARLY_DISPOSAL_CHECKING_ENABLED
       
  1631     ASSERT(RefCount() == 1);
       
  1632 #endif // ESWT_EARLY_DISPOSAL_CHECKING_ENABLED
       
  1633     RemoveRef();
       
  1634 }
       
  1635 
       
  1636 // ---------------------------------------------------------------------------
       
  1637 // CSwtImage::MaskBitmap
       
  1638 // From MSwtImage
       
  1639 // ---------------------------------------------------------------------------
       
  1640 //
       
  1641 const CFbsBitmap* CSwtImage::MaskBitmap(TBool aInvertedIfMonochrome /*= EFalse*/) const
       
  1642 {
       
  1643     EnsureMaskIsUpToDate();
       
  1644     CFbsBitmap* mask = iMask;
       
  1645     if (mask && aInvertedIfMonochrome && mask->IsMonochrome())
       
  1646     {
       
  1647         if (!iMaskInverted)
       
  1648         {
       
  1649             TRAP_IGNORE(iMaskInverted = SwtControlHelper::GetInvertedCopyOfMonoBitmapL(mask));
       
  1650         }
       
  1651         mask = iMaskInverted;
       
  1652     }
       
  1653     return mask;
       
  1654 }
       
  1655 
       
  1656 // ---------------------------------------------------------------------------
       
  1657 // CSwtImage::SubMaskBitmap
       
  1658 // From MSwtImage
       
  1659 // ---------------------------------------------------------------------------
       
  1660 //
       
  1661 const CFbsBitmap* CSwtImage::SubMaskBitmap(const TSize& aSize,
       
  1662         TBool aInvertedIfMonochrome /*= EFalse*/) const
       
  1663 {
       
  1664     ASSERT(iBitmap);
       
  1665 
       
  1666     // For the original size return the main mask
       
  1667     if (iBitmap->SizeInPixels() == aSize)
       
  1668     {
       
  1669         return MaskBitmap(aInvertedIfMonochrome);
       
  1670     }
       
  1671 
       
  1672     // Find scaled copy of the bitmap and return its scaled mask.
       
  1673     CFbsBitmap* bmp = NULL;
       
  1674     CFbsBitmap* mask = NULL;
       
  1675     TInt count = iScaledBitmaps.Count();
       
  1676     for (TInt i = 0; i < count; i++)
       
  1677     {
       
  1678         bmp = iScaledBitmaps[i];
       
  1679         if (bmp && bmp->SizeInPixels() == aSize)
       
  1680         {
       
  1681             mask = iScaledMasks[i];
       
  1682             if (mask && aInvertedIfMonochrome && mask->IsMonochrome())
       
  1683             {
       
  1684                 // NOTE! iScaledMasksInverted entries are valid only if
       
  1685                 // the main mask is monochrome. Otherwise they are NULL
       
  1686                 // and iScaledMasks entries should be used instead.
       
  1687                 mask = iScaledMasksInverted[i];
       
  1688             }
       
  1689             return mask;
       
  1690         }
       
  1691     }
       
  1692 
       
  1693     return mask;
       
  1694 }
       
  1695 
       
  1696 // ---------------------------------------------------------------------------
       
  1697 // CSwtImage::GetBounds
       
  1698 // From MSwtImage
       
  1699 // ---------------------------------------------------------------------------
       
  1700 //
       
  1701 TRect CSwtImage::GetBounds() const
       
  1702 {
       
  1703     return TRect(iBitmap->SizeInPixels());
       
  1704 }
       
  1705 
       
  1706 // ---------------------------------------------------------------------------
       
  1707 // CSwtImage::GetImageDataL
       
  1708 // From MSwtImage
       
  1709 // ---------------------------------------------------------------------------
       
  1710 //
       
  1711 MSwtImageData* CSwtImage::GetImageDataL() const
       
  1712 {
       
  1713     // Get the palette
       
  1714     CSwtGrPaletteData* paletteData = GetPaletteDataL();
       
  1715     CleanupStack::PushL(paletteData);
       
  1716 
       
  1717     // Get the buffers
       
  1718     HBufC8* pixelData = GetPixelDataLC(*iBitmap);
       
  1719     HBufC8* maskData = NULL;
       
  1720     if (iMaskType == EBinaryMask)
       
  1721     {
       
  1722         ASSERT(iMask);
       
  1723         maskData = GetPixelDataLC(*iMask);
       
  1724     }
       
  1725 
       
  1726     HBufC8* alphaData = NULL;
       
  1727     if (iMaskType == EAlphaMask)
       
  1728     {
       
  1729         ASSERT(iMask);
       
  1730         alphaData = GetPixelDataLC(*iMask);
       
  1731     }
       
  1732 
       
  1733     // Prepare the information
       
  1734     MSwtImageData::TInfo info;
       
  1735     info.iSize = iInfo.iSize;
       
  1736     info.iDepth = BitDepth(iBitmap->DisplayMode());
       
  1737     info.iScanlinePad = ScanlinePadding(info.iDepth);
       
  1738     info.iBytesPerLine = BytesPerLine(info.iSize.iWidth, info.iDepth,
       
  1739                                       info.iScanlinePad);
       
  1740     info.iMaskPad = (maskData) ? ScanlinePadding(1) : 0;
       
  1741     info.iAlpha = iInfo.iAlpha;
       
  1742     info.iType = iInfo.iType;
       
  1743     info.iTopLeft = iInfo.iTopLeft;
       
  1744     info.iDisposalMethod = iInfo.iDisposalMethod;
       
  1745     info.iDelayTime = iInfo.iDelayTime;
       
  1746 
       
  1747     if (!iColorKey)
       
  1748     {
       
  1749         info.iTransparentPixel = -1;
       
  1750     }
       
  1751     else
       
  1752     {
       
  1753         if (paletteData->IsDirect())
       
  1754         {
       
  1755             const MSwtPaletteData::TDirectData& directData =
       
  1756                 paletteData->DirectData();
       
  1757             TUint r = BitShift(iColorKey->Red(),
       
  1758                                - directData.iRedShift) & directData.iRedMask;
       
  1759             TUint g = BitShift(iColorKey->Green(),
       
  1760                                - directData.iGreenShift) & directData.iGreenMask;
       
  1761             TUint b = BitShift(iColorKey->Blue(),
       
  1762                                - directData.iBlueShift) & directData.iBlueMask;
       
  1763             info.iTransparentPixel = r | g | b;
       
  1764         }
       
  1765         else
       
  1766         {
       
  1767             info.iTransparentPixel = paletteData->IndirectData()->
       
  1768                                      NearestIndex(*iColorKey);
       
  1769         }
       
  1770     }
       
  1771 
       
  1772     if (alphaData)
       
  1773     {
       
  1774         CleanupStack::Pop(alphaData);
       
  1775     }
       
  1776     if (maskData)
       
  1777     {
       
  1778         CleanupStack::Pop(maskData);
       
  1779     }
       
  1780     CleanupStack::Pop(pixelData);
       
  1781     CleanupStack::Pop(paletteData);
       
  1782 
       
  1783     return CSwtGrImageData::NewL(info, paletteData, pixelData, maskData, alphaData);
       
  1784 }
       
  1785 
       
  1786 // ---------------------------------------------------------------------------
       
  1787 // CSwtImage::AddSubRef
       
  1788 // From MSwtImage
       
  1789 // ---------------------------------------------------------------------------
       
  1790 //
       
  1791 TInt CSwtImage::AddSubRef(const TSize& aSize) const
       
  1792 {
       
  1793     ASSERT(iBitmap);
       
  1794     if (iBitmap->SizeInPixels() == aSize)
       
  1795     {
       
  1796         AddRef();
       
  1797         return KErrNone;
       
  1798     }
       
  1799 
       
  1800     CFbsBitmap* bmp = NULL;
       
  1801     TInt count = iScaledBitmaps.Count();
       
  1802     for (TInt i = 0; i < count; i++)
       
  1803     {
       
  1804         bmp = iScaledBitmaps[i];
       
  1805         if (bmp && bmp->SizeInPixels() == aSize)
       
  1806         {
       
  1807             iScaledBitmapRefs[i]++; // mutable
       
  1808             return KErrNone;
       
  1809         }
       
  1810     }
       
  1811     return KErrNotFound;
       
  1812 }
       
  1813 
       
  1814 // ---------------------------------------------------------------------------
       
  1815 // CSwtImage::RemoveSubRef
       
  1816 // From MSwtImage
       
  1817 // ---------------------------------------------------------------------------
       
  1818 //
       
  1819 TInt CSwtImage::RemoveSubRef(const TSize& aSize) const
       
  1820 {
       
  1821     ASSERT(iBitmap);
       
  1822     if (iBitmap->SizeInPixels() == aSize)
       
  1823     {
       
  1824         RemoveRef();
       
  1825         return KErrNone;
       
  1826     }
       
  1827 
       
  1828     CFbsBitmap* bmp = NULL;
       
  1829     CFbsBitmap* mask = NULL;
       
  1830     CFbsBitmap* maski = NULL;
       
  1831     TInt count = iScaledBitmaps.Count();
       
  1832     for (TInt i = 0; i < count; i++)
       
  1833     {
       
  1834         // NOTE! iScaledBitmapRefs, iScaledBitmaps, iScaledMasks and
       
  1835         // iScaledMasksInverted must always have the same number of entries.
       
  1836         // NOTE! iScaledMasksInverted entries are valid only if
       
  1837         // the main mask is monochrome. Otherwise they are NULL
       
  1838         // and iScaledMasks entries should be used instead.
       
  1839         bmp = iScaledBitmaps[i];
       
  1840         mask = iScaledMasks[i];
       
  1841         maski = iScaledMasksInverted[i];
       
  1842         if (bmp && bmp->SizeInPixels() == aSize)
       
  1843         {
       
  1844             iScaledBitmapRefs[i]--; // mutable
       
  1845             if (iScaledBitmapRefs[i] == 0)
       
  1846             {
       
  1847                 delete bmp;
       
  1848                 delete mask;
       
  1849                 delete maski;
       
  1850                 iScaledMasks.Remove(i);
       
  1851                 iScaledMasksInverted.Remove(i);
       
  1852                 iScaledBitmaps.Remove(i);
       
  1853                 iScaledBitmapRefs.Remove(i);
       
  1854             }
       
  1855             return KErrNone;
       
  1856         }
       
  1857     }
       
  1858     return KErrNotFound;
       
  1859 }
       
  1860 
       
  1861 // ---------------------------------------------------------------------------
       
  1862 // CSwtImage::SubRefCount
       
  1863 // From MSwtImage
       
  1864 // ---------------------------------------------------------------------------
       
  1865 //
       
  1866 TInt CSwtImage::SubRefCount(const TSize& aSize) const
       
  1867 {
       
  1868     ASSERT(iBitmap);
       
  1869     if (iBitmap->SizeInPixels() == aSize)
       
  1870     {
       
  1871         return RefCount();
       
  1872     }
       
  1873 
       
  1874     CFbsBitmap* bmp = NULL;
       
  1875     TInt count = iScaledBitmaps.Count();
       
  1876     for (TInt i = 0; i < count; i++)
       
  1877     {
       
  1878         bmp = iScaledBitmaps[i];
       
  1879         if (bmp && bmp->SizeInPixels() == aSize)
       
  1880         {
       
  1881             return iScaledBitmapRefs[i];
       
  1882         }
       
  1883     }
       
  1884     return 0;
       
  1885 }
       
  1886 
       
  1887 
       
  1888 // ---------------------------------------------------------------------------
       
  1889 // CSwtImage::BitmapWithAlphaLC
       
  1890 // From MSwtImage
       
  1891 // ---------------------------------------------------------------------------
       
  1892 //
       
  1893 CFbsBitmap* CSwtImage::BitmapWithAlphaLC()
       
  1894 {
       
  1895 
       
  1896     ASSERT(iMask);
       
  1897     ASSERT(iBitmap);
       
  1898 
       
  1899 
       
  1900     // Create the bitmap
       
  1901     CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
       
  1902     CleanupStack::PushL(bitmap);
       
  1903 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  1904     User::LeaveIfError(bitmap->Create(iBitmap->SizeInPixels(), EColor16MAP));
       
  1905 #else
       
  1906     User::LeaveIfError(bitmap->Create(iBitmap->SizeInPixels(), EColor16MA));
       
  1907 #endif //RD_JAVA_S60_RELEASE_9_2
       
  1908 
       
  1909 
       
  1910     // Create bitmap mask
       
  1911     CFbsBitmap* mask = new(ELeave) CFbsBitmap;
       
  1912     CleanupStack::PushL(mask);
       
  1913     User::LeaveIfError(mask->Create(iMask->SizeInPixels(), EGray256));
       
  1914 
       
  1915     // copy bitmap
       
  1916     CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap);
       
  1917     CleanupStack::PushL(bitmapDevice);
       
  1918     BitBltBitmapL(*bitmapDevice, *iBitmap);
       
  1919     CleanupStack::PopAndDestroy(bitmapDevice);
       
  1920 
       
  1921     // copy bitmap mask
       
  1922     CFbsBitmapDevice* maskDevice = CFbsBitmapDevice::NewL(mask);
       
  1923     CleanupStack::PushL(maskDevice);
       
  1924     BitBltBitmapL(*maskDevice, *iMask);
       
  1925     CleanupStack::PopAndDestroy(maskDevice);
       
  1926 
       
  1927     // add mask to alpha bitmap's alpha channel
       
  1928     AddMaskToAlphaChannel(*bitmap, *mask);
       
  1929     CleanupStack::PopAndDestroy(mask);
       
  1930     return bitmap;
       
  1931 }
       
  1932 
       
  1933 
       
  1934 // ---------------------------------------------------------------------------
       
  1935 // CSwtImage::OfferResourceChangeL
       
  1936 // From MSwtResourceChangeObserver
       
  1937 // ---------------------------------------------------------------------------
       
  1938 //
       
  1939 void CSwtImage::OfferResourceChangeL(TInt /*aType*/)
       
  1940 {
       
  1941     ASSERT(iDevice);
       
  1942 
       
  1943     // We set new twips size of bitmap in case device resolution has changed
       
  1944     iBitmap->SetSizeInTwips(&(iDevice->GraphicsDevice()));
       
  1945 }