放置一点代码,关于汉字的知识,从DOS的汉字点阵字库说起。
汉字字库知识,首先了解以前DOS下的汉字字库的数据。
常用的汉字字库有12X12,15X15,16X16的点阵字库,还有24点阵,48点阵的字库用于打印机打印。出现在早期的UCDOS,CCDOS,和TW汉字系统上。
16X16点阵的汉字,一个汉字占32个字节。
24X24点阵的汉字,一个汉字占72个字节。
32X32点阵的汉字,一个汉字占128个字节。
点阵汉字的数据,分以行为主,和以列为主的汉字数据。CCDOS是以列为主的,UCDOS是以行为主的汉字数据字库。
汉字字库的读取:汉字字库的内码是区位码。这个计算机专业课有讲过。但是区位码的第7行到第12行之间为空白,或其它点阵信息。
所以DOS的点阵字库中有压缩版的汉字库和非压缩版的汉字库。
很多网上的DOS早期游戏中的中文游戏部分,一般一个游戏中是带有专门的字库的,这些点阵字库都很好看。
区位码是汉字点阵数据信息在原汉字库的序号。
公式:
m=((code/100)-1)*94+(code%100)-1
这里的code是区位码,m是字库汉字点阵数据中的汉字偏量数据值。
汉字点阵信息的第一个字节在原汉字库的偏移量为
k=m*kk
kk是汉字点阵信息所占用的字节数。
#include "stdlib.h" #include "stdio.h" void hzlibr1 (num,fn1,fn2,fn3) char *fn1,*fn2,fn3; int num; {FILE *fp1,*fp2,*fn3; int code,i,j,m,x,y,kk; long int k; char *p; kk=(num+1)*(num+1)*8; p=malloc(kk*sizeof(char)); if((fp1=fopen(fn1,"r+b"))==NULL) { printf("cannot open fn1 \n"); exit (0); } if ((fp2=fopen(fn2,"w+b"))==NULL) { printf("cannot open fn2 ! \n"); exit (0); } if ((fp3=fopen(fn3,"r+t"))==NULL) { printf ("cannot open fn3 ! \n"); exit (0); } i=0; while (fscanf(fp3,"%d",&code) != EOF) { j=code; y=j/100; x=j-y*100; m=(y-1)*94+(x-1); k=(long)m*(long)kk; fseek(fp1,k*sizeof(char),SEEK_SET); fread(p,sizeof(char),kk,fp1); k=(long)i*(long)kk; fseek(fp2,k*sizeof(char),SEEK_SET); fwrite(p,sizeof(char),kk,fp2); i=i+1; } fclose(fp1);fclose(fp2);fclose(fp3); free(p); return; }
程序函数介绍:
include 关键字是包含文件,包含 标准库文件头,和标准输入输出文件头。
函数带4个入口参数,返回值为NULL。
函数入口前三个参数为指针函数。
FILE 是一个数据结构,包含文件指针。
malloc 是分配内存空间函数。
fopen 是打开文件函数
printf 是显示文本函数
fscanf 是键盘输入函数
fseek 是文件查找指针函数
fread 是读文件数据函数
fwrite 是写文件数据函数
fclose 是关闭文件函数
free 是清空指针所指的内存缓冲区空间。
这些函数包含在标准头文件中,是文件处理模块,和标准输出输出模块。
上面的函数是读字库文件,字库文件是以行为主的方法保存数据的,且6行空白区没被压缩。
现在,让我们进化一下,我出个题目:
如果汉字数据第7行到第12行压缩了该怎么办?
列出公式:
(code / 100) < 7 时:
m=((code/100)-1*94+(code%100)-1
(code /100) >= 7 时:
m=((code/100)-7)*94+(code%100)-1
汉字点阵信息的第一字节偏移量是:
k=m*kk
下期再会,to be coniunte......