王鳳
摘 要:快速發展的社會經濟與日益發達的科技水平,使得社會中的多個層面開始普遍運用嵌入式系統,且人們也將關注的重點放在了嵌入式系統中的高質量漢字字庫上。文章首先對FreeType字體引擎TrueType矢量字體的概念分別進行了闡述;其次,介紹了裁剪與優化的方法,以供參考。
關鍵詞:FreeType;矢量字體;嵌入式
與TrueType矢量字庫相比,由于嵌入式系統以陣點為主的字庫不能對字體隨意進行縮大和縮小,不能滿足分辨率較高的屏幕的要求,由于分辨率較高的屏幕顯示的數據量較大,所以顯示的速度非常慢。但是,如果在嵌入式系統中使用矢量字體就能夠將效果很好地呈現出來。在嵌入式系統中,為了達到渲染TrueType矢量字庫的目的,通常都會用到FreeType字體引擎,對于FreeType字體引擎只有很少的一部分嵌入式系統能夠直接支持,由于受應算能力和儲存空間的限制,有很大一部門嵌入式系統都不能直接使用FreeType字體引擎,甚至有些還需要在移植過程中進行剪裁和優化。
1 FreeType字體引擎TrueType矢量字體
1.1 FreeType字體引擎
作為一個字體引擎,FreeType的優勢眾多,其不僅質量較高,且不收取任何費用,也可進行移植,其能夠對包括TrueType、OpenType,WindowsFON/FNT,Type1,CFF,X11PCF和CID等在內的多種字體格式文件進行訪問,且用到的接口也是統一的。在單色位圖、反走樣位圖等渲染上FreeType給予了大力支持。作為一個高度模塊化的程序庫,FreeType庫的開發雖然受益于ANSIC,但在思想上卻是面向對象的,所以,用戶可以對它進行靈活的裁減。
1.2 TrueType矢量字體
作為一種新型的數字化矢量字體格式,TrueType字體格式由兩家公司聯合提出,即Microsoft公司與美國Apple公司[1]。幾何學中的B樣條曲線與直線通常用于描述字體的外形輪廓。正切連續性和一階連續性是二次B樣條曲線的特點,而精確表示出拋物線則是二次B樣條曲線的優勢所在。
大多數情況下,諸如TrueType字體描述信息、各種標記表格和指令集等均可在MAC與PC平臺中得到有效應用,而這些都是描述TrueType字體的文件。“Sfnt”資源是這些文件存放于MAC平臺的一種主要存放形式,而在Windows平臺中,其存放形式便發生了變化,即為TTF形式。一般,高位在前,低位在后的Motorola式數據結構用得最多,而這樣做的目的也是為了避免TrueType的跨平臺兼容性受到影響。GDI圖形設備接口中已經包含了Windows的TrueType解釋器,因此TrueType字體輸出能在所有的Windows支持的輸出設備上使用。
2 裁剪與優化
因為FreeType庫中的API均為封裝好的組件,所以若要看到其中的具體細節,就必須進入到源碼中。利用分析源碼,對刪減了一些沒有用的步驟和定義,對一些算法進行了適當的裁減和改進。
首先,在初始化FreeType庫的時候,要將一些復雜的對象刪除掉,如FT_Library和FT_Face等,因為FreeType了面對對象的思想編程,里面包含了多個字體驅動的抽象接口,并使用抽象類來對所有的字體驅動初始化過程進行統一。而在這里不需要對字體驅動進行判斷,只需要用到格式TrueType矢量字體。
在對TrueType字體進行初始化的過程中,首先要在各個表項中將TrueType字體載入進來,針對Library對象、face對象的創建與初始化以及判斷字體平臺驅動進行相應的簡化,使之以TrueType中各個重要表項載入的形式呈現出來,以同初始化字體的相關參數予以對應。相對簡單一點的是字體大小的設置部分,這一部分主要是按照制定的大小,將包括額定的高度、寬度、EM正方形的像素寬度、高度等在內的縮放的規模以及縮放后字體的規格參數確定下來,且這一部分也不會用到其他結構體,如face對象等。
FreeType中涉及的字體與字符輪廓種類較多,這里主要對TrueType字符輪廓的載入方法進行介紹。首先取得字符索引方法是運用了函數FT_Get_Char_Index,二分查找和有線性查找是查找的主要方法。有序數據中使用的是二分法查找字符索引,獲取glyf表中的圖元信息一般都是利用local表中偏移量和字符索引。在載入圖元信息時,圖元頭應該第一個載入,簡單圖元排在第二,最后再對圖元信息進行處理。如果點陣信息為最后輪換的圖元數據,則可將smooth渲染器作用利用起來。這一渲染器優勢較多,其既可生成256色位圖信息,也可呈現出漸變的字體邊緣。在渲染過程中,平移操作應先于其他步驟進行,使之與目標窗口的位置相差無幾,之后再對ControlBox的值進行計算,同時分解輪廓,填充光柵化。
2.1 讀取字庫
針對不相關的字體,將其driver初始化去除掉,改用另一種字體的driver初始化,即TrueType字體[2]。第一,將字庫文件打開,對初始化的信息進行讀取。在包含支撐字體輪廓的數據上,TrueType矢量字體一般都是采取的多個表的形式,所以字體引擎在字體渲染上,必須要將各個表的信息利用起來,之后再對表目錄進行讀取。每個表中均包含有一個tableentry結構項,而資源標記、校驗和、偏移量以及每個表的大小均被其囊括其中。因為TrueType中的每個表其保存的邏輯信息各不相同,其中就包括字符調整信息、字符到圖元的映射以及圖元中數據等,所以,一些表是不可或缺的,當然也要做出合理選擇,之后再讀取如maxp,hhea,head,cmap,hmtx,vhea,loca,vmtx等一系列得常用表信息。
2.2 設置字體大小
該部分主要是為了函數FT_Set_Pixel_Sizes的實現部分進行優化。原函數實現部分主要是在FT_Request_Size的幾個函數,通常字體縮放的各個參數均來源于事先設定好的字體高度與寬度,諸如除法函數FT_MulFix、FT_DivFix和取整函數FT_PIX_CEIL等這些數學中的知識用得比較多。
2.3 取得字符輪廓信息
第一步,獲得字符的字形索引,二分法查找cmap表中字形索引是函FT_Get_Char_Index()中主要使用的方法,之后再結合偏移查找與字形索引找出字符所對應的圖元信息。glyf表在TrueType字體中居于核心位置,其也就是我們所謂的圖元數據。若無意外其最大表的地位不會被撼動。位置索引表是單獨存在的,并不存在依附情況,但圖元的序列卻全部在圖元數據表中;圖云頭結構是每個圖元的開始,當前圖元的輪廓線額數目保存于簡單圖元中,而一般要通過計算組成該合成圖元的所有圖元數據,方可將合成圖元的總共輪廓數得出來。針對簡單圖元,其圖元描述應在圖元頭結構之后進行。而要組成圖元描述則需要依靠所有輪廓線結束點的索引、圖元指令以及一系列的控制。每一個控制點均包括兩個坐標的標志,即x坐標與y坐標。控制所用到的信息與GDI函數、PolyDraw函數所要用的信息相比,兩者的概念并未有何不同,都代表的是坐標,而前者是一組標志,后者則是一組點。圖元中并未對輪廓線做強制要求,可以是一條,也可是多條。以圖1的漢字“宋”為例,其輪廓線有3條,而控制點則有多個。而TrueType字體中的圖元輪廓定義主要用到的便是二階Bezier曲線,其具體包括了曲線上的點、曲線外的點以及一個曲線上的點這3個點。對于多個連續的不在曲線上的點,并沒有做出不允許的要求。
2.4 輪換圖元數據為點陣信息
從字庫中對圖元信息進行提取是上一小節的主要內容,而本節的主要內容則是描述圖元信息的作圖與填充。直線與貝塞爾曲線是作圖的主要依據,而光柵填充排在第二。在填充字體后,可提取出字模,并按照2048X2048的格式進行縮小保存。FreeType帶了兩個渲染器,分別為raster和smooth,兩者支持的各不相同,前者主要針對向量輪廓到單色位圖的轉換,而后者則是由相同輪廓到高質量反走樣像素圖的轉換。通過smooth渲染器可直接生成span。若要使反走樣的位圖質量更高,那么smooth渲染器無疑是首選。首先,應分解輪廓。作為一系列封閉輪廓線的總和,輪廓主要存在于2D平面上,每一輪廓線均由兩部分組成,即一系列線段與Bezier弧。在分解輪廓點,使之以線段與弧的形式出現時,需對以下規定引起注意:兩個相鄰的“on”點代表的是一條線段,而conicBezier弧則由兩個on點之間的conicoff點來表示,off是控制點,on是起、止點;兩個on點之間的兩個相鄰cubicoff點代表的是一個cubicBezier弧,其必須由兩部分組成,即兩個on與兩個cubic控制點。最后,創建一個on點,其并非是真實的,且位置在兩個相鄰的conicoff點的正中間。為了對目標窗口的位置進行調整,就要在渲染成目標位圖之前,平移裝入或變換過的輪廓。
目前,無論是在日常生活中經常使用到的電子產品中,還是被用于工業自動化和監測的可編輯控制器中,甚至是娛樂設備的游戲機都屬于嵌入式系統。嵌入式系統運用越來越廣泛。
3 結語
本文對基于FreeType嵌入式矢量字體引擎進行了研究。通過對FreeType作為字體引擎的使用,將移植過程中的剪裁和優化步驟及方法進行了總結,以期在實際運用中取得良好的效果。