天天看點

Foxdisk11-小字庫顯示漢字2

(請保留 -> 作者:羅冰 )

剛從大學畢業那會,對作業系統極其入迷,總想搞清楚底層是怎麼運作的。其中最感興趣的是圖形的顯示,BIOS對硬體的控制等。找了很多資料看,正好公司的一些項目上也需要用到,就這麼磕磕碰碰地實作了各種顯示的代碼。

Foxdisk的代碼中,Vesa.c和Vesa.h就包含了顯示的所有資訊。主要是遵循了vesa的标準進行顯示,采用C嵌彙編的方式來編寫。目前,幾乎所有的機器都支援VESA标準,而在X86平台下程式設計就是基于此标準的。VESA标準在原有BIOS提供的API的基礎上,提供了一組擴充BIOS功能調用。對于标準VGA下的模式,仍然可以使用基本BIOS調用,但對于擴充模式,其許多操作如模式設定及視訊緩沖讀寫等,則隻能通過VESA标準提供的擴充BIOS來實作。

在VESA标準下,視訊緩沖是以分頁映射的方式進行操作。其基視窗一般為在0xA0000處,每頁為64K。整個視訊緩沖都通過映射到此視窗而得以直接存取。一般的圖形程式設計步驟如下:

  • 設定顯示模式(如0x103為 800×600 256色的配置)
  • 設定顔色寄存器
  • 按照圖形顯示的原理編寫畫點、畫線、畫圓等基本函數。

過多的細節不用糾結,Vesa.c中提供了畫點函數putpixel256()。把螢幕當做一個大畫布,設定模式的時候知道這塊畫布多大,用畫點函數繪制即可。Foxdisk使用的是模式0x105,也即1024×768,256色。想像一下,有張寬1024像素點,長768像素點的畫布,有支可在畫布任何坐标處畫點的筆,應該是什麼畫都可以畫出來了,包括漢字。

Foxdisk中顯示漢字,大緻可以分為兩步:

  1. 提取需要的漢字字模,儲存到程式内部;
  2. 調用Font.c中顯示漢字的函數,将需要的漢字顯示在螢幕上。

Vesa.c和Font.c中屏蔽了很多顯示的細節,特别是對各種字型及字型大小的處理。在設計之初,考慮去相容各種不同的字型,比如黑體、楷體、宋體等等。代碼中針對不同的字型,提供了各種編譯用的開關。實際程式中,主要用了16×16宋體和24×24楷體,從提取漢字庫的批處理指令可以看出來。

在部落格“Foxdisk09-工具篇”中,已經初略的介紹了提取漢字庫的工具了。我是為了能自動針對所有用到漢字的代碼,自動提取漢字字模,開發的這些小工具。下面具體介紹下如何提取字庫。

所謂無字庫技術,就是在程式中建立一個類似字庫的字庫數組來代替字庫。程式中建立的字庫某種意義上獨立于程式中顯示程式。也就是存在這樣的可能:單獨對字庫數組進行壓縮,在使用的時候重新解壓。這個特性在嵌入式的應用中非常有用,可以節約不少的程式空間。

一般說來,提取漢字字庫的步驟應該是這樣的:

1) 對包含需要提取漢字的源檔案進行文法分析,析取出需要提取字模的漢字

2) 對提取出的漢字再次分析,并去除重複的漢字打開相應的漢字庫,提取需要的字模,并按規則形成新的字庫數組

3) 對照上一篇部落格的說明,設計16×16及24×24的漢字字模結構體。

struct       hzk16_typ{         

  unsigned int code;

  unsigned int array[16];

};

struct       hzk24_typ{         

  unsigned int code;

  unsigned char array[3*24];

};

最終會将字模以上述資料結構的方式存儲,Foxdisk中存儲生成的檔案為HZTABLE.H和HZK24.H。

具體的提取代碼可以參照ehz24.c和etrhz.c,這兩個檔案的代碼量都在400行左右。核心工作在于分析指定的檔案,從中提取出需要轉換字模的漢字。

為了便于分析,也為了程式編寫簡單,對指定的檔案是有要求的。必須保證在提取的檔案中字元串中沒有//和/* 字元,否則可能會提取錯誤。提取程式并沒有去進行字元串内部的語義分析,否則要處理的情況太多了。 代碼就不貼出來了,放不下。對照程式設計的想法,以及代碼,還是比較容易看明白運作的機制的。

繼續閱讀