與傳統的使用點陣字型檔相比,truetype字型檔至少會帶來這樣的好處:可以高質量地實現字元的無級放大或縮小,高質量地實現字元的旋轉、傾斜等操作(如圖1),方便地實現「所見即所得」.
圖1應用效果圖
由於有以上優點,在很多對字形有特殊操作要求的地方最好使用truetype字型檔.windows中現在使用的就是truetype字型檔。
l、truetype字型檔的基礎
1.1 truetype簡介
truetype字型檔是一種輪廓字型檔,在true—type字型檔中,字形的資訊是通過使用一系列的點來描述的.這些點之間或通過直線段,或通過二次貝塞爾曲線來連線,從而形成字形輪廓.圖2是漢字「幹」的字形示例。
圖2字形輪廓線示例
圖2左邊圖形是直接連線字型檔中描述「幹」的點形成的,其中的圈表示描述字形的點:小圈表示直線段或貝塞爾曲線的端點,大圈表示貝塞爾曲線的控制點.
形成字形輪廓時對點的處理是這樣的:假設有了起點p0(x0,y0)(它肯定是端點,即小圈),再找下乙個點p1(x1,y1).如果p1也是端點,則用直線段連線p0,p1,再將p1作為新的起點繼續連線剩下的點;否則p是貝塞爾曲線控制點,再找下乙個點p2(x2,y2).如果p2是端點,則將p0,p1,p2用貝塞爾曲線連線,p2作為新的起點繼續連線剩下的點;否則再找下乙個點p3(x3,y3),計算p2與p3的中點px,將p0,p1,px用貝塞爾曲線連線,px作為新的起點繼續連線剩下的點.圖2右邊的圖形是加入了二次貝塞爾曲線形成的實際見到的字形輪廓.
得到字型輪廓後,再對它進行填充就得到了需要的字元位圖.剩下的工作就很簡單了,通過打點或貼圖都可以畫出字元來.
1.2 freetype的介紹
1.3 freetype使用
freetype提供了豐富的api,具體用法可以參見其文件,這裡僅作簡要介紹.
用freetype的api畫出乙個字元的流程大致如下(僅列出函式名):
……/*初始化 freetype庫 */
ft_init_freetype;
/*建立字型,如宋體 、楷體等 */
ft_new_face:
/*指定查詢字元字形的編碼,如 unicode、 gb2312等 *|
ft_select charmap
……/*根據字元編碼得到字元字形在字型檔中的位置 */
ft_get_char_index:
/*根據字元字形在字型檔中的位置得到其字形描述,即字形輪廓*/
ft_load_glyph:
/*將輪廓填充成位圖*/
ft_render_glyph:
/*使用者自定義函式畫出點陣圖*/
drawimage;
……/*撤消字型*/
ft_done_face:
/*撤消freetype庫*/
ft_done_freetype;
……當然實際系統中的應用不會這麼簡單,但是其基本過程是這樣的。
2、ugl字型驅動
ugl是zinc的基礎,首先在vxworks的ugl字型驅動中加入truetype字型檔支援:
1)根據vxworks的ugl字型驅動的介面標準寫出驅動**.
2)用行命令方式編譯ugl.在ugl文件中介紹了行命令方式編譯ugl,以及為加入新字型檔支援而修改相關檔案(如uglnit.h等)的方法.
現有ugl字型驅動只提供了用於水平方向字元顯示的介面,為了能夠更加靈活地顯示字元,可以在驅動介面中增加函式指標ugl-status(*textdrawfree);為了支援列印,可以加入函式指標ugl-status(*textprint).當然如果使用者要呼叫這2個函式,就得在ugl.h中加入相應的函式宣告,並在uglfont1.c中加入相應的函式定義.
typedef struct ugl-font-driver
ugl-font-driver;
textdrawfree中的結構uglrr_param中,定義了一些要用到的引數,如大小、前景及背景顏色、旋轉角度、傾斜程度等.
另外,為了提高字元顯示速度,可以用下面的方法:
1)將truetype字型檔調人記憶體.即用ft_new_memory_face代替ft_new_face;
2)利用freetype提供的快取功能.具體用法可以參見freetype提供的文件.
3)對固定尺寸的字型(一般用於介面,這種情況下對速度有較高的要求)專門建立乙個cache.現舉例說明如下:
假設cache的結構如下:
struct tt_cache_
;tt_cache_num是需要建立cache的字元數量.一般來說,cache中應包括ascii可顯示字元、漢字中的一級字及一些常用符號.
1)假設tt_cache一》code_aray中已經儲存了需要建立cache的字元編碼,首先對它排序(用c語言的qsort即可):
qsort(tt_cache—>code_array,tt_cache_num,sizeof(unsignedlong),compare);
2)為所有字元生成相應的點陣圖.
3)系統執行過程中需要查詢字元的字形時,執行以下步驟:
①用bsearch在tt_cache一》code_aray中查詢字元編碼.
②若查詢到,則相應的點陣圖也找到了.
③若沒查詢到,則到字型檔中去找.
4)銷毀字型時要同時銷毀cache.
應該注意的是上面的步驟1)、2)是在系統啟動時做的,如果第2)步時間太長的話,可以不執行步驟2),只需改變步驟3):
①用bsearch在tt_cache一》code_aray中查詢字元編碼.
②若查詢到,再看相應的點陣圖是不是存在.如果已經存在,則相應的點陣圖也找到了.如果還沒有,則根據字型檔生成位圖,並新增到cache中.
③若沒查詢到,則到字型檔中去找.
實踐證明,這種方法稍好一點.
3、列印
下面介紹在視窗系統zinc中利用ugl字型驅動如何實現列印中的「所見即所得」.
zinc中的列印流程是:先生成ps(postscript)檔案,再把ps檔案發到印表機埠進行列印,所以下面只討論如何生成ps檔案.
由於現有系統zinc不支援漢字的列印,所以必須回到ugl中用打點的方式畫出漢字.這就是為什麼實現ugl字型驅動時要加人函式指標ugl_status(*textprint)的原因.
textprint中的引數意義為:
pfacename字型名,如宋體、黑體等;
outfile指向列印的輸出目標:ps檔案.
修改zinc中的zafprinter,當要列印字元時就呼叫ugl中的列印函式,ugl中實現列印的部分基本與螢幕顯示相同,不同的只是把向螢幕(或記憶體位圖)打點(或貼圖)換成了向ps檔案寫人打點(或貼圖)命令.
由於列印和螢幕顯示兩者只是輸出目標的不同:前者是顯示器(如果是記憶體點陣圖也一樣);後者是ps檔案.這樣就很容易實現wysisyg——只要將座標單位設定為英吋(或英吋的千分之一)就行了.這裡介紹乙個技巧,由於漢字的列印是通過打點實現的,所以這樣會使得ps檔案比較大.要減小ps檔案,可以將連續的打點用畫線來代替.由於印表機的解析度很高,這樣做的效果會很明顯:一般可以將ps檔案減小到原來的1/5,這將大大減少寫印表機埠的時間.
4、結束語
在vxworks中使用truetype字型檔的方法已成功地應用於vxworks嵌人式地理資訊系統中,並可以很容易地移植到很多其他的系統中.
在QT中使用日誌系統
當寫好的軟體發布出去後,使用者遇到宕機或一些其他的bug,我們該怎麼追蹤這些問題呢,這時候日誌系統很好的幫助了我們。最近也是參照網路大牛的部落格 實現了log。下面看看 吧。void outputmessage qtmsgtype type,const qmessagelogcontext cont...
vxworks系統下列表的使用
vxworks系統對常用資料結構的實現比較少,但是提供了對雙向鍊錶的支援,其宣告位於lstlib.h標頭檔案中,主要定義了以下一些內容 1 list型別 list型別的定義如下 list結構體屬於是對整個鍊錶的描述,它包括了鍊錶的頭指標 尾指標以及鍊錶中節點的個數。其中,node的next指標是li...
在C 程式中使用系統熱鍵
1.首先引入system.runtime.interopservices using system.runtime.interopservices 2.在類內部宣告兩個api函式,它們的位置和類的成員變數等同.system.runtime.interopservices.dllimport user...