國標漢字字符集(gb2312-80)在漢字作業系統中以漢字型檔的形式提供,並對漢字型檔的結構做了統一規定。漢字型檔的結構如圖:
hzk16的gb2312-80支援的漢字有6763個,符號682個。字型檔有94個區,其中一級漢字有3755個,按聲序排列,二級漢字有3008個,按偏旁部首排列。每個區有94個位,每個位存乙個漢字。這樣每個漢字在漢字型檔中有確定的區號和位號。區號在前,位號在後,合成乙個4位十進位制數字,這就是區位碼。區位碼用兩個位元組存放(gb2312漢字是由兩個位元組編碼的,範圍為a1a1~fefe。a1-a9為符號區,b0到f7為漢字區),第乙個位元組表示區號,第二個位元組表示位號。只要知道了區位碼,就可以知道該字在字型檔中的位址。
16×16點陣庫中,每個點陣模用32個位元組來描述,其中的每個點使用乙個二進位制位。當需要顯示時,把某個漢字的16×16點陣資訊直接送到顯示器上,值為1的點在螢幕上顯示乙個亮點,值為0的點則不亮,這樣就可以顯示出相應的漢字。
在國標字型檔中,每個漢字還可以使用國標碼。國標碼與區位碼之間的換算關係:
國標碼的區號=區位碼的區號+32(或20h)
國標碼的位號=區位碼的位號+32(或20h)
或 區碼=區號-0xa0 (因為漢字編碼是從0xa0區開始的,所以檔案最前面就是從0xa0區開始,要算出相對區碼)
位碼=位號-0xa0
此外還有漢字內碼。漢字內碼是漢字資訊處理系統內部表示漢字的編碼,也稱機內碼。西文字元的機內碼多採用乙個位元組來表示的ascii碼,有的系統則採用ebcdic碼。一般只使用7位來表示128個字元,而把高位用作奇偶校驗(或者不用)。我國的國標gb2312-80規定,乙個漢字用兩個位元組表示,目前規定每個位元組也只用七位,其高位未作定義。為了保證系統的中西文相容,意味著系統的機內碼中必須保持ascii(ibm-pc採用該碼作為西文字元的機內碼)的使用,同時又要允許漢字機內碼的使用,並且使兩者之間沒有衝突。如果用gb2312-80中的國標碼作為機內碼,則在系統中同時存在ascii碼和國標碼時,將會產生二義性。例如,機內有兩個位元組的內容分別為30h和21h,它們既可以表示漢字「啊」的國標碼,又可以表示字元「0」和「!」的ascii碼。所以,原原本本地採用國標碼作為漢字機內碼是不行的,必須要加以適當的變換。
國標碼規定,組成兩位元組**的各位元組的最高位均為0,但在機程式碼頁示漢字時,應將每個位元組的最高位置1,以表示該編碼是漢字,這種編碼稱作為變形國標碼。這樣作既解決了西文機內碼與漢字機內碼的二義性,又保證漢字機內碼與國標碼之間有極簡單的對應關係。
國標碼兩位元組的最高位分別加1後,便得到機內碼。「計」字機內碼如圖:
這樣國標碼與機內碼存在一種簡單的對應關係:
機內碼區號=國標碼區號+128(或80h)
機內碼位號=國標碼位號+128(或80h)
因為知道了某漢字的內碼,即可確定出對應的區位碼,知道了區位碼,就可以找出該漢字字模在字型檔中的存放位址,從該位址中調出對應漢字的32個位元組的字模資訊,就可以顯示出16×16點陣組成的該漢字了。
從上文的分析可知,漢字內碼與區位碼存在固定的轉換關係,設某漢字內碼的十六進製制數表示為0xkkjj,則相應區位碼的區號qh和位號wh分別為:
qh=0xkk-0xa0;
wh=0xjj-oxa0;
若用十進位制數表示內碼為c1c2,則
qh=c1-160;
wh-c2-160;
即區位碼qw=100*(c1-160)+(c2-160);相反要是知道了區位碼qw,則也可以求得區號和位號:
qh=qw/100;
wh=qw-100*qh;
因而該漢字在漢字型檔中離起點的偏移位置(以位元組為單位),可有表示式offset=(94*(qh-1)+(wh-1))*32l(32l為長整形數)計算,其中假設int qh,wh,qw,long offset。
對於16×16點陣漢字,其字模大小為(16×16)/8=32個位元組,其輸出時的排列方式如圖:
1、ucdos中的字型檔cclib.dat存放16×16點陣字模:
offset=((qh-1)*94+(wh-1))*32l;
2、ccdos 2.13中的字型檔hzk16存放16×16點陣字模:
offset=((qh-16)*94+wh-1+15*94)*32l;
3、spdos 5.0的簡單字型檔cclib.dat存放16×16點陣字模:
offset=((qh-7)*94+wh-1)*32l;
4、ccdos 2.13中字型檔hzk24存放24×24點陣字模:
offset=((qh-16)*94+wh-1)*72;
下面以乙個小示例顯示漢字:
#include int main(void)
{ char chs[32];
file *fp;
int i,j;
unsigned long offset;
unsigned char hz="計";
unsigned char qh,wh;
qh=hz[0]-0xa0;//獲取區嗎
wh=hz[1]-0xa0;//獲取位碼
/*//int a=hz[0];
//int b=hz[1];
//printf("%x%x",a,b);
//hz[0] hz[1]分別為漢字的機內碼
//offset=((hz[0]-0xa1)*94+(hz[1]-0xa1))*32;//注意0xa1十進位制數為161
*/ offset=((qh-1)*94+(wh-1))*32;//根據內碼找出漢字在hzk16中的偏移位置
if ((fp=fopen("hzk16","r"))==null)
return 1;
fseek(fp,offset,seek_set);
fread(chs,32,1,fp);
for (i=0;i<32;i++)
{if (i%2==0)
printf("\n"); //每行兩位元組,16x16點陣
for (j=7;j>=0;j--)
{if (chs[i]&(0x01得到的效果:
漢字型檔HZK16的簡單介紹
hzk16 字型檔是符合gb2312標準的16 16點陣字型檔,hzk16的gb2312 80支援的漢字有6763個,符號682個。其中一級漢字有3755個,按聲序排列,二級漢字有3008個,按偏旁部首排列。我們在一些應用場合根本用不到這麼多漢字字模,所以在應用時就可以只提取部分字型作 為己用。hz...
hzk16理解和簡單使用
一般我們使用16x16的點陣宋體字庫,所謂16x16,是每乙個漢字在縱 橫各16點的區域內顯示的。不過後來又有了hzk12 hzk24,hzk32和hzk48字型檔及黑體 楷體和隸書字型檔。雖然漢字型檔種類繁多,但都是按照區位的順序排列的。前乙個位元組為該漢字的區號,後乙個位元組為該字的位號。每乙個...
hzk16的介紹以及簡單的使用方法
hzk16的介紹以及簡單的使用方法 hzk16 字型檔是符合gb2312標準的16 16點陣字型檔,hzk16的gb2312 80支援的漢字有6763個,符號682個。其中一級漢字有3755個,按聲序排列,二級漢字有3008個,按偏旁部首排列。我們在一些應用場合根本用不到這麼多漢字字模,所以在應用時...