idlehomescreen/widgetmanager/src/wmimageconverter.cpp
branchRCL_3
changeset 15 ff572dfe6d86
parent 5 c743ef5928ba
child 16 9674c1a575e9
equal deleted inserted replaced
9:f966699dea19 15:ff572dfe6d86
   198 //
   198 //
   199 void CWmImageConverter::CreateIconFromUidL( const TUid& aUid )
   199 void CWmImageConverter::CreateIconFromUidL( const TUid& aUid )
   200     {
   200     {
   201     CFbsBitmap* bitmap = NULL;
   201     CFbsBitmap* bitmap = NULL;
   202     CFbsBitmap* mask = NULL;
   202     CFbsBitmap* mask = NULL;
   203     
   203    
       
   204    
   204     if ( aUid.iUid >= KWidgetUidLowerBound &&
   205     if ( aUid.iUid >= KWidgetUidLowerBound &&
   205        aUid.iUid < KWidgetUidUpperBound  )
   206        aUid.iUid < KWidgetUidUpperBound  )
   206         {
   207         {
   207         // AknsUtils::CreateAppIconLC panics incase of WRT
       
   208 
       
   209         RApaLsSession lsSession;
   208         RApaLsSession lsSession;
   210         User::LeaveIfError( lsSession.Connect() );
   209         User::LeaveIfError( lsSession.Connect() );
   211         CleanupClosePushL( lsSession );
   210         CleanupClosePushL( lsSession );
   212         
   211         
   213         const TInt KAppSizeArraySize = 3;
   212         const TInt KAppSizeArraySize = 3;
   214         CArrayFixFlat<TSize>* sizeArray = new (ELeave)
   213         CArrayFixFlat<TSize>* sizeArray = new (ELeave)
   215             CArrayFixFlat<TSize>( KAppSizeArraySize );
   214             CArrayFixFlat<TSize>( KAppSizeArraySize );
   216         CleanupStack::PushL( sizeArray );
   215         CleanupStack::PushL( sizeArray );
       
   216 
   217         User::LeaveIfError( lsSession.GetAppIconSizes( aUid, *sizeArray ) );
   217         User::LeaveIfError( lsSession.GetAppIconSizes( aUid, *sizeArray ) );
   218         TSize size;
   218         
       
   219         // there should be atleast one size available
       
   220         if ( sizeArray->Count() == 0 ){ User::Leave( KErrNotReady ); };
       
   221         
       
   222         TSize size(0,0);
   219         for( TInt i=0; i < sizeArray->Count(); i++ )
   223         for( TInt i=0; i < sizeArray->Count(); i++ )
   220             {
   224             {
   221             size = (*sizeArray)[i];
   225             TSize s = (*sizeArray)[i];
   222             if ( size == iSize )
   226             if ( size.iWidth < s.iWidth || size.iHeight < s.iHeight )
   223                 {
   227                 { size = s; }
   224                 break;
   228             if ( size == iSize ) { break; }
   225                 }
   229             }
   226             }
   230 
   227         CApaMaskedBitmap* maskedBmp = CApaMaskedBitmap::NewLC();
   231         CApaMaskedBitmap* maskedBmp = CApaMaskedBitmap::NewLC();
   228         User::LeaveIfError( lsSession.GetAppIcon( aUid, size, *maskedBmp ) );
   232         User::LeaveIfError( lsSession.GetAppIcon( aUid, size, *maskedBmp ) );
   229         iBitmap = static_cast<CFbsBitmap*>( maskedBmp );  // ownership transfered
       
   230         
   233         
   231         iMask = new ( ELeave ) CFbsBitmap;
   234         // handle bitmap
   232         User::LeaveIfError( iMask->Create( 
   235         iBitmap = new ( ELeave ) CFbsBitmap;
   233                                     maskedBmp->Mask()->SizeInPixels(), 
   236         User::LeaveIfError( iBitmap->Create( 
   234                                     maskedBmp->Mask()->DisplayMode() ) );
   237                 maskedBmp->SizeInPixels(), 
   235         // duplicate mask, origional is owned by maskedBmp
   238                 maskedBmp->DisplayMode() ) );
   236         iMask->Duplicate( maskedBmp->Mask()->Handle() );
   239 
   237         CleanupStack::Pop( maskedBmp );
   240         // scale bitmap
   238         maskedBmp = NULL;
   241         ScaleBitmapL( iSize, iBitmap, maskedBmp );  
   239         CleanupStack::PopAndDestroy(sizeArray); 
   242 
       
   243         // handle mask
       
   244         if ( maskedBmp->Mask() )
       
   245             {
       
   246             iMask = new ( ELeave ) CFbsBitmap;
       
   247             User::LeaveIfError( iMask->Create( 
       
   248                     maskedBmp->Mask()->SizeInPixels(), 
       
   249                     maskedBmp->Mask()->DisplayMode() ) );
       
   250             
       
   251             // scale mask
       
   252             ScaleBitmapL( iSize, iMask, maskedBmp->Mask() );
       
   253             }
       
   254         
       
   255         // cleanup
       
   256         CleanupStack::PopAndDestroy( maskedBmp );
       
   257         CleanupStack::PopAndDestroy( sizeArray ); 
   240         CleanupStack::PopAndDestroy( &lsSession );
   258         CleanupStack::PopAndDestroy( &lsSession );
   241 
   259         
   242         // scale or notify
   260         // notify
   243         if ( size == iSize )
   261         iState = EIdle;
   244             {
   262         iObserver->NotifyCompletion( KErrNone );
   245             iState = EIdle;
       
   246             iObserver->NotifyCompletion( KErrNone );
       
   247             }
       
   248         else
       
   249             {
       
   250             iScaleNeeded = ETrue;
       
   251             ScaleBitmap( iSize.iWidth, iSize.iHeight );
       
   252             }
       
   253         }
   263         }
   254     else if ( aUid.iUid != KNullUid.iUid )
   264     else if ( aUid.iUid != KNullUid.iUid )
   255         {
   265         {
   256         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
   266         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
   257         TInt err( KErrNone );
   267         TInt err( KErrNone );
   396     iBitmap->Create( size,
   406     iBitmap->Create( size,
   397                      iImageDecoder->FrameInfo().iFrameDisplayMode ); 
   407                      iImageDecoder->FrameInfo().iFrameDisplayMode ); 
   398     
   408     
   399     iMask = new (ELeave) CFbsBitmap();
   409     iMask = new (ELeave) CFbsBitmap();
   400     iMask->Create( size, EGray256 ); 
   410     iMask->Create( size, EGray256 ); 
   401     
   411 
   402     if ( size != iSize )
   412     if ( size != iSize )
   403         {
   413         {
   404         iScaleNeeded = ETrue;
   414         iScaleNeeded = ETrue;
   405         }
   415         }
   406 
   416 
   931         User::Leave( err );
   941         User::Leave( err );
   932 	    }
   942 	    }
   933     }
   943     }
   934 
   944 
   935 // ---------------------------------------------------------------------------
   945 // ---------------------------------------------------------------------------
       
   946 // CWmImageConverter::DoesScaleBitmapUseFallBack
       
   947 // ---------------------------------------------------------------------------
       
   948 //
       
   949 TBool CWmImageConverter::DoesScaleBitmapUseFallBack( CFbsBitmap* aSrcBitmap )
       
   950     {
       
   951     if ( !aSrcBitmap )
       
   952         {
       
   953         return EFalse;
       
   954         }
       
   955 
       
   956     TDisplayMode displayMode = aSrcBitmap->DisplayMode();
       
   957     TBool fallbackOnly = EFalse;
       
   958 
       
   959     switch ( displayMode )
       
   960         {
       
   961         case EGray2:
       
   962         case EGray4:
       
   963         case EGray16:
       
   964         case EColor16:
       
   965         case EColor16M:
       
   966         case ERgb:
       
   967         case EColor16MA:
       
   968             fallbackOnly = ETrue;
       
   969             break;
       
   970         case EGray256:
       
   971         case EColor4K:
       
   972         case EColor64K:
       
   973         case EColor256:
       
   974         case EColor16MU:
       
   975             // These are the supported modes
       
   976             break;
       
   977         default:
       
   978             fallbackOnly = ETrue;
       
   979         }
       
   980 
       
   981     return fallbackOnly;
       
   982     }
       
   983 
       
   984 
       
   985 // ---------------------------------------------------------------------------
       
   986 // CWmImageConverter::ScaleBitmapL
       
   987 // ---------------------------------------------------------------------------
       
   988 //
       
   989 void CWmImageConverter::ScaleBitmapL( 
       
   990                             const TSize& aSize,
       
   991                             CFbsBitmap* aTrgBitmap,
       
   992                             CFbsBitmap* aSrcBitmap )
       
   993     {
       
   994     if ( !aSrcBitmap ) User::Leave( KErrArgument );
       
   995     if ( !aTrgBitmap ) User::Leave( KErrArgument );
       
   996     if ( aSrcBitmap->DisplayMode() != aTrgBitmap->DisplayMode() )
       
   997         {
       
   998         User::Leave( KErrArgument );
       
   999         }
       
  1000     
       
  1001     TRect targetRect( aSize );
       
  1002 
       
  1003     // calculate aspect ratio
       
  1004     TInt srcHeight = aSrcBitmap->SizeInPixels().iHeight;
       
  1005     TInt srcWidth = aSrcBitmap->SizeInPixels().iWidth;
       
  1006     TReal scaleRatio( 1 ); //no scale as defaul
       
  1007     
       
  1008     //If any dimension is 0, then we do not bother to scale
       
  1009     if ( targetRect.Width() > 0 && targetRect.Height() > 0 )
       
  1010         {
       
  1011         TReal xRatio = ( ( TReal )srcWidth / ( TReal )targetRect.Width() );
       
  1012         TReal yRatio = ( ( TReal )srcHeight / ( TReal )targetRect.Height() );
       
  1013         //Find out appropriate scaling factor
       
  1014         xRatio > yRatio ? ( scaleRatio = xRatio ) : ( scaleRatio = yRatio );
       
  1015         }
       
  1016 
       
  1017     //Scale the size for target bitmap
       
  1018     targetRect.SetHeight( srcHeight / scaleRatio );
       
  1019     targetRect.SetWidth( srcWidth / scaleRatio );    
       
  1020     
       
  1021     TSize trgBitmapSize = aTrgBitmap->SizeInPixels();
       
  1022     
       
  1023     // calculate the valid drawing area
       
  1024     TRect drawRect = targetRect;
       
  1025     drawRect.Intersection( TRect( TPoint( 0, 0 ), trgBitmapSize ) );
       
  1026 
       
  1027     if( drawRect.IsEmpty() || 
       
  1028         aSrcBitmap->SizeInPixels().iHeight <= 0 || 
       
  1029         aSrcBitmap->SizeInPixels().iWidth <= 0 )
       
  1030         {
       
  1031         User::Leave( KErrArgument );
       
  1032         }
       
  1033 
       
  1034     TSize srcSize = aSrcBitmap->SizeInPixels();
       
  1035 
       
  1036     TBool srcTemporary = EFalse;
       
  1037     if ( aSrcBitmap->IsRomBitmap() )
       
  1038         {
       
  1039         srcTemporary = ETrue;
       
  1040         }
       
  1041 
       
  1042     TDisplayMode displayMode = aSrcBitmap->DisplayMode();
       
  1043     TBool fallbackOnly = DoesScaleBitmapUseFallBack( aSrcBitmap );
       
  1044 
       
  1045     if ( fallbackOnly )
       
  1046         {
       
  1047         CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( aTrgBitmap );
       
  1048         CleanupStack::PushL( dev );
       
  1049         CFbsBitGc* gc = NULL;
       
  1050         User::LeaveIfError( dev->CreateContext( gc ) );
       
  1051         CleanupStack::PushL( gc );
       
  1052 
       
  1053         // write alpha information if it exists
       
  1054         if ( aSrcBitmap->DisplayMode() == EColor16MA )
       
  1055             {
       
  1056             gc->SetDrawMode( CGraphicsContext::EDrawModeWriteAlpha );
       
  1057             }
       
  1058 
       
  1059         // targetRect is used because DrawBitmap handles clipping automatically
       
  1060         gc->DrawBitmap( targetRect, aSrcBitmap );
       
  1061         CleanupStack::PopAndDestroy( 2 ); // dev, gc
       
  1062         return;
       
  1063         }
       
  1064 
       
  1065     // Heap lock for FBServ large chunk to prevent background
       
  1066     // compression of aSrcBitmap after if IsCompressedInRAM returns EFalse
       
  1067     aSrcBitmap->LockHeapLC( ETrue ); // fbsheaplock
       
  1068     TBool fbsHeapLock = ETrue;
       
  1069     if ( aSrcBitmap->IsCompressedInRAM() )
       
  1070         {
       
  1071         srcTemporary = ETrue;
       
  1072         }
       
  1073 
       
  1074     CFbsBitmap* realSource = aSrcBitmap;
       
  1075     if ( srcTemporary )
       
  1076         {
       
  1077         CleanupStack::PopAndDestroy(); // fbsheaplock
       
  1078         fbsHeapLock = EFalse;
       
  1079 
       
  1080         realSource = new ( ELeave ) CFbsBitmap();
       
  1081         CleanupStack::PushL( realSource );
       
  1082         User::LeaveIfError(
       
  1083             realSource->Create( srcSize, aSrcBitmap->DisplayMode() ) );
       
  1084         CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( realSource );
       
  1085         CleanupStack::PushL( dev );
       
  1086         CFbsBitGc* gc = NULL;
       
  1087         User::LeaveIfError( dev->CreateContext( gc ) );
       
  1088         CleanupStack::PushL( gc );
       
  1089         gc->BitBlt( TPoint( 0, 0 ), aSrcBitmap );
       
  1090         CleanupStack::PopAndDestroy( 2 ); // dev, gc
       
  1091         }
       
  1092 
       
  1093     if ( !fbsHeapLock )
       
  1094         {
       
  1095         // Heap lock for FBServ large chunk is only needed with large bitmaps.
       
  1096         if ( realSource->IsLargeBitmap() || aTrgBitmap->IsLargeBitmap() )
       
  1097             {
       
  1098             aTrgBitmap->LockHeapLC( ETrue ); // fbsheaplock
       
  1099             }
       
  1100         else
       
  1101             {
       
  1102             CleanupStack::PushL( ( TAny* )NULL );
       
  1103             }
       
  1104         }
       
  1105 
       
  1106     TUint32* srcAddress = realSource->DataAddress();
       
  1107     TUint32* trgAddress = aTrgBitmap->DataAddress();
       
  1108 
       
  1109     const TInt xSkip = ( srcSize.iWidth << 8 ) / targetRect.Width();
       
  1110     const TInt ySkip = ( srcSize.iHeight << 8 ) / targetRect.Height();
       
  1111 
       
  1112     const TInt drawWidth  = drawRect.Width();
       
  1113     const TInt drawHeight = drawRect.Height();
       
  1114 
       
  1115     TRect offsetRect( targetRect.iTl, drawRect.iTl );
       
  1116     const TInt yPosOffset = ySkip * offsetRect.Height();
       
  1117     const TInt xPosOffset = xSkip * offsetRect.Width();
       
  1118 
       
  1119     if ( ( displayMode == EGray256 ) || ( displayMode == EColor256 ) )
       
  1120         {
       
  1121         TInt srcScanLen8 = CFbsBitmap::ScanLineLength(
       
  1122             srcSize.iWidth, displayMode );
       
  1123         TInt trgScanLen8 = CFbsBitmap::ScanLineLength(
       
  1124             trgBitmapSize.iWidth, displayMode );
       
  1125 
       
  1126         TUint8* trgAddress8 = reinterpret_cast< TUint8* >( trgAddress );
       
  1127 
       
  1128         TInt yPos = yPosOffset;
       
  1129         // skip left and top margins in the beginning
       
  1130         trgAddress8 += trgScanLen8 * drawRect.iTl.iY + drawRect.iTl.iX;
       
  1131 
       
  1132         for ( TInt y = 0; y < drawHeight; y++ )
       
  1133             {
       
  1134             TUint8* srcAddress8 = reinterpret_cast< TUint8* >( srcAddress ) +
       
  1135                 ( srcScanLen8 * ( yPos >> 8 ) );
       
  1136 
       
  1137             TInt xPos = xPosOffset;
       
  1138             for ( TInt x = 0; x < drawWidth; x++ )
       
  1139                 {
       
  1140                 *( trgAddress8++ ) = srcAddress8[xPos >> 8];
       
  1141                 xPos += xSkip;
       
  1142                 }
       
  1143 
       
  1144             yPos += ySkip;
       
  1145 
       
  1146             trgAddress8 += trgScanLen8 - drawWidth;
       
  1147             }
       
  1148         }
       
  1149     else if ( displayMode == EColor4K || displayMode == EColor64K )
       
  1150         {
       
  1151         TInt srcScanLen16 = CFbsBitmap::ScanLineLength(
       
  1152             srcSize.iWidth, displayMode ) /2;
       
  1153         TInt trgScanLen16 = CFbsBitmap::ScanLineLength(
       
  1154             trgBitmapSize.iWidth, displayMode ) /2;
       
  1155 
       
  1156         TUint16* trgAddress16 = reinterpret_cast< TUint16* >( trgAddress );
       
  1157 
       
  1158         TInt yPos = yPosOffset;
       
  1159         // skip left and top margins in the beginning
       
  1160         trgAddress16 += trgScanLen16 * drawRect.iTl.iY + drawRect.iTl.iX;
       
  1161 
       
  1162         for ( TInt y = 0; y < drawHeight; y++ )
       
  1163             {
       
  1164             TUint16* srcAddress16 = reinterpret_cast< TUint16* >( srcAddress ) +
       
  1165                 ( srcScanLen16 * ( yPos >> 8 ) );
       
  1166 
       
  1167             TInt xPos = xPosOffset;
       
  1168             for ( TInt x = 0; x < drawWidth; x++ )
       
  1169                 {
       
  1170                 *( trgAddress16++ ) = srcAddress16[xPos >> 8];
       
  1171                 xPos += xSkip;
       
  1172                 }
       
  1173 
       
  1174             yPos += ySkip;
       
  1175 
       
  1176             trgAddress16 += trgScanLen16 - drawWidth;
       
  1177             }
       
  1178         }
       
  1179     else if ( displayMode == EColor16MU )
       
  1180         {
       
  1181         TInt srcScanLen32 = CFbsBitmap::ScanLineLength(
       
  1182             srcSize.iWidth, displayMode ) /4;
       
  1183         TInt trgScanLen32 = CFbsBitmap::ScanLineLength(
       
  1184             trgBitmapSize.iWidth, displayMode ) /4;
       
  1185 
       
  1186         TUint32* trgAddress32 = reinterpret_cast< TUint32* >( trgAddress );
       
  1187 
       
  1188         TInt yPos = yPosOffset;
       
  1189         // skip left and top margins in the beginning
       
  1190         trgAddress32 += trgScanLen32 * drawRect.iTl.iY + drawRect.iTl.iX;
       
  1191 
       
  1192         for ( TInt y = 0; y < drawHeight; y++ )
       
  1193             {
       
  1194             TUint32* srcAddress32 = reinterpret_cast< TUint32* >( srcAddress ) +
       
  1195                 ( srcScanLen32 * ( yPos >> 8 ) );
       
  1196 
       
  1197             TInt xPos = xPosOffset;
       
  1198             for ( TInt x = 0; x < drawWidth; x++ )
       
  1199                 {
       
  1200                 *( trgAddress32++ ) = srcAddress32[xPos >> 8];
       
  1201                 xPos += xSkip;
       
  1202                 }
       
  1203 
       
  1204             yPos += ySkip;
       
  1205 
       
  1206             trgAddress32 += trgScanLen32 - drawWidth;
       
  1207             }
       
  1208         }
       
  1209     else
       
  1210         {
       
  1211         User::Leave( KErrUnknown );
       
  1212         }
       
  1213 
       
  1214     CleanupStack::PopAndDestroy(); // fbsheaplock
       
  1215 
       
  1216     if ( srcTemporary )
       
  1217         {
       
  1218         CleanupStack::PopAndDestroy(); // realSource
       
  1219         }
       
  1220     }
       
  1221 
       
  1222 // ---------------------------------------------------------------------------
   936 // CWmImageConverter::Finished
  1223 // CWmImageConverter::Finished
   937 // ---------------------------------------------------------------------------
  1224 // ---------------------------------------------------------------------------
   938 //
  1225 //
   939 void CWmImageConverter::Finished()
  1226 void CWmImageConverter::Finished()
   940     {
  1227     {