skins/AknSkins/rlpluginsrc/AknsRlEffectPluginMovingLayers.cpp
changeset 0 05e9090e2422
equal deleted inserted replaced
-1:000000000000 0:05e9090e2422
       
     1 /*
       
     2 * Copyright (c) 2004-2008 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:  Provides moving layer(s) functionality.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "AknsRlEffectPluginMovingLayers.h"
       
    21 
       
    22 // ================= INTERNAL IMPL. OF MOVING LAYERS ===========================
       
    23 class AknsRlMovingLayers
       
    24     {
       
    25     public:
       
    26     static void RenderTiled( CFbsBitGc& aBitGc,
       
    27                          const TInt aX, const TInt aY,
       
    28                          const TInt aW, const TInt aH,
       
    29                          const CFbsBitmap& aBmp,
       
    30                          const CFbsBitmap* aMask=NULL )
       
    31         {
       
    32         if( 0 == aX && 0 == aY ) // Render 1:1
       
    33             {
       
    34             if( aMask )
       
    35                 {
       
    36                 aBitGc.BitBltMasked( TPoint( 0, 0 ), &aBmp,
       
    37                                      TRect( TPoint( 0, 0 ),
       
    38                                      TSize( aW, aH ) ),
       
    39                                      aMask, EFalse );
       
    40                 }
       
    41             else
       
    42                 {
       
    43                 aBitGc.BitBlt( TPoint( 0, 0 ), &aBmp,
       
    44                                 TRect( TPoint( 0, 0 ),
       
    45                                 TSize( aW, aH ) ) );
       
    46                 }
       
    47             }
       
    48         else // Draw tiled
       
    49             {
       
    50             /*
       
    51             Output        Input
       
    52              ---------     ---------
       
    53             |4' |3'   |   |1    |2  |
       
    54             |---o-----|   |     |   |
       
    55             |2' |1'   |   |     |   |
       
    56             |   |     |   |     |   |
       
    57             |   |     |   |-----o---|
       
    58             |   |     |   |3    |4  |
       
    59              ---------     ---------
       
    60 
       
    61             Output rects:
       
    62             1' (     x,     y, w - x, h - y )
       
    63             2' (     0,     y,     x, h - y )
       
    64             3' (     x,     0, w - x,     y )
       
    65             4' (     0,     0,     x,     y )
       
    66 
       
    67             Input rects:
       
    68             1  (     0,     0, w - x, h - y )
       
    69             2  ( w - x,     0,     x, h - y )
       
    70             3  (     0, h - y, w - x,     y )
       
    71             4  ( w - x, h - y,     x,     y )
       
    72 
       
    73             */
       
    74             TRect source;
       
    75 
       
    76             if( aMask )
       
    77                 {
       
    78                 // Target top left ( 4 -> 4' )
       
    79                 source.SetRect( TPoint( aW - aX, aH - aY ), TSize( aX, aY ) );
       
    80                 aBitGc.BitBltMasked( TPoint( 0, 0 ), &aBmp, source, aMask, EFalse );
       
    81                 // Target top right ( 3 -> 3' )
       
    82                 source.SetRect( TPoint( 0, aH - aY ), TSize( aW - aX, aY ) );
       
    83                 aBitGc.BitBltMasked( TPoint( aX, 0 ), &aBmp, source, aMask, EFalse );
       
    84                 // Target bottom left ( 2 -> 2' )
       
    85                 source.SetRect( TPoint( aW - aX, 0 ), TSize( aX, aH - aY ) );
       
    86                 aBitGc.BitBltMasked( TPoint( 0, aY ), &aBmp, source, aMask, EFalse );
       
    87                 // Target bottom right ( 1 -> 1' )
       
    88                 source.SetRect( TPoint( 0, 0 ), TSize( aW - aX, aH - aY ) );
       
    89                 aBitGc.BitBltMasked( TPoint( aX, aY ), &aBmp, source, aMask, EFalse );
       
    90                 }
       
    91             else
       
    92                 {
       
    93                 // Target top left ( 4 -> 4' )
       
    94                 source.SetRect( TPoint( aW - aX, aH - aY ), TSize( aX, aY ) );
       
    95                 aBitGc.BitBlt( TPoint( 0, 0 ), &aBmp, source );
       
    96                 // Target top right ( 3 -> 3' )
       
    97                 source.SetRect( TPoint( 0, aH - aY ), TSize( aW - aX, aY ) );
       
    98                 aBitGc.BitBlt( TPoint( aX, 0 ), &aBmp, source );
       
    99                 // Target bottom left ( 2 -> 2' )
       
   100                 source.SetRect( TPoint( aW - aX, 0 ), TSize( aX, aH - aY ) );
       
   101                 aBitGc.BitBlt( TPoint( 0, aY ), &aBmp, source );
       
   102                 // Target bottom right ( 1 -> 1' )
       
   103                 source.SetRect( TPoint( 0, 0 ), TSize( aW - aX, aH - aY ) );
       
   104                 aBitGc.BitBlt( TPoint( aX, aY ), &aBmp, source );
       
   105                 }
       
   106             }
       
   107         }
       
   108     };
       
   109 
       
   110 // ============================ MEMBER FUNCTIONS ===============================
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CAknsRlEffectPluginMovingLayers::CAknsRlEffectPluginMovingLayers
       
   114 // C++ default constructor can NOT contain any code, that
       
   115 // might leave.
       
   116 // -----------------------------------------------------------------------------
       
   117 //
       
   118 CAknsRlEffectPluginMovingLayers::CAknsRlEffectPluginMovingLayers()
       
   119     {
       
   120     }
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // Destructor
       
   124 // -----------------------------------------------------------------------------
       
   125 //
       
   126 CAknsRlEffectPluginMovingLayers::~CAknsRlEffectPluginMovingLayers()
       
   127     {
       
   128     // The user of this plugin should call deactivate...but we ensure deletion
       
   129     // here (just in case).
       
   130     DeleteTempBitmap(); //lint !e1551 No exception thrown
       
   131     }
       
   132 
       
   133 // -----------------------------------------------------------------------------
       
   134 // CAknsRlEffectPluginMovingLayers::EffectUid
       
   135 // -----------------------------------------------------------------------------
       
   136 //
       
   137 TUid CAknsRlEffectPluginMovingLayers::EffectUid() const
       
   138     {
       
   139     return TUid::Uid( KAknsRlEffectPluginMovingLayersUID );
       
   140     }
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // CAknsRlEffectPluginMovingLayers::Effect
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 MAknsRlEffect* CAknsRlEffectPluginMovingLayers::Effect( const TInt aInterface )
       
   147     {
       
   148     if( aInterface == KAknsRlEffectPluginInterfaceEffect )
       
   149         return this;
       
   150     return NULL;
       
   151     }
       
   152 
       
   153 // -----------------------------------------------------------------------------
       
   154 // CAknsRlEffectPluginMovingLayers::InitializeL
       
   155 // -----------------------------------------------------------------------------
       
   156 //
       
   157 void CAknsRlEffectPluginMovingLayers::InitializeL()
       
   158     {
       
   159     iContext = NULL;
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CAknsRlEffectPluginMovingLayers::Release
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 void CAknsRlEffectPluginMovingLayers::Release()
       
   167     {
       
   168     }
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CAknsRlEffectPluginMovingLayers::ActivateL
       
   172 // -----------------------------------------------------------------------------
       
   173 //
       
   174 void CAknsRlEffectPluginMovingLayers::ActivateL( MAknsRlEffectContext* aContext )
       
   175     {
       
   176     if( !aContext ) // We absolutely need the context
       
   177         {
       
   178         User::Leave( KErrArgument );
       
   179         }
       
   180 
       
   181     iContext = aContext;
       
   182 
       
   183     iAx = 0;
       
   184     iAy = 0;
       
   185     iBx = 0;
       
   186     iBy = 0;
       
   187 
       
   188     DeleteTempBitmap();
       
   189     }
       
   190 
       
   191 // -----------------------------------------------------------------------------
       
   192 // CAknsRlEffectPluginMovingLayers::Deactivate
       
   193 // -----------------------------------------------------------------------------
       
   194 //
       
   195 void CAknsRlEffectPluginMovingLayers::Deactivate()
       
   196     {
       
   197     DeleteTempBitmap();
       
   198     }
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // CAknsRlEffectPluginMovingLayers::SetParametersL
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 void CAknsRlEffectPluginMovingLayers::SetParametersL( MAknsRlParameterIterator& aParameters )
       
   205     {
       
   206     // Iterate over available parameters
       
   207     while( aParameters.HasNext() )
       
   208         {
       
   209         const TAknsRlParameterData* param = aParameters.NextL();
       
   210 
       
   211         if( param->iName->Compare( KAknsRlEffectMovingLayersAX ) == 0 )
       
   212             {
       
   213             if( param->iType != EAknsRlParameterTypeNumber )
       
   214                 User::Leave( KErrArgument );
       
   215 
       
   216             iAx = param->iNumber;
       
   217             }
       
   218         else if( param->iName->Compare( KAknsRlEffectMovingLayersAY ) == 0 )
       
   219             {
       
   220             if( param->iType != EAknsRlParameterTypeNumber )
       
   221                 User::Leave( KErrArgument );
       
   222 
       
   223             iAy = param->iNumber;
       
   224             }
       
   225         else if( param->iName->Compare( KAknsRlEffectMovingLayersBX ) == 0 )
       
   226             {
       
   227             if( param->iType != EAknsRlParameterTypeNumber )
       
   228                 User::Leave( KErrArgument );
       
   229 
       
   230             iBx = param->iNumber;
       
   231             }
       
   232         else if( param->iName->Compare( KAknsRlEffectMovingLayersBY ) == 0 )
       
   233             {
       
   234             if( param->iType != EAknsRlParameterTypeNumber )
       
   235                 User::Leave( KErrArgument );
       
   236 
       
   237             iBy = param->iNumber;
       
   238             }
       
   239         else if( param->iName->Compare( KAknsRlEffectMovingLayersAXY ) == 0 )
       
   240             {
       
   241             if( param->iType != EAknsRlParameterTypeString || !param->iString )
       
   242                 User::Leave( KErrArgument );
       
   243 
       
   244             if( param->iString->Length() < 2 )
       
   245                 User::Leave( KErrArgument );
       
   246 
       
   247             iAx = (*param->iString)[0];
       
   248             iAy = (*param->iString)[1];
       
   249             }
       
   250         else if( param->iName->Compare( KAknsRlEffectMovingLayersBXY ) == 0 )
       
   251             {
       
   252             if( param->iType != EAknsRlParameterTypeString || !param->iString )
       
   253                 User::Leave( KErrArgument );
       
   254 
       
   255             if( param->iString->Length() < 2 )
       
   256                 User::Leave( KErrArgument );
       
   257 
       
   258             iBx = (*param->iString)[0];
       
   259             iBy = (*param->iString)[1];
       
   260             }
       
   261         }
       
   262     }
       
   263 
       
   264 // -----------------------------------------------------------------------------
       
   265 // CAknsRlEffectPluginMovingLayers::GetCapabilities
       
   266 // -----------------------------------------------------------------------------
       
   267 //
       
   268 void CAknsRlEffectPluginMovingLayers::GetCapabilities( TAknsRlEffectCaps& aCaps )
       
   269     {
       
   270     aCaps.iOutputLayerSupport = KAknsRlLayerRGBOnly;
       
   271     aCaps.iInputLayerASupport = KAknsRlLayerRGBOnly;
       
   272     aCaps.iInputLayerBSupport = KAknsRlLayerNone | KAknsRlLayerRGBOnly | KAknsRlLayerRGBA;
       
   273     }
       
   274 
       
   275 // -----------------------------------------------------------------------------
       
   276 // CAknsRlEffectPluginMovingLayers::Render
       
   277 // -----------------------------------------------------------------------------
       
   278 //
       
   279 TInt CAknsRlEffectPluginMovingLayers::Render( const TAknsRlRenderOpParam& aParam )
       
   280     {
       
   281     if( !iContext ) // We absolutely need the context
       
   282         {
       
   283         return KErrBadHandle;
       
   284         }
       
   285 
       
   286     TAknsRlLayerData dataT;
       
   287     TAknsRlLayerData dataA;
       
   288     TAknsRlLayerData dataB;
       
   289 
       
   290     // We need the output layer
       
   291     if( !( ( aParam.iOutputLayerStatus & KAknsRlLayerRGBOnly ) ||
       
   292            ( aParam.iOutputLayerStatus & KAknsRlLayerRGBA ) ) )
       
   293         return KErrArgument; // Output must be some sort of RGB layer
       
   294 
       
   295     TRAPD( err, iContext->GetLayerDataL( dataT, aParam.iOutputLayerIndex,
       
   296                                          aParam.iOutputLayerStatus, EFalse ) );
       
   297     if( KErrNone != err )
       
   298         return KErrArgument;
       
   299 
       
   300     if( !dataT.iRGBGc || !dataT.iRGBBitmap )
       
   301         return KErrBadHandle;
       
   302 
       
   303     // We need the input layer A
       
   304     if( !( ( aParam.iInputLayerAStatus & KAknsRlLayerRGBOnly ) ||
       
   305            ( aParam.iInputLayerAStatus & KAknsRlLayerRGBA ) ) )
       
   306         return KErrArgument; // Input layer A must be some sort of RGB layer
       
   307 
       
   308     TRAP( err, iContext->GetLayerDataL( dataA, aParam.iInputLayerAIndex,
       
   309                                         aParam.iInputLayerAStatus, EFalse ) );
       
   310     if( KErrNone != err )
       
   311         return KErrArgument;
       
   312 
       
   313     if( !dataA.iRGBBitmap )
       
   314         return KErrBadHandle;
       
   315 
       
   316     // Input layer B is optional
       
   317     if( ( aParam.iInputLayerBStatus & KAknsRlLayerRGBOnly ) ||
       
   318         ( aParam.iInputLayerBStatus & KAknsRlLayerRGBA ) )
       
   319         {
       
   320         // Input layer B is RGB layer
       
   321         TRAP( err, iContext->GetLayerDataL( dataB, aParam.iInputLayerBIndex,
       
   322                                             aParam.iInputLayerBStatus, EFalse ) );
       
   323         if( KErrNone != err )
       
   324             return KErrArgument;
       
   325 
       
   326         if( !dataB.iRGBBitmap )
       
   327             return KErrBadHandle;
       
   328         }
       
   329 
       
   330     // If we got this far we have all the required devices for doing rendering.
       
   331 
       
   332     // Tiled rendering does not work correctly if one of the input layers is
       
   333     // the same as output layer.
       
   334     if( ( aParam.iInputLayerAIndex == aParam.iOutputLayerIndex && dataA.iRGBBitmap ) ||
       
   335         ( aParam.iInputLayerBIndex == aParam.iOutputLayerIndex && dataB.iRGBBitmap ) )
       
   336         {
       
   337         if( !iTempBitmap )
       
   338             {
       
   339             err = CreateTempBitmap( *dataT.iRGBBitmap );
       
   340             if( KErrNone != err )
       
   341                 return err;
       
   342             }
       
   343         else // Temp bitmap already exists
       
   344             {
       
   345             // Check if we can reuse the existing bitmap
       
   346             if( iTempBitmap->SizeInPixels() == dataT.iRGBBitmap->SizeInPixels() &&
       
   347                 iTempBitmap->DisplayMode() == dataT.iRGBBitmap->DisplayMode() )
       
   348                 {
       
   349                 iTempContext->BitBlt( TPoint( 0, 0 ), dataT.iRGBBitmap );
       
   350                 }
       
   351             else
       
   352                 {
       
   353                 DeleteTempBitmap();
       
   354                 err = CreateTempBitmap( *dataT.iRGBBitmap );
       
   355                 if( KErrNone != err )
       
   356                     return err;
       
   357                 }
       
   358             }
       
   359         }
       
   360 
       
   361     // Determine real coordinates (we do tiling)
       
   362     TSize size = iContext->LayerSize();
       
   363 
       
   364     TInt ax = iAx % size.iWidth;
       
   365     TInt ay = iAy % size.iHeight;
       
   366 
       
   367     if( ax < 0 )
       
   368         ax = ax + size.iWidth;
       
   369     if( ay < 0 )
       
   370         ay = ay + size.iHeight;
       
   371     // ax, bx are now in range [0, size.iWidth - 1]
       
   372 
       
   373     TInt bx = iBx % size.iWidth;
       
   374     TInt by = iBy % size.iHeight;
       
   375 
       
   376     if( bx < 0 )
       
   377         bx = bx + size.iWidth;
       
   378     if( by < 0 )
       
   379         by = by + size.iHeight;
       
   380     // bx, by are now in range [0, size.iHeight - 1]
       
   381 
       
   382     // Render
       
   383     if( dataA.iRGBBitmap && !dataB.iRGBBitmap ) // Only A is available
       
   384         {
       
   385         if( aParam.iInputLayerAIndex == aParam.iOutputLayerIndex  )
       
   386             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   387                             ax, ay, size.iWidth, size.iHeight,
       
   388                             *iTempBitmap );
       
   389         else
       
   390             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   391                             ax, ay, size.iWidth, size.iHeight,
       
   392                             *dataA.iRGBBitmap );
       
   393         }
       
   394     // A, B and mask B available
       
   395     else if( dataA.iRGBBitmap && dataB.iRGBBitmap && dataB.iAlphaBitmap )
       
   396         {
       
   397         if( aParam.iInputLayerAIndex == aParam.iOutputLayerIndex  )
       
   398             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   399                             ax, ay, size.iWidth, size.iHeight,
       
   400                             *iTempBitmap );
       
   401         else
       
   402             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   403                             ax, ay, size.iWidth, size.iHeight,
       
   404                             *dataA.iRGBBitmap );
       
   405 
       
   406         if( aParam.iInputLayerBIndex == aParam.iOutputLayerIndex  )
       
   407             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   408                             bx, by, size.iWidth, size.iHeight,
       
   409                             *iTempBitmap );
       
   410         else
       
   411             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   412                             bx, by, size.iWidth, size.iHeight,
       
   413                             *dataB.iRGBBitmap, dataB.iAlphaBitmap );
       
   414         }
       
   415     // A and B available, but no mask for B
       
   416     else if( dataA.iRGBBitmap && dataB.iRGBBitmap && !dataB.iAlphaBitmap )
       
   417         {
       
   418         // Render B only
       
   419         if( aParam.iInputLayerBIndex == aParam.iOutputLayerIndex  )
       
   420             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   421                             bx, by, size.iWidth, size.iHeight,
       
   422                             *iTempBitmap );
       
   423         else
       
   424             AknsRlMovingLayers::RenderTiled( *dataT.iRGBGc,
       
   425                             bx, by, size.iWidth, size.iHeight,
       
   426                             *dataB.iRGBBitmap, dataB.iAlphaBitmap );
       
   427         }
       
   428 
       
   429     // Clear the target alpha if it exists
       
   430     if( dataT.iAlphaGc )
       
   431         {
       
   432         dataT.iAlphaGc->SetBrushColor( KRgbWhite );
       
   433         dataT.iAlphaGc->Clear();
       
   434         }
       
   435 
       
   436     return KErrNone;
       
   437     }
       
   438 
       
   439 // -----------------------------------------------------------------------------
       
   440 // CAknsRlEffectPluginMovingLayers::CreateTempBitmap
       
   441 // -----------------------------------------------------------------------------
       
   442 //
       
   443 TInt CAknsRlEffectPluginMovingLayers::CreateTempBitmap(
       
   444     const CFbsBitmap& aBitmap )
       
   445     {
       
   446     ASSERT( NULL == iTempBitmap );
       
   447     ASSERT( NULL == iTempDevice );
       
   448     ASSERT( NULL == iTempContext );
       
   449 
       
   450     iTempBitmap = new CFbsBitmap(); // OOM returns NULL
       
   451     if( !iTempBitmap )
       
   452         {
       
   453         DeleteTempBitmap();
       
   454         return KErrNoMemory;
       
   455         }
       
   456 
       
   457     TInt err = iTempBitmap->Create( aBitmap.SizeInPixels(), aBitmap.DisplayMode() );
       
   458     if( KErrNone != err )
       
   459         {
       
   460         DeleteTempBitmap();
       
   461         return err;
       
   462         }
       
   463 
       
   464     TRAP( err, iTempDevice = CFbsBitmapDevice::NewL( iTempBitmap ) );
       
   465     if( KErrNone != err )
       
   466         {
       
   467         DeleteTempBitmap();
       
   468         return err;
       
   469         }
       
   470 
       
   471     err = iTempDevice->CreateContext( iTempContext );
       
   472     if( KErrNone != err )
       
   473         {
       
   474         DeleteTempBitmap();
       
   475         return err;
       
   476         }
       
   477 
       
   478     // Temp bitmap and related objects created ok, just render the temp bitmap.
       
   479     iTempContext->BitBlt( TPoint( 0, 0 ), &aBitmap );
       
   480 
       
   481     return KErrNone;
       
   482     }
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CAknsRlEffectPluginMovingLayers::DeleteTempBitmap
       
   486 // -----------------------------------------------------------------------------
       
   487 //
       
   488 void CAknsRlEffectPluginMovingLayers::DeleteTempBitmap()
       
   489     {
       
   490     delete iTempBitmap;
       
   491     iTempBitmap  = NULL;
       
   492     delete iTempDevice;
       
   493     iTempDevice  = NULL;
       
   494     delete iTempContext;
       
   495     iTempContext = NULL;
       
   496     }
       
   497 
       
   498 // End of File
       
   499