uifw/AvKon/src/AknBitmapMirrorUtils.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "AknBitmapMirrorUtils.h"
       
    20 #include <bitdev.h>
       
    21 
       
    22 enum
       
    23     {
       
    24     EAknNoMirroring = 0,
       
    25     EAknVerticalMirroring,
       
    26     EAknHorizontalMirroring
       
    27     };
       
    28 
       
    29 void AknBitmapMirrorUtils::LoadHorizontalMirroredBitmapL(CFbsBitmap* aBitmap, const TDesC& aFileName,TInt32 aId)
       
    30     {
       
    31     LoadPartialBitmapL(aBitmap, aFileName,aId, KWholeBitmapRect, ETrue);
       
    32     }
       
    33 
       
    34 void AknBitmapMirrorUtils::LoadPartialBitmapL(CFbsBitmap* aBitmap, const TDesC& aFileName,TInt32 aId, TRect aRect, TBool aMirrorHorizontally)
       
    35     {
       
    36     CFbsBitmap* destinationBitmap = aBitmap;
       
    37     User::LeaveIfNull(destinationBitmap);
       
    38 
       
    39     CFbsBitmap* sourceBitmap = new (ELeave) CFbsBitmap();   
       
    40     CleanupStack::PushL(sourceBitmap);   
       
    41     User::LeaveIfError(sourceBitmap->Load(aFileName, aId, ETrue));    
       
    42     TSize sourceBitmapSize = sourceBitmap->SizeInPixels();
       
    43     
       
    44     TRect sourceRect = TRect(aRect);
       
    45     if (sourceRect == KWholeBitmapRect)
       
    46         {
       
    47         sourceRect.iTl.iX = 0;
       
    48         sourceRect.iTl.iY = 0;
       
    49         sourceRect.iBr.iX = sourceBitmapSize.iWidth;
       
    50         sourceRect.iBr.iY = sourceBitmapSize.iHeight;
       
    51         }
       
    52       
       
    53     TSize destinationBitmapSize(sourceRect.Width(), sourceRect.Height()); 
       
    54     User::LeaveIfError(destinationBitmap->Create(destinationBitmapSize, sourceBitmap->DisplayMode()));
       
    55 
       
    56     CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL( destinationBitmap );
       
    57     CleanupStack::PushL(destinationDevice);
       
    58 
       
    59     CFbsBitGc* destinationGc;
       
    60     User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
       
    61 
       
    62     if (aMirrorHorizontally)
       
    63         {
       
    64         TRect sourceBitmapBlittingRect( sourceRect.iTl.iX,sourceRect.iTl.iY,sourceRect.iTl.iX + 1,sourceRect.iBr.iY );  
       
    65     
       
    66         for ( TInt xPos=destinationBitmapSize.iWidth-1; xPos >= 0; xPos-- )
       
    67             {
       
    68             destinationGc->BitBlt( TPoint(xPos,0), sourceBitmap, sourceBitmapBlittingRect );
       
    69             sourceBitmapBlittingRect.iTl.iX++;
       
    70             sourceBitmapBlittingRect.iBr.iX++;
       
    71             }
       
    72         }
       
    73     else
       
    74         {
       
    75         destinationGc->BitBlt( TPoint(0,0), sourceBitmap, sourceRect );
       
    76         }
       
    77 
       
    78     delete destinationGc;  
       
    79     CleanupStack::PopAndDestroy(2); // sourceBitmap, destinationDevice
       
    80     }
       
    81 
       
    82 CFbsBitmap* AknBitmapMirrorUtils::HorizontallyMirrorBitmapL( CFbsBitmap* aBitmap )
       
    83     {    
       
    84     return PartialBitmapL( aBitmap, KWholeBitmapRect, ETrue );
       
    85     }
       
    86 
       
    87 CFbsBitmap* AknBitmapMirrorUtils::PartialBitmapL( CFbsBitmap* aBitmap, TRect aRect, TBool aMirrorHorizontally )
       
    88     {
       
    89     User::LeaveIfNull(aBitmap);   
       
    90 	CFbsBitmap* tmpBitmap = NULL;
       
    91     TSize sourceBitmapSize = aBitmap->SizeInPixels();
       
    92 
       
    93     TRect sourceRect = TRect(aRect);
       
    94     if ( sourceRect == KWholeBitmapRect )
       
    95         {
       
    96         sourceRect.iTl.iX = 0;
       
    97         sourceRect.iTl.iY = 0; 
       
    98         sourceRect.iBr.iX = sourceBitmapSize.iWidth;
       
    99         sourceRect.iBr.iY = sourceBitmapSize.iHeight;
       
   100         if (aMirrorHorizontally)
       
   101         	tmpBitmap = CreateBitmapOptimizedL(aBitmap, EAknHorizontalMirroring);
       
   102         else
       
   103         	tmpBitmap = CreateBitmapOptimizedL(aBitmap, EAknNoMirroring);        
       
   104         }
       
   105     else
       
   106     	{      
       
   107 	    // Check rect sanity
       
   108 	    if ( sourceRect.iBr.iX > sourceBitmapSize.iWidth || sourceRect.iBr.iX <= 0 )
       
   109 	        {
       
   110 	        sourceRect.iBr.iX = sourceBitmapSize.iWidth;
       
   111 	        }
       
   112 	    if ( sourceRect.iBr.iY > sourceBitmapSize.iHeight || sourceRect.iBr.iY <= 0  )
       
   113 	        {
       
   114 	        sourceRect.iBr.iY = sourceBitmapSize.iHeight;
       
   115 	        }
       
   116 	    if ( sourceRect.iTl.iX >= sourceBitmapSize.iWidth || sourceRect.iTl.iX < 0)
       
   117 	        {
       
   118 	        sourceRect.iTl.iX = 0;
       
   119 	        }
       
   120 	    if ( sourceRect.iTl.iY >= sourceBitmapSize.iHeight || sourceRect.iTl.iY < 0)
       
   121 	        {
       
   122 	        sourceRect.iTl.iY = 0;        
       
   123 	        }
       
   124 	    TSize destinationBitmapSize = TSize( sourceRect.Width(), sourceRect.Height() );  
       
   125 
       
   126 	    // get a copy of wanted rect of source bitmap to tmpBitmap
       
   127 	    tmpBitmap = new (ELeave) CFbsBitmap();   
       
   128 	    CleanupStack::PushL( tmpBitmap );                      
       
   129 
       
   130 	    User::LeaveIfError( tmpBitmap->Create( destinationBitmapSize, aBitmap->DisplayMode() ) );
       
   131 
       
   132 	    CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL( tmpBitmap );
       
   133 	    CleanupStack::PushL( destinationDevice );
       
   134 	    
       
   135 	    CFbsBitGc* destinationGc;
       
   136 	    User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );           
       
   137 	    
       
   138 	    if ( aMirrorHorizontally )
       
   139 	        {        
       
   140 	        TRect sourceBitmapBlittingRect( sourceRect.iTl.iX, sourceRect.iTl.iY,
       
   141 	            sourceRect.iTl.iX + 1, sourceRect.iBr.iY );  
       
   142 	        
       
   143 	        for ( TInt xPos=destinationBitmapSize.iWidth-1; xPos >= 0; xPos-- )
       
   144 	            {
       
   145 	            destinationGc->BitBlt( TPoint(xPos,0), aBitmap, sourceBitmapBlittingRect );
       
   146 	            sourceBitmapBlittingRect.iTl.iX++;
       
   147 	            sourceBitmapBlittingRect.iBr.iX++;
       
   148 	            }	    
       
   149 	        }
       
   150 	    else
       
   151 	        {        
       
   152 	        destinationGc->BitBlt( TPoint(0,0), aBitmap, sourceRect );        
       
   153 	        }
       
   154 
       
   155 	    delete destinationGc;  
       
   156 	    CleanupStack::PopAndDestroy(); // destinationDevice
       
   157 	    CleanupStack::Pop(); // tmpBitmap    		
       
   158     	}        
       
   159 
       
   160     return tmpBitmap;
       
   161     }
       
   162 
       
   163 CFbsBitmap* AknBitmapMirrorUtils::CreateMirroredBitmapL(CFbsBitmap* aSourceBitmap, TBool aVerticalMirror, TBool aHorizontalMirror)
       
   164     {
       
   165     CFbsBitmap* verticalMirroredBitmap = NULL;
       
   166     CFbsBitmap* horizontalMirroredBitmap = NULL;
       
   167 
       
   168     if (aVerticalMirror)
       
   169         {
       
   170         verticalMirroredBitmap = CreateBitmapOptimizedL(aSourceBitmap, EAknVerticalMirroring);
       
   171         }
       
   172 
       
   173     if (aHorizontalMirror)
       
   174         {
       
   175         if (verticalMirroredBitmap)
       
   176             {
       
   177             CleanupStack::PushL(verticalMirroredBitmap);            
       
   178             horizontalMirroredBitmap =  CreateBitmapOptimizedL(verticalMirroredBitmap, EAknHorizontalMirroring);
       
   179             CleanupStack::PopAndDestroy(); // verticalMirroredBitmap
       
   180             verticalMirroredBitmap = NULL;
       
   181             }
       
   182         else
       
   183             {
       
   184             horizontalMirroredBitmap =  CreateBitmapOptimizedL(aSourceBitmap, EAknHorizontalMirroring);
       
   185             }
       
   186         }
       
   187     
       
   188 
       
   189     if (!aHorizontalMirror && !aVerticalMirror)
       
   190         {
       
   191         verticalMirroredBitmap = CreateBitmapOptimizedL(aSourceBitmap, EAknNoMirroring);
       
   192         }
       
   193 
       
   194     if (verticalMirroredBitmap)
       
   195         {
       
   196         return verticalMirroredBitmap;
       
   197         }
       
   198     else
       
   199         {
       
   200         return horizontalMirroredBitmap;
       
   201         }
       
   202         
       
   203 
       
   204     }
       
   205 
       
   206 
       
   207 CFbsBitmap* AknBitmapMirrorUtils::CreateBitmapL(CFbsBitmap* aSourceBitmap, TInt aMirrorDirection)
       
   208     {
       
   209     User::LeaveIfNull(aSourceBitmap);
       
   210     CFbsBitmap* destinationBitmap = new (ELeave) CFbsBitmap();
       
   211     CleanupStack::PushL(destinationBitmap);   
       
   212 
       
   213     TSize sourceBitmapSize = aSourceBitmap->SizeInPixels();            
       
   214     TRect sourceRect = TRect(TPoint(0,0), sourceBitmapSize);
       
   215     TSize destinationBitmapSize(sourceRect.Width(), sourceRect.Height()); 
       
   216 
       
   217     User::LeaveIfError(destinationBitmap->Create(destinationBitmapSize, aSourceBitmap->DisplayMode()));
       
   218 
       
   219     CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL( destinationBitmap );
       
   220     CleanupStack::PushL(destinationDevice);
       
   221 
       
   222     CFbsBitGc* destinationGc;
       
   223     User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) );
       
   224 
       
   225     switch (aMirrorDirection)
       
   226         {
       
   227         case EAknVerticalMirroring:
       
   228             {
       
   229             TRect sourceBitmapBlittingRect( sourceRect.iTl.iX,sourceRect.iTl.iY,sourceRect.iBr.iX,sourceRect.iTl.iY + 1 );  
       
   230             for ( TInt yPos=destinationBitmapSize.iHeight-1; yPos >= 0; yPos-- )
       
   231                 {
       
   232                 destinationGc->BitBlt( TPoint(0,yPos), aSourceBitmap, sourceBitmapBlittingRect );
       
   233                 sourceBitmapBlittingRect.iTl.iY++;
       
   234                 sourceBitmapBlittingRect.iBr.iY++;
       
   235                 }
       
   236             break;
       
   237             }
       
   238 
       
   239         case EAknHorizontalMirroring:
       
   240             {
       
   241             TRect sourceBitmapBlittingRect( sourceRect.iTl.iX,sourceRect.iTl.iY,sourceRect.iTl.iX + 1,sourceRect.iBr.iY );      
       
   242             for ( TInt xPos=destinationBitmapSize.iWidth-1; xPos >= 0; xPos-- )
       
   243                 {
       
   244                 destinationGc->BitBlt( TPoint(xPos,0), aSourceBitmap, sourceBitmapBlittingRect );
       
   245                 sourceBitmapBlittingRect.iTl.iX++;
       
   246                 sourceBitmapBlittingRect.iBr.iX++;
       
   247                 }
       
   248             break;
       
   249             }
       
   250 
       
   251         default:
       
   252             {
       
   253             destinationGc->BitBlt( TPoint(0,0), aSourceBitmap, sourceRect );
       
   254             break;
       
   255             }
       
   256         }
       
   257 
       
   258     delete destinationGc;  
       
   259     CleanupStack::Pop(2); // destinationBitmap, destinationDevice
       
   260     delete destinationDevice;
       
   261 
       
   262     return destinationBitmap;   
       
   263     }
       
   264 
       
   265 CFbsBitmap* AknBitmapMirrorUtils::CreateBitmapOptimizedL(CFbsBitmap* aSourceBitmap, TInt aMirrorDirection)
       
   266     {
       
   267     // Check if displaymode is optimized, fallback to non-optimized version if not.
       
   268     TBool fallback = ETrue;
       
   269     TDisplayMode displayMode = aSourceBitmap->DisplayMode();
       
   270     switch( displayMode )
       
   271         {
       
   272         case EGray256:
       
   273         case EColor256:
       
   274         case EColor4K:
       
   275         case EColor64K:
       
   276             fallback = EFalse;
       
   277             break;
       
   278         default:
       
   279             fallback = ETrue;
       
   280         }
       
   281 
       
   282     // Check if mirroring mode is supported, fallback to non-optimized version if not.
       
   283 	if ((aMirrorDirection != EAknVerticalMirroring) && (aMirrorDirection != EAknHorizontalMirroring))
       
   284 		{
       
   285 		fallback = ETrue;	
       
   286 		}
       
   287 
       
   288     if( fallback )
       
   289 		return CreateBitmapL(aSourceBitmap, aMirrorDirection);
       
   290     
       
   291 	// Prepare destination bitmap
       
   292     User::LeaveIfNull(aSourceBitmap);
       
   293     CFbsBitmap* destinationBitmap = new (ELeave) CFbsBitmap();
       
   294     CleanupStack::PushL(destinationBitmap);   
       
   295 
       
   296     TSize sourceBitmapSize = aSourceBitmap->SizeInPixels();            
       
   297     TRect sourceRect = TRect(TPoint(0,0), sourceBitmapSize);
       
   298     TSize destinationBitmapSize(sourceRect.Width(), sourceRect.Height()); 
       
   299 
       
   300     User::LeaveIfError(destinationBitmap->Create(destinationBitmapSize, aSourceBitmap->DisplayMode()));
       
   301 
       
   302 	// Check source, if rom bitmap or compressed then create uncompressed ram bitmap
       
   303     TBool srcTemporary = EFalse;
       
   304     if( aSourceBitmap->IsRomBitmap() )
       
   305         {
       
   306         srcTemporary = ETrue;
       
   307         }
       
   308         
       
   309     // Heap lock for FBServ large chunk to prevent background
       
   310     // compression of aSrcBitmap after if IsCompressedInRAM returns EFalse
       
   311     aSourceBitmap->LockHeapLC( ETrue ); // fbsheaplock
       
   312     TBool fbsHeapLock = ETrue;        
       
   313         
       
   314     if( aSourceBitmap->IsCompressedInRAM() )
       
   315         {
       
   316         srcTemporary = ETrue;
       
   317         }
       
   318     if( aSourceBitmap->ExtendedBitmapType() != KNullUid  )
       
   319         {
       
   320         srcTemporary = ETrue;
       
   321         }
       
   322 
       
   323     CFbsBitmap* realSource = aSourceBitmap;
       
   324     if( srcTemporary )
       
   325         {
       
   326         CleanupStack::PopAndDestroy(); // fbsheaplock
       
   327         fbsHeapLock = EFalse;
       
   328         
       
   329         realSource = new (ELeave) CFbsBitmap();
       
   330         CleanupStack::PushL( realSource );
       
   331         User::LeaveIfError( realSource->Create( sourceBitmapSize, aSourceBitmap->DisplayMode() ) );
       
   332         CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( realSource );
       
   333         CleanupStack::PushL( dev );
       
   334         CFbsBitGc* gc = NULL;
       
   335         User::LeaveIfError( dev->CreateContext( gc ) );
       
   336         CleanupStack::PushL( gc );
       
   337         gc->BitBlt( TPoint(0,0), aSourceBitmap );
       
   338         CleanupStack::PopAndDestroy(2); // dev, gc
       
   339         }
       
   340 
       
   341 	// Heap lock for FBServ large chunk is only needed with large bitmaps.
       
   342     if (!fbsHeapLock)
       
   343     	{
       
   344 	    if ( realSource->IsLargeBitmap() || destinationBitmap->IsLargeBitmap() )
       
   345 	        {
       
   346 	        destinationBitmap->LockHeapLC( ETrue ); // fbsheaplock
       
   347 	        }
       
   348 	    else
       
   349 	        {
       
   350 	        CleanupStack::PushL( (TAny*)NULL );
       
   351 	        }
       
   352     	}
       
   353 
       
   354     TUint32* srcAddress = realSource->DataAddress();
       
   355     TUint32* trgAddress = destinationBitmap->DataAddress();
       
   356 
       
   357     if ( displayMode == EColor4K || displayMode == EColor64K )
       
   358         {
       
   359         TInt srcScanLen16 = CFbsBitmap::ScanLineLength(sourceBitmapSize.iWidth, displayMode) / 2;
       
   360         TInt trgScanLen16 = CFbsBitmap::ScanLineLength(destinationBitmapSize.iWidth, displayMode) / 2;
       
   361         TInt srcScanLen32 = CFbsBitmap::ScanLineLength(sourceBitmapSize.iWidth, displayMode) / 4;
       
   362         TInt trgScanLen32 = CFbsBitmap::ScanLineLength(destinationBitmapSize.iWidth, displayMode) / 4;
       
   363 
       
   364 	    switch (aMirrorDirection)
       
   365 	        {
       
   366 	        case EAknVerticalMirroring:
       
   367 	            {
       
   368 		        TUint32* trgAddress32 = trgAddress;
       
   369 	            TUint32* srcAddress32 = srcAddress;            	
       
   370            		TInt trgPos = 0;
       
   371             	for ( TInt yPos=destinationBitmapSize.iHeight-1; yPos >= 0; yPos-- )
       
   372             		{
       
   373 		            srcAddress32 = srcAddress + srcScanLen32*yPos;
       
   374             		trgAddress32 = trgAddress + trgScanLen32*trgPos;            			
       
   375             		memcpy(trgAddress32, srcAddress32, srcScanLen32*4);
       
   376             		trgPos++;
       
   377             		}
       
   378 	            break;
       
   379 	            }
       
   380 	        case EAknHorizontalMirroring:
       
   381 	            {
       
   382 		        TUint16* trgAddress16 = reinterpret_cast<TUint16*>(trgAddress);
       
   383 	            TUint16* srcAddress16 = reinterpret_cast<TUint16*>(srcAddress);            	
       
   384            		TInt xTrgPos = 0;
       
   385             	for ( TInt yPos=destinationBitmapSize.iHeight-1; yPos >= 0; yPos-- )
       
   386             		{
       
   387 	           		xTrgPos = 0;            		            		
       
   388 	            	for ( TInt xPos=destinationBitmapSize.iWidth-1; xPos >= 0; xPos-- )
       
   389 	            		{
       
   390 						trgAddress16[xTrgPos] = srcAddress16[xPos];
       
   391 						xTrgPos++;
       
   392 	            		}
       
   393             		srcAddress16 += srcScanLen16;
       
   394 	            	trgAddress16 += trgScanLen16;	            		
       
   395             		}
       
   396 	            
       
   397 	            break;
       
   398 	            }
       
   399 	        default:
       
   400 	            {
       
   401 	            break;
       
   402 	            }
       
   403 	        }
       
   404         }
       
   405 	else if( (displayMode==EGray256) || (displayMode==EColor256) )
       
   406         {
       
   407         TInt srcScanLen8 = CFbsBitmap::ScanLineLength(sourceBitmapSize.iWidth, displayMode);
       
   408         TInt trgScanLen8 = CFbsBitmap::ScanLineLength(destinationBitmapSize.iWidth, displayMode);
       
   409         TInt srcScanLen32 = CFbsBitmap::ScanLineLength(sourceBitmapSize.iWidth, displayMode) / 4;
       
   410         TInt trgScanLen32 = CFbsBitmap::ScanLineLength(destinationBitmapSize.iWidth, displayMode) / 4;
       
   411                 
       
   412 	    switch (aMirrorDirection)
       
   413 	        {
       
   414 	        case EAknVerticalMirroring:
       
   415 	            {
       
   416 		        TUint32* trgAddress32 = trgAddress;
       
   417 	            TUint32* srcAddress32 = srcAddress;            	
       
   418            		TInt trgPos = 0;
       
   419             	for ( TInt yPos=destinationBitmapSize.iHeight-1; yPos >= 0; yPos-- )
       
   420             		{
       
   421 		            srcAddress32 = srcAddress + srcScanLen32*yPos;
       
   422             		trgAddress32 = trgAddress + trgScanLen32*trgPos;            			
       
   423             		memcpy(trgAddress32, srcAddress32, srcScanLen32*4);
       
   424             		trgPos++;
       
   425             		}
       
   426 	            break;
       
   427 	            }
       
   428 	        case EAknHorizontalMirroring:
       
   429 	            {
       
   430 		        TUint8* trgAddress8 = reinterpret_cast<TUint8*>(trgAddress);
       
   431 	            TUint8* srcAddress8 = reinterpret_cast<TUint8*>(srcAddress);            	
       
   432            		TInt xTrgPos = 0;
       
   433             	for ( TInt yPos=destinationBitmapSize.iHeight-1; yPos >= 0; yPos-- )
       
   434             		{
       
   435 	           		xTrgPos = 0;            		            		
       
   436 	            	for ( TInt xPos=destinationBitmapSize.iWidth-1; xPos >= 0; xPos-- )
       
   437 	            		{
       
   438 						trgAddress8[xTrgPos] = srcAddress8[xPos];
       
   439 						xTrgPos++;
       
   440 	            		}
       
   441             		srcAddress8 += srcScanLen8;
       
   442 	            	trgAddress8 += trgScanLen8;	            			            
       
   443             		}
       
   444 	            break;
       
   445 	            }
       
   446 	        default:
       
   447 	            {
       
   448 	            break;
       
   449 	            }        	            
       
   450 	        }
       
   451         }
       
   452 
       
   453 	CleanupStack::PopAndDestroy(); // fbsheaplock
       
   454 
       
   455     if( srcTemporary )
       
   456         {
       
   457         CleanupStack::PopAndDestroy(); // realSource
       
   458         }
       
   459 
       
   460     CleanupStack::Pop(); // destinationBitmap
       
   461     return destinationBitmap;   
       
   462     }