GB2312、GBK汉字字库偏移地址的计算

GB2312收录简化汉字及符号、字母、日文假名等共7445 个图形字符,其中汉字占6763 个。GB2312 规定“对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示”,习惯上称第一个字节为“高字节”,即所谓的区码。第二个字节为“低字节”,即所谓的位码。GB2312―80包含了大部分常用的一、二级汉字,和9区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1~0xfe,低位也是0xa1~0xfe;汉字从0xb0a1开始,结束于0xf7fe。GB2312将代码表分为94个区,对应第一字节(0xa1~0xfe);每个区94 个位(0xa1~0xfe),对应第二字节。两个字节的值分别为区号值和位号值加32(20H),因此也称为区位码。01~09区为符号、数字区,16~87区为汉字区(0xb0~0xf7),10~15区、88~94区是有待进一步标准化的空白区。GB2312将收录的汉字分成两级:第一级是常用汉字计3755个,置于16~55区,按汉语拼音字母/笔形顺序排列:第二级汉字是次常用汉字计3008 个,置于56~87 区,按部首/笔画顺序排列。故而GB2312 最多能表示6763 个汉字。

而GBK内码完全兼容GB2312,同时支持繁体字,总汉字数有2万多个,编码格式如下,每个GBK 码由2 个字节组成,第一个字节为0X81~0XFE,第二个字节分为两部分,一是0X40~0X7E,二是0X80~0XFE。其中与GB2312相同的区域,字完全相同。把第一个字节代表的意义称为区,那么GBK里面总共有126个区(0XFE~0X81+1),每个区内有190 个汉字(0XFE~0X80+0X7E~0X40+2),总共就有126x190=23940 个汉字。点阵库只要按照这个编码规则从0X8140开始,逐一建立,每个区的点阵大小为每个汉字所用的字节数乘以190。这样,就可以得到在这个字库里面定位汉字的方法:

当GBKL<0X7F 时:Hp=((GBKH-0x81)×190+GBKL-0X40)×(sizex2);

当GBKL>0X80 时:Hp=((GBKH-0x81)×190+GBKL-0X41)×(sizex2);

其中GBKH、GBKLL 分别代表GBK 的第一个字节和第二个字节(也就是高位和低位),size 代表汉字字体的大小(比如16 字体,12 字体等),Hp 则为对应汉字点阵数据在字库里面的起始地址。

对于GBK 字库和GB2312 字库,他们的解码部分部分略有不同,这个区别主要是由于他们的编码方式不同引起的,对于GBK 字库,解码的方式如下:

qh=*code;

ql=*(++code);

if(ql<0x7f)

    ql -= 0x40;

else

    ql -= 0x41;

qh -= 0x81;

foffset = ((unsigned long)190*qh + ql)*(size * 2);

对于GB2312 字库,解码的方式如下:

qh=*code;

ql=*(++code);

ql -= 0xa1;

qh -= 0xa1;

foffset = ((unsigned long)94*qh + ql)*(size * 2);

其中qh、ql 分别代表GBK 的第一个字节和第二个字节(也就是高位和低位),size代表汉字字体的大小(比如16字体,12字体等),foffset 则为对应汉字点阵数据在字库里面的起始地址。

自己取模若干汉字的偏移地址计算

1:定义汉字字模数据结构

2:利用取模软件(如PCtoLCD2002)获取汉字点阵数据

3:编写程序获取汉字点阵输出到LCD显示汉字

Example:

1、16*16汉字字模的数据结构

// ------------16*16汉字字模的数据结构定义 -------------------//

struct typFNT_GB16                 // 汉字字模数据结构

{

    unsigned char Index[3];               // 汉字内码索引      

    char Msk[32];    // 16*16的汉字需要的点阵数据为16*16/8=32字节

};

2、16*16汉字点阵信息,注意格式

// 取模软件:PCtoLCD2002                                                        

// 汉字库: 取模方式列行式,阴码,点阵16,索引32,取模方向顺向,宽高16        

const struct typFNT_GB16 codeGB_16[] =          // 数据表

{

"时",

0x00,0x00,0x7C,0x44,0x47,0x44,0x7C,0x45,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x10,0xFE,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x10,0x50,0x20,/*"时",3*/

"间",

0x20,0x13,0x10,0x40,0x47,0x44,0x44,0x47,0x44,0x44,0x47,0x40,0x40,0x40,0x40,0x40,0x00,0xFC,0x04,0x04,0xE4,0x24,0x24,0xE4,0x24,0x24,0xE4,0x04,0x04,0x04,0x14,0x08,/*"间",4*/

"日",

0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x10,0x10,0x10,0x10,0x10,0x1F,0x10,0x00,0x00,0x00,0xF0,0x10,0x10,0x10,0x10,0xF0,0x10,0x10,0x10,0x10,0x10,0xF0,0x10,0x00,0x00,/*"日",5*/

"期",

0x22,0x22,0x7F,0x22,0x3E,0x22,0x3E,0x22,0x22,0xFF,0x00,0x24,0x22,0x43,0x81,0x00,0x00,0x7C,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x7C,0x44,0x84,0x84,0x14,0x08,0x00,/*"期",6*/

"星",

0x00,0x1F,0x10,0x1F,0x10,0x1F,0x01,0x11,0x1F,0x21,0x21,0x4F,0x01,0x01,0x7F,0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8,0x00,0x00,0xFC,0x00,0x00,0xF8,0x00,0x00,0xFE,0x00,/*"星",0*/

"一",

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"一",1*/

};

2、查找汉字在点阵字库中位置

for (k=0;k<200;k++)     //k表示汉字的个数。查找200个汉字

{

if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1]))

//找到汉字u8 c[2]表示汉字的两字节

{

for(i=0 ; i<32 ; i++)

{

m[i]=codeGB_16[k].Msk[i];//读取这个汉字的32字节点阵数据到//m[32]这个数组中,再根据这个数组中点阵信息显示汉字

      }    

}

}

转:https://blog.csdn.net/syn_dyf/article/details/78577301

https://blog.csdn.net/syn_dyf/article/details/78577301

猜你喜欢

转载自blog.csdn.net/timeless_2014/article/details/84569998