Fix def files so that the implementation agnostic interface definition has no non-standards defined entry points, and change the eglrefimpl specific implementation to place its private entry points high up in the ordinal order space in the implementation region, not the standards based entrypoints region.
// 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 <TUint8*> (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 <const TUint8*> (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 <const TUint8*> (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 <const TUint8*> (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 <TUint8*> (aBuffer);
const TUint8* bufferPtrLimit = bufferPtr + aLength;
if(iScalingOff)
{
while(bufferPtr < bufferPtrLimit)
{
*pixelPtr = *bufferPtr++;
pixelPtr += pixelPtrInc;
}
}
else
{
const TUint8* bitsStart = reinterpret_cast <const TUint8*> (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 <TUint8*> (aBuffer);
const TUint8* bufferPtrLimit = bufferPtr + aLength;
if(iScalingOff)
{
while(bufferPtr < bufferPtrLimit)
{
*pixelPtr ^= *bufferPtr++;
pixelPtr += pixelPtrInc;
}
}
else
{
const TUint8* bitsStart = reinterpret_cast <const TUint8*> (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 <TUint8*> (aBuffer);
const TUint8* bufferPtrLimit = bufferPtr + aLength;
if(iScalingOff)
{
while(bufferPtr < bufferPtrLimit)
{
*pixelPtr &= *bufferPtr++;
pixelPtr += pixelPtrInc;
}
}
else
{
const TUint8* bitsStart = reinterpret_cast <const TUint8*> (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 <TUint8*> (aBuffer);
const TUint8* bufferPtrLimit = bufferPtr + aLength;
if(iScalingOff)
{
while(bufferPtr < bufferPtrLimit)
{
*pixelPtr |= *bufferPtr++;
pixelPtr += pixelPtrInc;
}
}
else
{
const TUint8* bitsStart = reinterpret_cast <const TUint8*> (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 <const TUint8*> (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 <const TUint8*> (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 <const TUint8*> (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 <const TUint8*> (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<MFastBlit2*>(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<MScalingSettings*>(interface1)->IsScalingOff()))
{
return KErrNotSupported;
}
ret = aSrcDrawDevice->GetInterface(KOrientationInterfaceID, interface1);
if(ret != KErrNone || (interface1 && reinterpret_cast<MDrawDeviceOrientation*>(interface1)->Orientation() != 0))
{
return KErrNotSupported;
}
ret = aSrcDrawDevice->GetInterface(KDrawDeviceOriginInterfaceID, interface1);
if(ret != KErrNone)
{
return KErrNotSupported;
}
if(interface1)
{
TPoint pt;
reinterpret_cast<MDrawDeviceOrigin*>(interface1)->Get(pt);
if(pt.iX != 0 || pt.iY != 0)
{
return KErrNotSupported;
}
}
const TUint32* srcBase = reinterpret_cast<MFastBlit2*>(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;
}