os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW16.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1997-20010 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 "BMDRAW.H"
    17 #include "BitDrawInterfaceId.h"
    18 #include <graphics/lookuptable.h>
    19 #include <graphics/blendingalgorithms.h>
    20 
    21 #if defined(SYMBIAN_USE_FAST_FADING)
    22 // 16bpp fast fade - half the contrast and brighten
    23 const TInt K16bppFastFadeShift = 1;
    24 const TUint16 K16bppFastFadeMask = 0x8410;
    25 // Use the 32 -> 16 bit colour convesrion method to get
    26 // the 16 bit fading constant (K16bppFastFadeOffset)
    27 // from 32 bit fading constant (SYMBIAN_USE_FAST_FADING).
    28 const TUint16 K16bppFastFadeOffset = ((SYMBIAN_USE_FAST_FADING & 0x0000f8) >> 3) |
    29 									((SYMBIAN_USE_FAST_FADING & 0x00fc00) >> 5) |
    30 									((SYMBIAN_USE_FAST_FADING & 0xf80000) >> 8);
    31 #endif
    32 
    33 // CDrawSixteenBppBitmapCommon
    34 
    35 //Initializes iSize, iDrawRect, iLongWidth, iScanlineWords data members.
    36 //It should be called every time when iSize is going to be changed - from Construct().
    37 //@param aSize Physical screen size in pixels.
    38 //@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the 
    39 //device is scaled and the scaling origin goes outside physical drawing rectangle.
    40 void CDrawSixteenBppBitmapCommon::SetSize(const TSize& aSize) 
    41 	{
    42 	CDrawBitmap::SetSize(aSize);
    43 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
    44 	iLongWidth = (iSize.iWidth + 1) & ~1;
    45 	iScanLineWords = iLongWidth >> 1;
    46 	}
    47  
    48 TInt CDrawSixteenBppBitmapCommon::Construct(TSize aSize, TInt aStride)
    49 	{
    50 	iBits = NULL;
    51 	CDrawBitmap::SetSize(aSize);
    52 	__ASSERT_DEBUG(iSize == aSize, User::Invariant());
    53 	if (aStride & 3)
    54 		return KErrArgument;
    55 	iLongWidth = aStride >> 1;
    56 	if (iLongWidth < aSize.iWidth)
    57 		return KErrArgument;
    58 	iScanLineWords = aStride >> 2;
    59 	TInt size = Max(aSize.iWidth,aSize.iHeight) << 1;
    60 	if(size < 0)
    61 		return KErrArgument;
    62 	iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
    63 	if (iScanLineBuffer == NULL)
    64 		return KErrNoMemory;
    65 	return KErrNone;
    66 	}
    67 
    68 TUint16* CDrawSixteenBppBitmapCommon::PixelAddress(TInt aX,TInt aY) const
    69 	{
    70 	return(((TUint16*)iBits) + (aY * iLongWidth) + aX);
    71 	}
    72 
    73 void CDrawSixteenBppBitmapCommon::InvertBuffer(TInt aLength,TUint32* aBuffer)
    74 	{
    75 	__ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicZeroLength));
    76 	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
    77 
    78 	const TUint32* limit = aBuffer + ((aLength + 1) >> 1);
    79 
    80 	while (aBuffer < limit)
    81 		*aBuffer++ ^= 0xffffffff;
    82 	}
    83 
    84 void CDrawSixteenBppBitmapCommon::ShadowArea(const TRect& aRect)
    85 	{
    86 	const TRect rect(DeOrientate(aRect));
    87 
    88 	__ASSERT_DEBUG(rect.iTl.iX>=0 && rect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
    89 	__ASSERT_DEBUG(rect.iTl.iY>=0 && rect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
    90 
    91 	const TInt longWidth = iLongWidth;
    92 	TUint16* pixelPtr = PixelAddress(rect.iTl.iX,rect.iTl.iY);
    93 	const TUint16* pixelRowPtrLimit = pixelPtr + (rect.Height() * longWidth);
    94 
    95 	if (iShadowMode & EFade)
    96 		{
    97 		TUint16* pixelRowPtr = pixelPtr;
    98 		TUint16* pixelPtrLimit = pixelPtr + rect.Width();
    99 
   100 		while (pixelRowPtr < pixelRowPtrLimit)
   101 			{
   102 			for (TUint16* tempPixelPtr = pixelRowPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
   103 				tempPixelPtr[0] = FadeIndex(tempPixelPtr[0]);
   104 
   105 			pixelRowPtr += longWidth;
   106 			pixelPtrLimit += longWidth;
   107 			}
   108 		}
   109 
   110 	if (iShadowMode & EShadow)
   111 		{
   112 		TUint16* pixelRowPtr = pixelPtr;
   113 		TUint16* pixelPtrLimit = pixelPtr + rect.Width();
   114 
   115 		while (pixelRowPtr < pixelRowPtrLimit)
   116 			{
   117 			for (TUint16* tempPixelPtr = pixelRowPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
   118 				tempPixelPtr[0] = ShadowIndex(tempPixelPtr[0]);
   119 
   120 			pixelRowPtr += longWidth;
   121 			pixelPtrLimit += longWidth;
   122 			}
   123 		}
   124 	}
   125 
   126 void CDrawSixteenBppBitmapCommon::ShadowBuffer(TInt aLength,TUint32* aBuffer)
   127 	{
   128 	__ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicZeroLength));
   129 	__ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
   130 
   131 	const TUint16* limit = ((TUint16*)aBuffer) + aLength;
   132 
   133 	if (iShadowMode & EFade)
   134 		{
   135 		for (TUint16* buffer = (TUint16*)aBuffer; buffer < limit; buffer++)
   136 			buffer[0] = FadeIndex(buffer[0]);
   137 		}
   138 
   139 	if (iShadowMode & EShadow)
   140 		{
   141 		for (TUint16* buffer = (TUint16*)aBuffer; buffer < limit; buffer++)
   142 			buffer[0] = ShadowIndex(buffer[0]);
   143 		}
   144 	}
   145 
   146 void CDrawSixteenBppBitmapCommon::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
   147 	{
   148 	const TUint16* pixelPtr = PixelAddress(aX,aY);
   149 	if (iOrientation == EOrientationNormal && iScalingOff)
   150 		Mem::Copy(aBuffer,pixelPtr,aLength * 2);
   151 	else
   152 		{
   153 		const TInt pixelPtrInc = LogicalPixelAddressIncrement();
   154 		TUint16* bufferPtr = STATIC_CAST(TUint16*,aBuffer);
   155 		const TUint16* bufferPtrLimit = bufferPtr + aLength;
   156 		while (bufferPtr < bufferPtrLimit)
   157 			{
   158 			*bufferPtr++ = *pixelPtr;
   159 			pixelPtr += pixelPtrInc;
   160 			}
   161 		}
   162 	}
   163 
   164 void CDrawSixteenBppBitmapCommon::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TUint16 aColor)
   165 	{
   166 	DeOrientate(aX,aY);
   167 	TInt pixelInc;
   168 	TInt rowInc;
   169 	SetPixelInc(pixelInc, rowInc);
   170 	const TUint32* dataLimit = aData + aHeight;
   171 	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
   172 	TUint16* pixelPtr = PixelAddress(aX,aY);
   173 	const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
   174 	const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   175 	TInt orgY = aY;
   176 	while (aData < dataLimit)
   177 		{
   178 		TUint32 dataWord = *aData++;
   179 		TUint32 dataMask = 1;
   180 		TUint16* tempPixelPtr = pixelPtr;
   181 		if (iScalingOff)
   182 			{
   183 			while (dataMask != dataMaskLimit)
   184 				{
   185 				if(dataWord & dataMask)
   186 					*tempPixelPtr = aColor;
   187 
   188 				tempPixelPtr += pixelInc;
   189 				dataMask <<= 1;
   190 				}
   191 			}
   192 		else
   193 			{
   194 			while (dataMask != dataMaskLimit)
   195 				{
   196 				if(dataWord & dataMask)
   197 					{
   198 					const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   199 					SetPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
   200 					}
   201 				tempPixelPtr += pixelInc;
   202 				dataMask <<= 1;
   203 				IncScaledY(aY);
   204 				}
   205 			}
   206 		pixelPtr += rowInc;
   207 		IncScaledY(aY, orgY);		
   208 		}
   209 	}
   210 
   211 void CDrawSixteenBppBitmapCommon::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TUint16 aColor,CGraphicsContext::TDrawMode aDrawMode)
   212 	{
   213 	if (aLength <= 0)
   214 		return;
   215 
   216 	DeOrientate(aX,aY);
   217 	TUint16* pixelPtr = PixelAddress(aX,aY);
   218 	const TUint32* dataPtrLimit = aData + aHeight;
   219 	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
   220 	TInt pixelInc;
   221 	TInt rowInc;
   222 	SetPixelInc(pixelInc, rowInc);
   223 	const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
   224 	const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   225 	TInt orgY = aY;
   226 	if (aColor)
   227 		{
   228 		while (aData < dataPtrLimit)
   229 			{
   230 			TUint32 dataWord = *aData++;
   231 			TUint32 dataMask = 1;
   232 			TUint16* tempPixelPtr = pixelPtr;
   233 			if (iScalingOff)
   234 				{
   235 				while (dataMask != dataMaskLimit)
   236 					{
   237 					if(dataWord & dataMask)
   238 						{
   239 						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
   240 							*tempPixelPtr ^= aColor;
   241 						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
   242 							*tempPixelPtr &= aColor;
   243 						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
   244 							*tempPixelPtr |= aColor;
   245 						}
   246 					tempPixelPtr += pixelInc;
   247 					dataMask <<= 1;
   248 					}
   249 				}
   250 			else
   251 				{
   252 				while(dataMask != dataMaskLimit)
   253 					{
   254 					if(dataWord & dataMask)
   255 						{
   256 						const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   257 						if(aDrawMode==CGraphicsContext::EDrawModeXOR)
   258 							{
   259 							XORPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
   260 							}
   261 						else if(aDrawMode==CGraphicsContext::EDrawModeAND)
   262 							{
   263 							ANDPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
   264 							}
   265 						else if(aDrawMode==CGraphicsContext::EDrawModeOR)
   266 							{
   267 							ORPixels(tempPixelPtr, aColor, pixelRowPtrLimit, bitsStart, bitsEnd);
   268 							}
   269 						}
   270 					tempPixelPtr += pixelInc;
   271 					dataMask <<= 1;
   272 					IncScaledY(aY);
   273 					}
   274 				}
   275 			pixelPtr += rowInc;
   276 			IncScaledY(aY, orgY);			
   277 			}
   278 		}
   279 	else if(aDrawMode==CGraphicsContext::EDrawModeAND)
   280 		{
   281 		while (aData < dataPtrLimit)
   282 			{
   283 			TUint32 dataWord = *aData++;
   284 			TUint32 dataMask = 1;
   285 			TUint16* tempPixelPtr = pixelPtr;
   286 			if (iScalingOff)
   287 				{
   288 				while (dataMask != dataMaskLimit)
   289 					{
   290 					if(dataWord & dataMask)
   291 						*tempPixelPtr = 0;
   292 
   293 					tempPixelPtr += pixelInc;
   294 					dataMask <<= 1;
   295 					}
   296 				}
   297 			else
   298 				{
   299 				while(dataMask != dataMaskLimit)
   300 					{
   301 					if(dataWord & dataMask)
   302 						{
   303 						const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   304 						SetPixels(tempPixelPtr, TUint16(0), pixelRowPtrLimit, bitsStart, bitsEnd);
   305 						}
   306 					tempPixelPtr += pixelInc;
   307 					dataMask <<= 1;
   308 					}
   309 				}
   310 			pixelPtr += rowInc;
   311 			IncScaledY(aY, orgY);			
   312 			}
   313 		}
   314 	}
   315 
   316 void CDrawSixteenBppBitmapCommon::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,TInt aHeight,TUint16 aColor,TBool aUp)
   317 	{
   318 	__ASSERT_DEBUG(iScalingOff, User::Invariant());	
   319 	DeOrientate(aX,aY);
   320 
   321 	TInt scanlineByteLength;
   322 
   323 	switch(iOrientation)
   324 		{
   325 		case EOrientationNormal:
   326 			scanlineByteLength = iLongWidth;
   327 			break;
   328 		case EOrientationRotated90:
   329 			scanlineByteLength = -1;
   330 			break;
   331 		case EOrientationRotated180:
   332 			scanlineByteLength = -iLongWidth;
   333 			break;
   334 		default: // EOrientationRotated270
   335 			scanlineByteLength = 1;	
   336 		}
   337 
   338 	if (aUp)
   339 		scanlineByteLength = -scanlineByteLength;
   340 
   341 	TUint16* pixelPtr = PixelAddress(aX,aY);
   342 	const TUint16* pixelPtrLimit = pixelPtr + (aHeight * scanlineByteLength);
   343 	TUint32 dataWord = *aData;
   344 	TUint32 dataMask = 1;
   345 
   346 	while(pixelPtr != pixelPtrLimit)
   347 		{
   348 		if(!dataMask)
   349 			{
   350 			dataMask = 1;
   351 			aData++;
   352 			dataWord = *aData;
   353 			}
   354 			
   355 		if(dataWord & dataMask)
   356 			*pixelPtr = aColor;
   357 		
   358 		dataMask <<= 1;
   359 		pixelPtr += scanlineByteLength;
   360 		}
   361 	}
   362 
   363 
   364 void CDrawSixteenBppBitmapCommon::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
   365 	{
   366 	const TInt longWidth = iLongWidth;
   367 	const TInt scanLineWords = iScanLineWords;
   368 
   369 	TUint16* pixelPtr = PixelAddress(aX,aY);
   370 	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
   371 
   372 	if ((aColor >> 8) == (TUint8)aColor)
   373 		{
   374 		while (pixelPtr < pixelRowPtrLimit)
   375 			{
   376 			Mem::Fill(pixelPtr,aLength * 2,TUint8(aColor));
   377 			pixelPtr += longWidth;
   378 			}
   379 		}
   380 	else
   381 		{
   382 		const TBool leadingPixel = aX & 1;
   383 		const TBool trailingPixel = (aX + aLength) & 1;
   384 		const TUint32 colorWord = (aColor << 16) | aColor;
   385 
   386 		TUint16* lastPixelPtr = pixelPtr + aLength - 1;
   387 		TUint32* wordPtr = REINTERPRET_CAST(TUint32*,pixelPtr + (leadingPixel ? 1 : 0));
   388 		TUint32* wordPtrLimit = REINTERPRET_CAST(TUint32*,lastPixelPtr + (trailingPixel ? 0 : 1));
   389 
   390 		__ASSERT_DEBUG(!(TInt(wordPtr) & 3),Panic(EScreenDriverPanicInvalidPointer));
   391 		__ASSERT_DEBUG(!(TInt(wordPtrLimit) & 3),Panic(EScreenDriverPanicInvalidPointer));
   392 
   393 		if (leadingPixel)
   394 			{
   395 			while (pixelPtr < pixelRowPtrLimit)
   396 				{
   397 				pixelPtr[0] = aColor;
   398 				pixelPtr += longWidth;
   399 				}
   400 			}
   401 
   402 		while (wordPtr < (TUint32*)pixelRowPtrLimit)
   403 			{
   404 			MemFillTUint32(wordPtr, wordPtrLimit-wordPtr, colorWord);
   405 			wordPtr += scanLineWords;
   406 			wordPtrLimit += scanLineWords;
   407 			}
   408 
   409 		if (trailingPixel)
   410 			{
   411 			while (lastPixelPtr < pixelRowPtrLimit)
   412 				{
   413 				lastPixelPtr[0] = aColor;
   414 				lastPixelPtr += longWidth;
   415 				}
   416 			}
   417 		}
   418 	}
   419 
   420 void CDrawSixteenBppBitmapCommon::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
   421 	{
   422 	const TInt longWidth = iLongWidth;
   423 	TUint16* pixelPtr = PixelAddress(aX,aY);
   424 	TUint16* pixelPtrLimit = pixelPtr + aLength;
   425 	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
   426 
   427 	while (pixelPtr < pixelRowPtrLimit)
   428 		{
   429 		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
   430 			tempPixelPtr[0] ^= aColor;
   431 
   432 		pixelPtr += longWidth;
   433 		pixelPtrLimit += longWidth;
   434 		}
   435 	}
   436 
   437 void CDrawSixteenBppBitmapCommon::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
   438 	{
   439 	const TInt longWidth = iLongWidth;
   440 	TUint16* pixelPtr = PixelAddress(aX,aY);
   441 	TUint16* pixelPtrLimit = pixelPtr + aLength;
   442 	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
   443 
   444 	while (pixelPtr < pixelRowPtrLimit)
   445 		{
   446 		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
   447 			tempPixelPtr[0] &= aColor;
   448 
   449 		pixelPtr += longWidth;
   450 		pixelPtrLimit += longWidth;
   451 		}
   452 	}
   453 
   454 void CDrawSixteenBppBitmapCommon::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TUint16 aColor)
   455 	{
   456 	const TInt longWidth = iLongWidth;
   457 	TUint16* pixelPtr = PixelAddress(aX,aY);
   458 	TUint16* pixelPtrLimit = pixelPtr + aLength;
   459 	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
   460 
   461 	while (pixelPtr < pixelRowPtrLimit)
   462 		{
   463 		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
   464 			tempPixelPtr[0] |= aColor;
   465 
   466 		pixelPtr += longWidth;
   467 		pixelPtrLimit += longWidth;
   468 		}
   469 	}
   470 
   471 void CDrawSixteenBppBitmapCommon::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   472 	{
   473 	TUint16* pixelPtr = PixelAddress(aX,aY);
   474 	if (iOrientation == EOrientationNormal && iScalingOff)
   475 		Mem::Copy(pixelPtr,aBuffer,aLength * 2);
   476 	else
   477 		{
   478 		const TInt pixelPtrInc = LogicalPixelAddressIncrement();
   479 		TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
   480 		TUint16* bufferPtrLimit = bufferPtr + aLength;
   481 		if (iScalingOff)
   482 			{
   483 			while (bufferPtr < bufferPtrLimit)
   484 				{
   485 				*pixelPtr = *bufferPtr++;
   486 				pixelPtr += pixelPtrInc;
   487 				}
   488 			}
   489 		else
   490 			{
   491 			const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
   492 			const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   493 			while(bufferPtr < bufferPtrLimit)
   494 				{
   495 				const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   496 				SetPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   497 				pixelPtr += pixelPtrInc;
   498 				IncScaledY(aY);
   499 				}
   500 			}
   501 		}
   502 	}
   503 
   504 void CDrawSixteenBppBitmapCommon::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   505 	{
   506 	TUint16* pixelPtr = PixelAddress(aX,aY);
   507 	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
   508 	TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
   509 	const TUint16* bufferPtrLimit = bufferPtr + aLength;
   510 	if (iScalingOff)
   511 		{
   512 		while (bufferPtr < bufferPtrLimit)
   513 			{
   514 			*pixelPtr ^= *bufferPtr++;
   515 			pixelPtr += pixelPtrInc;
   516 			}
   517 		}
   518 	else
   519 		{
   520 		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
   521 		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   522 		while(bufferPtr < bufferPtrLimit)
   523 			{
   524 			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   525 			XORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   526 			pixelPtr += pixelPtrInc;
   527 			IncScaledY(aY);
   528 			}
   529 		}
   530 	}
   531 
   532 void CDrawSixteenBppBitmapCommon::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   533 	{
   534 	TUint16* pixelPtr = PixelAddress(aX,aY);
   535 	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
   536 	TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
   537 	const TUint16* bufferPtrLimit = bufferPtr + aLength;
   538 	if (iScalingOff)
   539 		{
   540 		while (bufferPtr < bufferPtrLimit)
   541 			{
   542 			*pixelPtr &= *bufferPtr++;
   543 			pixelPtr += pixelPtrInc;
   544 			}
   545 		}
   546 	else
   547 		{
   548 		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
   549 		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   550 		while(bufferPtr < bufferPtrLimit)
   551 			{
   552 			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   553 			ANDPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   554 			pixelPtr += pixelPtrInc;
   555 			IncScaledY(aY);
   556 			}
   557 		}
   558 	}
   559 
   560 void CDrawSixteenBppBitmapCommon::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
   561 	{
   562 	TUint16* pixelPtr = PixelAddress(aX,aY);
   563 	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
   564 	TUint16* bufferPtr = REINTERPRET_CAST(TUint16*,aBuffer);
   565 	const TUint16* bufferPtrLimit = bufferPtr + aLength;
   566 	if (iScalingOff)
   567 		{
   568 		while (bufferPtr < bufferPtrLimit)
   569 			{
   570 			*pixelPtr |= *bufferPtr++;
   571 			pixelPtr += pixelPtrInc;
   572 			}
   573 		}
   574 	else
   575 		{
   576 		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
   577 		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   578 		while(bufferPtr < bufferPtrLimit)
   579 			{
   580 			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   581 			ORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd);
   582 			pixelPtr += pixelPtrInc;
   583 			IncScaledY(aY);
   584 			}
   585 		}
   586 	}
   587 
   588 /**
   589 Implementation for CFbsDrawDevice::GetInterface().
   590 Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
   591 @param aInterfaceId Interface identifier of the interface to be retrieved.
   592 @param aInterface Address of variable that retrieves the specified interface.
   593 @return KErrNone If the interface is supported, KErrNotSupported otherwise.
   594 */
   595 
   596 TInt CDrawSixteenBppBitmapCommon::GetInterface(TInt aInterfaceId, TAny*& aInterface)
   597 	{
   598 	aInterface = NULL;
   599 	TInt ret = KErrNotSupported;
   600 	
   601 	if (aInterfaceId == KFastBlit2InterfaceID)
   602 		{
   603 		aInterface = static_cast<MFastBlit2*>(this);
   604 		ret = KErrNone;
   605 		}
   606 	else 
   607 		return CDrawBitmap::GetInterface(aInterfaceId, aInterface);
   608 		
   609 	return ret;
   610 	}
   611 
   612 /**
   613 CDrawSixteenBppBitmapCommon::WriteBitmapBlock() implementation.
   614 @internalTechnology
   615 @see MFastBlit2::WriteBitmapBlock()
   616 */
   617 TInt CDrawSixteenBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest,
   618 									CFbsDrawDevice* aSrcDrawDevice,
   619 									const TRect& aSrcRect)
   620 	{
   621 	__ASSERT_DEBUG(aSrcDrawDevice && ((aSrcDrawDevice->DisplayMode()==EColor64K) || (aSrcDrawDevice->DisplayMode()==EColor4K)), Panic(EScreenDriverPanicInvalidParameter));
   622 	
   623 	TAny* interface=NULL;
   624 	TInt ret = aSrcDrawDevice->GetInterface(KFastBlit2InterfaceID, interface);
   625 	if (ret != KErrNone)
   626 		{
   627 		return KErrNotSupported;
   628 		}
   629 
   630 	TAny* interface1=NULL;
   631 	ret = aSrcDrawDevice->GetInterface(KScalingSettingsInterfaceID, interface1);
   632 	if(ret != KErrNone || (interface1 && !reinterpret_cast<MScalingSettings*>(interface1)->IsScalingOff()))
   633 		{
   634 		return KErrNotSupported;
   635 		}
   636 
   637 	ret = aSrcDrawDevice->GetInterface(KOrientationInterfaceID, interface1);
   638 	if(ret != KErrNone || (interface1 && reinterpret_cast<MDrawDeviceOrientation*>(interface1)->Orientation() != 0))
   639 		{
   640 		return KErrNotSupported;
   641 		}
   642 
   643 	ret = aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, interface1);
   644 	if(ret != KErrNone)
   645 		{
   646 		return KErrNotSupported;
   647 		}
   648 	
   649 	if(interface1)
   650 		{
   651 	 	TPoint pt;
   652 	 	reinterpret_cast<MDrawDeviceOrigin*>(interface1)->Get(pt);
   653 	 	if(pt.iX != 0 || pt.iY != 0)
   654 	 		{
   655 			return KErrNotSupported;
   656 	 		}
   657 		}
   658 
   659 	const TUint32* srcBase = reinterpret_cast<MFastBlit2*>(interface)->Bits();
   660 	__ASSERT_DEBUG(srcBase!=NULL, Panic(EScreenDriverPanicInvalidParameter));
   661 	TInt srcStride = aSrcDrawDevice->ScanLineBytes();  
   662 	__ASSERT_DEBUG((srcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter));  // stride is assumed to be a multiple of 4
   663 	TSize srcSize = aSrcDrawDevice->SizeInPixels();
   664 
   665 	return WriteBitmapBlock(aDest, srcBase, srcStride, srcSize, aSrcRect);
   666 	}
   667 
   668 								
   669 /**
   670 CDrawSixteenBppBitmapCommon::WriteBitmapBlock() implementation.
   671 @internalTechnology
   672 @see MFastBlit2::WriteBitmapBlock()
   673 */													
   674 TInt CDrawSixteenBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest,
   675 									const TUint32* aSrcBase,
   676 									TInt aSrcStride,
   677 									const TSize& aSrcSize,
   678 									const TRect& aSrcRect)
   679 	{
   680 	__ASSERT_DEBUG(aSrcBase, Panic(EScreenDriverPanicInvalidParameter));
   681 	__ASSERT_DEBUG((aSrcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter));
   682 	__ASSERT_DEBUG(iBits, Panic(EScreenDriverPanicInvalidPointer));
   683 
   684 	if (iShadowMode!=NULL ||
   685     	(iUserDispMode!=NULL && iUserDispMode!=iDispMode) ||
   686     	iOrientation!=EOrientationNormal ||
   687 		!IsScalingOff() ||
   688 		!iOriginIsZero)
   689 		{
   690 		return KErrNotSupported;
   691 		}
   692 	
   693 	__ASSERT_DEBUG(aSrcRect.iTl.iX >= 0, Panic(EScreenDriverPanicOutOfBounds)); 
   694 	__ASSERT_DEBUG(aSrcRect.iTl.iY >= 0, Panic(EScreenDriverPanicOutOfBounds));
   695 	__ASSERT_DEBUG(aSrcRect.iBr.iX <= aSrcSize.iWidth,  Panic(EScreenDriverPanicOutOfBounds));
   696 	__ASSERT_DEBUG(aSrcRect.iBr.iY <= aSrcSize.iHeight, Panic(EScreenDriverPanicOutOfBounds));
   697 	__ASSERT_DEBUG(aDest.iX >= 0, Panic(EScreenDriverPanicOutOfBounds));
   698 	__ASSERT_DEBUG(aDest.iY >= 0, Panic(EScreenDriverPanicOutOfBounds));
   699 	__ASSERT_DEBUG((aDest.iX + aSrcRect.Width())  <= SizeInPixels().iWidth,  Panic(EScreenDriverPanicOutOfBounds));
   700 	__ASSERT_DEBUG((aDest.iY + aSrcRect.Height()) <= SizeInPixels().iHeight, Panic(EScreenDriverPanicOutOfBounds));
   701 	
   702 	const TInt srcStride16 = aSrcStride     >> 1;
   703 	const TInt dstStride16 = iScanLineWords << 1;
   704 	
   705 	if (aSrcSize.iWidth == aSrcRect.Width() &&
   706 		aSrcSize.iWidth == SizeInPixels().iWidth &&
   707 		srcStride16 == dstStride16)
   708 		{
   709 		// Optimum case - one memcpy
   710 		__ASSERT_DEBUG(aSrcRect.iTl.iX==0 && aDest.iX==0, Panic(EScreenDriverPanicInvalidParameter));  // this is implied by the above conditions
   711 		const TUint32* srcPtr = aSrcBase + (iScanLineWords * aSrcRect.iTl.iY);
   712 		TUint32* dstPtr       = iBits    + (iScanLineWords * aDest.iY);
   713 		const TInt length = aSrcStride * aSrcRect.Height();
   714 		Mem::Move(dstPtr, srcPtr, length);
   715 		return KErrNone;
   716 		}
   717 		
   718 	// Sub-optimal case - one memcpy per line
   719 	const TUint16* srcPtr = (TUint16*)aSrcBase + (srcStride16 * aSrcRect.iTl.iY) + aSrcRect.iTl.iX;
   720 	TUint16* dstPtr       = (TUint16*)iBits    + (dstStride16 * aDest.iY       ) + aDest.iX;
   721 	const TInt length = aSrcRect.Width() << 1;
   722 	TInt lines = aSrcRect.Height();
   723 	while (lines--)
   724 		{
   725 		Mem::Copy(dstPtr, srcPtr, length);
   726 		srcPtr += srcStride16;
   727 		dstPtr += dstStride16;
   728 		}
   729 	return KErrNone;
   730 	}
   731 
   732 /**
   733 CDrawSixteenBppBitmapCommon::Bits() implementation.
   734 @internalTechnology
   735 @see MFastBlit2::Bits()
   736 */
   737 const TUint32* CDrawSixteenBppBitmapCommon::Bits() const
   738 	{
   739 	return iBits;
   740 	}
   741 
   742 // CDrawSixteenBppBitmap
   743 
   744 TInt CDrawSixteenBppBitmap::Construct(TSize aSize)
   745 	{
   746 	return Construct(aSize, ((aSize.iWidth + 1) & ~1) << 1);
   747 	}
   748 
   749 TInt CDrawSixteenBppBitmap::Construct(TSize aSize, TInt aStride)
   750 	{
   751 	iDispMode = EColor64K;
   752 	return CDrawSixteenBppBitmapCommon::Construct(aSize, aStride);
   753 	}
   754 
   755 void CDrawSixteenBppBitmap::Shadow(TRgb& aColor)
   756 	{
   757 	if (iShadowMode & EFade)
   758 		{
   759 #if defined(SYMBIAN_USE_FAST_FADING)
   760 		TUint16 color = aColor._Color64K();
   761 		TInt alpha = aColor.Alpha();
   762 		color = TUint16(((color >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
   763 		aColor = TRgb::_Color64K(color);
   764 		aColor.SetAlpha(alpha);
   765 #else
   766 		TRgb fadeColor = TRgb::_Color64K(aColor._Color64K());
   767 		fadeColor.SetAlpha(aColor.Alpha());
   768 		aColor = FadeRgb(fadeColor);
   769 #endif
   770 		}
   771 
   772 	if (iShadowMode & EShadow)
   773 		{
   774 		TRgb shadowColor = TRgb::_Color64K(ShadowIndex(TUint16(aColor._Color64K())));
   775 		shadowColor.SetAlpha(aColor.Alpha());
   776 		aColor = shadowColor;
   777 		}
   778 	}
   779 
   780 /**
   781 The overloaded function for Shadow(TRgb) which works directly with
   782 the Red, Green and Blue colour components to increase the performance.
   783 @param aRed Red component of colour.
   784 @param aGreen Green component of colour.
   785 @param aBlue Blue component of colour.
   786 */
   787 FORCEINLINE void CDrawSixteenBppBitmap::Shadow(TInt& aRed, TInt& aGreen, TInt& aBlue)
   788 	{
   789 	if (iShadowMode & EFade)
   790 		{
   791 #if defined(SYMBIAN_USE_FAST_FADING)
   792 		TUint16 color = PackColor64K(aRed, aGreen, aBlue);
   793 		color = TUint16(((color >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
   794 		UnpackColor64K(color, aRed, aGreen, aBlue);
   795 #else
   796 		FadeRgb(aRed, aGreen, aBlue);
   797 #endif
   798 		}
   799 
   800 	if (iShadowMode & EShadow)
   801 		{
   802 		ShadowIndex(aRed, aGreen, aBlue);
   803 		}
   804 	}
   805 
   806 /**
   807 The overloaded function for Shadow(TRgb) which works directly with
   808 16 bit colour instead of TRgb to increase the performance.
   809 @param a64KColor The 16 bit colour value.
   810 */
   811 FORCEINLINE void CDrawSixteenBppBitmap::Shadow(TUint16& a64KColor)
   812 	{
   813 	if (iShadowMode & EFade)
   814 		{
   815 #if defined(SYMBIAN_USE_FAST_FADING)
   816 		a64KColor = TUint16(((a64KColor >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
   817 #else
   818 		TRgb fadeColor = TRgb::_Color64K(a64KColor);
   819 		fadeColor.SetAlpha(0xFF);
   820 		a64KColor = FadeRgb(fadeColor)._Color64K();
   821 #endif
   822 		}
   823 	if (iShadowMode & EShadow)
   824 		{
   825 		a64KColor = ShadowIndex(a64KColor);
   826 		}
   827 	}
   828 
   829 TUint16 CDrawSixteenBppBitmap::ShadowIndex(TUint16 aColor64KIndex)
   830 	{
   831 	TInt red = (aColor64KIndex & 0xf800) >> 11;
   832 	TInt green = (aColor64KIndex & 0x07e0) >> 5;
   833 	TInt blue = aColor64KIndex & 0x001f;
   834 
   835 	red = Max(0,red-8);
   836 	green = Max(0,green-16);
   837 	blue = Max(0,blue-8);
   838 
   839 	return TUint16((red << 11) | (green << 5) | blue);
   840 	}
   841 
   842 /**
   843 The overloaded function for ShadowIndex(TUint16) which works directly with
   844 the Red, Green and Blue colour components to increase the performance.
   845 @param aRed Red component of colour.
   846 @param aGreen Green component of colour.
   847 @param aBlue Blue component of colour.
   848 */
   849 FORCEINLINE void CDrawSixteenBppBitmap::ShadowIndex(TInt& aRed, TInt& aGreen, TInt& aBlue)
   850 	{
   851 	aRed = Max(0,aRed-8);
   852 	aGreen = Max(0,aGreen-16);
   853 	aBlue = Max(0,aBlue-8);
   854 	}
   855 
   856 TUint16 CDrawSixteenBppBitmap::FadeIndex(TUint16 aColor64KIndex)
   857 	{
   858 #if defined(SYMBIAN_USE_FAST_FADING)
   859 	return TUint16(((aColor64KIndex >> K16bppFastFadeShift) & ~K16bppFastFadeMask) + K16bppFastFadeOffset);
   860 #else
   861 	return TUint16(FadeRgb(TRgb::_Color64K(aColor64KIndex))._Color64K());
   862 #endif
   863 	}
   864 
   865 TRgb CDrawSixteenBppBitmap::ReadRgbNormal(TInt aX,TInt aY) const
   866 	{
   867 	return TRgb::_Color64K(*PixelAddress(aX,aY));
   868 	}
   869 
   870 void CDrawSixteenBppBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor)
   871 	{
   872 	register TUint16* pixelAddr = PixelAddress(aX, aY);
   873 	register TUint16 aPixel = TUint16(aColor._Color64K());
   874 	
   875 	const TInt sourceAlpha = aColor.Alpha();	
   876 
   877 	if (sourceAlpha==0)
   878 		return;
   879 	
   880 	if (sourceAlpha<0xff)
   881 		{
   882 		const TUint32 srcInternal=aColor.Internal();
   883 		const TUint32 srcRB=srcInternal & 0x00FF00FF;
   884 		const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
   885 		aPixel = BlendTo16(srcRB, srcG, sourceAlpha, *pixelAddr);
   886 		}
   887 
   888 	if (iScalingOff)
   889 		{
   890 		*pixelAddr = aPixel;
   891 		}
   892 	else
   893 		{
   894 		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
   895 		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
   896 		const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
   897 		SetPixels(pixelAddr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd);
   898 		}
   899 	}
   900 
   901 void CDrawSixteenBppBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor)
   902 	{
   903 	const TInt sourceAlpha = aColor.Alpha();
   904 	if (sourceAlpha==255)
   905 		{
   906 		CDrawSixteenBppBitmapCommon::WriteBinary(aX,aY,aData,aLength,aHeight,(TUint16)aColor._Color64K());
   907 		return;
   908 		}
   909 	if (sourceAlpha==0)
   910 		return;
   911 
   912 	DeOrientate(aX,aY);
   913 
   914 	TInt pixelInc;
   915 	TInt rowInc;
   916 
   917 	switch(iOrientation)
   918 		{
   919 		case EOrientationNormal:
   920 			{
   921 			pixelInc = 1;
   922 			rowInc = iLongWidth;
   923 			break;
   924 			}
   925 		case EOrientationRotated90:
   926 			{
   927 			pixelInc = iLongWidth;
   928 			rowInc = -1;
   929 			break;
   930 			}
   931 		case EOrientationRotated180:
   932 			{
   933 			pixelInc = -1;
   934 			rowInc = -iLongWidth;
   935 			break;
   936 			}
   937 		default: // EOrientationRotated270
   938 			{
   939 			pixelInc = -iLongWidth;
   940 			rowInc = 1;
   941 			}
   942 		}
   943 
   944 	const TUint32* dataLimit = aData + aHeight;
   945 	const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0;
   946 
   947 	TUint16* pixelPtr = PixelAddress(aX,aY);
   948 
   949 	const TUint32 srcInternal=aColor.Internal();
   950 	const TUint32 srcRB=srcInternal & 0x00FF00FF;
   951 	const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
   952 	while (aData < dataLimit)
   953 		{
   954 		TUint32 dataWord = *aData++;
   955 		TUint32 dataMask = 1;
   956 		TUint16* tempPixelPtr = pixelPtr;
   957 
   958 		while (dataMask != dataMaskLimit)
   959 			{
   960 			if(dataWord & dataMask)
   961 				{
   962 				*tempPixelPtr = BlendTo16(srcRB, srcG, sourceAlpha, *tempPixelPtr);
   963 				}
   964 
   965 			tempPixelPtr += pixelInc;
   966 			dataMask <<= 1;
   967 			}
   968 
   969 		pixelPtr += rowInc;
   970 		}
   971 	}
   972 
   973 void CDrawSixteenBppBitmap::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength,TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
   974 	{
   975 	CDrawSixteenBppBitmapCommon::WriteBinaryOp(aX,aY,aData,aLength,aHeight,(TUint16)aColor._Color64K(),aDrawMode);
   976 	}
   977 
   978 void CDrawSixteenBppBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData,TInt aHeight,TRgb aColor,TBool aUp)
   979 	{
   980 	const TInt sourceAlpha = aColor.Alpha();
   981 	if (sourceAlpha==255)
   982 		{
   983 		CDrawSixteenBppBitmapCommon::WriteBinaryLineVertical(aX,aY,aData,aHeight,(TUint16)aColor._Color64K(),aUp);
   984 		return;
   985 		}
   986 	if (sourceAlpha==0)
   987 		return;
   988 
   989 	DeOrientate(aX,aY);
   990 
   991 	TInt scanlineByteLength;
   992 
   993 	switch(iOrientation)
   994 		{
   995 		case EOrientationNormal:
   996 			scanlineByteLength = iLongWidth;
   997 			break;
   998 		case EOrientationRotated90:
   999 			scanlineByteLength = -1;
  1000 			break;
  1001 		case EOrientationRotated180:
  1002 			scanlineByteLength = -iLongWidth;
  1003 			break;
  1004 		default:// EOrientationRotated270
  1005 			scanlineByteLength = 1;	
  1006 		}
  1007 
  1008 	if (aUp)
  1009 		scanlineByteLength = -scanlineByteLength;
  1010 
  1011 	TUint16* pixelPtr = PixelAddress(aX,aY);
  1012 	const TUint16* pixelPtrLimit = pixelPtr + (aHeight * scanlineByteLength);
  1013 	TUint32 dataWord = *aData;
  1014 	TUint32 dataMask = 1;
  1015 
  1016 	const TUint32 srcInternal=aColor.Internal();
  1017 	const TUint32 srcRB=srcInternal & 0x00FF00FF;
  1018 	const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
  1019 	while(pixelPtr != pixelPtrLimit)
  1020 		{
  1021 		if(!dataMask)
  1022 			{
  1023 			dataMask = 1;
  1024 			aData++;
  1025 			dataWord = *aData;
  1026 			}
  1027 
  1028 		if(dataWord & dataMask)
  1029 			{
  1030 			*pixelPtr = BlendTo16(srcRB, srcG, sourceAlpha, *pixelPtr);
  1031 			}
  1032 		dataMask <<= 1;
  1033 		pixelPtr += scanlineByteLength;
  1034 		}
  1035 	}
  1036 
  1037 /**
  1038 MAlphaBlend::WriteRgbAlphaLine2() implementation.
  1039 @see MAlphaBlend::WriteRgbAlphaLine2()
  1040 */
  1041 void CDrawSixteenBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
  1042                                               const TUint8* aRgbBuffer,
  1043                                               const TUint8* aMaskBuffer,
  1044                                               MAlphaBlend::TShadowing aShadowing,
  1045                                               CGraphicsContext::TDrawMode /*aDrawMode*/)
  1046     {
  1047 	DeOrientate(aX,aY);
  1048 	TUint16* pixelPtr = PixelAddress(aX,aY);
  1049 	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
  1050 	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
  1051 	TUint16 pixelColor;
  1052 
  1053 	__ASSERT_DEBUG( (((((TUint)pixelPtr)&1)==0) && ((((TUint)aRgbBuffer)&3)==0)), Panic(EScreenDriverPanicInvalidParameter));
  1054 
  1055 	if (iScalingOff)
  1056 		{
  1057 		if (!(iShadowMode & (EFade | EShadow)) && iUserDispMode == ENone)
  1058 			{
  1059 			TUint32* rgbBuffer32 = (TUint32*)aRgbBuffer;
  1060 			while (aMaskBuffer < maskBufferPtrLimit)
  1061 				{
  1062 				pixelPtr[0] = Blend32To16(rgbBuffer32[0], aMaskBuffer[0], pixelPtr[0]);
  1063 				pixelPtr += pixelPtrInc;
  1064 				rgbBuffer32 ++;
  1065 				aMaskBuffer++;
  1066 				}
  1067 			}
  1068 		else
  1069 			{
  1070 			while (aMaskBuffer < maskBufferPtrLimit)
  1071 				{
  1072 				TInt blue = aRgbBuffer[0];
  1073 				TInt green = aRgbBuffer[1];
  1074 				TInt red = aRgbBuffer[2];
  1075 				if(aShadowing == MAlphaBlend::EShdwBefore)
  1076 					{
  1077 					Shadow(red,green,blue);
  1078 					}
  1079 				pixelColor = ::AlphaBlend(red,green,blue, pixelPtr[0],aMaskBuffer[0]);
  1080 				if(aShadowing == MAlphaBlend::EShdwAfter)
  1081 					{
  1082 					Shadow(pixelColor);
  1083 					}
  1084 				MapColorToUserDisplayMode(pixelColor);
  1085 				pixelPtr[0] = pixelColor;
  1086 
  1087 				pixelPtr += pixelPtrInc;
  1088 				aRgbBuffer += 4;
  1089 				aMaskBuffer++;
  1090 				}
  1091 			}
  1092 		}
  1093 	else
  1094 		{
  1095 		const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
  1096 		const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
  1097 		while (aMaskBuffer < maskBufferPtrLimit)
  1098 			{
  1099 			TInt blue = aRgbBuffer[0];
  1100 			TInt green = aRgbBuffer[1];
  1101 			TInt red = aRgbBuffer[2];
  1102             if(aShadowing == MAlphaBlend::EShdwBefore)
  1103                 {
  1104                 Shadow(red,green,blue);
  1105                 }
  1106             pixelColor = ::AlphaBlend(red,green,blue,pixelPtr[0],aMaskBuffer[0]);
  1107             if(aShadowing == MAlphaBlend::EShdwAfter)
  1108                 {
  1109 		        Shadow(pixelColor);
  1110                 }
  1111 			MapColorToUserDisplayMode(pixelColor);
  1112 			const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
  1113 			SetPixels(pixelPtr, pixelColor, pixelRowPtrLimit, bitsStart, bitsEnd);
  1114 			pixelPtr += pixelPtrInc;
  1115 			aRgbBuffer += 4;
  1116 			aMaskBuffer++;
  1117 			IncScaledY(aY);
  1118 			}
  1119 		}
  1120 	}
  1121 
  1122 void CDrawSixteenBppBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
  1123 	{
  1124 	CDrawSixteenBppBitmapCommon::WriteRgbMulti(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
  1125 	}
  1126 
  1127 void CDrawSixteenBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
  1128 	{
  1129 	const TInt sourceAlpha = aColor.Alpha();
  1130 	if (sourceAlpha==255)// opaque
  1131 		{
  1132 		CDrawSixteenBppBitmapCommon::WriteRgbMulti(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
  1133 		return;
  1134 		}
  1135 	if (sourceAlpha==0)// transparent
  1136 		return;
  1137 
  1138 	const TInt sourceRed = aColor.Red();
  1139 	const TInt sourceGreen = aColor.Green();
  1140 	const TInt sourceBlue = aColor.Blue();
  1141 
  1142 	const TInt longWidth = iLongWidth;
  1143 	TUint16* pixelPtr = PixelAddress(aX,aY);
  1144 	TUint16* pixelPtrLimit = pixelPtr + aLength;
  1145 	const TUint16* pixelRowPtrLimit = pixelPtr + (aHeight * longWidth);
  1146 	const TInt mask=aColor.Alpha();
  1147 	const TUint32 srcInternal=aColor.Internal();
  1148 	const TUint32 srcRB=srcInternal & 0x00FF00FF;
  1149 	const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
  1150 	while (pixelPtr < pixelRowPtrLimit)
  1151 		{
  1152 		for (TUint16* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
  1153 			{
  1154 			*tempPixelPtr = BlendTo16(srcRB, srcG, mask, *tempPixelPtr);
  1155 			}
  1156 		pixelPtr += longWidth;
  1157 		pixelPtrLimit += longWidth;
  1158 		}
  1159 	}
  1160 
  1161 void CDrawSixteenBppBitmap::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
  1162 	{
  1163 	CDrawSixteenBppBitmapCommon::WriteRgbMultiXOR(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
  1164 	}
  1165 
  1166 void CDrawSixteenBppBitmap::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
  1167 	{
  1168 	CDrawSixteenBppBitmapCommon::WriteRgbMultiAND(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
  1169 	}
  1170 
  1171 void CDrawSixteenBppBitmap::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
  1172 	{
  1173 	CDrawSixteenBppBitmapCommon::WriteRgbMultiOR(aX,aY,aLength,aHeight,(TUint16)aColor._Color64K());
  1174 	}
  1175 
  1176 void CDrawSixteenBppBitmap::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer)
  1177 	{
  1178 	const TInt alpha = aColor.Alpha();
  1179 	if (alpha==0 || aLength<=0)
  1180 		return;
  1181 	DeOrientate(aX,aY);
  1182 	TUint16* pixelPtr = PixelAddress(aX,aY);
  1183 	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
  1184 	const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
  1185 
  1186  	if (iShadowMode)
  1187  		{
  1188  		Shadow(aColor);
  1189  		}
  1190  
  1191 	if (iScalingOff)
  1192 		{
  1193 	    const TUint32 color16bpp=aColor.Color64K();
  1194 		const TUint32 srcInternal=aColor.Internal();
  1195 		const TUint32 srcRB=srcInternal & 0x00FF00FF;
  1196 		const TUint32 srcG=(srcInternal & 0xFF00) >> 8;
  1197 		if (alpha == 0xff)
  1198 			{
  1199 			while (aMaskBuffer < maskBufferPtrLimit)
  1200 				{
  1201 				const TUint32 mask=*aMaskBuffer++;
  1202 				if (mask)
  1203 					{
  1204 					if (mask==0xFF)
  1205 						*pixelPtr = color16bpp;
  1206 					else
  1207 						*pixelPtr = BlendTo16(srcRB, srcG, mask, *pixelPtr);
  1208 					}
  1209 				pixelPtr += pixelPtrInc;
  1210 				}
  1211 			}
  1212 		else
  1213 			{ // pen is semi-transparent, so we must blend using both the mask and pen alpha
  1214 			while (aMaskBuffer < maskBufferPtrLimit)
  1215 				{
  1216 				TUint blendAlpha = alpha;
  1217 				TUint maskAlpha = *aMaskBuffer++;
  1218 				if (maskAlpha)
  1219 					{
  1220 					if (maskAlpha!=0xFF)
  1221 						blendAlpha=((maskAlpha+1) * alpha)>>8;
  1222 					*pixelPtr = BlendTo16(srcRB, srcG, blendAlpha, *pixelPtr);
  1223 					}
  1224 				pixelPtr += pixelPtrInc;
  1225 				}
  1226 			}
  1227 		}
  1228 	else
  1229 		{
  1230 		const TInt red = aColor.Red();
  1231 		const TInt green = aColor.Green();
  1232 		const TInt blue = aColor.Blue();
  1233 		if (alpha == 0xff)
  1234 			{
  1235 			const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
  1236 			const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
  1237 			while(aMaskBuffer < maskBufferPtrLimit)
  1238 				{
  1239 				TUint16 pixelColor = AlphaBlend(red,green,blue, *pixelPtr, *aMaskBuffer);
  1240 				const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
  1241 				SetPixels(pixelPtr, pixelColor, pixelRowPtrLimit, bitsStart, bitsEnd);
  1242 				pixelPtr += pixelPtrInc;
  1243 				aMaskBuffer++;
  1244 				IncScaledY(aY);
  1245 				}
  1246 			}
  1247 		else
  1248 			{ // require special handling for different alpha values
  1249 			const TUint16* bitsStart = reinterpret_cast <const TUint16*> (iBits);
  1250 			const TUint16* bitsEnd = bitsStart + iLongWidth * iSize.iHeight;
  1251 			while(aMaskBuffer < maskBufferPtrLimit)
  1252 				{
  1253 				const TInt maskAlpha = *aMaskBuffer;
  1254 				const TInt sourceAlpha = alpha * maskAlpha;
  1255 				const TInt inverseAlpha = 255*255 - sourceAlpha;
  1256 
  1257 				TInt pixelRed;
  1258 				TInt pixelGreen;
  1259 				TInt pixelBlue;
  1260 				UnpackColor64K(*pixelPtr, pixelRed, pixelGreen, pixelBlue);
  1261 				TInt blueAfter = TUint8(((blue * sourceAlpha) + (pixelBlue * inverseAlpha)) / (255*255));
  1262 				TInt greenAfter = TUint8(((green * sourceAlpha) + (pixelGreen * inverseAlpha)) / (255*255));
  1263 				TInt redAfter = TUint8(((red * sourceAlpha) + (pixelRed * inverseAlpha)) / (255*255));
  1264 				TUint16 pixelColor = PackColor64K(redAfter, greenAfter, blueAfter);
  1265 
  1266 				const TUint16* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth;
  1267 				SetPixels(pixelPtr, pixelColor, pixelRowPtrLimit, bitsStart, bitsEnd);
  1268 				pixelPtr += pixelPtrInc;
  1269 				aMaskBuffer++;
  1270 				IncScaledY(aY);
  1271 				}
  1272 			}
  1273 		}
  1274 	}
  1275 
  1276 void CDrawSixteenBppBitmap::MapColorToUserDisplayMode(TRgb& aColor)
  1277 	{
  1278 	switch (iUserDispMode)
  1279 		{
  1280 	case EGray2:
  1281 		aColor = TRgb::_Gray2(aColor._Gray2());
  1282 		break;
  1283 	case EGray4:
  1284 		aColor = TRgb::_Gray4(aColor._Gray4());
  1285 		break;
  1286 	case EGray16:
  1287 		aColor = TRgb::_Gray16(aColor._Gray16());
  1288 		break;
  1289 	case EGray256:
  1290 		aColor = TRgb::_Gray256(aColor._Gray256());
  1291 		break;
  1292 	case EColor16:
  1293 		aColor = TRgb::Color16(aColor.Color16());
  1294 		break;
  1295 	case EColor256:
  1296 		aColor = TRgb::Color256(aColor.Color256());
  1297 		break;
  1298 	case EColor4K:
  1299 		aColor = TRgb::_Color4K(aColor._Color4K());
  1300 		break;
  1301 	default:
  1302 		break;
  1303 		}
  1304 	}
  1305 
  1306 /**
  1307 The overloaded function for MapColorToUserDisplayMode(TRgb) which works directly with
  1308 16 bit colour instead of TRgb to increase the performance.
  1309 @param a64KColor The 16 bit colour value.
  1310 */
  1311 void CDrawSixteenBppBitmap::MapColorToUserDisplayMode(TUint16& aColor64K)
  1312 	{
  1313 	TRgb color = TRgb::_Color64K(aColor64K);
  1314 
  1315 	switch (iUserDispMode)
  1316 		{
  1317 	case EGray2:
  1318 		{
  1319 		color = TRgb::_Gray2(color._Gray2());
  1320 		}
  1321 		break;
  1322 	case EGray4:
  1323 		{
  1324 		color = TRgb::_Gray4(color._Gray4());
  1325 		}
  1326 		break;
  1327 	case EGray16:
  1328 		{
  1329 		color = TRgb::_Gray16(color._Gray16());
  1330 		}
  1331 		break;
  1332 	case EGray256:
  1333 		{
  1334 		color = TRgb::_Gray256(color._Gray256());
  1335 		}
  1336 		break;
  1337 	case EColor16:
  1338 		{
  1339 		color = TRgb::Color16(color.Color16());
  1340 		}
  1341 		break;
  1342 	case EColor256:
  1343 		{
  1344 		color = TRgb::Color256(color.Color256());
  1345 		}
  1346 		break;
  1347 	case EColor4K:
  1348 		{
  1349 		color = TRgb::_Color4K(color._Color4K());
  1350 		}
  1351 		break;
  1352 	default:
  1353 		break;
  1354 		}
  1355 	aColor64K = color._Color64K();
  1356 	}
  1357 
  1358 void CDrawSixteenBppBitmap::MapBufferToUserDisplayMode(TInt aLength,TUint32* aBuffer)
  1359 	{
  1360 	TUint16* bufferPtr = (TUint16*)aBuffer;
  1361 	const TUint16* bufferLimit = bufferPtr + aLength;
  1362 	TRgb color;
  1363 	
  1364 	switch (iUserDispMode)
  1365 		{
  1366 	case EGray2:
  1367 		while (bufferPtr < bufferLimit)
  1368 			{
  1369 			color = TRgb::_Color64K(*bufferPtr);
  1370 			color = TRgb::_Gray2(color._Gray2());
  1371 			*bufferPtr++ = TUint16(color._Color64K());
  1372 			}
  1373 		break;
  1374 	case EGray4:
  1375 		while (bufferPtr < bufferLimit)
  1376 			{
  1377 			color = TRgb::_Color64K(*bufferPtr);
  1378 			color = TRgb::_Gray4(color._Gray4());
  1379 			*bufferPtr++ = TUint16(color._Color64K());
  1380 			}
  1381 		break;
  1382 	case EGray16:
  1383 		while (bufferPtr < bufferLimit)
  1384 			{
  1385 			color = TRgb::_Color64K(*bufferPtr);
  1386 			color = TRgb::_Gray16(color._Gray16());
  1387 			*bufferPtr++ = TUint16(color._Color64K());
  1388 			}
  1389 		break;
  1390 	case EGray256:
  1391 		while (bufferPtr < bufferLimit)
  1392 			{
  1393 			color = TRgb::_Color64K(*bufferPtr);
  1394 			color = TRgb::_Gray256(color._Gray256());
  1395 			*bufferPtr++ = TUint16(color._Color64K());
  1396 			}
  1397 		break;
  1398 	case EColor16:
  1399 		while (bufferPtr < bufferLimit)
  1400 			{
  1401 			color = TRgb::_Color64K(*bufferPtr);
  1402 			color = TRgb::Color16(color.Color16());
  1403 			*bufferPtr++ = TUint16(color._Color64K());
  1404 			}
  1405 		break;
  1406 	case EColor256:
  1407 		while (bufferPtr < bufferLimit)
  1408 			{
  1409 			color = TRgb::_Color64K(*bufferPtr);
  1410 			color = TRgb::Color256(color.Color256());
  1411 			*bufferPtr++ = TUint16(color._Color64K());
  1412 			}
  1413 		break;
  1414 	case EColor4K:
  1415 		while (bufferPtr < bufferLimit)
  1416 			{
  1417 			color = TRgb::_Color64K(*bufferPtr);
  1418 			color = TRgb::_Color4K(color._Color4K());
  1419 			*bufferPtr++ = TUint16(color._Color64K());
  1420 			}
  1421 		break;
  1422 	default:
  1423 		break;
  1424 		}
  1425 	}
  1426 
  1427 TInt CDrawSixteenBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength, 
  1428 													TUint32 aOutlinePenColor, TUint32 aShadowColor,
  1429 													TUint32 aFillColor, const TUint8* aDataBuffer)
  1430 	{
  1431 	DeOrientate(aX,aY);
  1432 	TUint16* pixelPtr = PixelAddress(aX,aY);
  1433 	const TInt pixelPtrInc = LogicalPixelAddressIncrement();
  1434 	const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;	
  1435 	TInt blendedRedColor;
  1436 	TInt blendedGreenColor;
  1437 	TInt blendedBlueColor;
  1438 	TUint blendedAlpha;
  1439 	TUint32 finalColor;
  1440 	const TUint16* normTable = PtrTo16BitNormalisationTable();
  1441 
  1442 	//Get red color. Equivalent to TRgb::Red()
  1443 	const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16;
  1444 	const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16;
  1445 	const TInt redFillColor = (aFillColor & 0xff0000) >> 16;
  1446 
  1447 	//Get green color. Equivalent to TRgb::Green()
  1448 	const TInt greenOutlinePenColor = (aOutlinePenColor & 0xff00) >> 8;
  1449 	const TInt greenShadowColor = (aShadowColor & 0xff00) >> 8;
  1450 	const TInt greenFillColor = (aFillColor & 0xff00) >> 8;
  1451 
  1452 	//Get blue color. Equivalent to TRgb::Blue()
  1453 	const TInt blueOutlinePenColor = aOutlinePenColor & 0xff;
  1454 	const TInt blueShadowColor = aShadowColor & 0xff;
  1455 	const TInt blueFillColor = aFillColor & 0xff;
  1456 
  1457 	//Get alpha color. Equivalent to TRgb::Alpha()
  1458 	const TUint alphaOutlinePenColor = aOutlinePenColor >> 24;
  1459 	const TUint alphaShadowColor = aShadowColor >> 24;
  1460 	const TUint alphaFillColor = aFillColor >> 24;
  1461 
  1462 	while (aDataBuffer < dataBufferPtrLimit)
  1463 		{
  1464 		TUint8 index = *aDataBuffer++;
  1465 		if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
  1466 			{
  1467 			//background colour
  1468 			//No drawing required
  1469 			}
  1470 		else if (255 == FourColorBlendLookup[index][KFillColorIndex])
  1471 			{
  1472 			//Use fill colour to draw
  1473 			finalColor = aFillColor;
  1474 			*pixelPtr = Blend32To16((finalColor | 0xff000000), alphaFillColor, *pixelPtr);
  1475 			}
  1476 		else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
  1477 			{
  1478 			//Use shadow colour to draw
  1479 			finalColor = aShadowColor;
  1480 			*pixelPtr = Blend32To16((finalColor | 0xff000000), alphaShadowColor, *pixelPtr);
  1481 			}
  1482 		else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
  1483 			{
  1484 			//Use outline colour to draw
  1485 			finalColor = aOutlinePenColor; 
  1486 			*pixelPtr = Blend32To16((finalColor | 0xff000000), alphaOutlinePenColor, *pixelPtr);
  1487 			}
  1488 		else
  1489 			{
  1490 			//Get the background pixel colour. Using the lookup table to convert 16 to 32 bit colour
  1491 			blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor + 
  1492 								redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
  1493 								redFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
  1494 	
  1495 			blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor  + 
  1496 								greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
  1497 								greenFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
  1498 	
  1499 			blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor  + 
  1500 								blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
  1501 								blueFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
  1502 	
  1503 			blendedAlpha = (alphaOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + 
  1504 							alphaShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
  1505 							alphaFillColor * FourColorBlendLookup[index][KFillColorIndex]) >> 8;
  1506 
  1507 			finalColor = PMA2NonPMAPixel((blendedAlpha << 24) | (blendedRedColor << 16) | (blendedGreenColor << 8) | blendedBlueColor, normTable);		
  1508 			*pixelPtr = Blend32To16((finalColor | 0xff000000), blendedAlpha, *pixelPtr);
  1509 			}
  1510 		pixelPtr += pixelPtrInc;
  1511 		}
  1512 	return KErrNone;
  1513 	}