【QT環境搭建】qt字庫的移植(使其很好的顯示中文)



原文:http://blog.chinaunix.net/uid-21025382-id-168772.html

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/enwenquanyi wenquanyi_12pt.bdf BDF n 50 120 uwenquanyi wenquanyi_13pt.bdf BDF n 50 130 uwenquanyi wenquanyi_15pt.bdf BDF n 50 150 uwenquanyi wenquanyi_16pt.bdf BDF n 50 160 uwenquanyi wenquanyi_12ptb.bdf BDF n 75 120 uwenquanyi wenquanyi_13ptb.bdf BDF n 75 130 uwenquanyi wenquanyi_15ptb.bdf BDF n 75 150 uwenquanyi 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(Table3 總結
   
經過本人對字庫進行上述處理後,就可以在嵌入式開發板上顯示各種字體,只要找到給定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]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章