diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/screendriver/sbit/BMDRAW24.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/screendriver/sbit/BMDRAW24.CPP Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,1125 @@ +// Copyright (c) 1997-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" + +//Initializes iSize, iDrawRect, iLongWidth, iScanLineBytes, iScanlineWords data members. +//It should be called every time when iSize is going to be changed - from Construct(). +//@param aSize Physical screen size in pixels. +//@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the +//device is scaled and the scaling origin goes outside physical drawing rectangle. +void CDrawTwentyFourBppBitmap::SetSize(const TSize& aSize) + { + CDrawBitmap::SetSize(aSize); + __ASSERT_DEBUG(iSize == aSize, User::Invariant()); + iScanLineBytes = (((iSize.iWidth * 3) + 11) / 12) * 12; + iLongWidth = iScanLineBytes / 3; + iScanLineWords = iScanLineBytes / 4; + } + +TInt CDrawTwentyFourBppBitmap::Construct(TSize aSize) + { + return Construct(aSize, (((aSize.iWidth * 3) + 11) / 12) * 12); + } + +TInt CDrawTwentyFourBppBitmap::Construct(TSize aSize, TInt aStride) + { + iBits = NULL; + iDispMode = EColor16M; + CDrawBitmap::SetSize(aSize); + __ASSERT_DEBUG(iSize == aSize, User::Invariant()); + if (aStride % 12) + return KErrArgument; + iScanLineBytes = aStride; + iLongWidth = aStride / 3; + if (iLongWidth < aSize.iWidth) + return KErrArgument; + iScanLineWords = aStride >> 2; + TInt size = (((Max(aSize.iWidth,aSize.iHeight) * 3) + 11) / 12) * 12; + if(size < 0) + return KErrArgument; + iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size)); + if (iScanLineBuffer == NULL) + return KErrNoMemory; + return KErrNone; + } + +inline TInt CDrawTwentyFourBppBitmap::PixelAddressIncrement() const + { + switch (iOrientation) + { + case EOrientationNormal: + return 3; + case EOrientationRotated90: + return iScanLineBytes; + case EOrientationRotated180: + return -3; + case EOrientationRotated270: + return -iScanLineBytes; + default: + return 1; + } + } + +inline void CDrawTwentyFourBppBitmap::PixelAddressIncrement(TInt& aPixelInc,TInt& aRowInc) const + { + switch (iOrientation) + { + case EOrientationNormal: + aPixelInc = 3; + aRowInc = iScanLineBytes; + break; + case EOrientationRotated90: + aPixelInc = iScanLineBytes; + aRowInc = -3; + break; + case EOrientationRotated180: + aPixelInc = -3; + aRowInc = -iScanLineBytes; + break; + case EOrientationRotated270: + aPixelInc = -iScanLineBytes; + aRowInc = 3; + break; + default: + aPixelInc = 1; + aRowInc = 1; + } + } + +void CDrawTwentyFourBppBitmap::FadeRgb(TInt& red,TInt& green,TInt& blue) + { + blue = ((blue * iFadeMapFactor) >> 8) + iFadeMapOffset; + green = ((green * iFadeMapFactor) >> 16) + iFadeMapOffset; + red = ((red * iFadeMapFactor) >> 8) + iFadeMapOffset; + } + +void CDrawTwentyFourBppBitmap::Shadow(TRgb& aColor) + { + if (iShadowMode & EFade) + aColor = CDrawBitmap::FadeRgb(aColor); + + if (iShadowMode & EShadow) + { + TInt r = ShadowComponentInl(aColor.Red()); + TInt g = ShadowComponentInl(aColor.Green()); + TInt b = ShadowComponentInl(aColor.Blue()); + aColor = TRgb(r,g,b); + } + } + +void CDrawTwentyFourBppBitmap::Shadow(TInt& red,TInt& green,TInt& blue) + { + if (iShadowMode & EFade) + FadeRgb(red,green,blue); + + if (iShadowMode & EShadow) + { + red = ShadowComponentInl(red); + green = ShadowComponentInl(green); + blue = ShadowComponentInl(blue); + } + } + +TUint8 CDrawTwentyFourBppBitmap::ShadowAndFade(TInt aComponent) + { + if (iShadowMode & EFade) + aComponent = FadeGray(aComponent); + + if (iShadowMode & EShadow) + aComponent = ShadowComponentInl(aComponent); + + return TUint8(aComponent); + } + +TUint8 CDrawTwentyFourBppBitmap::ShadowComponentInl(TInt aRgbComponent) + { + return TUint8(Max(0,aRgbComponent-0x40)); + } + +TUint8 CDrawTwentyFourBppBitmap::ShadowComponent(TInt aRgbComponent) + { + return ShadowComponentInl(aRgbComponent); + } + +void CDrawTwentyFourBppBitmap::InvertBuffer(TInt aLength,TUint32* aBuffer) + { + __ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer)); + + TUint8* buffer = (TUint8*)aBuffer; + TUint8* limit = buffer + (aLength * 3); + + while (buffer < limit) + *buffer++ ^= 0xff; + } + +void CDrawTwentyFourBppBitmap::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const + { + const TUint8* pixelPtr = PixelAddress(aX,aY); + + if (iOrientation == EOrientationNormal) + Mem::Copy(aBuffer,pixelPtr,aLength * 3); + else + { + const TInt pixelPtrInc = PixelAddressIncrement(); + + TUint8* bufferPtr = STATIC_CAST(TUint8*,aBuffer); + const TUint8* bufferPtrLimit = bufferPtr + (aLength * 3); + + while (bufferPtr < bufferPtrLimit) + { + *bufferPtr++ = pixelPtr[0]; + *bufferPtr++ = pixelPtr[1]; + *bufferPtr++ = pixelPtr[2]; + pixelPtr += pixelPtrInc; + } + } + } + +TRgb CDrawTwentyFourBppBitmap::ReadRgbNormal(TInt aX,TInt aY) const + { + TUint8* pixelPtr = PixelAddress(aX,aY); + return TRgb(pixelPtr[2],pixelPtr[1],pixelPtr[0]); + } + +void CDrawTwentyFourBppBitmap::ShadowArea(const TRect& aRect) + { + const TRect rect(DeOrientate(aRect)); + + __ASSERT_DEBUG(rect.iTl.iX>=0 && rect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG(rect.iTl.iY>=0 && rect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds)); + + TUint8* pixelPtr = PixelAddress(rect.iTl.iX,rect.iTl.iY); + TUint8* pixelRowPtrLimit = pixelPtr + (rect.Height() * iScanLineBytes); + + if (iShadowMode & EFade) + { + TUint8* pixelRowPtr = pixelPtr; + TUint8* pixelPtrLimit = pixelPtr + (rect.Width() * 3); + + while (pixelRowPtr < pixelRowPtrLimit) + { + TUint8* tempPixelPtr = pixelRowPtr; + + while (tempPixelPtr < pixelPtrLimit) + { + *tempPixelPtr = FadeGray(*tempPixelPtr); + ++tempPixelPtr; + } + + pixelRowPtr += iScanLineBytes; + pixelPtrLimit += iScanLineBytes; + } + } + + if (iShadowMode & EShadow) + { + TUint8* pixelRowPtr = pixelPtr; + TUint8* pixelPtrLimit = pixelPtr + (rect.Width() * 3); + + while (pixelRowPtr < pixelRowPtrLimit) + { + TUint8* tempPixelPtr = pixelRowPtr; + + while (tempPixelPtr < pixelPtrLimit) + { + *tempPixelPtr = ShadowComponent(*tempPixelPtr); + ++tempPixelPtr; + } + + pixelRowPtr += iScanLineBytes; + pixelPtrLimit += iScanLineBytes; + } + } + } + +void CDrawTwentyFourBppBitmap::ShadowBuffer(TInt aLength,TUint32* aBuffer) + { + __ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicZeroLength)); + __ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer)); + + TUint8* limit = ((TUint8*)aBuffer) + (aLength * 3); + + if (iShadowMode & EFade) + { + TUint8* buffer = (TUint8*)aBuffer; + + while (buffer < limit) + { + *buffer = FadeGray(*buffer); + ++buffer; + } + } + + if (iShadowMode & EShadow) + { + TUint8* buffer = (TUint8*)aBuffer; + + while (buffer < limit) + { + *buffer = ShadowComponent(*buffer); + ++buffer; + } + } + } + +void CDrawTwentyFourBppBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + pixelPtr[0] = TUint8(aColor.Blue()); + pixelPtr[1] = TUint8(aColor.Green()); + pixelPtr[2] = TUint8(aColor.Red()); + } + +void CDrawTwentyFourBppBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,TInt aHeight,TRgb aColor) + { + DeOrientate(aX,aY); + + TInt pixelInc; + TInt rowInc; + + PixelAddressIncrement(pixelInc,rowInc); + + const TUint32* dataLimit = aBuffer + aHeight; + const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0; + + TUint8* pixelPtr = PixelAddress(aX,aY); + + const TUint8 r = (TUint8)aColor.Red(); + const TUint8 g = (TUint8)aColor.Green(); + const TUint8 b = (TUint8)aColor.Blue(); + + while (aBuffer < dataLimit) + { + TUint32 dataWord = *aBuffer++; + TUint32 dataMask = 1; + TUint8* tempPixelPtr = pixelPtr; + + while (dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + tempPixelPtr[0] = b; + tempPixelPtr[1] = g; + tempPixelPtr[2] = r; + } + + tempPixelPtr += pixelInc; + dataMask <<= 1; + } + + pixelPtr += rowInc; + } + } + +void CDrawTwentyFourBppBitmap::WriteBinaryOp(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode) + { + if (aLength <= 0) + return; + + DeOrientate(aX,aY); + TUint8* pixelPtr = PixelAddress(aX,aY); + + const TUint32* dataPtrLimit = aBuffer + aHeight; + const TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0; + + TInt pixelInc; + TInt rowInc; + + PixelAddressIncrement(pixelInc,rowInc); + + const TUint8 r = (TUint8)aColor.Red(); + const TUint8 g = (TUint8)aColor.Green(); + const TUint8 b = (TUint8)aColor.Blue(); + + if (r || g || b) + { + while (aBuffer < dataPtrLimit) + { + TUint32 dataWord = *aBuffer++; + TUint32 dataMask = 1; + TUint8* tempPixelPtr = pixelPtr; + + while (dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + switch (aDrawMode) + { + case CGraphicsContext::EDrawModeXOR: + tempPixelPtr[0] ^= b; + tempPixelPtr[1] ^= g; + tempPixelPtr[2] ^= r; + break; + case CGraphicsContext::EDrawModeAND: + tempPixelPtr[0] &= b; + tempPixelPtr[1] &= g; + tempPixelPtr[2] &= r; + break; + case CGraphicsContext::EDrawModeOR: + tempPixelPtr[0] |= b; + tempPixelPtr[1] |= g; + tempPixelPtr[2] |= r; + break; + default: + break; + } + } + tempPixelPtr += pixelInc; + dataMask <<= 1; + } + + pixelPtr += rowInc; + } + } + else if (aDrawMode == CGraphicsContext::EDrawModeAND) + { + while (aBuffer < dataPtrLimit) + { + TUint32 dataWord = *aBuffer++; + TUint32 dataMask = 1; + TUint8* tempPixelPtr = pixelPtr; + + while (dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + tempPixelPtr[0] = 0; + tempPixelPtr[1] = 0; + tempPixelPtr[2] = 0; + } + + tempPixelPtr += pixelInc; + dataMask <<= 1; + } + + pixelPtr += rowInc; + } + } + } + +void CDrawTwentyFourBppBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aBuffer,TInt aHeight,TRgb aColor,TBool aUp) + { + DeOrientate(aX,aY); + + TInt scanlineByteLength; + + switch (iOrientation) + { + case EOrientationNormal: + scanlineByteLength = iScanLineBytes; + break; + case EOrientationRotated90: + scanlineByteLength = -3; + break; + case EOrientationRotated180: + scanlineByteLength = -iScanLineBytes; + break; + default: // EOrientationRotated270 + scanlineByteLength = 3; + break; + } + + if (aUp) + scanlineByteLength = -scanlineByteLength; + + TUint8* pixelPtr = PixelAddress(aX,aY); + const TUint8* pixelPtrLimit = pixelPtr + (aHeight * scanlineByteLength); + TUint32 dataWord = *aBuffer; + TUint32 dataMask = 1; + + const TUint8 r = (TUint8)aColor.Red(); + const TUint8 g = (TUint8)aColor.Green(); + const TUint8 b = (TUint8)aColor.Blue(); + + while(pixelPtr != pixelPtrLimit) + { + if(!dataMask) + { + dataMask = 1; + aBuffer++; + dataWord = *aBuffer; + } + + if(dataWord & dataMask) + { + pixelPtr[0] = b; + pixelPtr[1] = g; + pixelPtr[2] = r; + } + + dataMask <<= 1; + pixelPtr += scanlineByteLength; + } + } + +void CDrawTwentyFourBppBitmap::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + + if (iOrientation == EOrientationNormal) + Mem::Copy(pixelPtr,aBuffer,aLength * 3); + else + { + const TInt pixelPtrInc = PixelAddressIncrement(); + + TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer); + TUint8* bufferPtrLimit = bufferPtr + (aLength * 3); + + while (bufferPtr < bufferPtrLimit) + { + pixelPtr[0] = *bufferPtr++; + pixelPtr[1] = *bufferPtr++; + pixelPtr[2] = *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + } + +void CDrawTwentyFourBppBitmap::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + const TInt pixelPtrInc = PixelAddressIncrement(); + + TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer); + TUint8* bufferPtrLimit = bufferPtr + (aLength * 3); + + while (bufferPtr < bufferPtrLimit) + { + pixelPtr[0] ^= *bufferPtr++; + pixelPtr[1] ^= *bufferPtr++; + pixelPtr[2] ^= *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + +void CDrawTwentyFourBppBitmap::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + const TInt pixelPtrInc = PixelAddressIncrement(); + + TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer); + TUint8* bufferPtrLimit = bufferPtr + (aLength * 3); + + while (bufferPtr < bufferPtrLimit) + { + pixelPtr[0] &= *bufferPtr++; + pixelPtr[1] &= *bufferPtr++; + pixelPtr[2] &= *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + +void CDrawTwentyFourBppBitmap::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + const TInt pixelPtrInc = PixelAddressIncrement(); + + TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer); + TUint8* bufferPtrLimit = bufferPtr + (aLength * 3); + + while (bufferPtr < bufferPtrLimit) + { + pixelPtr[0] |= *bufferPtr++; + pixelPtr[1] |= *bufferPtr++; + pixelPtr[2] |= *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + +/** +MAlphaBlend::WriteRgbAlphaLine() implementation. +@see MAlphaBlend::WriteRgbAlphaLine() +*/ +void CDrawTwentyFourBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength, + const TUint8* aRgbBuffer, + const TUint8* aMaskBuffer, + MAlphaBlend::TShadowing aShadowing, + CGraphicsContext::TDrawMode /*aDrawMode*/) + { + DeOrientate(aX,aY); + TUint8* pixelPtr = PixelAddress(aX,aY); + const TInt pixelPtrInc = PixelAddressIncrement(); + const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength; + + while (aMaskBuffer < maskBufferPtrLimit) + { + TInt mask = aMaskBuffer[0]; + + if(mask) + { + TInt red = aRgbBuffer[2]; + TInt green = aRgbBuffer[1]; + TInt blue = aRgbBuffer[0]; + + if(aShadowing == MAlphaBlend::EShdwBefore) + { + Shadow(red,green,blue); + } + + if(aMaskBuffer[0] != 0xff) // Blend 24bpp + { + mask = mask * 257; + red = (((red - pixelPtr[2]) * mask) >> 16) + pixelPtr[2]; + green = (((green - pixelPtr[1]) * mask) >> 16) + pixelPtr[1]; + blue = (((blue - pixelPtr[0]) * mask) >> 16) + pixelPtr[0]; + } + + if(aShadowing == MAlphaBlend::EShdwAfter) + { + Shadow(red,green,blue); + } + CDrawBitmap::MapColorToUserDisplayMode(red,green,blue); + pixelPtr[0] = TUint8(blue); + pixelPtr[1] = TUint8(green); + pixelPtr[2] = TUint8(red); + } + pixelPtr += pixelPtrInc; + aRgbBuffer += 4; + aMaskBuffer++; + } + } + +const TUint32 KWordAlignedCount = 4; +const TUint32 KWordAlignedMask = 3; +const TUint32 KFinishEarlyByThree = 3; + +void WriteTwentyFourBppColourAsWords(TUint8& r, TUint8& g, TUint8& b, TUint8* pixelPtr, const TInt byteLength, TUint8* pixelRowPtrLimit, const TInt scanLineBytes) + { + TUint8 bgr[3] = + { + b,g,r + }; + TUint32 bgrb = b+(g<<8)+(r<<16)+(b<<24); + TUint32 grbg = g+(r<<8)+(b<<16)+(g<<24); + TUint32 rbgr = r+(b<<8)+(g<<16)+(r<<24); + + TUint8* pixelPtrLimit = pixelPtr + byteLength; + + TInt leadingPixels = KWordAlignedCount-((TUint32)pixelPtr)&KWordAlignedMask; + if (leadingPixels == KWordAlignedCount) + leadingPixels = 0; + const TInt trailingPixels = ((TUint32)pixelPtrLimit & KWordAlignedMask); + + while (pixelPtr < pixelRowPtrLimit) + { + TUint8* tempPixelPtr; + TUint32* tempWordPtr; + TInt nextOfBgr = 0; + TUint8* leadingPixelPtrLimit = pixelPtr+leadingPixels; + for (tempPixelPtr = pixelPtr; tempPixelPtr < leadingPixelPtrLimit; tempPixelPtr++) + { + tempPixelPtr[0] = bgr[nextOfBgr++]; + } + + if (nextOfBgr == (KWordAlignedCount-1)) + nextOfBgr = 0; + + TUint32* wordPtrLimit = ((TUint32*)(pixelPtrLimit-trailingPixels))-KFinishEarlyByThree; + + tempWordPtr = (TUint32*)tempPixelPtr; + switch (nextOfBgr) + { + case 1: + if (tempWordPtr < wordPtrLimit) + { + *tempWordPtr++ = grbg; + nextOfBgr = 2; + } + //no break + case 2: + if (tempWordPtr < wordPtrLimit) + { + *tempWordPtr++ = rbgr; + nextOfBgr = 0; + } + } + + while (tempWordPtr < wordPtrLimit) + { + *tempWordPtr++ = bgrb; + *tempWordPtr++ = grbg; + *tempWordPtr++ = rbgr; + } + + for (tempPixelPtr = (TUint8*)tempWordPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++) + { + tempPixelPtr[0] = bgr[nextOfBgr++]; + if (nextOfBgr > 2) + nextOfBgr = 0; + } + + pixelPtr += scanLineBytes; + pixelPtrLimit += scanLineBytes; + } + } + +/** +Writes a specific colour to the screen, optimised to use mem fill if the colour is shade of grey +and word aligned access the three possible combinations of the colour bytes. +*/ +void CDrawTwentyFourBppBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor) + { + const TInt scanLineBytes = iScanLineBytes; + const TInt byteLength = aLength * 3; + + TUint8* pixelPtr = PixelAddress(aX,aY); + TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * scanLineBytes); + + TUint8 r = TUint8(aColor.Red()); + TUint8 g = TUint8(aColor.Green()); + TUint8 b = TUint8(aColor.Blue()); + + if ((r == g) && (g == b)) + { + while (pixelPtr < pixelRowPtrLimit) + { + Mem::Fill(pixelPtr,byteLength,r); + pixelPtr += scanLineBytes; + } + } + else + { + WriteTwentyFourBppColourAsWords(r, g, b, pixelPtr, byteLength, pixelRowPtrLimit, scanLineBytes); + } + } + +void CDrawTwentyFourBppBitmap::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + TUint8* pixelPtrLimit = pixelPtr + (aLength * 3); + TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineBytes); + + TUint8 r = TUint8(aColor.Red()); + TUint8 g = TUint8(aColor.Green()); + TUint8 b = TUint8(aColor.Blue()); + + while (pixelPtr < pixelRowPtrLimit) + { + for (TUint8* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr += 3) + { + tempPixelPtr[0] ^= b; + tempPixelPtr[1] ^= g; + tempPixelPtr[2] ^= r; + } + + pixelPtr += iScanLineBytes; + pixelPtrLimit += iScanLineBytes; + } + } + +void CDrawTwentyFourBppBitmap::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + TUint8* pixelPtrLimit = pixelPtr + (aLength * 3); + TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineBytes); + TUint8 r = TUint8(aColor.Red()); + TUint8 g = TUint8(aColor.Green()); + TUint8 b = TUint8(aColor.Blue()); + + while (pixelPtr < pixelRowPtrLimit) + { + for (TUint8* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr += 3) + { + tempPixelPtr[0] &= b; + tempPixelPtr[1] &= g; + tempPixelPtr[2] &= r; + } + + pixelPtr += iScanLineBytes; + pixelPtrLimit += iScanLineBytes; + } + } + +void CDrawTwentyFourBppBitmap::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + TUint8* pixelPtrLimit = pixelPtr + (aLength * 3); + TUint8* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineBytes); + TUint8 r = TUint8(aColor.Red()); + TUint8 g = TUint8(aColor.Green()); + TUint8 b = TUint8(aColor.Blue()); + + while (pixelPtr < pixelRowPtrLimit) + { + for (TUint8* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr += 3) + { + tempPixelPtr[0] |= b; + tempPixelPtr[1] |= g; + tempPixelPtr[2] |= r; + } + + pixelPtr += iScanLineBytes; + pixelPtrLimit += iScanLineBytes; + } + } + +void CDrawTwentyFourBppBitmap::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer) + { + DeOrientate(aX,aY); + TUint8* pixelPtr = PixelAddress(aX,aY); + const TInt pixelPtrInc = PixelAddressIncrement(); + const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength; + + if (iShadowMode) + Shadow(aColor); + + const TInt red = aColor.Red(); + const TInt green = aColor.Green(); + const TInt blue = aColor.Blue(); + while (aMaskBuffer < maskBufferPtrLimit) + { + if(aMaskBuffer[0]) + { + TRgb pixelClr; + + if(aMaskBuffer[0] != 0xff) + { + pixelClr = AlphaBlend(red, green, blue, TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0]), aMaskBuffer[0]); + } + else + { + pixelClr = aColor; + } + + pixelPtr[0] = TUint8(pixelClr.Blue()); + pixelPtr[1] = TUint8(pixelClr.Green()); + pixelPtr[2] = TUint8(pixelClr.Red()); + } + pixelPtr += pixelPtrInc; + aMaskBuffer++; + } + } + +void CDrawTwentyFourBppBitmap::MapColorToUserDisplayMode(TRgb& aColor) + { + switch (iUserDispMode) + { + case EGray2: + aColor = TRgb::_Gray2(aColor._Gray2()); + break; + case EGray4: + aColor = TRgb::_Gray4(aColor._Gray4()); + break; + case EGray16: + aColor = TRgb::_Gray16(aColor._Gray16()); + break; + case EGray256: + aColor = TRgb::_Gray256(aColor._Gray256()); + break; + case EColor16: + aColor = TRgb::Color16(aColor.Color16()); + break; + case EColor256: + aColor = TRgb::Color256(aColor.Color256()); + break; + case EColor4K: + aColor = TRgb::_Color4K(aColor._Color4K()); + break; + case EColor64K: + aColor = TRgb::_Color64K(aColor._Color64K()); + break; + default: + break; + } + } + +void CDrawTwentyFourBppBitmap::MapBufferToUserDisplayMode(TInt aLength,TUint32* aBuffer) + { + TUint8* bufferPtr = (TUint8*)aBuffer; + const TUint8* bufferLimit = bufferPtr + (aLength * 3); + + switch (iUserDispMode) + { + case EGray2: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::_Gray2(color._Gray2()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + case EGray4: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::_Gray4(color._Gray4()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + case EGray16: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::_Gray16(color._Gray16()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + case EGray256: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::_Gray256(color._Gray256()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + case EColor16: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::Color16(color.Color16()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + case EColor256: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::Color256(color.Color256()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + case EColor4K: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::_Color4K(color._Color4K()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + case EColor64K: + while (bufferPtr < bufferLimit) + { + TInt blue = bufferPtr[0]; + TInt green = bufferPtr[1]; + TInt red = bufferPtr[2]; + TRgb color(red,green,blue); + color = TRgb::_Color64K(color._Color64K()); + bufferPtr[0] = TUint8(color.Blue()); + bufferPtr[1] = TUint8(color.Green()); + bufferPtr[2] = TUint8(color.Red()); + bufferPtr += 3; + } + break; + default: + break; + } + } + +TInt CDrawTwentyFourBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength, + TUint32 aOutlinePenColor, TUint32 aShadowColor, + TUint32 aFillColor, const TUint8* aDataBuffer) + { + DeOrientate(aX,aY); + TUint8* pixelPtr = PixelAddress(aX,aY); + const TInt pixelPtrInc = PixelAddressIncrement(); + const TUint8* dataBufferPtrLimit = aDataBuffer + aLength; + TInt blendedRedColor; + TInt blendedGreenColor; + TInt blendedBlueColor; + TUint8 index = 0; + TRgb finalColor; + + TRgb outlinePenColor; + outlinePenColor.SetInternal(aOutlinePenColor); + TRgb shadowColor; + shadowColor.SetInternal(aShadowColor); + TRgb fillColor; + fillColor.SetInternal(aFillColor); + + const TInt redOutlinePenColor = outlinePenColor.Red(); + const TInt redShadowColor = shadowColor.Red(); + const TInt redFillColor = fillColor.Red(); + + const TInt greenOutlinePenColor = outlinePenColor.Green(); + const TInt greenShadowColor = shadowColor.Green(); + const TInt greenFillColor = fillColor.Green(); + + const TInt blueOutlinePenColor = outlinePenColor.Blue(); + const TInt blueShadowColor = shadowColor.Blue(); + const TInt blueFillColor = fillColor.Blue(); + const TInt alpha = aOutlinePenColor >> 24; + + 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]) + { + //fill colour + finalColor.SetInternal(aFillColor); + } + else if (255 == FourColorBlendLookup[index][KShadowColorIndex]) + { + //Shadow colour + finalColor.SetInternal(aShadowColor); + } + else if (255 == FourColorBlendLookup[index][KOutlineColorIndex]) + { + //Outline colour + finalColor.SetInternal(aOutlinePenColor); + } + else + { + TRgb backgroundColor = TRgb::_Color16M(TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0])._Color16M()); + + blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + + redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] + + redFillColor * FourColorBlendLookup[index][KFillColorIndex] + + backgroundColor.Red() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8; + + blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + + greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] + + greenFillColor * FourColorBlendLookup[index][KFillColorIndex] + + backgroundColor.Green() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8; + + blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] + + blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] + + blueFillColor * FourColorBlendLookup[index][KFillColorIndex] + + backgroundColor.Blue() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8; + + if (alpha != 0xff) + { + TRgb alphablend = AlphaBlend(blendedRedColor, blendedGreenColor, blendedBlueColor, TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0]), alpha); + pixelPtr[0] = TUint8(alphablend.Blue()); + pixelPtr[1] = TUint8(alphablend.Green()); + pixelPtr[2] = TUint8(alphablend.Red()); + } + else + { + //opaque + pixelPtr[0] = TUint8(blendedBlueColor); + pixelPtr[1] = TUint8(blendedGreenColor); + pixelPtr[2] = TUint8(blendedRedColor); + } + pixelPtr += pixelPtrInc; + continue; + } + + if (alpha != 0xff) + { + TRgb alphablend = AlphaBlend(finalColor, TRgb(pixelPtr[2], pixelPtr[1], pixelPtr[0]), alpha); + pixelPtr[0] = TUint8(alphablend.Blue()); + pixelPtr[1] = TUint8(alphablend.Green()); + pixelPtr[2] = TUint8(alphablend.Red()); + } + else + { + pixelPtr[0] = TUint8(finalColor.Blue()); + pixelPtr[1] = TUint8(finalColor.Green()); + pixelPtr[2] = TUint8(finalColor.Red()); + } + pixelPtr += pixelPtrInc; + } + return KErrNone; + } + +void CDrawTwentyFourBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor) + { + const TInt sourceAlpha = aColor.Alpha(); + + if (sourceAlpha == 0xFF) //Fully opaque + { + WriteRgbMulti(aX,aY,aLength,aHeight,aColor); + return; + } + else if (sourceAlpha == 0x00) //Fully transparent + { + return; + } + else //Perform alpha blending + { + TUint8* pixelPtr = PixelAddress(aX,aY); + const TInt pixelPtrInc = PixelAddressIncrement(); + TUint8* pixelPtrEnd = pixelPtr + (aLength * pixelPtrInc); + + TUint8 dr; + TUint8 dg; + TUint8 db; + + //Perform pre-multiplication on values from aColor + const TUint8 pmsr = (sourceAlpha * aColor.Red()) / 255; + const TUint8 pmsg = (sourceAlpha * aColor.Green()) / 255; + const TUint8 pmsb = (sourceAlpha * aColor.Blue()) / 255; + + for (TInt ii = 0 ; ii <= aHeight; ii++) + { + while (pixelPtr != pixelPtrEnd) + { + dr = pixelPtr[2]; + dg = pixelPtr[1]; + db = pixelPtr[0]; + + //Target has no alpha channel so assume to be 0xFF (opaque) + pixelPtr[0] = pmsb + ((0xFF-sourceAlpha) * db)/255; + pixelPtr[1] = pmsg + ((0xFF-sourceAlpha) * dg)/255; + pixelPtr[2] = pmsr + ((0xFF-sourceAlpha) * dr)/255; + + pixelPtr+=pixelPtrInc; + } + pixelPtr = PixelAddress(aX, ii+aY); + pixelPtrEnd = pixelPtr + (aLength * pixelPtrInc); + } + } + }