--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/screendriver/sbit/BMDRAW24U.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1284 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "BMDRAW.H"
+#include "BitDrawInterfaceId.h"
+#include <graphics/lookuptable.h>
+
+TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize)
+ {
+ return Construct(aSize, aSize.iWidth << 2);
+ }
+
+TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize, TInt aStride)
+ {
+ iDispMode = EColor16MU;
+ return CDrawThirtyTwoBppBitmapCommon::Construct(aSize, aStride);
+ }
+
+/**
+MAlphaBlend::WriteRgbAlphaLine() implementation.
+@see MAlphaBlend::WriteRgbAlphaLine()
+*/
+void CDrawUTwentyFourBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
+ const TUint8* aRgbBuffer,
+ const TUint8* aMaskBuffer,
+ MAlphaBlend::TShadowing aShadowing,
+ CGraphicsContext::TDrawMode /*aDrawMode*/)
+ {
+ // precondition for this function is that the aRgbBuffer lies on a word boundary
+ // Assert checks that the pointer is at a word boundary
+ __ASSERT_DEBUG(!(((TUint)aRgbBuffer) & 0x3), Panic(EScreenDriverPanicInvalidPointer));
+
+ DeOrientate(aX,aY);
+ TUint32* pixelPtr = PixelAddress(aX,aY);
+ TUint32* rgbBuffer = (TUint32*)aRgbBuffer;
+ const TInt pixelPtrInc = PixelAddressIncrement();
+ const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
+
+ if (!(iShadowMode & (EFade | EShadow)) && (iUserDispMode == ENone))
+ {
+ while (aMaskBuffer < maskBufferPtrLimit)
+ {
+ *pixelPtr = CalcAlphaPixel(*rgbBuffer, *aMaskBuffer, *pixelPtr);
+ aMaskBuffer++;
+ pixelPtr += pixelPtrInc;
+ rgbBuffer++;
+ }
+ }
+ else
+ {
+ while (aMaskBuffer < maskBufferPtrLimit)
+ {
+ TInt mask = *aMaskBuffer++;
+ if (mask)
+ {
+ TInt b = aRgbBuffer[0];
+ TInt g = aRgbBuffer[1];
+ TInt r = aRgbBuffer[2];
+ if(aShadowing == MAlphaBlend::EShdwBefore)
+ {
+ if (iShadowMode & EFade)
+ {
+ r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ }
+ if (iShadowMode & EShadow)
+ {
+ r = (Max(0,r-0x40));
+ g = (Max(0,g-0x40));
+ b = (Max(0,b-0x40));
+ }
+ }
+ if (mask != 0xff)
+ {
+ // (mask * r + (255 - mask) * value) / 255 =
+ // ((257 * mask * (r - value)) >> 16) + value
+ TInt value = *pixelPtr & 0xffffff;
+ mask = (mask << 8) + mask; // mask = mask * 257
+ TInt v = value >> 16;
+ r = ((mask * (r - v)) >> 16) + v;
+ v = (value >> 8) & 0xff;
+ g = ((mask * (g - v)) >> 16) + v;
+ v = value & 0xff;
+ b = ((mask * (b - v)) >> 16) + v;
+ }
+ if(aShadowing == MAlphaBlend::EShdwAfter)
+ {
+ if (iShadowMode & EFade)
+ {
+ r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ }
+ if (iShadowMode & EShadow)
+ {
+ r = (Max(0,r-0x40));
+ g = (Max(0,g-0x40));
+ b = (Max(0,b-0x40));
+ }
+ }
+ // Convert colour if an incompatible UserDisplayMode is being used
+ CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
+ *pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
+ }
+ aRgbBuffer += 4;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+ }
+
+void CDrawUTwentyFourBppBitmap::ReadLine(TInt aX, TInt aY, TInt aLength, TAny* aBuffer, TDisplayMode aDispMode) const
+ {
+ if (aDispMode == EColor16MAP)
+ {
+ DeOrientate(aX, aY);
+ CDrawThirtyTwoBppBitmapCommon::ReadLine(aX, aY, aLength, aBuffer);
+
+ //Overwrite unused byte with 0xff to produce valid 16MAP data
+ TUint8* alphaptr = (TUint8*) aBuffer+3;
+ TUint8* bufEnd = (TUint8*) aBuffer + (aLength << 2);
+ while (alphaptr < bufEnd)
+ {
+ *alphaptr = 0xff;
+ alphaptr+=4;
+ }
+
+ return;
+ }
+ CDrawBitmap::ReadLine(aX, aY, aLength, aBuffer, aDispMode);
+ }
+
+void CDrawUTwentyFourBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
+ {
+ const TInt sourceAlpha = aColor.Alpha();
+ if (sourceAlpha==255)// opaque
+ {
+ WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
+ return;
+ }
+ if (sourceAlpha==0)// transparent
+ return;
+
+ TUint32* pixelPtr = PixelAddress(aX,aY);
+ TUint32* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineWords);
+ TUint32* pixelPtrLimit = pixelPtr + aLength;
+
+ const TUint32 sourceInternal=aColor.Internal();
+ const TUint32 s_rb = sourceInternal & 0x00FF00FF;
+ const TUint32 s_g = (sourceInternal & 0xFF00) >> 8;
+ const TUint32 mask2 = sourceAlpha | (sourceAlpha << 16);
+ while (pixelPtr < pixelRowPtrLimit)
+ {
+ for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
+ {
+ const TUint32 d = *tempPixelPtr;
+ const TUint32 d_rb = d & 0x00FF00FF;
+ const TUint32 rb = ((((sourceAlpha * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
+
+ const TInt d_g = (d & 0xFF00) >> 8;
+ const TInt g = ((sourceAlpha * (s_g - d_g)) >> 8) + d_g;
+
+ *tempPixelPtr = rb | (g<<8) | 0xff000000;
+ }
+
+ pixelPtr += iScanLineWords;
+ pixelPtrLimit += iScanLineWords;
+ }
+ }
+
+void CDrawUTwentyFourBppBitmap::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
+ {
+ TUint32* pixelPtr = PixelAddress(aX,aY);
+
+ const TUint32* bufferPtrLimit = aBuffer + aLength;
+ const TInt pixelPtrInc = (iOrientation == EOrientationNormal) ? 1 : PixelAddressIncrement();
+
+ while (aBuffer < bufferPtrLimit)
+ {
+ if((*aBuffer &0xFF000000) == 0xFF000000)
+ {
+ *pixelPtr = *aBuffer;
+ }
+ else if((*aBuffer & 0xFF000000))
+ {
+ // specialization of pre-multiplied blending when the destination alpha is always 255
+ const TUint32 src_rb = *aBuffer & 0x00FF00FF;
+ const TUint32 src_g = *aBuffer & 0x0000FF00;
+ const TUint32 mask = 0x100 - (*aBuffer >> 24);
+ TUint32 dst_rb = *pixelPtr & 0x00FF00FF;
+ TUint32 dst_g = *pixelPtr & 0x0000FF00;
+ dst_rb = (src_rb + ((mask * dst_rb) >> 8)) & 0x00FF00FF;
+ dst_g = (src_g + ((mask * dst_g) >> 8)) & 0x0000FF00;
+ *pixelPtr = 0xFF000000 | dst_rb | dst_g;
+ }
+
+ aBuffer++;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+
+TRgb CDrawUTwentyFourBppBitmap::RgbColor(TUint32 aColor) const
+ {
+ return TRgb::_Color16MU(aColor);
+ }
+
+TUint32 CDrawUTwentyFourBppBitmap::Color(const TRgb& aColor)
+ {
+ return aColor._Color16MA() | 0xff000000;
+ }
+
+
+// Copies an EColor64K pixel to an EColor16MU screen
+FORCEINLINE static void CopyPixel(const TUint16*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
+ {
+ *aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
+ aDestPtr += aPixelPtrInc;
+ aSrcPtr++;
+ }
+
+
+// Copies two EColor64K pixels to an EColor16MU screen
+FORCEINLINE static void CopyTwoPixels(const TUint32*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
+ {
+ const TUint16* scanPtr = reinterpret_cast<const TUint16*&>(aSrcPtr);
+ *aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
+ aDestPtr += aPixelPtrInc;
+ scanPtr++;
+ *aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
+ aDestPtr += aPixelPtrInc;
+ aSrcPtr++;
+ }
+
+
+// Copies an EColor16MU pixel to an EColor16MU screen if necessary.
+FORCEINLINE static void ProcessMaskPixel(const TUint32*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
+ {
+ if (aMaskWord & aSingleBitMask)
+ {
+ *aDestPtr = *aSrcPtr;
+ }
+ aSrcPtr++;
+ aDestPtr += aPixelPtrInc;
+ aSingleBitMask <<= 1;
+ }
+
+
+// Copies an EColor64K pixel to an EColor16MU screen if necessary.
+FORCEINLINE static void ProcessMaskPixel(const TUint16*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
+ {
+ if (aMaskWord & aSingleBitMask)
+ {
+ *aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
+ }
+ aSrcPtr++;
+ aDestPtr += aPixelPtrInc;
+ aSingleBitMask <<= 1;
+ }
+
+
+// Alpha-blends an EColor16MU pixel to an EColor16MU screen using a fixed mask value.
+FORCEINLINE static void BlendAlphaPixel(const TUint32*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
+ {
+ const TUint32 s = *aSrcPtr++;
+ const TUint32 d = *aDestPtr;
+
+ // (a) (mask * src + (255 - mask) * dest) / 255 This ideal formula
+ // (b) ((mask * (src - dest)) >> 8) + dest A faster approximation to (a)
+ // (c) ((mask * (256 + src - dest) >> 8) + dest - mask Equivalent to (b) but can be used on multiple colors at a time
+
+ const TUint32 s_rb = s & 0x00FF00FF;
+ const TUint32 d_rb = d & 0x00FF00FF;
+ const TUint32 mask2 = aMask | (aMask << 16);
+ const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
+
+ const TInt s_g = (s & 0xFF00) >> 8;
+ const TInt d_g = (d & 0xFF00) >> 8;
+ const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
+
+ *aDestPtr = rb | (g<<8) | 0xff000000;
+ aDestPtr += aPixelPtrInc;
+ }
+
+
+// Alpha-blends an EColor16MU pixel to an EColor16MU screen if necessary.
+FORCEINLINE static void ProcessAlphaPixel(const TUint32*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc)
+ {
+ const TInt mask = *aMaskPtr++;
+
+ if (!mask)
+ {
+ // pixel is masked
+ aSrcPtr++;
+ aDestPtr += aPixelPtrInc;
+ }
+ else if (mask == 0xFF)
+ {
+ // pixel is unmasked
+ *aDestPtr = *aSrcPtr++;
+ aDestPtr += aPixelPtrInc;
+ }
+ else
+ {
+ BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
+ }
+ }
+
+
+// Alpha-blends an EColor64K pixel to an EColor16MU screen using a fixed mask value.
+FORCEINLINE static void BlendAlphaPixel(const TUint16*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
+ {
+ const TUint32 s = *aSrcPtr++;
+ const TUint32 d = *aDestPtr;
+
+ // convert the source EColor64K red / blue pixels to EColor16MU
+ // the top two bits in EColor64K are used to fill the bottom two bits in EColor16MU
+
+ const TUint32 s_rb = ((s & 0xF800) << 8) | ((s & 0xE000) << 3) | ((s & 0x1F) << 3) | ((s & 0x1C) >>2);
+ const TUint32 d_rb = d & 0x00FF00FF;
+ const TUint32 mask2 = aMask | (aMask << 16);
+ const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
+
+ // convert the source EColor64K green pixel to EColor16MU
+ const TInt s_g = ((s & 0x07E0) >> 3) | ((s & 0x0600) >> 9);
+ const TInt d_g = (d & 0xFF00) >> 8;
+ const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
+
+ *aDestPtr = rb | (g<<8) | 0xff000000;
+ aDestPtr += aPixelPtrInc;
+ }
+
+
+// Alpha-blends an EColor64K pixel to an EColor16MU screen if necessary.
+FORCEINLINE static void ProcessAlphaPixel(const TUint16*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
+ {
+ const TInt mask = *aMaskPtr++;
+
+ if (!mask)
+ {
+ // pixel is masked
+ aSrcPtr++;
+ aDestPtr += aPixelPtrInc;
+ }
+ else if (mask == 0xFF)
+ {
+ // pixel is unmasked
+ CopyPixel(aSrcPtr, aDestPtr, aPixelPtrInc, aHighAdd, aLowAdd);
+ }
+ else
+ {
+ BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
+ }
+ }
+
+
+/**
+CDrawUTwentyFourBppBitmap::WriteAlphaLineEx() implementation.
+@internalTechnology
+@see MFastBlit::WriteAlphaLineEx()
+*/
+void CDrawUTwentyFourBppBitmap::WriteAlphaLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
+ const TUint32* aSrcPtr, TDisplayMode aSrcFormat,
+ TInt aMaskX, const TUint32* aMaskPtr,
+ MAlphaBlend::TShadowing aShadowing)
+ {
+ // Only certain pixel formats are supported. Caller should check this.
+ __ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
+
+ DeOrientate(aX,aY);
+ TUint32* pixelPtr = PixelAddress(aX,aY);
+ const TInt pixelPtrInc = PixelAddressIncrement();
+
+ if (aSrcFormat==EColor16MU)
+ {
+ if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)) )
+ {
+ aSrcPtr += aSrcX;
+ const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
+ const TInt startBit = aMaskX & 0x3;
+
+ if (startBit)
+ {
+ // Process initial incomplete mask word
+ const TUint32 maskWord = *maskWordPtr++;
+ TInt numPix = Min(aLength, 4 - startBit); // number of pixels to process from the first word of the mask
+ aLength -= numPix;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip the pixels
+ aSrcPtr += numPix;
+ pixelPtr += pixelPtrInc * numPix;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy the pixels
+ while (numPix--)
+ {
+ *pixelPtr = *aSrcPtr++;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+ else
+ {
+ // At least one of the pixels needs to be blended
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
+ maskPtr8 += startBit;
+ while (numPix--)
+ {
+ ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
+ }
+ }
+ }
+
+ TInt numMaskWords = aLength >> 2;
+ aLength &= 0x3;
+ while (numMaskWords--)
+ {
+ // Process a complete mask word - 4 pixels
+ const TUint32 maskWord = *maskWordPtr++;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip 4 pixels
+ aSrcPtr += 4;
+ pixelPtr += pixelPtrInc << 2;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy 4 pixels
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ }
+ else
+ {
+ // At least one of the 4 pixels needs to be blended
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
+
+ if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
+ maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
+ maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
+ maskPtr8[3] && (maskPtr8[3] != 0xFF))
+ {
+ // Blend all 4 pixels inline
+ BlendAlphaPixel(aSrcPtr, maskPtr8[0], pixelPtr, pixelPtrInc);
+ BlendAlphaPixel(aSrcPtr, maskPtr8[1], pixelPtr, pixelPtrInc);
+ BlendAlphaPixel(aSrcPtr, maskPtr8[2], pixelPtr, pixelPtrInc);
+ BlendAlphaPixel(aSrcPtr, maskPtr8[3], pixelPtr, pixelPtrInc);
+ }
+ else
+ {
+ ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
+ ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
+ ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
+ ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
+ }
+ }
+ }
+
+ if (aLength)
+ {
+ const TUint32 maskWord = *maskWordPtr;
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip the pixels
+ return;
+ }
+ if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy the pixels
+ while (aLength--)
+ {
+ *pixelPtr = *aSrcPtr++;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+ else
+ {
+ // At least one of the pixels needs to be blended
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
+ while (aLength--)
+ {
+ ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Non-optimised path including shadowing and UserDisplayMode conversion
+ const TUint8* srcPtr8 = reinterpret_cast<const TUint8*>(aSrcPtr + aSrcX);
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
+
+ while (aLength--)
+ {
+ TInt mask = *maskPtr8++;
+ if (mask)
+ {
+ TInt b = srcPtr8[0];
+ TInt g = srcPtr8[1];
+ TInt r = srcPtr8[2];
+ if(aShadowing == MAlphaBlend::EShdwBefore)
+ {
+ if (iShadowMode & EFade)
+ {
+ r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ }
+ if (iShadowMode & EShadow)
+ {
+ r = (Max(0,r-0x40));
+ g = (Max(0,g-0x40));
+ b = (Max(0,b-0x40));
+ }
+ }
+ if (mask != 0xff)
+ {
+ // (mask * r + (255 - mask) * value) / 255 =
+ // ((257 * mask * (r - value)) >> 16) + value
+ TInt value = *pixelPtr & 0xffffff;
+ mask = (mask << 8) + mask; // mask = mask * 257
+ TInt v = value >> 16;
+ r = ((mask * (r - v)) >> 16) + v;
+ v = (value >> 8) & 0xff;
+ g = ((mask * (g - v)) >> 16) + v;
+ v = value & 0xff;
+ b = ((mask * (b - v)) >> 16) + v;
+ }
+ if(aShadowing == MAlphaBlend::EShdwAfter)
+ {
+ if (iShadowMode & EFade)
+ {
+ r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ }
+ if (iShadowMode & EShadow)
+ {
+ r = (Max(0,r-0x40));
+ g = (Max(0,g-0x40));
+ b = (Max(0,b-0x40));
+ }
+ }
+ // Convert colour if an incompatible UserDisplayMode is being used
+ CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
+ *pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
+ }
+ pixelPtr += pixelPtrInc;
+ srcPtr8 += 4;
+ }
+ }
+ return;
+ }
+ else // (aSrcFormat==EColor64K)
+ {
+ const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
+
+ if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)))
+ {
+ const TUint16* lowAdd = Convert16to32bppLow();
+ const TUint32* highAdd = Convert16to32bppHigh();
+ const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
+ const TInt startBit = aMaskX & 0x3;
+
+ if (startBit)
+ {
+ // Process initial incomplete mask word
+ const TUint32 maskWord = *maskWordPtr++;
+ TInt numPix = Min(aLength, 4 - startBit); // number of pixels to process from the first word of the mask
+ aLength -= numPix;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked
+ srcPtr16 += numPix;
+ pixelPtr += pixelPtrInc * numPix;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked
+ while (numPix--)
+ {
+ CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ else
+ {
+ // At least one of the pixels needs to be blended
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
+ maskPtr8 += startBit;
+ while (numPix--)
+ {
+ ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ }
+
+ TInt numMaskWords = aLength >> 2;
+ aLength &= 0x3;
+ while (numMaskWords--)
+ {
+ // Process 4 mask pixels
+ const TUint32 maskWord = *maskWordPtr++;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip 4 pixels
+ srcPtr16 += 4;
+ pixelPtr += pixelPtrInc << 2;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy and convert 4 pixels
+ const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ srcPtr16 = (const TUint16*)srcPtr32;
+ }
+ else
+ {
+ // At least one of the 4 pixels needs to be blended
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
+
+ if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
+ maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
+ maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
+ maskPtr8[3] && (maskPtr8[3] != 0xFF))
+ {
+ // Blend all 4 pixels inline
+ BlendAlphaPixel(srcPtr16, maskPtr8[0], pixelPtr, pixelPtrInc);
+ BlendAlphaPixel(srcPtr16, maskPtr8[1], pixelPtr, pixelPtrInc);
+ BlendAlphaPixel(srcPtr16, maskPtr8[2], pixelPtr, pixelPtrInc);
+ BlendAlphaPixel(srcPtr16, maskPtr8[3], pixelPtr, pixelPtrInc);
+ }
+ else
+ {
+ ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ }
+
+ if (aLength)
+ {
+ // Process final incomplete mask word
+ const TUint32 maskWord = *maskWordPtr; // this will over-read
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip the pixels
+ return;
+ }
+ if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy and convert the pixels
+ while (aLength--)
+ {
+ CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ else
+ {
+ // At least one of the pixels needs to be blended
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
+ while (aLength--)
+ {
+ ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Non-optimised path including shadowing and UserDisplayMode conversion
+ const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
+ while (aLength--)
+ {
+ TInt mask = *maskPtr8++;
+ if (mask)
+ {
+ const TUint32 src = *srcPtr16;
+ TInt r = (src & 0xF800) >> 8;
+ r |= (src & 0xE000) >>13;
+ TInt g = (src & 0x07E0) >> 3;
+ g |= (src & 0x0600) >> 9;
+ TInt b = (src & 0x001F) << 3;
+ b |= (src & 0x001C) >> 2;
+
+ if(aShadowing == MAlphaBlend::EShdwBefore)
+ {
+ if (iShadowMode & EFade)
+ {
+ r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ }
+ if (iShadowMode & EShadow)
+ {
+ r = Max(0,r-0x40);
+ g = Max(0,g-0x40);
+ b = Max(0,b-0x40);
+ }
+ }
+ if (mask != 0xff)
+ {
+ // (mask * r + (255 - mask) * value) / 255 =
+ // ((257 * mask * (r - value)) >> 16) + value
+ const TInt value = *pixelPtr & 0xffffff;
+ mask = (mask << 8) + mask; // mask = mask * 257
+ TInt v = value >> 16;
+ r = ((mask * (r - v)) >> 16) + v;
+ v = (value >> 8) & 0xff;
+ g = ((mask * (g - v)) >> 16) + v;
+ v = value & 0xff;
+ b = ((mask * (b - v)) >> 16) + v;
+ }
+ if(aShadowing == MAlphaBlend::EShdwAfter)
+ {
+ if (iShadowMode & EFade)
+ {
+ r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
+ }
+ if (iShadowMode & EShadow)
+ {
+ r = Max(0,r-0x40);
+ g = Max(0,g-0x40);
+ b = Max(0,b-0x40);
+ }
+ }
+ // Convert colour if an incompatible UserDisplayMode is being used
+ CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
+ *pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
+ }
+ srcPtr16++;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+ return;
+ }
+ }
+
+/**
+CDrawUTwentyFourBppBitmap::WriteMaskLineEx() implementation.
+@internalTechnology
+@see MFastBlit::WriteMaskLineEx()
+*/
+void CDrawUTwentyFourBppBitmap::WriteMaskLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
+ const TUint32* aSrcPtr, TDisplayMode aSrcFormat,
+ TInt aMaskX, const TUint32* aMaskPtr, TBool aInvertMask)
+ {
+ // Only certain pixel formats are supported. Caller should check this.
+ __ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
+
+ DeOrientate(aX,aY);
+ TUint32* pixelPtr = PixelAddress(aX,aY);
+ const TInt pixelPtrInc = PixelAddressIncrement();
+ const TUint32 invertWord = (aInvertMask ? 0xFFFFFFFF : 0); // to be XORed with the mask
+
+ if (aSrcFormat==EColor16MU)
+ {
+ aSrcPtr += aSrcX;
+
+ if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
+ {
+ const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
+ const TInt startBit = aMaskX & 0x1F;
+
+ if (startBit)
+ {
+ // Process initial incomplete mask word
+ TUint32 maskWord = *maskWordPtr++;
+ maskWord ^= invertWord;
+ TInt numPix = Min(aLength, 32 - startBit); // number of pixels to process from the first word of the mask
+ aLength -= numPix;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip the pixels
+ aSrcPtr += numPix;
+ pixelPtr += pixelPtrInc * numPix;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy the pixels
+ while (numPix--)
+ {
+ *pixelPtr = *aSrcPtr++;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+ else
+ {
+ // maskWord is partially masked - process each pixel
+ TUint32 singleBitMask = 1 << startBit;
+ while (numPix--)
+ {
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ }
+ }
+ }
+
+ TInt numMaskWords = aLength >> 5;
+ aLength &= 0x1F;
+ while (numMaskWords--)
+ {
+ // Process a complete mask word (32 pixels)
+ TUint32 maskWord = *maskWordPtr++;
+ maskWord ^= invertWord;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip 32 pixels
+ aSrcPtr += 32;
+ pixelPtr += pixelPtrInc << 5;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy 32 pixels
+ if (pixelPtrInc==1)
+ {
+ pixelPtr=(TUint32*)Mem::Move(pixelPtr, aSrcPtr, 128);
+ aSrcPtr+= 32;
+ }
+ else
+ {
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
+ }
+ }
+ else
+ {
+ // maskWord is partially masked - process each of the 32 pixels
+ TUint32 singleBitMask = 1;
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ }
+ }
+
+
+ if (aLength)
+ {
+ // Process final incomplete mask word
+ TUint32 maskWord = *maskWordPtr;
+ maskWord ^= invertWord;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip the pixels
+ return;
+ }
+ if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy the pixels
+ while (aLength--)
+ {
+ *pixelPtr = *aSrcPtr++;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+ else
+ {
+ // maskWord is partially masked - process each pixel
+ TUint32 singleBitMask = 1;
+ while (aLength--)
+ {
+ ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Non-optimised path. UserDisplay mode is different to the true display mode
+ while (aLength--)
+ {
+ TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
+ if (aInvertMask)
+ {
+ mask = !mask;
+ }
+ if (mask)
+ {
+ TRgb pixel(*aSrcPtr);
+ MapColorToUserDisplayMode(pixel);
+ *pixelPtr = pixel.Value();
+ }
+ aSrcPtr++;
+ aMaskX++;
+ pixelPtr += pixelPtrInc;
+ }
+ }
+ return;
+ }
+ else // (aSrcFormat==EColor64K)
+ {
+ const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
+
+ if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
+ {
+ const TUint16* lowAdd = Convert16to32bppLow();
+ const TUint32* highAdd = Convert16to32bppHigh();
+ const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
+ const TInt startBit = aMaskX & 0x1F;
+
+ if (startBit)
+ {
+ // Process initial incomplete mask word
+ TUint32 maskWord = *maskWordPtr++;
+ maskWord ^= invertWord;
+ TInt numPix = Min(aLength, 32 - startBit); // number of pixels to process from the first word of the mask
+ aLength -= numPix;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip the pixels
+ srcPtr16 += numPix;
+ pixelPtr += pixelPtrInc * numPix;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy and convert the pixels
+ while (numPix--)
+ {
+ CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ else
+ {
+ // maskWord is partially masked - process each of the pixels
+ TUint32 singleBitMask = 1 << startBit;
+ while (numPix--)
+ {
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ }
+
+ TInt numMaskWords = aLength >> 5;
+ aLength &= 0x1F;
+ while (numMaskWords--)
+ {
+ // Process complete mask words
+ TUint32 maskWord = *maskWordPtr++;
+ maskWord ^= invertWord;
+
+ if (!maskWord)
+ {
+ // maskWord is fully masked - skip 32 pixels
+ srcPtr16 += 32;
+ pixelPtr += pixelPtrInc << 5;
+ }
+ else if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy and convert 32 pixels
+ const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ srcPtr16 = (const TUint16*)srcPtr32;
+ }
+ else
+ {
+ // maskWord is partially masked - process each of the 32 pixels
+ TUint32 singleBitMask = 1;
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+
+ if (aLength)
+ {
+ // Process final incomplete mask word
+ TUint32 maskWord = *maskWordPtr; // this will over-read
+ maskWord ^= invertWord;
+
+ if (!maskWord)
+ {
+ // maskWord is masked - skip the pixels
+ return;
+ }
+
+ if (maskWord == 0xFFFFFFFF)
+ {
+ // maskWord is fully unmasked - copy and convert the pixels
+ while (aLength--)
+ {
+ CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ else
+ {
+ // maskWord is partially masked - process each of the pixels
+ TUint32 singleBitMask = 1;
+ while (aLength--)
+ {
+ ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Non-optimised - expects aMaskPtr untouched and srcPtr16 to be accurate
+ while (aLength--)
+ {
+ TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
+ if (aInvertMask)
+ {
+ mask = !mask;
+ }
+ if (mask)
+ {
+ const TUint32 src = *srcPtr16;
+ TUint32 color = (src & 0xF800) << 8; // R top 5
+ color |= (src & 0xE000) << 3; // R bottom 3
+ color |= (src & 0x07E0) << 5; // G top 6
+ color |= (src & 0x0600) >> 1; // G bottom 2
+ color |= (src & 0x001F) << 3; // B top 5
+ color |= (src & 0x001C) >> 2; // B bottom 3
+ TRgb pixel(color);
+ MapColorToUserDisplayMode(pixel);
+ *pixelPtr = pixel.Value();
+ }
+ pixelPtr += pixelPtrInc;
+ srcPtr16++;
+ aMaskX++;
+ }
+ }
+ return;
+ }
+ }
+
+/**
+Implementation for CFbsDrawDevice::GetInterface().
+Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
+@param aInterfaceId Interface identifier of the interface to be retrieved.
+@param aInterface Address of variable that retrieves the specified interface.
+@return KErrNone If the interface is supported, KErrNotSupported otherwise.
+*/
+TInt CDrawUTwentyFourBppBitmap::GetInterface(TInt aInterfaceId, TAny*& aInterface)
+ {
+ aInterface = NULL;
+ TInt ret = KErrNotSupported;
+
+ switch (aInterfaceId)
+ {
+ case KFastBlitInterfaceID:
+ {
+ aInterface = static_cast<MFastBlit*>(this);
+ ret = KErrNone;
+ break;
+ }
+ default:
+ {
+ return CDrawThirtyTwoBppBitmapCommon::GetInterface(aInterfaceId, aInterface);
+ }
+ }
+
+ return ret;
+ }
+
+TInt CDrawUTwentyFourBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
+ TUint32 aOutlinePenColor, TUint32 aShadowColor,
+ TUint32 aFillColor, const TUint8* aDataBuffer)
+ {
+ const TInt alpha = aOutlinePenColor >> 24;
+ if (alpha==0 || aLength<=0)
+ return KErrNone;
+ DeOrientate(aX,aY);
+ TUint32* pixelPtr = PixelAddress(aX,aY);
+ const TInt pixelPtrInc = PixelAddressIncrement();
+ const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
+ TInt blendedRedColor;
+ TInt blendedGreenColor;
+ TInt blendedBlueColor;
+ TUint8 index = 0;
+ TUint32 finalColor;
+
+ //Get red color. Equivalent to TRgb::Red()
+ const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16;
+ const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16;
+ const TInt redFillColor = (aFillColor & 0xff0000) >> 16;
+
+ //Get green color. Equivalent to TRgb::Green()
+ const TInt greenOutlinePenColor = (aOutlinePenColor & 0xff00) >> 8;
+ const TInt greenShadowColor = (aShadowColor & 0xff00) >> 8;
+ const TInt greenFillColor = (aFillColor & 0xff00) >> 8;
+
+ //Get blue color. Equivalent to TRgb::Blue()
+ const TInt blueOutlinePenColor = aOutlinePenColor & 0xff;
+ const TInt blueShadowColor = aShadowColor & 0xff;
+ const TInt blueFillColor = aFillColor & 0xff;
+
+ const TUint32 mask2 = alpha | (alpha << 16);
+ while (aDataBuffer < dataBufferPtrLimit)
+ {
+ index = *aDataBuffer++;
+
+ if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
+ {
+ //background colour
+ //No drawing required so move on to next pixel.
+ pixelPtr += pixelPtrInc;
+ continue;
+ }
+ else if (255 == FourColorBlendLookup[index][KFillColorIndex])
+ {
+ //Use fill colour to draw
+ finalColor = aFillColor;
+ }
+ else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
+ {
+ //Use shadow colour to draw
+ finalColor = aShadowColor;
+ }
+ else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
+ {
+ //Use outline colour to draw
+ finalColor = aOutlinePenColor;
+ }
+ else
+ {
+ TUint32 backgroundColor = *pixelPtr;
+ blendedRedColor = redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
+ redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
+ redFillColor * FourColorBlendLookup[index][KFillColorIndex] +
+ ((backgroundColor & 0xff0000) >> 16) * FourColorBlendLookup[index][KBackgroundColorIndex];
+
+ blendedGreenColor = greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
+ greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
+ greenFillColor * FourColorBlendLookup[index][KFillColorIndex] +
+ ((backgroundColor & 0xff00) >> 8) * FourColorBlendLookup[index][KBackgroundColorIndex];
+
+ blendedBlueColor = blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
+ blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
+ blueFillColor * FourColorBlendLookup[index][KFillColorIndex] +
+ (backgroundColor & 0xff) * FourColorBlendLookup[index][KBackgroundColorIndex];
+
+ //Equivalent to TRgb::TRgb(TUint32)
+ finalColor = ((blendedRedColor&0xFF00) << 8) | (blendedGreenColor&0xFF00) | (blendedBlueColor>>8);
+ }
+
+ if (alpha != 0xff)
+ {
+ TUint32 backgroundColor = *pixelPtr;
+ //Draw the final colour
+//
+ const TUint32 s_rb = finalColor & 0x00FF00FF;
+ const TUint32 s_g = (finalColor & 0xFF00) >> 8;
+ const TUint32 d_rb = backgroundColor & 0x00FF00FF;
+ const TUint32 rb = ((((alpha * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
+
+ const TInt d_g = (backgroundColor & 0xFF00) >> 8;
+ const TInt g = ((alpha * (s_g - d_g)) >> 8) + d_g;
+
+ finalColor = rb | (g<<8);
+ }
+
+ *pixelPtr = (finalColor | 0xff000000);
+ pixelPtr += pixelPtrInc;
+ }
+ return KErrNone;
+ }