skins/AknSkins/rlpluginsrc/AknsRlEffectPluginChannelBlend.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:  ChannelBlend provides functionality to combine bitmaps arithmetically.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "AknsRlEffectPluginChannelBlend.h"
       
    21 #include "AknsRlEffectUtil.h"
       
    22 #include "AknsRlExpand.h"
       
    23 
       
    24 // ==================== TEMPLATE IMPL. OF CHANNEL BLEND ========================
       
    25 /**
       
    26 * Template implementation of ChannelBlend. It is assumed that arithmetic
       
    27 * shifting is supported -> negative values are shifted correctly. Pitch is the
       
    28 * number of data elements to skip before moving to next line. Note that all
       
    29 * non-masked cases are also done with the alpha blended version (masks are
       
    30 * constants in that case).
       
    31 *
       
    32 * The next parameters are passed to blend functions:
       
    33 * aW      Bitmap width in pixels
       
    34 * aH      Bitmap height in pixels
       
    35 * aT      Target bitmap data address
       
    36 * aPT     Target bitmap scanline pitch
       
    37 * aA      Source bitmap A data address
       
    38 * aPA     Source bitmap A scanline pitch
       
    39 * aMA     Source bitmap A mask data address
       
    40 * aPMA    Source bitmap A mask scanline pitch
       
    41 * aB      Source bitmap B data address
       
    42 * aPB     Source bitmap B scanline pitch
       
    43 * aMB     Source bitmap B mask data address
       
    44 * aPMA    Source bitmap B mask scanline pitch
       
    45 * aFactor The blend factor between A and B on the output.
       
    46 *
       
    47 * Inside methods local variables have the following roles:
       
    48 * x   The current pixel's x position
       
    49 * y   The current pixel's y position
       
    50 * r   The resulting red color component
       
    51 * g   The resulting green color component
       
    52 * b   The resulting blue color component
       
    53 * sa  Currently processed source A color component
       
    54 * sb  Currently processed source B color component
       
    55 * ma  Mask A value for current pixel position
       
    56 * mb  Mask B value for current pixel position
       
    57 * ca  A RGB color value for current pixel position
       
    58 * cb  B RGB color value for current pixel position
       
    59 */
       
    60 template <class T, TInt X, TInt R, TInt G, TInt B>
       
    61 class AknsRlBlend
       
    62     {
       
    63     public:
       
    64     static void Normal( TInt aW, TInt aH, T* aT, TInt aPT,
       
    65                         const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
    66                         const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
    67                         TInt aFactor );
       
    68 
       
    69     static void Darken( TInt aW, TInt aH, T* aT, TInt aPT,
       
    70                         const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
    71                         const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
    72                         TInt aFactor );
       
    73 
       
    74     static void Lighten( TInt aW, TInt aH, T* aT, TInt aPT,
       
    75                          const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
    76                          const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
    77                          TInt aFactor );
       
    78 
       
    79     static void Multiply( TInt aW, TInt aH, T* aT, TInt aPT,
       
    80                           const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
    81                           const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
    82                           TInt aFactor );
       
    83 
       
    84     static void Screen( TInt aW, TInt aH, T* aT, TInt aPT,
       
    85                         const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
    86                         const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
    87                         TInt aFactor );
       
    88 
       
    89     static void Overlay( TInt aW, TInt aH, T* aT, TInt aPT,
       
    90                          const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
    91                          const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
    92                          TInt aFactor );
       
    93 
       
    94     static void HardLight( TInt aW, TInt aH, T* aT, TInt aPT,
       
    95                            const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
    96                            const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
    97                            TInt aFactor );
       
    98 
       
    99     static void SoftLight( TInt aW, TInt aH, T* aT, TInt aPT,
       
   100                            const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   101                            const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   102                            TInt aFactor );
       
   103 
       
   104     static void Difference( TInt aW, TInt aH, T* aT, TInt aPT,
       
   105                             const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   106                             const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   107                             TInt aFactor );
       
   108 
       
   109     static void Dodge( TInt aW, TInt aH, T* aT, TInt aPT,
       
   110                        const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   111                        const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   112                        TInt aFactor );
       
   113 
       
   114     static void Burn( TInt aW, TInt aH, T* aT, TInt aPT,
       
   115                       const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   116                       const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   117                       TInt aFactor );
       
   118     };
       
   119 
       
   120 // -----------------------------------------------------------------------------
       
   121 // AknsRlBlend::Normal
       
   122 // -----------------------------------------------------------------------------
       
   123 //
       
   124 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   125 void AknsRlBlend<T,X,R,G,B>::Normal( TInt aW, TInt aH, T* aT, TInt aPT,
       
   126                                      const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   127                                      const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   128                                      TInt aFactor )
       
   129     {
       
   130     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   131     for( y= 0; y < aH; y++ )
       
   132         {
       
   133         for( x=0; x < aW; x++ )
       
   134             {
       
   135             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   136 
       
   137             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   138             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   139             r = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   140             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   141             // AlphaBlend red (BoverA)
       
   142             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   143 
       
   144             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   145             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   146             g = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   147             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   148             // AlphaBlend green (BoverA)
       
   149             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   150 
       
   151             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   152             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   153             b = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   154             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   155             // AlphaBlend blue (BoverA)
       
   156             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   157 
       
   158             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   159 
       
   160             aT++; aA++; aMA++; aB++; aMB++;
       
   161             }
       
   162 
       
   163         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   164         }
       
   165     }
       
   166 
       
   167 // -----------------------------------------------------------------------------
       
   168 // AknsRlBlend::Darken
       
   169 // -----------------------------------------------------------------------------
       
   170 //
       
   171 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   172 void AknsRlBlend<T,X,R,G,B>::Darken( TInt aW, TInt aH, T* aT, TInt aPT,
       
   173                                      const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   174                                      const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   175                                      TInt aFactor )
       
   176     {
       
   177     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   178     for( y= 0; y < aH; y++ )
       
   179         {
       
   180         for( x=0; x < aW; x++ )
       
   181             {
       
   182             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   183 
       
   184             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   185             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   186             if( sa < sb )
       
   187                 r = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   188             else
       
   189                 r = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   190             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   191             // AlphaBlend red (BoverA)
       
   192             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   193 
       
   194             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   195             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   196             if( sa < sb )
       
   197                 g = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   198             else
       
   199                 g = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   200             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   201             // AlphaBlend green (BoverA)
       
   202             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   203 
       
   204             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   205             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   206             if( sa < sb )
       
   207                 b = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   208             else
       
   209                 b = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   210             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   211             // AlphaBlend blue (BoverA)
       
   212             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   213 
       
   214             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   215 
       
   216             aT++; aA++; aMA++; aB++; aMB++;
       
   217             }
       
   218 
       
   219         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   220         }
       
   221     }
       
   222 
       
   223 // -----------------------------------------------------------------------------
       
   224 // AknsRlBlend::Lighten
       
   225 // -----------------------------------------------------------------------------
       
   226 //
       
   227 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   228 void AknsRlBlend<T,X,R,G,B>::Lighten( TInt aW, TInt aH, T* aT, TInt aPT,
       
   229                                       const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   230                                       const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   231                                       TInt aFactor )
       
   232     {
       
   233     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   234     for( y= 0; y < aH; y++ )
       
   235         {
       
   236         for( x=0; x < aW; x++ )
       
   237             {
       
   238             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   239 
       
   240             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   241             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   242             if( sa > sb )
       
   243                 r = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   244             else
       
   245                 r = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   246             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   247             // AlphaBlend red (BoverA)
       
   248             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   249 
       
   250             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   251             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   252             if( sa > sb )
       
   253                 g = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   254             else
       
   255                 g = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   256             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   257             // AlphaBlend green (BoverA)
       
   258             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   259 
       
   260             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   261             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   262             if( sa > sb )
       
   263                 b = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   264             else
       
   265                 b = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   266             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   267             // AlphaBlend blue (BoverA)
       
   268             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   269 
       
   270             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   271 
       
   272             aT++; aA++; aMA++; aB++; aMB++;
       
   273             }
       
   274 
       
   275         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   276         }
       
   277     }
       
   278 
       
   279 // -----------------------------------------------------------------------------
       
   280 // AknsRlBlend::Multiply
       
   281 // -----------------------------------------------------------------------------
       
   282 //
       
   283 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   284 void AknsRlBlend<T,X,R,G,B>::Multiply( TInt aW, TInt aH, T* aT, TInt aPT,
       
   285                                        const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   286                                        const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   287                                        TInt aFactor )
       
   288     {
       
   289     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   290     for( y= 0; y < aH; y++ )
       
   291         {
       
   292         for( x=0; x < aW; x++ )
       
   293             {
       
   294             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   295 
       
   296             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   297             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   298             r = ( (( sa * sb ) >> 8) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   299             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   300             // AlphaBlend red (BoverA)
       
   301             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   302 
       
   303             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   304             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   305             g = ( (( sa * sb ) >> 8) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   306             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   307             // AlphaBlend green (BoverA)
       
   308             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   309 
       
   310             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   311             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   312             b = ( (( sa * sb ) >> 8) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   313             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   314             // AlphaBlend blue (BoverA)
       
   315             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   316 
       
   317             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   318 
       
   319             aT++; aA++; aMA++; aB++; aMB++;
       
   320             }
       
   321 
       
   322         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   323         }
       
   324     }
       
   325 
       
   326 // -----------------------------------------------------------------------------
       
   327 // AknsRlBlend::Screen
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   331 void AknsRlBlend<T,X,R,G,B>::Screen( TInt aW, TInt aH, T* aT, TInt aPT,
       
   332                                      const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   333                                      const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   334                                      TInt aFactor )
       
   335     {
       
   336     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   337     for( y= 0; y < aH; y++ )
       
   338         {
       
   339         for( x=0; x < aW; x++ )
       
   340             {
       
   341             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   342 
       
   343             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   344             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   345             r = ( (255 - ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   346             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   347             // AlphaBlend red (BoverA)
       
   348             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   349 
       
   350             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   351             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   352             g = ( (255 - ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   353             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   354             // AlphaBlend green (BoverA)
       
   355             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   356 
       
   357             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   358             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   359             b = ( (255 - ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   360             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   361             // AlphaBlend blue (BoverA)
       
   362             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   363 
       
   364             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   365 
       
   366             aT++; aA++; aMA++; aB++; aMB++;
       
   367             }
       
   368 
       
   369         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   370         }
       
   371     }
       
   372 
       
   373 // -----------------------------------------------------------------------------
       
   374 // AknsRlBlend::Overlay
       
   375 // -----------------------------------------------------------------------------
       
   376 //
       
   377 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   378 void AknsRlBlend<T,X,R,G,B>::Overlay( TInt aW, TInt aH, T* aT, TInt aPT,
       
   379                                       const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   380                                       const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   381                                       TInt aFactor )
       
   382     {
       
   383     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   384     for( y= 0; y < aH; y++ )
       
   385         {
       
   386         for( x=0; x < aW; x++ )
       
   387             {
       
   388             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   389 
       
   390             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   391             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   392             if( sa < 127 )
       
   393                 r = ( (2 * (( sa * sb ) >> 8)) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   394             else
       
   395                 r = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   396             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   397             // AlphaBlend red (BoverA)
       
   398             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   399 
       
   400             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   401             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   402             if( sa < 127 )
       
   403                 g = ( (2 * (( sa * sb ) >> 8)) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   404             else
       
   405                 g = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   406             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   407             // AlphaBlend green (BoverA)
       
   408             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   409 
       
   410             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   411             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   412             if( sa < 127 )
       
   413                 b = ( (2 * (( sa * sb ) >> 8)) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   414             else
       
   415                 b = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   416             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   417             // AlphaBlend blue (BoverA)
       
   418             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   419 
       
   420             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   421 
       
   422             aT++; aA++; aMA++; aB++; aMB++;
       
   423             }
       
   424 
       
   425         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   426         }
       
   427     }
       
   428 
       
   429 // -----------------------------------------------------------------------------
       
   430 // AknsRlBlend::HardLight
       
   431 // -----------------------------------------------------------------------------
       
   432 //
       
   433 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   434 void AknsRlBlend<T,X,R,G,B>::HardLight( TInt aW, TInt aH, T* aT, TInt aPT,
       
   435                                         const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   436                                         const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   437                                         TInt aFactor )
       
   438     {
       
   439     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   440     for( y= 0; y < aH; y++ )
       
   441         {
       
   442         for( x=0; x < aW; x++ )
       
   443             {
       
   444             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   445 
       
   446             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   447             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   448             if( sb < 127 )
       
   449                 r = ( (2 * (( sa * sb ) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   450             else
       
   451                 r = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   452             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   453             // AlphaBlend red (BoverA)
       
   454             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   455 
       
   456             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   457             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   458             if( sb < 127 )
       
   459                 g = ( (2 * (( sa * sb ) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   460             else
       
   461                 g = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   462             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   463             // AlphaBlend green (BoverA)
       
   464             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   465 
       
   466             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   467             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   468             if( sb < 127 )
       
   469                 b = ( (2 * (( sa * sb ) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   470             else
       
   471                 b = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   472             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   473             // AlphaBlend blue (BoverA)
       
   474             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   475 
       
   476             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   477 
       
   478             aT++; aA++; aMA++; aB++; aMB++;
       
   479             }
       
   480 
       
   481         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   482         }
       
   483     }
       
   484 
       
   485 // -----------------------------------------------------------------------------
       
   486 // AknsRlBlend::SoftLight
       
   487 // -----------------------------------------------------------------------------
       
   488 //
       
   489 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   490 void AknsRlBlend<T,X,R,G,B>::SoftLight( TInt aW, TInt aH, T* aT, TInt aPT,
       
   491                                         const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   492                                         const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   493                                         TInt aFactor )
       
   494     {
       
   495     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   496     for( y= 0; y < aH; y++ )
       
   497         {
       
   498         for( x=0; x < aW; x++ )
       
   499             {
       
   500             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   501 
       
   502             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   503             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   504             r = ( (2 * (( sa * sb ) >> 8 ) + (( sa * sa ) >> 8 ) - 2 * (( sa * (( sa * sb ) >> 8 )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   505             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   506             // AlphaBlend red (BoverA)
       
   507             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   508 
       
   509             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   510             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   511             g = ( (2 * (( sa * sb ) >> 8 ) + (( sa * sa ) >> 8 ) - 2 * (( sa * (( sa * sb ) >> 8 )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   512             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   513             // AlphaBlend green (BoverA)
       
   514             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   515 
       
   516             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   517             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   518             b = ( (2 * (( sa * sb ) >> 8 ) + (( sa * sa ) >> 8 ) - 2 * (( sa * (( sa * sb ) >> 8 )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   519             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   520             // AlphaBlend blue (BoverA)
       
   521             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   522 
       
   523             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   524 
       
   525             aT++; aA++; aMA++; aB++; aMB++;
       
   526             }
       
   527 
       
   528         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   529         }
       
   530     }
       
   531 
       
   532 // -----------------------------------------------------------------------------
       
   533 // AknsRlBlend::Difference
       
   534 // -----------------------------------------------------------------------------
       
   535 //
       
   536 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   537 void AknsRlBlend<T,X,R,G,B>::Difference( TInt aW, TInt aH, T* aT, TInt aPT,
       
   538                                          const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   539                                          const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   540                                          TInt aFactor )
       
   541     {
       
   542     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   543     for( y= 0; y < aH; y++ )
       
   544         {
       
   545         for( x=0; x < aW; x++ )
       
   546             {
       
   547             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   548 
       
   549             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   550             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   551             r = ( (sa - sb) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   552             if( r < 0 ) r = -r;
       
   553             if( r > 255 ) r = 255;
       
   554             // AlphaBlend red (BoverA)
       
   555             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   556 
       
   557             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   558             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   559             g = ( (sa - sb) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   560             if( g < 0 ) g = -g;
       
   561             if( g > 255 ) g = 255;
       
   562             // AlphaBlend green (BoverA)
       
   563             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   564 
       
   565             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   566             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   567             b = ( (sa - sb) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   568             if( b < 0 ) b = -b;
       
   569             if( b > 255 ) b = 255;
       
   570             // AlphaBlend blue (BoverA)
       
   571             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   572 
       
   573             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   574 
       
   575             aT++; aA++; aMA++; aB++; aMB++;
       
   576             }
       
   577 
       
   578         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   579         }
       
   580 
       
   581     }
       
   582 
       
   583 // -----------------------------------------------------------------------------
       
   584 // AknsRlBlend::Dodge
       
   585 // -----------------------------------------------------------------------------
       
   586 //
       
   587 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   588 void AknsRlBlend<T,X,R,G,B>::Dodge( TInt aW, TInt aH, T* aT, TInt aPT,
       
   589                                     const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   590                                     const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   591                                     TInt aFactor )
       
   592     {
       
   593     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   594     for( y= 0; y < aH; y++ )
       
   595         {
       
   596         for( x=0; x < aW; x++ )
       
   597             {
       
   598             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   599 
       
   600             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   601             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   602             if( 255 == sb )
       
   603                 r = ( 255 * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   604             else
       
   605                 {
       
   606                 r = ( sa << 8 ) / ( 255 - sb );
       
   607                 if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   608                 r = ( r * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   609                 }
       
   610             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   611             // AlphaBlend red (BoverA)
       
   612             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   613 
       
   614             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   615             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   616             if( 255 == sb )
       
   617                 g = ( 255 * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   618             else
       
   619                 {
       
   620                 g = ( sa << 8 ) / ( 255 - sb );
       
   621                 if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   622                 g = ( g * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   623                 }
       
   624             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   625             // AlphaBlend green (BoverA)
       
   626             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   627 
       
   628             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   629             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   630             if( 255 == sb )
       
   631                 b = ( 255 * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   632             else
       
   633                 {
       
   634                 b = ( sa << 8 ) / ( 255 - sb );
       
   635                 if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   636                 b = ( b * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   637                 }
       
   638             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   639             // AlphaBlend blue (BoverA)
       
   640             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   641 
       
   642             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   643 
       
   644             aT++; aA++; aMA++; aB++; aMB++;
       
   645             }
       
   646 
       
   647         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   648         }
       
   649     }
       
   650 
       
   651 // -----------------------------------------------------------------------------
       
   652 // AknsRlBlend::Burn
       
   653 // -----------------------------------------------------------------------------
       
   654 //
       
   655 template <class T, TInt X, TInt R, TInt G, TInt B>
       
   656 void AknsRlBlend<T,X,R,G,B>::Burn( TInt aW, TInt aH, T* aT, TInt aPT,
       
   657                                    const T* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   658                                    const T* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   659                                    TInt aFactor )
       
   660     {
       
   661     TInt x, y, r, g, b, sa, sb, ma, mb, ca, cb;
       
   662     for( y= 0; y < aH; y++ )
       
   663         {
       
   664         for( x=0; x < aW; x++ )
       
   665             {
       
   666             ma = *aMA; mb = *aMB; ca = *aA; cb = *aB;
       
   667 
       
   668             sa = (ma * AknsRlRgb<T,X,R,G,B>::R8(ca)) >> 8;
       
   669             sb = (mb * AknsRlRgb<T,X,R,G,B>::R8(cb)) >> 8;
       
   670             if( 0 == sb )
       
   671                 r = 0; // This makes burn work as in Paint Shop Pro
       
   672             else
       
   673                 {
       
   674                 r = 255 - ((( 255 - sa ) << 8 ) / sb );
       
   675                 if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   676                 r = ( r * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   677                 }
       
   678             if( r < 0 ) r = 0; else if( r > 255 ) r = 255;
       
   679             // AlphaBlend red (BoverA)
       
   680             r = ((mb * r)>>8) + ((sa * (255 - mb)) >> 8);
       
   681 
       
   682             sa = (ma * AknsRlRgb<T,X,R,G,B>::G8(ca)) >> 8;
       
   683             sb = (mb * AknsRlRgb<T,X,R,G,B>::G8(cb)) >> 8;
       
   684             if( 0 == sb )
       
   685                 g = 0; // This makes burn work as in Paint Shop Pro
       
   686             else
       
   687                 {
       
   688                 g = 255 - ((( 255 - sa ) << 8 ) / sb );
       
   689                 if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   690                 g = ( g * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   691                 }
       
   692             if( g < 0 ) g = 0; else if( g > 255 ) g = 255;
       
   693             // AlphaBlend green (BoverA)
       
   694             g = ((mb * g)>>8) + ((sa * (255 - mb)) >> 8);
       
   695 
       
   696             sa = (ma * AknsRlRgb<T,X,R,G,B>::B8(ca)) >> 8;
       
   697             sb = (mb * AknsRlRgb<T,X,R,G,B>::B8(cb)) >> 8;
       
   698             if( 0 == sb )
       
   699                 b = 0; // This makes burn work as in Paint Shop Pro
       
   700             else
       
   701                 {
       
   702                 b = 255 - ((( 255 - sa ) << 8 ) / sb );
       
   703                 if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   704                 b = ( b * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   705                 }
       
   706             if( b < 0 ) b = 0; else if( b > 255 ) b = 255;
       
   707             // AlphaBlend blue (BoverA)
       
   708             b = ((mb * b)>>8) + ((sa * (255 - mb)) >> 8);
       
   709 
       
   710             AknsRlRgb<T,X,R,G,B>::SetRgb8( aT, r, g, b );
       
   711 
       
   712             aT++; aA++; aMA++; aB++; aMB++;
       
   713             }
       
   714 
       
   715         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   716         }
       
   717     }
       
   718 
       
   719 // ==================== GRAYSCALE IMPL. OF CHANNEL BLEND =======================
       
   720 /**
       
   721 * See RGB implementation above for comments.
       
   722 */
       
   723 NONSHARABLE_CLASS(AknsRlBlendGray)
       
   724     {
       
   725     public:
       
   726     static void Normal( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   727                         const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   728                         const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   729                         TInt aFactor );
       
   730 
       
   731     static void Darken( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   732                         const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   733                         const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   734                         TInt aFactor );
       
   735 
       
   736     static void Lighten( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   737                          const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   738                          const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   739                          TInt aFactor );
       
   740 
       
   741     static void Multiply( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   742                           const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   743                           const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   744                           TInt aFactor );
       
   745 
       
   746     static void Screen( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   747                         const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   748                         const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   749                         TInt aFactor );
       
   750 
       
   751     static void Overlay( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   752                          const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   753                          const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   754                          TInt aFactor );
       
   755 
       
   756     static void HardLight( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   757                            const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   758                            const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   759                            TInt aFactor );
       
   760 
       
   761     static void SoftLight( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   762                            const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   763                            const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   764                            TInt aFactor );
       
   765 
       
   766     static void Difference( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   767                             const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   768                             const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   769                             TInt aFactor );
       
   770 
       
   771     static void Dodge( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   772                        const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   773                        const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   774                        TInt aFactor );
       
   775 
       
   776     static void Burn( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   777                       const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   778                       const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   779                       TInt aFactor );
       
   780     };
       
   781 
       
   782 // -----------------------------------------------------------------------------
       
   783 // AknsRlBlendGray::Normal
       
   784 // -----------------------------------------------------------------------------
       
   785 //
       
   786 void AknsRlBlendGray::Normal( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   787                               const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   788                               const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   789                               TInt aFactor )
       
   790     {
       
   791     /*lint -save -e702 */ // Arithmetic shifting assumed
       
   792     TInt x, y, s, sa, sb, ma, mb;
       
   793     for( y= 0; y < aH; y++ )
       
   794         {
       
   795         for( x=0; x < aW; x++ )
       
   796             {
       
   797             ma = *aMA; mb = *aMB;
       
   798 
       
   799             sa = (ma * (*aA)) >> 8;
       
   800             sb = (mb * (*aB)) >> 8;
       
   801             s = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   802             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
   803             // AlphaBlend shade (BoverA)
       
   804             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
   805 
       
   806             aT++; aA++; aMA++; aB++; aMB++;
       
   807             }
       
   808 
       
   809         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   810         }
       
   811     /*lint -restore */
       
   812     }
       
   813 
       
   814 // -----------------------------------------------------------------------------
       
   815 // AknsRlBlendGray::Darken
       
   816 // -----------------------------------------------------------------------------
       
   817 //
       
   818 void AknsRlBlendGray::Darken( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   819                               const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   820                               const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   821                               TInt aFactor )
       
   822     {
       
   823     /*lint -save -e702 */ // Arithmetic shifting assumed
       
   824     TInt x, y, s, sa, sb, ma, mb;
       
   825     for( y= 0; y < aH; y++ )
       
   826         {
       
   827         for( x=0; x < aW; x++ )
       
   828             {
       
   829             ma = *aMA; mb = *aMB;
       
   830 
       
   831             sa = (ma * (*aA)) >> 8;
       
   832             sb = (mb * (*aB)) >> 8;
       
   833             if( sa < sb )
       
   834                 s = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   835             else
       
   836                 s = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   837             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
   838             // AlphaBlend shade (BoverA)
       
   839             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
   840 
       
   841             aT++; aA++; aMA++; aB++; aMB++;
       
   842             }
       
   843 
       
   844         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   845         }
       
   846     /*lint -restore */
       
   847     }
       
   848 
       
   849 // -----------------------------------------------------------------------------
       
   850 // AknsRlBlendGray::Lighten
       
   851 // -----------------------------------------------------------------------------
       
   852 //
       
   853 void AknsRlBlendGray::Lighten( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   854                                const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   855                                const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   856                                TInt aFactor )
       
   857     {
       
   858     /*lint -save -e702 */ // Arithmetic shifting assumed
       
   859     TInt x, y, s, sa, sb, ma, mb;
       
   860     for( y= 0; y < aH; y++ )
       
   861         {
       
   862         for( x=0; x < aW; x++ )
       
   863             {
       
   864             ma = *aMA; mb = *aMB;
       
   865 
       
   866             sa = (ma * (*aA)) >> 8;
       
   867             sb = (mb * (*aB)) >> 8;
       
   868             if( sa > sb )
       
   869                 s = ( sa * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   870             else
       
   871                 s = ( sb * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   872             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
   873             // AlphaBlend shade (BoverA)
       
   874             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
   875 
       
   876             aT++; aA++; aMA++; aB++; aMB++;
       
   877             }
       
   878 
       
   879         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   880         }
       
   881     /*lint -restore */
       
   882     }
       
   883 
       
   884 // -----------------------------------------------------------------------------
       
   885 // AknsRlBlendGray::Multiply
       
   886 // -----------------------------------------------------------------------------
       
   887 //
       
   888 void AknsRlBlendGray::Multiply( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   889                                 const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   890                                 const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   891                                 TInt aFactor )
       
   892     {
       
   893     /*lint -save -e702 */ // Arithmetic shifting assumed
       
   894     TInt x, y, s, sa, sb, ma, mb;
       
   895     for( y= 0; y < aH; y++ )
       
   896         {
       
   897         for( x=0; x < aW; x++ )
       
   898             {
       
   899             ma = *aMA; mb = *aMB;
       
   900 
       
   901             sa = (ma * (*aA)) >> 8;
       
   902             sb = (mb * (*aB)) >> 8;
       
   903             s = ( (( sa * sb ) >> 8) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   904             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
   905             // AlphaBlend shade (BoverA)
       
   906             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
   907 
       
   908             aT++; aA++; aMA++; aB++; aMB++;
       
   909             }
       
   910 
       
   911         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   912         }
       
   913     /*lint -restore */
       
   914     }
       
   915 
       
   916 // -----------------------------------------------------------------------------
       
   917 // AknsRlBlendGray::Screen
       
   918 // -----------------------------------------------------------------------------
       
   919 //
       
   920 void AknsRlBlendGray::Screen( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   921                               const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   922                               const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   923                               TInt aFactor )
       
   924     {
       
   925     /*lint -save -e702 */ // Arithmetic shifting assumed
       
   926     TInt x, y, s, sa, sb, ma, mb;
       
   927     for( y= 0; y < aH; y++ )
       
   928         {
       
   929         for( x=0; x < aW; x++ )
       
   930             {
       
   931             ma = *aMA; mb = *aMB;
       
   932 
       
   933             sa = (ma * (*aA)) >> 8;
       
   934             sb = (mb * (*aB)) >> 8;
       
   935             s = ( (255 - ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   936             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
   937             // AlphaBlend shade (BoverA)
       
   938             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
   939 
       
   940             aT++; aA++; aMA++; aB++; aMB++;
       
   941             }
       
   942 
       
   943         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   944         }
       
   945     /*lint -restore */
       
   946     }
       
   947 
       
   948 // -----------------------------------------------------------------------------
       
   949 // AknsRlBlendGray::Overlay
       
   950 // -----------------------------------------------------------------------------
       
   951 //
       
   952 void AknsRlBlendGray::Overlay( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   953                                const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   954                                const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   955                                TInt aFactor )
       
   956     {
       
   957     /*lint -save -e702 */ // Arithmetic shifting assumed
       
   958     TInt x, y, s, sa, sb, ma, mb;
       
   959     for( y= 0; y < aH; y++ )
       
   960         {
       
   961         for( x=0; x < aW; x++ )
       
   962             {
       
   963             ma = *aMA; mb = *aMB;
       
   964 
       
   965             sa = (ma * (*aA)) >> 8;
       
   966             sb = (mb * (*aB)) >> 8;
       
   967             if( sa < 127 )
       
   968                 s = ( (2 * (( sa * sb ) >> 8)) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   969             else
       
   970                 s = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
   971             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
   972             // AlphaBlend shade (BoverA)
       
   973             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
   974 
       
   975             aT++; aA++; aMA++; aB++; aMB++;
       
   976             }
       
   977 
       
   978         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
   979         }
       
   980     /*lint -restore */
       
   981     }
       
   982 
       
   983 // -----------------------------------------------------------------------------
       
   984 // AknsRlBlendGray::HardLight
       
   985 // -----------------------------------------------------------------------------
       
   986 //
       
   987 void AknsRlBlendGray::HardLight( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
   988                                  const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
   989                                  const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
   990                                  TInt aFactor )
       
   991     {
       
   992     /*lint -save -e702 */ // Arithmetic shifting assumed
       
   993     TInt x, y, s, sa, sb, ma, mb;
       
   994     for( y= 0; y < aH; y++ )
       
   995         {
       
   996         for( x=0; x < aW; x++ )
       
   997             {
       
   998             ma = *aMA; mb = *aMB;
       
   999 
       
  1000             sa = (ma * (*aA)) >> 8;
       
  1001             sb = (mb * (*aB)) >> 8;
       
  1002             if( sb < 127 )
       
  1003                 s = ( (2 * (( sa * sb ) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
  1004             else
       
  1005                 s = ( (255 - 2 * ((( 255 - sa ) * ( 255 - sb )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
  1006             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
  1007             // AlphaBlend shade (BoverA)
       
  1008             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
  1009 
       
  1010             aT++; aA++; aMA++; aB++; aMB++;
       
  1011             }
       
  1012 
       
  1013         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
  1014         }
       
  1015     /*lint -restore */
       
  1016     }
       
  1017 
       
  1018 // -----------------------------------------------------------------------------
       
  1019 // AknsRlBlendGray::SoftLight
       
  1020 // -----------------------------------------------------------------------------
       
  1021 //
       
  1022 void AknsRlBlendGray::SoftLight( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
  1023                                  const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
  1024                                  const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
  1025                                  TInt aFactor )
       
  1026     {
       
  1027     /*lint -save -e702 */ // Arithmetic shifting assumed
       
  1028     TInt x, y, s, sa, sb, ma, mb;
       
  1029     for( y= 0; y < aH; y++ )
       
  1030         {
       
  1031         for( x=0; x < aW; x++ )
       
  1032             {
       
  1033             ma = *aMA; mb = *aMB;
       
  1034 
       
  1035             sa = (ma * (*aA)) >> 8;
       
  1036             sb = (mb * (*aB)) >> 8;
       
  1037             s = ( (2 * (( sa * sb ) >> 8 ) + (( sa * sa ) >> 8 ) - 2 * (( sa * (( sa * sb ) >> 8 )) >> 8 )) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
  1038             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
  1039             // AlphaBlend shade (BoverA)
       
  1040             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
  1041 
       
  1042             aT++; aA++; aMA++; aB++; aMB++;
       
  1043             }
       
  1044 
       
  1045         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
  1046         }
       
  1047     /*lint -restore */
       
  1048     }
       
  1049 
       
  1050 // -----------------------------------------------------------------------------
       
  1051 // AknsRlBlendGray::Difference
       
  1052 // -----------------------------------------------------------------------------
       
  1053 //
       
  1054 void AknsRlBlendGray::Difference( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
  1055                                   const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
  1056                                   const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
  1057                                   TInt aFactor )
       
  1058     {
       
  1059     /*lint -save -e702 */ // Arithmetic shifting assumed
       
  1060     TInt x, y, s, sa, sb, ma, mb;
       
  1061     for( y= 0; y < aH; y++ )
       
  1062         {
       
  1063         for( x=0; x < aW; x++ )
       
  1064             {
       
  1065             ma = *aMA; mb = *aMB;
       
  1066 
       
  1067             sa = (ma * (*aA)) >> 8;
       
  1068             sb = (mb * (*aB)) >> 8;
       
  1069             s = ( (sa - sb) * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
  1070             if( s < 0 ) s = -s;
       
  1071             if( s > 255 ) s = 255;
       
  1072             // AlphaBlend shade (BoverA)
       
  1073             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
  1074 
       
  1075             aT++; aA++; aMA++; aB++; aMB++;
       
  1076             }
       
  1077 
       
  1078         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
  1079         }
       
  1080     /*lint -restore */
       
  1081     }
       
  1082 
       
  1083 // -----------------------------------------------------------------------------
       
  1084 // AknsRlBlendGray::Dodge
       
  1085 // -----------------------------------------------------------------------------
       
  1086 //
       
  1087 void AknsRlBlendGray::Dodge( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
  1088                              const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
  1089                              const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
  1090                              TInt aFactor )
       
  1091     {
       
  1092     /*lint -save -e702 */ // Arithmetic shifting assumed
       
  1093     TInt x, y, s, sa, sb, ma, mb;
       
  1094     for( y= 0; y < aH; y++ )
       
  1095         {
       
  1096         for( x=0; x < aW; x++ )
       
  1097             {
       
  1098             ma = *aMA; mb = *aMB;
       
  1099 
       
  1100             sa = (ma * (*aA)) >> 8;
       
  1101             sb = (mb * (*aB)) >> 8;
       
  1102             if( 255 == sb )
       
  1103                 s = ( 255 * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
  1104             else
       
  1105                 {
       
  1106                 s = ( sa << 8 ) / ( 255 - sb );
       
  1107                 if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
  1108                 s = ( s * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
  1109                 }
       
  1110             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
  1111             // AlphaBlend shade (BoverA)
       
  1112             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
  1113 
       
  1114             aT++; aA++; aMA++; aB++; aMB++;
       
  1115             }
       
  1116 
       
  1117         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
  1118         }
       
  1119     /*lint -restore */
       
  1120     }
       
  1121 
       
  1122 // -----------------------------------------------------------------------------
       
  1123 // AknsRlBlendGray::Burn
       
  1124 // -----------------------------------------------------------------------------
       
  1125 //
       
  1126 void AknsRlBlendGray::Burn( TInt aW, TInt aH, TUint8* aT, TInt aPT,
       
  1127                             const TUint8* aA, TInt aPA, const TUint8* aMA, TInt aPMA,
       
  1128                             const TUint8* aB, TInt aPB, const TUint8* aMB, TInt aPMB,
       
  1129                             TInt aFactor )
       
  1130     {
       
  1131     /*lint -save -e702 */ // Arithmetic shifting assumed
       
  1132     TInt x, y, s, sa, sb, ma, mb;
       
  1133     for( y= 0; y < aH; y++ )
       
  1134         {
       
  1135         for( x=0; x < aW; x++ )
       
  1136             {
       
  1137             ma = *aMA; mb = *aMB;
       
  1138 
       
  1139             sa = (ma * (*aA)) >> 8;
       
  1140             sb = (mb * (*aB)) >> 8;
       
  1141             if( 0 == sb )
       
  1142                 s = 0; // This makes burn work as in Paint Shop Pro
       
  1143             else
       
  1144                 {
       
  1145                 s = 255 - ((( 255 - sa ) << 8 ) / sb );
       
  1146                 if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
  1147                 s = ( s * aFactor + ( 255 - aFactor ) * sa ) >> 8;
       
  1148                 }
       
  1149             if( s < 0 ) s = 0; else if( s > 255 ) s = 255;
       
  1150             // AlphaBlend shade (BoverA)
       
  1151             *aT = ((mb * s)>>8) + ((sa * (255 - mb)) >> 8);
       
  1152 
       
  1153             aT++; aA++; aMA++; aB++; aMB++;
       
  1154             }
       
  1155 
       
  1156         aT += aPT; aA += aPA; aMA += aPMA; aB += aPB; aMB += aPMB;
       
  1157         }
       
  1158     /*lint -restore */
       
  1159     }
       
  1160 
       
  1161 // ============================ MEMBER FUNCTIONS ===============================
       
  1162 
       
  1163 // -----------------------------------------------------------------------------
       
  1164 // CAknsRlEffectPluginChannelBlend::CAknsRlEffectPluginChannelBlend
       
  1165 // C++ default constructor can NOT contain any code, that
       
  1166 // might leave.
       
  1167 // -----------------------------------------------------------------------------
       
  1168 //
       
  1169 CAknsRlEffectPluginChannelBlend::CAknsRlEffectPluginChannelBlend()
       
  1170     {
       
  1171     }
       
  1172 
       
  1173 // -----------------------------------------------------------------------------
       
  1174 // Destructor
       
  1175 // -----------------------------------------------------------------------------
       
  1176 //
       
  1177 CAknsRlEffectPluginChannelBlend::~CAknsRlEffectPluginChannelBlend()
       
  1178     {
       
  1179     iContext = NULL; // Removes lint nag
       
  1180     delete iScans; //lint !e1551 No exception thrown
       
  1181     }
       
  1182 
       
  1183 // -----------------------------------------------------------------------------
       
  1184 // CAknsRlEffectPluginChannelBlend::EffectUid
       
  1185 // -----------------------------------------------------------------------------
       
  1186 //
       
  1187 TUid CAknsRlEffectPluginChannelBlend::EffectUid() const
       
  1188     {
       
  1189     return TUid::Uid( KAknsRlEffectPluginChannelBlendUID );
       
  1190     }
       
  1191 
       
  1192 // -----------------------------------------------------------------------------
       
  1193 // CAknsRlEffectPluginChannelBlend::Effect
       
  1194 // -----------------------------------------------------------------------------
       
  1195 //
       
  1196 MAknsRlEffect* CAknsRlEffectPluginChannelBlend::Effect( const TInt aInterface )
       
  1197     {
       
  1198     if( aInterface == KAknsRlEffectPluginInterfaceEffect )
       
  1199         return this;
       
  1200     return NULL;
       
  1201     }
       
  1202 
       
  1203 // -----------------------------------------------------------------------------
       
  1204 // CAknsRlEffectPluginChannelBlend::InitializeL
       
  1205 // -----------------------------------------------------------------------------
       
  1206 //
       
  1207 void CAknsRlEffectPluginChannelBlend::InitializeL()
       
  1208     {
       
  1209     delete iScans;
       
  1210     iScans = NULL;
       
  1211 
       
  1212     iScans = CAknsRlScanlines::NewL();
       
  1213     }
       
  1214 
       
  1215 // -----------------------------------------------------------------------------
       
  1216 // CAknsRlEffectPluginChannelBlend::Release
       
  1217 // -----------------------------------------------------------------------------
       
  1218 //
       
  1219 void CAknsRlEffectPluginChannelBlend::Release()
       
  1220     {
       
  1221     }
       
  1222 
       
  1223 // -----------------------------------------------------------------------------
       
  1224 // CAknsRlEffectPluginChannelBlend::ActivateL
       
  1225 // -----------------------------------------------------------------------------
       
  1226 //
       
  1227 void CAknsRlEffectPluginChannelBlend::ActivateL( MAknsRlEffectContext* aContext )
       
  1228     {
       
  1229     if( !aContext ) // We absolutely need the context
       
  1230         {
       
  1231         User::Leave( KErrArgument );
       
  1232         }
       
  1233 
       
  1234     iContext = aContext;
       
  1235     iBlendMode = EAknsRlChannelBlendNormal;
       
  1236     iBlendFactor = 255;
       
  1237     iFlags = 0;
       
  1238 
       
  1239     iARed   = 255;
       
  1240     iAGreen = 255;
       
  1241     iABlue  = 255;
       
  1242 
       
  1243     iBRed   = 255;
       
  1244     iBGreen = 255;
       
  1245     iBBlue  = 255;
       
  1246 
       
  1247     iAMask  = 255;
       
  1248     iBMask  = 255;
       
  1249     }
       
  1250 
       
  1251 // -----------------------------------------------------------------------------
       
  1252 // CAknsRlEffectPluginChannelBlend::Deactivate
       
  1253 // -----------------------------------------------------------------------------
       
  1254 //
       
  1255 void CAknsRlEffectPluginChannelBlend::Deactivate()
       
  1256     {
       
  1257     }
       
  1258 
       
  1259 // -----------------------------------------------------------------------------
       
  1260 // CAknsRlEffectPluginChannelBlend::SetParametersL
       
  1261 // -----------------------------------------------------------------------------
       
  1262 //
       
  1263 void CAknsRlEffectPluginChannelBlend::SetParametersL( MAknsRlParameterIterator& aParameters )
       
  1264     {
       
  1265     // Iterate over available parameters
       
  1266     while( aParameters.HasNext() )
       
  1267         {
       
  1268         const TAknsRlParameterData* param = aParameters.NextL();
       
  1269 
       
  1270         // Fetch blend mode value
       
  1271         if( param->iName->Compare( KAknsRlEffectChannelBlendMode ) == 0 )
       
  1272             {
       
  1273             if( param->iType != EAknsRlParameterTypeNumber )
       
  1274                 User::Leave( KErrArgument );
       
  1275 
       
  1276             if( param->iNumber < EAknsRlChannelBlendNormal ||
       
  1277                 param->iNumber > EAknsRlChannelBlendBurn )
       
  1278                 User::Leave( KErrArgument );
       
  1279 
       
  1280             iBlendMode = param->iNumber;
       
  1281             }
       
  1282         // Fetch blend factor value
       
  1283         else if( param->iName->Compare( KAknsRlEffectChannelBlendBlendFactor ) == 0 )
       
  1284             {
       
  1285             if( param->iType != EAknsRlParameterTypeNumber )
       
  1286                 User::Leave( KErrArgument );
       
  1287 
       
  1288             iBlendFactor = param->iNumber;
       
  1289             }
       
  1290         // Fetch Color A constant values
       
  1291         else if( param->iName->Compare( KAknsRlEffectChannelBlendARed ) == 0 )
       
  1292             {
       
  1293             if( param->iType != EAknsRlParameterTypeNumber )
       
  1294                 User::Leave( KErrArgument );
       
  1295 
       
  1296             iFlags = TUint8( iFlags | EConstantAColor );
       
  1297             iARed = TUint8( param->iNumber );
       
  1298             }
       
  1299         else if( param->iName->Compare( KAknsRlEffectChannelBlendAGreen ) == 0 )
       
  1300             {
       
  1301             if( param->iType != EAknsRlParameterTypeNumber )
       
  1302                 User::Leave( KErrArgument );
       
  1303 
       
  1304             iFlags = TUint8( iFlags | EConstantAColor );
       
  1305             iAGreen = TUint8( param->iNumber );
       
  1306             }
       
  1307         else if( param->iName->Compare( KAknsRlEffectChannelBlendABlue ) == 0 )
       
  1308             {
       
  1309             if( param->iType != EAknsRlParameterTypeNumber )
       
  1310                 User::Leave( KErrArgument );
       
  1311 
       
  1312             iFlags = TUint8( iFlags | EConstantAColor );
       
  1313             iABlue = TUint8( param->iNumber );
       
  1314             }
       
  1315         // Fetch Color B constant values
       
  1316         else if( param->iName->Compare( KAknsRlEffectChannelBlendBRed ) == 0 )
       
  1317             {
       
  1318             if( param->iType != EAknsRlParameterTypeNumber )
       
  1319                 User::Leave( KErrArgument );
       
  1320 
       
  1321             iFlags = TUint8( iFlags | EConstantBColor );
       
  1322             iBRed = TUint8( param->iNumber );
       
  1323             }
       
  1324         else if( param->iName->Compare( KAknsRlEffectChannelBlendBGreen ) == 0 )
       
  1325             {
       
  1326             if( param->iType != EAknsRlParameterTypeNumber )
       
  1327                 User::Leave( KErrArgument );
       
  1328 
       
  1329             iFlags = TUint8( iFlags | EConstantBColor );
       
  1330             iBGreen = TUint8( param->iNumber );
       
  1331             }
       
  1332         else if( param->iName->Compare( KAknsRlEffectChannelBlendBBlue ) == 0 )
       
  1333             {
       
  1334             if( param->iType != EAknsRlParameterTypeNumber )
       
  1335                 User::Leave( KErrArgument );
       
  1336 
       
  1337             iFlags = TUint8( iFlags | EConstantBColor );
       
  1338             iBBlue = TUint8( param->iNumber );
       
  1339             }
       
  1340         // Fetch Mask A constant value
       
  1341         else if( param->iName->Compare( KAknsRlEffectChannelBlendAMask ) == 0 )
       
  1342             {
       
  1343             if( param->iType != EAknsRlParameterTypeNumber )
       
  1344                 User::Leave( KErrArgument );
       
  1345 
       
  1346             iFlags = TUint8( iFlags | EConstantAMask );
       
  1347             iAMask = TUint8( param->iNumber );
       
  1348             }
       
  1349         // Fetch Mask B constant value
       
  1350         else if( param->iName->Compare( KAknsRlEffectChannelBlendBMask ) == 0 )
       
  1351             {
       
  1352             if( param->iType != EAknsRlParameterTypeNumber )
       
  1353                 User::Leave( KErrArgument );
       
  1354 
       
  1355             iFlags = TUint8( iFlags | EConstantBMask );
       
  1356             iBMask = TUint8( param->iNumber );
       
  1357             }
       
  1358         }
       
  1359     }
       
  1360 
       
  1361 // -----------------------------------------------------------------------------
       
  1362 // CAknsRlEffectPluginChannelBlend::GetCapabilities
       
  1363 // -----------------------------------------------------------------------------
       
  1364 //
       
  1365 void CAknsRlEffectPluginChannelBlend::GetCapabilities( TAknsRlEffectCaps& aCaps )
       
  1366     {
       
  1367     // In all cases we can handle RGBOnly and RGBA output layers (alpha is
       
  1368     // simply cleared to white if it exists).
       
  1369     aCaps.iOutputLayerSupport = KAknsRlLayerRGBOnly | KAknsRlLayerRGBA;
       
  1370 
       
  1371     // In all cases we can handle RGBA and RGBOnly input layers.
       
  1372     aCaps.iInputLayerASupport = KAknsRlLayerRGBA | KAknsRlLayerRGBOnly;
       
  1373     aCaps.iInputLayerBSupport = KAknsRlLayerRGBA | KAknsRlLayerRGBOnly;
       
  1374 
       
  1375     // If both mask and color are constant we can handle None as input layer
       
  1376     if( (iFlags & EConstantAMask) && (iFlags & EConstantAColor) )
       
  1377         aCaps.iInputLayerASupport = aCaps.iInputLayerASupport | KAknsRlLayerNone;
       
  1378 
       
  1379     if( (iFlags & EConstantBMask) && (iFlags & EConstantBColor) )
       
  1380         aCaps.iInputLayerBSupport = aCaps.iInputLayerBSupport | KAknsRlLayerNone;
       
  1381     }
       
  1382 
       
  1383 // -----------------------------------------------------------------------------
       
  1384 // CAknsRlEffectPluginChannelBlend::Render
       
  1385 // -----------------------------------------------------------------------------
       
  1386 //
       
  1387 TInt CAknsRlEffectPluginChannelBlend::Render(
       
  1388         const TAknsRlRenderOpParam& aParam )
       
  1389     {
       
  1390     TRAPD( err, DoRenderL( aParam ) );
       
  1391     return err;
       
  1392     }
       
  1393 
       
  1394 // -----------------------------------------------------------------------------
       
  1395 // CAknsRlEffectPluginChannelBlend::DoRenderL
       
  1396 // -----------------------------------------------------------------------------
       
  1397 //
       
  1398 void CAknsRlEffectPluginChannelBlend::DoRenderL(
       
  1399         const TAknsRlRenderOpParam& aParam )
       
  1400     {
       
  1401     if( !iContext ) // We absolutely need the context
       
  1402         {
       
  1403         User::Leave( KErrBadHandle );
       
  1404         }
       
  1405 
       
  1406     //---------------------------------
       
  1407     // Step 1: Prepare layer query
       
  1408 
       
  1409     // We need to process alpha if mask constant is set or if both input
       
  1410     // layers have the alpha status set.
       
  1411     TBool useAlpha = EFalse;
       
  1412     if( ( iFlags & EConstantAMask ) || ( iFlags & EConstantBMask ) ||
       
  1413         ( ( aParam.iInputLayerAStatus & KAknsRlLayerRGBA ) &&
       
  1414           ( aParam.iInputLayerBStatus & KAknsRlLayerRGBA ) ) )
       
  1415         {
       
  1416         useAlpha = ETrue;
       
  1417         }
       
  1418 
       
  1419     // In some cases we need not to query layer A or B
       
  1420     TBool queryA = EFalse;
       
  1421     TBool queryB = EFalse;
       
  1422 
       
  1423     // If constants are not defined we need to query both A and B
       
  1424     if( 0 == iFlags )
       
  1425         {
       
  1426         queryA = ETrue;
       
  1427         queryB = ETrue;
       
  1428         }
       
  1429     else // Constant flags were defined, queries may depend on constants
       
  1430         {
       
  1431         // No need to query A if only constant color is used or color and
       
  1432         // mask are both constants.
       
  1433         if( ( ( iFlags & EConstantAColor ) && !useAlpha ) ||
       
  1434             ( ( iFlags & EConstantAColor ) && ( iFlags & EConstantAMask ) ) )
       
  1435             queryA = EFalse;
       
  1436         else
       
  1437             queryA = ETrue;
       
  1438 
       
  1439         // No need to query B if only constant color is used or color and
       
  1440         // mask are both constants.
       
  1441         if( ( ( iFlags & EConstantBColor ) && !useAlpha ) ||
       
  1442             ( ( iFlags & EConstantBColor ) && ( iFlags & EConstantBMask ) ) )
       
  1443             queryB = EFalse;
       
  1444         else
       
  1445             queryB = ETrue;
       
  1446         }
       
  1447 
       
  1448     //---------------------------------
       
  1449     // Step 2: Do layer query
       
  1450 
       
  1451     TAknsRlLayerData dataT;
       
  1452     TAknsRlLayerData dataA;
       
  1453     TAknsRlLayerData dataB;
       
  1454 
       
  1455     TDisplayMode modeT = ENone;
       
  1456     TDisplayMode modeA = ENone;
       
  1457     TDisplayMode modeB = ENone;
       
  1458 
       
  1459     // We need to query the output layer in any case
       
  1460     if( !( ( aParam.iOutputLayerStatus & KAknsRlLayerRGBOnly ) ||
       
  1461            ( aParam.iOutputLayerStatus & KAknsRlLayerRGBA ) ) )
       
  1462         User::Leave( KErrArgument ); // The output must be some sort of RGB layer
       
  1463 
       
  1464     iContext->GetLayerDataL( dataT, aParam.iOutputLayerIndex,
       
  1465                              aParam.iOutputLayerStatus, EFalse );
       
  1466 
       
  1467     if( !dataT.iRGBBitmap ) // The target bitmap must exist
       
  1468         User::Leave( KErrBadHandle );
       
  1469 
       
  1470     modeT = dataT.iRGBBitmap->DisplayMode();
       
  1471 
       
  1472     // Check for non-supported display modes
       
  1473     if( modeT != EColor64K && modeT != EColor16MU && modeT != EGray256 )
       
  1474         User::Leave( KErrArgument );
       
  1475 
       
  1476     // Query layer A
       
  1477     if( queryA )
       
  1478         {
       
  1479         iContext->GetLayerDataL( dataA, aParam.iInputLayerAIndex,
       
  1480                                  aParam.iInputLayerAStatus, EFalse );
       
  1481 
       
  1482         // If we don't use constant color A check that the bitmap is ok
       
  1483         if( !( iFlags & EConstantAColor ) )
       
  1484             {
       
  1485             if( !dataA.iRGBBitmap ) // We need the bitmap A
       
  1486                 User::Leave( KErrBadHandle );
       
  1487 
       
  1488             modeA = dataA.iRGBBitmap->DisplayMode();
       
  1489 
       
  1490             if( modeT != modeA ) // Display mode must match target
       
  1491                 User::Leave( KErrArgument );
       
  1492             }
       
  1493         }
       
  1494 
       
  1495     // Query layer B
       
  1496     if( queryB )
       
  1497         {
       
  1498         iContext->GetLayerDataL( dataB, aParam.iInputLayerBIndex,
       
  1499                                  aParam.iInputLayerBStatus, EFalse );
       
  1500 
       
  1501         // If we don't use constant color B check that the bitmap is ok
       
  1502         if( !( iFlags & EConstantBColor ) )
       
  1503             {
       
  1504             if( !dataB.iRGBBitmap ) // We need the bitmap B
       
  1505                 User::Leave( KErrBadHandle );
       
  1506 
       
  1507             modeB = dataB.iRGBBitmap->DisplayMode();
       
  1508 
       
  1509             if( modeT != modeB ) // Display mode must match target
       
  1510                 User::Leave( KErrArgument );
       
  1511             }
       
  1512         }
       
  1513 
       
  1514     // We have queried the layers, check that alpha bitmaps are ok (if needed)
       
  1515     if( useAlpha && !( iFlags & EConstantAMask ) )
       
  1516         {
       
  1517         if( !dataA.iAlphaBitmap ) // We need the mask A bitmap
       
  1518             User::Leave( KErrBadHandle );
       
  1519 
       
  1520         if( EGray256 != dataA.iAlphaBitmap->DisplayMode() )
       
  1521             User::Leave( KErrArgument );
       
  1522         }
       
  1523 
       
  1524     if( useAlpha && !( iFlags & EConstantBMask ) )
       
  1525         {
       
  1526         if( !dataB.iAlphaBitmap ) // We need the mask B bitmap
       
  1527             User::Leave( KErrBadHandle );
       
  1528 
       
  1529         if( EGray256 != dataB.iAlphaBitmap->DisplayMode() )
       
  1530             User::Leave( KErrArgument );
       
  1531         }
       
  1532 
       
  1533     // If we got this far:
       
  1534     // 1. We know if alpha/masks should be processed
       
  1535     // 2. We know used display mode, same on all layers
       
  1536     // 3. Relevant layers have been queried and are ready to be used
       
  1537     // 4. Alpha bitmaps are ok (if needed)
       
  1538 
       
  1539     // Clear the target alpha if it exists
       
  1540     if( useAlpha && dataT.iAlphaGc )
       
  1541         {
       
  1542         dataT.iAlphaGc->SetBrushColor( KRgbWhite );
       
  1543         dataT.iAlphaGc->Clear();
       
  1544         }
       
  1545 
       
  1546     //---------------------------
       
  1547     // Step 3: Process the filter
       
  1548     TSize size = dataT.iRGBBitmap->SizeInPixels();
       
  1549 
       
  1550     // Lock the global bitmap heap
       
  1551     dataT.iRGBBitmap->LockHeap( ETrue );
       
  1552     CleanupStack::PushL( TCleanupItem( AknsRlLockCleanup, dataT.iRGBBitmap ) );
       
  1553 
       
  1554     // Leaves are ok because the cleanup item will take care of unlocking the
       
  1555     // bitmap heap.
       
  1556 
       
  1557     // Mask scanlines are the same for all color modes, we can prepare them
       
  1558     // here
       
  1559     if ( !iScans )
       
  1560         {
       
  1561         User::Leave( KErrNotReady );
       
  1562         }
       
  1563 
       
  1564     if( useAlpha )
       
  1565         {
       
  1566         if( iFlags & EConstantAMask ) // MA is a constant
       
  1567             {
       
  1568             iScans->Config8L( AknsRlIMA, size.iWidth, iAMask );
       
  1569             }
       
  1570         else // MA is bitmap
       
  1571             {
       
  1572             iScans->Config8L( AknsRlIMA, size.iWidth, *dataA.iAlphaBitmap );
       
  1573             }
       
  1574 
       
  1575         if( iFlags & EConstantBMask ) // MB is a constant
       
  1576             {
       
  1577             iScans->Config8L( AknsRlIMB, size.iWidth, iBMask );
       
  1578             }
       
  1579         else // MB is bitmap
       
  1580             {
       
  1581             iScans->Config8L( AknsRlIMB, size.iWidth, *dataB.iAlphaBitmap );
       
  1582             }
       
  1583         }
       
  1584     else // Non-masked mode, use alpha 255 for MA and MB
       
  1585         {
       
  1586         iScans->Config8L( AknsRlIMA, size.iWidth, 255 );
       
  1587         iScans->Config8L( AknsRlIMB, size.iWidth, 255 );
       
  1588         }
       
  1589 
       
  1590     // Color mode specific step
       
  1591     if( EColor64K == modeT )
       
  1592         {
       
  1593         TUint16* ptrT = NULL; TInt pitchT = 0;
       
  1594 
       
  1595         // Target is always bitmap
       
  1596         BitmapData( *dataT.iRGBBitmap, size.iWidth, ptrT, pitchT );
       
  1597 
       
  1598         if( iFlags & EConstantAColor ) // A is a constant
       
  1599             {
       
  1600             TUint16 color;
       
  1601             AknsRlRgb<TUint16,0,5,6,5>::SetRgb8( &color, iARed, iAGreen, iABlue );
       
  1602             iScans->Config16L( AknsRlIA, size.iWidth, color );
       
  1603             }
       
  1604         else // A is bitmap
       
  1605             {
       
  1606             iScans->Config16L( AknsRlIA, size.iWidth, *dataA.iRGBBitmap );
       
  1607             }
       
  1608 
       
  1609         if( iFlags & EConstantBColor ) // B is a constant
       
  1610             {
       
  1611             TUint16 color;
       
  1612             AknsRlRgb<TUint16,0,5,6,5>::SetRgb8( &color, iBRed, iBGreen, iBBlue );
       
  1613             iScans->Config16L( AknsRlIB, size.iWidth, color );
       
  1614             }
       
  1615         else // B is bitmap
       
  1616             {
       
  1617             iScans->Config16L( AknsRlIB, size.iWidth, *dataB.iRGBBitmap );
       
  1618             }
       
  1619 
       
  1620         typedef AknsRlBlend<TUint16,0,5,6,5> Blend16; // For brevity
       
  1621         // For brevity and maintainability, all blend functions share the same
       
  1622         // signature -> function pointer can be used
       
  1623         void (*blendfn)( TInt, TInt, TUint16*, TInt, const TUint16*, TInt,
       
  1624                          const TUint8*, TInt, const TUint16*, TInt,
       
  1625                          const TUint8*, TInt, TInt ) = NULL;
       
  1626 
       
  1627         switch( iBlendMode )
       
  1628             {
       
  1629             case EAknsRlChannelBlendNormal:
       
  1630                 blendfn = Blend16::Normal;
       
  1631                 break;
       
  1632             case EAknsRlChannelBlendDarken:
       
  1633                 blendfn = Blend16::Darken;
       
  1634                 break;
       
  1635             case EAknsRlChannelBlendLighten:
       
  1636                 blendfn = Blend16::Lighten;
       
  1637                 break;
       
  1638             case EAknsRlChannelBlendMultiply:
       
  1639                 blendfn = Blend16::Multiply;
       
  1640                 break;
       
  1641             case EAknsRlChannelBlendScreen:
       
  1642                 blendfn = Blend16::Screen;
       
  1643                 break;
       
  1644             case EAknsRlChannelBlendOverlay:
       
  1645                 blendfn = Blend16::Overlay;
       
  1646                 break;
       
  1647             case EAknsRlChannelBlendHardLight:
       
  1648                 blendfn = Blend16::HardLight;
       
  1649                 break;
       
  1650             case EAknsRlChannelBlendSoftLight:
       
  1651                 blendfn = Blend16::SoftLight;
       
  1652                 break;
       
  1653             case EAknsRlChannelBlendDifference:
       
  1654                 blendfn = Blend16::Difference;
       
  1655                 break;
       
  1656             case EAknsRlChannelBlendDodge:
       
  1657                 blendfn = Blend16::Dodge;
       
  1658                 break;
       
  1659             case EAknsRlChannelBlendBurn:
       
  1660                 blendfn = Blend16::Burn;
       
  1661                 break;
       
  1662             default:
       
  1663                 break;
       
  1664             }
       
  1665 
       
  1666         // Apply the blend
       
  1667         if( blendfn )
       
  1668             {
       
  1669             blendfn( size.iWidth, size.iHeight, ptrT, pitchT,
       
  1670                      iScans->Mem16(AknsRlIA), iScans->Pitch(AknsRlIA),
       
  1671                      iScans->Mem8(AknsRlIMA), iScans->Pitch(AknsRlIMA),
       
  1672                      iScans->Mem16(AknsRlIB), iScans->Pitch(AknsRlIB),
       
  1673                      iScans->Mem8(AknsRlIMB), iScans->Pitch(AknsRlIMB),
       
  1674                      iBlendFactor );
       
  1675             }
       
  1676         }
       
  1677     else if( EColor16MU == modeT )
       
  1678         {
       
  1679         TUint32* ptrT = NULL; TInt pitchT = 0;
       
  1680 
       
  1681         // Target is always bitmap
       
  1682         BitmapData( *dataT.iRGBBitmap, size.iWidth, ptrT, pitchT );
       
  1683 
       
  1684         if( iFlags & EConstantAColor ) // A is a constant
       
  1685             {
       
  1686             TUint32 color;
       
  1687             AknsRlRgb<TUint32,8,8,8,8>::SetRgb8( &color, iARed, iAGreen, iABlue );
       
  1688             iScans->Config32L( AknsRlIA, size.iWidth, color );
       
  1689             }
       
  1690         else // A is bitmap
       
  1691             {
       
  1692             iScans->Config32L( AknsRlIA, size.iWidth, *dataA.iRGBBitmap );
       
  1693             }
       
  1694 
       
  1695         if( iFlags & EConstantBColor ) // B is a constant
       
  1696             {
       
  1697             TUint32 color;
       
  1698             AknsRlRgb<TUint32,8,8,8,8>::SetRgb8( &color, iBRed, iBGreen, iBBlue );
       
  1699             iScans->Config32L( AknsRlIB, size.iWidth, color );
       
  1700             }
       
  1701         else // B is bitmap
       
  1702             {
       
  1703             iScans->Config32L( AknsRlIB, size.iWidth, *dataB.iRGBBitmap );
       
  1704             }
       
  1705 
       
  1706         typedef AknsRlBlend<TUint32,8,8,8,8> Blend32; // For brevity
       
  1707         // For brevity and maintainability, all blend functions share the same
       
  1708         // signature -> function pointer can be used
       
  1709         void (*blendfn)( TInt, TInt, TUint32*, TInt, const TUint32*, TInt,
       
  1710                          const TUint8*, TInt, const TUint32*, TInt,
       
  1711                          const TUint8*, TInt, TInt ) = NULL;
       
  1712 
       
  1713         switch( iBlendMode )
       
  1714             {
       
  1715             case EAknsRlChannelBlendNormal:
       
  1716                 blendfn = Blend32::Normal;
       
  1717                 break;
       
  1718             case EAknsRlChannelBlendDarken:
       
  1719                 blendfn = Blend32::Darken;
       
  1720                 break;
       
  1721             case EAknsRlChannelBlendLighten:
       
  1722                 blendfn = Blend32::Lighten;
       
  1723                 break;
       
  1724             case EAknsRlChannelBlendMultiply:
       
  1725                 blendfn = Blend32::Multiply;
       
  1726                 break;
       
  1727             case EAknsRlChannelBlendScreen:
       
  1728                 blendfn = Blend32::Screen;
       
  1729                 break;
       
  1730             case EAknsRlChannelBlendOverlay:
       
  1731                 blendfn = Blend32::Overlay;
       
  1732                 break;
       
  1733             case EAknsRlChannelBlendHardLight:
       
  1734                 blendfn = Blend32::HardLight;
       
  1735                 break;
       
  1736             case EAknsRlChannelBlendSoftLight:
       
  1737                 blendfn = Blend32::SoftLight;
       
  1738                 break;
       
  1739             case EAknsRlChannelBlendDifference:
       
  1740                 blendfn = Blend32::Difference;
       
  1741                 break;
       
  1742             case EAknsRlChannelBlendDodge:
       
  1743                 blendfn = Blend32::Dodge;
       
  1744                 break;
       
  1745             case EAknsRlChannelBlendBurn:
       
  1746                 blendfn = Blend32::Burn;
       
  1747                 break;
       
  1748             default:
       
  1749                 break;
       
  1750             }
       
  1751 
       
  1752         // Apply the blend
       
  1753         if( blendfn )
       
  1754             {
       
  1755             blendfn( size.iWidth, size.iHeight, ptrT, pitchT,
       
  1756                      iScans->Mem32(AknsRlIA), iScans->Pitch(AknsRlIA),
       
  1757                      iScans->Mem8(AknsRlIMA), iScans->Pitch(AknsRlIMA),
       
  1758                      iScans->Mem32(AknsRlIB), iScans->Pitch(AknsRlIB),
       
  1759                      iScans->Mem8(AknsRlIMB), iScans->Pitch(AknsRlIMB),
       
  1760                      iBlendFactor );
       
  1761             }
       
  1762         }
       
  1763     else if( EGray256 == modeT )
       
  1764         {
       
  1765         TUint8* ptrT = NULL; TInt pitchT = 0;
       
  1766 
       
  1767         // Target is always bitmap
       
  1768         BitmapData( *dataT.iRGBBitmap, size.iWidth, ptrT, pitchT );
       
  1769 
       
  1770         if( iFlags & EConstantAColor ) // A is a constant
       
  1771             {
       
  1772             iScans->Config8L( AknsRlIA, size.iWidth,
       
  1773                               AknsRlUtil::Grayscale( iARed, iAGreen, iABlue ) );
       
  1774             }
       
  1775         else // A is bitmap
       
  1776             {
       
  1777             iScans->Config8L( AknsRlIA, size.iWidth, *dataA.iRGBBitmap );
       
  1778             }
       
  1779 
       
  1780         if( iFlags & EConstantBColor ) // B is a constant
       
  1781             {
       
  1782             iScans->Config8L( AknsRlIB, size.iWidth,
       
  1783                               AknsRlUtil::Grayscale( iBRed, iBGreen, iBBlue ) );
       
  1784             }
       
  1785         else // B is bitmap
       
  1786             {
       
  1787             iScans->Config8L( AknsRlIB, size.iWidth, *dataB.iRGBBitmap );
       
  1788             }
       
  1789 
       
  1790         typedef AknsRlBlendGray BlendG; // For brevity
       
  1791         // For brevity and maintainability, all blend functions share the same
       
  1792         // signature -> function pointer can be used
       
  1793         void (*blendfn)( TInt, TInt, TUint8*, TInt, const TUint8*, TInt,
       
  1794                          const TUint8*, TInt, const TUint8*, TInt,
       
  1795                          const TUint8*, TInt, TInt ) = NULL;
       
  1796 
       
  1797         switch( iBlendMode )
       
  1798             {
       
  1799             case EAknsRlChannelBlendNormal:
       
  1800                 blendfn = BlendG::Normal;
       
  1801                 break;
       
  1802             case EAknsRlChannelBlendDarken:
       
  1803                 blendfn = BlendG::Darken;
       
  1804                 break;
       
  1805             case EAknsRlChannelBlendLighten:
       
  1806                 blendfn = BlendG::Lighten;
       
  1807                 break;
       
  1808             case EAknsRlChannelBlendMultiply:
       
  1809                 blendfn = BlendG::Multiply;
       
  1810                 break;
       
  1811             case EAknsRlChannelBlendScreen:
       
  1812                 blendfn = BlendG::Screen;
       
  1813                 break;
       
  1814             case EAknsRlChannelBlendOverlay:
       
  1815                 blendfn = BlendG::Overlay;
       
  1816                 break;
       
  1817             case EAknsRlChannelBlendHardLight:
       
  1818                 blendfn = BlendG::HardLight;
       
  1819                 break;
       
  1820             case EAknsRlChannelBlendSoftLight:
       
  1821                 blendfn = BlendG::SoftLight;
       
  1822                 break;
       
  1823             case EAknsRlChannelBlendDifference:
       
  1824                 blendfn = BlendG::Difference;
       
  1825                 break;
       
  1826             case EAknsRlChannelBlendDodge:
       
  1827                 blendfn = BlendG::Dodge;
       
  1828                 break;
       
  1829             case EAknsRlChannelBlendBurn:
       
  1830                 blendfn = BlendG::Burn;
       
  1831                 break;
       
  1832             default:
       
  1833                 break;
       
  1834             }
       
  1835 
       
  1836         // Apply the blend
       
  1837         if( blendfn )
       
  1838             {
       
  1839             blendfn( size.iWidth, size.iHeight, ptrT, pitchT,
       
  1840                      iScans->Mem8(AknsRlIA), iScans->Pitch(AknsRlIA),
       
  1841                      iScans->Mem8(AknsRlIMA), iScans->Pitch(AknsRlIMA),
       
  1842                      iScans->Mem8(AknsRlIB), iScans->Pitch(AknsRlIB),
       
  1843                      iScans->Mem8(AknsRlIMB), iScans->Pitch(AknsRlIMB),
       
  1844                      iBlendFactor );
       
  1845             }
       
  1846         }
       
  1847 
       
  1848     CleanupStack::Pop(); // Heap lock cleanup item
       
  1849 
       
  1850     // Unlock the global bitmap heap
       
  1851     dataT.iRGBBitmap->UnlockHeap( ETrue );
       
  1852     }
       
  1853 
       
  1854 // End of File