os/graphics/graphicsdeviceinterface/screendriver/sbit/FastBlend.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <bitstd.h>
    17 #include <graphics/lookuptable.h>
    18 #include <bitdrawinterfaceid.h>
    19 #include "../inc/BMDRAW.H"
    20 #include <graphics/gdi/gdiinline.inl>
    21 
    22 // Current plan is to depreciate 16MA targets so we have removed acceleration of these.
    23 // To re-enable put the __SUPPORT_16MA_TARGET__ back in
    24 //#define __SUPPORT_16MA_TARGET__
    25 
    26 // Enabling __CHECK_ALPHA01__ causes checks for alpha values of 0 and 1 to be made to attempt to
    27 // accelerate handling of these cases. This may not always work as branching the execution path
    28 // can potentially lose more time than is gained.
    29 
    30 #define __CHECK_ALPHA01__
    31 
    32 #define WRITE_RUN \
    33 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \
    34 		{ \
    35 		switch (aLen % 8)  /* aLen > 0 assumed */ \
    36 			{ \
    37 			case 0:        do {  write(aSrc, aDst);aSrc+=4;aDst+=4; \
    38 			case 7:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    39 			case 6:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    40 			case 5:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    41 			case 4:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    42 			case 3:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    43 			case 2:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    44 			case 1:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    45 				} while ((aLen -= 8) > 0); \
    46 			} \
    47 		}
    48 
    49 #define WRITE_RUN2ROT \
    50 	FORCEINLINE static void write2rot(const TUint8* aSrc, TUint8* aDst, TInt aLen, TInt aSrcStep, TInt aDstStep) \
    51 		{ \
    52 		switch (aLen % 8)  /* aLen > 0 assumed */ \
    53 			{ \
    54 			case 0:        do {  write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    55 			case 7:              write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    56 			case 6:              write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    57 			case 5:              write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    58 			case 4:              write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    59 			case 3:              write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    60 			case 2:              write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    61 			case 1:              write(aSrc, aDst);aSrc+=aSrcStep;aDst+=aDstStep; \
    62 				} while ((aLen -= 8) > 0); \
    63 			} \
    64 		}
    65 
    66 #define WRITE_RUN2H \
    67 	static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen);
    68 
    69 #define WRITE_RUN2C(class3232) \
    70 	void class3232::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) \
    71 		{ \
    72 		switch (aLen % 8)  /* aLen > 0 assumed */ \
    73 			{ \
    74 			case 0:        do {  write(aSrc, aDst);aSrc+=4;aDst+=4; \
    75 			case 7:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    76 			case 6:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    77 			case 5:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    78 			case 4:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    79 			case 3:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    80 			case 2:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    81 			case 1:              write(aSrc, aDst);aSrc+=4;aDst+=4; \
    82 				} while ((aLen -= 8) > 0); \
    83 			} \
    84 		}
    85 
    86 #define WRITE_RUN2416 \
    87 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \
    88 		{ \
    89 		switch (aLen % 8)  /* aLen > 0 assumed */ \
    90 			{ \
    91 			case 0:        do {  write(aSrc, aDst);aSrc+=3;aDst+=2; \
    92 			case 7:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
    93 			case 6:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
    94 			case 5:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
    95 			case 4:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
    96 			case 3:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
    97 			case 2:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
    98 			case 1:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
    99 				} while ((aLen -= 8) > 0); \
   100 			} \
   101 		}
   102 
   103 #define WRITE_RUN3216 \
   104 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \
   105 		{ \
   106 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   107 			{ \
   108 			case 0:        do {  write(aSrc, aDst);aSrc+=4;aDst+=2; \
   109 			case 7:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   110 			case 6:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   111 			case 5:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   112 			case 4:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   113 			case 3:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   114 			case 2:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   115 			case 1:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   116 				} while ((aLen -= 8) > 0); \
   117 			} \
   118 		}
   119 
   120 #define WRITE_RUN3216C2(class3216) \
   121 	void class3216::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) \
   122 		{ \
   123 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   124 			{ \
   125 			case 0:        do {  write(aSrc, aDst);aSrc+=4;aDst+=2; \
   126 			case 7:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   127 			case 6:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   128 			case 5:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   129 			case 4:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   130 			case 3:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   131 			case 2:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   132 			case 1:              write(aSrc, aDst);aSrc+=4;aDst+=2; \
   133 				} while ((aLen -= 8) > 0); \
   134 			} \
   135 		}
   136 
   137 #define WRITE_RUN2416C2(class2416) \
   138 	void class2416::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen) \
   139 		{ \
   140 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   141 			{ \
   142 			case 0:        do {  write(aSrc, aDst);aSrc+=3;aDst+=2; \
   143 			case 7:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
   144 			case 6:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
   145 			case 5:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
   146 			case 4:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
   147 			case 3:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
   148 			case 2:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
   149 			case 1:              write(aSrc, aDst);aSrc+=3;aDst+=2; \
   150 				} while ((aLen -= 8) > 0); \
   151 			} \
   152 		}
   153 
   154 #define WRITE_RUN1632 \
   155 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen) \
   156 		{ \
   157 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   158 			{ \
   159 			case 0:        do {  write(aSrc, aDst);aSrc+=2;aDst+=4; \
   160 			case 7:              write(aSrc, aDst);aSrc+=2;aDst+=4; \
   161 			case 6:              write(aSrc, aDst);aSrc+=2;aDst+=4; \
   162 			case 5:              write(aSrc, aDst);aSrc+=2;aDst+=4; \
   163 			case 4:              write(aSrc, aDst);aSrc+=2;aDst+=4; \
   164 			case 3:              write(aSrc, aDst);aSrc+=2;aDst+=4; \
   165 			case 2:              write(aSrc, aDst);aSrc+=2;aDst+=4; \
   166 			case 1:              write(aSrc, aDst);aSrc+=2;aDst+=4; \
   167 				} while ((aLen -= 8) > 0); \
   168 			} \
   169 		}
   170 
   171 // Using non-inline versions can make better usage of registers, need to experiment to find fastest mix
   172 
   173 #define WRITE_RUN1632C(class1632) \
   174 	void class1632::write2(const TUint8* aSrc, TUint8* aDst, TInt aLen)\
   175 		{ \
   176 		const TUint16* lowAdd = Convert16to32bppLow();\
   177 		const TUint32* highAdd = Convert16to32bppHigh();\
   178 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   179 			{ \
   180 			case 0:        do {  Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   181 			case 7:              Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   182 			case 6:              Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   183 			case 5:              Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   184 			case 4:              Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   185 			case 3:              Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   186 			case 2:              Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   187 			case 1:              Write64KTo16MLookup(aSrc, aDst, lowAdd, highAdd);aSrc+=2;aDst+=4; \
   188 				} while ((aLen -= 8) > 0); \
   189 			} \
   190 		}
   191 
   192 #define WRITE_ALPHA_MASK_RUN \
   193 	FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\
   194 		{ \
   195 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   196 			{ \
   197 			case 0:        do {  writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   198 			case 7:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   199 			case 6:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   200 			case 5:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   201 			case 4:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   202 			case 3:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   203 			case 2:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   204 			case 1:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=4; \
   205 				} while ((aLen -= 8) > 0); \
   206 			} \
   207 		}
   208 
   209 #define WRITE_ALPHA_MASK_RUN3216 \
   210 	FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\
   211 		{ \
   212 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   213 			{ \
   214 			case 0:        do {  writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   215 			case 7:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   216 			case 6:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   217 			case 5:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   218 			case 4:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   219 			case 3:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   220 			case 2:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   221 			case 1:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=4;aDst+=2; \
   222 				} while ((aLen -= 8) > 0); \
   223 			} \
   224 		}
   225 
   226 #define WRITE_ALPHA_MASK_RUN2416 \
   227 	FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\
   228 		{ \
   229 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   230 			{ \
   231 			case 0:        do {  writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   232 			case 7:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   233 			case 6:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   234 			case 5:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   235 			case 4:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   236 			case 3:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   237 			case 2:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   238 			case 1:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=3;aDst+=2; \
   239 				} while ((aLen -= 8) > 0); \
   240 			} \
   241 		}
   242 
   243 #define WRITE_ALPHA_MASK_RUN1632 \
   244 	FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\
   245 		{ \
   246 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   247 			{ \
   248 			case 0:        do {  writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   249 			case 7:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   250 			case 6:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   251 			case 5:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   252 			case 4:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   253 			case 3:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   254 			case 2:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   255 			case 1:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=4; \
   256 				} while ((aLen -= 8) > 0); \
   257 			} \
   258 		}
   259 
   260 #define WRITE_ALPHA_MASK_RUN1632H \
   261 	static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen);
   262 
   263 #define WRITE_ALPHA_MASK_RUN1632C(class1632) \
   264 	void class1632::writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\
   265 		{ \
   266 		const TUint8* srcPtr=aSrc;\
   267 		TUint8* dstPtr=aDst;\
   268 		const TUint8* alphaPtr=aAlpha;\
   269 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   270 			{ \
   271 			case 0:        do {  writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   272 			case 7:              writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   273 			case 6:              writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   274 			case 5:              writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   275 			case 4:              writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   276 			case 3:              writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   277 			case 2:              writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   278 			case 1:              writeMask(srcPtr, dstPtr, *alphaPtr++);srcPtr+=2;dstPtr+=4; \
   279 				} while ((aLen -= 8) > 0); \
   280 			} \
   281 		aSrc=srcPtr;\
   282 		aDst=dstPtr;\
   283 		aAlpha=alphaPtr;\
   284 		}
   285 
   286 #define WRITE_ALPHA_MASK_RUN1616 \
   287 	FORCEINLINE static void writeAlphaMask(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen)\
   288 		{ \
   289 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   290 			{ \
   291 			case 0:        do {  writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   292 			case 7:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   293 			case 6:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   294 			case 5:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   295 			case 4:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   296 			case 3:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   297 			case 2:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   298 			case 1:              writeMask(aSrc, aDst, *aAlpha++);aSrc+=2;aDst+=2; \
   299 				} while ((aLen -= 8) > 0); \
   300 			} \
   301 		}
   302 
   303 #define WRITE_ALPHA_MASK_RUN_ROT32 \
   304 	FORCEINLINE static void writeAlphaMaskRot(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen, TInt aSrcStride, TInt aMaskStride)\
   305 		{ \
   306 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   307 			{ \
   308 			case 0:        do {  writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   309 			case 7:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   310 			case 6:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   311 			case 5:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   312 			case 4:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   313 			case 3:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   314 			case 2:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   315 			case 1:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=4;aAlpha+=aMaskStride; \
   316 				} while ((aLen -= 8) > 0); \
   317 			} \
   318 		}
   319 
   320 #define WRITE_ALPHA_MASK_RUN_ROT16 \
   321 	FORCEINLINE static void writeAlphaMaskRot(const TUint8* &aSrc, TUint8* &aDst, const TUint8* aAlpha, TInt aLen, TInt aSrcStride, TInt aMaskStride)\
   322 		{ \
   323 		switch (aLen % 8)  /* aLen > 0 assumed */ \
   324 			{ \
   325 			case 0:        do {  writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   326 			case 7:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   327 			case 6:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   328 			case 5:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   329 			case 4:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   330 			case 3:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   331 			case 2:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   332 			case 1:              writeMask(aSrc, aDst, *aAlpha);aSrc+=aSrcStride;aDst+=2;aAlpha+=aMaskStride; \
   333 				} while ((aLen -= 8) > 0); \
   334 			} \
   335 		}
   336 
   337 #define MultAlphaWithSrcAlpha(aAlpha, aSrc)\
   338 	{\
   339 	const TUint32 src=*(TUint32*)aSrc;\
   340 	TUint32 srcAlpha=src>>24;\
   341 	aAlpha=(aAlpha*srcAlpha);\
   342 	aAlpha+=srcAlpha;\
   343 	aAlpha>>=8;\
   344 	}
   345 
   346 // Takes a pre-multipled alpha source and additionally multiplies it by the alpha
   347 // value so the source is effectively now pre-multiplied by both it's own alpha
   348 // and the specified alpha.
   349 // No aAlpha==0xFF or ==0 checks as should never come here in those situations
   350 #define MultMapSrcByAlpha(aAlpha, aSrc)\
   351 	{\
   352 	TUint32 d1 = (aSrc>>8)&0x00FF00FF;\
   353 	d1=d1*aAlpha+d1;\
   354 	TUint32 d2=aSrc&0x00FF00FF;\
   355 	d2=d2*aAlpha+d2;\
   356 	aSrc=(d1&0xFF00FF00)|((d2&0xFF00FF00)>>8);\
   357 	}
   358 
   359 #define Write16MTo64K(aSrc, aDst)\
   360 	{\
   361 	TInt color64K=(aSrc & 0x0000f8) >> 3;\
   362 	color64K|=(aSrc & 0x00fc00) >> 5;\
   363 	color64K|=(aSrc & 0xf80000) >> 8;\
   364 	*(TUint16*)aDst = color64K;\
   365 	}
   366 
   367 // Calc new alpha as src+(1-src)*dst;
   368 #define CalcDestMultAlpha(aDestMultAlpha, aDA, aSrcAlpha, aDstAlpha)\
   369 	{\
   370 	const TUint32 srcAlpha=aSrcAlpha;\
   371 	const TUint32 dstAlpha=aDstAlpha;\
   372 	aDA=dstAlpha<<16;\
   373 	aDA=aDA*(0x100-srcAlpha);\
   374 	aDA+=srcAlpha<<24;\
   375 	aDestMultAlpha=(((0x100-srcAlpha)*dstAlpha)>>8)+1;\
   376 	}
   377 
   378 // Note: This function assumes incoming rgb's are shifted up by an extra 8 bits as that's the
   379 // most efficient way of processing the preceding functions with this final write to 64K handling
   380 // the extra shift down.
   381 #define WriteRedBlueAndGreenTo64K(aRedBlue, aGreen, aDst)\
   382 	{\
   383 	TInt targ64K=(aRedBlue&0x00f800) >> 11;\
   384 	targ64K|=(aRedBlue&0xf8000000) >> 16;\
   385 	targ64K|=(aGreen&0xfc0000) >> 13;\
   386 	*(TUint16*)aDst = targ64K;\
   387 	}
   388 
   389 
   390 // Used for calculating blending from a MAP source to any of 16M dest formats.
   391 #define CalcMapToMxRGBA(aSrcPixel, aDst, aDestMult, aDestAG, aDestRB)\
   392 	{\
   393 	const TUint32 dstPixel=*(TUint32*)aDst;\
   394 	aDestAG=(dstPixel&0xFF00FF00)>>8;\
   395 	aDestAG=aDestAG*aDestMult;\
   396 	aDestAG+=aSrcPixel&0xFF00FF00;\
   397 	aDestRB=dstPixel&0x00FF00FF;\
   398 	aDestRB=(aDestRB*aDestMult)>>8;\
   399 	aDestRB+=aSrcPixel&0x00FF00FF;\
   400 	}
   401 
   402 // Used For non MAP source blending using dest=src*alpha+dest*destAlpha
   403 // aDestMultAlpha is typically (1-aAlpha) or (srcAlpha+(1-srcAlpha)*destAlpha)
   404 #define CalcMxToMxRGBA2A(aMxMxSrcPixel, aMxMxDestPixel, aMxMxAlpha, aMxMxDestMultAlpha, aMxMxDestAG, aMxMxDestRB)\
   405 	{\
   406 	aMxMxDestAG=(aMxMxDestPixel & 0xFF00FF00)>>8;\
   407 	aMxMxDestAG=aMxMxDestAG*aMxMxDestMultAlpha;\
   408 	TUint32 srcAG=(aMxMxSrcPixel&0xFF00FF00)>>8;\
   409 	aMxMxDestAG&=0xFF00FF00;\
   410 	TUint32 alphaPlus1=aMxMxAlpha+1;\
   411 	aMxMxDestAG+=srcAG*alphaPlus1;\
   412 	aMxMxDestRB=aMxMxDestPixel&0x00FF00FF;\
   413 	aMxMxDestRB=aMxMxDestRB*aMxMxDestMultAlpha;\
   414 	aMxMxDestRB&=0xFF00FF00;\
   415 	TUint32 srcRB=(aMxMxSrcPixel&0x00FF00FF);\
   416 	aMxMxDestRB+=srcRB*alphaPlus1;\
   417 	aMxMxDestRB>>=8;\
   418 	}
   419 
   420 // Used For non MAP source blending using dest=src*alpha+dest*(1-alpha)
   421 #define CalcMxToMxRGBA(aSrc, aDest, aAlpha, aDestAG, aDestRB)\
   422 	{\
   423 	const TUint32 srcPixel=*(TUint32*)aSrc;\
   424 	const TUint32 dstPixel=*(TUint32*)aDst;\
   425 	const TUint32 oneMinusAlpha = 0x100 - aAlpha;\
   426 	CalcMxToMxRGBA2A(srcPixel, dstPixel, aAlpha, oneMinusAlpha , aDestAG, aDestRB);\
   427 	}
   428 
   429 #define WriteMu(aDestAG, aDestRB, aDst)\
   430 	*(TUint32*)aDst=(aDestAG&0xFF00FF00)|(aDestRB&0x00FF00FF)|0xFF000000
   431 
   432 #define WriteMxA(aDestG, aDestRB, aDestA, aDst)\
   433 	*(TUint32*)aDst=(aDestG&0x0000FF00)|(aDestRB&0x00FF00FF)|(aDestA&0xFF000000)
   434 
   435 #define WriteMx(aDestAG, aDestRB, aDst)\
   436 	*(TUint32*)aDst=(aDestAG&0xFF00FF00)|(aDestRB&0x00FF00FF)
   437 
   438 struct TMapToMu
   439 	{
   440 	#define writeMapMu(aSrc, aDst)\
   441 		{\
   442 		const TUint32 oneMinusAlpha = 0x100-(aSrc>>24);\
   443 		TUint32 d1;\
   444 		TUint32 d2;\
   445 		CalcMapToMxRGBA(aSrc,aDst,oneMinusAlpha,d1,d2);\
   446 		WriteMu(d1,d2,aDst);\
   447 		}
   448 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   449 		{
   450 		const TUint32 src=*(TUint32*)aSrc;
   451 #if defined(__CHECK_ALPHA01__)
   452 		if (src >= 0xFF000000)
   453 			{
   454 			*(TUint32*)aDst = src;
   455 			return;
   456 			}
   457 		if (src <= 0x00FFFFFF)
   458 			return;
   459 #endif
   460 		writeMapMu(src, aDst);
   461 		}
   462 	WRITE_ALPHA_MASK_RUN_ROT32
   463 	WRITE_RUN2ROT
   464 	WRITE_RUN
   465 	WRITE_RUN2H
   466 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   467 		{
   468 		TUint32 src=*(TUint32*)aSrc;
   469 #if defined(__CHECK_ALPHA01__)
   470 		if (src>0x00FFFFFF)
   471 #endif
   472 			{
   473 			MultMapSrcByAlpha(aAlpha,src);
   474 			// No aAlpha==0xFF check as should never come here in that situation
   475 			writeMapMu(src, aDst);
   476 			}
   477 		}
   478 	WRITE_ALPHA_MASK_RUN
   479 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   480 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   481 	};
   482 
   483 struct TMapToMa
   484 	{
   485 	#define writeMapMa(aSrc, aDst)\
   486 		{\
   487 		const TUint32 d=*(TUint32*)aDst;\
   488 		TUint32 da;\
   489 		TUint32 destMultAlpha;\
   490 		CalcDestMultAlpha(destMultAlpha,da,aSrc>>24,d>>24);\
   491 		TUint32 d1;\
   492 		TUint32 d2;\
   493 		CalcMapToMxRGBA(aSrc,aDst,destMultAlpha,d1,d2);\
   494 		WriteMxA(d1,d2,da,aDst);\
   495 		}
   496 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   497 		{
   498 		const TUint32 src=*(TUint32*)aSrc;
   499 #if defined(__CHECK_ALPHA01__)
   500 		if (src>0x00FFFFFF)
   501 			{
   502 			if (src >= 0xFF000000)
   503 				*(TUint32*)aDst=src;
   504 			else
   505 				writeMapMa(src,aDst);
   506 			}
   507 #else
   508 		writeMapMa(src,aDst);
   509 #endif
   510 		}
   511 	WRITE_RUN
   512 	WRITE_ALPHA_MASK_RUN_ROT32
   513 	WRITE_RUN2ROT
   514 	WRITE_RUN2H
   515 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   516 		{
   517 		TUint32 src=*(TUint32*)aSrc;
   518 #if defined(__CHECK_ALPHA01__)
   519 		if (src>0x00FFFFFF)
   520 #endif
   521 			{
   522 			MultMapSrcByAlpha(aAlpha,src);
   523 			// No aAlpha==0xFF check as should never come here in that situation
   524 			writeMapMa(src,aDst);
   525 			}
   526 		}
   527 	WRITE_ALPHA_MASK_RUN
   528 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   529 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   530 	};
   531 
   532 struct TMapToMap
   533 	{
   534 	#define writeMapMap(aSrc, aDst)\
   535 		{\
   536 		const TUint32 oneMinusAlpha = 0x100-(aSrc>>24);\
   537 		TUint32 d1;\
   538 		TUint32 d2;\
   539 		CalcMapToMxRGBA(aSrc,aDst,oneMinusAlpha,d1,d2);\
   540 		WriteMx(d1,d2,aDst);\
   541 		}
   542 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   543 		{
   544 		const TUint32 src=*(TUint32*)aSrc;
   545 #if defined(__CHECK_ALPHA01__)
   546 		if (src >= 0xFF000000)
   547 			{
   548 			*(TUint32*)aDst = src;
   549 			return;
   550 			}
   551 		if (src <= 0x00FFFFFF)
   552 			return;
   553 #endif
   554 		writeMapMap(src,aDst);
   555 		}
   556 	WRITE_RUN
   557 	WRITE_ALPHA_MASK_RUN_ROT32
   558 	WRITE_RUN2ROT
   559 	WRITE_RUN2H
   560 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   561 		{
   562 		TUint32 src=*(TUint32*)aSrc;
   563 #if defined(__CHECK_ALPHA01__)
   564 		if (src<=0x00FFFFFF)
   565 			return;
   566 #endif
   567 		MultMapSrcByAlpha(aAlpha,src);
   568 		// No aAlpha==0xFF check as should never come here in that situation
   569 		writeMapMap(src,aDst);
   570 		}
   571 	WRITE_ALPHA_MASK_RUN
   572 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   573 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   574 	};
   575 
   576 struct TMaToMu
   577 	{
   578 	#define writeMaMu(aSrc, aAlpha, aDst)\
   579 		{\
   580 		TUint32 d1;\
   581 		TUint32 d2;\
   582 		CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2);\
   583 		WriteMu(d1,d2,aDst);\
   584 		}
   585 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   586 		{
   587 		const TUint32 src=*(TUint32*)aSrc;
   588 #if defined(__CHECK_ALPHA01__)
   589 		if (src >= 0xFF000000)
   590 			{
   591 			*(TUint32*)aDst = src;
   592 			return;
   593 			}
   594 		if (src <= 0x00FFFFFF)
   595 			return;
   596 #endif
   597 		const TUint32 alpha=src>>24;
   598 		writeMaMu(aSrc,alpha,aDst);
   599 		}
   600 	WRITE_RUN
   601 	WRITE_ALPHA_MASK_RUN_ROT32
   602 	WRITE_RUN2ROT
   603 	WRITE_RUN2H
   604 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   605 		{
   606 		MultAlphaWithSrcAlpha(aAlpha,aSrc);
   607 		writeMaMu(aSrc,aAlpha,aDst);
   608 		}
   609 	WRITE_ALPHA_MASK_RUN
   610 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   611 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   612 	};
   613 
   614 struct TMuToMu
   615 	{
   616 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   617 		{
   618 		*(TUint32*)aDst = *(TUint32*)aSrc;
   619 		}
   620 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen)
   621 		{
   622 		Mem::Move(aDst,aSrc,aLen*sizeof(TUint32));
   623 		aSrc+=aLen*4;
   624 		aDst+=aLen*4;
   625 		}
   626 	FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen)
   627 		{
   628 		Mem::Move(aDst,aSrc,aLen*sizeof(TUint32));
   629 		}
   630 	WRITE_ALPHA_MASK_RUN_ROT32
   631 	WRITE_RUN2ROT
   632 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   633 		{
   634 		TUint32 d1;
   635 		TUint32 d2;
   636 		CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2);
   637 		WriteMu(d1,d2,aDst);
   638 		}
   639 	WRITE_ALPHA_MASK_RUN
   640 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   641 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   642 	};
   643 
   644 struct TMuToMa
   645 	{
   646 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   647 		{
   648 		*(TUint32*)aDst = (*(TUint32*)aSrc);
   649 		}
   650 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen)
   651 		{
   652 		Mem::Move(aDst,aSrc,aLen*sizeof(TUint32));
   653 		aSrc+=aLen*4;
   654 		aDst+=aLen*4;
   655 		}
   656 	FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen)
   657 		{
   658 		Mem::Move(aDst,aSrc,aLen*sizeof(TUint32));
   659 		}
   660 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   661 		{
   662 		TUint32 da;
   663 		TUint32 d1;
   664 		TUint32 d2;
   665 		TUint32 destMultAlpha;
   666 		const TUint32 d = *(TUint32*)aDst;
   667 		CalcDestMultAlpha(destMultAlpha,da,aAlpha,d>>24);
   668 		const TUint32 srcPixel=*(TUint32*)aSrc;
   669 		const TUint32 dstPixel=*(TUint32*)aDst;
   670 		CalcMxToMxRGBA2A(srcPixel, dstPixel, aAlpha, destMultAlpha, d1, d2);
   671 		WriteMxA(d1,d2,da,aDst);
   672 		}
   673 	WRITE_ALPHA_MASK_RUN
   674 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   675 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   676 	};
   677 
   678 struct TMaToMa
   679 	{
   680 	#define writeMaMa(aSrc, aAlpha, aDst)\
   681 		{\
   682 		TUint32 da;\
   683 		TUint32 d1;\
   684 		TUint32 d2;\
   685 		TUint32 destMultAlpha;\
   686 		const TUint32 d = *(TUint32*)aDst;\
   687 		CalcDestMultAlpha(destMultAlpha,da,aAlpha,d>>24);\
   688 		const TUint32 srcPixel=*(TUint32*)aSrc;\
   689 		const TUint32 dstPixel=*(TUint32*)aDst;\
   690 		CalcMxToMxRGBA2A(srcPixel, dstPixel, aAlpha, destMultAlpha, d1, d2);\
   691 		WriteMxA(d1,d2,da,aDst);\
   692 		}
   693 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   694 		{
   695 		const TUint32 src=*(TUint32*)aSrc;
   696 #if defined(__CHECK_ALPHA01__)
   697 		if (src >= 0xFF000000)
   698 			{
   699 			*(TUint32*)aDst = src;
   700 			return;
   701 			}
   702 		if (src <= 0x00FFFFFF)
   703 			return;
   704 #endif
   705 		const TUint32 alpha=src>>24;
   706 		writeMaMa(aSrc,alpha,aDst);
   707 		}
   708 	WRITE_RUN
   709 	WRITE_ALPHA_MASK_RUN_ROT32
   710 	WRITE_RUN2ROT
   711 	WRITE_RUN2H
   712 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   713 		{
   714 		MultAlphaWithSrcAlpha(aAlpha,aSrc);
   715 		writeMaMa(aSrc,aAlpha,aDst);
   716 		}
   717 	WRITE_ALPHA_MASK_RUN
   718 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   719 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   720 	};
   721 
   722 struct TMaToMap
   723 	{
   724 	#define writeMaToMap(aSrc, aAlpha, aDst)\
   725 		{\
   726 		const TUint32 d = *(TUint32*)aDst;\
   727 		const TUint32 oneMinusAlpha = 0x100-aAlpha;\
   728 		TUint32 da=(d&0xFF000000)>>8;\
   729 		da=da*oneMinusAlpha;\
   730 		da+=aAlpha<<24;\
   731 		TUint32 d1;\
   732 		TUint32 d2;\
   733 		CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2);\
   734 		WriteMxA(d1,d2,da,aDst);\
   735 		}
   736 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   737 		{
   738 		const TUint32 src=*(TUint32*)aSrc;
   739 #if defined(__CHECK_ALPHA01__)
   740 		if (src >= 0xFF000000)
   741 			{
   742 			*(TUint32*)aDst = src;
   743 			return;
   744 			}
   745 		if (src <= 0x00FFFFFF)
   746 			return;
   747 #endif
   748 		const TUint32 alpha=src>>24;
   749 		writeMaToMap(aSrc,alpha,aDst);
   750 		}
   751 	WRITE_RUN
   752 	WRITE_ALPHA_MASK_RUN_ROT32
   753 	WRITE_RUN2ROT
   754 	WRITE_RUN2H
   755 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   756 		{
   757 		MultAlphaWithSrcAlpha(aAlpha,aSrc);
   758 		writeMaToMap(aSrc,aAlpha,aDst);
   759 		}
   760 	WRITE_ALPHA_MASK_RUN
   761 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   762 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   763 	};
   764 
   765 struct TMuToMap
   766 	{
   767 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   768 		{
   769 		*(TUint32*)aDst = (*(TUint32*)aSrc);
   770 		}
   771 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen)
   772 		{
   773 		Mem::Move(aDst,aSrc,aLen*sizeof(TUint32));
   774 		aSrc+=aLen*4;
   775 		aDst+=aLen*4;
   776 		}
   777 	FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen)
   778 		{
   779 		Mem::Move(aDst,aSrc,aLen*sizeof(TUint32));
   780 		}
   781 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   782 		{
   783 		TUint32 d1;
   784 		TUint32 d2;
   785 		CalcMxToMxRGBA(aSrc, aDst, aAlpha, d1, d2);
   786 		WriteMx(d1,d2,aDst);
   787 		}
   788 	WRITE_ALPHA_MASK_RUN_ROT32
   789 	WRITE_RUN2ROT
   790 	WRITE_ALPHA_MASK_RUN
   791 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   792 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
   793 	};
   794 
   795 WRITE_RUN2C(TMapToMap)
   796 WRITE_RUN2C(TMapToMa)
   797 WRITE_RUN2C(TMapToMu)
   798 WRITE_RUN2C(TMaToMap)
   799 WRITE_RUN2C(TMaToMa)
   800 WRITE_RUN2C(TMaToMu)
   801 
   802 // reads green value from 64K source, or's it with 0xFF alpha channel, and leaves
   803 // it shifted down by 8 ready for multiplying by alpha value.
   804 #define ReadGreen64K(aRG64KGreen, aRG64KSrc)\
   805 	aRG64KGreen=(aRG64KSrc&0x07E0)>>3;\
   806 	aRG64KGreen=((aRG64KGreen+(aRG64KGreen>>6))&0x000000FF)|0x00FF0000;
   807 
   808 // Reads the red and blue values from a 64K source into their RGBA values.
   809 #define ReadRedBlue64K(aRedBlue,aColor64K)\
   810 	{\
   811 	aRedBlue=(aColor64K&0xF800)<<8;\
   812 	aRedBlue|=(aColor64K&0x001F)<<3;\
   813 	aRedBlue+=aRedBlue>>5;\
   814 	aRedBlue&=0x00FF00FF;\
   815 	}
   816 
   817 // reads green value from 64K source into aGreen and red and blue into aRedBlue
   818 // All left in correct place for 16M operations
   819 #define Read64KColors(aGreen,aRedBlue,aPtr)\
   820 	{\
   821 	const TUint32 r64Kcolor64K=*(TUint16*)aPtr;\
   822 	aGreen=(r64Kcolor64K&0x07E0)<<5;\
   823 	aGreen+=aGreen>>6;\
   824 	aGreen&=0x0000FF00;\
   825 	ReadRedBlue64K(aRedBlue,r64Kcolor64K);\
   826 	}
   827 
   828 struct TMapTo64K
   829 	{
   830 	#define writeMap64K(aSrc, aDst)\
   831 		{\
   832 		TUint32 green;\
   833 		TUint32 redBlue;\
   834 		Read64KColors(green,redBlue,aDst);\
   835 		const TUint32 oneMinusAlpha = 0x100-(aSrc>>24);\
   836 		green=green*oneMinusAlpha;\
   837 		green+=(aSrc<<8)&0x00FF00FF;\
   838 		redBlue=redBlue*oneMinusAlpha;\
   839 		redBlue+=(aSrc&0x00FF00FF)<<8;\
   840 		WriteRedBlueAndGreenTo64K(redBlue,green,aDst);\
   841 		}
   842 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   843 		{
   844 		const TUint32 src=*(TUint32*)aSrc;
   845 #if defined(__CHECK_ALPHA01__)
   846 		if (src >= 0xFF000000)
   847 			{
   848 			Write16MTo64K(src,aDst);
   849 			return;
   850 			}
   851 		if (src <= 0x00FFFFFF)
   852 			return;
   853 #endif
   854 		writeMap64K(src,aDst);
   855 		}
   856 	WRITE_RUN2H
   857 	WRITE_RUN3216
   858 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   859 		{
   860 		TUint32 src=*(TUint32*)aSrc;
   861 #if defined(__CHECK_ALPHA01__)
   862 		if (src<=0x00FFFFFF)
   863 			return;
   864 #endif
   865 		MultMapSrcByAlpha(aAlpha,src);
   866 		// No aAlpha==0xFF check as should never come here in that situation
   867 		writeMap64K(src,aDst);
   868 		}
   869 	WRITE_ALPHA_MASK_RUN3216
   870 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   871 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));};
   872 	};
   873 
   874 // Calculates green and redBlue shifted up by 8, that will be sorted in WriteRedBlueAndGreenTo64K
   875 // this works out the most efficient way of getting the end result
   876 //
   877 // Note +++
   878 // Having the extra +greenSrc and +redBlueSrc (as in lines shown below) gives a better result, but
   879 // is inconsistent with old code and causes test code failures, so it has been removed.
   880 //	greenSrc=greenSrc*aAlpha+greenSrc;
   881 //	redBlueSrc=redBlueSrc*aAlpha+redBlueSrc;
   882 #define WriteMaOrMuTo64K(aSrc, aDst, aAlpha)\
   883 	{\
   884 	const TUint32 src=*(TUint32*)aSrc;\
   885 	TUint32 green;\
   886 	TUint32 redBlue;\
   887 	Read64KColors(green,redBlue,aDst);\
   888 	const TUint32 oneMinusAlpha = 0x100-aAlpha;\
   889 	green=green*oneMinusAlpha;\
   890 	TUint32 greenSrc=src&0x0000FF00;\
   891 	greenSrc=greenSrc*aAlpha;\
   892 	green+=greenSrc;\
   893 	redBlue=redBlue*oneMinusAlpha;\
   894 	TUint32 redBlueSrc=src&0x00FF00FF;\
   895 	redBlueSrc=redBlueSrc*aAlpha;\
   896 	redBlue+=redBlueSrc;\
   897 	WriteRedBlueAndGreenTo64K(redBlue,green,aDst);\
   898 	}
   899 
   900 struct TMTo64K
   901 	{
   902 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   903 		{
   904 		const TUint32 src=aSrc[0]+(aSrc[1]<<8)+(aSrc[2]<<16);
   905 		Write16MTo64K(src,aDst);
   906 		}
   907 	WRITE_RUN2416
   908 	WRITE_RUN2H
   909 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   910 		{
   911 		const TUint32 src=aSrc[0]+(aSrc[1]<<8)+(aSrc[2]<<16);
   912 		TUint32 green;
   913 		TUint32 redBlue;
   914 		Read64KColors(green,redBlue,aDst);
   915 		const TUint32 oneMinusAlpha = 0x100-aAlpha;
   916 		green=green*oneMinusAlpha;
   917 		TUint32 greenSrc=src&0x0000FF00;
   918 		greenSrc=greenSrc*aAlpha+greenSrc;
   919 		green+=greenSrc;
   920 		redBlue=redBlue*oneMinusAlpha;
   921 		TUint32 redBlueSrc=src&0x00FF00FF;
   922 		redBlueSrc=redBlueSrc*aAlpha+redBlueSrc;
   923 		redBlue+=redBlueSrc;
   924 		WriteRedBlueAndGreenTo64K(redBlue,green,aDst);
   925 		}
   926 	WRITE_ALPHA_MASK_RUN2416
   927 	FORCEINLINE static TInt SrcPixelBytes() {return(3);};
   928 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));};
   929 	};
   930 
   931 struct TMuTo64K
   932 	{
   933 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   934 		{
   935 		const TUint32 src=*(TUint32*)aSrc;
   936 		Write16MTo64K(src,aDst);
   937 		}
   938 	WRITE_RUN3216
   939 	WRITE_RUN2H
   940 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   941 		{
   942 		WriteMaOrMuTo64K(aSrc,aDst,aAlpha);
   943 		}
   944 	WRITE_ALPHA_MASK_RUN3216
   945 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   946 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));};
   947 	};
   948 
   949 struct TMaTo64K
   950 	{
   951 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   952 		{
   953 		const TUint32 src=*(TUint32*)aSrc;
   954 #if defined(__CHECK_ALPHA01__)
   955 		if (src >= 0xFF000000)
   956 			{
   957 			Write16MTo64K(src,aDst);
   958 			return;
   959 			}
   960 		if (src <= 0x00FFFFFF)
   961 			return;
   962 #endif
   963 		const TUint32 alpha=src>>24;
   964 		WriteMaOrMuTo64K(aSrc,aDst,alpha);
   965 		}
   966 	WRITE_RUN3216
   967 	WRITE_RUN2H
   968 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   969 		{
   970 		MultAlphaWithSrcAlpha(aAlpha,aSrc);
   971 		WriteMaOrMuTo64K(aSrc,aDst,aAlpha);
   972 		}
   973 	WRITE_ALPHA_MASK_RUN3216
   974 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint32));};
   975 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));};
   976 	};
   977 
   978 struct T64KTo64K
   979 	{
   980 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
   981 		{
   982 		*(TUint16*)aDst=*(const TUint16 *)aSrc;
   983 		}
   984 	FORCEINLINE static void write(const TUint8* &aSrc, TUint8* &aDst, TInt aLen)
   985 		{
   986 		Mem::Copy(aDst,aSrc,aLen*sizeof(TUint16));
   987 		aSrc+=aLen*2;
   988 		aDst+=aLen*2;
   989 		}
   990 	FORCEINLINE static void write2(const TUint8* aSrc, TUint8* aDst, TInt aLen)
   991 		{
   992 		Mem::Copy(aDst,aSrc,aLen*sizeof(TUint16));
   993 		}
   994 	WRITE_ALPHA_MASK_RUN_ROT16
   995 	WRITE_RUN2ROT
   996 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
   997 		{
   998 		const TUint32 oneMinusAlpha = 0x100-aAlpha;
   999 //
  1000 		TUint32 green;
  1001 		TUint32 redBlue;
  1002 		Read64KColors(green,redBlue,aDst);
  1003 		green=green*oneMinusAlpha;
  1004 		TUint32 greenSrc;
  1005 		TUint32 redBlueSrc;
  1006 		Read64KColors(greenSrc,redBlueSrc,aSrc);
  1007 // See note +++
  1008 //		greenSrc=greenSrc*aAlpha+greenSrc;
  1009 		greenSrc=greenSrc*aAlpha;
  1010 		green+=greenSrc;	// needs shift down by 8, but do that when going to 64K
  1011 //
  1012 		redBlue=redBlue*oneMinusAlpha;
  1013 // See note +++
  1014 //		redBlueSrc=redBlueSrc*aAlpha+redBlueSrc;
  1015 		redBlueSrc=redBlueSrc*aAlpha;
  1016 		redBlue+=redBlueSrc;	// needs shift down by 8, but do that when going to 64K
  1017 		WriteRedBlueAndGreenTo64K(redBlue,green,aDst);
  1018 		}
  1019 	WRITE_ALPHA_MASK_RUN1616
  1020 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));};
  1021 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint16));};
  1022 	};
  1023 
  1024 #define Write64KTo16M(aSrc, aDst)\
  1025 	TUint32 w6216Mgreen;\
  1026 	TUint32 w6216MredBlue;\
  1027 	Read64KColors(w6216Mgreen,w6216MredBlue, aSrc);\
  1028 	WriteMu(w6216Mgreen,w6216MredBlue,aDst);
  1029 
  1030 #define Write64KTo16MLookup(aSrc, aDst, aLowAdd, aHighAdd)\
  1031 	{\
  1032 	const TUint32 srcData=*(TUint16*)aSrc;\
  1033 	*(TUint32*)aDst = aHighAdd[srcData>>8] | aLowAdd[srcData&0xff];\
  1034 	}
  1035 
  1036 struct T64KToMu
  1037 	{
  1038 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
  1039 		{
  1040 		Write64KTo16M(aSrc,aDst);
  1041 		}
  1042 	WRITE_RUN1632
  1043 	WRITE_RUN2H
  1044 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
  1045 		{
  1046 		const TUint32 oneMinusAlpha = 0x100-aAlpha;
  1047 		const TUint32 d = *(TUint32*)aDst;
  1048 		TUint32 src=*(TUint16*)aSrc;
  1049 //
  1050 		TUint32 green = (d&0x0000FF00)>>8;
  1051 		green=green*oneMinusAlpha;
  1052 		TUint32 greenSrc;
  1053 		ReadGreen64K(greenSrc,src);
  1054 // See note +++
  1055 //		greenSrc=greenSrc*aAlpha+greenSrc;
  1056 		greenSrc=greenSrc*aAlpha;
  1057 		green+=greenSrc;
  1058 //
  1059 		TUint32 redBlue = d&0x00FF00FF;
  1060 		redBlue=redBlue*oneMinusAlpha;
  1061 		TUint32 redBlueSrc;
  1062 		ReadRedBlue64K(redBlueSrc,src);
  1063 // See note +++
  1064 //		redBlueSrc=redBlueSrc*aAlpha+redBlueSrc;
  1065 		redBlueSrc=redBlueSrc*aAlpha;
  1066 		redBlue+=redBlueSrc;
  1067 //
  1068 		redBlue>>=8;
  1069 		WriteMu(green,redBlue,aDst);
  1070 		}
  1071 	WRITE_ALPHA_MASK_RUN1632
  1072 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));};
  1073 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
  1074 	};
  1075 
  1076 struct T64KToMa
  1077 	{
  1078 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
  1079 		{
  1080 		Write64KTo16M(aSrc,aDst);
  1081 		}
  1082 	WRITE_RUN1632
  1083 	WRITE_RUN2H
  1084 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
  1085 		{
  1086 		const TUint32 destSrc = *(TUint32*)aDst;
  1087 		TUint32 destAlpha=destSrc>>24;
  1088 // Calc new alpha as src+(1-src)*dst;
  1089 		destAlpha=(0x100-aAlpha)*destAlpha;
  1090 		TUint32 targDestPixel=(destAlpha>>8)<<24;
  1091 		targDestPixel+=aAlpha<<24;
  1092 //
  1093 		TUint32 greenAlpha=(destSrc>>8)&0x000000FF;
  1094 		const TUint32 destMultAlpha = (destAlpha>>8)+1;
  1095 		greenAlpha=greenAlpha*destMultAlpha;
  1096 		TUint32 redBlue = destSrc&0x00FF00FF;
  1097 		redBlue=redBlue*destMultAlpha;
  1098 //
  1099 		TUint32 src=*(TUint16*)aSrc;
  1100 		TUint32 greenSrc;
  1101 		ReadGreen64K(greenSrc,src);
  1102 		greenSrc=greenSrc*aAlpha+greenSrc;
  1103 		greenAlpha+=greenSrc;
  1104 		targDestPixel|=greenAlpha&0x0000FF00;
  1105 //
  1106 		TUint32 redBlueSrc;
  1107 		ReadRedBlue64K(redBlueSrc,src);
  1108 		redBlueSrc=redBlueSrc*aAlpha+redBlueSrc;
  1109 		redBlue+=redBlueSrc;
  1110 //
  1111 		targDestPixel|=(redBlue>>8)&0x00FF00FF;
  1112 		*(TUint32*)aDst=targDestPixel;
  1113 		}
  1114 	WRITE_ALPHA_MASK_RUN1632H
  1115 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));};
  1116 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
  1117 	};
  1118 
  1119 WRITE_ALPHA_MASK_RUN1632C(T64KToMa)
  1120 
  1121 struct T64KToMap
  1122 	{
  1123 	FORCEINLINE static void write(const TUint8 *aSrc, TUint8* aDst)
  1124 		{
  1125 		Write64KTo16M(aSrc,aDst);
  1126 		}
  1127 	WRITE_RUN1632
  1128 	WRITE_RUN2H
  1129 	FORCEINLINE static void writeMask(const TUint8 *aSrc, TUint8* aDst, TUint aAlpha)
  1130 		{
  1131 		const TUint32 oneMinusAlpha = 0x100-aAlpha;
  1132 		const TUint32 d = *(TUint32*)aDst;
  1133 		TUint32 src=*(TUint16*)aSrc;
  1134 //
  1135 		TUint32 greenAlpha = (d&0xFF00FF00)>>8;
  1136 		greenAlpha=greenAlpha*oneMinusAlpha;
  1137 		TUint32 greenSrc;
  1138 		ReadGreen64K(greenSrc,src);
  1139 		greenSrc=greenSrc*aAlpha+greenSrc;
  1140 		greenAlpha&=0xFF00FF00;	// Needed to stop adding rounding errors together in next step
  1141 		greenAlpha+=greenSrc;
  1142 //
  1143 		TUint32 redBlue = d&0x00FF00FF;
  1144 		redBlue=redBlue*oneMinusAlpha;
  1145 		TUint32 redBlueSrc;
  1146 		ReadRedBlue64K(redBlueSrc,src);
  1147 		redBlueSrc=redBlueSrc*aAlpha+redBlueSrc;
  1148 		redBlue&=0xFF00FF00; // Needed to stop adding rounding errors together in next step
  1149 		redBlue+=redBlueSrc;	// needs shift down by 8, but do that when writing to dest
  1150 //
  1151 		redBlue>>=8;
  1152 		WriteMx(greenAlpha,redBlue,aDst);
  1153 		}
  1154 	WRITE_ALPHA_MASK_RUN1632
  1155 	FORCEINLINE static TInt SrcPixelBytes() {return(sizeof(TUint16));};
  1156 	FORCEINLINE static TInt DestPixelBytes() {return(sizeof(TUint32));};
  1157 	};
  1158 
  1159 WRITE_RUN1632C(T64KToMap)
  1160 WRITE_RUN1632C(T64KToMa)
  1161 WRITE_RUN1632C(T64KToMu)
  1162 WRITE_RUN3216C2(TMapTo64K)
  1163 WRITE_RUN3216C2(TMaTo64K)
  1164 WRITE_RUN3216C2(TMuTo64K)
  1165 WRITE_RUN2416C2(TMTo64K)
  1166 
  1167 inline TInt InitDda(TInt &aDdaCount, TBool &aStretching, TInt aSrcValue, TInt aDstValue, TInt aSkipSteps)
  1168 	{
  1169 	aDdaCount=0;
  1170 	aStretching=aDstValue>aSrcValue;
  1171 	TInt skip=0;
  1172 	if (aStretching)
  1173 		{
  1174 		aDdaCount=aDstValue-1;
  1175 		while(aSkipSteps--)
  1176 			{
  1177 			aDdaCount-=aSrcValue;
  1178 			if (aDdaCount<0)
  1179 				{
  1180 				skip++;
  1181 				aDdaCount+=aDstValue;
  1182 				}
  1183 			}
  1184 		}
  1185 	else
  1186 		{
  1187 		aDdaCount=aSrcValue-1;
  1188 		while(aSkipSteps)
  1189 			{
  1190 			aDdaCount-=aDstValue;
  1191 			if (aDdaCount<0)
  1192 				{
  1193 				aSkipSteps--;
  1194 				aDdaCount+=aSrcValue;
  1195 				}
  1196 			skip++;
  1197 			}
  1198 		}
  1199 	return(skip);
  1200 	}
  1201 
  1202 inline void DdaStep(TInt &aDdaCount, TBool aStretching, TInt aSrcValue, TInt aDstValue, TInt &aSkipCount)
  1203 	{
  1204 	if (aStretching)
  1205 		{
  1206 		aDdaCount-=aSrcValue;
  1207 		if (aDdaCount<0)
  1208 			{
  1209 			aSkipCount++;
  1210 			aDdaCount+=aDstValue;
  1211 			}
  1212 		}
  1213 	else
  1214 		{
  1215 		do
  1216 			{
  1217 			aSkipCount++;
  1218 			aDdaCount-=aDstValue;
  1219 			} while(aDdaCount>=0);
  1220 		aDdaCount+=aSrcValue;
  1221 		}
  1222 	}
  1223 
  1224 template <class op>
  1225 static void ScaledFastBlit(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, TUint8 *aDataAddress, TUint32 aDstStride, TRect& aDstRect, const TRect &aClipRect)
  1226 	{
  1227 	TInt srcWidth = aSrcRect.Width();
  1228 	TInt srcHeight = aSrcRect.Height();
  1229 	TInt dstWidth = aDstRect.Width();
  1230 	TInt dstHeight = aDstRect.Height();
  1231 //
  1232 	TInt yDdaCount;
  1233 	TBool yStretching;
  1234 	TInt ySrcOffset=aSrcRect.iTl.iY+InitDda(yDdaCount, yStretching, srcHeight, dstHeight, aClipRect.iTl.iY-aDstRect.iTl.iY);
  1235 //
  1236 	TInt xDdaCountBase;
  1237 	TBool xStretching;
  1238 	TInt sxOffset=aSrcRect.iTl.iX+InitDda(xDdaCountBase, xStretching, srcWidth, dstWidth, aClipRect.iTl.iX-aDstRect.iTl.iX);
  1239 	sxOffset*=op::SrcPixelBytes();
  1240 //
  1241 	const TInt yEnd=aClipRect.iBr.iY-aDstRect.iTl.iY;
  1242 	const TInt xCount=aClipRect.Width();
  1243 	TUint8* dstPixelBase = aDataAddress + aDstStride*aClipRect.iTl.iY + aClipRect.iTl.iX*op::DestPixelBytes();
  1244 	for (TInt y = aClipRect.iTl.iY-aDstRect.iTl.iY; y < yEnd; ++y)
  1245 		{
  1246 		const TUint8* srcPixel = aSrcBase + aSrcStride*ySrcOffset + sxOffset;
  1247 		TUint8* dstPixel = dstPixelBase;
  1248 		TInt xCountDown=xCount;
  1249 		TInt ddaCount = xDdaCountBase;
  1250 		if (xStretching)
  1251 			{
  1252 			do
  1253 				{
  1254 				op::write(srcPixel, dstPixel);
  1255 				dstPixel+=op::DestPixelBytes();
  1256 				ddaCount-=srcWidth;
  1257 				if (ddaCount<0)
  1258 					{
  1259 					srcPixel+=op::SrcPixelBytes();
  1260 					ddaCount+=dstWidth;
  1261 					}
  1262 				} while(--xCountDown);
  1263 			}
  1264 		else
  1265 			{
  1266 			do
  1267 				{
  1268 				op::write(srcPixel, dstPixel);
  1269 				dstPixel+=op::DestPixelBytes();
  1270 				do
  1271 					{
  1272 					srcPixel+=op::SrcPixelBytes();
  1273 					ddaCount-=dstWidth;
  1274 					} while(ddaCount>=0);
  1275 				ddaCount+=srcWidth;
  1276 				} while(--xCountDown);
  1277 			}
  1278 		dstPixelBase+=aDstStride;
  1279 		DdaStep(yDdaCount, yStretching, srcHeight, dstHeight, ySrcOffset);
  1280 		}
  1281 	}
  1282 
  1283 template <class op>
  1284 static void UnscaledFastBlit(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos)
  1285 	{
  1286 	const TInt blitWidth = aSrcRect.Width();
  1287 	const TUint8* srcPixel = aSrcBase + aSrcStride*aSrcRect.iTl.iY + aSrcRect.iTl.iX*op::SrcPixelBytes();
  1288 	TUint8* dstPixel = aDataAddress + aDstStride*aDstPos.iY + aDstPos.iX*op::DestPixelBytes();
  1289 	const TUint8* dstPixelEnd = dstPixel+aSrcRect.Height()*aDstStride;
  1290 	do
  1291 		{
  1292 		op::write2(srcPixel,dstPixel,blitWidth);
  1293 		srcPixel+=aSrcStride;
  1294 		dstPixel+=aDstStride;
  1295 		} while(dstPixel<dstPixelEnd);
  1296 	}
  1297 
  1298 static void ReplaceBlit(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos)
  1299 	{
  1300 	TInt srcStride=aSrcStride/4;
  1301 	TInt dstStride=aDstStride/4;
  1302 	TInt dx = aDstPos.iX;
  1303 	TInt dstWidth = aSrcRect.Width();
  1304 	const TUint32* srcPixel = reinterpret_cast<const TUint32*>(aSrcBase) + srcStride*aSrcRect.iTl.iY + aSrcRect.iTl.iX;
  1305 	TUint32* dstPixel = ((TUint32*)aDataAddress) + dstStride*aDstPos.iY + dx;
  1306 	const TInt copyLen=dstWidth*4;
  1307 	for (TInt linesToGo=aSrcRect.Height();linesToGo;--linesToGo)
  1308 		{
  1309 		// Andy - not convinced that this function is any good atall
  1310 		// try stdlib memcpy instead.
  1311 		Mem::Move(dstPixel, srcPixel, copyLen);
  1312 		srcPixel+=srcStride;
  1313 		dstPixel+=dstStride;
  1314 		}
  1315 	}
  1316 
  1317 template <class op>
  1318 static void UnscaledFastBlitRot(const TUint8* aSrcBase, CFbsDrawDevice::TOrientation aOrientation, TInt aSrcStride, TRect& aSrcRect, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TSize &aDestSize, TUint32* aScanLineBuffer)
  1319 	{
  1320 	TInt srcStep=op::SrcPixelBytes();
  1321 	TInt dstStep=op::DestPixelBytes();
  1322 	TInt dstStride=aDstStride;
  1323 	TInt blitWidth = aSrcRect.Width(); 
  1324 	TInt blitHeight = aSrcRect.Height(); 
  1325 	const TUint8* srcPixel = aSrcBase + aSrcRect.iTl.iY*aSrcStride + aSrcRect.iTl.iX*srcStep; 
  1326 	const TUint8* srcPixelEnd = srcPixel + blitHeight*aSrcStride;
  1327 	TUint8* dstPixel = aDataAddress; 
  1328 	
  1329 	
  1330 	switch(aOrientation)
  1331 		{
  1332 		case CFbsDrawDevice::EOrientationRotated90:
  1333 			dstPixel += (aDstPos.iX*aDstStride + (aDestSize.iWidth-aDstPos.iY-1)*op::DestPixelBytes());
  1334 			dstStep = aDstStride;
  1335 			dstStride = - op::DestPixelBytes();
  1336 			break;
  1337 		case CFbsDrawDevice::EOrientationRotated180: 
  1338 			dstPixel += ( (aDestSize.iHeight - aDstPos.iY -1 )*aDstStride +(aDestSize.iWidth - aDstPos.iX -1)*op::DestPixelBytes() ) ;
  1339 			dstStep = -dstStep;
  1340 			dstStride = -aDstStride;
  1341 			break;
  1342 		case CFbsDrawDevice::EOrientationRotated270:
  1343 			dstPixel += ( (aDestSize.iHeight- aDstPos.iX - 1 )*aDstStride + aDstPos.iY*op::DestPixelBytes() ) ;
  1344 			dstStep = -aDstStride;
  1345 			dstStride = op::DestPixelBytes();
  1346 			break;
  1347 		}
  1348 	do
  1349 		{
  1350 		Mem::Copy(aScanLineBuffer, srcPixel, blitWidth*srcStep);
  1351 		op::write2rot((TUint8*)aScanLineBuffer, dstPixel, blitWidth, srcStep, dstStep);
  1352 		srcPixel+=aSrcStride;
  1353 		dstPixel+=dstStride;
  1354 		} 
  1355 		while(srcPixel<srcPixelEnd);
  1356 	}
  1357 
  1358 template <class op>
  1359 static void ScaledFastBlitMaskedG2(const TUint8* aSrcBase, TInt aSrcStride, const TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TBool aInvertMask, TUint8 *aDataAddress, TInt aDstStride, const TRect& aDstRect, const TRect &aClipRect)
  1360 	{
  1361 	TInt sx = aSrcRect.iTl.iX;
  1362 	TInt sxOffset=sx*op::SrcPixelBytes();
  1363 	
  1364 	TInt srcWidth = aSrcRect.Width();
  1365 	TInt srcHeight = aSrcRect.Height();
  1366 	TInt dstWidth = aDstRect.Width();
  1367 	TInt dstHeight = aDstRect.Height();
  1368 //
  1369 	TInt yDdaCount;
  1370 	TBool yStretching;
  1371 	TInt ySrcOffset=aSrcRect.iTl.iY+InitDda(yDdaCount, yStretching, srcHeight, dstHeight, aClipRect.iTl.iY-aDstRect.iTl.iY);
  1372 //
  1373 	TInt xDdaCountBase;
  1374 	TBool xStretching;
  1375 	TInt xOffsetBase=InitDda(xDdaCountBase, xStretching, srcWidth, dstWidth, aClipRect.iTl.iX-aDstRect.iTl.iX);
  1376 //
  1377 	const TInt yEnd=aClipRect.iBr.iY-aDstRect.iTl.iY;
  1378 	const TInt xCount=aClipRect.Width();
  1379 	TUint8* dstPixelBase = aDataAddress+aDstStride*aClipRect.iTl.iY+aClipRect.iTl.iX*op::DestPixelBytes();
  1380 	for (TInt y = aClipRect.iTl.iY-aDstRect.iTl.iY; y < yEnd; ++y)
  1381 		{
  1382 		const TUint8* srcPixel = aSrcBase+aSrcStride*ySrcOffset+sxOffset;
  1383 		const TUint32* mskRowBase = (const TUint32*)(aMaskBase+aMaskStride*ySrcOffset);
  1384 		TUint8* dstPixel = dstPixelBase;
  1385 		TInt xCountDown=xCount;
  1386 		TInt curMaskOffset=-1;
  1387 		TUint32 maskbits=0;
  1388 		TInt xOffset=xOffsetBase;
  1389 		TInt ddaCount = xDdaCountBase;
  1390 		if (xStretching)
  1391 			{
  1392 			do
  1393 				{
  1394 				const TInt maskOffset=xOffset+sx;
  1395 				TInt maskBitOffset=maskOffset>>5;
  1396 				if (curMaskOffset==maskBitOffset)
  1397 					{
  1398 blitIt1:			const TInt mask=1<<(maskOffset%32);
  1399 					if (maskbits&mask)
  1400 						op::write(srcPixel, dstPixel);
  1401 					dstPixel+=op::DestPixelBytes();
  1402 					ddaCount-=srcWidth;
  1403 					if (ddaCount<0)
  1404 						{
  1405 						xOffset++;
  1406 						srcPixel+=op::SrcPixelBytes();
  1407 						ddaCount+=dstWidth;
  1408 						}
  1409 					continue;
  1410 					}
  1411 				maskbits=*(mskRowBase+maskBitOffset);
  1412 				if (aInvertMask)
  1413 					maskbits=~maskbits;
  1414 				curMaskOffset=maskBitOffset;
  1415 				goto blitIt1;
  1416 				} while(--xCountDown);
  1417 			}
  1418 		else
  1419 			{
  1420 			do
  1421 				{
  1422 				const TInt maskOffset=xOffset+sx;
  1423 				TInt maskBitOffset=maskOffset>>5;
  1424 				if (curMaskOffset==maskBitOffset)
  1425 					{
  1426 blitIt2:			const TInt mask=1<<(maskOffset%32);
  1427 					if (maskbits&mask)
  1428 						op::write(srcPixel, dstPixel);
  1429 					dstPixel+=op::DestPixelBytes();
  1430 					do
  1431 						{
  1432 						xOffset++;
  1433 						srcPixel+=op::SrcPixelBytes();
  1434 						ddaCount-=dstWidth;
  1435 						} while(ddaCount>=0);
  1436 					ddaCount+=srcWidth;
  1437 					continue;
  1438 					}
  1439 				maskbits=*(mskRowBase+maskBitOffset);
  1440 				if (aInvertMask)
  1441 					maskbits=~maskbits;
  1442 				curMaskOffset=maskBitOffset;
  1443 				goto blitIt2;
  1444 				} while(--xCountDown);
  1445 			}
  1446 		dstPixelBase+=aDstStride;
  1447 		DdaStep(yDdaCount, yStretching, srcHeight, dstHeight, ySrcOffset);
  1448 		}
  1449 	}
  1450 
  1451 template <class op>
  1452 static void UnscaledFastBlitMaskedG2(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TBool aInvertMask, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TPoint& aMaskSrcPos, const TSize &aMaskSize)
  1453 	{
  1454 	TInt sx = aSrcRect.iTl.iX;
  1455 	TInt sy = aSrcRect.iTl.iY;
  1456 	TInt dx = aDstPos.iX;
  1457 	TInt dy = aDstPos.iY;
  1458 	
  1459 	TInt dstWidth = aSrcRect.Width();
  1460 	TInt dstHeight = aSrcRect.Height();
  1461 	TInt maskWidth=aMaskSize.iWidth;
  1462 	TInt maskHeight=aMaskSize.iHeight;
  1463 	TInt maskXStart=aMaskSrcPos.iX%maskWidth;
  1464 	TInt maskStartShift=maskXStart&0x1F;
  1465 	TInt xMaskLoopCount=1+(dstWidth-1)/maskWidth;
  1466 	const TUint8* mskBasePtr=aMaskBase + (maskXStart/32)*4;
  1467 	for(TInt xMaskLoop=0;xMaskLoop<xMaskLoopCount;xMaskLoop++)
  1468 	  {
  1469 	  TInt xOffset=xMaskLoop*maskWidth;
  1470 	  TInt blitWidth=Min(maskWidth-maskStartShift,dstWidth-xOffset);
  1471 	  const TUint8* srcPixelStart = aSrcBase + aSrcStride*sy + (sx+xOffset)*op::SrcPixelBytes();
  1472 	  TUint8* dstPixelStart = aDataAddress + aDstStride*dy + (dx+xOffset)*op::DestPixelBytes();
  1473 	  for(TInt yPos=0;yPos<dstHeight;yPos++)
  1474 		{
  1475 		const TUint8* srcPixel=srcPixelStart;
  1476 		const TUint32* mskPixel=(const TUint32*)(mskBasePtr + aMaskStride*((aMaskSrcPos.iY+yPos)%maskHeight));
  1477 		TUint8* dstPixel=dstPixelStart;
  1478 		TUint mask=1<<maskStartShift;
  1479 		TUint32 maskPixels=*mskPixel;
  1480 		if (aInvertMask)
  1481 			maskPixels=~maskPixels;
  1482 		TInt runCount=0;
  1483 		TInt toGo=blitWidth;
  1484 		TUint32 endMask=0;
  1485 		const TInt tgMinusRun0=toGo+maskStartShift;
  1486 		if (tgMinusRun0<32)
  1487 			{
  1488 			endMask=1<<tgMinusRun0;
  1489 			maskPixels|=endMask;	// ensure the end of the scanline will fail set run where we will check for the end
  1490 			}
  1491 		// Into skip loop first, assume start of scanline more likely to be masked out than set
  1492 		FOREVER
  1493 			{
  1494 			if (!(mask&maskPixels))
  1495 				{
  1496 				runCount++;
  1497 rbm2startSkipRun:
  1498 				mask<<=1;
  1499 				if (mask!=0)
  1500 					continue;
  1501 				mask=1;
  1502 rbm2nextMaskSkip:
  1503 				const TInt tgMinusRun1=toGo-runCount;
  1504 				if (tgMinusRun1 == 0)
  1505 					{
  1506 					endMask = mask;
  1507 					maskPixels = endMask;
  1508 					}
  1509 				else
  1510 					{
  1511 					maskPixels=*++mskPixel;
  1512 					if (aInvertMask)
  1513 						{
  1514 						maskPixels=~maskPixels;
  1515 						}
  1516 					if (tgMinusRun1<32)
  1517 						{
  1518 						endMask=1<<tgMinusRun1;
  1519 						maskPixels|=endMask;	// ensure the end of the scanline will fail set run where we will check for the end
  1520 						}
  1521 					else if (maskPixels==0)
  1522 						{
  1523 						runCount+=32;
  1524 						goto rbm2nextMaskSkip;
  1525 						}
  1526 					}
  1527 				continue;
  1528 				}
  1529 			toGo-=runCount;
  1530 			if (toGo==0)
  1531 				goto rbm2nextY;
  1532 			dstPixel+=runCount*op::DestPixelBytes();
  1533 			srcPixel+=runCount*op::SrcPixelBytes();
  1534 			runCount=1;
  1535 			maskPixels^=endMask;	// toggle the end mask (if there is one)
  1536 			goto rbm2startSetRun;
  1537 			}
  1538 // Code within this section deals with runs of pixels to set
  1539 			{
  1540 rbm2startTopLoop:
  1541 			if (mask&maskPixels)
  1542 				{
  1543 				runCount++;
  1544 rbm2startSetRun:
  1545 				mask<<=1;
  1546 				if (mask!=0)
  1547 					goto rbm2startTopLoop;
  1548 				mask=1;
  1549 rbm2nextMaskSet:
  1550 				const TInt tgMinusRun2=toGo-runCount;
  1551 				if (tgMinusRun2 == 0)
  1552 					{
  1553 					endMask = mask;
  1554 					maskPixels = 0;
  1555 					}
  1556 				else
  1557 					{
  1558 					maskPixels=*++mskPixel;
  1559 					if (aInvertMask)
  1560 						{
  1561 						maskPixels=~maskPixels;
  1562 						}
  1563 					if (tgMinusRun2<32)
  1564 						{
  1565 						endMask=mask<<tgMinusRun2;
  1566 						maskPixels&=~endMask;	// ensure the end of the scanline will fail set run where we will check for the end
  1567 						}
  1568 					else if (maskPixels==0xFFFFFFFF)
  1569 						{
  1570 						runCount+=32;
  1571 						goto rbm2nextMaskSet;
  1572 						}
  1573 					}
  1574 				goto rbm2startTopLoop;
  1575 				}
  1576 			op::write(srcPixel, dstPixel, runCount);
  1577 			toGo-=runCount;
  1578 			if (toGo==0)
  1579 				goto rbm2nextY;
  1580 			maskPixels^=endMask;	// toggle the end mask (if there is one)
  1581 			runCount=1;
  1582 			goto rbm2startSkipRun;
  1583 			}
  1584 rbm2nextY:
  1585 		srcPixelStart+=aSrcStride;
  1586 		dstPixelStart+=aDstStride;
  1587 		}
  1588 	  maskStartShift=0;
  1589 	  }
  1590 	}
  1591 
  1592 template <class op>
  1593 static void ScaledFastBlitMaskedG256(const TUint8* aSrcBase, TInt aSrcStride, const TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TUint8 *aDataAddress, TInt aDstStride, const TRect& aDstRect, const TRect &aClipRect)
  1594 	{
  1595 	TInt sx = aSrcRect.iTl.iX;
  1596 	TInt sxOffset=sx*op::SrcPixelBytes();
  1597 	
  1598 	TInt srcWidth = aSrcRect.Width();
  1599 	TInt srcHeight = aSrcRect.Height();
  1600 	TInt dstWidth = aDstRect.Width();
  1601 	TInt dstHeight = aDstRect.Height();
  1602 //
  1603 	TInt yDdaCount;
  1604 	TBool yStretching;
  1605 	TInt ySrcOffset=aSrcRect.iTl.iY+InitDda(yDdaCount, yStretching, srcHeight, dstHeight, aClipRect.iTl.iY-aDstRect.iTl.iY);
  1606 //
  1607 	TInt xDdaCountBase;
  1608 	TBool xStretching;
  1609 	TInt xOffsetBase=InitDda(xDdaCountBase, xStretching, srcWidth, dstWidth, aClipRect.iTl.iX-aDstRect.iTl.iX);
  1610 //
  1611 	const TInt yEnd=aClipRect.iBr.iY-aDstRect.iTl.iY;
  1612 	const TInt xCount=aClipRect.Width();
  1613 	TUint8* dstPixelBase = aDataAddress+aClipRect.iTl.iY*aDstStride+aClipRect.iTl.iX*op::DestPixelBytes();
  1614 	for (TInt y = aClipRect.iTl.iY-aDstRect.iTl.iY; y < yEnd; ++y)
  1615 		{
  1616 		const TUint8* srcRowBase = aSrcBase+aSrcStride*ySrcOffset+sxOffset;
  1617 		const TUint8* mskRowBase = aMaskBase+aMaskStride*ySrcOffset+sx;
  1618 		TUint8* dstPixel = dstPixelBase;
  1619 		TInt xCountDown=xCount;
  1620 		TInt xOffset=xOffsetBase;
  1621 //
  1622 		TInt ddaCount = xDdaCountBase;
  1623 		if (xStretching)
  1624 			{
  1625 			do
  1626 				{
  1627 				TUint mask=*(mskRowBase+xOffset);
  1628 				if (mask==0xFF)
  1629 					op::write(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel);
  1630 				else if (mask!=0)
  1631 					op::writeMask(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel, mask);
  1632 				dstPixel+=op::DestPixelBytes();
  1633 //
  1634 				ddaCount-=srcWidth;
  1635 				if (ddaCount<0)
  1636 					{
  1637 					xOffset++;
  1638 					ddaCount+=dstWidth;
  1639 					}
  1640 				} while(--xCountDown);
  1641 			}
  1642 		else
  1643 			{
  1644 			do
  1645 				{
  1646 				TUint mask=*(mskRowBase+xOffset);
  1647 				if (mask==0xFF)
  1648 					op::write(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel);
  1649 				else if (mask!=0)
  1650 					op::writeMask(srcRowBase + xOffset*op::SrcPixelBytes(), dstPixel, mask);
  1651 				dstPixel+=op::DestPixelBytes();
  1652 //
  1653 				do
  1654 					{
  1655 					xOffset++;
  1656 					ddaCount-=dstWidth;
  1657 					} while(ddaCount>=0);
  1658 				ddaCount+=srcWidth;
  1659 				} while(--xCountDown);
  1660 			}
  1661 		dstPixelBase+=aDstStride;
  1662 		DdaStep(yDdaCount, yStretching, srcHeight, dstHeight, ySrcOffset);
  1663 		}
  1664 	}
  1665 
  1666 template <class op>
  1667 static void UnscaledFastBlitMaskedG256(const TUint8* aSrcBase, TInt aSrcStride, TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride, TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TPoint& aMaskSrcPos, const TSize &aMaskSize)
  1668 	{
  1669 	TInt dstWidth = aSrcRect.Width();
  1670 	const TInt dstHeight = aSrcRect.Height();
  1671 	const TUint8* srcPixelStart = aSrcBase + aSrcStride*aSrcRect.iTl.iY + aSrcRect.iTl.iX*op::SrcPixelBytes();
  1672 	TUint8* dstPixelStart = aDataAddress + aDstStride*aDstPos.iY + aDstPos.iX*op::DestPixelBytes();
  1673 	TInt yPos=0;
  1674 	const TInt maskWidth=aMaskSize.iWidth;
  1675 	const TInt maskHeight=aMaskSize.iHeight;
  1676 	const TInt maskStartOffset=aMaskSrcPos.iX%maskWidth;
  1677 	FOREVER
  1678 		{
  1679 		const TUint8* srcPixel=srcPixelStart;
  1680 		const TUint8* maskBase=aMaskBase + (aMaskStride*((aMaskSrcPos.iY+yPos)%maskHeight));
  1681 		const TUint8* mskPixel=maskBase + maskStartOffset;
  1682 		const TUint8* mskEnd=maskBase + maskWidth;
  1683 		if (dstWidth<(mskEnd-mskPixel))
  1684 			mskEnd=mskPixel+dstWidth;
  1685 		TUint8* dstPixel=dstPixelStart;
  1686 		const TUint8* runStart=mskPixel;
  1687 		TInt toGo=dstWidth;
  1688 		FOREVER
  1689 			{
  1690 // Into skip loop first, assume start of scanline more likely to be masked out than set
  1691 			TInt runLen1=0;
  1692 skipPixels:
  1693 			while(mskPixel<mskEnd && *mskPixel==0)
  1694 				mskPixel++;
  1695 			const TInt runSubLen1=mskPixel-runStart;
  1696 			runLen1+=runSubLen1;
  1697 			toGo-=runSubLen1;
  1698 			if (mskPixel==mskEnd && toGo!=0)
  1699 				{
  1700 				mskPixel=maskBase;
  1701 				runStart=maskBase;
  1702 				if (toGo<maskWidth)
  1703 					mskEnd=mskPixel+toGo;
  1704 				goto skipPixels;
  1705 				}
  1706 			dstPixel+=runLen1*op::DestPixelBytes();
  1707 			srcPixel+=runLen1*op::SrcPixelBytes();
  1708 			if (toGo==0)
  1709 				break;
  1710 			runStart=mskPixel++;
  1711 			if (*runStart!=255)
  1712 				goto blendIt;
  1713 // Fall through to solid fill code
  1714 solidFill:
  1715 			{// bracketing to avoid gccxml compile errors
  1716 			TInt runLen2=0;
  1717 solidFill2:
  1718 			while(mskPixel<mskEnd && *mskPixel==0xFF)
  1719 				mskPixel++;
  1720 			{// bracketing to avoid gccxml compile errors
  1721 			const TInt runSubLen2=mskPixel-runStart;
  1722 			runLen2+=runSubLen2;
  1723 			toGo-=runSubLen2;
  1724 			}
  1725 			if (mskPixel==mskEnd && toGo!=0)
  1726 				{
  1727 				mskPixel=maskBase;
  1728 				runStart=maskBase;
  1729 				if (toGo<maskWidth)
  1730 					mskEnd=mskPixel+toGo;
  1731 				goto solidFill2;
  1732 				}
  1733 			if (runLen2)
  1734 				op::write(srcPixel, dstPixel, runLen2);
  1735 			}
  1736 			if (toGo==0)
  1737 				break;
  1738 			runStart=mskPixel++;
  1739 			if (*runStart==0)
  1740 				continue;
  1741 blendIt:
  1742 			while(mskPixel<mskEnd && *mskPixel!=0 && *mskPixel!=255)
  1743 				mskPixel++;
  1744 			const TInt runSubLen3=mskPixel-runStart;
  1745 			if (runSubLen3)
  1746 				{
  1747 				toGo-=runSubLen3;
  1748 				op::writeAlphaMask(srcPixel,dstPixel,runStart,runSubLen3);
  1749 				}
  1750 			if (mskPixel==mskEnd && toGo!=0)
  1751 				{
  1752 				mskPixel=maskBase;
  1753 				runStart=maskBase;
  1754 				if (toGo<maskWidth)
  1755 					mskEnd=mskPixel+toGo;
  1756 				goto blendIt;
  1757 				}
  1758 			if (toGo==0)
  1759 				break;
  1760 			runStart=mskPixel++;
  1761 			if (*runStart==255)
  1762 				goto solidFill;
  1763 			}
  1764 		if (++yPos==dstHeight)
  1765 			break;
  1766 		srcPixelStart+=aSrcStride;
  1767 		dstPixelStart+=aDstStride;
  1768 		}
  1769 	}
  1770 
  1771 template <class op>
  1772 static void UnscaledFastBlitMaskedRotG256(const TUint8* aSrcBase, CFbsDrawDevice::TOrientation aOrientation, 
  1773 				TInt aSrcStride, TRect& aSrcRect, const TUint8* aMaskBase, TInt aMaskStride,
  1774 				TUint8 *aDataAddress, TUint32 aDstStride, const TPoint& aDstPos, const TSize &aDestSize,
  1775 				const TPoint& aMaskSrcPos, const TSize &aMaskSize)
  1776 	{
  1777 	TPoint dstPos(aDstPos);
  1778 	TInt srcStep=op::SrcPixelBytes();
  1779 	TInt maskStep=1;
  1780 	TRect srcRect(aSrcRect);
  1781 	TSize maskSize(aMaskSize);
  1782 	TPoint maskSrcPos(aMaskSrcPos);
  1783 	switch(aOrientation)
  1784 		{
  1785 	case CFbsDrawDevice::EOrientationRotated90:
  1786 		srcStep=-aSrcStride;
  1787 		aSrcStride=op::SrcPixelBytes();
  1788 		maskStep=-aMaskStride;
  1789 		aMaskStride=1;
  1790 		dstPos.iX=aDestSize.iWidth-aDstPos.iY-aSrcRect.Height();
  1791 		dstPos.iY=aDstPos.iX;
  1792 		srcRect.SetRect(aSrcRect.iTl.iY,aSrcRect.iTl.iX,aSrcRect.iBr.iY,aSrcRect.iBr.iX);
  1793 		maskSize.SetSize(aMaskSize.iHeight,aMaskSize.iWidth);
  1794 		maskSrcPos.iX=aMaskSrcPos.iY;
  1795 		maskSrcPos.iY=aMaskSrcPos.iX;
  1796 		break;
  1797 	case CFbsDrawDevice::EOrientationRotated180:
  1798 		srcStep=-op::SrcPixelBytes();
  1799 		maskStep=-1;
  1800 		aSrcStride=-aSrcStride;
  1801 		aMaskStride=-aMaskStride;
  1802 		dstPos.iX=aDestSize.iWidth-aDstPos.iX-aSrcRect.Width();
  1803 		dstPos.iY=aDestSize.iHeight-aDstPos.iY-aSrcRect.Height();
  1804 		break;
  1805 	case CFbsDrawDevice::EOrientationRotated270:
  1806 		srcStep=aSrcStride;
  1807 		aSrcStride=-op::SrcPixelBytes();
  1808 		maskStep=aMaskStride;
  1809 		aMaskStride=-1;
  1810 		dstPos.iX=aDstPos.iY;
  1811 		dstPos.iY=aDestSize.iHeight-aDstPos.iX-aSrcRect.Width();
  1812 		srcRect.SetRect(aSrcRect.iTl.iY,aSrcRect.iTl.iX,aSrcRect.iBr.iY,aSrcRect.iBr.iX);
  1813 		maskSrcPos.iX=aMaskSrcPos.iY;
  1814 		maskSrcPos.iY=aMaskSrcPos.iX;
  1815 		maskSize.SetSize(aMaskSize.iHeight,aMaskSize.iWidth);
  1816 		break;
  1817 		}
  1818 	const TUint8* srcPixelStart = aSrcBase;
  1819 	if (srcStep>0)
  1820 		srcPixelStart+=srcRect.iTl.iX*srcStep;
  1821 	else
  1822 		srcPixelStart-=(srcRect.iBr.iX-1)*srcStep;
  1823 	if (aSrcStride>0)
  1824 		srcPixelStart+=srcRect.iTl.iY*aSrcStride;
  1825 	else
  1826 		srcPixelStart-=(srcRect.iBr.iY-1)*aSrcStride;
  1827 //
  1828 	const TInt dstWidth = srcRect.Width();
  1829 	const TInt dstHeight = srcRect.Height();
  1830 	TUint8* dstPixelStart = aDataAddress + aDstStride*dstPos.iY + dstPos.iX*op::DestPixelBytes();
  1831 	TInt yPos=0;
  1832 	const TInt maskWidth=dstWidth<maskSize.iWidth?dstWidth:maskSize.iWidth;
  1833 	const TInt maskHeight=maskSize.iHeight;
  1834 	const TInt maskStartOffset=(maskStep>0?maskSrcPos.iX:srcRect.iBr.iX-1)%maskSize.iWidth;
  1835 	FOREVER
  1836 		{
  1837 		const TUint8* srcPixel=srcPixelStart;
  1838 		const TUint8* maskBase=aMaskBase;
  1839 		TInt maskYpos=(maskSrcPos.iY+yPos)%maskHeight;
  1840 		if (aMaskStride>0)
  1841 			maskBase+=maskYpos*aMaskStride;
  1842 		else
  1843 			{
  1844 			TInt maskEndPos=(maskSrcPos.iY+dstHeight-1-yPos)%maskHeight;
  1845 			maskBase-=maskEndPos*aMaskStride;
  1846 			}
  1847 		const TUint8* mskPixel=maskBase;
  1848 		const TUint8* mskEnd=maskBase;
  1849 		if (maskStep>0)
  1850 			{
  1851 			mskPixel+=maskStartOffset*maskStep;
  1852 			mskEnd+=maskSize.iWidth*maskStep;
  1853 			}
  1854 		else
  1855 			{
  1856 			maskBase-=(maskSize.iWidth-1)*maskStep;
  1857 			mskPixel-=maskStartOffset*maskStep;
  1858 			mskEnd+=maskStep;
  1859 			}
  1860 		const TInt maskToGo=(mskEnd-mskPixel)/maskStep;
  1861 		if (maskToGo>dstWidth)
  1862 			mskEnd=mskPixel+dstWidth*maskStep;
  1863 		TUint8* dstPixel=dstPixelStart;
  1864 		const TUint8* runStart=mskPixel;
  1865 		TInt toGo=dstWidth;
  1866 		FOREVER
  1867 			{
  1868 // Into skip loop first, assume start of scanline more likely to be masked out than set
  1869 			TInt runLen1=0;
  1870 skipPixels:
  1871 			while(mskPixel!=mskEnd && *mskPixel==0)
  1872 				mskPixel+=maskStep;
  1873 			const TInt runSubLen1=(mskPixel-runStart)/maskStep;
  1874 			runLen1+=runSubLen1;
  1875 			toGo-=runSubLen1;
  1876 			if (mskPixel==mskEnd && toGo!=0)
  1877 				{
  1878 				mskPixel=maskBase;
  1879 				runStart=maskBase;
  1880 				if (toGo<maskWidth)
  1881 					mskEnd=mskPixel+toGo*maskStep;
  1882 				goto skipPixels;
  1883 				}
  1884 			dstPixel+=runLen1*op::DestPixelBytes();
  1885 			srcPixel+=runLen1*srcStep;
  1886 			if (toGo==0)
  1887 				break;
  1888 			runStart=mskPixel;
  1889 			mskPixel+=maskStep;
  1890 			if (*runStart!=255)
  1891 				goto blendIt;
  1892 // Fall through to solid fill code
  1893 solidFill:
  1894 			{// bracketing to avoid gccxml compile errors
  1895 			TInt runLen2=0;
  1896 solidFill2:
  1897 			while(mskPixel!=mskEnd && *mskPixel==0xFF)
  1898 				mskPixel+=maskStep;
  1899 			{// bracketing to avoid gccxml compile errors
  1900 			const TInt runSubLen2=(mskPixel-runStart)/maskStep;
  1901 			runLen2+=runSubLen2;
  1902 			toGo-=runSubLen2;
  1903 			}
  1904 			if (mskPixel==mskEnd && toGo!=0)
  1905 				{
  1906 				mskPixel=maskBase;
  1907 				runStart=maskBase;
  1908 				if (toGo<maskWidth)
  1909 					mskEnd=mskPixel+toGo*maskStep;
  1910 				goto solidFill2;
  1911 				}
  1912 			if (runLen2)
  1913 				{
  1914 				op::write2rot(srcPixel,dstPixel,runLen2,srcStep, op::DestPixelBytes());
  1915 				srcPixel+=runLen2*srcStep;
  1916 				dstPixel+=runLen2*op::DestPixelBytes();
  1917 				}
  1918 			}
  1919 			if (toGo==0)
  1920 				break;
  1921 			runStart=mskPixel;
  1922 			mskPixel+=maskStep;
  1923 			if (*runStart==0)
  1924 				continue;
  1925 blendIt:
  1926 			while(mskPixel!=mskEnd && *mskPixel!=0 && *mskPixel!=255)
  1927 				mskPixel+=maskStep;
  1928 			const TInt runSubLen3=(mskPixel-runStart)/maskStep;
  1929 			if (runSubLen3)
  1930 				{
  1931 				toGo-=runSubLen3;
  1932 				op::writeAlphaMaskRot(srcPixel,dstPixel,runStart,runSubLen3,srcStep,maskStep);
  1933 				}
  1934 			if (mskPixel==mskEnd && toGo!=0)
  1935 				{
  1936 				mskPixel=maskBase;
  1937 				runStart=maskBase;
  1938 				if (toGo<maskWidth)
  1939 					mskEnd=mskPixel+toGo*maskStep;
  1940 				goto blendIt;
  1941 				}
  1942 			if (toGo==0)
  1943 				break;
  1944 			runStart=mskPixel;
  1945 			mskPixel+=maskStep;
  1946 			if (*runStart==255)
  1947 				goto solidFill;
  1948 			}
  1949 		if (++yPos==dstHeight)
  1950 			break;
  1951 		srcPixelStart+=aSrcStride;
  1952 		dstPixelStart+=aDstStride;
  1953 		}
  1954 	}
  1955 
  1956 void CDrawBitmap::GetBlendPosAndRect(TRect &aSrcRect, const TRect &aSrcRectIn, const TSize &aSrcSize, const TPoint &aDestOffset)
  1957 	{
  1958 	aSrcRect.iTl=aSrcRectIn.iTl+aDestOffset;
  1959 	aSrcRect.iBr=aSrcRectIn.iBr;
  1960 // Wrap source top left to within source bitmap
  1961 	if (aSrcRect.iTl.iX<0)
  1962 		{
  1963 		TInt negOffset=1-(aSrcRect.iTl.iX+1)/aSrcSize.iWidth;
  1964 		aSrcRect.Move(negOffset*aSrcSize.iWidth,0);
  1965 		}
  1966 	else if (aSrcRect.iTl.iX>=aSrcSize.iWidth)
  1967 		aSrcRect.Move(-(aSrcRect.iTl.iX/aSrcSize.iWidth)*aSrcSize.iWidth,0);
  1968 	if (aSrcRect.iTl.iY<0)
  1969 		{
  1970 		TInt negOffset=1-(aSrcRect.iTl.iY+1)/aSrcSize.iHeight;
  1971 		aSrcRect.Move(0,negOffset*aSrcSize.iHeight);
  1972 		}
  1973 	else if (aSrcRect.iTl.iY>=aSrcSize.iHeight)
  1974 		aSrcRect.Move(0,-(aSrcRect.iTl.iY/aSrcSize.iHeight)*aSrcSize.iHeight);
  1975 	if (aSrcRect.iBr.iY>aSrcSize.iHeight)
  1976 		aSrcRect.iBr.iY=aSrcSize.iHeight;
  1977 	if (aSrcRect.iBr.iX>aSrcSize.iWidth)
  1978 		aSrcRect.iBr.iX=aSrcSize.iWidth;
  1979 	}
  1980 
  1981 void CDrawBitmap::GetBlendPosAndRect(TRect &aDstRect, TRect &aSrcRect, const TRect &aDstRectIn, const TRect &aSrcRectIn, const TSize &aSrcSize)
  1982 	{
  1983 	aDstRect=aDstRectIn;
  1984 	aSrcRect=aSrcRectIn;
  1985 	if (aSrcRect.iTl.iX<0)
  1986 		aSrcRect.iTl.iX=0;
  1987 	if (aSrcRect.iTl.iY<0)
  1988 		aSrcRect.iTl.iY=0;
  1989 	TInt extraWidth=aSrcRect.iBr.iX-aSrcSize.iWidth;
  1990 	if (extraWidth>0)
  1991 		aSrcRect.iBr.iX-=extraWidth;
  1992 	TInt extraHeight=aSrcRect.iBr.iY-aSrcSize.iHeight;
  1993 	if (extraHeight>0)
  1994 		aSrcRect.iBr.iY-=extraHeight;
  1995 	}
  1996 
  1997 TInt CDrawBitmap::FastBlendBitmapMaskedScaled(const TRect &aClipRect, const TRect& aDest,
  1998 							const TRect& aSrcRect, const TUint32 *aSrcBase, TInt aSrcLinePitch,
  1999 							TDisplayMode aSrcDisplayMode, const TSize &aSrcSize,
  2000 							const TUint32* aMaskBase, TInt aMaskStride, TDisplayMode aMaskDisplayMode, const TSize &aMaskSize,TBool aInvertMask,
  2001 							CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode)
  2002 	{
  2003 	if (!FastBlendSupported(aSrcDisplayMode, aDrawMode, aShadowMode, aSrcLinePitch) ||
  2004 		!FastBlendMaskSupported(aMaskDisplayMode, aMaskStride) ||
  2005     	iOrientation!=EOrientationNormal)
  2006 		return(KErrNotSupported);
  2007 	TRect srcRect;
  2008 	TRect dstRect;
  2009 	GetBlendPosAndRect(dstRect,srcRect,aDest,aSrcRect,aSrcSize);
  2010 	const TInt KDestModeShift=8;
  2011 	const TInt KMaskModeShift=16;
  2012 #define MASKED_MODE_SWITCH(src,dest,mask) case src|(dest<<KDestModeShift)|(mask<<KMaskModeShift)
  2013 #define MODE_SWITCH(src,dest) case src|(dest<<KDestModeShift)
  2014 	TInt switchValue=aSrcDisplayMode|(iDispMode<<KDestModeShift)|(aMaskDisplayMode<<KMaskModeShift);
  2015 	if (srcRect.iBr.iX>aMaskSize.iWidth || srcRect.iBr.iY>aMaskSize.iHeight)
  2016 		return(KErrNotSupported);
  2017 	TUint8 *dstBits=reinterpret_cast<TUint8*>(iBits);
  2018 	TInt dstStride=iScanLineWords*4;
  2019 	const TUint8* srcBase=reinterpret_cast<const TUint8*>(aSrcBase);
  2020 	const TUint8 *maskBits=reinterpret_cast<const TUint8*>(aMaskBase);
  2021 	if (!dstRect.IsEmpty() && !srcRect.IsEmpty())
  2022 		{
  2023 		switch (switchValue)
  2024 			{
  2025 // 16MA source
  2026 			MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray2):
  2027 				ScaledFastBlitMaskedG2<TMaToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2028 				break;
  2029 			MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray2):
  2030 				ScaledFastBlitMaskedG2<TMaToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2031 				break;
  2032 			MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray2):
  2033 				ScaledFastBlitMaskedG2<TMaTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2034 				break;
  2035 			MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray256):
  2036 				ScaledFastBlitMaskedG256<TMaToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2037 				break;
  2038 			MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray256):
  2039 				ScaledFastBlitMaskedG256<TMaToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2040 				break;
  2041 			MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray256):
  2042 				ScaledFastBlitMaskedG256<TMaTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2043 				break;
  2044 	// 16MU source
  2045 			MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray2):
  2046 				ScaledFastBlitMaskedG2<TMuToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2047 				break;
  2048 			MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray2):
  2049 				ScaledFastBlitMaskedG2<TMuToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2050 				break;
  2051 			MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray2):
  2052 				ScaledFastBlitMaskedG2<TMuTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2053 				break;
  2054 			MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray2):
  2055 				ScaledFastBlitMaskedG2<TMTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2056 				break;
  2057 			MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray256):
  2058 				ScaledFastBlitMaskedG256<TMuToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2059 				break;
  2060 			MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray256):
  2061 				ScaledFastBlitMaskedG256<TMuToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2062 				break;
  2063 			MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray256):
  2064 				ScaledFastBlitMaskedG256<TMuTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2065 				break;
  2066 			MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray256):
  2067 				ScaledFastBlitMaskedG256<TMTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2068 				break;
  2069 	// 16MAP source
  2070 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray2):
  2071 				ScaledFastBlitMaskedG2<TMapToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2072 				break;
  2073 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray2):
  2074 				ScaledFastBlitMaskedG2<TMapToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2075 				break;
  2076 			MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray2):
  2077 				ScaledFastBlitMaskedG2<TMapTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2078 				break;
  2079 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray256):
  2080 				ScaledFastBlitMaskedG256<TMapToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2081 				break;
  2082 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray256):
  2083 				ScaledFastBlitMaskedG256<TMapToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2084 				break;
  2085 			MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray256):
  2086 				ScaledFastBlitMaskedG256<TMapTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2087 				break;
  2088 	// 64K source
  2089 			MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray2):
  2090 				ScaledFastBlitMaskedG2<T64KToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2091 				break;
  2092 			MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray2):
  2093 				ScaledFastBlitMaskedG2<T64KToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2094 				break;
  2095 			MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray2):
  2096 				ScaledFastBlitMaskedG2<T64KTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2097 				break;
  2098 			MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray256):
  2099 				ScaledFastBlitMaskedG256<T64KToMu>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2100 				break;
  2101 			MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray256):
  2102 				ScaledFastBlitMaskedG256<T64KToMap>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2103 				break;
  2104 			MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray256):
  2105 				ScaledFastBlitMaskedG256<T64KTo64K>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2106 				break;
  2107 #if defined(__SUPPORT_16MA_TARGET__)
  2108 			MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray2):
  2109 				ScaledFastBlitMaskedG2<TMaToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2110 				break;
  2111 			MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray256):
  2112 				ScaledFastBlitMaskedG256<TMaToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2113 				break;
  2114 			MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray2):
  2115 				ScaledFastBlitMaskedG2<TMuToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2116 				break;
  2117 			MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray256):
  2118 				ScaledFastBlitMaskedG256<TMuToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2119 				break;
  2120 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray2):
  2121 				ScaledFastBlitMaskedG2<TMapToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2122 				break;
  2123 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray256):
  2124 				ScaledFastBlitMaskedG256<TMapToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2125 				break;
  2126 			MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray2):
  2127 				ScaledFastBlitMaskedG2<T64KToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, dstRect, aClipRect);
  2128 				break;
  2129 			MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray256):
  2130 				ScaledFastBlitMaskedG256<T64KToMa>(srcBase, aSrcLinePitch, srcRect, maskBits, aMaskStride, dstBits, dstStride, dstRect, aClipRect);
  2131 				break;
  2132 #endif
  2133 			default:
  2134 				return KErrNotSupported;
  2135 			}
  2136 		}
  2137 	return(KErrNone);
  2138 	}
  2139 
  2140 TInt CDrawBitmap::FastBlendBitmapScaled(const TRect &aClipRect, const TRect& aDest, const TRect& aSrcRect, const TUint32 *aSrcBase, TInt aSrcLinePitch, TDisplayMode aSrcDisplayMode, const TSize &aSrcSize, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode)
  2141 	{
  2142 	if (!FastBlendSupported(aSrcDisplayMode, aDrawMode, aShadowMode, aSrcLinePitch))
  2143 		return(KErrNotSupported);
  2144 	TRect srcRect;
  2145 	TRect dstRect;
  2146 	GetBlendPosAndRect(dstRect,srcRect,aDest,aSrcRect,aSrcSize);
  2147 	const TInt KDestModeShift=8;
  2148 #define MODE_SWITCH(src,dest) case src|(dest<<KDestModeShift)
  2149 	TInt switchValue=aSrcDisplayMode|(iDispMode<<KDestModeShift);
  2150 	TUint8 *dstBits=reinterpret_cast<TUint8*>(iBits);
  2151 	TInt dstStride=iScanLineWords*4;
  2152 	const TUint8* srcBase=reinterpret_cast<const TUint8*>(aSrcBase);
  2153 	if (!dstRect.IsEmpty() && !srcRect.IsEmpty())
  2154 		{
  2155 		switch (switchValue)
  2156 			{
  2157 // 16MA Source
  2158 			MODE_SWITCH(EColor16MA,EColor16MU):
  2159 				ScaledFastBlit<TMaToMu>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2160 				break;
  2161 			MODE_SWITCH(EColor16MA,EColor16MAP):
  2162 				ScaledFastBlit<TMaToMap>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2163 				break;
  2164 			MODE_SWITCH(EColor16MA,EColor64K):
  2165 				ScaledFastBlit<TMaTo64K>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2166 				break;
  2167 // 16MAP Source
  2168 			MODE_SWITCH(EColor16MAP,EColor16MU):
  2169 				ScaledFastBlit<TMapToMu>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2170 				break;
  2171 			MODE_SWITCH(EColor16MAP,EColor16MAP):
  2172 				ScaledFastBlit<TMapToMap>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2173 				break;
  2174 			MODE_SWITCH(EColor16MAP,EColor64K):
  2175 				ScaledFastBlit<TMapTo64K>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2176 				break;
  2177 // 16MU Source
  2178 			MODE_SWITCH(EColor16MU,EColor16MU):
  2179 				ScaledFastBlit<TMuToMu>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2180 				break;
  2181 			MODE_SWITCH(EColor16MU,EColor64K):
  2182 				ScaledFastBlit<TMuTo64K>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2183 				break;
  2184 			// No EColor16MU to EColor16MAP fast blit performed because it
  2185 			// cannot be guaranteed that the alpha channel of the EColor16MU
  2186 			// source is 0xFF, which any fast blit would require. 
  2187 // 64K Source
  2188 			MODE_SWITCH(EColor64K,EColor16MU):
  2189 				ScaledFastBlit<T64KToMu>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2190 				break;
  2191 			MODE_SWITCH(EColor64K,EColor16MAP):
  2192 				ScaledFastBlit<T64KToMap>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2193 				break;
  2194 			MODE_SWITCH(EColor64K,EColor64K):
  2195 				ScaledFastBlit<T64KTo64K>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2196 				break;
  2197 // 16M source
  2198 			MODE_SWITCH(EColor16M,EColor64K):
  2199 				ScaledFastBlit<TMTo64K>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2200 				break;
  2201 #if defined(__SUPPORT_16MA_TARGET__)
  2202 			MODE_SWITCH(EColor16MA,EColor16MA):
  2203 				ScaledFastBlit<TMaToMa>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2204 				break;
  2205 			MODE_SWITCH(EColor16MAP,EColor16MA):
  2206 				ScaledFastBlit<TMapToMa>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2207 				break;
  2208 			MODE_SWITCH(EColor64K,EColor16MA):
  2209 				ScaledFastBlit<T64KToMa>(srcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstRect, aClipRect);
  2210 				break;
  2211 			// No EColor16MU to EColor16MA fast blit performed because it
  2212 			// cannot be guaranteed that the alpha channel of the EColor16MU
  2213 			// source is 0xFF, which any fast blit would require. 
  2214 #endif
  2215 			default:
  2216 				return KErrNotSupported;
  2217 			}
  2218 		}
  2219 	return KErrNone;
  2220 	}
  2221 
  2222 TInt CDrawBitmap::DoFastBlendBitmap(const TPoint &aDest, const TRect& aSrcRect, const TUint8 *aSrcBase, TInt aSrcLinePitch, TDisplayMode aSrcDisplayMode, const TSize &aSrcSize)
  2223 	{
  2224 	const TInt KDestModeShift=8;
  2225 	TInt dstStride=iScanLineWords*4;
  2226 	TUint8 *dstBits=(TUint8*)iBits;
  2227 #define MODE_SWITCH(src,dest) case src|(dest<<KDestModeShift)
  2228 	TInt switchValue=aSrcDisplayMode|(iDispMode<<KDestModeShift);
  2229 	TInt xEnd=aDest.iX+aSrcRect.Width();
  2230 	TInt yEnd=aDest.iY+aSrcRect.Height();
  2231 	TPoint dstPos;
  2232 	dstPos.iY=aDest.iY;
  2233 	while(dstPos.iY<yEnd)
  2234 		{
  2235 		TRect srcRect;
  2236 		dstPos.iX=aDest.iX;
  2237 		while(dstPos.iX<xEnd)
  2238 			{
  2239 // Clip source rect to within source bitmap size
  2240 			GetBlendPosAndRect(srcRect,aSrcRect,aSrcSize,dstPos-aDest);
  2241 			if (iOrientation==EOrientationNormal)
  2242 				{
  2243 				switch (switchValue)
  2244 					{
  2245 		// 16MA Source
  2246 				MODE_SWITCH(EColor16MA,EColor16MU):
  2247 					UnscaledFastBlit<TMaToMu>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2248 					break;
  2249 				MODE_SWITCH(EColor16MA,EColor16MAP):
  2250 					UnscaledFastBlit<TMaToMap>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2251 					break;
  2252 				MODE_SWITCH(EColor16MA,EColor64K):
  2253 					UnscaledFastBlit<TMaTo64K>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2254 					break;
  2255 		// 16MAP Source
  2256 				MODE_SWITCH(EColor16MAP,EColor16MU):
  2257 					UnscaledFastBlit<TMapToMu>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2258 					break;
  2259 				MODE_SWITCH(EColor16MAP,EColor16MAP):
  2260 					UnscaledFastBlit<TMapToMap>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2261 					break;
  2262 				MODE_SWITCH(EColor16MAP,EColor64K):
  2263 					UnscaledFastBlit<TMapTo64K>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2264 					break;
  2265 		// 16MU Source
  2266 				MODE_SWITCH(EColor16MU,EColor16MU):
  2267 					ReplaceBlit(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2268 					break;
  2269 				MODE_SWITCH(EColor16MU,EColor64K):
  2270 					UnscaledFastBlit<TMuTo64K>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2271 					break;
  2272 				// No EColor16MU to EColor16MAP fast blit performed because it
  2273 				// cannot be guaranteed that the alpha channel of the EColor16MU
  2274 				// source is 0xFF, which any fast blit would require. 
  2275 		// 64K Source
  2276 				MODE_SWITCH(EColor64K,EColor16MU):
  2277 					UnscaledFastBlit<T64KToMu>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2278 					break;
  2279 				MODE_SWITCH(EColor64K,EColor16MAP):
  2280 					UnscaledFastBlit<T64KToMap>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2281 					break;
  2282 				MODE_SWITCH(EColor64K,EColor64K):
  2283 					UnscaledFastBlit<T64KTo64K>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2284 					break;
  2285 		// 16M Source
  2286 				MODE_SWITCH(EColor16M,EColor64K):
  2287 					UnscaledFastBlit<TMTo64K>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2288 					break;
  2289 #if defined(__SUPPORT_16MA_TARGET__)
  2290 				MODE_SWITCH(EColor16MA,EColor16MA):
  2291 					UnscaledFastBlit<TMaToMa>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2292 					break;
  2293 				MODE_SWITCH(EColor16MAP,EColor16MA):
  2294 					UnscaledFastBlit<TMapToMa>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2295 					break;
  2296 				MODE_SWITCH(EColor64K,EColor16MA):
  2297 					UnscaledFastBlit<T64KToMa>(aSrcBase, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos);
  2298 					break;
  2299 				// No EColor16MU to EColor16MA fast blit performed because it
  2300 				// cannot be guaranteed that the alpha channel of the EColor16MU
  2301 				// source is 0xFF, which any fast blit would require. 
  2302 #endif
  2303 				default:
  2304 					return KErrNotSupported;
  2305 					}
  2306 				}
  2307 			else
  2308 				{
  2309 				switch (switchValue)
  2310 					{
  2311 		// 16MA Source
  2312 				MODE_SWITCH(EColor16MA,EColor16MU):
  2313 					UnscaledFastBlitRot<TMaToMu>(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer);
  2314 					break;
  2315 				MODE_SWITCH(EColor16MA,EColor16MAP):
  2316 					UnscaledFastBlitRot<TMaToMap>(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer);
  2317 					break;
  2318 		// 16MAP Source
  2319 				MODE_SWITCH(EColor16MAP,EColor16MU):
  2320 					UnscaledFastBlitRot<TMapToMu>(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer);
  2321 					break;
  2322 				MODE_SWITCH(EColor16MAP,EColor16MAP):
  2323 					UnscaledFastBlitRot<TMapToMap>(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer);
  2324 					break;
  2325 		// 16MU Source
  2326 				MODE_SWITCH(EColor16MU,EColor16MU):
  2327 					UnscaledFastBlitRot<TMuToMu>(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer);
  2328 					break;
  2329 				MODE_SWITCH(EColor16MU,EColor16MAP):
  2330 					UnscaledFastBlitRot<TMuToMap>(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer);
  2331 					break;
  2332 		// 64K Source
  2333 				MODE_SWITCH(EColor64K,EColor64K):
  2334 					UnscaledFastBlitRot<T64KTo64K>(aSrcBase, iOrientation, aSrcLinePitch, srcRect, dstBits, dstStride, dstPos, iSize, iScanLineBuffer);
  2335 					break;
  2336 				default:
  2337 					return KErrNotSupported;
  2338 					}
  2339 				}
  2340 			dstPos.iX+=srcRect.Width();
  2341 			}
  2342 		dstPos.iY+=srcRect.Height();
  2343 		}
  2344 	return KErrNone;
  2345 	}
  2346 
  2347 TBool CDrawBitmap::FastBlendSupported(TDisplayMode aSrcDisplayMode, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode, TInt aSrcLinePitch)
  2348     {
  2349     // FastBlend supports all combinations of EColor16Mxx and EColor64K, and when User Display Mode is ENone.
  2350     if ((iUserDispMode != EColor64K && iUserDispMode != EColor16M && 
  2351     	 iUserDispMode != EColor16MU && iUserDispMode != EColor16MA && 
  2352    	     iUserDispMode != EColor16MAP && iUserDispMode != ENone))
  2353     	{
  2354     	return (EFalse);
  2355     	}
  2356     if (!IsScalingOff() ||
  2357         !iOriginIsZero)
  2358         {
  2359 		return(EFalse);
  2360         }
  2361 	return((aDrawMode==CGraphicsContext::EDrawModePEN || (aDrawMode==CGraphicsContext::EDrawModeWriteAlpha && !IsAlphaChannel(aSrcDisplayMode))) &&
  2362 		aShadowMode==CFbsDrawDevice::ENoShadow && aSrcLinePitch>0);
  2363 	}
  2364 
  2365 TBool CDrawBitmap::FastBlendMaskSupported(TDisplayMode aMaskDisplayMode, TInt aMaskStride)
  2366 	{
  2367 	return((aMaskDisplayMode==EGray2 || aMaskDisplayMode==EGray256) && aMaskStride>0);
  2368 	}
  2369 
  2370 /**
  2371 CDrawBitmap::BlendBitmap() implementation.
  2372 @internalTechnology
  2373 */
  2374 TInt CDrawBitmap::FastBlendBitmap(const TPoint& aDest, CFbsDrawDevice* aSrcDrawDevice, const TRect& aSrcRect, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode)
  2375 	{
  2376 	TInt srcPitch=aSrcDrawDevice->ScanLineBytes();
  2377 	if (!FastBlendSupported(aSrcDrawDevice->DisplayMode(), aDrawMode, aShadowMode, srcPitch))
  2378 		return(KErrNotSupported);
  2379 	MScalingSettings* scalingSettings=NULL;
  2380 	if (aSrcDrawDevice->GetInterface(KScalingSettingsInterfaceID, 
  2381 							reinterpret_cast<TAny*&>(scalingSettings))==KErrNone)
  2382 		{
  2383 		if (!scalingSettings->IsScalingOff())
  2384 			return(KErrNotSupported);
  2385 		}
  2386 	MDrawDeviceOrigin* originInterface = NULL;
  2387 	if(aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, 
  2388 							reinterpret_cast <TAny*&> (originInterface)) == KErrNone)
  2389 		{
  2390 		TPoint origin;
  2391 		originInterface->Get(origin);
  2392 		if (origin.iX!=0 || origin.iY!=0)
  2393 			return(KErrNotSupported);
  2394 		}
  2395 	MDrawDeviceOrientation* orientationInterface=NULL;
  2396 	if(aSrcDrawDevice->GetInterface(KOrientationInterfaceID,
  2397 							reinterpret_cast <TAny*&> (orientationInterface))!=KErrNone || (orientationInterface && orientationInterface->Orientation() != 0))
  2398 		{
  2399 		return KErrNotSupported;
  2400 		}
  2401 	TAny* interface=NULL;
  2402 	TInt ret=aSrcDrawDevice->GetInterface(KFastBlit2InterfaceID, interface);
  2403 	if (ret!=KErrNone)
  2404 		return(ret);
  2405 	MFastBlit2 *fb2=reinterpret_cast<MFastBlit2*>(interface);
  2406 	const TUint8* srcBase = reinterpret_cast<const TUint8*>(fb2->Bits());
  2407 	return(DoFastBlendBitmap(aDest, aSrcRect, srcBase, srcPitch, aSrcDrawDevice->DisplayMode(), aSrcDrawDevice->SizeInPixels()));
  2408 	}
  2409 
  2410 TInt CDrawBitmap::FastBlendBitmap(const TPoint& aDest, const TUint32* aSrcBase, TInt aSrcStride, const TSize& aSrcSize, const TRect& aSrcRect, TDisplayMode aDisplayMode, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode)
  2411 	{
  2412 	if (!FastBlendSupported(aDisplayMode, aDrawMode, aShadowMode, aSrcStride))
  2413 		return(KErrNotSupported);
  2414 	return(DoFastBlendBitmap(aDest, aSrcRect, reinterpret_cast<const TUint8*>(aSrcBase), aSrcStride, aDisplayMode, aSrcSize));
  2415 	}
  2416 
  2417 TInt CDrawBitmap::FastBlendBitmapMasked(const TPoint& aDest, const TUint32* aSrcBase, TInt aSrcStride, const TSize& aSrcSize, const TRect& aSrcRect, TDisplayMode aSrcDisplayMode, const TUint32* aMaskBase, TInt aMaskStride, TDisplayMode aMaskDisplayMode, const TSize &aMaskSize, const TPoint &aMaskSrcPos, TBool aInvertMask, CGraphicsContext::TDrawMode aDrawMode, TInt aShadowMode)
  2418 	{
  2419 	if (!FastBlendSupported(aSrcDisplayMode, aDrawMode, aShadowMode, aSrcStride) ||
  2420 		!FastBlendMaskSupported(aMaskDisplayMode, aMaskStride))
  2421 		return(KErrNotSupported);
  2422 	TRect srcRect;
  2423 	GetBlendPosAndRect(srcRect,aSrcRect,aSrcSize,TPoint(0,0));
  2424 	const TInt KDestModeShift=8;
  2425 	const TInt KMaskModeShift=16;
  2426 	TInt dstStride=iScanLineWords*4;
  2427 #define MASKED_MODE_SWITCH(src,dest,mask) case src|(dest<<KDestModeShift)|(mask<<KMaskModeShift)
  2428 	TInt switchValue=aSrcDisplayMode|(iDispMode<<KDestModeShift);
  2429 	switchValue|=aMaskDisplayMode<<KMaskModeShift;
  2430 	const TUint8* srcBase=reinterpret_cast<const TUint8*>(aSrcBase);
  2431 	TUint8 *dstBits=(TUint8*)iBits;
  2432 	const TUint8 *maskBits=reinterpret_cast<const TUint8*>(aMaskBase);
  2433 	if (iOrientation==EOrientationNormal)
  2434 		{
  2435 		switch (switchValue)
  2436 			{
  2437 // 16MA source
  2438 			MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray2):
  2439 				UnscaledFastBlitMaskedG2<TMaToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2440 				break;
  2441 			MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray2):
  2442 				UnscaledFastBlitMaskedG2<TMaToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2443 				break;
  2444 			MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray2):
  2445 				UnscaledFastBlitMaskedG2<TMaTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2446 				break;
  2447 			MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray256):
  2448 				UnscaledFastBlitMaskedG256<TMaToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2449 				break;
  2450 			MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray256):
  2451 				UnscaledFastBlitMaskedG256<TMaToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2452 				break;
  2453 			MASKED_MODE_SWITCH(EColor16MA,EColor64K,EGray256):
  2454 				UnscaledFastBlitMaskedG256<TMaTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2455 				break;
  2456 // 16MU source
  2457 			MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray2):
  2458 				UnscaledFastBlitMaskedG2<TMuToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2459 				break;
  2460 			MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray2):
  2461 				UnscaledFastBlitMaskedG2<TMuToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2462 				break;
  2463 			MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray2):
  2464 				UnscaledFastBlitMaskedG2<TMuTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2465 				break;
  2466 			MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray2):
  2467 				UnscaledFastBlitMaskedG2<TMTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2468 				break;
  2469 			MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray256):
  2470 				UnscaledFastBlitMaskedG256<TMuToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2471 				break;
  2472 			MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray256):
  2473 				UnscaledFastBlitMaskedG256<TMuToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2474 				break;
  2475 			MASKED_MODE_SWITCH(EColor16MU,EColor64K,EGray256):
  2476 				UnscaledFastBlitMaskedG256<TMuTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2477 				break;
  2478 			MASKED_MODE_SWITCH(EColor16M,EColor64K,EGray256):
  2479 				UnscaledFastBlitMaskedG256<TMTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2480 				break;
  2481 // 16MAP source
  2482 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray2):
  2483 				UnscaledFastBlitMaskedG2<TMapToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2484 				break;
  2485 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray2):
  2486 				UnscaledFastBlitMaskedG2<TMapToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2487 				break;
  2488 			MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray2):
  2489 				UnscaledFastBlitMaskedG2<TMapTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2490 				break;
  2491 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray256):
  2492 				UnscaledFastBlitMaskedG256<TMapToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2493 				break;
  2494 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray256):
  2495 				UnscaledFastBlitMaskedG256<TMapToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2496 				break;
  2497 			MASKED_MODE_SWITCH(EColor16MAP,EColor64K,EGray256):
  2498 				UnscaledFastBlitMaskedG256<TMapTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2499 				break;
  2500 // 64K source
  2501 			MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray2):
  2502 				UnscaledFastBlitMaskedG2<T64KToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2503 				break;
  2504 			MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray2):
  2505 				UnscaledFastBlitMaskedG2<T64KToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2506 				break;
  2507 			MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray2):
  2508 				UnscaledFastBlitMaskedG2<T64KTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2509 				break;
  2510 			MASKED_MODE_SWITCH(EColor64K,EColor16MU,EGray256):
  2511 				UnscaledFastBlitMaskedG256<T64KToMu>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2512 				break;
  2513 			MASKED_MODE_SWITCH(EColor64K,EColor16MAP,EGray256):
  2514 				UnscaledFastBlitMaskedG256<T64KToMap>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2515 				break;
  2516 			MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray256):
  2517 				UnscaledFastBlitMaskedG256<T64KTo64K>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2518 				break;
  2519 #if defined(__SUPPORT_16MA_TARGET__)
  2520 			MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray2):
  2521 				UnscaledFastBlitMaskedG2<TMaToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2522 				break;
  2523 			MASKED_MODE_SWITCH(EColor16MA,EColor16MA,EGray256):
  2524 				UnscaledFastBlitMaskedG256<TMaToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2525 				break;
  2526 			MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray2):
  2527 				UnscaledFastBlitMaskedG2<TMuToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2528 				break;
  2529 			MASKED_MODE_SWITCH(EColor16MU,EColor16MA,EGray256):
  2530 				UnscaledFastBlitMaskedG256<TMuToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2531 				break;
  2532 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray2):
  2533 				UnscaledFastBlitMaskedG2<TMapToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2534 				break;
  2535 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MA,EGray256):
  2536 				UnscaledFastBlitMaskedG256<TMapToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2537 				break;
  2538 			MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray2):
  2539 				UnscaledFastBlitMaskedG2<T64KToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, aInvertMask, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2540 				break;
  2541 			MASKED_MODE_SWITCH(EColor64K,EColor16MA,EGray256):
  2542 				UnscaledFastBlitMaskedG256<T64KToMa>(srcBase, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, aMaskSrcPos, aMaskSize);
  2543 				break;
  2544 #endif
  2545 			default:
  2546 				return KErrNotSupported;
  2547 			}
  2548 		}
  2549 	else
  2550 		{
  2551 		switch (switchValue)
  2552 			{
  2553 	// 16MA Source
  2554 			MASKED_MODE_SWITCH(EColor16MA,EColor16MU,EGray256):
  2555 				UnscaledFastBlitMaskedRotG256<TMaToMu>(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize);
  2556 				break;
  2557 			MASKED_MODE_SWITCH(EColor16MA,EColor16MAP,EGray256):
  2558 				UnscaledFastBlitMaskedRotG256<TMaToMap>(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize);
  2559 				break;
  2560 	// 16MAP Source
  2561 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MU,EGray256):
  2562 				UnscaledFastBlitMaskedRotG256<TMapToMu>(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize);
  2563 				break;
  2564 			MASKED_MODE_SWITCH(EColor16MAP,EColor16MAP,EGray256):
  2565 				UnscaledFastBlitMaskedRotG256<TMapToMap>(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize);
  2566 				break;
  2567 	// 16MU Source
  2568 			MASKED_MODE_SWITCH(EColor16MU,EColor16MU,EGray256):
  2569 				UnscaledFastBlitMaskedRotG256<TMuToMu>(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize);
  2570 				break;
  2571 			MASKED_MODE_SWITCH(EColor16MU,EColor16MAP,EGray256):
  2572 				UnscaledFastBlitMaskedRotG256<TMuToMap>(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize);
  2573 				break;
  2574 	// 64K Source
  2575 			MASKED_MODE_SWITCH(EColor64K,EColor64K,EGray256):
  2576 				UnscaledFastBlitMaskedRotG256<T64KTo64K>(srcBase, iOrientation, aSrcStride, srcRect, maskBits, aMaskStride, dstBits, dstStride, aDest, iSize, aMaskSrcPos, aMaskSize);
  2577 				break;
  2578 			default:
  2579 				return KErrNotSupported;
  2580 			}
  2581 		}
  2582 	return KErrNone;
  2583 	}