摘 ?要:嵌入式設(shè)備上常用的有兩種類型的字體:點陣型字體和TrueType類型字體。點陣字體很難進行縮放,否則會失真,而TrueType文件并不存在這個問題。但因TrueType字體文件較大,并不能直接使用在嵌入式系統(tǒng)中。因此,在使用TrueType字體前須對其進行適當(dāng)?shù)亩ㄖ疲贿x取用到的字符,這樣可以使字體文件的大小減小很多,更適合使用在嵌入式系統(tǒng)上。
關(guān)鍵詞:嵌入式設(shè)備;字體文件;TrueType;造字程序
中圖分類號:TP311.1 ? ? 文獻標(biāo)識碼:A 文章編號:2096-4706(2019)17-0005-04
Abstract:Two type of fonts are used most on embedded device,the lattice and the TrueType font. It is almost impossible to resize the lattice or distortion will occur while there’s no the same problem on TrueType font. However,the full size TrueType font are usually too big to be used on embedded device directly. Therefore,TrueType fonts should be customized properly before using them,and only the characters used should be selected,which can reduce the size of font files a lot and make them more suitable for use in embedded systems.
Keywords:embedded device;font file;TrueType;font program
0 ?引 ?言
TrueType字體現(xiàn)今在PC機上的使用已經(jīng)非常廣泛,然而在嵌入式系統(tǒng)中,字體主要還是以點陣型為主。究其原因主要為嵌入式系統(tǒng)資源有限,而TrueType字體占用資源和空間較多,雖然嵌入式系統(tǒng)的資源和性能較原來已經(jīng)好了很多,但是TrueType字體動輒幾十兆的大小還是太過龐大。隨著顯示精度的提高,點陣型字體已無法達到顯示要求,TrueType字體取代點陣型字體已是大勢所趨,為了克服TrueType字體文件較大的難題,在使用TrueType字體時必須對其進行裁剪,只選取字體文件中將來會用到的字符重新生成新的字體文件,以減小字體文件的大小[1]。
1 ?TrueType字體簡介
TrueType字體技術(shù)是由蘋果和微軟聯(lián)合推出的一種新型數(shù)字字形描述技術(shù),用數(shù)學(xué)函數(shù)描述字體輪廓外形,含有字形結(jié)構(gòu)、顏色填充、數(shù)字描述函數(shù)、流程條件控制、柵格處理控制、附加提示控制等指令。其字體外形輪廓采用二次貝塞爾曲線,相對之前PostScript等字體,曲線方程次數(shù)降低,但配合其豐富的指令集,在實現(xiàn)輪廓曲線光滑性的前提下,大大提高了解釋器的工作速度。加之其公布字體文件結(jié)構(gòu),可實現(xiàn)在不同系統(tǒng)間進行移植并方便用戶加入已實現(xiàn)的字符,因此TrueType字體得以作為標(biāo)準(zhǔn)字體,應(yīng)用如此廣泛。
2 ?TrueType字體分析
2.1 ?TrueType字體結(jié)構(gòu)
TrueType字體文件數(shù)據(jù)內(nèi)容由表頭、一系列描述表目錄和描述表組成,并由不同表中的數(shù)據(jù)組合起來描述字體中的每個字,其結(jié)構(gòu)如圖1所示。
2.2 ?表頭
TTF文件開頭12字節(jié)為表頭(offset table),其內(nèi)容及數(shù)據(jù)類型如下(其中FIXED類型為帶符號整數(shù)小數(shù)各16位的32位定點實數(shù)):
FIXED ? ? version //文件版本號
USHORT ?numTables //描述表數(shù)目
USHORT ?searchRange //快速查找范圍
USHORT ?entrySelector //描述表入口
USHORT ?rangeShift //范圍調(diào)整
其中最重要的為numTables,其余項都可以由其計算得到,詳細(xì)信息可以參考TrueType說明文件[2]。
2.3 ?描述表目錄
表頭(offset table)之后緊跟著描述表目錄,其個數(shù)為numTables個,每個描述表目錄項都占有16個字節(jié),其結(jié)構(gòu)如下:
ULONG ?tag //描述表名稱
ULONG ?checksum //描述表校驗和
ULONG ?offset //描述表偏移
ULONG ?length //描述表字節(jié)長度
2.4 ?描述表
TrueType類型字體中包含的描述表最多可達到24個,其中10個必須,14個可選,描述表目錄項按照表名字(tag)的升序排列。本文僅介紹10個必須的表,如下所示,可選表信息可參考TrueType說明文件,且其不會影響字體裁剪。
cmap //字符代碼到文字序號映射表
glyf ? //字符輪廓信息表
head //字體文件頭信息表
hhea //水平度量頭信息表
hmtx //垂直尺寸信息表
loca //文字序號到位置索引信息表
maxp //最大值描述表
name //字體名表
post //PostScript信息
OS/2 //OS/2與Windows度量信息
10個表中與字體裁剪關(guān)聯(lián)較大的表有cmap、glyf、loca等三個;head、hhex、hmtx、maxp、name等五個表也會有所涉及,下面對cmap、loca、glyf三個表進行簡要介紹。
2.4.1 ?cmap表
cmap表給出了字符由其本身編碼到字體中其序號的映射關(guān)系。譬如漢字“文”,其Unicode編碼為0x6587,根據(jù)這個編碼值通過cmap表便可以索引到“文”字在字體文件中的序號,進而可以根據(jù)字形輪廓繪制出“文”字。cmap表結(jié)構(gòu)如圖2所示。
表頭格式為:
USHORT ?cmap_version//cmap版本號
USHORT ?cmap_tables//cmap子表數(shù)
描述表目錄格式為:
USHORT ?Platform_ID
USHORT ?Platform_Encoding
ULONG ? Offset
描述子表有四種格式,分別對應(yīng)Format0、Format2、Format4、Format6,下面以Format4為例,簡述輪廓信息查找過程。
Format4描述子表格式如下:
USHORT ?format//子表格式,此處為4
USHORT ?length//子表長度(字節(jié)計)
USHORT ?version//子表版本
USHORT ?segCountX2//子表分段數(shù)*2
USHORT ?searchRange//快速查找范圍
USHORT ?entrySelector//入口值范圍
USHORT ?rangeShift//偏移調(diào)整
//每段結(jié)束字符代碼
USHORT ?endCount[segCount]
USHORT ?reservedPad//保留對齊,為0
//每段開始字符代碼
USHORT ?startCount[segCount]
//字符輪廓序號調(diào)整量
USHORT ?idDelta[segCount]
//每段映射子表所有字符輪廓序號存儲
//位置(在glyphIdArray數(shù)組中)相對
//當(dāng)前位置的偏移量
USHORT ?idRangeOffset[segCount]
//文字輪廓序號數(shù)組(變長)
USHORT ?glyphIdArray[]
其根據(jù)字符編碼查找字符輪廓索引(index)流程如圖3所示。
2.4.2 ?loca表
loca表記錄了每個文字的輪廓數(shù)據(jù)信息在glyf表中相對于glyf表初始位置的偏移,其依據(jù)cmap表中查詢到的字符索引,由該字符索引確定偏移位置,loca表結(jié)構(gòu)比較簡單(其中char_index為字符輪廓索引):
USHORT offsets[char_index];
整個查詢過程如圖4所示。
2.4.3 ?glyf表
glyf表是TrueType文件中重要的表,其存儲了文字的輪廓描述信息,以及一系列的指令信息。glyf表較為復(fù)雜,不再將其表中變量一一說明,具體說明見TrueType文件。這里僅介紹簡單及復(fù)雜字符輪廓的讀取過程如圖5所示。
3 ?軟件設(shè)計
為達到字體的定制功能,字體定制軟件要能夠讀取某一字體文件的內(nèi)容,對其進行解析,根據(jù)需要對其裁剪,最后保存所需的部分,字體定制軟件結(jié)構(gòu)框圖如圖6所示。
字體定制軟件主要由兩個模塊組成:字體文件讀取模塊、字體子集定制模塊,軟件采用基于MFC架構(gòu)的C++語言開發(fā)[3]。
考慮到TTF文件中表數(shù)的眾多,如果對每個表分別進行獨立操作,將會使軟件的工程量變得很大,同時結(jié)構(gòu)還會變得相當(dāng)松散,這是比較差的設(shè)計方式??紤]到實際過程中并不需要對所有的表都進行修改,并且利用C++語言的繼承和多態(tài)的特性,可以將對描述表的讀取通過以下方式實現(xiàn)。
所有的描述表都需要實現(xiàn)內(nèi)容讀取、內(nèi)容保存的功能,具有一定的共性,所以可以設(shè)計一個基類CTaleInfo類,而具體的每個表都可以從CTableInfo類進行派生,如圖7所示。
類的定義如下所示:
Class CTableInfo
{
public:
//保存表信息
virtual void SetSave();
//從硬盤讀取文件
virtual void Load();
//將表信息寫入文件
virtual void Store() const;
//將信息附加到表中
virtual void AppendGlyfByDoc(){};
//復(fù)制表信息
virtual void Duplicate();
//設(shè)置表對應(yīng)的TTF文件類
virtual void SetTtfDoc();
}
軟件界面如圖8所示。
4 ?結(jié) ?論
該軟件已經(jīng)開始于工程中使用,其操作方便、運用直觀,可對字體按需定制。經(jīng)過裁剪的文件大小適合于嵌入式系統(tǒng),大大提高了系統(tǒng)的運行效率。
參考文獻:
[1] 呂強,史磊,楊季文.TrueType字體文件格式初探 [J].計算機研究與發(fā)展,1995(11):23-31+60.
[2] TrueType 1.0 Font Files,Technical Specification(Revision 1.66) [Z].Microsoft Corporation,1995.
[3] 孫鑫.VC++深入詳解(修訂版) [M].北京:電子工業(yè)出版社,2012.
作者簡介:閆文奇(1988.10-),男,漢族,江蘇贛榆人,工程師,碩士,研究方向:控制器軟件開發(fā)。