自定义Bitblt函数

你在draw offscreenbuffer的时候不要用CFbsBitGc::BitBlt(),效率很低
可以自己写一个,比如

void inline CDrawBitmap:DoCopyPixel(TUint8*& aDest, TUint8*& aSource, TInt aBpp, TBool aCopy) const
{
switch(aBpp)
{
case 1:
{
*aDest++ = *aSource++;
break;
}
case 2:
{
TUint16* pDest = (TUint16*) aDest;
TUint16* pSource = (TUint16*) aSource;

if(aCopy)
{
*pDest = *pSource;
}

pDest++;
pSource++;

aDest = (TUint8*) pDest;
aSource = (TUint8*) pSource;
break;
}
default:
// If bitmap is not 1 byte per pixel or 2 bytes per pixel
// we don't draw anything.
break;
}
}


void CDrawBitmap::CustomBitBlt(TPoint aDestPoint, CFbsBitmap* aDest, CFbsBitmap* aSource, CFbsBitmap* aMask) const
{
// 锁定
TBitmapUtil bmpUtil1(aDest);
TBitmapUtil bmpUtil2(aSource);


bmpUtil1.Begin(aDestPoint);
bmpUtil2.Begin(TPoint(0,0), bmpUtil1);

TBitmapUtil bmpUtil3(aMask);
if(aMask) bmpUtil3.Begin(TPoint(0,0), bmpUtil2);

TUint8* pDataLineMask = NULL;
TInt strideMask = 0;

if(aMask)
{
pDataLineMask = (TUint8*) aMask->DataAddress();
strideMask = CFbsBitmap::ScanLineLength(aMask->SizeInPixels().iWidth, aMask->DisplayMode());
}

TUint8* pDataLineSource = (TUint8*) aSource->DataAddress();
TUint8* pDataLineDest = (TUint8*) aDest->DataAddress();

TSize sizeSource = aSource->SizeInPixels();
TSize sizeDest = aDest->SizeInPixels();

// Width in bytes
TInt strideSource = CFbsBitmap::ScanLineLength(sizeSource.iWidth, aSource->DisplayMode());
TInt strideDest = CFbsBitmap::ScanLineLength(sizeDest.iWidth, aDest->DisplayMode());

// Bytes per pixel in target bitmap
TInt bpp = strideDest / aDest->SizeInPixels().iWidth;

// Calculate dimensions of the copied area, we know that pixel-depth is 16-bits and mask is 1-bit


TInt lines; // The number of lines we are going to copy
TInt pixels; // The number of pixels per line


TInt maskPixelXInit;

if(aDestPoint.iY >= 0)
{
pDataLineDest = pDataLineDest + (bpp * aDestPoint.iX) + (aDestPoint.iY * strideDest);
lines = Min(sizeSource.iHeight, sizeDest.iHeight - aDestPoint.iY);
}
else
{
// The vertical position is negative so we need to make sure that we don't draw
// before the valid memory area.
pDataLineDest = pDataLineDest + (bpp * aDestPoint.iX);
lines = Min(sizeSource.iHeight + aDestPoint.iY, sizeDest.iHeight);
pDataLineSource = pDataLineSource + (-aDestPoint.iY * strideSource);
pDataLineMask = pDataLineMask + (-aDestPoint.iY * strideMask);
}

if(aDestPoint.iX >= 0)
{
pixels = Min(sizeSource.iWidth, sizeDest.iWidth - aDestPoint.iX);
maskPixelXInit = 0;
}
else
{
// The horizontal line starts left from screen edge; we must adjust
// so that copying starts from the screen edge.
pDataLineDest = pDataLineDest - (bpp * aDestPoint.iX);
pixels = Min(sizeSource.iWidth, sizeSource.iWidth + aDestPoint.iX);
maskPixelXInit = -aDestPoint.iX;
pDataLineSource = pDataLineSource + (bpp * -aDestPoint.iX);
}

TUint8* pDestX;
TUint8* pSourceX;
TInt maskPixelX;

// Copy contents
if(pixels > 0)
{
if(aMask)
{
for(TInt y = 0; y < lines; y++)
{
// Copy a line
pDestX = pDataLineDest;
pSourceX = pDataLineSource;
maskPixelX = maskPixelXInit;
for(TInt x = 0; x < pixels; x++)
{
if( (( *(pDataLineMask + (maskPixelX >> 3))) >> (maskPixelX % 8)) & 1 != 0)
{
DoCopyPixel(pDestX, pSourceX, bpp);
}
else
{
// Don't copy, just increase pointers
DoCopyPixel(pDestX, pSourceX, bpp, EFalse);
}
maskPixelX++;
}
// Advance to the next line
pDataLineDest = pDataLineDest + strideDest;
pDataLineSource = pDataLineSource + strideSource;
pDataLineMask = pDataLineMask + strideMask;
}
}
else
{
for(TInt y = 0; y < lines; y++)
{
// Copy a line
pDestX = pDataLineDest;
pSourceX = pDataLineSource;
maskPixelX = maskPixelXInit;
for(TInt x = 0; x < pixels; x++)
{
DoCopyPixel(pDestX, pSourceX, bpp);
}
// Advance to the next line
pDataLineDest = pDataLineDest + strideDest;
pDataLineSource = pDataLineSource + strideSource;
}
}
}

if(aMask) bmpUtil3.End();
bmpUtil2.End();
bmpUtil1.End();
}

猜你喜欢

转载自blog.csdn.net/dymx101/article/details/6553995