📄 puthz.cpp
字号:
/////////////
// putHZ.h : v0011
// Written by : Liu Gang
// Compiler : Microsoft Visual C++ 4.0 & DirectX
// Library : DDraw.Lib
// Copyright (C) : 1996 WayAhead Corporation
// v0010 : Oct.4.1996
// v0011 : Apr.9.1997, change the name of GetSurface() to GetDDSurface()
// v0012 : Sep.2.1997, add an English version of PloyTextOut()
/////////////
// implementation file
#include "stdafx.h"
#include <stdio.h>
#include "putHZ.h"
//#define ENGLISH
//#define COMPLEX
//#define JAPANESE
#define SIMPLE
FILE *HZ_fp = NULL;
CDDText::CDDText()
{
myhdc=NULL;
//bmpsize;
m_bmpsize.cx = m_bmpsize.cy = 0;
m_mybytes=NULL;
myhbmpsec=NULL;
oldbmp=NULL;
m_rcClient.left = m_rcClient.top = 0;
m_rcClient.bottom = m_rcClient.right = 0;
m_textcolor=RGB(255,255,255);
m_dwColorCaps=DDBLTFAST_SRCCOLORKEY;
m_nCol = 0;
m_nRow = 0;
m_nLineDist = 4; // line distance
//m_Face;
}
CDDText::~CDDText()
{
EndText();
};
//prepare dc for MyDrawText and MyTextOut
BOOL CDDText::BeginText( int nCol, int nRow/*=1*/, BOOL bColorKey/*=TRUE*/)
{
// ASSERT(!myhdc);
if(myhdc) return FALSE;
//m_bmpsize.cx = m_rcClient.right-m_rcClient.left;
//m_bmpsize.cy = m_rcClient.bottom-m_rcClient.top;
m_bmpsize.cx=800, m_bmpsize.cy=CHAR_HEIGHT;
//line may over 800
myhdc=::CreateCompatibleDC(NULL);
LPBITMAPINFOHEADER header=(LPBITMAPINFOHEADER)new BYTE[(sizeof(BITMAPINFOHEADER)+8)];
if(header==NULL) return FALSE;
header->biSize=sizeof(BITMAPINFOHEADER);
header->biWidth=m_bmpsize.cx;
header->biHeight=-m_bmpsize.cy;
header->biPlanes=1;
header->biBitCount=1;
header->biCompression=BI_RGB;
header->biSizeImage=0;
header->biXPelsPerMeter=0;
header->biYPelsPerMeter=0;
header->biClrUsed=0;
header->biClrImportant=0;
DWORD *rgb=(DWORD*)(header+1);
rgb[0]=0;
rgb[1]=0xffffff00;
myhbmpsec=CreateDIBSection(myhdc, (LPBITMAPINFO)header, DIB_RGB_COLORS, (void**)&m_mybytes, NULL, 0);
if( !myhbmpsec ) return FALSE;
oldbmp=::SelectObject(myhdc, myhbmpsec);
delete header;
// prepare surface object
m_rcClient.right = nCol*CHAR_WIDTH, m_rcClient.bottom = nRow*(CHAR_HEIGHT+m_nLineDist);
m_nCol = nCol;
m_nRow = nRow;
if( bColorKey )
m_dwColorCaps = DDBLTFAST_SRCCOLORKEY;
else
m_dwColorCaps = DDBLTFAST_NOCOLORKEY;
// in system memory
if( m_Face.Create( m_rcClient.right, m_rcClient.bottom, bColorKey, FALSE ) )
{
m_Face.Erase(); return TRUE;
}
return FALSE;
}
//delete objects used by MyDrawText and MyTextOut
void CDDText::EndText()
{
if(!myhdc) return;
::SelectObject(myhdc, oldbmp);
::DeleteObject(myhbmpsec);
::DeleteDC(myhdc);
myhdc=NULL;
// can be omitted
m_Face.Release();
}
/////////////////
/////////////////
// read text data from charactor library
#ifdef SIMPLE
inline int CDDText::ReadData( LPCTSTR String, int len )
{
SIZE bmpsize;
BYTE *mybytes;
mybytes=m_mybytes;
bmpsize.cx = m_bmpsize.cx, bmpsize.cy = m_bmpsize.cy;
/*
// read from hz lib file
FILE *HZ_fp;
HZ_fp=fopen("hzk\\complex.exp", "rb");
if( !HZ_fp ) return 0;
*/
//Assert(HZ_fp);
int xsize=len*CHAR_WIDTH;
//ASSERT(xsize+16<bmpsize.cx);
BYTE *strp=(BYTE*)String;
for(int i=0;i<xsize/CHAR_WIDTH;i++){
BYTE c=*strp++;
if(c<(BYTE)0x81){
fseek(HZ_fp, (9*94+c-0x20-1)*32, SEEK_SET);
WORD buf[16];
fread(buf, 1, 32, HZ_fp);
__asm{
lea esi, buf
mov edi, mybytes
add edi, i
lea eax, bmpsize
mov eax, [eax] //load bmpsize.cx
shr eax, 3
sub eax, 2
mov ecx, 16
rep3:
movsw
add edi, eax
// inc esi
loop rep3
}
}
else
if(c>=(BYTE)0xa1 && c<=(BYTE)0xf7 && *strp>=(BYTE)0xa1 && *strp<=(BYTE)0xff){
// fseek(HZ_fp, ((c-(c>=(BYTE)0xe0?0xc1:0x81))*0xbc+*strp-(*strp>(BYTE)0x7f?0x41:0x40))*32, SEEK_SET);
fseek(HZ_fp, ((c-0xa1)*94+*strp-0xa1)*32, SEEK_SET);
// WORD* off=(WORD*)(mybytes+i);
// int add=bmpsize.cx/8/2;
// WORD* end=off+bmpsize.cx;
// for(;off<end;off+=add)fread(off, 2, 1, HZ_fp);
WORD buf[16];
fread(buf, 32, 1, HZ_fp);
__asm{
lea esi, buf
mov edi, mybytes
add edi, i
lea eax, bmpsize
mov eax, [eax] //load bmpsize.cx
shr eax, 3
sub eax, 2
mov ecx, 16
rep1:
movsw
add edi, eax
loop rep1
}
i++;strp++;
}
else {
static WORD scancode[]={0x8FAA,0xE041,0x90AA,0xAC72,0xD867,0xEB68,0xEE84,0xAB64,0xAB95,0x8379};
int fileoffset=sizeof(scancode)/sizeof(WORD);
_asm{
lea edi, scancode[0]
mov ecx, fileoffset
mov eax, strp
mov al, [eax]
mov ah, c
repne scasw
mov fileoffset, ecx
}
if(fileoffset)fileoffset=(10*94+sizeof(scancode)/2-fileoffset-1)*32;
fseek(HZ_fp, fileoffset, SEEK_SET);
WORD buf[16];
fread(buf, 1, 32, HZ_fp);
__asm{
lea esi, buf
mov edi, mybytes
add edi, i
lea eax, bmpsize
mov eax, [eax] //load bmpsize.cx
shr eax, 3
sub eax, 2
mov ecx, 16
rep2:
movsw
add edi, eax
loop rep2
}
// TRACE("%02X%02X%c%c\n", c, *strp, c, *strp);
i++;strp++;
}
}
// fclose(HZ_fp);
return xsize;
}
#endif
#ifdef ENGLISH
inline int CDDText::ReadData( LPCTSTR string, int nLen )
{
return 0;
}
#endif
#ifdef COMPLEX
inline int CDDText::ReadData( LPCTSTR string, int nLen )
{
return 0;
}
#endif
#ifdef JAPANESE
inline int CDDText::ReadData( LPCTSTR string, int len )
{
SIZE bmpsize;
BYTE *mybytes;
mybytes=m_mybytes;
bmpsize.cx = m_bmpsize.cx, bmpsize.cy = m_bmpsize.cy;
/*
FILE *HZ_fp;
HZ_fp=fopen("hzk\\jisexp.16", "rb");
if( !HZ_fp ) return 0;
*/
//Assert(HZ_fp);
int xsize=len*CHAR_WIDTH;
BYTE *strp=(BYTE*)string;
for(int i=0;i<xsize/CHAR_WIDTH;i++){
BYTE c=*strp++;
if(c<(BYTE)0x80){
fseek(HZ_fp, (3*0xbc+(BYTE)0xdc-(BYTE)0x41+c)*32, SEEK_SET);
BYTE* off=mybytes+i;
BYTE buf[32];
BYTE* bufp=buf;
fread(buf, 32, 1, HZ_fp);
__asm{
lea esi, buf
mov edi, mybytes
add edi, i
lea eax, bmpsize
mov eax, [eax] //load bmpsize.cx
shr eax, 3
sub eax, 2
mov ecx, 16
rep3:
movsw
add edi, eax
loop rep3
}
}
else if(c<(BYTE)0xdf && c>=(BYTE)0xa0){
fseek(HZ_fp, (4*0xbc+(BYTE)0x9e-(BYTE)0x41+c-(BYTE)0xa0)*32, SEEK_SET);
BYTE* off=mybytes+i;
BYTE buf[32];
BYTE* bufp=buf;
fread(buf, 32, 1, HZ_fp);
__asm{
lea esi, buf
mov edi, mybytes
add edi, i
lea eax, bmpsize
mov eax, [eax] //load bmpsize.cx
shr eax, 3
sub eax, 2
mov ecx, 16
rep1:
movsw
add edi, eax
loop rep1
}
i++;strp++;
}
else
if(c>=(BYTE)0x81 && c<=(BYTE)0xea
&& *strp>=(BYTE)0x40 && *strp!=(BYTE)0x7f && *strp<=(BYTE)0xfc){
fseek(HZ_fp, ((c-(c>=(BYTE)0xe0?0xc1:0x81))*0xbc+
*strp-(*strp>(BYTE)0x7f?0x41:0x40))*32, SEEK_SET);
WORD buf[16];
fread(buf, 1, 32, HZ_fp);
__asm{
lea esi, buf
mov edi, mybytes
add edi, i
lea eax, bmpsize
mov eax, [eax] //load bmpsize.cx
shr eax, 3
sub eax, 2
mov ecx, 16
rep2:
movsw
add edi, eax
loop rep2
}
i++;strp++;
}
}
// fclose(HZ_fp);
return xsize;
}
#endif
/////////////////
/////////////////
// draw text
BOOL CDDText::MyTextOut(LPDIRECTDRAWSURFACE2 pSurface, int x, int y, LPCTSTR String)
{
return MyTextOut(pSurface, x, y, String, strlen(String));
}
#ifdef ENGLISH
// english
BOOL CDDText::MyTextOut(LPDIRECTDRAWSURFACE2 pSurface, int x, int y, LPCTSTR String, int len)
{
HDC hdc=NULL;
if( pSurface->GetDC( &hdc ) == DD_OK )
{
if( m_dwColorCaps==DDBLTFAST_SRCCOLORKEY )
::SetBkMode( hdc, TRANSPARENT );
else
{
::SetBkColor( hdc, RGB(0,0,0) );
::SetBkMode( hdc, OPAQUE );
}
::SetTextColor( hdc, RGB(10,10,10) );
::TextOut( hdc, x+2,y+2, String, len );
::SetTextColor( hdc, m_textcolor );
::TextOut( hdc, x, y, String, len );
pSurface->ReleaseDC( hdc );
return TRUE;
}
return FALSE;
}
#else
// other language
BOOL CDDText::MyTextOut(LPDIRECTDRAWSURFACE2 pSurface, int x, int y, LPCTSTR String, int len)
{
if(!myhdc) return FALSE;
if( len<0 ) len = strlen( String );
if( len>m_nCol ) len = m_nCol;
// read data
int xsize = ReadData( String, len );
// draw to my surface
//COLORREF color=::GetTextColor( hdc );
HDC hdc=0;
if( m_Face.GetSurface()->GetDC( &hdc ) == DD_OK )
{
RGBQUAD rgb[2]={{0,0,0,0},
{GetBValue(m_textcolor),
GetGValue(m_textcolor),
GetRValue(m_textcolor),0}};
::SetDIBColorTable(myhdc, 0, 2, (RGBQUAD*)rgb);
::BitBlt(hdc, 0,0,xsize,m_bmpsize.cy,myhdc,0,0,SRCCOPY);
m_Face.GetSurface()->ReleaseDC( hdc );
}
// draw to output surface
RECT rect;
rect.left=rect.top=0;
if( m_rcClient.right < xsize ) rect.right=xsize;
else rect.right=m_rcClient.right;
rect.bottom = m_bmpsize.cy;
if( rect.right+x > SCREEN_WIDTH ) rect.right = SCREEN_WIDTH-x;
if( rect.bottom+y > SCREEN_HEIGHT ) rect.bottom = SCREEN_HEIGHT-y;
POINT pt;
pt.x = x, pt.y = y;
::DD_BltSurface( pt, pSurface,
&rect, m_Face.GetSurface(), m_dwColorCaps );
m_Face.Erase();
/*
if( pSurface->GetSurface()->GetDC( &hdc ) == DD_OK )
{
RGBQUAD rgb[2]={{0,0,0,0}, {GetBValue(color),GetGValue(color),GetRValue(color),0}};
RGBQUAD rgb2[2]={{255,255,255,0},{0,0,0,0}};
::SetDIBColorTable(myhdc, 0, 2, (RGBQUAD*)rgb2);
::BitBlt(hdc, x,y,xsize,bmpsize.cy,myhdc,0,0,SRCAND);
pSurface->GetSurface()->ReleaseDC( hdc );
}
*/
return TRUE;
}
#endif
BOOL CDDText::MyDrawText(LPDIRECTDRAWSURFACE2 pSurface, LPCTSTR String, int len, LPRECT prect, UINT nFormat)
{
if(len<0)len=strlen(String);
if(nFormat & DT_CENTER)
return(MyTextOut(pSurface, prect->left+(prect->right-prect->left-len*CHAR_WIDTH)/2,
prect->top+(prect->bottom-prect->top-CHAR_HEIGHT)/2,String, len));
else
return(MyTextOut(pSurface,0,0,String, len));
}
BOOL CDDText::MyDrawText(LPDIRECTDRAWSURFACE2 pSurface, LPCTSTR String, LPRECT prect, UINT nFormat)
{
int len=strlen( String );
if(nFormat & DT_CENTER)
return(MyTextOut(pSurface, prect->left+(prect->right-prect->left-len*CHAR_WIDTH)/2,
prect->top+(prect->bottom-prect->top-CHAR_HEIGHT)/2,String, len));
else
return(MyTextOut(pSurface,0,0,String));
}
#ifdef ENGLISH
BOOL CDDText::PolyTextOut( LPDIRECTDRAWSURFACE2 pSurface, int x, int y, const char *String )
{
if( !myhdc ) return FALSE;
int len = strlen( String );
int xsize=0;
char Str[1024], *pStr;
strcpy( Str, String ); pStr=Str;
int nCol = m_nCol; // chinese charactor number
int nRow = len/nCol+1;
if( nRow>m_nRow ) nRow = m_nRow;
// read data
COLORREF color=m_textcolor;
HDC hdc=0;
if( m_Face.GetSurface()->GetDC( &hdc ) == DD_OK )
{
int nCounter = len;
int nLineCounter = 0;
while( nCounter > 0 )
{
int nLineCol = nCol;
if( nCounter < nCol )
{
nLineCol = nCounter; // 不够满行
}
else
{
// 判断是否把一个词分开了
while( *(pStr+nLineCol) != ' ' )
{
nLineCol--;
if( nLineCol == 0 )
{ // 如果没有空格,则断行写
nLineCol = nCol;
if( nCounter < nCol )
nLineCol = nCounter; // 不够满行
break;
}
}
}
// my text
if( m_dwColorCaps==DDBLTFAST_SRCCOLORKEY )
::SetBkMode( hdc, TRANSPARENT );
else
{
::SetBkColor( hdc, RGB(0,0,0) );
::SetBkMode( hdc, OPAQUE );
}
::SetTextColor( hdc, RGB(10,10,10) );
::TextOut( hdc, 2,nLineCounter*(CHAR_HEIGHT+m_nLineDist)+2, pStr, nLineCol );
::SetTextColor( hdc, color );
::TextOut( hdc, 0,nLineCounter*(CHAR_HEIGHT+m_nLineDist), pStr, nLineCol );
pStr += nLineCol;
nCounter -= nLineCol;
nLineCounter ++;
if( nLineCounter > nRow )
break;
}
m_Face.GetSurface()->ReleaseDC( hdc );
}
// draw to output surface
RECT rect;
rect.left=rect.top=0;
if( m_rcClient.right < xsize ) rect.right=xsize;
else rect.right=m_rcClient.right;
rect.bottom = m_rcClient.bottom;
if( rect.right+x > SCREEN_WIDTH ) rect.right = SCREEN_WIDTH-x;
if( rect.bottom+y > SCREEN_HEIGHT ) rect.bottom = SCREEN_HEIGHT-y;
POINT pt;
pt.x = x, pt.y = y;
::DD_BltSurface( pt, pSurface,
&rect, m_Face.GetSurface(), m_dwColorCaps );
return TRUE;
}
#else
// for other languages
BOOL CDDText::PolyTextOut( LPDIRECTDRAWSURFACE2 pSurface, int x, int y, const char *String )
{
if( !myhdc ) return FALSE;
int len = strlen( String );
int xsize=0;
char Str[1024], *pStr;
strcpy( Str, String ); pStr=Str;
int nCol = m_nCol; // chinese charactor number
int nRow = len/nCol+1;
if( nRow>m_nRow ) nRow = m_nRow;
// read data
COLORREF color=m_textcolor;
HDC hdc=0;
if( m_Face.GetSurface()->GetDC( &hdc ) == DD_OK )
{
for( int i=0; i< nRow; i++ )
{
int linelen = strlen( pStr )/nCol;
if( linelen > 0 ) linelen = nCol;
else linelen = strlen(pStr)%nCol;
xsize = ReadData( pStr, linelen );
// draw to my surface
RGBQUAD rgb[2]={{0,0,0,0}, {GetBValue(color),GetGValue(color),GetRValue(color),0}};
::SetDIBColorTable(myhdc, 0, 2, (RGBQUAD*)rgb);
::BitBlt(hdc, 0,i*(CHAR_HEIGHT+m_nLineDist),xsize,m_bmpsize.cy,
myhdc,0,0,SRCCOPY);
// read next line
pStr += nCol;
}
m_Face.GetSurface()->ReleaseDC( hdc );
}
// draw to output surface
RECT rect;
rect.left=rect.top=0;
if( m_rcClient.right < xsize ) rect.right=xsize;
else rect.right=m_rcClient.right;
rect.bottom = m_rcClient.bottom;
if( rect.right+x > SCREEN_WIDTH ) rect.right = SCREEN_WIDTH-x;
if( rect.bottom+y > SCREEN_HEIGHT ) rect.bottom = SCREEN_HEIGHT-y;
POINT pt;
pt.x = x, pt.y = y;
::DD_BltSurface( pt, pSurface,
&rect, m_Face.GetSurface(), m_dwColorCaps );
return TRUE;
}
#endif
// 打开和关闭字库
int HZ_OpenLib( char *filename)
{
#ifdef ENGLISH
return 1; // 对于英语无作用
#endif
HZ_fp=fopen( filename, "rb");
if( !HZ_fp ) return 0;
return 1;
}
void HZ_CloseLib()
{
#ifdef ENGLISH
return; // 对于英语无作用
#endif
fclose( HZ_fp );
}
/////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -