1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW24U.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,1270 @@
1.4 +// Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "BMDRAW.H"
1.20 +#include "BitDrawInterfaceId.h"
1.21 +#include <graphics/lookuptable.h>
1.22 +#include <graphics/blendingalgorithms.h>
1.23 +
1.24 +TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize)
1.25 + {
1.26 + return Construct(aSize, aSize.iWidth << 2);
1.27 + }
1.28 +
1.29 +TInt CDrawUTwentyFourBppBitmap::Construct(TSize aSize, TInt aStride)
1.30 + {
1.31 + iDispMode = EColor16MU;
1.32 + return CDrawThirtyTwoBppBitmapCommon::Construct(aSize, aStride);
1.33 + }
1.34 +
1.35 +/**
1.36 +MAlphaBlend::WriteRgbAlphaLine() implementation.
1.37 +@see MAlphaBlend::WriteRgbAlphaLine()
1.38 +*/
1.39 +void CDrawUTwentyFourBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
1.40 + const TUint8* aRgbBuffer,
1.41 + const TUint8* aMaskBuffer,
1.42 + MAlphaBlend::TShadowing aShadowing,
1.43 + CGraphicsContext::TDrawMode /*aDrawMode*/)
1.44 + {
1.45 + // precondition for this function is that the aRgbBuffer lies on a word boundary
1.46 + // Assert checks that the pointer is at a word boundary
1.47 + __ASSERT_DEBUG(!(((TUint)aRgbBuffer) & 0x3), Panic(EScreenDriverPanicInvalidPointer));
1.48 +
1.49 + DeOrientate(aX,aY);
1.50 + TUint32* pixelPtr = PixelAddress(aX,aY);
1.51 + TUint32* rgbBuffer = (TUint32*)aRgbBuffer;
1.52 + const TInt pixelPtrInc = PixelAddressIncrement();
1.53 + const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
1.54 +
1.55 + if (!(iShadowMode & (EFade | EShadow)) && (iUserDispMode == ENone))
1.56 + {
1.57 + while (aMaskBuffer < maskBufferPtrLimit)
1.58 + {
1.59 + *pixelPtr = CalcAlphaPixel(*rgbBuffer, *aMaskBuffer, *pixelPtr);
1.60 + aMaskBuffer++;
1.61 + pixelPtr += pixelPtrInc;
1.62 + rgbBuffer++;
1.63 + }
1.64 + }
1.65 + else
1.66 + {
1.67 + while (aMaskBuffer < maskBufferPtrLimit)
1.68 + {
1.69 + TInt mask = *aMaskBuffer++;
1.70 + if (mask)
1.71 + {
1.72 + TInt b = aRgbBuffer[0];
1.73 + TInt g = aRgbBuffer[1];
1.74 + TInt r = aRgbBuffer[2];
1.75 + if(aShadowing == MAlphaBlend::EShdwBefore)
1.76 + {
1.77 + if (iShadowMode & EFade)
1.78 + {
1.79 + r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.80 + g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.81 + b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.82 + }
1.83 + if (iShadowMode & EShadow)
1.84 + {
1.85 + r = (Max(0,r-0x40));
1.86 + g = (Max(0,g-0x40));
1.87 + b = (Max(0,b-0x40));
1.88 + }
1.89 + }
1.90 + if (mask != 0xff)
1.91 + {
1.92 + // (mask * r + (255 - mask) * value) / 255 =
1.93 + // ((257 * mask * (r - value)) >> 16) + value
1.94 + TInt value = *pixelPtr & 0xffffff;
1.95 + mask = (mask << 8) + mask; // mask = mask * 257
1.96 + TInt v = value >> 16;
1.97 + r = ((mask * (r - v)) >> 16) + v;
1.98 + v = (value >> 8) & 0xff;
1.99 + g = ((mask * (g - v)) >> 16) + v;
1.100 + v = value & 0xff;
1.101 + b = ((mask * (b - v)) >> 16) + v;
1.102 + }
1.103 + if(aShadowing == MAlphaBlend::EShdwAfter)
1.104 + {
1.105 + if (iShadowMode & EFade)
1.106 + {
1.107 + r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.108 + g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.109 + b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.110 + }
1.111 + if (iShadowMode & EShadow)
1.112 + {
1.113 + r = (Max(0,r-0x40));
1.114 + g = (Max(0,g-0x40));
1.115 + b = (Max(0,b-0x40));
1.116 + }
1.117 + }
1.118 + // Convert colour if an incompatible UserDisplayMode is being used
1.119 + CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
1.120 + *pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
1.121 + }
1.122 + aRgbBuffer += 4;
1.123 + pixelPtr += pixelPtrInc;
1.124 + }
1.125 + }
1.126 + }
1.127 +
1.128 +void CDrawUTwentyFourBppBitmap::ReadLine(TInt aX, TInt aY, TInt aLength, TAny* aBuffer, TDisplayMode aDispMode) const
1.129 + {
1.130 + if (aDispMode == EColor16MAP)
1.131 + {
1.132 + DeOrientate(aX, aY);
1.133 + CDrawThirtyTwoBppBitmapCommon::ReadLine(aX, aY, aLength, aBuffer);
1.134 +
1.135 + //Overwrite unused byte with 0xff to produce valid 16MAP data
1.136 + TUint8* alphaptr = (TUint8*) aBuffer+3;
1.137 + TUint8* bufEnd = (TUint8*) aBuffer + (aLength << 2);
1.138 + while (alphaptr < bufEnd)
1.139 + {
1.140 + *alphaptr = 0xff;
1.141 + alphaptr+=4;
1.142 + }
1.143 +
1.144 + return;
1.145 + }
1.146 + CDrawBitmap::ReadLine(aX, aY, aLength, aBuffer, aDispMode);
1.147 + }
1.148 +
1.149 +void CDrawUTwentyFourBppBitmap::BlendRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
1.150 + {
1.151 + const TInt sourceAlpha = aColor.Alpha();
1.152 + if (sourceAlpha==255)// opaque
1.153 + {
1.154 + WriteRgbMulti(aX,aY,aLength,aHeight,aColor);
1.155 + return;
1.156 + }
1.157 + if (sourceAlpha==0)// transparent
1.158 + return;
1.159 +
1.160 + TUint32* pixelPtr = PixelAddress(aX,aY);
1.161 + TUint32* pixelRowPtrLimit = pixelPtr + (aHeight * iScanLineWords);
1.162 + TUint32* pixelPtrLimit = pixelPtr + aLength;
1.163 +
1.164 + const TUint32 sourceInternal=aColor.Internal();
1.165 + const TUint32 s_rb = sourceInternal & 0x00FF00FF;
1.166 + const TUint32 s_g = (sourceInternal & 0xFF00) >> 8;
1.167 + const TUint32 mask2 = sourceAlpha | (sourceAlpha << 16);
1.168 + while (pixelPtr < pixelRowPtrLimit)
1.169 + {
1.170 + for (TUint32* tempPixelPtr = pixelPtr; tempPixelPtr < pixelPtrLimit; tempPixelPtr++)
1.171 + {
1.172 + const TUint32 d = *tempPixelPtr;
1.173 + const TUint32 d_rb = d & 0x00FF00FF;
1.174 + const TUint32 rb = ((((sourceAlpha * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
1.175 +
1.176 + const TInt d_g = (d & 0xFF00) >> 8;
1.177 + const TInt g = ((sourceAlpha * (s_g - d_g)) >> 8) + d_g;
1.178 +
1.179 + *tempPixelPtr = rb | (g<<8) | 0xff000000;
1.180 + }
1.181 +
1.182 + pixelPtr += iScanLineWords;
1.183 + pixelPtrLimit += iScanLineWords;
1.184 + }
1.185 + }
1.186 +
1.187 +void CDrawUTwentyFourBppBitmap::BlendLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
1.188 + {
1.189 + TUint32* pixelPtr = PixelAddress(aX,aY);
1.190 +
1.191 + const TUint32* bufferPtrLimit = aBuffer + aLength;
1.192 + const TInt pixelPtrInc = (iOrientation == EOrientationNormal) ? 1 : PixelAddressIncrement();
1.193 +
1.194 + while (aBuffer < bufferPtrLimit)
1.195 + {
1.196 + if((*aBuffer &0xFF000000) == 0xFF000000)
1.197 + {
1.198 + *pixelPtr = *aBuffer;
1.199 + }
1.200 + else if((*aBuffer & 0xFF000000))
1.201 + {
1.202 + // specialization of pre-multiplied blending when the destination alpha is always 255
1.203 + const TUint32 src_rb = *aBuffer & 0x00FF00FF;
1.204 + const TUint32 src_g = *aBuffer & 0x0000FF00;
1.205 + const TUint32 mask = 0x100 - (*aBuffer >> 24);
1.206 + TUint32 dst_rb = *pixelPtr & 0x00FF00FF;
1.207 + TUint32 dst_g = *pixelPtr & 0x0000FF00;
1.208 + dst_rb = (src_rb + ((mask * dst_rb) >> 8)) & 0x00FF00FF;
1.209 + dst_g = (src_g + ((mask * dst_g) >> 8)) & 0x0000FF00;
1.210 + *pixelPtr = 0xFF000000 | dst_rb | dst_g;
1.211 + }
1.212 +
1.213 + aBuffer++;
1.214 + pixelPtr += pixelPtrInc;
1.215 + }
1.216 + }
1.217 +
1.218 +TRgb CDrawUTwentyFourBppBitmap::RgbColor(TUint32 aColor) const
1.219 + {
1.220 + return TRgb::_Color16MU(aColor);
1.221 + }
1.222 +
1.223 +TUint32 CDrawUTwentyFourBppBitmap::Color(const TRgb& aColor)
1.224 + {
1.225 + return aColor._Color16MA() | 0xff000000;
1.226 + }
1.227 +
1.228 +
1.229 +// Copies an EColor64K pixel to an EColor16MU screen
1.230 +FORCEINLINE static void CopyPixel(const TUint16*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
1.231 + {
1.232 + *aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
1.233 + aDestPtr += aPixelPtrInc;
1.234 + aSrcPtr++;
1.235 + }
1.236 +
1.237 +
1.238 +// Copies two EColor64K pixels to an EColor16MU screen
1.239 +FORCEINLINE static void CopyTwoPixels(const TUint32*& aSrcPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
1.240 + {
1.241 + const TUint16* scanPtr = reinterpret_cast<const TUint16*&>(aSrcPtr);
1.242 + *aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
1.243 + aDestPtr += aPixelPtrInc;
1.244 + scanPtr++;
1.245 + *aDestPtr = aHighAdd[(*scanPtr) >> 8] | aLowAdd[(*scanPtr) & 0xff];
1.246 + aDestPtr += aPixelPtrInc;
1.247 + aSrcPtr++;
1.248 + }
1.249 +
1.250 +
1.251 +// Copies an EColor16MU pixel to an EColor16MU screen if necessary.
1.252 +FORCEINLINE static void ProcessMaskPixel(const TUint32*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
1.253 + {
1.254 + if (aMaskWord & aSingleBitMask)
1.255 + {
1.256 + *aDestPtr = *aSrcPtr;
1.257 + }
1.258 + aSrcPtr++;
1.259 + aDestPtr += aPixelPtrInc;
1.260 + aSingleBitMask <<= 1;
1.261 + }
1.262 +
1.263 +
1.264 +// Copies an EColor64K pixel to an EColor16MU screen if necessary.
1.265 +FORCEINLINE static void ProcessMaskPixel(const TUint16*& aSrcPtr, const TUint32 aMaskWord, TUint32& aSingleBitMask, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
1.266 + {
1.267 + if (aMaskWord & aSingleBitMask)
1.268 + {
1.269 + *aDestPtr = aHighAdd[(*aSrcPtr) >> 8] | aLowAdd[(*aSrcPtr) & 0xff];
1.270 + }
1.271 + aSrcPtr++;
1.272 + aDestPtr += aPixelPtrInc;
1.273 + aSingleBitMask <<= 1;
1.274 + }
1.275 +
1.276 +
1.277 +// Alpha-blends an EColor16MU pixel to an EColor16MU screen using a fixed mask value.
1.278 +FORCEINLINE static void BlendAlphaPixel(const TUint32*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
1.279 + {
1.280 + const TUint32 s = *aSrcPtr++;
1.281 + const TUint32 d = *aDestPtr;
1.282 +
1.283 + // (a) (mask * src + (255 - mask) * dest) / 255 This ideal formula
1.284 + // (b) ((mask * (src - dest)) >> 8) + dest A faster approximation to (a)
1.285 + // (c) ((mask * (256 + src - dest) >> 8) + dest - mask Equivalent to (b) but can be used on multiple colors at a time
1.286 +
1.287 + const TUint32 s_rb = s & 0x00FF00FF;
1.288 + const TUint32 d_rb = d & 0x00FF00FF;
1.289 + const TUint32 mask2 = aMask | (aMask << 16);
1.290 + const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
1.291 +
1.292 + const TInt s_g = (s & 0xFF00) >> 8;
1.293 + const TInt d_g = (d & 0xFF00) >> 8;
1.294 + const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
1.295 +
1.296 + *aDestPtr = rb | (g<<8) | 0xff000000;
1.297 + aDestPtr += aPixelPtrInc;
1.298 + }
1.299 +
1.300 +
1.301 +// Alpha-blends an EColor16MU pixel to an EColor16MU screen if necessary.
1.302 +FORCEINLINE static void ProcessAlphaPixel(const TUint32*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc)
1.303 + {
1.304 + const TInt mask = *aMaskPtr++;
1.305 +
1.306 + if (!mask)
1.307 + {
1.308 + // pixel is masked
1.309 + aSrcPtr++;
1.310 + aDestPtr += aPixelPtrInc;
1.311 + }
1.312 + else if (mask == 0xFF)
1.313 + {
1.314 + // pixel is unmasked
1.315 + *aDestPtr = *aSrcPtr++;
1.316 + aDestPtr += aPixelPtrInc;
1.317 + }
1.318 + else
1.319 + {
1.320 + BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
1.321 + }
1.322 + }
1.323 +
1.324 +
1.325 +// Alpha-blends an EColor64K pixel to an EColor16MU screen using a fixed mask value.
1.326 +FORCEINLINE static void BlendAlphaPixel(const TUint16*& aSrcPtr, const TUint8 aMask, TUint32*& aDestPtr, TInt aPixelPtrInc)
1.327 + {
1.328 + const TUint32 s = *aSrcPtr++;
1.329 + const TUint32 d = *aDestPtr;
1.330 +
1.331 + // convert the source EColor64K red / blue pixels to EColor16MU
1.332 + // the top two bits in EColor64K are used to fill the bottom two bits in EColor16MU
1.333 +
1.334 + const TUint32 s_rb = ((s & 0xF800) << 8) | ((s & 0xE000) << 3) | ((s & 0x1F) << 3) | ((s & 0x1C) >>2);
1.335 + const TUint32 d_rb = d & 0x00FF00FF;
1.336 + const TUint32 mask2 = aMask | (aMask << 16);
1.337 + const TUint32 rb = ((((aMask * ((0x01000100 + s_rb) - d_rb)) >> 8) + d_rb) - mask2) & 0x00FF00FF;
1.338 +
1.339 + // convert the source EColor64K green pixel to EColor16MU
1.340 + const TInt s_g = ((s & 0x07E0) >> 3) | ((s & 0x0600) >> 9);
1.341 + const TInt d_g = (d & 0xFF00) >> 8;
1.342 + const TInt g = ((aMask * (s_g - d_g)) >> 8) + d_g;
1.343 +
1.344 + *aDestPtr = rb | (g<<8) | 0xff000000;
1.345 + aDestPtr += aPixelPtrInc;
1.346 + }
1.347 +
1.348 +
1.349 +// Alpha-blends an EColor64K pixel to an EColor16MU screen if necessary.
1.350 +FORCEINLINE static void ProcessAlphaPixel(const TUint16*& aSrcPtr, const TUint8*& aMaskPtr, TUint32*& aDestPtr, TInt aPixelPtrInc, const TUint32* aHighAdd, const TUint16* aLowAdd)
1.351 + {
1.352 + const TInt mask = *aMaskPtr++;
1.353 +
1.354 + if (!mask)
1.355 + {
1.356 + // pixel is masked
1.357 + aSrcPtr++;
1.358 + aDestPtr += aPixelPtrInc;
1.359 + }
1.360 + else if (mask == 0xFF)
1.361 + {
1.362 + // pixel is unmasked
1.363 + CopyPixel(aSrcPtr, aDestPtr, aPixelPtrInc, aHighAdd, aLowAdd);
1.364 + }
1.365 + else
1.366 + {
1.367 + BlendAlphaPixel(aSrcPtr, mask, aDestPtr, aPixelPtrInc);
1.368 + }
1.369 + }
1.370 +
1.371 +
1.372 +/**
1.373 +CDrawUTwentyFourBppBitmap::WriteAlphaLineEx() implementation.
1.374 +@internalTechnology
1.375 +@see MFastBlit::WriteAlphaLineEx()
1.376 +*/
1.377 +void CDrawUTwentyFourBppBitmap::WriteAlphaLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
1.378 + const TUint32* aSrcPtr, TDisplayMode aSrcFormat,
1.379 + TInt aMaskX, const TUint32* aMaskPtr,
1.380 + MAlphaBlend::TShadowing aShadowing)
1.381 + {
1.382 + // Only certain pixel formats are supported. Caller should check this.
1.383 + __ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
1.384 +
1.385 + DeOrientate(aX,aY);
1.386 + TUint32* pixelPtr = PixelAddress(aX,aY);
1.387 + const TInt pixelPtrInc = PixelAddressIncrement();
1.388 +
1.389 + if (aSrcFormat==EColor16MU)
1.390 + {
1.391 + if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)) )
1.392 + {
1.393 + aSrcPtr += aSrcX;
1.394 + const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
1.395 + const TInt startBit = aMaskX & 0x3;
1.396 +
1.397 + if (startBit)
1.398 + {
1.399 + // Process initial incomplete mask word
1.400 + const TUint32 maskWord = *maskWordPtr++;
1.401 + TInt numPix = Min(aLength, 4 - startBit); // number of pixels to process from the first word of the mask
1.402 + aLength -= numPix;
1.403 +
1.404 + if (!maskWord)
1.405 + {
1.406 + // maskWord is fully masked - skip the pixels
1.407 + aSrcPtr += numPix;
1.408 + pixelPtr += pixelPtrInc * numPix;
1.409 + }
1.410 + else if (maskWord == 0xFFFFFFFF)
1.411 + {
1.412 + // maskWord is fully unmasked - copy the pixels
1.413 + while (numPix--)
1.414 + {
1.415 + *pixelPtr = *aSrcPtr++;
1.416 + pixelPtr += pixelPtrInc;
1.417 + }
1.418 + }
1.419 + else
1.420 + {
1.421 + // At least one of the pixels needs to be blended
1.422 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
1.423 + maskPtr8 += startBit;
1.424 + while (numPix--)
1.425 + {
1.426 + ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
1.427 + }
1.428 + }
1.429 + }
1.430 +
1.431 + TInt numMaskWords = aLength >> 2;
1.432 + aLength &= 0x3;
1.433 + while (numMaskWords--)
1.434 + {
1.435 + // Process a complete mask word - 4 pixels
1.436 + const TUint32 maskWord = *maskWordPtr++;
1.437 +
1.438 + if (!maskWord)
1.439 + {
1.440 + // maskWord is fully masked - skip 4 pixels
1.441 + aSrcPtr += 4;
1.442 + pixelPtr += pixelPtrInc << 2;
1.443 + }
1.444 + else if (maskWord == 0xFFFFFFFF)
1.445 + {
1.446 + // maskWord is fully unmasked - copy 4 pixels
1.447 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.448 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.449 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.450 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.451 + }
1.452 + else
1.453 + {
1.454 + // At least one of the 4 pixels needs to be blended
1.455 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
1.456 +
1.457 + if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
1.458 + maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
1.459 + maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
1.460 + maskPtr8[3] && (maskPtr8[3] != 0xFF))
1.461 + {
1.462 + // Blend all 4 pixels inline
1.463 + BlendAlphaPixel(aSrcPtr, maskPtr8[0], pixelPtr, pixelPtrInc);
1.464 + BlendAlphaPixel(aSrcPtr, maskPtr8[1], pixelPtr, pixelPtrInc);
1.465 + BlendAlphaPixel(aSrcPtr, maskPtr8[2], pixelPtr, pixelPtrInc);
1.466 + BlendAlphaPixel(aSrcPtr, maskPtr8[3], pixelPtr, pixelPtrInc);
1.467 + }
1.468 + else
1.469 + {
1.470 + ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
1.471 + ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
1.472 + ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
1.473 + ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
1.474 + }
1.475 + }
1.476 + }
1.477 +
1.478 + if (aLength)
1.479 + {
1.480 + const TUint32 maskWord = *maskWordPtr;
1.481 + if (!maskWord)
1.482 + {
1.483 + // maskWord is fully masked - skip the pixels
1.484 + return;
1.485 + }
1.486 + if (maskWord == 0xFFFFFFFF)
1.487 + {
1.488 + // maskWord is fully unmasked - copy the pixels
1.489 + while (aLength--)
1.490 + {
1.491 + *pixelPtr = *aSrcPtr++;
1.492 + pixelPtr += pixelPtrInc;
1.493 + }
1.494 + }
1.495 + else
1.496 + {
1.497 + // At least one of the pixels needs to be blended
1.498 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
1.499 + while (aLength--)
1.500 + {
1.501 + ProcessAlphaPixel(aSrcPtr, maskPtr8, pixelPtr, pixelPtrInc);
1.502 + }
1.503 + }
1.504 + }
1.505 + }
1.506 + else
1.507 + {
1.508 + // Non-optimised path including shadowing and UserDisplayMode conversion
1.509 + const TUint8* srcPtr8 = reinterpret_cast<const TUint8*>(aSrcPtr + aSrcX);
1.510 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
1.511 +
1.512 + while (aLength--)
1.513 + {
1.514 + TInt mask = *maskPtr8++;
1.515 + if (mask)
1.516 + {
1.517 + TInt b = srcPtr8[0];
1.518 + TInt g = srcPtr8[1];
1.519 + TInt r = srcPtr8[2];
1.520 + if(aShadowing == MAlphaBlend::EShdwBefore)
1.521 + {
1.522 + if (iShadowMode & EFade)
1.523 + {
1.524 + r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.525 + g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.526 + b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.527 + }
1.528 + if (iShadowMode & EShadow)
1.529 + {
1.530 + r = (Max(0,r-0x40));
1.531 + g = (Max(0,g-0x40));
1.532 + b = (Max(0,b-0x40));
1.533 + }
1.534 + }
1.535 + if (mask != 0xff)
1.536 + {
1.537 + // (mask * r + (255 - mask) * value) / 255 =
1.538 + // ((257 * mask * (r - value)) >> 16) + value
1.539 + TInt value = *pixelPtr & 0xffffff;
1.540 + mask = (mask << 8) + mask; // mask = mask * 257
1.541 + TInt v = value >> 16;
1.542 + r = ((mask * (r - v)) >> 16) + v;
1.543 + v = (value >> 8) & 0xff;
1.544 + g = ((mask * (g - v)) >> 16) + v;
1.545 + v = value & 0xff;
1.546 + b = ((mask * (b - v)) >> 16) + v;
1.547 + }
1.548 + if(aShadowing == MAlphaBlend::EShdwAfter)
1.549 + {
1.550 + if (iShadowMode & EFade)
1.551 + {
1.552 + r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.553 + g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.554 + b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.555 + }
1.556 + if (iShadowMode & EShadow)
1.557 + {
1.558 + r = (Max(0,r-0x40));
1.559 + g = (Max(0,g-0x40));
1.560 + b = (Max(0,b-0x40));
1.561 + }
1.562 + }
1.563 + // Convert colour if an incompatible UserDisplayMode is being used
1.564 + CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
1.565 + *pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
1.566 + }
1.567 + pixelPtr += pixelPtrInc;
1.568 + srcPtr8 += 4;
1.569 + }
1.570 + }
1.571 + return;
1.572 + }
1.573 + else // (aSrcFormat==EColor64K)
1.574 + {
1.575 + const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
1.576 +
1.577 + if (!(iShadowMode & EFade) && !(iShadowMode & EShadow) && ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU)))
1.578 + {
1.579 + const TUint16* lowAdd = Convert16to32bppLow();
1.580 + const TUint32* highAdd = Convert16to32bppHigh();
1.581 + const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 2);
1.582 + const TInt startBit = aMaskX & 0x3;
1.583 +
1.584 + if (startBit)
1.585 + {
1.586 + // Process initial incomplete mask word
1.587 + const TUint32 maskWord = *maskWordPtr++;
1.588 + TInt numPix = Min(aLength, 4 - startBit); // number of pixels to process from the first word of the mask
1.589 + aLength -= numPix;
1.590 +
1.591 + if (!maskWord)
1.592 + {
1.593 + // maskWord is fully masked
1.594 + srcPtr16 += numPix;
1.595 + pixelPtr += pixelPtrInc * numPix;
1.596 + }
1.597 + else if (maskWord == 0xFFFFFFFF)
1.598 + {
1.599 + // maskWord is fully unmasked
1.600 + while (numPix--)
1.601 + {
1.602 + CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.603 + }
1.604 + }
1.605 + else
1.606 + {
1.607 + // At least one of the pixels needs to be blended
1.608 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
1.609 + maskPtr8 += startBit;
1.610 + while (numPix--)
1.611 + {
1.612 + ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.613 + }
1.614 + }
1.615 + }
1.616 +
1.617 + TInt numMaskWords = aLength >> 2;
1.618 + aLength &= 0x3;
1.619 + while (numMaskWords--)
1.620 + {
1.621 + // Process 4 mask pixels
1.622 + const TUint32 maskWord = *maskWordPtr++;
1.623 +
1.624 + if (!maskWord)
1.625 + {
1.626 + // maskWord is fully masked - skip 4 pixels
1.627 + srcPtr16 += 4;
1.628 + pixelPtr += pixelPtrInc << 2;
1.629 + }
1.630 + else if (maskWord == 0xFFFFFFFF)
1.631 + {
1.632 + // maskWord is fully unmasked - copy and convert 4 pixels
1.633 + const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
1.634 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.635 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.636 + srcPtr16 = (const TUint16*)srcPtr32;
1.637 + }
1.638 + else
1.639 + {
1.640 + // At least one of the 4 pixels needs to be blended
1.641 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
1.642 +
1.643 + if (maskPtr8[0] && (maskPtr8[0] != 0xFF) &&
1.644 + maskPtr8[1] && (maskPtr8[1] != 0xFF) &&
1.645 + maskPtr8[2] && (maskPtr8[2] != 0xFF) &&
1.646 + maskPtr8[3] && (maskPtr8[3] != 0xFF))
1.647 + {
1.648 + // Blend all 4 pixels inline
1.649 + BlendAlphaPixel(srcPtr16, maskPtr8[0], pixelPtr, pixelPtrInc);
1.650 + BlendAlphaPixel(srcPtr16, maskPtr8[1], pixelPtr, pixelPtrInc);
1.651 + BlendAlphaPixel(srcPtr16, maskPtr8[2], pixelPtr, pixelPtrInc);
1.652 + BlendAlphaPixel(srcPtr16, maskPtr8[3], pixelPtr, pixelPtrInc);
1.653 + }
1.654 + else
1.655 + {
1.656 + ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.657 + ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.658 + ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.659 + ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.660 + }
1.661 + }
1.662 + }
1.663 +
1.664 + if (aLength)
1.665 + {
1.666 + // Process final incomplete mask word
1.667 + const TUint32 maskWord = *maskWordPtr; // this will over-read
1.668 + if (!maskWord)
1.669 + {
1.670 + // maskWord is fully masked - skip the pixels
1.671 + return;
1.672 + }
1.673 + if (maskWord == 0xFFFFFFFF)
1.674 + {
1.675 + // maskWord is fully unmasked - copy and convert the pixels
1.676 + while (aLength--)
1.677 + {
1.678 + CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.679 + }
1.680 + }
1.681 + else
1.682 + {
1.683 + // At least one of the pixels needs to be blended
1.684 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(&maskWord);
1.685 + while (aLength--)
1.686 + {
1.687 + ProcessAlphaPixel(srcPtr16, maskPtr8, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.688 + }
1.689 + }
1.690 + }
1.691 + }
1.692 + else
1.693 + {
1.694 + // Non-optimised path including shadowing and UserDisplayMode conversion
1.695 + const TUint8* maskPtr8 = reinterpret_cast<const TUint8*>(aMaskPtr) + aMaskX;
1.696 + while (aLength--)
1.697 + {
1.698 + TInt mask = *maskPtr8++;
1.699 + if (mask)
1.700 + {
1.701 + const TUint32 src = *srcPtr16;
1.702 + TInt r = (src & 0xF800) >> 8;
1.703 + r |= (src & 0xE000) >>13;
1.704 + TInt g = (src & 0x07E0) >> 3;
1.705 + g |= (src & 0x0600) >> 9;
1.706 + TInt b = (src & 0x001F) << 3;
1.707 + b |= (src & 0x001C) >> 2;
1.708 +
1.709 + if(aShadowing == MAlphaBlend::EShdwBefore)
1.710 + {
1.711 + if (iShadowMode & EFade)
1.712 + {
1.713 + r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.714 + g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.715 + b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.716 + }
1.717 + if (iShadowMode & EShadow)
1.718 + {
1.719 + r = Max(0,r-0x40);
1.720 + g = Max(0,g-0x40);
1.721 + b = Max(0,b-0x40);
1.722 + }
1.723 + }
1.724 + if (mask != 0xff)
1.725 + {
1.726 + // (mask * r + (255 - mask) * value) / 255 =
1.727 + // ((257 * mask * (r - value)) >> 16) + value
1.728 + const TInt value = *pixelPtr & 0xffffff;
1.729 + mask = (mask << 8) + mask; // mask = mask * 257
1.730 + TInt v = value >> 16;
1.731 + r = ((mask * (r - v)) >> 16) + v;
1.732 + v = (value >> 8) & 0xff;
1.733 + g = ((mask * (g - v)) >> 16) + v;
1.734 + v = value & 0xff;
1.735 + b = ((mask * (b - v)) >> 16) + v;
1.736 + }
1.737 + if(aShadowing == MAlphaBlend::EShdwAfter)
1.738 + {
1.739 + if (iShadowMode & EFade)
1.740 + {
1.741 + r = ((r * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.742 + g = ((g * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.743 + b = ((b * iFadeMapFactor) >> 8) + iFadeMapOffset;
1.744 + }
1.745 + if (iShadowMode & EShadow)
1.746 + {
1.747 + r = Max(0,r-0x40);
1.748 + g = Max(0,g-0x40);
1.749 + b = Max(0,b-0x40);
1.750 + }
1.751 + }
1.752 + // Convert colour if an incompatible UserDisplayMode is being used
1.753 + CDrawBitmap::MapColorToUserDisplayMode(r,g,b);
1.754 + *pixelPtr = (r<<16) | (g<<8) | b | 0xff000000;
1.755 + }
1.756 + srcPtr16++;
1.757 + pixelPtr += pixelPtrInc;
1.758 + }
1.759 + }
1.760 + return;
1.761 + }
1.762 + }
1.763 +
1.764 +/**
1.765 +CDrawUTwentyFourBppBitmap::WriteMaskLineEx() implementation.
1.766 +@internalTechnology
1.767 +@see MFastBlit::WriteMaskLineEx()
1.768 +*/
1.769 +void CDrawUTwentyFourBppBitmap::WriteMaskLineEx(TInt aX, TInt aY, TInt aLength, TInt aSrcX,
1.770 + const TUint32* aSrcPtr, TDisplayMode aSrcFormat,
1.771 + TInt aMaskX, const TUint32* aMaskPtr, TBool aInvertMask)
1.772 + {
1.773 + // Only certain pixel formats are supported. Caller should check this.
1.774 + __ASSERT_DEBUG(aSrcFormat ==EColor16MU || aSrcFormat ==EColor64K, User::Invariant());
1.775 +
1.776 + DeOrientate(aX,aY);
1.777 + TUint32* pixelPtr = PixelAddress(aX,aY);
1.778 + const TInt pixelPtrInc = PixelAddressIncrement();
1.779 + const TUint32 invertWord = (aInvertMask ? 0xFFFFFFFF : 0); // to be XORed with the mask
1.780 +
1.781 + if (aSrcFormat==EColor16MU)
1.782 + {
1.783 + aSrcPtr += aSrcX;
1.784 +
1.785 + if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
1.786 + {
1.787 + const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
1.788 + const TInt startBit = aMaskX & 0x1F;
1.789 +
1.790 + if (startBit)
1.791 + {
1.792 + // Process initial incomplete mask word
1.793 + TUint32 maskWord = *maskWordPtr++;
1.794 + maskWord ^= invertWord;
1.795 + TInt numPix = Min(aLength, 32 - startBit); // number of pixels to process from the first word of the mask
1.796 + aLength -= numPix;
1.797 +
1.798 + if (!maskWord)
1.799 + {
1.800 + // maskWord is fully masked - skip the pixels
1.801 + aSrcPtr += numPix;
1.802 + pixelPtr += pixelPtrInc * numPix;
1.803 + }
1.804 + else if (maskWord == 0xFFFFFFFF)
1.805 + {
1.806 + // maskWord is fully unmasked - copy the pixels
1.807 + while (numPix--)
1.808 + {
1.809 + *pixelPtr = *aSrcPtr++;
1.810 + pixelPtr += pixelPtrInc;
1.811 + }
1.812 + }
1.813 + else
1.814 + {
1.815 + // maskWord is partially masked - process each pixel
1.816 + TUint32 singleBitMask = 1 << startBit;
1.817 + while (numPix--)
1.818 + {
1.819 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.820 + }
1.821 + }
1.822 + }
1.823 +
1.824 + TInt numMaskWords = aLength >> 5;
1.825 + aLength &= 0x1F;
1.826 + while (numMaskWords--)
1.827 + {
1.828 + // Process a complete mask word (32 pixels)
1.829 + TUint32 maskWord = *maskWordPtr++;
1.830 + maskWord ^= invertWord;
1.831 +
1.832 + if (!maskWord)
1.833 + {
1.834 + // maskWord is fully masked - skip 32 pixels
1.835 + aSrcPtr += 32;
1.836 + pixelPtr += pixelPtrInc << 5;
1.837 + }
1.838 + else if (maskWord == 0xFFFFFFFF)
1.839 + {
1.840 + // maskWord is fully unmasked - copy 32 pixels
1.841 + if (pixelPtrInc==1)
1.842 + {
1.843 + pixelPtr=(TUint32*)Mem::Move(pixelPtr, aSrcPtr, 128);
1.844 + aSrcPtr+= 32;
1.845 + }
1.846 + else
1.847 + {
1.848 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.849 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.850 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.851 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.852 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.853 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.854 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.855 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.856 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.857 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.858 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.859 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.860 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.861 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.862 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.863 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.864 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.865 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.866 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.867 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.868 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.869 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.870 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.871 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.872 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.873 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.874 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.875 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.876 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.877 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.878 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.879 + *pixelPtr = *aSrcPtr++; pixelPtr += pixelPtrInc;
1.880 + }
1.881 + }
1.882 + else
1.883 + {
1.884 + // maskWord is partially masked - process each of the 32 pixels
1.885 + TUint32 singleBitMask = 1;
1.886 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.887 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.888 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.889 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.890 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.891 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.892 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.893 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.894 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.895 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.896 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.897 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.898 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.899 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.900 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.901 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.902 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.903 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.904 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.905 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.906 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.907 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.908 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.909 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.910 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.911 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.912 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.913 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.914 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.915 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.916 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.917 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.918 + }
1.919 + }
1.920 +
1.921 +
1.922 + if (aLength)
1.923 + {
1.924 + // Process final incomplete mask word
1.925 + TUint32 maskWord = *maskWordPtr;
1.926 + maskWord ^= invertWord;
1.927 +
1.928 + if (!maskWord)
1.929 + {
1.930 + // maskWord is fully masked - skip the pixels
1.931 + return;
1.932 + }
1.933 + if (maskWord == 0xFFFFFFFF)
1.934 + {
1.935 + // maskWord is fully unmasked - copy the pixels
1.936 + while (aLength--)
1.937 + {
1.938 + *pixelPtr = *aSrcPtr++;
1.939 + pixelPtr += pixelPtrInc;
1.940 + }
1.941 + }
1.942 + else
1.943 + {
1.944 + // maskWord is partially masked - process each pixel
1.945 + TUint32 singleBitMask = 1;
1.946 + while (aLength--)
1.947 + {
1.948 + ProcessMaskPixel(aSrcPtr, maskWord, singleBitMask, pixelPtr, pixelPtrInc);
1.949 + }
1.950 + }
1.951 + }
1.952 + }
1.953 + else
1.954 + {
1.955 + // Non-optimised path. UserDisplay mode is different to the true display mode
1.956 + while (aLength--)
1.957 + {
1.958 + TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
1.959 + if (aInvertMask)
1.960 + {
1.961 + mask = !mask;
1.962 + }
1.963 + if (mask)
1.964 + {
1.965 + TRgb pixel(*aSrcPtr);
1.966 + MapColorToUserDisplayMode(pixel);
1.967 + *pixelPtr = pixel.Value();
1.968 + }
1.969 + aSrcPtr++;
1.970 + aMaskX++;
1.971 + pixelPtr += pixelPtrInc;
1.972 + }
1.973 + }
1.974 + return;
1.975 + }
1.976 + else // (aSrcFormat==EColor64K)
1.977 + {
1.978 + const TUint16* srcPtr16 = reinterpret_cast<const TUint16*>(aSrcPtr) + aSrcX;
1.979 +
1.980 + if ((iUserDispMode==ENone) || (iUserDispMode==EColor16MU))
1.981 + {
1.982 + const TUint16* lowAdd = Convert16to32bppLow();
1.983 + const TUint32* highAdd = Convert16to32bppHigh();
1.984 + const TUint32* maskWordPtr = aMaskPtr + (aMaskX >> 5);
1.985 + const TInt startBit = aMaskX & 0x1F;
1.986 +
1.987 + if (startBit)
1.988 + {
1.989 + // Process initial incomplete mask word
1.990 + TUint32 maskWord = *maskWordPtr++;
1.991 + maskWord ^= invertWord;
1.992 + TInt numPix = Min(aLength, 32 - startBit); // number of pixels to process from the first word of the mask
1.993 + aLength -= numPix;
1.994 +
1.995 + if (!maskWord)
1.996 + {
1.997 + // maskWord is fully masked - skip the pixels
1.998 + srcPtr16 += numPix;
1.999 + pixelPtr += pixelPtrInc * numPix;
1.1000 + }
1.1001 + else if (maskWord == 0xFFFFFFFF)
1.1002 + {
1.1003 + // maskWord is fully unmasked - copy and convert the pixels
1.1004 + while (numPix--)
1.1005 + {
1.1006 + CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1007 + }
1.1008 + }
1.1009 + else
1.1010 + {
1.1011 + // maskWord is partially masked - process each of the pixels
1.1012 + TUint32 singleBitMask = 1 << startBit;
1.1013 + while (numPix--)
1.1014 + {
1.1015 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1016 + }
1.1017 + }
1.1018 + }
1.1019 +
1.1020 + TInt numMaskWords = aLength >> 5;
1.1021 + aLength &= 0x1F;
1.1022 + while (numMaskWords--)
1.1023 + {
1.1024 + // Process complete mask words
1.1025 + TUint32 maskWord = *maskWordPtr++;
1.1026 + maskWord ^= invertWord;
1.1027 +
1.1028 + if (!maskWord)
1.1029 + {
1.1030 + // maskWord is fully masked - skip 32 pixels
1.1031 + srcPtr16 += 32;
1.1032 + pixelPtr += pixelPtrInc << 5;
1.1033 + }
1.1034 + else if (maskWord == 0xFFFFFFFF)
1.1035 + {
1.1036 + // maskWord is fully unmasked - copy and convert 32 pixels
1.1037 + const TUint32* srcPtr32 = (const TUint32*)srcPtr16;
1.1038 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1039 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1040 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1041 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1042 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1043 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1044 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1045 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1046 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1047 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1048 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1049 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1050 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1051 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1052 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1053 + CopyTwoPixels(srcPtr32, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1054 + srcPtr16 = (const TUint16*)srcPtr32;
1.1055 + }
1.1056 + else
1.1057 + {
1.1058 + // maskWord is partially masked - process each of the 32 pixels
1.1059 + TUint32 singleBitMask = 1;
1.1060 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1061 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1062 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1063 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1064 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1065 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1066 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1067 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1068 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1069 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1070 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1071 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1072 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1073 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1074 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1075 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1076 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1077 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1078 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1079 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1080 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1081 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1082 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1083 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1084 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1085 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1086 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1087 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1088 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1089 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1090 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1091 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1092 + }
1.1093 + }
1.1094 +
1.1095 + if (aLength)
1.1096 + {
1.1097 + // Process final incomplete mask word
1.1098 + TUint32 maskWord = *maskWordPtr; // this will over-read
1.1099 + maskWord ^= invertWord;
1.1100 +
1.1101 + if (!maskWord)
1.1102 + {
1.1103 + // maskWord is masked - skip the pixels
1.1104 + return;
1.1105 + }
1.1106 +
1.1107 + if (maskWord == 0xFFFFFFFF)
1.1108 + {
1.1109 + // maskWord is fully unmasked - copy and convert the pixels
1.1110 + while (aLength--)
1.1111 + {
1.1112 + CopyPixel(srcPtr16, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1113 + }
1.1114 + }
1.1115 + else
1.1116 + {
1.1117 + // maskWord is partially masked - process each of the pixels
1.1118 + TUint32 singleBitMask = 1;
1.1119 + while (aLength--)
1.1120 + {
1.1121 + ProcessMaskPixel(srcPtr16, maskWord, singleBitMask, pixelPtr, pixelPtrInc, highAdd, lowAdd);
1.1122 + }
1.1123 + }
1.1124 + }
1.1125 + }
1.1126 + else
1.1127 + {
1.1128 + // Non-optimised - expects aMaskPtr untouched and srcPtr16 to be accurate
1.1129 + while (aLength--)
1.1130 + {
1.1131 + TUint32 mask = *(aMaskPtr + (aMaskX >> 5)) & (1 << (aMaskX & 0x1F));
1.1132 + if (aInvertMask)
1.1133 + {
1.1134 + mask = !mask;
1.1135 + }
1.1136 + if (mask)
1.1137 + {
1.1138 + const TUint32 src = *srcPtr16;
1.1139 + TUint32 color = (src & 0xF800) << 8; // R top 5
1.1140 + color |= (src & 0xE000) << 3; // R bottom 3
1.1141 + color |= (src & 0x07E0) << 5; // G top 6
1.1142 + color |= (src & 0x0600) >> 1; // G bottom 2
1.1143 + color |= (src & 0x001F) << 3; // B top 5
1.1144 + color |= (src & 0x001C) >> 2; // B bottom 3
1.1145 + TRgb pixel(color);
1.1146 + MapColorToUserDisplayMode(pixel);
1.1147 + *pixelPtr = pixel.Value();
1.1148 + }
1.1149 + pixelPtr += pixelPtrInc;
1.1150 + srcPtr16++;
1.1151 + aMaskX++;
1.1152 + }
1.1153 + }
1.1154 + return;
1.1155 + }
1.1156 + }
1.1157 +
1.1158 +/**
1.1159 +Implementation for CFbsDrawDevice::GetInterface().
1.1160 +Retrieves a pointer to a specified interface of CFbsDrawDevice implementation.
1.1161 +@param aInterfaceId Interface identifier of the interface to be retrieved.
1.1162 +@param aInterface Address of variable that retrieves the specified interface.
1.1163 +@return KErrNone If the interface is supported, KErrNotSupported otherwise.
1.1164 +*/
1.1165 +TInt CDrawUTwentyFourBppBitmap::GetInterface(TInt aInterfaceId, TAny*& aInterface)
1.1166 + {
1.1167 + aInterface = NULL;
1.1168 + TInt ret = KErrNotSupported;
1.1169 +
1.1170 + switch (aInterfaceId)
1.1171 + {
1.1172 + case KFastBlitInterfaceID:
1.1173 + {
1.1174 + aInterface = static_cast<MFastBlit*>(this);
1.1175 + ret = KErrNone;
1.1176 + break;
1.1177 + }
1.1178 + default:
1.1179 + {
1.1180 + return CDrawThirtyTwoBppBitmapCommon::GetInterface(aInterfaceId, aInterface);
1.1181 + }
1.1182 + }
1.1183 +
1.1184 + return ret;
1.1185 + }
1.1186 +
1.1187 +TInt CDrawUTwentyFourBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
1.1188 + TUint32 aOutlinePenColor, TUint32 aShadowColor,
1.1189 + TUint32 aFillColor, const TUint8* aDataBuffer)
1.1190 + {
1.1191 + DeOrientate(aX,aY);
1.1192 + TUint32* pixelPtr = PixelAddress(aX,aY);
1.1193 + const TInt pixelPtrInc = PixelAddressIncrement();
1.1194 + const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
1.1195 + TInt blendedRedColor;
1.1196 + TInt blendedGreenColor;
1.1197 + TInt blendedBlueColor;
1.1198 + TInt blendedAlpha;
1.1199 + TUint8 index = 0;
1.1200 + TUint32 finalColor;
1.1201 + const TUint16* normTable = PtrTo16BitNormalisationTable();
1.1202 +
1.1203 + //Get red color. Equivalent to TRgb::Red()
1.1204 + const TInt redOutlinePenColor = (aOutlinePenColor & 0xff0000) >> 16;
1.1205 + const TInt redShadowColor = (aShadowColor & 0xff0000) >> 16;
1.1206 + const TInt redFillColor = (aFillColor & 0xff0000) >> 16;
1.1207 +
1.1208 + //Get green color. Equivalent to TRgb::Green()
1.1209 + const TInt greenOutlinePenColor = (aOutlinePenColor & 0xff00) >> 8;
1.1210 + const TInt greenShadowColor = (aShadowColor & 0xff00) >> 8;
1.1211 + const TInt greenFillColor = (aFillColor & 0xff00) >> 8;
1.1212 +
1.1213 + //Get blue color. Equivalent to TRgb::Blue()
1.1214 + const TInt blueOutlinePenColor = aOutlinePenColor & 0xff;
1.1215 + const TInt blueShadowColor = aShadowColor & 0xff;
1.1216 + const TInt blueFillColor = aFillColor & 0xff;
1.1217 +
1.1218 + //Get alpha color. Equivalent to TRgb::Alpha()
1.1219 + const TInt alphaOutlinePenColor = aOutlinePenColor >> 24;
1.1220 + const TInt alphaShadowColor = aShadowColor >> 24;
1.1221 + const TInt alphaFillColor = aFillColor >> 24;
1.1222 +
1.1223 + while (aDataBuffer < dataBufferPtrLimit)
1.1224 + {
1.1225 + index = *aDataBuffer++;
1.1226 + if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
1.1227 + {
1.1228 + //background colour
1.1229 + //No drawing required
1.1230 + }
1.1231 + else if (255 == FourColorBlendLookup[index][KFillColorIndex])
1.1232 + {
1.1233 + //Use fill colour to draw
1.1234 + finalColor = aFillColor;
1.1235 + AlphaBlendPixelToDest((finalColor | 0xff000000), alphaFillColor, pixelPtr);
1.1236 + }
1.1237 + else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
1.1238 + {
1.1239 + //Use shadow colour to draw
1.1240 + finalColor = aShadowColor;
1.1241 + AlphaBlendPixelToDest((finalColor | 0xff000000), alphaShadowColor, pixelPtr);
1.1242 + }
1.1243 + else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
1.1244 + {
1.1245 + //Use outline colour to draw
1.1246 + finalColor = aOutlinePenColor;
1.1247 + AlphaBlendPixelToDest((finalColor | 0xff000000), alphaOutlinePenColor, pixelPtr);
1.1248 + }
1.1249 + else
1.1250 + {
1.1251 + blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor +
1.1252 + redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
1.1253 + redFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
1.1254 +
1.1255 + blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor +
1.1256 + greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
1.1257 + greenFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
1.1258 +
1.1259 + blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] * alphaOutlinePenColor +
1.1260 + blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] * alphaShadowColor +
1.1261 + blueFillColor * FourColorBlendLookup[index][KFillColorIndex] * alphaFillColor) >> 16;
1.1262 +
1.1263 + blendedAlpha = (alphaOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
1.1264 + alphaShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
1.1265 + alphaFillColor * FourColorBlendLookup[index][KFillColorIndex]) >> 8;
1.1266 +
1.1267 + finalColor = PMA2NonPMAPixel((blendedAlpha << 24) | (blendedRedColor << 16) | (blendedGreenColor << 8) | blendedBlueColor, normTable);
1.1268 + AlphaBlendPixelToDest(finalColor | 0xff000000, blendedAlpha, pixelPtr);
1.1269 + }
1.1270 + pixelPtr += pixelPtrInc;
1.1271 + }
1.1272 + return KErrNone;
1.1273 + }