做了無數的windows程式,從來沒有把顯示漢字和英文本母當成一回事兒。這也難怪,寫視窗程式的時候,什麼setwindowtext、messagebox、setdlgitemtext等等,你只需要把自己想要顯示的字串傳進去,然後編譯、鏈結,就能夠顯示出來了,非常非常簡單;若說麻煩,可能就是在ascii碼和unicode碼之間轉換比較麻煩,但是習慣之後,似乎又沒什麼了。可是,如果沒有作業系統的支援呢?例如,在乙個純dos的環境下,該如何顯示中文?或者是日文、韓文?甚至是英文ascii碼?這就是我想在這裡討論的問題,這裡需要一種叫「字模」的技術。
最近在做arm平台上的簡單gui系統,用於我們自己開發的嵌入式作業系統potato os。作為乙個gui系統,顯示文字應該是最基本的乙個功能。顯示文字,一般有兩種選擇:一是用字模進行打點處理;二是用向量字型進行計算後再打點顯示。字模的原理是,通過乙個位是1表示該點有顏色,0表示沒有來形成乙個字模矩陣,該矩陣作為乙個整體則形成乙個漢字。事實上,乙個字模漢字實際上就是一副影象,只不過這幅影象是單色的。它的優點是處理簡單,顯示速度快,可免費獲得16*16點陣的字型檔(再大些的字型檔要收費,我用的是一款叫「字模生成器」的軟體);缺點是不能夠被放大,一旦被放大,就能看到乙個乙個的字模畫素,很難看,當然,縮小是可以的,但是比較麻煩。適量字型檔則用一系列數學公式來表示乙個漢字,它告訴繪圖程式怎樣繪製乙個漢字,因此它能夠在漢字被放大和縮小的過程中保持漢字的清晰;缺點則是每個漢字是計算出來的,因此消耗的系統資源要比字模多得多。由於我們的系統需要進行的是簡單的文字顯示,所以我選擇了實現起來也比較簡單的字模方法來處理文字顯示。
首先,要用「字模生成器」生成字模檔案,例如16*16矩陣字模檔案。上面提到了,這字模就是用1或者0表示打點資訊,16*16則表示用16*16的畫素矩陣來顯示乙個漢字,所以,16*16/8=32,每個字模需要32個位元組來儲存打點資訊。在arm平台上,我習慣於用乙個無符號的字元資料來儲存所有的資料,例如、二進位制檔案等,因此還需要把生成的字模檔案轉換成無符號的字元陣列。為此,我還特意用mfc寫了乙個程式來處理這個工作。這個處理軟體其實還可以處理其他的資源。需要的可以和我聯絡,我提供全部源**。
漢字的內碼
點頭表示什麼?是「對」、「yes」,偏偏有的地方表示的意義卻恰恰相反。乙個動作,有不同的詮釋;乙個問題,有不同的答案;而乙個符號,卻有不同的意義,關鍵在於:你是如何地理解。在電腦中亦如此,所有的資料都是以0和1儲存的,按不同的資料操作,可以得到不同的結果。對於顯示英文操作,由於英文本母種類很少,只需要8位(一位元組)即可。而對於中文,常用卻有5000以上,於是我們的dos前輩想了乙個辦法,就是將ascii表的高128個很少用到的數值以兩個為一組來表示漢字,即漢字的內碼。而剩下的低128位則留給英文本元使用,即英文的內碼。不信,你可以用記事本寫一c檔案:
main()
printf("\nchinease char=");
s=c;
while(*s!=0)
getch();
}再用tc輸入*.txt開啟執行,看見了沒有,那些數值即英文和漢字的各位元組內碼。
得到了漢字的內碼後,還僅是一組數字,那又如何在螢幕上去顯示呢?這就涉及到文字的字模,字模雖然也是一組數字,但它的意義卻與數字的意義有了根本的變化,它是用數字的各位資訊來記載英文或漢字的形狀,如英文的'a'在字模中是這樣記載的:
而中文的「你」在字模中卻是這樣記載的:
在硬體系統內,英文的字模資訊一般固化在rom裡,即使在沒有進入系統的cmos裡,也可以讓你看到英文本元。而在dos下,中文的字模資訊一般記錄在漢字型檔檔案hzk16裡。
下面講講漢字型檔檔案。
了解字母和漢字是按字模位資訊顯示的原理後,那如何得到漢字的字模資訊呢?難道要我們自己去做?no。dos前輩們經過艱辛的努力,將製作好的字模放到了乙個個標準的庫中以免去後輩的麻煩,這就是點陣字型檔檔案。一般我們使用16*16的點陣宋體字庫,所謂16*16,是每乙個漢字在縱、橫各16點的區域內顯示的。不過後來又有了hzk12、hzk24,hzk32和hzk48字型檔及黑體、楷體和隸書字型檔。雖然漢字型檔種類繁多,但都是按照區位的順序排列的。前乙個位元組為該漢字的區號,後乙個位元組為該字的位號。每乙個區記錄94個漢字,位號則為該字在該區中的位置。因此,漢字在漢字型檔中的具體位置計算公式為:94*(區號-1)+位號-1。減1是因為陣列是以0為開始而區號位號是以1為開始的。這僅為以漢字為單位該漢字在漢字型檔中的位置,那麼,如何得到以位元組為單位得到該漢字在漢字型檔中的位置呢?只需乘上乙個漢字字模占用的位元組數即可,即:(94*(區號-1)+位號-1)*乙個漢字字模占用位元組數,而按每種漢字型檔的漢字大小不同又會得到不同的結果。以16*16點陣字型檔為例,計算公式則為:(94*(區號-1)+(位號-1))*32。漢字型檔文該從該位置起的32位元組資訊即記錄了該字的字模資訊。
了解點陣漢字及漢字型檔的構成原理後,顯示漢字就變得簡單。以16*16點陣字型檔為例,通常的方法是:將檔案工作指標移到需要的漢字字模處、將漢字型檔檔案讀入一2*16陣列再用for迴圈一位位地顯示。以使用vgahi模式顯示「我」字為例,程式如下:
#include "graphics.h"
#include "stdio.h"
main()
怎麼樣?只要掌握了正確的方法,顯示漢字並不複雜。
(原文出處:在此向作者表示衷心感謝!)
那麼,明白了漢字怎麼顯示之後,那英文本模怎麼顯示呢?其實,顯示的道理是一樣的。在16*16字模檔案中,英文ascii碼也是用16*16的畫素點陣來繪製,當然,英文ascii的字模,需要你另外生成。知道乙個英文本母後,如何在字模檔案中定位那32個位元組資料?不像漢字那樣分割槽碼和位碼,只需要用該英文本母的ascii碼值乘上32即可得出字模檔案的位置,即:
fseek(ascii碼字模檔案,i*32,seek_set);//i為該字模的ascii碼值
怎麼樣?是不是更簡單?
還有乙個問題:如何區分漢字和英文ascii碼?其實很簡單,英文ascii碼(不包括ibm255擴充套件ascii碼),最高位是0,而漢字最高位是1。也就是說,如果你讀取到乙個字元(8位),最高位是0,那麼該字元一定表示ascii字元,因此,他的下乙個字元應該表示另外乙個和該字元無關的字元資訊;相反,如果最高位是1,則表示該字元和該字元接下去的那個字元一起,表示乙個漢字(還記得嗎?乙個漢字是兩個位元組),因此,要將這兩個字元一起進行處理。
下面,我將我在arm平台上實現漢字、ascii英文本模混合輸出的函式源**貼出來,需要的可以隨意借鑑。
void g_drawtext(unsigned x, unsigned y,
char text, unsigned length,
unsigned color)
} index++;
temp+=2;
}else
}temp++;
}for(j=0;j<16;j++)
for(i=0;i<2;i++)
for(k=0;k<8;k++)
if(mat[j][i]&(0x80>>k))
g_pixel(i*8+k+x+8*space,y+j,color);
space=temp;
}}
ARM平台LCD顯示漢字
arm平台lcd顯示漢字 2008 06 13 18 54 33 做了無數的windows程式,從來沒有把顯示漢字和英文本母當成一回事兒。這也難怪,寫視窗程式的時候,什麼setwindowtext messagebox setdlgitemtext等等,你只需要把自己想要顯示的字串傳進去,然後編譯 ...
arm的lcd基礎顯示
進行逐行掃瞄rgb的數值,顯現出來。需要通過image2lcd工具,轉為字元陣列那樣的格式。它每3個值為rgb顏色值,然後放入include資料夾,然後匯入即可。board fimd lcd.c include stdio.h include s5pv210.h include img1.h uns...
ARM學習筆記 LCD顯示
lcd概述 lcd liquid crystal display 即液晶顯示器,是一種採用了液晶控制透光度技術來實現色彩的顯示器。lcd有多種型別,比如stn tft ltps tft oled等。cpu或顯示卡發出的影象資料是ttl訊號,lcd本身接收的也是ttl訊號。由於ttl訊號在高速率的長距...