日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字模的原理和获取(一)

發(fā)布時間:2023/12/9 编程问答 69 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字模的原理和获取(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、什么是字模

單片機應用經(jīng)常會用到液晶顯示模塊,是用點陣的方式顯示的,要顯示漢字或字符的時候會用到字模,字模就是字在點陣上顯示時對應的編碼,如圖1顯示的“正”字,使用16×16點陣。點陣中黃色的點是高亮的,對應于二進制編碼中的1,綠色的低亮對應于二進制編碼中的0。如第一行 二進制編碼應該是 00000000 00001000 剛好用兩個字節(jié)表示就是 0x0,0x08,這樣,16總共需要用32個字節(jié)來表示,這32個字節(jié)就是“正”的字模。在單片機程序中,將字模發(fā)送給液晶顯示模塊,就能夠顯示出響應的漢字或字符。

?

二、字模的獲取

 漢字的點陣字模是從點陣字庫文件中提取出來的。例如常用的16×16點陣HZK16文件,12×12點陣HZK12文件等等,這些文件包括了GB 2312字符集中的所有漢字。現(xiàn)在只要弄清漢字點陣在字庫文件中的格式,就可以按照自己的意愿去顯示漢字了。

  下面以HZK16文件為例,分析取得漢字點陣字模的方法。

   HZK16文件是按照GB 2312-80標準,也就是通常所說的國標碼或區(qū)位碼的標準排列的。國標碼分為 94 個區(qū)(Section),每個區(qū) 94 個位(Position),所以也稱為區(qū)位碼。其中0109 區(qū)為符號、數(shù)字區(qū),1687 區(qū)為漢字區(qū)。而 1015 區(qū)、8894 區(qū)是空白區(qū)域。

  如何取得漢字的區(qū)位碼呢?在計算機處理漢字和ASCII字符時,使每個ASCII字符占用1個字節(jié),而一個漢字占用兩個字節(jié),其值稱為漢字的內(nèi)碼。其中第一個字節(jié)的值為區(qū)號加上32(20H),第二個字節(jié)的值為位號加上32(20H)。為了與ASCII字符區(qū)別開,表示漢字的兩個字節(jié)的最高位都是1,也就是兩個字節(jié)的值都又加上了128(80H)。這樣,通過漢字的內(nèi)碼,就可以計算出漢字的區(qū)位碼。

  具體算式如下:

  qh=c1-32-128=c1-160 wh=c2-32-128=c2-160

  或   

  qh=c1-0xa0 wh=c2-0xa0

  qh,wh為漢字的區(qū)號和位號,c1,c2為漢字的第一字節(jié)和第二字節(jié)。

  根據(jù)區(qū)號和位號可以得到漢字字模在文件中的位置:

  location=(94*(qh1)+(wh1))*一個點陣字模的字節(jié)數(shù)。

  上面計算過,一個16×16點陣的漢字總共需要16*16/8=32個字節(jié)表示。字模的表示順序為:先從左到右,再從上到下,也就是先畫左上方的8個點,再是右上方的8個點,然后是第二行左邊8個點,右邊8個點,依此類推,畫滿16×16個點。??

對于其它點陣字庫文件,則也是使用類似的方法進行顯示。例如HZK12,但是HZK12文件的格式有些特別,如果你將它的字模當作12*12位計算的話,根本無法正常顯示漢字。因為字庫設計者為了使用的方便,字模每行的位數(shù)均補齊為8的整數(shù)倍,于是實際該字庫的位長度是16*12,每個字模大小為24字節(jié),雖然每行都多出了4位,但這4位都是0(不顯示),并不影響顯示效果。 還有UCDOS下的HZK24S(宋體)、HZK24K(楷體)或HZK24H(黑體)這些打印字庫文件,每個字模占用24*24/8=72字節(jié),不過這類大字模漢字庫為了打印的方便,將字模都放倒了,所以在顯示時要注意把橫縱方向顛倒過來就可以了。

字模獲取工具的制作

分析過字模的原理后,就可以來編寫工具,首先要準備字庫文件,HZK16.DAT,可以從網(wǎng)上下載。

根據(jù)原理,先打開文件,然后根據(jù)漢字的內(nèi)碼獲取區(qū)碼和位碼,然后根據(jù)區(qū)嗎和位碼索引到文件中的地址,再讀取32個字節(jié)數(shù)據(jù)到BUFFER中即大功告成。

下面是VC中的一段代碼,供參考:

void CFontDlg::GetGridFromHZK16() {UpdateData();BYTE AnsiCode[2];BYTE qh,wh;UINT location;// BYTE buffer[32];FILE* fp;AnsiCode[0]=m_strFont.GetAt(0);//將對話框中的字符轉換為內(nèi)碼,先讀取第一個字節(jié),判斷是漢字還是字母或字符if(AnsiCode[0]<160) //英文字母和字符,轉換為全角的字符內(nèi)碼{BYTE temp=AnsiCode[0];AnsiCode[0]=HIBYTE(temp-0x21+0xA3A1); //0xA3A1 是ASCII 碼為0X21的字符對應的全角字符的內(nèi)碼,這是一個偏移量的計算AnsiCode[1]=LOBYTE(temp-0x21+0xA3A1);}else //是漢字,則直接轉換{AnsiCode[1]=m_strFont.GetAt(1);}qh=AnsiCode[0]-160; //區(qū)碼和位碼wh=AnsiCode[1]-160;location=(94*(qh-1)+(wh-1))*32; //HZK16 中的索引 32是一個字的字模字節(jié)數(shù)fp=fopen("HZK16.dat","r");if(fp==NULL){MessageBox("文件打開錯誤");return;}else{//fseek(fp,location,SEEK_SET); //fread(buffer,1,32,fp); fseek(fp,location,SEEK_SET); //定位到指定地方,然后讀取fread(buffer,1,16,fp); fseek(fp,location+16,SEEK_SET); fread(buffer+16,1,16,fp); //讀兩次,不知為什么讀一次時有些字會出錯,比如"家"fclose(fp);}FontCodeToGridBuffer();SetDlgItemText(IDC_EDIT_FONTCODE,"");}

?

上面獲取的漢字,默認是宋體的,假如對字體有要求,就要選用相應字體的字庫。當然,大多數(shù)時候在液晶上顯示是不會在乎字體的,可能看習慣了,感覺宋體最適合點陣顯示了。

?

總結

以上是生活随笔為你收集整理的字模的原理和获取(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。