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