点阵字库HZK12 HZK16 HZK24 ASC12 ASC16 简介 及 使用方法[附源码]

字库点阵格式定义

ASC12  ' 8x12 ASCII点阵 一个字符12Byte
ASC16  ' 8x16 ASCII点阵 一个字符16Byte
ASC48  '24x48 ASCII点阵 一个字符144Byte

HZK12  '16x12 宋体汉字点阵  一个汉字24Byte
HZK14  '16x14 宋体汉字点阵  一个汉字28Byte
HZK16  '16x16 宋体汉字点阵  一个汉字32Byte
HZK16F '16x16 繁体宋体汉字点阵  一个汉字32Byte

HZK24F '24x24 仿宋汉字打印点阵  一个汉字72Byte
HZK24H '24x24 黑体汉字打印点阵  一个汉字72Byte
HZK24K '24x24 楷体汉字打印点阵  一个汉字72Byte
HZK24S '24x24 宋体汉字打印点阵  一个汉字72Byte
HZK24T '24x24 宋体符号打印点阵  一个符号72Byte

HZK40S '40x40 宋体汉字点阵  一个汉字200Byte
HZK40T '40x40 宋体符号点阵  一个符号200Byte

HZK48S '48x48 宋体汉字点阵  一个汉字288Byte
HZK48T '48x48 宋体符号点阵  一个符号288Byte

如何在嵌入式系统中使用大量的汉字和字符呢?

        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的显示方法的话,你会看到......呵呵,字被放倒了。这是因为该类字库与一般的汉字库不同,这类大字模汉字库是专供打印的打印字库,为了打印的方便将字模都放倒了,你使用时,只要将字模的位信息纵横转置显示即可。例如你如果定义为mat[24][3]则应该这样输出:
         for(i=0;i<24;i++)
              for(j=0;j<24;j++)
                  if((0x80>>i%8)&mat[j][i/8]) /*转置显示*/
                       putpixel(j+x,y+i,color);
  还有一类字库HZK12,虽然属于标准字库类型,但如果你将它的字模当作12*12位计算的话,根本无法正常显示汉字。因为字库设计者为了使用的方便,字摸每行的位数均补齐为8的整数倍,于是实际该字库的位长度是16*12,虽然每行都多出了4位,但这4位都是0(不显示),并不影响显示效果。

HZK16字库是符合GB2312标准的16×16点阵字库,HZK16的GB2312-80支持的汉字有6763个,符号682个。其中一级汉字有3755个,按声序排列,二级汉字有3008个,按偏旁部首排列。我们在一些应用场合根本用不到这么多汉字字模,所以在应用时就可以只提取部分字体作为己用。

HZK16字库里的16×16汉字一共需要256个点来显示,也就是说需要32个字节才能达到显示一个普通汉字的目的。

我们知道一个GB2312汉字是由两个字节编码的,范围为A1A1~FEFE。A1-A9为符号区,B0到F7为汉字区。每一个区有94个字符(注意:这只是编码的许可范围,不一定都有字型对应,比如符号区就有很多编码空白区域)。下面以汉字“我”为例,介绍如何在HZK16文件中找到它对应的32个字节的字模数据。

前面说到一个汉字占两个字节,这两个中前一个字节为该汉字的区号,后一个字节为该字的位号。其中,每个区记录94个汉字,位号为该字在该区中的位置。所以要找到“我”在hzk16库中的位置就必须得到它的区码和位码。(为了区别使用了区码和区号,其实是一个东西,别被我误导了)

区码:区号(汉字的第一个字节)-0xa0    (因为汉字编码是从0xa0区开始的,所以文件最前面就是从0xa0区开始,要算出相对区码)

位码:位号(汉字的第二个字节)-0xa0

这样我们就可以得到汉字在HZK16中的绝对偏移位置:

offset=(94*(区码-1)+(位码-1))*32

注解:1、区码减1是因为数组是以0为开始而区号位号是以1为开始的

            2、(94*(区号-1)+位号-1)是一个汉字字模占用的字节数

           3、最后乘以32是因为汉字库文应从该位置起的32字节信息记录该字的字模信息(前面提到一个汉字要有32个字节显示)

有了偏移地址就可以从HZK16中读取汉字编码了,剩下的就是文件操作了,就不说了,要看代码如下,是一个最简单的c语言程序。


hzk汉字点阵   
     

  7     int    i,j,k;
  8     unsigned    char    incode[3]="沈";    //    要读出的汉字   
  9     unsigned    char    qh,wh;
 10     unsigned    long    offset;
 11     //    占两个字节,    取其区位号   
 12     qh    =    incode[0]    -    0xa0;// /获得区码            
 13     wh    =    incode[1]    -    0xa0;//   / /获得位码               
 14     offset    =    (94*(qh-1)+(wh-1))*32;//          /    *得到偏移位置*    /   
 15
 16     FILE    *HZK;
 17     char    mat[32];
 18     if((HZK=fopen("HZK16",    "rb"))    ==    NULL)
 19     {
 20         printf("Can't    Open    hzk16\n");
 21         exit(0);
 22     }
 23     fseek(HZK,    offset,    SEEK_SET);
 24     fread(mat,    32,    1,    HZK);
 25
 26     //显示
 27     for(j=0;j<16;j++){
 28         for(i=0;i<2;i++)
 29         {
 30             for(k=0;k<8;k++)
 31                 if(mat[j*2+i]&(0x80>>k))///*测试为1的位则显示*/
 32                 {
 33                     printf("#");
 34
 35                 }else{   printf("-");
 36
 37                 }
 38         }
 39         printf("\n");
 40     }
 41     fclose(HZK);




http://www.cnblogs.com/nbsofer/archive/2012/11/01/2749026.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值