1 如何定製字型檔(移植字型檔) 需要將至少兩個檔案賦值到....lib/font目錄下 1. fontdir 檔案。這個是應用程式尋找當前系統中最合適自己需要的字型檔的索引;
2,需要的字型庫檔案,一般是多個。具體移植那一個,看你使用的字型檔是什麼了,。比如我現在的系統我就是移植的wenquanyi_12pt.bdf就可以了,當然這個比較大。你也可以用小點的。我的flash比較大呵呵,懶得折騰。 在程式中需要這樣設定: QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8")); 設定使用utf-8編碼也就是unicode編碼了,這樣在tr和string的都是unicode的編碼了,根據字型檔的索引就能對應相應的字元了。 然後設定字型: //字型設定 QFont font("wenquanyi",12,QFont::Bold); //使用wenquanyi字型 this->setFont(font); //這樣就設定了字型了,中文一般使用wenquanyi字型就可以了。很好的。 基礎知識介紹: 字元編碼 1、 字元必須編碼後才能被電腦處理。電腦使用的預設編碼方式就是電腦的內碼。早期的電腦使用7位的ASCII編碼,為了處理漢字,程式員設計了用於簡體中文的GB2312和用於繁體中文的big5。在這些編碼中,中文和英文可以統一的處理,區分中文編碼的方法是高位元組的最高位為不為0。GB內碼的儲存方式始終都是big endian,即高位在前。 2、 Unicode是一種字元編碼方法,它是由國際組織設計,可以容納全世界所有語言文字的編碼方案。Unicode的學名是"Universal Multiple-Octet Coded Character Set",簡稱為UCS。UCS可以看作是"Unicode Character Set"的縮寫。 Unicode與GB碼不相容,只與ASCII相容。 UCS規定了怎麼用多個位元組表示各種文字。怎樣傳輸這些編碼,是由UTF(Unicode transforation format)規範規定的。常見的UTF規範包括UTF-8(就是以8位為單元對UCS進行編碼)、UT F-7、UTF-16。 UTF-*和Unicode是同類,就是在編碼方式上不同。首先UTF編碼後的大小是不一定,不像Unicode編碼後的大小是一樣的。 字型庫: 一般認為,一個漢字的編碼就對應著這樣的字形,這還是錯誤的。內碼對於字型檔來說,只是尋找字形的索引。如果換成另一個編碼通訊協定的字型,同一個字串就會呈現不同的字形,也就是亂碼。 隨著GUI的發展,字型檔逐漸轉向TTF.TTF字型檔的編碼通訊協定沒有UTF8的 由於工作需要把ttf字型轉換成qpf字型,牽扯到了qt的makeqpf工具的使用方法 先簡單說一下qt的字型支援 Qte可以支援以下四種形態的字型格式 TrueType (TTF)、Postscript Type(PFA/PFB)、Bitmap Distribution Format fonts(BDF)、Qt Prerendered Font(QPF) Qt中不同字型是用Unicode來處理、轉換 因為Unicode(UTF16或者UTF8)最適合在任何人之間傳遞資訊, 至於TrueType(不知道是什麼東西,先唬著)的支援,目前Qte採用的是FreeType2 Livrary來顯示字型,可充分享受無段式anti-aliased顯示。 經過下午的查證:Truetype是由AppleComputer公司和Microsoft公司聯合提出的一種新型數學字形描述技術。他用數學函數描述字型輪廓外形,含有字形構造、顏色填充、數字描述函數、流程條件控制、珊格處理控制、附加提示控制等指令。TrueType採用幾何學中二次B樣條曲線及直線來描述字型的外形輪廓,其特點是:TrueType即可以作列印字型又可以做螢幕顯示;由於它是由指令對字形進行描述,因此它與解析度無關,輸出時總是按照印表機的解析度輸出。無論放大或縮小,字元總是光滑的,不會有鋸齒出現。但相對PostScript字型來說,其品質要差一些,特別是在文字太小時,就表現得不是很清楚 簡單 一下: truetype,字型就是可以不變形放大的字型,標準的字型大約有三種。*.fon 、*.ttf 、*.ttc,你所問的就是*.ttf 、*.ttc是*.ttf的新標準。*.fon就是很久以前用的字型,dos下現windows還有少量,主要用在系統使用方面可以提高程式的執行效率 FreeType是一個免費的並且可以被移植的TrueType 字型檔引擎,可以應用於很多平台! fontdir的簡介 下面是截取qtcore中預設的fontdir檔案中的中文字型檔部分 #Chinese character font from http://wqy.sourceforge.net/en wenquanyi wenquanyi_12pt.bdf BDF n 50 120 u wenquanyi wenquanyi_13pt.bdf BDF n 50 130 u wenquanyi wenquanyi_15pt.bdf BDF n 50 150 u wenquanyi wenquanyi_16pt.bdf BDF n 50 160 u wenquanyi wenquanyi_12ptb.bdf BDF n 75 120 u wenquanyi wenquanyi_13ptb.bdf BDF n 75 130 u wenquanyi wenquanyi_15ptb.bdf BDF n 75 150 u wenquanyi wenquanyi_16ptb.bdf BDF n 75 160 u
可以看到共有七列 第一列:字型的名字,就是你在設定字型的時候的字型的名字 第二列: (file)即具體的檔案名稱字 第三列: (renderer)字型的格式,有BDF,TTT,QPF等選擇. 第四列: n 表示iitalic,是否為斜體 第五列:weight, 50 = Nomal,75=Bold 第六列: size 120表示12pt 第七列flags 有三個選項:s (smooth) u (unicode順序儲存) a (ascii 順序儲存,預設是Latin 1)。 檔案中每行都標識一個特定的字型檔,每個段的含義是:第一列為name,第二列為file,第三列為renderer,相當於字型格式,所以有 BDF,TTT,QPF等選擇。第四列n表示iitalic,表示是否為斜體字。第五列表示weight,其中50表示Normal,75表示Bold。第六列表示size,例如:120表示12pt。第七列為flags,有下面三個選擇:s=smooth(anti-aliased)u =unicode range when saving (default is Latin 1 a = ASCII range when saving(default is Latin 1)) —— 摘自參考文獻[1] 其中屬性file,renderer(BDF,TTF,QPF)和size特別要設定對,其它屬性問題不大。還要注意如果在該目錄下有QPF的檔案,系統只會使用QPF格式的檔案,而不會讀取其它格式的檔案,不管FONTDIR裡面的內容是什麼。如果有多個QPF檔案,應用程式按照大小,家族,黑體和斜體的順序尋找,即首先尋找大小和自己一樣的字型檔,大小無法區分唯一的字型檔的再看對應的家族,還是無法區分的再看是否黑體,是否斜體。可以參考PC上的字型檔索引檔案FONTDIR: 例如: -cclib -song -medium -r -normal -jiantizi -16 -160 -75 -75 -c -160 -gb2312 1980 -0 其中,每個段的含義如下: cclib:製造商 song:字型族,此處表示“宋體”字 medium:字權重(中等),還有bold(粗體)選項 r:傾斜,R(Roman),I(Italic),O(Oblique) normal:字元集寬度,此外還有condensed,narrow,double jiantizi:附加說明(此處意義為“簡體字”) 16:用像素衡量的寬度。 160:點數 10 75(1):水平解析度(dpi) 75(2):垂直解析度(dpi) c:間距。c:square,m:fixed width,p:variable width 160:平均寬度(10*pixels) gb2312.1980:註冊字元集,標準名 0:第0套,基本集 —— 摘自參考文獻[2] 1.2 幾種格式字型檔的簡介 QT支援四種格式的字型檔(TTF,BDF,PFA/PFB,QPF)(見參考文獻[3]),但在產品中,如果直接使用,TTF或PFA/PFB。即讓應用程式在顯示的時候再計算點陣,最終的效果並不理想,會發現有些字大,有些字小,而且需要佔用非常多的FLASH和記憶體,速度也有點慢,所以我在此不想過多的介紹PFA/PFB。如果直接使用BDF,速度非常慢,而且需要佔用比較多的FLASH和記憶體;使用QPF,速度和佔用其它資源是最小的,因此我們最終的產品中採用QPF格式。下面我簡單介紹,TTF,BDF和QPF字型的結構,這樣就比較容易理解後面的轉換過程。 1.2.1 TTF字型 TTF(TrueType Font)是Apple公司和Microsoft公司共同推出的字型檔格式,隨著Windows的流行,已經變成最常用的一種字型檔表示方式。TTF 字型已經成功用在Windows中文版產生漢字字型檔,此字型採用二次B樣條曲線來描述字元輪廓,對字元輪廓的上的點,按順時針方向從小到大編號,填充部分在其右邊。TTF檔案結構分成三個部分:檔案名稱(12Bytes),描述表目錄(每個16Bytes),描述表資料。 對於每一個字,都有一個假想的矩形框,正常情況字是不會超出這個矩形框的,中文屬於象形字,不象英文,大小不一致,比如:英文中的f就可能會超出矩形框。微軟把矩形的高度稱為EM,實際字元的高度稱為BODY.矩形框最原始的座標系是矩形的中心為原點,但為了實際字型在列印和顯示的使用過程中的方便,通常將座標原點放在左下角,或中下。 通常,在實際列印過程中,TTF字型是用像素來度量的,如何將矩形框中的字型轉成像素呢?有一個計算公式,執行個體如下:如果18個點的72點每英寸屏下有一個550的長度,矩形框內有2048個單位。那其像素為550*18*72/72/2048=4.83像素。顯然,每英寸裡的點取的越多,字就越逼真,同時這樣的儲存空間和計算的時間也就越多。在嵌入程式開發過程中,這往往是不可以接受的,因為嵌入式系統的硬體資源本來就很有限,如果真的這樣的話,在顯示過程會很慢。並且如果為了提高速度而減少每英寸中的點數,則字型失真的情況很嚴重。更加具體的關於,TTF字型的內容可見參考資料[3]。 另外,在Windows下編程,Microsoft實現了讓使用者對字型操作處理具有透明性,有關字型結構定義見參考文獻[4]。 1.2.2 BDF字型 BDF(Bitmap Distribution Format)是在X視窗系統中的一種表示位元影像字型的檔案格式。是X協會定義的一種標準,是ASCII檔案它由兩部分組成,一是表示字型整體屬性的檔案頭資訊;二是每一個字元專屬的屬性和位元影像資料。我以16*16的位元影像字型為例描述BDF字型檔格式。 STARTFONT2.1 /*後面跟一個版本號碼,指出該字型檔版本*/ COMMENT /*表示注釋*/ FONT -adobe -courier -bold -r -normal -16 -160 -75 -75 -m -160 -gb2312.1980 -0 /*表示字型名*/ SIZE 16 75 75 /*字元大小與在X,Y方向上的解析度*/ FONTBOUNDINGBOX 16 16 0 0 /*X方向上寬度與Y方向高度及x和Y方向上的位移*/ STARTPROPERTIES 16 /*設定字型的屬性項目數*/ FOUNDRY "Adobe" /*字型的製造廠家*/ FAMILY_NAME "Courier" /*字型的變種字型*/ WEIGHT_NAME "Bold" /*字型的印刷權*/ SLANT "R" /*字型字型的設計情況*/ SEWINDTH_NAME "Normal" /*字型的縮放因素*/ ADD_STYLE_NAME "" /*唯一的標識該字型,一般為空白*/ PIXEL_SIZE 16 /*依賴於裝置的字型尺寸*/ POINT_SIZE 160 /*設計字型的實際尺寸*/ RESOLUTION_X 75 /*設計字型的水平解析度*/ RESOLUTION_Y 75 /*設計字型的垂直解析度*/ SPACING "m" /*指出字元寬度是定長還是可變*/ AVERAGE_WIDTH 160 /*字型中所有字元的平均寬度*/ CHARSET_REGISTRY "gb2312.1980" /*字元集名*/ CHARSET_ENCODING "0" /*字元集編號*/ FONT_DESCENT 0 /*基準下的高度*/ FONT_ASCENT 16 /*基準上的高度*/ ENDPROPERTIES /*屬性項設定結束*/ CHAR 6775 /*字型檔中的字元數*/ STARTCHAR 啊 /*字元起始標誌及名稱*/ ENCODE 3021 /*X伺服器在存取該字元時使用的編碼。如漢字國標碼*/ SWIDTH 1000 0 /*X和Y方向上的邏輯寬度和高度*/ DWIDTH 16 0 /*字元在x和Y方向上的裝置單位寬度*/ BBX 16 16 0 0 /*字元邊界框的寬度,高度以及位移*/ BITMAP /*字元的位元影像的資訊起始標誌*/ 0000 /*字元位元影像*/ 04a0 …… 0590 ENDCHAR /*字元結束標誌*/ STARTCHAR 阿 /*第二個字元開始*/ …… ENDFONT /*BDF字型檔結束標誌*/ 1.2.3 QPF字型簡介 QPF格式的字型檔是僅用於QT/Embedded的不可縮放的字型,在程式運行過程中,對TTF格式的字型,在第一次裝入使用時,都要以給定的字型大小進行處理;而對於BDF字型,當其使用時,所有字型都必須被處理;而對於QPF字型,均以相同格式的儲存。所以在字型顯示時,Qt只要讀取字型,做相應分析,然後顯示就完成了,這樣進一步減少了對RAM資源的浪費。QPF字型是基於UNICODE編碼的,這為QT/Embedded良好的可移植性奠定了基礎。有關QPF更詳細的資料可以查閱參考文獻[5]。 2 如何從TTF字型檔轉成QPF字型檔 2.1 把TTF轉換成BDF 儘管不推薦使用TTF格式的字型檔,但由於TTF格式的字型檔可以轉換成任意大小的BDF字型檔,而可以找到的BDF字型檔都是固定大小的,因此在實際製作QPF字型檔時,還是需要TTF格式的字型檔。把TTF轉換成BDF的方法如下: ./ttf2bdf source.ttf -p yourSize -o destination.bdf 即利用軟體ttf2bdf可以把源檔案source.ttf轉換成大小為yourSize的BDF格式的檔案destination.bdf。那在程式內部是如何?將TTF轉成BDF的呢?由2.2.1和2.2.2的介紹,並且查閱參考文獻[3],可以知道TTF的內部儲存結構。其中最核心的部分是 TTF檔案格式中的12個位元組的檔案表:表目錄按tag以升序排列。
| Type |
Name |
Description |
| ULONG |
tag |
4位元組的標識 |
| ULONG |
checkSum |
表中的CheckSum |
| ULONG |
offset |
TrueType font檔案的起始位移量Offset |
| ULONG |
length |
表長 |
還有一個有關Offset表的資訊,包括版本號碼,表的數量,尋找範圍。入口選擇,轉換範圍。 通過操作檔案表,將描述表中的資料取出來,按照BDF字型所定義的格式寫入,就可以產生對應的字型。比如,可以給出一小段c語言程式,此程式用於計算當前CheckSum的位置。 ULONG CalcTableChecksum(ULONG *Table,ULONG Length) { ULONG Sum = 0L; ULONG *Endptr=Table+((Length+3)& ~3)/sizeof(ULONG); while(Table<EndPtr) Sum += *Table++; return Sum; } 利用此程式可以將每個字型的資訊分開,並將每個字型資訊從檔案中取出來,對每個字型進行操作。在從TTF轉到BDF過程中,僅通過使用WINDOW的函數是很不方便的,最方便的辦法是使用c語言對字型進行操作。我在此列出轉換過程中最重要的幾個值:PIXEL_SIZE,POINT_SIZE,RESOLUTION_X,RESOLUTION_Y,FONT_DESCENT,FONT_ASCENT,SWIDTH,DWIDTH,BBX。這些值決定著最後產生的BDF字型與TTF字型的失真度,因為TTF是可縮放的,而BDF是固定大小的,所以在轉換過程中一定會出現失真的情況。 2.2 對得到的BDF檔案進行調整 由於從軟體xmbdfed裡得到的三個字型檔不符合系統的要求,因此需要手動對其進行一些調整,其它方法得到的BDF檔案不需要進行調整。 直接從xmbdfed裡得到的字型檔是按照GB2312-80.0進行編碼的,因此首先要將其轉換成符合UNICODE編碼,這需要用到我手動寫的一個程式 gb2unieode,把源檔案拷貝到gb2unicode程式的目錄下,將其名字改為hanzist24a.txt(程式的要求,也可以不改名字而修改程式裡源檔案的名字再重新編譯),然後運行./change之後,就完成了,因為QT中因現成的轉換函式可以調用,在此我不想多說關於用程式轉換的代碼。因為有一種更簡單的方法,即在Word中開啟GB字型檔。然後另存新檔UNICODE字型檔檔案就行了。 等待該命令執行完後(注意需要的時間比較長),對所產生的檔案dest.txt進行排序,方法如下:把dest.txt的名字改為dest.bdf(只要尾碼名為bdf就行);然後運行軟體xmbdfed,用其開啟該檔案(xmbdfed只能直接開啟尾碼明為bdf的檔案),另存新檔 yourname.bdf即可。排完序後需要手 動修改處理yourname.bdf。 由上面介紹的BDF字型格式,現在對轉換得到的BDF字型檔進行如下手工處理:先刪除行說明屬性預設的字元的行DEFAULT_CHAR 8481,因為從GB2312轉換成UNICODE後,編碼為8481的字元已經不存在了,如果不刪除該行,運行時會出現段錯誤。然後刪除那些存在於兩個 16號字型檔但在標準GB2312中沒有的一些字模。標準GB2312中有7445個字模,而兩個16字型檔有7612個字模,多出來的那部分在用 gb2unicode轉換的時候因為找不到相應的GB2312碼而沒有寫進dest.txt的字模開始行"STARTCHAR ****"。可以用xmbdfed開啟,如果出錯則說明還有一些不完整的字模,還需要手動刪除這些不完整的字模,如果可以正確開啟則說明目標檔案已經是正確的。(24號字型檔不存在這個問題,因此不需要進行本項操作。)最後從其它大小相同的.bdf檔案中拷貝編碼為20-7F(ASCII碼)和編碼為 FE54(分號;)的字模到目標檔案。 2.3 把TTF.BDF轉換成QPF 從參考文獻[5]中可以知道QT提供的把TTF,BDF轉換成QPF的方法有兩種,一種是工具makeqpf,這個命令無論是在Pc機上還是在開發板上都沒有效果(但是QT的官方網站卻說是可以的,不知道為什麼,並且,也不是每個版本的QT都有makeqpf這個工具,還要說明的是,文獻[6]中說這個工具是可以的,不過我沒有實驗成功)。 另一種是運行應用程式時加上選項-savefonts,如在開發板上運行應用程式的命令:./sulfur -qws -savefonts 如果此時系統中/usr/qt/lib/fonts目錄下沒有QPF格式的字型檔而只有TTF或BDF格式的字型檔,對應的檔案fontdir中只保留要轉換的檔案的行,QT就會在運行時首先產生QPF格式的字型檔。儘管通過TTF字型也可以得到QPF字型,不過最好不要這樣做,因為失真太大。 3 總結 經過本人對字型檔進行上述處理後,就可以在嵌入式開發板上顯示各種字型,只要找到給定TTF或BDF的字型檔,如果找不到BDF字型檔,可以找到字型檔,然後通過 TTF2BDF這個程式來得到BDF字型檔。這樣在開發板上可以顯示行書,楷書等字型,並且字型顯示也很正常,不會出現大小不一致的問題。但是,本人認為,由於這是嵌入式開發,儲存資源非常有限,如果能進一步將字型檔縮小,只留下程式中所要用的漢字組成的字型檔就好了,這是需要下一步研究的方向。 參考文獻: [1] http://jserv.Sayya.org/qtopia/doe/qte.txt [2] http://www.Linuxfans.org/nuke/modules.php?name=Forums&file= viewtopic&t=82950&highlight=fonts.dir [3] Microsoft Corporation. TTF Technical Specification Revision 1.66 November 1995. [4] Windows 2000編程核心技術精解[M].中國水利水電出版社,2001. [5] http://doc.Trolltech.com/3.0/emb-fonts.html [6] 黃敬群.Qt/Embedded中文處理實戰[M] |