linux点阵ascii像素字体,点阵字体显示系列之一:ASCII码字库的显示 | 迟思堂工作室...
起因:
早在閱讀tslib源代碼時(shí)就注意到里面有font_8x8.c和font_8x16.c兩個(gè)文件(后來(lái)才得知,它們來(lái)自Linux內(nèi)核,具體目錄是./drivers/video/console),它們包含了在屏幕上顯示所需的所有字符(當(dāng)然,是可打印字符),由此也看了一下tslib顯示字符的代碼。對(duì)將來(lái)在觸摸屏上顯示漢字有所幫助,——這是后話,暫且按下不提。
上面所說(shuō)的字符當(dāng)然是ASCII碼了,這種編碼學(xué)過(guò)計(jì)算機(jī)的人可能會(huì)很熟悉,就不多講了。本文所述者,就是通過(guò)ASCII碼字庫(kù)文件(網(wǎng)上有下載)和上面提到的其中之一的文件在終端上顯示ASCII字符。這也為研究漢字顯示打下基礎(chǔ)(此為假話,寫文章及做作所需也,實(shí)際上本文作者是先研究漢字顯示再研究ASCII碼顯示的,勿模仿,切切)。
本文中使用的字庫(kù)是8×16,每個(gè)字符占用內(nèi)存空間為16字節(jié)(后面不再提及),文中顯示字符所做工作有下面幾步(顯示漢字也差不多,當(dāng)然,這又是后話 ):
1、打開(kāi)字庫(kù)文件(似乎是廢話);
2、計(jì)算出要打印的字符在字庫(kù)文件中的偏移量(亦即網(wǎng)上所說(shuō)的“尋址”);
3、將這個(gè)偏移地址的數(shù)據(jù)(16字節(jié))讀取緩沖區(qū)中;
4、顯示這個(gè)緩沖區(qū),為1者打印,為0者留空。(由于是在終端上顯示,因此,可以使用如“#”、“*”等字符代替。)
先說(shuō)說(shuō)如何找到某個(gè)字符在字庫(kù)文件中的偏移量。字庫(kù)里的字符排序是符合ASCII碼順序的,而每個(gè)字符占16字節(jié),因此,將要打印的字符與16相乘,便得到這個(gè)字符在字庫(kù)中的位置了,這個(gè)位置之后的16個(gè)字節(jié)的數(shù)據(jù),就是這個(gè)字符了。比如大寫字母“A”,十六進(jìn)制是0x41(“A”還是十進(jìn)制的65、八進(jìn)制的101,其實(shí)都是一回事),它與0x10(十進(jìn)制的16)相乘,得到0x410(計(jì)算機(jī)中使用十六進(jìn)制十分方便,對(duì)于某些試題要求計(jì)算出某地址的十進(jìn)制,我表示不理解,既不直觀,又不方便,還容易出錯(cuò))。使用十六進(jìn)制編輯器(用UE相信會(huì)更方便些)查看這個(gè)偏移量,會(huì)發(fā)現(xiàn)有如下數(shù)據(jù):
$ hexdump -C ../HZK/ASC16 | grep 41000000410? 00 00 10 38 6c c6 c6 fe? c6 c6 c6 c6 00 00 00 00? |…8l………..|
所謂的字庫(kù),里面就是一些二進(jìn)制數(shù)據(jù)。我們看看上面得到“A”的16個(gè)字節(jié)數(shù)據(jù)顯示效果是怎樣的。將上面的十六進(jìn)制數(shù)據(jù)按二進(jìn)制輸出,一個(gè)字節(jié)一行,共占16行,如下:
0000000000000000
00010000
00111000
01101100
11000110
11000110
11111110
11000110
11000110
11000110
11000110
00000000
00000000
00000000
00000000
不直觀,將出現(xiàn)0的地方留空,則變成如下形狀(受網(wǎng)頁(yè)影響,為美觀起見(jiàn)進(jìn)行調(diào)整,雖非實(shí)際中二進(jìn)制所示,但形狀是一致的):
1
111
11? 11
11????? 11
11????? 11
1111111
11????? 11
11????? 11
11????? 11
11????? 11
上面的便是傳說(shuō)中的“A”了。
下面就用代碼讀取字庫(kù)信息,并顯示出來(lái)。完整代碼如下:
/***************************************************源代碼文件編碼:ANSI
測(cè)試環(huán)境編碼:zh_CN.UTF-8、zh_CN.gd2312
* ************************************************/
#include#include
#include
#include
#include
#include
#include
#include
#ifdef?DEBUG
#define?debug(fmt,?…)?printf(fmt,?#__VA_ARGS__)
#else
#define?debug(fmt,?…)
#endif
void?display_font_ascii(char?*asc)
{
int?i,?j;
debug(“=================n”);
for(i=0;i<16;i++)
{
for(j=0;j<8;j++)
{
/*?逐位相與,為1者打印“*”,否則打印空格?*/
if(asc[i]?&?(0x80>>j))
printf(“*”);
else
printf(” “);
}
printf(“n”);
}
debug(“=================n”);
}
int?main()
{
int?i;
unsigned?char?*p;
unsigned?char?asciicode[]?=?“Ab”;
unsigned?long?offset;
FILE?*asc;
char?ascii[16];
if((asc=fopen(“ASC16″,“rb”))==NULL)
{
perror(“Can’t Open ASC16″);
exit(0);
}
/*?ASCII字庫(kù)文件?*/
for?(i?=?0;?i?
{
debug(“%c %xn”,?asciicode[i],?asciicode[i]); /*?打印數(shù)值?*/
offset?=?asciicode[i]*16;
debug(“offset: %xn”,?offset); /*?打印偏移量?*/
fseek(asc,offset,SEEK_SET);
fread(ascii,16,1,asc);????????????? /*?讀取16字節(jié)?*/
display_font_ascii(ascii);??????? /*?顯示?*/
}
fclose(asc);
return?0;
}
由于是示意性代碼,不必糾結(jié)于代碼優(yōu)化、代碼風(fēng)格等等問(wèn)題。效果(同樣進(jìn)行了調(diào)整)如下:
$ ./a.out*
***
**? **
**????? **
**????? **
*******
**????? **
**????? **
**????? **
**????? **
***
**
**
****
**? **
**??? **
**??? **
**??? **
**??? **
*****
還有另一種方法,不讀取字庫(kù),而是將所有的字符存放于某個(gè)數(shù)組中,比如像font_8x16.c文件中的fontdata_8x16數(shù)組。這里假設(shè)數(shù)組為ascii_code,那么,上面的代碼只需修改一小部分,如下:
for (i = 0; i < sizeof(asciicode)-1; i++){
debug(“%c %xn”, asciicode[i], asciicode[i]);
offset = asciicode[i]* 16; // 尋址
p = ascii_code+offset;????// 查找字符在ascii_code數(shù)組中的偏移量
debug(“offset: %xn”, offset);
display_font_ascii(p);
}
效果是一樣的,所不同的是,前一種方法需要讀取字庫(kù)文件,后一種方法直接在內(nèi)存中讀取,完整的ASCII碼占用空間為4KB。不過(guò),ASCII中可打印的字符共96個(gè)(經(jīng)過(guò)認(rèn)真數(shù)那些可打印的字符,發(fā)現(xiàn)實(shí)際上是95個(gè)(即32號(hào)到126號(hào)),這里將127號(hào)算上了,具體的請(qǐng)搜索一下ASCII),占用空間為96*16,即1536字節(jié)。由于前面0x20(即32)個(gè)字符在顯示中沒(méi)有用到,因此是可以去掉的,這樣一來(lái),尋址方式又稍有不同,如下:
for (i = 0; i < sizeof(asciicode)-1; i++){
debug(“%c %xn”, asciicode[i], asciicode[i]);
offset = (asciicode[i] – 0x20 )* 16; // 尋址
p = ascii_code+offset;????// 查找字符在ascii_code數(shù)組中的偏移量
debug(“offset: %xn”, offset);
display_font_ascii(p);
}
由于文中涉及知識(shí)、代碼、字庫(kù)文件都可以在網(wǎng)絡(luò)上找到,因此文中就不提供下載了。
資料:
1、ASCII碼字庫(kù),有多種形式,如8*16、8*12,名稱為ASC12、ASC16,搜索一下就能找到。
2、“字庫(kù)數(shù)組”,可以在Linux內(nèi)核源代碼的./drivers/video/console目錄下找到很多相關(guān)代碼文件,如font_8x8.c、font_8x16.c、font_sun8x16.c等等。像font_8x16.c文件,代碼中說(shuō)是由cpi2fnt這個(gè)東西產(chǎn)生的,但搜索一下,沒(méi)什么介紹,英文的又不想去看,對(duì)這個(gè)東西也就不了解了。
3、可以搜索一下字庫(kù)生成工具,用這些工具可以生成需要的字庫(kù)。
總結(jié)
以上是生活随笔為你收集整理的linux点阵ascii像素字体,点阵字体显示系列之一:ASCII码字库的显示 | 迟思堂工作室...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux ndk编译静态库,Andro
- 下一篇: linux vim(gvim) 多标签页