diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/screendriver/sbit/BMDRAW8.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/screendriver/sbit/BMDRAW8.CPP Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,737 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "BMDRAW.H" +#include "BitDrawInterfaceId.h" + +// CDrawEightBppBitmapCommon +//EColor256 screen/bitmap device might be scaled. +//In this case right-bottom coordinate might go outside the drawing rectangle. +//Then - we need to check that we do not try to draw something outside the drawing rectangle. + +//Initializes iSize, iDrawRect, iLongWidth, iScanlineWords data members. +//It should be called every time when iSize is going to be changed - from Construct(). +//@param aSize Physical screen size in pixels. +//@panic EScreenDriverPanicInvalidSize - Invalid aSize parameter. This might happen if the +//device is scaled and the scaling origin goes outside physical drawing rectangle. +void CDrawEightBppBitmapCommon::SetSize(const TSize& aSize) + { + CDrawBitmap::SetSize(aSize); + __ASSERT_DEBUG(iSize == aSize, User::Invariant()); + iLongWidth = (iSize.iWidth + 3) & ~3; + iScanLineWords = iLongWidth / 4; + } + +TInt CDrawEightBppBitmapCommon::Construct(TSize aSize, TInt aStride) + { + iBits = NULL; + CDrawBitmap::SetSize(aSize); + __ASSERT_DEBUG(iSize == aSize, User::Invariant()); + if (aStride & 3) + return KErrArgument; + iLongWidth = aStride; + if (iLongWidth < aSize.iWidth) + return KErrArgument; + iScanLineWords = aStride >> 2; + TInt size = Max(aSize.iWidth,aSize.iHeight); + if(size < 0) + return KErrArgument; + iScanLineBuffer = (TUint32*)(User::Heap().Alloc(size)); + if(iScanLineBuffer == NULL) + return KErrNoMemory; + return KErrNone; + } + +//aX, aY - physical coordinates +TUint8* CDrawEightBppBitmapCommon::PixelAddress(TInt aX,TInt aY) const + { + return (TUint8*)iBits + aY * iLongWidth + aX; + } + +void CDrawEightBppBitmapCommon::InvertBuffer(TInt aLength,TUint32* aBuffer) + { + const TUint32* limit = aBuffer + (aLength + 3) / 4; + + while (aBuffer < limit) + *aBuffer++ ^= 0xffffffff; + } + +//CDrawEightBppBitmapCommon::ReadLine() called from CDrawBitmap::ReadLine() +//aX and aY - physical coordinates. +//Reads aLength pixel values and places them in aBuffer. +//aBuffer size should be at least aLength. +void CDrawEightBppBitmapCommon::ReadLine(TInt aX,TInt aY,TInt aLength,TAny* aBuffer) const + { + const TUint8* pixelPtr = PixelAddress(aX,aY); + + if (iOrientation == EOrientationNormal && iScalingOff) + Mem::Copy(aBuffer,pixelPtr,aLength); + else + { + register TInt pixelPtrInc = LogicalPixelAddressIncrement(); + + TUint8* bufferPtr = static_cast (aBuffer); + const TUint8* bufferPtrLimit = bufferPtr + aLength; + + while (bufferPtr < bufferPtrLimit) + { + *bufferPtr++ = *pixelPtr; + pixelPtr += pixelPtrInc; + } + } + } + +//CDrawEightBppBitmapCommon::WriteRgb() called from exported CDrawBitmap::WriteRgb() +//aX, aY - physical coordinates +void CDrawEightBppBitmapCommon::WriteRgb(TInt aX,TInt aY,TUint8 aPixel) + { + register TUint8* pixelAddr = PixelAddress(aX, aY); + if(iScalingOff) + { + *pixelAddr = aPixel; + } + else + { + const TUint8* bitsStart = reinterpret_cast (iBits); + const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + SetPixels(pixelAddr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); + } + } + +//CDrawEightBppBitmapCommon::WriteBinary() called from exported CDrawBitmap::WriteBinary() +//aX, aY - logical coordinates +//"aData" parameter has "aHeight" 32 bits words +//"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word +//This method is used for bitmap font symbols drawing +//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then +//writing could be made on 32 bits words (they has to be aligned before the operation) +void CDrawEightBppBitmapCommon::WriteBinary(TInt aX,TInt aY,TUint32* aData,TInt aLength, + TInt aHeight,TUint8 aPixel) + { + DeOrientate(aX,aY);//aX, aY - physical coordinates + TInt pixelInc; + TInt rowInc; + SetPixelInc(pixelInc, rowInc); + const TUint32* dataLimit = aData + aHeight; + register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0; + TUint8* pixelPtr = PixelAddress(aX,aY); + const TUint8* bitsStart = reinterpret_cast (iBits); + const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; + TInt orgY = aY; + while (aData < dataLimit) + { + register TUint32 dataWord = *aData++; + register TUint32 dataMask = 1; + register TUint8* tempPixelPtr = pixelPtr; + if(iScalingOff) + { + while (dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + *tempPixelPtr = aPixel; + } + tempPixelPtr += pixelInc; + dataMask <<= 1; + } + } + else + { + while (dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + SetPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); + } + tempPixelPtr += pixelInc; + dataMask <<= 1; + IncScaledY(aY); + } + } + pixelPtr += rowInc; + IncScaledY(aY, orgY); + } + } + +//CDrawEightBppBitmapCommon::WriteBinaryOp() called from exported CDrawBitmap::WriteBinary() +//aX, aY - logical coordinates +//"aData" parameter has "aHeight" 32 bits words +//"aLength" parameter tells how many bits (up to 32) has to be used from each 32 bit word +//This method is used for bitmap font symbols drawing +//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then +//writing could be made on 32 bits words (they has to be aligned before the operation) +void CDrawEightBppBitmapCommon::WriteBinaryOp(TInt aX,TInt aY,TUint32* aData,TInt aLength, + TInt aHeight,TUint8 aPixel, + CGraphicsContext::TDrawMode aDrawMode) + { + if(aLength <= 0) + { + return; + } + DeOrientate(aX,aY);//aX, aY - physical coordinates + TUint8* pixelPtr = PixelAddress(aX,aY); + const TUint32* dataPtrLimit = aData + aHeight; + register TUint32 dataMaskLimit = (aLength < 32) ? 1 << aLength : 0; + TInt pixelInc; + TInt rowInc; + SetPixelInc(pixelInc, rowInc); + const TUint8* bitsStart = reinterpret_cast (iBits); + const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; + TInt orgY = aY; + if(aPixel) + { + while(aData < dataPtrLimit) + { + register TUint32 dataWord = *aData++; + register TUint32 dataMask = 1; + register TUint8* tempPixelPtr = pixelPtr; + if(iScalingOff) + { + while(dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + if(aDrawMode==CGraphicsContext::EDrawModeXOR) + { + *tempPixelPtr ^= aPixel; + } + else if(aDrawMode==CGraphicsContext::EDrawModeAND) + { + *tempPixelPtr &= aPixel; + } + else if(aDrawMode==CGraphicsContext::EDrawModeOR) + { + *tempPixelPtr |= aPixel; + } + } + tempPixelPtr += pixelInc; + dataMask <<= 1; + } + } + else + { + while(dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + if(aDrawMode==CGraphicsContext::EDrawModeXOR) + { + XORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); + } + else if(aDrawMode==CGraphicsContext::EDrawModeAND) + { + ANDPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); + } + else if(aDrawMode==CGraphicsContext::EDrawModeOR) + { + ORPixels(tempPixelPtr, aPixel, pixelRowPtrLimit, bitsStart, bitsEnd); + } + } + tempPixelPtr += pixelInc; + dataMask <<= 1; + IncScaledY(aY); + } + } + pixelPtr += rowInc; + IncScaledY(aY, orgY); + } + } + else if(aDrawMode==CGraphicsContext::EDrawModeAND) + { + while(aData < dataPtrLimit) + { + register TUint32 dataWord = *aData++; + register TUint32 dataMask = 1; + register TUint8* tempPixelPtr = pixelPtr; + if(iScalingOff) + { + while(dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + *tempPixelPtr = 0; + } + tempPixelPtr += pixelInc; + dataMask <<= 1; + } + } + else + { + while(dataMask != dataMaskLimit) + { + if(dataWord & dataMask) + { + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + SetPixels(tempPixelPtr, TUint8(0), pixelRowPtrLimit, bitsStart, bitsEnd); + } + tempPixelPtr += pixelInc; + dataMask <<= 1; + } + } + pixelPtr += rowInc; + IncScaledY(aY, orgY); + } + } + } + +//aX, aY - logical coordinates +//"aData" parameter has 32 bits words +//"aLength" parameter tells how many pixels have to be written +//This method is used for bitmap font symbols vertical drawing +//The method should not be called if the scaling is ON! +void CDrawEightBppBitmapCommon::WriteBinaryLineVertical(TInt aX,TInt aY,TUint32* aData, + TInt aLength,TUint8 aPixel,TBool aUp) + { + __ASSERT_DEBUG(iScalingOff, User::Invariant()); + + DeOrientate(aX,aY);//aX, aY - physical coordinates + + TInt scanlineByteLength; + switch(iOrientation) + { + case EOrientationNormal: + scanlineByteLength = iLongWidth; + break; + case EOrientationRotated90: + scanlineByteLength = -1; + break; + case EOrientationRotated180: + scanlineByteLength = -iLongWidth; + break; + default: // EOrientationRotated270 + scanlineByteLength = 1; + } + + if (aUp) + scanlineByteLength = -scanlineByteLength; + + register TUint8* pixelPtr = PixelAddress(aX,aY); + const TUint8* pixelPtrLimit = pixelPtr + aLength * scanlineByteLength; + register TUint32 dataWord = *aData; + register TUint32 dataMask = 1; + + while(pixelPtr != pixelPtrLimit) + { + if(!dataMask) + { + dataMask = 1; + aData++; + dataWord = *aData; + } + if(dataWord & dataMask) + { + *pixelPtr = aPixel; + } + dataMask <<= 1; + pixelPtr += scanlineByteLength; + } + } + +//CDrawEightBppBitmapCommon::WriteLine() called from CDrawBitmap::WriteLine() +//aX and aY - physical coordinates +void CDrawEightBppBitmapCommon::WriteLine(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + if (iOrientation == EOrientationNormal && iScalingOff) + { + Mem::Copy(pixelPtr,aBuffer,aLength); + } + else + { + register TInt pixelPtrInc = LogicalPixelAddressIncrement(); + TUint8* bufferPtr = reinterpret_cast (aBuffer); + const TUint8* bufferPtrLimit = bufferPtr + aLength; + if(iScalingOff) + { + while(bufferPtr < bufferPtrLimit) + { + *pixelPtr = *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + else + { + const TUint8* bitsStart = reinterpret_cast (iBits); + const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; + while(bufferPtr < bufferPtrLimit) + { + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + SetPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); + pixelPtr += pixelPtrInc; + IncScaledY(aY); + } + } + } + } + +//CDrawEightBppBitmapCommon::WriteLineXOR() called from CDrawBitmap::WriteLine() +//aX and aY - physical coordinates +//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then +//XOR could be made on 32 bits words (they has to be aligned before the operation) +void CDrawEightBppBitmapCommon::WriteLineXOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + register TInt pixelPtrInc = LogicalPixelAddressIncrement(); + TUint8* bufferPtr = reinterpret_cast (aBuffer); + const TUint8* bufferPtrLimit = bufferPtr + aLength; + if(iScalingOff) + { + while(bufferPtr < bufferPtrLimit) + { + *pixelPtr ^= *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + else + { + const TUint8* bitsStart = reinterpret_cast (iBits); + const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; + while(bufferPtr < bufferPtrLimit) + { + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + XORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); + pixelPtr += pixelPtrInc; + IncScaledY(aY); + } + } + } + +//CDrawEightBppBitmapCommon::WriteLineAND() called from CDrawBitmap::WriteLine() +//aX and aY - deorientated and scaled +//aLength - not scaled +//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then +//AND could be made on 32 bits words (they has to be aligned before the operation) +void CDrawEightBppBitmapCommon::WriteLineAND(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + register TInt pixelPtrInc = LogicalPixelAddressIncrement(); + TUint8* bufferPtr = reinterpret_cast (aBuffer); + const TUint8* bufferPtrLimit = bufferPtr + aLength; + if(iScalingOff) + { + while(bufferPtr < bufferPtrLimit) + { + *pixelPtr &= *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + else + { + const TUint8* bitsStart = reinterpret_cast (iBits); + const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; + while(bufferPtr < bufferPtrLimit) + { + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + ANDPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); + pixelPtr += pixelPtrInc; + IncScaledY(aY); + } + } + } + +//CDrawEightBppBitmapCommon::WriteLineOR() called from CDrawBitmap::WriteLine() +//aX and aY - physical coordinates +//One possible optimization: If "no scaling" And "pixelPtrInc == 1" Then +//OR could be made on 32 bits words (they has to be aligned before the operation) +void CDrawEightBppBitmapCommon::WriteLineOR(TInt aX,TInt aY,TInt aLength,TUint32* aBuffer) + { + TUint8* pixelPtr = PixelAddress(aX,aY); + register TInt pixelPtrInc = LogicalPixelAddressIncrement(); + TUint8* bufferPtr = reinterpret_cast (aBuffer); + const TUint8* bufferPtrLimit = bufferPtr + aLength; + if(iScalingOff) + { + while(bufferPtr < bufferPtrLimit) + { + *pixelPtr |= *bufferPtr++; + pixelPtr += pixelPtrInc; + } + } + else + { + const TUint8* bitsStart = reinterpret_cast (iBits); + const TUint8* bitsEnd = bitsStart + iLongWidth * iSize.iHeight; + while(bufferPtr < bufferPtrLimit) + { + const TUint8* pixelRowPtrLimit = bitsStart + (aY + 1) * iLongWidth; + ORPixels(pixelPtr, *bufferPtr++, pixelRowPtrLimit, bitsStart, bitsEnd); + pixelPtr += pixelPtrInc; + IncScaledY(aY); + } + } + } + +//CDrawEightBppBitmapCommon::WriteRgbMulti() called from CDrawBitmap::WriteRgbMulti() +//aX and aY - physical coordinates +//aLength and aRows - physical length and rows +void CDrawEightBppBitmapCommon::WriteRgbMulti(TInt aX,TInt aY,TInt aLength,TInt aRows, + TUint8 aPixel) + { + register TInt longWidth = iLongWidth; + TUint8* pixelPtr = PixelAddress(aX,aY); + const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; + register const TUint8* bitsEnd = reinterpret_cast (iBits) + iLongWidth * iSize.iHeight; + if(pixelRowPtrLimit >= bitsEnd) + { + pixelRowPtrLimit = bitsEnd; + } + + while (pixelPtr < pixelRowPtrLimit) + { + Mem::Fill(pixelPtr,aLength,aPixel); + pixelPtr += longWidth; + } + } + +//CDrawEightBppBitmapCommon::WriteRgbMultiXOR() called from CDrawBitmap::WriteRgbMulti() +//aX and aY - physical coordinates +//aLength and aRows - physical length and rows +void CDrawEightBppBitmapCommon::WriteRgbMultiXOR(TInt aX,TInt aY,TInt aLength,TInt aRows, + TUint8 aPixel) + { + register TInt longWidth = iLongWidth; + TUint8* pixelPtr = PixelAddress(aX,aY); + TUint8* pixelPtrLimit = pixelPtr + aLength; + const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; + register const TUint8* bitsEnd = reinterpret_cast (iBits) + iLongWidth * iSize.iHeight; + if(pixelRowPtrLimit >= bitsEnd) + { + pixelRowPtrLimit = bitsEnd; + } + + while (pixelPtr < pixelRowPtrLimit) + { + TUint8* tempPixelPtr = pixelPtr; + + while (tempPixelPtr < pixelPtrLimit) + *tempPixelPtr++ ^= aPixel; + + pixelPtr += longWidth; + pixelPtrLimit += longWidth; + } + } + +//CDrawEightBppBitmapCommon::WriteRgbMultiAND() called from CDrawBitmap::WriteRgbMulti() +//aX and aY - physical coordinates +//aLength and aRows - physical length and rows +void CDrawEightBppBitmapCommon::WriteRgbMultiAND(TInt aX,TInt aY,TInt aLength,TInt aRows, + TUint8 aPixel) + { + register TInt longWidth = iLongWidth; + TUint8* pixelPtr = PixelAddress(aX,aY); + const TUint8* pixelPtrLimit = pixelPtr + aLength; + const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; + register const TUint8* bitsEnd = reinterpret_cast (iBits) + iLongWidth * iSize.iHeight; + if(pixelRowPtrLimit >= bitsEnd) + { + pixelRowPtrLimit = bitsEnd; + } + + while (pixelPtr < pixelRowPtrLimit) + { + TUint8* tempPixelPtr = pixelPtr; + + while (tempPixelPtr < pixelPtrLimit) + *tempPixelPtr++ &= aPixel; + + pixelPtr += longWidth; + pixelPtrLimit += longWidth; + } + } + +//CDrawEightBppBitmapCommon::WriteRgbMultiOR() called from CDrawBitmap::WriteRgbMulti() +//aX and aY - physical coordinates +//aLength and aRows - physical length and rows +void CDrawEightBppBitmapCommon::WriteRgbMultiOR(TInt aX,TInt aY,TInt aLength,TInt aRows,TUint8 aPixel) + { + register TInt longWidth = iLongWidth; + TUint8* pixelPtr = PixelAddress(aX,aY); + TUint8* pixelPtrLimit = pixelPtr + aLength; + const TUint8* pixelRowPtrLimit = pixelPtr + aRows * longWidth; + register const TUint8* bitsEnd = reinterpret_cast (iBits) + iLongWidth * iSize.iHeight; + if(pixelRowPtrLimit >= bitsEnd) + { + pixelRowPtrLimit = bitsEnd; + } + + while (pixelPtr < pixelRowPtrLimit) + { + TUint8* tempPixelPtr = pixelPtr; + + while (tempPixelPtr < pixelPtrLimit) + *tempPixelPtr++ |= aPixel; + + pixelPtr += longWidth; + pixelPtrLimit += longWidth; + } + } + +/** +Implementation for CFbsDrawDevice::GetInterface(). +Retrieves a pointer to a specified interface of CFbsDrawDevice implementation. +@param aInterfaceId Interface identifier of the interface to be retrieved. +@param aInterface Address of variable that retrieves the specified interface. +@return KErrNone If the interface is supported, KErrNotSupported otherwise. +*/ + +TInt CDrawEightBppBitmapCommon::GetInterface(TInt aInterfaceId, TAny*& aInterface) + { + aInterface = NULL; + TInt ret = KErrNotSupported; + + if (aInterfaceId == KFastBlit2InterfaceID) + { + aInterface = static_cast(this); + ret = KErrNone; + } + else + return CDrawBitmap::GetInterface(aInterfaceId, aInterface); + + return ret; + } + +/** +CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation. +@internalTechnology +@see MFastBlit2::WriteBitmapBlock() +*/ +TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest, + CFbsDrawDevice* aSrcDrawDevice, + const TRect& aSrcRect) + { + __ASSERT_DEBUG(aSrcDrawDevice && ((aSrcDrawDevice->DisplayMode()==EColor256) || (aSrcDrawDevice->DisplayMode()==EGray256)), Panic(EScreenDriverPanicInvalidParameter)); + + TAny* interface=NULL; + TInt ret = aSrcDrawDevice->GetInterface(KFastBlit2InterfaceID, interface); + if (ret != KErrNone) + { + return KErrNotSupported; + } + + TAny* interface1=NULL; + ret = aSrcDrawDevice->GetInterface(KScalingSettingsInterfaceID, interface1); + if(ret != KErrNone || (interface1 && !reinterpret_cast(interface1)->IsScalingOff())) + { + return KErrNotSupported; + } + + ret = aSrcDrawDevice->GetInterface(KOrientationInterfaceID, interface1); + if(ret != KErrNone || (interface1 && reinterpret_cast(interface1)->Orientation() != 0)) + { + return KErrNotSupported; + } + + ret = aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, interface1); + if(ret != KErrNone) + { + return KErrNotSupported; + } + + if(interface1) + { + TPoint pt; + reinterpret_cast(interface1)->Get(pt); + if(pt.iX != 0 || pt.iY != 0) + { + return KErrNotSupported; + } + } + + const TUint32* srcBase = reinterpret_cast(interface)->Bits(); + __ASSERT_DEBUG(srcBase!=NULL, Panic(EScreenDriverPanicInvalidParameter)); + TInt srcStride = aSrcDrawDevice->ScanLineBytes(); + __ASSERT_DEBUG((srcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter)); // stride is assumed to be a multiple of 4 + TSize srcSize = aSrcDrawDevice->SizeInPixels(); + + return WriteBitmapBlock(aDest, srcBase, srcStride, srcSize, aSrcRect); + } + + +/** +CDrawEightBppBitmapCommon::WriteBitmapBlock() implementation. +@internalTechnology +@see MFastBlit2::WriteBitmapBlock() +*/ +TInt CDrawEightBppBitmapCommon::WriteBitmapBlock(const TPoint& aDest, + const TUint32* aSrcBase, + TInt aSrcStride, + const TSize& aSrcSize, + const TRect& aSrcRect) + { + __ASSERT_DEBUG(aSrcBase, Panic(EScreenDriverPanicInvalidParameter)); + __ASSERT_DEBUG((aSrcStride&3)==0, Panic(EScreenDriverPanicInvalidParameter)); + __ASSERT_DEBUG(iBits, Panic(EScreenDriverPanicInvalidPointer)); + + if (iShadowMode!=NULL || + (iUserDispMode!=NULL && iUserDispMode!=iDispMode) || + iOrientation!=EOrientationNormal || + !IsScalingOff() || + !iOriginIsZero) + { + return KErrNotSupported; + } + + __ASSERT_DEBUG(aSrcRect.iTl.iX >= 0, Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG(aSrcRect.iTl.iY >= 0, Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG(aSrcRect.iBr.iX <= aSrcSize.iWidth, Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG(aSrcRect.iBr.iY <= aSrcSize.iHeight, Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG(aDest.iX >= 0, Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG(aDest.iY >= 0, Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG((aDest.iX + aSrcRect.Width()) <= SizeInPixels().iWidth, Panic(EScreenDriverPanicOutOfBounds)); + __ASSERT_DEBUG((aDest.iY + aSrcRect.Height()) <= SizeInPixels().iHeight, Panic(EScreenDriverPanicOutOfBounds)); + + const TInt srcStride8 = aSrcStride; + const TInt dstStride8 = iScanLineWords << 2; + + if (aSrcSize.iWidth == aSrcRect.Width() && + aSrcSize.iWidth == SizeInPixels().iWidth && + srcStride8 == dstStride8) + { + // Optimum case - one memcpy + __ASSERT_DEBUG(aSrcRect.iTl.iX==0 && aDest.iX==0, Panic(EScreenDriverPanicInvalidParameter)); // this is implied by the above conditions + const TUint32* srcPtr = aSrcBase + (iScanLineWords * aSrcRect.iTl.iY); + TUint32* dstPtr = iBits + (iScanLineWords * aDest.iY); + const TInt length = aSrcStride * aSrcRect.Height(); + Mem::Move(dstPtr, srcPtr, length); + return KErrNone; + } + + // Sub-optimal case - one memcpy per line + const TUint8* srcPtr = (TUint8*)aSrcBase + (srcStride8 * aSrcRect.iTl.iY) + aSrcRect.iTl.iX; + TUint8* dstPtr = (TUint8*)iBits + (dstStride8 * aDest.iY ) + aDest.iX; + const TInt length = aSrcRect.Width(); + TInt lines = aSrcRect.Height(); + while (lines--) + { + Mem::Copy(dstPtr, srcPtr, length); + srcPtr += srcStride8; + dstPtr += dstStride8; + } + return KErrNone; + } + + +/** +CDrawEightBppBitmapCommon::Bits() implementation. +@internalTechnology +@see MFastBlit2::Bits() +*/ +const TUint32* CDrawEightBppBitmapCommon::Bits() const + { + return iBits; +}