📄 imageobj.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:对图形对象进行管理(brush,bitmap,pen,font,region,palette)
版本号:3.0.0
开发时期:1999
作者:李林
修改记录:
2004-02-21: WinGdi_CreateDIBSection 用 hgwmeProcess 代替 GetCurrentProcess
2003-05-14 : CreateBitmap 为避免Heap的碎片化 对bitmap,
当其所用缓存大小 大于 某大小时, 用VirtualAlloc
当bmType = 1, 用VirtualAlloc;否则用,malloc
2003-05-07: LN:将CreateBitmap的默认值由白改为黑
******************************************************/
#include <eframe.h>
#include <eapisrv.h>
#include <bheap.h>
#include <epwin.h>
#include <gdc.h>
#include <winsrv.h>
#include <gdisrv.h>
#define MALLOC_SIZE_LIMIT (4 * 1024)
static LPOBJLIST _lpGdiObjList = NULL;
static CRITICAL_SECTION csGdiObjList;
BOOL AddToObjMgr( LPOBJLIST lpObj, DWORD objType, ULONG hOwner );
BOOL RemoveFromObjMgr( LPOBJLIST lpObj );
extern HBITMAP WINAPI WinGdi_CreateCompatibleBitmap(HDC hdc, int iWidth, int iHeight);
extern int _WinGdi_ConvertImageColorValue(
_LPCDISPLAYDRV lpDrv,
_LPBITMAP_DIB lpDestImage, // dest image data
LPCRECT lprcDestClip,
CONST BITMAPINFO * lpbi,// src image info
LPCRECT lprcSrcClip,
DWORD dwStartScanLine, // src start scan line
DWORD dwScanLineNum,
DWORD dwScanLineWidth,
LPCBYTE lpbData,// src bitmap bits data
int fuColorUse // use src's RGB or PAL
);
// **************************************************
// 声明:BOOL __InitialGdiObjMgr( void )
// 参数:
// 无
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 初始化 GDI 图形对象管理器
// 引用:
//
// ************************************************
BOOL _InitialGdiObjMgr( void )
{
InitializeCriticalSection( &csGdiObjList );
csGdiObjList.lpcsName = "CS-GOM";
return TRUE;
}
// **************************************************
// 声明:void __DeInitialGdiObjMgr( void )
// 参数:
// 无
// 返回值:
// 无
// 功能描述:
// 与 __InitialGdiObjMgr相反,释放图形对象管理器
// 引用:
//
// ************************************************
void _DeInitialGdiObjMgr( void )
{
DeleteCriticalSection( &csGdiObjList );
}
// **************************************************
// 声明:BOOL AddToObjMgr( LPOBJLIST lpObj, DWORD objType, ULONG hOwner )
// 参数:
// IN lpObj - OBJLIST 结构指针
// IN objType - 对象类型
// IN hOwner - 对象拥有者进程
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 将对象加入对象链表
// 引用:
//
// ************************************************
BOOL AddToObjMgr( LPOBJLIST lpObj, DWORD objType, ULONG hOwner )
{
BOOL bRetv;
EnterCriticalSection( &csGdiObjList );
bRetv = ObjList_Init( &_lpGdiObjList, lpObj, objType, (ULONG)hOwner );
LeaveCriticalSection( &csGdiObjList );
return bRetv;
}
// **************************************************
// 声明:BOOL RemoveFromObjMgr( LPOBJLIST lpObj )
// 参数:
// IN lpObj - OBJLIST 结构指针
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 与 AddToObjMgr 相反,将对象移出对象链表
// 引用:
//
// ************************************************
BOOL RemoveFromObjMgr( LPOBJLIST lpObj )
{
EnterCriticalSection( &csGdiObjList );
ObjList_Remove( &_lpGdiObjList, lpObj );
LeaveCriticalSection( &csGdiObjList );
return TRUE;
}
// **************************************************
// 声明:HBITMAP _GetShareBitmapObj( HINSTANCE hInst, DWORD dwName )
// 参数:
// IN hInst - 实例句柄
// IN dwName - 对象名
// 返回值:
// 假如成功,返回位图对象句柄;否则,返回 NULL
// 功能描述:
// 得到共享对象句柄
// 引用:
//
// ************************************************
HBITMAP _GetShareBitmapObj( HINSTANCE hInst, DWORD dwName )
{
HBITMAP hRetv = NULL;
LPOBJLIST lpObjList;
EnterCriticalSection( &csGdiObjList );
lpObjList = _lpGdiObjList;
while( lpObjList )
{
if( ( (WORD)lpObjList->objType ) == OBJ_BITMAP )
{
_LPBITMAP_SHARE lpBitmap = (_LPBITMAP_SHARE)lpObjList;
if( lpBitmap->bitmap.bmFlags & BF_SHARE )
{
if( hInst == lpBitmap->hInst &&
dwName == lpBitmap->szName )
{
lpObjList->iRefCount++;
hRetv = (HBITMAP)PTR_TO_HANDLE( lpBitmap );
break;
}
}
}
lpObjList = lpObjList->lpNext;
}
LeaveCriticalSection( &csGdiObjList );
return hRetv;
}
// **************************************************
// 声明:HBITMAP _WinGdi_CreateBitmap(
// int nWidth,
// int nHeight,
// UINT cPlanes,
// UINT cBitsPerPel,
// int iDir,
// const VOID *lpvBits,
// _LPBITMAPDATA * lppBitmap,
// UINT uiObjFlag,
// CONST BITMAPINFO *lpbmi,
// BOOL bIsShareResource
// )
// 参数:
// IN nWidth - 位图的宽度
// IN nHeight - 位图的高度
// IN cPlanes - 位面数
// IN cBitsPerPel - 每个点的 bit数
// IN iDir - 位图的方向(从顶向底或相反)
// IN lpvBits - 位图数据
// OUT lppBitmap - 用于接受描述位图格式的结构的指针
// IN uiObjFlag - 附加的对象标志
// IN lpbmi - 描述lpvBits位图格式的结构的指针,可以为NULL
// IN bIsShareResource - 说明新对象是否需要共享(来自于资源文件, lpbmi必须= NULL)
// 返回值:
// 假如成功,返回位图对象句柄;否则,返回NULL
// 功能描述:
// 按要求创建位图对象
// 引用:
//
// ************************************************
HBITMAP _WinGdi_CreateBitmap( int nWidth,
int nHeight,
UINT cPlanes,
UINT cBitsPerPel,
int iDir,
const VOID *lpvBits,
_LPBITMAPDATA * lppBitmap,
UINT uiObjFlag,
CONST BITMAPINFO *lpbmi,
BOOL bIsShareResource
)
{
_LPBITMAPDATA lpBitmap;
LPBYTE lpbBuf;
int scanBytes, size;
DWORD bmType = 0;
ASSERT( nWidth >= 0 && nHeight >= 0 );
//扫描行字节宽度
scanBytes = (cBitsPerPel * nWidth+31) / 32 * 4; // align to dword
//总的位图需要的字节数
size = scanBytes * nHeight * cPlanes;
//
if( lpbmi == NULL )
{ //默认的位图格式,分配 _BITMAPDATA结构对象
if( bIsShareResource )
{
lpBitmap = (_LPBITMAPDATA)BlockHeap_AllocString( hgwmeBlockHeap, 0, sizeof(_BITMAP_SHARE) );
if( lpBitmap )
memset( lpBitmap, 0, sizeof(_BITMAP_SHARE) );
bmType |= BF_SHARE;
}
else
{
lpBitmap = (_LPBITMAPDATA)BlockHeap_AllocString( hgwmeBlockHeap, 0, sizeof(_BITMAPDATA) );
if( lpBitmap )
memset( lpBitmap, 0, sizeof(_BITMAPDATA) );
}
if( lpBitmap == NULL )
{
ASSERT( 0 );
return NULL;
}
}
else
{ //lpbmi 包含设备无关信息
DWORD dwAllocSize = 0;
DWORD dwPalSize = 0;
UINT uiPalIndexNum = 0;
if( lpbmi->bmiHeader.biBitCount <= 8 )
{ // 可能有调色板
uiPalIndexNum = (1 << lpbmi->bmiHeader.biBitCount);
if( lpbmi->bmiHeader.biClrUsed )
uiPalIndexNum = MIN( lpbmi->bmiHeader.biClrUsed, uiPalIndexNum );
dwPalSize = uiPalIndexNum * sizeof(RGBQUAD);
}
else if( ( lpbmi->bmiHeader.biBitCount == 16 ||
lpbmi->bmiHeader.biBitCount == 32 ) &&
lpbmi->bmiHeader.biCompression == BI_BITFIELDS )
{ //无需调色板,应该有三个DWORD的 RGB 占位描述符
uiPalIndexNum = 3;
dwPalSize = sizeof( DWORD ) * uiPalIndexNum;
}
//计算 _BITMAPDATA 结构对象大小
dwAllocSize = sizeof( _BITMAP_DIB ) + dwPalSize - sizeof( DWORD );
//分配 _BITMAPDATA结构对象
lpBitmap = (_LPBITMAPDATA)BlockHeap_AllocString( hgwmeBlockHeap, 0, dwAllocSize );
if( lpBitmap )
{
UINT i;
PALETTEENTRY * lpPal = ((_LPBITMAP_DIB)lpBitmap)->palEntry;
RGBQUAD * lpQuad = (RGBQUAD *)lpbmi->bmiColors;
memset( lpBitmap, 0, dwAllocSize );
//初始化调色板信息
if( lpbmi->bmiHeader.biCompression == BI_BITFIELDS )
{ //三个 DWORD mask
for( i = 0; i < uiPalIndexNum; i++ )
{
*((LPDWORD)lpPal) = *( (LPDWORD)lpQuad );
lpPal++;
lpQuad++;
}
}
else
{
for( i = 0; i < uiPalIndexNum; i++ )
{
lpPal->peRed = lpQuad->rgbRed;
lpPal->peGreen = lpQuad->rgbGreen;
lpPal->peBlue = lpQuad->rgbBlue;
lpPal->peFlags = 0;
lpPal++;
lpQuad++;
}
}
bmType |= BF_DIB;
((_LPBITMAP_DIB)lpBitmap)->biClrImportant = lpbmi->bmiHeader.biClrImportant;
((_LPBITMAP_DIB)lpBitmap)->biClrUsed = uiPalIndexNum;
((_LPBITMAP_DIB)lpBitmap)->biCompression = lpbmi->bmiHeader.biCompression;
((_LPBITMAP_DIB)lpBitmap)->biDir = lpbmi->bmiHeader.biHeight > 0 ? -1 : 1;
((_LPBITMAP_DIB)lpBitmap)->biSizeImage = size;
}
}
//分配位图数据缓存,为防止堆碎片。
//如果缓存较小,则用BlockHeap_Alloc分配,
//否则用Page_AllocMem分配
if( bmType & BF_DIB )
{ //frame buffer 会被 user 访问, so PM_SHARE
lpbBuf = Page_AllocMem( size, NULL, PM_SHARE );
bmType |= 1;
}
else
{
if( size <= MALLOC_SIZE_LIMIT )
{
lpbBuf = (LPBYTE)BlockHeap_Alloc( hgwmeBlockHeap, 0, size );
//lpbBuf = (LPBYTE)BLK_Alloc( 0, size );
}
else
{
lpbBuf = Page_AllocMem( size, NULL, 0 );
bmType |= 1;
}
}
ASSERT( lpBitmap && lpbBuf );
if( lpBitmap && lpbBuf )
{ //分配成功
int i;
if( nWidth <= 0 )
nWidth = 1;
if( nHeight <= 0 )
nHeight = 1;
lpBitmap->bmFlags = (WORD)bmType;
lpBitmap->bmWidth = nWidth;
lpBitmap->bmHeight = nHeight;
lpBitmap->bmWidthBytes = scanBytes;
lpBitmap->bmPlanes = cPlanes;
lpBitmap->bmBitsPixel = cBitsPerPel;
lpBitmap->bmBits = lpbBuf;
if( lpvBits )
{ //如果有用户位图数据,则对齐到 WORD
int iDataByteWidth = (cBitsPerPel * nWidth+15) / 16 * 2;// align to word
LPBYTE lpBuf = (LPBYTE)lpBitmap->bmBits;
for( i = 0; i < nHeight; i++ )
{
memcpy( lpBuf, lpvBits, iDataByteWidth );
lpBuf += scanBytes;
(LPBYTE)lpvBits += iDataByteWidth;
}
}
else
{ //没有需要初始化的位图数据,为0
memset( lpBitmap->bmBits, 0, size );
}
//加入对象链表
AddToObjMgr( &lpBitmap->obj, OBJ_BITMAP | uiObjFlag, (ULONG)GetCallerProcess() );
}
else
{ //错误,做清除工作
if( lpBitmap )
{
BlockHeap_FreeString( hgwmeBlockHeap, 0, lpBitmap);
//BLK_FreeString( 0, lpBitmap);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -