關於字庫中字模的偏移量算法

本文是寫給這篇文章的博主的:

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,有很多問題需要博主賜教。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章