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