graphicsdeviceinterface/screendriver/sbit/FastBlend.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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 	}