/* ---------------------------------------------------------------------------------------------------
*
* Windows CE Graphics Libary v1.00.0000
*
*
* Written by James.
* Bug report : jiet@msn.com
* Copyright 2001
*/
// File : CEGDIObject.CPP
// Graphics Object define.
//-----------------------------------------------------------------------------------------------------
// Update Information.
//-----------------------------------------------------------------------------------------------------
/*
* Created by James D. 2001.
* Date: 01/11/2001
*/
#include "StdAfx.h"
#include "CEGDIObject.h"
#include "CEDraw.h"
/*----------------------------------- Pen Class ------------------------------- */
//
// Function : CCEPen()
// Purpose : Construction function.
//
CCEPen::CCEPen( UINT nPenStyle, UINT nWidth, unsigned short Color )
{
m_dwObjectType = CEG_GDIOBJECT_TYPE_PEN;
m_nPenStyle = nPenStyle;
m_nWidth = nWidth;
m_Color = Color;
}
CCEPen::CCEPen()
{
m_nPenStyle = 0;
m_nWidth = 1;
m_Color = 0;
m_dwObjectType = CEG_GDIOBJECT_TYPE_PEN;
}
//
// Function : ~CCEPen()
// Purpose : Destruction function.
//
CCEPen::~CCEPen()
{
}
//
// Function : CreatePen()
// Purpose : Create the pen and set items' style
//
BOOL CCEPen::CreatePen( UINT nPenStyle, UINT nWidth, unsigned short Color )
{
m_nPenStyle = nPenStyle;
m_nWidth = nWidth;
m_Color = Color;
return TRUE;
}
/*----------------------------------- Brush Class ------------------------------- */
//
// Function : CCEBrush()
// Purpose : Construction function.
//
CCEBrush::CCEBrush( UINT nBrushStyle, unsigned short Color, long lbHatch )
{
m_dwObjectType = CEG_GDIOBJECT_TYPE_BRUSH;
m_nBrushStyle = nBrushStyle;
m_lbHatch = lbHatch;
m_Color = Color;
}
CCEBrush::CCEBrush()
{
m_nBrushStyle = 0;
m_lbHatch = 0;
m_Color = 0;
m_dwObjectType = CEG_GDIOBJECT_TYPE_BRUSH;
}
//
// Function : ~CCEPen()
// Purpose : Destruction function.
//
CCEBrush::~CCEBrush()
{
}
//
// Function : CreatePen()
// Purpose : Create the pen and set items' style
//
BOOL CCEBrush::CreateBrush( UINT nBrushStyle, unsigned short Color, long lbHatch )
{
m_dwObjectType = CEG_GDIOBJECT_TYPE_BRUSH;
m_nBrushStyle = nBrushStyle;
m_lbHatch = lbHatch;
m_Color = Color;
return TRUE;
}
/*----------------------------------- Font Class ------------------------------- */
//
// Function : CCEFont()
// Purpose : Construction function.
//
CCEFont::CCEFont()
{
m_hFont = NULL;
}
//
// Function : ~CCEFont()
// Purpose : Destruction function.
//
CCEFont::~CCEFont()
{
if( NULL != m_hFont )
{
::DeleteObject( m_hFont );
}
}
//
// Function : CreateFont()
// Purpose : Create the Font
//
BOOL CCEFont::CreateFont( int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int nWeight,
BYTE bItalic,
BYTE bUnderline,
BYTE cStrikeOut,
BYTE nCharSet,
BYTE nOutPrecision,
BYTE nClipPrecision,
BYTE nQuality,
BYTE nPitchAndFamily,
LPCTSTR lpszFacename )
{
LOGFONT logFont;
logFont.lfHeight = nHeight;
logFont.lfWidth = nWidth;
logFont.lfEscapement = nEscapement;
logFont.lfOrientation = nOrientation;
logFont.lfWeight = nWeight;
logFont.lfItalic = bItalic;
logFont.lfUnderline = bUnderline;
logFont.lfStrikeOut = cStrikeOut;
logFont.lfCharSet = nCharSet;
logFont.lfOutPrecision = nOutPrecision;
logFont.lfClipPrecision = nClipPrecision;
logFont.lfQuality = nQuality;
logFont.lfPitchAndFamily = nPitchAndFamily;
memcpy( logFont.lfFaceName, lpszFacename, LF_FACESIZE );
m_hFont = ::CreateFontIndirect( &logFont );
if ( NULL == m_hFont ) return FALSE;
return TRUE;
}
BOOL CCEFont::CreateFontIndirect( const LOGFONT *lpFont )
{
m_hFont = ::CreateFontIndirect( lpFont );
if ( NULL == m_hFont ) return FALSE;
return TRUE;
}
/*----------------------------------- Bitmap Class ------------------------------- */
//
// Function : CCEBitmap()
// Purpose : Construction function.
//
CCEBitmap::CCEBitmap()
{
m_pBitmapBuffer = NULL;
m_nType = CEB_TYPE_BITMAP;
}
//
// Function : ~CCEFont()
// Purpose : Destruction function.
//
CCEBitmap::~CCEBitmap()
{
if( NULL != m_pBitmapBuffer )
{
free( m_pBitmapBuffer );
}
}
//
// Function : LoadBitmap()
// Purpose : Load the bitmap and translate to the GAPI recoginzlia memory buffer...
//
BOOL CCEBitmap::LoadBitmap( CCEDraw* pCEDraw, LPCTSTR lpszBitmapName )
{
HBITMAP hBitmap;
BITMAP Bitmap;
// Free the buffer, if it exist...
if( NULL != m_pBitmapBuffer )
{
free( m_pBitmapBuffer );
m_pBitmapBuffer = NULL;
}
// If the lpszBitmapName == NULL, that means we create a screen bitmap...
if( NULL == lpszBitmapName )
{
m_sizeBitmap.cx = pCEDraw->GetDisplayProperties().cxWidth;
m_sizeBitmap.cy = pCEDraw->GetDisplayProperties().cyHeight;
m_pBitmapBuffer = (unsigned char*)malloc( m_sizeBitmap.cx * m_sizeBitmap.cy * pCEDraw->GetDisplayProperties().cBPP / 8 );
memcpy( m_pBitmapBuffer, pCEDraw->GetBuffer(), m_sizeBitmap.cx * m_sizeBitmap.cy * pCEDraw->GetDisplayProperties().cBPP / 8 );
m_nType = CEB_TYPE_SCREENBUFFER;
return TRUE;
}
// First to load the bitmap from file...
hBitmap = (HBITMAP) LoadFile( lpszBitmapName );
//hBitmap =(HBITMAP)::LoadBitmap( GetModuleHandle( NULL ), MAKEINTRESOURCE(IDB_BITMAP1));
if( hBitmap == NULL )
{
// Failed to load the bitmap...
return FALSE;
}
GetObject( hBitmap, sizeof(BITMAP), &Bitmap );
// Creating new bitmap and receive pointer to it's bits.
HBITMAP hTargetBitmap;
unsigned char *pBuffer;
// Initilize DIBINFO structure
BITMAPINFO dibInfo;
dibInfo.bmiHeader.biBitCount = 24;
dibInfo.bmiHeader.biClrImportant = 0;
dibInfo.bmiHeader.biClrUsed = 0;
dibInfo.bmiHeader.biCompression = 0;
dibInfo.bmiHeader.biHeight = Bitmap.bmHeight;
dibInfo.bmiHeader.biPlanes = 1;
dibInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
dibInfo.bmiHeader.biSizeImage = Bitmap.bmWidth*Bitmap.bmHeight*3;
dibInfo.bmiHeader.biWidth = Bitmap.bmWidth;
dibInfo.bmiHeader.biXPelsPerMeter = 3780;
dibInfo.bmiHeader.biYPelsPerMeter = 3780;
dibInfo.bmiColors[0].rgbBlue = 0;
dibInfo.bmiColors[0].rgbGreen = 0;
dibInfo.bmiColors[0].rgbRed = 0;
dibInfo.bmiColors[0].rgbReserved = 0;
// Create bitmap and receive pointer to points into pBuffer
HDC hDC = ::GetDC(NULL);
ASSERT(hDC);
hTargetBitmap = CreateDIBSection( hDC,
(const BITMAPINFO*)&dibInfo,
DIB_RGB_COLORS,
(void**)&pBuffer,
NULL,
0
);
::ReleaseDC(NULL, hDC);
// Copy source bitmap into the target bitmap.
// Create 2 device contexts
HDC memDc;
if ( !( memDc = CreateCompatibleDC(NULL) ) )
{
DeleteObject( hBitmap );
DeleteObject( hTargetBitmap );
return FALSE;
}
HDC targetDc;
if ( !( targetDc = CreateCompatibleDC(NULL) ) )
{
DeleteDC( memDc );
DeleteObject( hBitmap );
DeleteObject( hTargetBitmap );
return FALSE;
}
// Select source bitmap into one DC, target into another
HBITMAP hOldBitmap1 = (HBITMAP)::SelectObject( memDc, hBitmap);
HBITMAP hOldBitmap2 = (HBITMAP)::SelectObject( targetDc, hTargetBitmap );
// Copy source bitmap into the target one
::BitBlt( targetDc, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight, memDc, 0, 0, SRCCOPY );
// Create my own bitmap buffer use the GAPI recognized style...
// Free the memory if it exist...
int nX, nY;
unsigned short nColor;
int nBitmapYPitch = ((Bitmap.bmWidth*3)+3) & 0xfffc;
BOOL bReturn = TRUE;
if( NULL != m_pBitmapBuffer )
{
free( m_pBitmapBuffer );
m_pBitmapBuffer = NULL;
}
long cByte = pCEDraw->GetDisplayProperties().cBPP / 8;
m_sizeBitmap.cx = Bitmap.bmWidth;
m_sizeBitmap.cy = Bitmap.bmHeight;
m_pBitmapBuffer = (unsigned char*)malloc( Bitmap.bmWidth * Bitmap.bmHeight * cByte );
if( !m_pBitmapBuffer )
{
bReturn = FALSE;
goto Exit;
}
/* Warning : Does not support 8 byte color model in here */
for( nY = 0; nY < Bitmap.bmHeight ; nY ++ )
{
for( nX = 0; nX < Bitmap.bmWidth ; nX ++ )
{
nColor = pCEDraw->GetBitmapPointColor( ( pBuffer + ( nX ) * 3 +
( Bitmap.bmHeight - nY - 1 ) *
nBitmapYPitch ) );
if( cByte == 2 )
*(unsigned short*)( m_pBitmapBuffer + ( nX + nY * Bitmap.bmWidth ) * cByte ) = nColor;
else *( m_pBitmapBuffer + ( nX + nY * Bitmap.bmWidth ) * cByte ) = (BYTE)nColor;
}
}
// Restore device contexts
Exit:
::SelectObject( memDc, hOldBitmap1 );
::SelectObject( targetDc, hOldBitmap2 );
DeleteDC( memDc );
DeleteDC( targetDc );
DeleteObject( hBitmap );
DeleteObject( hTargetBitmap );
return bReturn;
}
//
// Function : BitBlt()
// Transfers pixels from a specified source rectangle to a specified destination rectangle
//
BOOL CCEBitmap::BitBlt( CCEDraw* pCEDraw, int nXDest, int nYDest, int nWidth, int nHeight, int nXSrc, int nYSrc, DWORD dwRop, float fAlpha )
{
if( NULL == pCEDraw || NULL == m_pBitmapBuffer ) return FALSE;
unsigned char* pBuffer = pCEDraw->GetBuffer();
unsigned char* pBitmap = m_pBitmapBuffer;
long cbxPitch = pCEDraw->m_cbxPitch;
long cbyPitch = pCEDraw->m_cbyPitch;
long cbxBmpPitch = pCEDraw->GetDisplayProperties().cBPP / 8;
long cbyBmpPitch = cbxBmpPitch * m_sizeBitmap.cx;
long cBPP = pCEDraw->GetDisplayProperties().cBPP;
// The buffer type is screenbuffer, so...
if( m_nType == CEB_TYPE_SCREENBUFFER )
{
//cbxBmpPitch = cbxPitch;
//cbyBmpPitch = cbyPitch;
if( dwRop == SRCCOPY )
memcpy( pCEDraw->GetBuffer(), m_pBitmapBuffer, m_sizeBitmap.cx * m_sizeBitmap.cy * pCEDraw->GetDisplayProperties().cBPP / 8 );
else return FALSE;
}
nWidth == 0 ? nWidth = m_sizeBitmap.cx : nWidth;
nHeight == 0 ? nHeight = m_sizeBitmap.cy : nHeight;
if( ( nXSrc + nWidth ) > m_sizeBitmap.cx ) nWidth = m_sizeBitmap.cx - nXSrc;
if( ( nYSrc + nHeight ) > m_sizeBitmap.cy ) nHeight = m_sizeBitmap.cy - nYSrc;
if( ( nXDest + nWidth ) > (LONG)pCEDraw->GetDisplayProperties().cxWidth )
nWidth = pCEDraw->GetDisplayProperties().cxWidth - nXDest;
if( ( nYDest + nHeight ) > (LONG)pCEDraw->GetDisplayProperties().cyHeight )
nHeight = pCEDraw->GetDisplayProperties().cyHeight - nYDest;
if( pCEDraw->IsPointOutside( nXDest, nYDest ) &&
pCEDraw->IsPointOutside( nXDest + nWidth, nYDest + nHeight ) &&
pCEDraw->IsPointOutside( nXDest + nWidth, nYDest ) &&
pCEDraw->IsPointOutside( nXDest, nYDest + nHeight ) ) return TRUE; // Not need to draw the bitmap;
// Prepare the buffer pointer...
pBuffer += nXDest * cbxPitch + nYDest * cbyPitch;
pBitmap += nXSrc * cbxBmpPitch + nYSrc * cbyBmpPitch;
// Copy the buffer data ...
unsigned char* pHeadBuffer = pBuffer;
unsigned char* pHeadBmpBuffer = pBitmap;
unsigned short ColorR, ColorG, ColorB, Color;
if( dwRop == SRCCOPY )
{
for( int y = 0; y < nHeight; y ++ )
{
pBuffer = pHeadBuffer;
pBitmap = pHeadBmpBuffer;
for( int x = 0; x < nWidth; x ++ )
{
if( cBPP == 8 )
{
*pBuffer = *pBitmap;
}
else
{
*(unsigned short*)pBuffer = *(unsigned short*)pBitmap;
}
pBuffer += cbxPitch;
pBitmap += cbxBmpPitch;
}
pHeadBmpBuffer += cbyBmpPitch;
pHeadBuffer += cbyPitch;
}
}
else if( dwRop == SRCCOLORKEY )
{
// Get the up left color as the colorkey
unsigned short ColorKey;
if( cBPP == 8 ) ColorKey = *pHeadBmpBuffer;
else ColorKey = *(unsigned short*)pHeadBmpBuffer;
for( int y = 0; y < nHeight; y ++ )
{
pBuffer = pHeadBuffer;
pBitmap = pHeadBmpBuffer;
for( int x = 0; x < nWidth; x ++ )
{
if( cBPP == 8 )
{
if( *pBitmap != ColorKey ) *pBuffer = *pBitmap;
}
else
{
if( *(unsigned short*)pBitmap != ColorKey )
*(unsigned short*)pBuffer = *(unsigned short*)pBitmap;
}
pBuffer += cbxPitch;
pBitmap += cbxBmpPitch;
}
pHeadBmpBuffer += cbyBmpPitch;
pHeadBuffer += cbyPitch;
}
}
else if ( dwRop == SRCALPHA && fAlpha != 0.5f )
{
for( int y = 0; y < nHeight; y ++ )
{
pBuffer = pHeadBuffer;
pBitmap = pHeadBmpBuffer;
for( int x = 0; x < nWidth; x ++ )
{
if( cBPP == 8 )
{
*pBuffer = *pBitmap;
}
else
{
if( pCEDraw->GetDisplayProperties().ffFormat & kfDirect565 )
{
/* n% ALPHA */
Color = *(unsigned short*)pBuffer;
ColorR = (unsigned short)((Color >> 11) & 0x1f) * ( 1 - fAlpha );
ColorG = (unsigned short)((Color >> 5) & 0x3f) * ( 1 - fAlpha );
ColorB = (unsigned short)(Color & 0x1f) * ( 1 - fAlpha );
Color = *(unsigned short*)pBitmap;
ColorR = (unsigned short)(((Color >> 11)&0x1f) * fAlpha + ColorR);
ColorG = (unsigned short)(((Color >> 5)&0x3f) * fAlpha + ColorG);
ColorB = (unsigned short)((Color & 0x1f)* fAlpha + ColorB);
Color = (unsigned short)( ( ColorR & 0xff ) << 11 |
( ColorG & 0xff ) << 5 |
( ColorB & 0xff ) );
*(unsigned short*)pBuffer = Color;
}
else if( pCEDraw->GetDisplayProperties().ffFormat & kfDirect555 )
{
/* n% ALPHA */
Color = *(unsigned short*)pBuffer;
ColorR = (unsigned short)((Color >> 10) & 0x1f) * ( 1 - fAlpha );
ColorG = (unsigned short)((Color >> 5) & 0x1f) * ( 1 - fAlpha );
ColorB = (unsigned short)(Color & 0x1f) * ( 1 - fAlpha );
Color = *(unsigned short*)pBitmap;
ColorR = (unsigned short)(((Color >> 10)&0x1f) * fAlpha + ColorR);
ColorG = (unsigned short)(((Color >> 5)&0x1f) * fAlpha + ColorG);
ColorB = (unsigned short)((Color & 0x1f)* fAlpha + ColorB);
Color = (unsigned short)( ( ColorR & 0xff ) << 10 |
( ColorG & 0xff ) << 5 |
( ColorB & 0xff ) );
*(unsigned short*)pBuffer = Color;
}
else *(unsigned short*)pBuffer = Color;
}
pBuffer += cbxPitch;
pBitmap += cbxBmpPitch;
}
pHeadBmpBuffer += cbyBmpPitch;
pHeadBuffer += cbyPitch;
}
}
else if ( dwRop == SRCALPHA )
{
for( int y = 0; y < nHeight; y ++ )
{
pBuffer = pHeadBuffer;
pBitmap = pHeadBmpBuffer;
for( int x = 0; x < nWidth; x ++ )
{
if( cBPP == 8 )
{
*pBuffer = *pBitmap;
}
else
{
if( pCEDraw->GetDisplayProperties().ffFormat & kfDirect565 )
{
Color = *(unsigned short*)pBuffer;
ColorR = ((Color >> 11)&0x1f)>>1;
ColorG = ((Color >> 5)&0x3f)>>1;
ColorB = (Color & 0x1f)>>1;
Color = *(unsigned short*)pBitmap;
ColorR = ((Color >> 11)&0x1f)>>1 + ColorR;
ColorG = ((Color >> 5)&0x3f)>>1 + ColorG;
ColorB = ((Color & 0x1f))>>1 + ColorB;
Color = (unsigned short)( ( ColorR & 0xff ) << 11 |
( ColorG & 0xff ) << 5 |
( ColorB & 0xff ) );
*(unsigned short*)pBuffer = Color;
}
else *(unsigned short*)pBuffer = Color;
}
pBuffer += cbxPitch;
pBitmap += cbxBmpPitch;
}
pHeadBmpBuffer += cbyBmpPitch;
pHeadBuffer += cbyPitch;
}
}
return TRUE;
}
//
// Function : LoadFile()
// Use the IMGDECMP.DLL to load the image data file...
//
HBITMAP CCEBitmap::LoadFile( LPCTSTR lpszBitmapName )
{
HBITMAP hBitmap = 0;
HDC hdc = CreateCompatibleDC(NULL);
HRESULT hr;
BYTE szBuffer[1024] = {0};
HANDLE hFile = INVALID_HANDLE_VALUE;
DecompressImageInfo dii;
hFile = CreateFile(lpszBitmapName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (hFile == INVALID_HANDLE_VALUE)
{
DeleteDC( hdc );
return FALSE;
}
// Fill in the 'DecompressImageInfo' structure
dii.dwSize = sizeof( DecompressImageInfo ); // Size of this structure
dii.pbBuffer = szBuffer; // Pointer to the buffer to use for data
dii.dwBufferMax = 1024; // Size of the buffer
dii.dwBufferCurrent = 0; // The amount of data which is current in the buffer
dii.phBM = &hBitmap; // Pointer to the bitmap returned (can be NULL)
dii.ppImageRender = NULL; // Pointer to an IImageRender object (can be NULL)
dii.iBitDepth = GetDeviceCaps(hdc,BITSPIXEL); // Bit depth of the output image
dii.lParam = ( LPARAM ) hFile; // User parameter for callback functions
dii.hdc = hdc; // HDC to use for retrieving palettes
dii.iScale = 100; // Scale factor (1 - 100)
dii.iMaxWidth = 10000; // Maximum width of the output image
dii.iMaxHeight = 10000; // Maxumum height of the output image
dii.pfnGetData = GetImageData; // Callback function to get image data
dii.pfnImageProgress = ImageProgress; // Callback function to notify caller of progress decoding the image
dii.crTransparentOverride = ( UINT ) -1; // If this color is not (UINT)-1, it will override the
// transparent color in the image with this color. (GIF ONLY)
// Process and decompress the image data
typedef HRESULT (CALLBACK* ULPRET)( DecompressImageInfo* pParams );
HINSTANCE hLib;
ULPRET lpfnDLLProc;
hLib = LoadLibrary ( L"Imgdecmp.dll" );
if ( hLib )
{
lpfnDLLProc = (ULPRET) GetProcAddress ( hLib, L"DecompressImageIndirect" );
hr = (*lpfnDLLProc) ( &dii );
FreeLibrary ( hLib );
}
// Clean up
DeleteDC( hdc );
CloseHandle( hFile );
return hBitmap;
}
//
// Function : GetImageData()
// Callback function to load image data...
//
DWORD CALLBACK CCEBitmap::GetImageData(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam )
{
DWORD dwNumberOfBytesRead;
if ( (HANDLE)lParam == INVALID_HANDLE_VALUE )
return 0;
ReadFile( (HANDLE)lParam, szBuffer, dwBufferMax, &dwNumberOfBytesRead, NULL );
// Return number of bytes read
return dwNumberOfBytesRead;
}
void CALLBACK CCEBitmap::ImageProgress(IImageRender *pRender, BOOL bComplete, LPARAM lParam )
{
if( bComplete )
{
// (Optional) add code here for completion processing
}
}