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