天天看點

漢字在字庫中的偏移位址計算、顯示方法

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,

"間",

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,

"日",

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,

"期",

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,

"星",

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,

"一",

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,

};

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]這個數組中,再根據這個數組中點陣資訊顯示漢字

      }    

}

}