关于字库中字模的偏移量算法

本文是写给这篇文章的博主的:

http://blog.csdn.net/king_bingge/article/details/8779494

 

CSDN博客回复限制1000个字,装不下这些东西;发私信又得互相关注才行,留言也有字数限制发不出去,加博主的QQ呢他又设置了验证问题,我实在猜不出他的名字,所以,还是直接在这儿发一篇吧。

不知道博主的公式现在看懂了没有,我假装他仍然没懂,来帮他解答一下吧。以下文字仅代表个人意见。
博主曾转过一篇文章叫《信息处理交换用汉字编码字符集 GB2312-80》相信这一篇文章他肯定已经看懂了。

汉字的输入法中有一款叫做区位码输入法,就是根据他转载的这篇文章中的分区分位的原理来的。

我小时候曾经整理过常用汉字的区位码,记得第一个汉字是“啊”,区位码是1601。当时印象特别深的就是,区位码是从01到94共94个区,每个区都是从01位开始到94位,共94个字符。我印象中前3个区是标点符号,中间还有一些比如①②③之类的特殊符号区。汉字是从16区开始的。这个我们就不去管它了。

先来具体说说区位码和汉字内码的关系。

汉字的内码分为2个字节,高字节对应区位码的区,低字节对应位,但是要注意的是并不是直接相等,而是,2个字节分别是区码和位码加上160。至于为什么要加160我就不知道了,可能是为了区分ASCII的127个字符吧,但我认为+128就可以区分了,可它还是加了160。这也正是为什么区位码只能有94个区的原因。160+94=254,一字节最大是255,但255是个特殊值(二进制中的全1和全0都是特殊值)不能用的。

这样的话,以“啊”为例,它的内码的算法,高字节=160+区码16=176,低字节=160+位码1=161,十六进制就是0xB0A1,十进制是176*256+161=45217,验证一下,打开记事本,按住ALT键不要松手,用数字键区(注意只能是大键盘右侧的小键盘即NumLock数字键区,笔记本上可能不行),输入45217,就会出现“啊”字。

另一个例子,我姓韩,“韩”的区位码是2611,它的内码,高字节=160+区码16=186,低字节=160+位码11=171,十六进制是0xBAAB,十进制就是 (26+160)*256+(11+160)=47787,打开记事本,ALT+47787,记事本上可以出现“韩”字。

好,接下来说说字模。既然是16x16的字库,可以想到的是,每个汉字占用的是16行*16列=16行*8列*2,即16*2字节。

偏移量计算就简单了,顺着说的话就是,第n个文字的偏移是offset=(n-1)*16*2。

我们假设字库是从第1区第1位开始的,每个区94个文字,那么第j区第k位的文字,它就相当于第(j-1)*94+k个文字,套用到上面的式子,n=(j-1)*94+k,它的字模偏移量是offset=((j-1)*94+k-1)*16*2。

但是上面说了,第一个汉字“啊”它在16区,而不是在1区。1~15区没有汉字,所以呢,有的字库文件为了节省空间就把前15个区的字模去掉了(这实在不应该,因为这样就把全角的标点符号给去掉了,全角标点无法显示),这样的话,第j区(j≥16)第k位的文字,就相当于字库中的第 (j-16)*94+k 个文字了,它的字模偏移量就是 offset=((j-16)*94+k-1)*16*2。

结合内码和区位码的关系,高字节hi低字节low的汉字,对应的内码是:

j=hi-160

k=low-160

字模偏移量就是


1区开始的字库:offset=((j-1)*94+k-1)*16*2=((hi-160-1)*94+low-160-1)*16*2=((hi-0xa1)*94+low-0xa1)*16*2

16区开始的字库:offset=((j-16)*94+k-1)*16*2=((hi-160-16)*94+low-160-1)*16*2=((hi-0xb0)*94+low-0xa1)*16*2

举例子,“啊”

在1区开始的字库中,偏移为((176-0xa1)*94+161-0xa1)*16*2=45120=0xb040

在16区开始的字库中,偏移为((176-0xb0)*94+161-0xa1)*16*2=0

“韩”

在1区开始的字库中,偏移为((186-0xa1)*94+171-0xa1)*16*2=75520=0x012700

在16区开始的字库中,偏移为((186-0xb0)*94+171-0xa1)*16*2=30400=0x76c0

 

看一下博主的2句代码:

    pos = ((High8bit-0xb0)*94+Low8bit-0xa1)*2*16;

这一句很明显是用的16区开始的字库;  

    //    pos = ((High8bit-0xa0)*94+Low8bit-0xa0)*2*16;

这句看上去是用的1区开始的字库,但是里面的高位应该是减去0xa1而不是0xa0,否则是取不到对应的字的,会取到后一个区同一个位的字。

 

就是这些了。我的QQ是34368900,希望能多交流交流,我刚入门STM32,有很多问题需要博主赐教。

你可能感兴趣的:(关于字库中字模的偏移量算法)