1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/graphicsdeviceinterface/screendriver/sbit/BMDRAW1.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,936 @@
1.4 +// Copyright (c) 1997-2009 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 +
1.21 +const TInt KPixelsPerByte = 8;
1.22 +const TInt KPixelsPerWord = 32;
1.23 +
1.24 +//Initializes iSize, iDrawRect, iLongWidth, iScanlineWords data members.
1.25 +//It should be called every time when iSize is going to be changed - from Construct().
1.26 +//@param aSize Physical screen size in pixels.
1.27 +//@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the
1.28 +//device is scaled and the scaling origin goes outside physical drawing rectangle.
1.29 +void CDrawOneBppBitmap::SetSize(const TSize& aSize)
1.30 + {
1.31 + CDrawBitmap::SetSize(aSize);
1.32 + __ASSERT_DEBUG(iSize == aSize, User::Invariant());
1.33 + iLongWidth = (iSize.iWidth + (KPixelsPerWord - 1)) & ~(KPixelsPerWord - 1);
1.34 + iScanLineWords = iLongWidth / KPixelsPerWord;
1.35 + }
1.36 +
1.37 +TInt CDrawOneBppBitmap::Construct(TSize aSize)
1.38 + {
1.39 + return Construct(aSize, ((aSize.iWidth + (KPixelsPerWord - 1)) & ~(KPixelsPerWord - 1)) / KPixelsPerByte);
1.40 + }
1.41 +
1.42 +TInt CDrawOneBppBitmap::Construct(TSize aSize, TInt aStride)
1.43 + {
1.44 + iBits = NULL;
1.45 + iDispMode = EGray2;
1.46 + CDrawBitmap::SetSize(aSize);
1.47 + __ASSERT_DEBUG(iSize == aSize, User::Invariant());
1.48 + if (aStride & 3)
1.49 + return KErrArgument;
1.50 + iLongWidth = aStride * KPixelsPerByte;
1.51 + if (iLongWidth < aSize.iWidth)
1.52 + return KErrArgument;
1.53 + iScanLineWords = aStride >> 2;
1.54 + TInt size = 1 + (Max(aSize.iWidth,aSize.iHeight) >> 3);
1.55 + if(size < 0)
1.56 + return KErrArgument;
1.57 + iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size));
1.58 + if (iScanLineBuffer == NULL)
1.59 + return KErrNoMemory;
1.60 + return KErrNone;
1.61 + }
1.62 +
1.63 +void CDrawOneBppBitmap::Shadow(TRgb& aColor)
1.64 + {
1.65 + if (iShadowMode & EFade)
1.66 + aColor = FadeRgb(TRgb::_Gray2(aColor._Gray2()));
1.67 +
1.68 + if (iShadowMode & EShadow)
1.69 + aColor = KRgbBlack;
1.70 + }
1.71 +
1.72 +void CDrawOneBppBitmap::InvertBuffer(TInt aLength,TUint32* aBuffer)
1.73 + {
1.74 + __ASSERT_DEBUG(aLength > 0,Panic(EScreenDriverPanicZeroLength));
1.75 + __ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
1.76 +
1.77 + const TUint32* const limit = aBuffer + ((aLength + KPixelsPerWord - 1) / KPixelsPerWord);
1.78 +
1.79 + while (aBuffer < limit)
1.80 + *aBuffer++ ^= 0xffffffff;
1.81 + }
1.82 +
1.83 +/** Copies a number of pixels into a word-aligned buffer without format translation.
1.84 + Note that the byte length to the target buffer is honoured,
1.85 + but the end contents of the last byte are generally overwritten with extra pixel data (or garbage)
1.86 + Note that I am assuming the compiler optimiser will convert all these divides and multiplies into shifts!
1.87 +@param aX x coordinate to start copy from (need not be aligned at all)
1.88 +@param aY y coordinate to copy line from
1.89 +@param aLength number of pixels to copy
1.90 +@param aBuffer target word-aligned buffer (but may or may not be word length)
1.91 + **/
1.92 +void CDrawOneBppBitmap::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const
1.93 + {
1.94 + TUint32* pixelPtr = ScanLine(aY);
1.95 + TInt startLongPix = aX & -KPixelsPerWord;
1.96 + pixelPtr += startLongPix / KPixelsPerWord;
1.97 + TUint32* bufferPtr = (TUint32*)aBuffer;
1.98 + TInt wordsCnt = (aLength+KPixelsPerByte-1) / KPixelsPerWord; //how many words to write to target
1.99 + TInt restPixels = aLength - wordsCnt * KPixelsPerWord; //how many pixels left to copy
1.100 + TInt bytesCnt = (restPixels+KPixelsPerByte-1) / KPixelsPerByte ; //how many target bytes to copy
1.101 + TInt shiftBits = aX - startLongPix;
1.102 + restPixels=shiftBits+restPixels; //How many pixels are read from the second word by the final word copy
1.103 + if (bytesCnt==0 && shiftBits && restPixels<=0)
1.104 + {
1.105 + // This correction is required because although a last whole word will be written to the target buffer,
1.106 + // this special test indicates that the required significant data bits plus the shift
1.107 + // add up to one word (or less) to be read.
1.108 + // The copy words optimisation used to copy the main body of the line
1.109 + // will read from the next location after the copy,
1.110 + // but this may not always be accessable memory (on the last scanline)
1.111 + // The correction is not required if the second word would need to be read anyway.
1.112 + //eg we want to copy 7 nibbles with a 1 nibble shift (16 color), restpixels would be 0
1.113 + bytesCnt=4;
1.114 + wordsCnt--;
1.115 + }
1.116 + //How many pixels are read from the second word in the final byte copy?
1.117 + //If zero (or less) then the second word should not be read in the copy bytes phase
1.118 + //really this should be an else of the if above, but this gives the same end condition.
1.119 + //eg we want to copy 5 nibbles with a 2 nibble shift (16 color), restpixels would be -1.
1.120 + restPixels-=KPixelsPerWord;
1.121 + ReadLineCommon(pixelPtr,bufferPtr,wordsCnt,restPixels,bytesCnt,shiftBits);
1.122 + }
1.123 +
1.124 +
1.125 +TRgb CDrawOneBppBitmap::ReadRgbNormal(TInt aX,TInt aY) const
1.126 + {
1.127 + TUint32 colorWord = *(ScanLine(aY) + (aX / KPixelsPerWord));
1.128 +
1.129 + if (colorWord & (1 << (aX & 0x1f)))
1.130 + return KRgbWhite;
1.131 +
1.132 + return KRgbBlack;
1.133 + }
1.134 +
1.135 +void CDrawOneBppBitmap::ShadowArea(const TRect& aRect)
1.136 + {
1.137 + __ASSERT_DEBUG(aRect.iTl.iX>=0 && aRect.iBr.iX<=iSize.iWidth,Panic(EScreenDriverPanicOutOfBounds));
1.138 + __ASSERT_DEBUG(aRect.iTl.iY>=0 && aRect.iBr.iY<=iSize.iHeight,Panic(EScreenDriverPanicOutOfBounds));
1.139 +
1.140 + if (iShadowMode & EFade)
1.141 + {
1.142 + TInt fadedWhite = FadeRgb(KRgbWhite)._Gray2();
1.143 + TInt fadedBlack = FadeRgb(KRgbBlack)._Gray2();
1.144 +
1.145 + if (fadedWhite)
1.146 + {
1.147 + if (fadedBlack) // Everything fades to white
1.148 + WriteRgbMulti(aRect.iTl.iX,aRect.iTl.iY,aRect.Width(),aRect.Height(),KRgbWhite);
1.149 + // else Nothing changes
1.150 + }
1.151 + else
1.152 + {
1.153 + if (fadedBlack) // Everything inverted
1.154 + WriteRgbMultiXOR(aRect.iTl.iX,aRect.iTl.iY,aRect.Width(),aRect.Height(),KRgbWhite);
1.155 + else // Everything fades to black
1.156 + WriteRgbMulti(aRect.iTl.iX,aRect.iTl.iY,aRect.Width(),aRect.Height(),KRgbBlack);
1.157 + }
1.158 + }
1.159 +
1.160 + if (iShadowMode & EShadow)
1.161 + {
1.162 + const TInt x = aRect.iTl.iX;
1.163 + TInt y = aRect.iTl.iY;
1.164 + const TInt startLong = (x + KPixelsPerWord - 1) & (~0x1f);
1.165 + const TInt finishLong = (aRect.iBr.iX) & (~0x1f);
1.166 + const TInt startShift = startLong - x;
1.167 + TUint32* base = ScanLine(y);
1.168 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.169 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.170 +
1.171 + if (finishLong < startLong)
1.172 + {
1.173 + TUint32 mask = (0xffffffff >> (startLong - aRect.iBr.iX)) & (0xffffffff << (x - finishLong));
1.174 + mask = ~mask;
1.175 +
1.176 + for (; y < aRect.iBr.iY; y++)
1.177 + {
1.178 + pixelPtrLimit[0] &= mask;
1.179 + pixelPtrLimit += iScanLineWords;
1.180 + }
1.181 +
1.182 + return;
1.183 + }
1.184 +
1.185 + const TInt bytesToFill = (pixelPtrLimit - pixelPtr) * sizeof(TUint32);
1.186 + const TInt finishShift = 32 - aRect.iBr.iX + finishLong;
1.187 +
1.188 + for (;y<aRect.iBr.iY;y++)
1.189 + {
1.190 + if (x < startLong)
1.191 + pixelPtr[-1] = PasteInt(pixelPtr[-1],0,startShift);
1.192 +
1.193 + Mem::FillZ(pixelPtr,bytesToFill);
1.194 +
1.195 + if (finishLong < aRect.iBr.iX)
1.196 + pixelPtrLimit[0] = PasteInt(0,pixelPtrLimit[0],finishShift);
1.197 +
1.198 + pixelPtr += iScanLineWords;
1.199 + pixelPtrLimit += iScanLineWords;
1.200 + }
1.201 + }
1.202 + }
1.203 +
1.204 +void CDrawOneBppBitmap::ShadowBuffer(TInt aLength,TUint32* aBuffer)
1.205 + {
1.206 + __ASSERT_DEBUG(aLength>0,Panic(EScreenDriverPanicZeroLength));
1.207 + __ASSERT_DEBUG(aBuffer,Panic(EScreenDriverPanicNullPointer));
1.208 +
1.209 + const TInt byteLength = (aLength + 7) / 8;
1.210 +
1.211 + if (iShadowMode & EFade)
1.212 + {
1.213 + TInt fadedWhite = FadeRgb(KRgbWhite)._Gray2();
1.214 + TInt fadedBlack = FadeRgb(KRgbBlack)._Gray2();
1.215 +
1.216 + if (fadedWhite)
1.217 + {
1.218 + if (fadedBlack) // Everything fades to white
1.219 + Mem::Fill(aBuffer,byteLength,0xff);
1.220 + // else Nothing changes
1.221 + }
1.222 + else
1.223 + {
1.224 + if (fadedBlack) // Everything inverted
1.225 + {
1.226 + TUint8* bufferPtr = REINTERPRET_CAST(TUint8*,aBuffer);
1.227 + const TUint8* bufferPtrLimit = bufferPtr + byteLength;
1.228 +
1.229 + while (bufferPtr < bufferPtrLimit)
1.230 + *bufferPtr ^= 0xff;
1.231 + }
1.232 + else // Everything fades to black
1.233 + Mem::FillZ(aBuffer,byteLength);
1.234 + }
1.235 + }
1.236 +
1.237 + if (iShadowMode & EShadow)
1.238 + Mem::FillZ(aBuffer,byteLength);
1.239 + }
1.240 +
1.241 +void CDrawOneBppBitmap::WriteRgb(TInt aX,TInt aY,TRgb aColor)
1.242 + {
1.243 + TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
1.244 + const TUint32 mask = 1 << (aX & 0x1f);
1.245 +
1.246 + if (aColor._Gray2())
1.247 + pixelPtr[0] |= mask;
1.248 + else
1.249 + pixelPtr[0] &= ~mask;
1.250 + }
1.251 +
1.252 +void CDrawOneBppBitmap::WriteBinary(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,TInt aHeight,TRgb aColor)
1.253 + {
1.254 + const TBool white = (aColor._Gray2() == 1);
1.255 + TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
1.256 + const TUint32* pixelPtrLimit = pixelPtr + (aHeight * iScanLineWords);
1.257 +
1.258 + while (pixelPtr < pixelPtrLimit)
1.259 + {
1.260 + TUint32 dataMask = 1;
1.261 + TUint32 mask = 1 << (aX & 0x1f);
1.262 + TUint32* tempPixelPtr = pixelPtr;
1.263 +
1.264 + for (TInt count = 0; count < aLength; count++,dataMask <<= 1,mask <<= 1)
1.265 + {
1.266 + if (!mask)
1.267 + {
1.268 + mask = 1;
1.269 + tempPixelPtr++;
1.270 + }
1.271 +
1.272 + if (aBuffer[0] & dataMask)
1.273 + {
1.274 + if (white)
1.275 + tempPixelPtr[0] |= mask;
1.276 + else
1.277 + tempPixelPtr[0] &= ~mask;
1.278 + }
1.279 + }
1.280 +
1.281 + aBuffer++;
1.282 + pixelPtr += iScanLineWords;
1.283 + }
1.284 + }
1.285 +
1.286 +void CDrawOneBppBitmap::WriteBinaryOp(TInt aX,TInt aY,TUint32* aBuffer,TInt aLength,TInt aHeight,TRgb aColor,CGraphicsContext::TDrawMode aDrawMode)
1.287 + {
1.288 + const TBool white = (aColor._Gray2() == 1);
1.289 + TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
1.290 + const TUint32* pixelPtrLimit = pixelPtr + (aHeight * iScanLineWords);
1.291 + TUint32 initialMask = 1 << (aX & 0x1f);
1.292 +
1.293 + if (white)
1.294 + {
1.295 + if (aDrawMode == CGraphicsContext::EDrawModeXOR || aDrawMode == CGraphicsContext::EDrawModeOR)
1.296 + {
1.297 + while (pixelPtr < pixelPtrLimit)
1.298 + {
1.299 + TUint32 dataMask = 1;
1.300 + TUint32 mask = initialMask;
1.301 + TUint32* tempPixelPtr = pixelPtr;
1.302 +
1.303 + for (TInt count = 0; count < aLength;count++,dataMask <<= 1,mask <<= 1)
1.304 + {
1.305 + if (!mask)
1.306 + {
1.307 + mask = 1;
1.308 + tempPixelPtr++;
1.309 + }
1.310 +
1.311 + if (aBuffer[0] & dataMask)
1.312 + {
1.313 + if (aDrawMode == CGraphicsContext::EDrawModeXOR)
1.314 + tempPixelPtr[0] ^= mask;
1.315 + else if (aDrawMode == CGraphicsContext::EDrawModeOR)
1.316 + tempPixelPtr[0] |= mask;
1.317 + }
1.318 + }
1.319 +
1.320 + aBuffer++;
1.321 + pixelPtr += iScanLineWords;
1.322 + }
1.323 + }
1.324 + }
1.325 + else
1.326 + {
1.327 + if (aDrawMode == CGraphicsContext::EDrawModeAND)
1.328 + {
1.329 + while (pixelPtr < pixelPtrLimit)
1.330 + {
1.331 + TUint32 dataMask = 1;
1.332 + TUint32 mask = initialMask;
1.333 + TUint32* tempPixelPtr = pixelPtr;
1.334 +
1.335 + for (TInt count = 0; count < aLength;count++,dataMask <<= 1,mask <<= 1)
1.336 + {
1.337 + if (!mask)
1.338 + {
1.339 + mask = 1;
1.340 + tempPixelPtr++;
1.341 + }
1.342 +
1.343 + if (*aBuffer & dataMask)
1.344 + *tempPixelPtr &= ~mask;
1.345 + }
1.346 +
1.347 + aBuffer++;
1.348 + pixelPtr += iScanLineWords;
1.349 + }
1.350 + }
1.351 + }
1.352 + }
1.353 +
1.354 +void CDrawOneBppBitmap::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aBuffer,TInt aHeight,TRgb aColor,TBool aUp)
1.355 + {
1.356 + const TBool white = (aColor._Gray2() == 1);
1.357 + const TInt yLimit = aY + ((aUp) ? -aHeight : aHeight);
1.358 + const TInt scanLineWords = (aUp) ? -iScanLineWords : iScanLineWords;
1.359 + const TInt startWord = aX / KPixelsPerWord;
1.360 + TUint32* pixelPtr = ScanLine(aY) + startWord;
1.361 + TUint32* pixelPtrLimit = ScanLine(yLimit) + startWord;
1.362 + TUint32 mask = 1 << (aX & 0x1f);
1.363 + TUint32 dataMask = 1;
1.364 +
1.365 + if (white)
1.366 + {
1.367 + while (pixelPtr != pixelPtrLimit)
1.368 + {
1.369 + if (!dataMask)
1.370 + {
1.371 + dataMask = 1;
1.372 + aBuffer++;
1.373 + }
1.374 +
1.375 + if (aBuffer[0] & dataMask)
1.376 + pixelPtr[0] |= mask;
1.377 +
1.378 + dataMask <<= 1;
1.379 + pixelPtr += scanLineWords;
1.380 + }
1.381 + }
1.382 + else
1.383 + {
1.384 + mask = ~mask;
1.385 + while (pixelPtr != pixelPtrLimit)
1.386 + {
1.387 + if (!dataMask)
1.388 + {
1.389 + dataMask = 1;
1.390 + aBuffer++;
1.391 + }
1.392 +
1.393 + if (aBuffer[0] & dataMask)
1.394 + pixelPtr[0] &= mask;
1.395 +
1.396 + dataMask <<= 1;
1.397 + pixelPtr += scanLineWords;
1.398 + }
1.399 + }
1.400 + }
1.401 +
1.402 +void CDrawOneBppBitmap::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
1.403 + {
1.404 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.405 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.406 + const TInt startShift = startLong - aX;
1.407 + const TInt startShiftExtra = 32 - startShift;
1.408 + const TInt finishX = aX + aLength;
1.409 + TUint32* base = ScanLine(aY);
1.410 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.411 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.412 +
1.413 + if (finishLong < startLong)
1.414 + {
1.415 + TUint32 mask = (0xffffffff << startShiftExtra) & (0xffffffff >> (startLong - finishX));
1.416 + pixelPtrLimit[0] &= ~mask;
1.417 + pixelPtrLimit[0] |= (aBuffer[0] << startShiftExtra) & mask;
1.418 + return;
1.419 + }
1.420 +
1.421 + if (startShift > 0)
1.422 + {
1.423 + pixelPtr[-1] &= 0xffffffff >> startShift;
1.424 + pixelPtr[-1] |= aBuffer[0] << startShiftExtra;
1.425 +
1.426 + while (pixelPtr < pixelPtrLimit)
1.427 + {
1.428 + pixelPtr[0] = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.429 + pixelPtr++;
1.430 + aBuffer++;
1.431 + }
1.432 +
1.433 + if (finishLong < finishX)
1.434 + {
1.435 + TUint32 value = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.436 + pixelPtrLimit[0] = PasteInt(value,pixelPtrLimit[0],32 - finishX + finishLong);
1.437 + }
1.438 + }
1.439 + else
1.440 + {
1.441 + while (pixelPtr < pixelPtrLimit)
1.442 + *pixelPtr++ = *aBuffer++;
1.443 +
1.444 + if (finishLong < finishX)
1.445 + pixelPtrLimit[0] = PasteInt(aBuffer[0],pixelPtrLimit[0],32 - finishX + finishLong);
1.446 + }
1.447 + }
1.448 +
1.449 +void CDrawOneBppBitmap::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
1.450 + {
1.451 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.452 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.453 + const TInt startShift = startLong - aX;
1.454 + const TInt startShiftExtra = 32 - startShift;
1.455 + const TInt finishX = aX + aLength;
1.456 + TUint32* base = ScanLine(aY);
1.457 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.458 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.459 +
1.460 + if (finishLong < startLong)
1.461 + {
1.462 + TUint32 mask = (0xffffffff << startShiftExtra) & (0xffffffff >> (startLong - finishX));
1.463 + pixelPtrLimit[0] ^= (aBuffer[0] << startShiftExtra) & mask;
1.464 + return;
1.465 + }
1.466 +
1.467 + if (startShift > 0)
1.468 + {
1.469 + pixelPtr[-1] ^= aBuffer[0] << startShiftExtra;
1.470 +
1.471 + while (pixelPtr < pixelPtrLimit)
1.472 + {
1.473 + pixelPtr[0] ^= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.474 + pixelPtr++;
1.475 + aBuffer++;
1.476 + }
1.477 +
1.478 + if (finishLong < finishX)
1.479 + {
1.480 + TUint32 value = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.481 + pixelPtrLimit[0] ^= PasteInt(value,0,32 - finishX + finishLong);
1.482 + }
1.483 + }
1.484 + else
1.485 + {
1.486 + while (pixelPtr < pixelPtrLimit)
1.487 + *pixelPtr++ ^= *aBuffer++;
1.488 +
1.489 + if (finishLong < finishX)
1.490 + pixelPtrLimit[0] ^= PasteInt(aBuffer[0],0,32 - finishX + finishLong);
1.491 + }
1.492 + }
1.493 +
1.494 +void CDrawOneBppBitmap::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
1.495 + {
1.496 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.497 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.498 + const TInt startShift = startLong - aX;
1.499 + const TInt startShiftExtra = 32 - startShift;
1.500 + const TInt finishX = aX + aLength;
1.501 + TUint32* base = ScanLine(aY);
1.502 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.503 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.504 +
1.505 + if (finishLong < startLong)
1.506 + {
1.507 + TUint32 mask = (0xffffffff << startShiftExtra) & (0xffffffff >> (startLong - finishX));
1.508 + pixelPtrLimit[0] &= (aBuffer[0] << startShiftExtra) | ~mask;
1.509 + return;
1.510 + }
1.511 +
1.512 + if (startShift > 0)
1.513 + {
1.514 + pixelPtr[-1] &= (aBuffer[0] << startShiftExtra) | (0xffffffff >> startShift);
1.515 +
1.516 + while (pixelPtr < pixelPtrLimit)
1.517 + {
1.518 + pixelPtr[0] &= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.519 + pixelPtr++;
1.520 + aBuffer++;
1.521 + }
1.522 +
1.523 + if (finishLong < finishX)
1.524 + {
1.525 + TUint32 value = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.526 + pixelPtrLimit[0] &= PasteInt(value,0xffffffff,32 - finishX + finishLong);
1.527 + }
1.528 + }
1.529 + else
1.530 + {
1.531 + while (pixelPtr < pixelPtrLimit)
1.532 + *pixelPtr++ &= *aBuffer++;
1.533 +
1.534 + if (finishLong < finishX)
1.535 + pixelPtrLimit[0] &= PasteInt(aBuffer[0],0xffffffff,32 - finishX + finishLong);
1.536 + }
1.537 + }
1.538 +
1.539 +void CDrawOneBppBitmap::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer)
1.540 + {
1.541 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.542 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.543 + const TInt startShift = startLong - aX;
1.544 + const TInt startShiftExtra = 32 - startShift;
1.545 + const TInt finishX = aX + aLength;
1.546 + TUint32* base = ScanLine(aY);
1.547 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.548 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.549 +
1.550 + if (finishLong < startLong)
1.551 + {
1.552 + TUint32 mask = (0xffffffff << startShiftExtra) & (0xffffffff >> (startLong - finishX));
1.553 + pixelPtrLimit[0] |= (aBuffer[0] << startShiftExtra) & mask;
1.554 + return;
1.555 + }
1.556 +
1.557 + if (startShift > 0)
1.558 + {
1.559 + pixelPtr[-1] |= aBuffer[0] << startShiftExtra;
1.560 +
1.561 + while (pixelPtr < pixelPtrLimit)
1.562 + {
1.563 + pixelPtr[0] |= (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.564 + pixelPtr++;
1.565 + aBuffer++;
1.566 + }
1.567 +
1.568 + if (finishLong < finishX)
1.569 + {
1.570 + TUint32 value = (aBuffer[0] >> startShift) | (aBuffer[1] << startShiftExtra);
1.571 + pixelPtrLimit[0] |= PasteInt(value,0,32 - finishX + finishLong);
1.572 + }
1.573 + }
1.574 + else
1.575 + {
1.576 + while (pixelPtr < pixelPtrLimit)
1.577 + *pixelPtr++ |= *aBuffer++;
1.578 +
1.579 + if (finishLong < finishX)
1.580 + pixelPtrLimit[0] |= PasteInt(aBuffer[0],0,32 - finishX + finishLong);
1.581 + }
1.582 + }
1.583 +
1.584 +/**
1.585 +MAlphaBlend::WriteRgbAlphaLine() implementation.
1.586 +@see MAlphaBlend::WriteRgbAlphaLine()
1.587 +*/
1.588 +void CDrawOneBppBitmap::WriteRgbAlphaLine(TInt aX, TInt aY, TInt aLength,
1.589 + const TUint8* aRgbBuffer,
1.590 + const TUint8* aMaskBuffer,
1.591 + MAlphaBlend::TShadowing,
1.592 + CGraphicsContext::TDrawMode /*aDrawMode*/)
1.593 + {
1.594 + TUint32* pixelPtr = ScanLine(aY) + (aX / KPixelsPerWord);
1.595 + const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
1.596 + TUint32 bitMask = 1 << (aX & 0x1f);
1.597 +
1.598 + while (aMaskBuffer < maskBufferPtrLimit)
1.599 + {
1.600 + if (*aMaskBuffer++ & 0x80)
1.601 + {
1.602 + if (((aRgbBuffer[2] << 1) + aRgbBuffer[1] + (aRgbBuffer[1] << 2) + aRgbBuffer[0]) > 1016)
1.603 + pixelPtr[0] |= bitMask;
1.604 + else
1.605 + pixelPtr[0] &= ~bitMask;
1.606 + }
1.607 +
1.608 + bitMask <<= 1;
1.609 +
1.610 + if (!bitMask)
1.611 + {
1.612 + bitMask = 1;
1.613 + pixelPtr++;
1.614 + }
1.615 +
1.616 + aRgbBuffer += 4;
1.617 + }
1.618 + }
1.619 +
1.620 +void CDrawOneBppBitmap::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
1.621 + {
1.622 + const TUint32 colorWord = (aColor._Gray2() == 1) ? 0xffffffff : 0;
1.623 + const TInt yLimit = aY + aHeight;
1.624 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.625 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.626 + const TInt startShift = startLong - aX;
1.627 + const TInt finishShift = 32 - aX - aLength + finishLong;
1.628 + TUint32* base = ScanLine(aY);
1.629 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.630 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.631 +
1.632 + if (finishLong < startLong)
1.633 + {
1.634 + TUint32 mask = (0xffffffff << (32 - startShift)) & (0xffffffff >> (startShift - aLength));
1.635 + const TUint32 maskedColorWord = colorWord & mask;
1.636 + mask = ~mask;
1.637 +
1.638 + for (; aY < yLimit; aY++)
1.639 + {
1.640 + pixelPtrLimit[0] &= mask;
1.641 + pixelPtrLimit[0] |= maskedColorWord;
1.642 + pixelPtrLimit += iScanLineWords;
1.643 + }
1.644 + return;
1.645 + }
1.646 +
1.647 + const TBool extra = (finishLong < aX + aLength);
1.648 +
1.649 + for (; aY < yLimit; aY++)
1.650 + {
1.651 + TUint32* bmpbitstmp = pixelPtr;
1.652 +
1.653 + if (startShift > 0)
1.654 + bmpbitstmp[-1] = PasteInt(bmpbitstmp[-1],colorWord,startShift);
1.655 +
1.656 + while (bmpbitstmp < pixelPtrLimit)
1.657 + *bmpbitstmp++ = colorWord;
1.658 +
1.659 + if (extra)
1.660 + pixelPtrLimit[0] = PasteInt(colorWord,pixelPtrLimit[0],finishShift);
1.661 +
1.662 + pixelPtr += iScanLineWords;
1.663 + pixelPtrLimit += iScanLineWords;
1.664 + }
1.665 + }
1.666 +
1.667 +void CDrawOneBppBitmap::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
1.668 + {
1.669 + const TUint32 colorWord = (aColor._Gray2() == 1) ? 0xffffffff : 0;
1.670 + const TInt yLimit = aY + aHeight;
1.671 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.672 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.673 + const TInt startShift = startLong - aX;
1.674 + const TInt finishShift = 32 - aX - aLength + finishLong;
1.675 + TUint32* base = ScanLine(aY);
1.676 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.677 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.678 +
1.679 + if (finishLong < startLong)
1.680 + {
1.681 + TUint32 mask = (0xffffffff << (32 - startShift)) & (0xffffffff >> (startShift - aLength));
1.682 + const TUint32 maskedColorWord = colorWord & mask;
1.683 +
1.684 + for (; aY < yLimit; aY++)
1.685 + {
1.686 + pixelPtrLimit[0] ^= maskedColorWord;
1.687 + pixelPtrLimit += iScanLineWords;
1.688 + }
1.689 + return;
1.690 + }
1.691 +
1.692 + const TBool extra = (finishLong < aX + aLength);
1.693 +
1.694 + for (; aY < yLimit; aY++)
1.695 + {
1.696 + TUint32* bmpbitstmp = pixelPtr;
1.697 +
1.698 + if (startShift > 0)
1.699 + bmpbitstmp[-1] ^= PasteInt(0,colorWord,startShift);
1.700 +
1.701 + while (bmpbitstmp < pixelPtrLimit)
1.702 + *bmpbitstmp++ ^= colorWord;
1.703 +
1.704 + if (extra)
1.705 + pixelPtrLimit[0] ^= PasteInt(colorWord,0,finishShift);
1.706 +
1.707 + pixelPtr += iScanLineWords;
1.708 + pixelPtrLimit += iScanLineWords;
1.709 + }
1.710 + }
1.711 +
1.712 +void CDrawOneBppBitmap::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
1.713 + {
1.714 + const TUint32 colorWord = (aColor._Gray2() == 1) ? 0xffffffff : 0;
1.715 + const TInt yLimit = aY + aHeight;
1.716 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.717 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.718 + const TInt startShift = startLong - aX;
1.719 + const TInt finishShift = 32 - aX - aLength + finishLong;
1.720 + TUint32* base = ScanLine(aY);
1.721 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.722 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.723 +
1.724 + if (finishLong < startLong)
1.725 + {
1.726 + TUint32 mask = (0xffffffff << (32 - startShift)) & (0xffffffff >> (startShift - aLength));
1.727 + const TUint32 maskedColorWord = colorWord | ~mask;
1.728 +
1.729 + for (; aY < yLimit; aY++)
1.730 + {
1.731 + pixelPtrLimit[0] &= maskedColorWord;
1.732 + pixelPtrLimit += iScanLineWords;
1.733 + }
1.734 + return;
1.735 + }
1.736 +
1.737 + const TBool extra = (finishLong < aX + aLength);
1.738 +
1.739 + for (; aY < yLimit; aY++)
1.740 + {
1.741 + TUint32* bmpbitstmp = pixelPtr;
1.742 +
1.743 + if (startShift > 0)
1.744 + bmpbitstmp[-1] &= PasteInt(0xffffffff,colorWord,startShift);
1.745 +
1.746 + while (bmpbitstmp < pixelPtrLimit)
1.747 + *bmpbitstmp++ &= colorWord;
1.748 +
1.749 + if (extra)
1.750 + pixelPtrLimit[0] &= PasteInt(colorWord,0xffffffff,finishShift);
1.751 +
1.752 + pixelPtr += iScanLineWords;
1.753 + pixelPtrLimit += iScanLineWords;
1.754 + }
1.755 + }
1.756 +
1.757 +void CDrawOneBppBitmap::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aHeight,TRgb aColor)
1.758 + {
1.759 + const TUint32 colorWord = (aColor._Gray2() == 1) ? 0xffffffff : 0;
1.760 + const TInt yLimit = aY + aHeight;
1.761 + const TInt startLong = (aX + KPixelsPerWord - 1) & (~0x1f);
1.762 + const TInt finishLong = (aX + aLength) & (~0x1f);
1.763 + const TInt startShift = startLong - aX;
1.764 + const TInt finishShift = 32 - aX - aLength + finishLong;
1.765 + TUint32* base = ScanLine(aY);
1.766 + TUint32* pixelPtr = base + (startLong / KPixelsPerWord);
1.767 + TUint32* pixelPtrLimit = base + (finishLong / KPixelsPerWord);
1.768 +
1.769 + if (finishLong < startLong)
1.770 + {
1.771 + TUint32 mask = (0xffffffff << (32 - startShift)) & (0xffffffff >> (startShift - aLength));
1.772 + const TUint32 maskedColorWord = colorWord & mask;
1.773 +
1.774 + for (; aY < yLimit; aY++)
1.775 + {
1.776 + pixelPtrLimit[0] |= maskedColorWord;
1.777 + pixelPtrLimit += iScanLineWords;
1.778 + }
1.779 + return;
1.780 + }
1.781 +
1.782 + const TBool extra = (finishLong < aX + aLength);
1.783 +
1.784 + for (; aY < yLimit; aY++)
1.785 + {
1.786 + TUint32* bmpbitstmp = pixelPtr;
1.787 +
1.788 + if (startShift > 0)
1.789 + bmpbitstmp[-1] |= PasteInt(bmpbitstmp[-1],colorWord,startShift);
1.790 +
1.791 + while (bmpbitstmp < pixelPtrLimit)
1.792 + *bmpbitstmp++ |= colorWord;
1.793 +
1.794 + if (extra)
1.795 + pixelPtrLimit[0] |= PasteInt(colorWord,pixelPtrLimit[0],finishShift);
1.796 +
1.797 + pixelPtr += iScanLineWords;
1.798 + pixelPtrLimit += iScanLineWords;
1.799 + }
1.800 + }
1.801 +
1.802 +void CDrawOneBppBitmap::WriteRgbAlphaMulti(TInt aX,TInt aY,TInt aLength,TRgb aColor,const TUint8* aMaskBuffer)
1.803 + {
1.804 + DeOrientate(aX,aY);
1.805 + TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 8);
1.806 + TInt pixelMask = 1 << (aX & 7);
1.807 + const TUint8* maskBufferPtrLimit = aMaskBuffer + aLength;
1.808 +
1.809 + if (iShadowMode)
1.810 + Shadow(aColor);
1.811 +
1.812 + const TInt gray = aColor._Gray256();
1.813 + TRgb pixelColor;
1.814 +
1.815 + while (aMaskBuffer < maskBufferPtrLimit)
1.816 + {
1.817 + const TInt pixelGray256Value = (pixelPtr[0] & pixelMask) ? 255 : 0;
1.818 + pixelColor = TRgb::_Gray256(((gray * aMaskBuffer[0]) + ((255 - aMaskBuffer[0]) * pixelGray256Value)) / 255);
1.819 + if (pixelColor._Gray2())
1.820 + pixelPtr[0] |= pixelMask;
1.821 + else
1.822 + pixelPtr[0] &= ~pixelMask;
1.823 +
1.824 + pixelMask <<= 1;
1.825 + if (pixelMask > 128)
1.826 + {
1.827 + pixelPtr++;
1.828 + pixelMask = 1;
1.829 + }
1.830 + aMaskBuffer++;
1.831 + }
1.832 + }
1.833 +
1.834 +TInt CDrawOneBppBitmap::WriteRgbOutlineAndShadow(TInt aX, TInt aY, const TInt aLength,
1.835 + TUint32 aOutlinePenColor, TUint32 aShadowColor,
1.836 + TUint32 aFillColor, const TUint8* aDataBuffer)
1.837 + {
1.838 + //This is non-optimised since this screen mode is rarely used and is usually
1.839 + //fast enough without optimisation.
1.840 + DeOrientate(aX,aY);
1.841 + TUint8* pixelPtr = REINTERPRET_CAST(TUint8*,ScanLine(aY)) + (aX / 8);
1.842 + TInt pixelMask = 1 << (aX & 7);
1.843 + const TUint8* dataBufferPtrLimit = aDataBuffer + aLength;
1.844 +
1.845 + TInt blendedRedColor;
1.846 + TInt blendedGreenColor;
1.847 + TInt blendedBlueColor;
1.848 + TUint8 index = 0;
1.849 + TRgb finalColor;
1.850 +
1.851 + TRgb outlinePenColor;
1.852 + outlinePenColor.SetInternal(aOutlinePenColor);
1.853 + TRgb shadowColor;
1.854 + shadowColor.SetInternal(aShadowColor);
1.855 + TRgb fillColor;
1.856 + fillColor.SetInternal(aFillColor);
1.857 +
1.858 + const TInt redOutlinePenColor = outlinePenColor.Red();
1.859 + const TInt redShadowColor = shadowColor.Red();
1.860 + const TInt redFillColor = fillColor.Red();
1.861 +
1.862 + const TInt greenOutlinePenColor = outlinePenColor.Green();
1.863 + const TInt greenShadowColor = shadowColor.Green();
1.864 + const TInt greenFillColor = fillColor.Green();
1.865 +
1.866 + const TInt blueOutlinePenColor = outlinePenColor.Blue();
1.867 + const TInt blueShadowColor = shadowColor.Blue();
1.868 + const TInt blueFillColor = fillColor.Blue();
1.869 +
1.870 + while (aDataBuffer < dataBufferPtrLimit)
1.871 + {
1.872 + index = *aDataBuffer++;
1.873 + if (255 == FourColorBlendLookup[index][KBackgroundColorIndex])
1.874 + {
1.875 + //background colour
1.876 + //No drawing required so move on to next pixel.
1.877 + pixelMask <<= 1;
1.878 + if (pixelMask > 0x80)
1.879 + {
1.880 + pixelPtr++;
1.881 + pixelMask = 1;
1.882 + }
1.883 + continue;
1.884 + }
1.885 + else if (255 == FourColorBlendLookup[index][KFillColorIndex])
1.886 + {
1.887 + //fill colour
1.888 + finalColor.SetInternal(aFillColor);
1.889 + }
1.890 + else if (255 == FourColorBlendLookup[index][KShadowColorIndex])
1.891 + {
1.892 + //Shadow colour
1.893 + finalColor.SetInternal(aShadowColor);
1.894 + }
1.895 + else if (255 == FourColorBlendLookup[index][KOutlineColorIndex])
1.896 + {
1.897 + //Outline colour
1.898 + finalColor.SetInternal(aOutlinePenColor);
1.899 + }
1.900 + else
1.901 + {
1.902 + TRgb backgroundColor = TRgb::_Gray2((pixelPtr[0] & pixelMask) ? 255 : 0);
1.903 + blendedRedColor = (redOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
1.904 + redShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
1.905 + redFillColor * FourColorBlendLookup[index][KFillColorIndex] +
1.906 + backgroundColor.Red() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
1.907 +
1.908 + blendedGreenColor = (greenOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
1.909 + greenShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
1.910 + greenFillColor * FourColorBlendLookup[index][KFillColorIndex] +
1.911 + backgroundColor.Green() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
1.912 +
1.913 + blendedBlueColor = (blueOutlinePenColor * FourColorBlendLookup[index][KOutlineColorIndex] +
1.914 + blueShadowColor * FourColorBlendLookup[index][KShadowColorIndex] +
1.915 + blueFillColor * FourColorBlendLookup[index][KFillColorIndex] +
1.916 + backgroundColor.Blue() * FourColorBlendLookup[index][KBackgroundColorIndex]) >> 8;
1.917 +
1.918 + finalColor = TRgb(blendedRedColor, blendedGreenColor, blendedBlueColor);
1.919 + }
1.920 +
1.921 + if (finalColor._Gray2())
1.922 + {
1.923 + pixelPtr[0] |= pixelMask;
1.924 + }
1.925 + else
1.926 + {
1.927 + pixelPtr[0] &= ~pixelMask;
1.928 + }
1.929 +
1.930 + pixelMask <<= 1;
1.931 +
1.932 + if (pixelMask > 0x80)
1.933 + {
1.934 + pixelPtr++;
1.935 + pixelMask = 1;
1.936 + }
1.937 + }
1.938 + return KErrNone;
1.939 + }