📄 bitmapmethods.cpp
字号:
/*
* ============================================================================
* Name : NBitmapMethods from BitmapMethods.cpp
* Part of : Mopoid
* Created : 16.01.2004 by Andreas Jakl / Mopius - http://www.mopius.com/
* Based on source file originally provided by Nokia
* Version : 1.02
* Copyright:
* 'Mopoid' is free software; you can redistribute
* it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* 'Mopoid' is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 'Mopoid'; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ============================================================================
*/
#include "bitmapmethods.h"
#include <eikenv.h>
#include <fbs.h>
CFbsBitGc* NBitmapMethods::CreateGraphicsContextLC(CFbsBitmapDevice& aBitmapDevice)
{
CFbsBitGc* graphicsContext = NULL;
User::LeaveIfError(aBitmapDevice.CreateContext(graphicsContext));
CleanupStack::PushL(graphicsContext);
return graphicsContext;
}
CFbsBitGc* NBitmapMethods::CreateGraphicsContextL(CFbsBitmapDevice& aBitmapDevice)
{
CFbsBitGc* gc = CreateGraphicsContextLC(aBitmapDevice);
CleanupStack::Pop(gc);
return gc;
}
CFbsBitmapDevice* NBitmapMethods::CreateBitmapDeviceLC(CFbsBitmap& aBitmap)
{
CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(&aBitmap);
CleanupStack::PushL(bitmapDevice);
return bitmapDevice;
}
CFbsBitmapDevice* NBitmapMethods::CreateBitmapDeviceL(CFbsBitmap& aBitmap)
{
CFbsBitmapDevice* device = CreateBitmapDeviceLC(aBitmap);
CleanupStack::Pop(device);
return device;
}
CFbsBitmap* NBitmapMethods::CreateBitmapLC(TSize aSizeInPixels,TDisplayMode aDispMode)
{
CFbsBitmap* bitmap = new(ELeave) CFbsBitmap();
CleanupStack::PushL(bitmap);
User::LeaveIfError(bitmap->Create(aSizeInPixels,aDispMode));
//ASSERT((bitmap->DisplayMode() == KColourDepth) || (bitmap->DisplayMode() == EGray2));
return bitmap;
}
CFbsBitmap* NBitmapMethods::CreateBitmapL(TSize aSizeInPixels,TDisplayMode aDispMode)
{
CFbsBitmap* bitmap = CreateBitmapLC(aSizeInPixels,aDispMode);
CleanupStack::Pop(bitmap);
return bitmap;
}
CFbsBitmap* NBitmapMethods::CreateBitmapLC(const TDesC& aFileName,TInt aId)
{
CFbsBitmap* bitmap = new(ELeave) CFbsBitmap();
CleanupStack::PushL(bitmap);
TInt loadException = bitmap->Load(aFileName,aId);
User::LeaveIfError(loadException);
if ((bitmap->DisplayMode() == KColourDepth) || (bitmap->DisplayMode() == EGray2))
{
return bitmap;
}
else
{
CFbsBitmap* newBitmap = CreateBitmapLC( bitmap->SizeInPixels(),KColourDepth);
CFbsBitmapDevice* bitmapDevice = CreateBitmapDeviceLC(*newBitmap);
CFbsBitGc* bitmapGc = CreateGraphicsContextLC(*bitmapDevice);
bitmapGc->BitBlt(TPoint(0,0),bitmap,TRect(bitmap->SizeInPixels()));
CleanupStack::PopAndDestroy(2); // gc and device
// The next three lines are here to get rid of the old bitmap but keep the new one
CleanupStack::Pop(newBitmap);
CleanupStack::PopAndDestroy(bitmap);
CleanupStack::PushL(newBitmap);
return newBitmap;
}
}
CFbsBitmap* NBitmapMethods::CreateBitmapL(const TDesC& aFileName,TInt aId)
{
CFbsBitmap* bitmap = CreateBitmapLC(aFileName, aId);
CleanupStack::Pop(bitmap);
return bitmap;
}
CFbsBitmap* NBitmapMethods::CreateMaskL(CFbsBitmap* aBmpSource, TBool aUseMaskColor, TUint16 aMaskColor)
{
// Build transparency mask
//TUint16 maskColor = (MASK_RED / 17) << 8 | (MASK_GREEN / 17) << 4 | (MASK_BLUE / 17);
const TSize bmpSize = aBmpSource->SizeInPixels();
CFbsBitmap* bmpTarget = NBitmapMethods::CreateBitmapLC(bmpSize, EGray2);
// TBitmapUtil is used to lock the bitmap data's heap position, so it can't be
// relocated by the FBServer which would result in a access violation)
TBitmapUtil buSrcLock(aBmpSource);
buSrcLock.Begin(TPoint(0,0));
TBitmapUtil buDstLock(bmpTarget);
buDstLock.Begin(TPoint(0,0), buSrcLock);
// get the pointer to the bmp raw data
TUint16* pRawSrc = (TUint16*)aBmpSource->DataAddress();
TUint8* pRawDst = (TUint8*)bmpTarget->DataAddress();
TUint8 destPixel = 0x00;
// Get top left pixel color and use it as transparency mask color
TUint16 maskColor;
if (aUseMaskColor)
maskColor = aMaskColor;
else
maskColor = (*pRawSrc);
// Get the width of the source bitmap
TInt w = bmpSize.iWidth;
// Correction for bitmaps with uneven width
TInt oddW = w & 0x01;
// Calculate number of bits of one line of the 2 color bitmap
TInt bitW = w;
if (w % 32 != 0)
bitW += (32 - w % 32);
TInt combinedPixels = 0;
TInt combinedLinePixels = 0;
TInt i;
//To set a specific bit to 0 rather than 1, the program could be modified to include the following expression x &= ~(01 << n)
for (TInt y = 0; y < bmpSize.iHeight; y++)
{
for (TInt x = 0; x < w; x++)
{
if ((*pRawSrc) != maskColor)
{
destPixel |= (0x01 << combinedPixels);
}
pRawSrc++;
combinedPixels++;
combinedLinePixels++;
if (combinedPixels == 8)
{
// One byte of the target data complete, save it to the bitmap
(*pRawDst) = destPixel;
pRawDst++;
destPixel = 0;
combinedPixels = 0;
}
}
if (combinedPixels > 0)
{
// Width of source bitmap not dividable by 8 - some pixels were left over
// -> write rest of it to target bitmap
for (i = combinedPixels; i<8; i++)
destPixel |= (0x01 << i);
(*pRawDst) = destPixel;
pRawDst++;
destPixel = 0x00;
combinedLinePixels += 8 - combinedPixels;
combinedPixels = 0;
}
if (combinedLinePixels < bitW)
{
// Fill the target bitmap so that the line contains a number of bytes
// dividable by 4 (that's the way symbian stores 1bit bitmaps...)
TInt difference = (bitW - combinedLinePixels);
for (i = 0; i < difference; i+= 8)
{
(*pRawDst) = 0xFF;
pRawDst++;
}
}
combinedLinePixels = 0;
pRawSrc += oddW; // correction for bitmaps of odd width
}
buDstLock.End(); // unlock bitmap server heap
buSrcLock.End();
CleanupStack::Pop(bmpTarget); // if this fails, crashes in system memory!
return bmpTarget;
}
void NBitmapMethods::SplitImageL(CFbsBitmap* aSourceBmp, CFbsBitmap** aTargetBmps, TInt aNumPics, TDisplayMode aDisplayMode, TBool aReverseOrder)
{
TInt bmpWidth = (aSourceBmp->SizeInPixels()).iWidth / aNumPics;
TSize newBmpSize(bmpWidth, (aSourceBmp->SizeInPixels()).iHeight);
TInt index = (aReverseOrder) ? (aNumPics-1) : 0;
// Split the bitmap up into the individual frames
for (TInt i = 0; i < aNumPics; i++)
{
aTargetBmps[index] = NBitmapMethods::CreateBitmapL(newBmpSize, aDisplayMode);
CFbsBitmapDevice* bitmapDevice = NBitmapMethods::CreateBitmapDeviceLC(*aTargetBmps[index]);
CFbsBitGc* bitmapGc;
User::LeaveIfError( bitmapDevice->CreateContext(bitmapGc) );
bitmapGc->BitBlt( TPoint(0, 0), aSourceBmp, TRect(TPoint(i * bmpWidth, 0), newBmpSize) );
delete bitmapGc;
CleanupStack::PopAndDestroy(1); // device
index += ((aReverseOrder) ? (-1) : 1);
}
}
void NBitmapMethods::BitBltMaskedEntireBitmap(CFbsBitGc& aTargetGc,TPoint aTopLeft,
const CFbsBitmap& aBitmap,const CFbsBitmap& aBitMask)
{
PartialReset(aTargetGc);
aTargetGc.BitBltMasked(aTopLeft,&aBitmap,aBitmap.SizeInPixels(),&aBitMask,ETrue);
PartialReset(aTargetGc);
}
void NBitmapMethods::PartialReset(CFbsBitGc& aGc)
{
aGc.SetPenSize(TSize(1,1));
aGc.SetPenColor(KRgbBlack);
aGc.SetPenStyle(CFbsBitGc::ESolidPen);
aGc.SetDrawMode(CFbsBitGc::EDrawModePEN);
aGc.DiscardFont();
aGc.DiscardBrushPattern();
aGc.SetBrushColor(KRgbWhite);
aGc.SetBrushStyle(CFbsBitGc::ENullBrush);
aGc.SetCharJustification(0,0);
aGc.SetWordJustification(0,0);
aGc.SetDitherOrigin(TPoint(0,0));
aGc.SetPenStyle(CFbsBitGc::ENullPen);
aGc.SetShadowMode(EFalse);
aGc.SetStrikethroughStyle(EStrikethroughOff);
aGc.SetUnderlineStyle(EUnderlineOff);
aGc.SetUserDisplayMode(ENone);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -