资源描述
1/ 4如何在嵌入式系统中使用大量的汉字和字符呢?DOS 前辈们经过艰辛的努力,将制作好的字模放到了一个个标准的库中以 免去后辈的麻烦,这就是点阵字库文件。一般我们使用 16*16 的点阵宋体字库,所谓 16*16,是每一个汉字在纵、横 各 16点的区域内显示的。不过后来又有了 HZK12、HZK24, HZK32 和 HZK48 字库及黑体、楷体和隶书字库。虽然汉字库种 类繁多,但都是按照区位的顺序排列的。前一个字节为该汉字的区号,后一个 字节为该字的位号。每一个区记录 94 个汉字,位号则为该字在该区中的位置。因此,汉字在汉字库中的具体位置计算公式为: 94*(区号-1)+位号-1。减 1 是因为数组是以 0 为开始而区号位号是以 1 为开始的。这仅为以汉字为单位该 汉字在汉字库中的位置,那么,如何得到以字节为单位得到该汉字在汉字库中 的位置呢?只需乘上一个汉字字模占用的字节数即可,即:(94*(区号-1)+位号-1)*一个汉字字模占用字节数,而按每种汉字库的汉字大小不同又会得到不同的结果。以 16*16 点阵字库为例,计算公式则为:(94*(区号- 1 )+(位号- 1 )*32 。汉字库文该从该位置起的 32 字节信息即记录了 该字的字模信息。打印字库文件和 HZK12女口果你有 UCDOS 的 HZK24S(宋体)、 HZK24K(楷体) 或 HZK24H(黑 体) ,你还可以使用不同字体的大字模汉字了。HZK24 系列是 24*24 的点阵字库,每字模占用 3*24 字节。如果你按照 HZK16 的显示方法的话,你会看到 呵呵,字被放倒了。这是因为该类字库与一般的汉字库不同,这类大字模汉字 库是专供打印的打印字库,为了打印的方便将字模都放倒了,你使用时,只要 将字模的位信息纵横转置显示即可。例如你如果定义为 mat243 则应该这样输 出:for(i=0;i24;i+)for(j=0;ji%8)&matji/8)/* 转置显示 */putpixel(j+x,y+i,color);还有一类字库 HZK12 虽然属于标准字库类型,但如果你将它的字模当作12*12 位计算的话,根本无法正常显示汉字。因为字库设计者为了使用的方便, 字摸每行的位数均补齐为 8 的整数倍,于是实际该字库的位长度是 16*12,虽然 每行都多出了 4 位,但这 4 位都是 0(不显示),并不影响显示效果。HZK16 字库是符合 GB2312 标准的 16X1 点阵字库,HZK16 的 GB2312-80 支持的汉字有 6763 个,符号 682 个。其中一级汉字有 3755 个,按声序排列,二级 汉字有 3008 个,按偏旁部首排列。我们在一些应用场合根本用不到这么多汉字 字模,所以在应用时就可以只提取部分字体作为己用。HZK16 字库里的 16X1 汉字一共需要 256 个点来显示,也就是说需要 32 个 字节才能达到显示一个普通汉字的目的。我们知道一个 GB2312 汉字是由两个字节编码的,范围为 A1FE A1-A9 为 符号区,B0 到 F7 为汉字区。每一个区有 94 个字符(注意:这只是编码的许可范围,不一定都有字型对应,比如符号区就有很多编码 空白区域)。下面以汉字 我”为例,介绍如何在 HZK16 文件中找到它对应的 32 个字节的字模数据。前面说到一个汉字占两个字节,这两个中前一个字节为该汉字的区号,后 一个字节为该字的位号。其中,每个区记录 94 个汉字,位号为该字在该区中的 位置。所以要找到 我”在 hzk16 库中的位置就必须得到它的区码和位码。(为了 区别使用了区码和区号,其实是一个东西,别被我误导了)区码:区号(汉字的第一个字节)-0 xa0(因为汉字编码是从 0 xa0 区开始的,所以 文件最前面就是从 0 xa0 区开始,要算出相对区码)位码:位号(汉字的第二个字节) -0 xa03/ 4这样我们就可以得到汉字在HZK16 中的绝对偏移位置:offset=(94*(区码-1)+(位 码-1)*32注解:1、 区码减 1 是因为数组是以 0 为开始而区号位号是以 1 为开始的2、 (94*(区号-1)+位号-1)是一个汉字字模占用的字节数3、 最后乘以 32 是因为汉字库文应从该位置起的 32 字节信息记录该字的字 模信息(前面提到一个汉字要有 32 个字节显示)有了偏移地址就可以从 HZK16 中读取汉字编码了,剩下的就是文件操作 了,就不说了,要看代码如下,是一个最简单的 c 语言程序。hzk 汉字点阵inti,j,k;unsignedcharincode3=我”; ;要读出的汉字unsignedcharqh,wh;unsignedlongoffset;/ 占两个字节 ,取其区位号qh=incode0-0 xa0;/ /获得区码wh=incode1-0 xa0;/ /获得位码offset=(94*(qh-1)+(wh-1)*32;/* 得到偏移位置 */FILE*HZK;charmat32;if(HZK=fopen(hzk16,rb)=NULL)printf(CantOpenhzk16n);exit_(d4Qsoo4OZH)SOO抿(&%=)七20宀F芟s%=)匕u一dFL氷M0(M仝O8xo)03=s4euj)七(+X8VMO艾)04(+zvo.ll)04(+r9LVod04 OZHL&ec5E)pe4U山sly山山swgqXZHWSHS)
展开阅读全文