DOS下的点阵汉字显示_孙麟 HungryAnt

来源:百度文库 编辑:神马文学网 时间:2024/04/28 09:52:09
DOS下的点阵汉字显示
这里以 HZK16 文件为例,分析取得汉字字模的方法。
HZK16 文件是按照国标码的标准排列的。国标码分为 94 个区,每个区 94个位(Position),所以也称为区位码。
汉字占用两个字节,其中第一个字节的值为区号加上32(20H),第二个字节的值为位号加上32(20H)。为了与ASCII字符区别开,表示汉字的两个字节的最高位都是1,也就是两个字节的值都又加上了 128(80H)。这样,通过汉字的内码,就可以计算出汉字的区位码。具体算式如下:
qh=c1-32-128=c1-160,wh=c2-32-128=c2-160
qh,wh为汉字的区号和位号,c1,c2为汉字的第一字节和第二字节。根据区号和位号可以得到汉字字模在文件中的位置:
location=(94*(qh-1)+(wh-1))*一个点阵字模的字节数。
一个点阵字模究竟占用多少字节数是看其点阵数来确定的。如使用16×16点阵,字模中每一点使用一个二进制位(Bit)表示,如果是1,则说明此处有点,若是0,则说明没有。这样,一个16×16点阵的汉字总共需要16*16/8=32个字节表示。
下面是一些例子(特别说明:如果发现例子不能运行,请与站长联系。)
#include
#include
#include
#include
#include
#include
#define Byte unsigned char
#define Word unsigned int
int flag16,flag24;
void dishz();
main()
{
int Driver=DETECT,Mode;
registerbgidriver(EGAVGA_driver);
initgraph(&Driver,&Mode,"");
directvideo=0;
setbkcolor(1);
cleardevice();
dishz();
getch();
closegraph();
}
/*========================================================================*/
/*------------------------------16×16点阵汉字----------------------------*/
/*========================================================================*/
int out16hz(int x,int y,int z,int color,char *p)/* x,y起点坐标,z字间距 */
{
Word num,QM,WM,flag=0; /* QM,WM 区号和位号 */
int record,i,j,k;
long pointer;
char Bit[32]; /* 16点阵的汉字占32个字节 */
while((num=*p++)!=0)
{
if(num>0xA1)
if(flag==0) /* 注意一个汉字是两个字节的,这里是第一个字节 */
{
QM=(num-0xA1)&0x07F; /* 注意这里是减161了 */
flag=1;
}
else   /* 阅第二个字节 */
{
WM=(num-0xA1)&0x07F; /* 与上 0x07F 再检测一次 */
flag=0;
record=QM*94+WM;
pointer=record*32L; /* 定位出汉字字模在文件中的位置 */
lseek(flag16,pointer,SEEK_SET);
read(flag16,Bit,32);
for(i=0;i<16;i++) /* 写点 */
for(j=0;j<2;j++)
for(k=0;k<8;k++)
if(((Bit[i*2+j]>>(7-k))&0x1)!=NULL)
putpixel(x+j*8+k,y+i,color);
x=x+z+16;
}
}
}
/*========================================================================*/
/*------------------------------24×24点阵汉字----------------------------*/
/*========================================================================*/
int out24hz(int x,int y,int z,int color,int m,int n,char *p)
{
Word num,QM,WM,flag=0;
int i,j,k,width,height,record;
long pointer;
char Bit[72];
while((num=*p++)!=0)
{
if(num>0xA1)
if(flag==0)
{
QM=(num-15-0xA1)&0x07F;
flag=1;
}
else
{
WM=(num-0xA1)&0x07F;
flag=0;
record=QM*94+WM;
pointer=record*72L;
lseek(flag24,pointer,SEEK_SET);
read(flag24,Bit,72);
for(i=0;i<24*m;i=i+m)
for(width=0;widthfor(j=0;j<=2;j++)
for(k=0;k<8;k++)
if(((Bit[i/m*3+j]>>(7-k))&0x1)!=NULL)
for(height=0;heightputpixel(x+i+width,y+j*8*n+k*n+height,color);
x=x+24*m+z;
}
}
}
/*========================================================================*/
/*---------------------------------输出演示-------------------------------*/
/*========================================================================*/
void dishz()
{
Byte *str1[]={"16点阵汉字输出演示"};
Byte *str2[]={"24点阵汉字输出演示"};
int x=200,y=50,size=10;
flag16=open("c:\\ucdos\\HZK16F",O_RDWR|O_BINARY);
flag24=open("c:\\ucdos\\HZK24F",O_RDWR|O_BINARY);
if(flag16==-1)
{
printf("Cannot Open HZK16\n");
exit(1);
}
if(flag24==-1)
{
printf("Cannot Open HZK24\n");
exit(1);
}
out16hz(x,y,size,15,*str1);
y+=30;
out24hz(x,y,size,10,1,1,*str2);
x=100;y+=50;
x=200;y+=50;
out24hz(x,y,size,12,1,2,*str2);
x=100;y+=80;
out24hz(x,y,size,9,2,2,*str2);
close(flag16);
close(flag24);
}