本文永久地址為http://www.cnblogs.com/vertexshader/articles/3201632.html,來源請注明。
嘗試了一下使用FreeType來渲染字體,FreeType是一個免費且開源的,可移植的字體引擎,有許多程序包括游戲使用它作為字體渲染的庫,下面說說我對FreeType的理解。
准備工作
首先是到freetype.org下載最新的FreeType庫,在使用之前需要對其進行編譯,還好在bulids目錄下有相應平台的工程,可以直接打開FreeType進行編譯。編譯選項有Debug Multithreaded、Debug Singlethreaded、Release Multithreaded、Release Singlethreaded四個選項,這里要注意的是,如果鏈接FreeType的工程是Debug配置,那么應該使用FreeType的Debug配置編譯出來的lib文件,否則可能導致未知的錯誤。主工程添加了庫目錄和庫文件之后,相應的准備工作算是完成了。
開始使用FreeType
參考了FreeType大部分英文文檔,理解了FreeType核心的幾個操作,FreeType渲染文字需要好幾步,以下是FreeType渲染字體的大致過程:
- 初始化FreeType Library;
- 初始化和載入Font Face;
- 設置字符大小;
- 渲染字符,得到相應的bitmap;
- 拷貝並排版文字。
關於FreeType入門方面的知識不是本文的重點,這里不想多述,可以參考官方的范例和文檔,它們在這里。
關於FreeType字符的排版
FreeType渲染字體后,生成的bitmap正好就是文字的大小,所以把bitmap拷貝到大圖像上以后必須對其進行排版。文字不能都直接拷貝入同樣大小的方形子圖像上,雖然對於東亞文字問題不大,但是對於西方文字會非常的難看。因為東亞文字不存在基線,字符的大小也相同;而西方的文字存在基線,文字需要對齊,字符的大小也不相同。有助於排版的幾個重要參數如下:
- font_face->size->metrics.height 這個參數其實就是每一行的高度,在設置相應的字體和字符大小之后生成的,每一行的字符都不會超過這個范圍;
- font_face->size->metrics.ascender 這個參數就是上部的高度,同時也可以算出基線的高度,用於帶基線的字符的對齊,在后面會詳述;
- font_face->glyph->metrics.horiAdvance 這個參數就是每個字符的寬度,在渲染文字后可用;
- font_face_->glyph->bitmap.pitch 這個參數是生成的bitmap每行的像素數量,在渲染文字后可用;
- font_face->glyph->bitmap.rows 這個參數是生成的bitmap的行數,在渲染文字后可用;
- font_face->glyph->bitmap_left 這個參數是bitmap到文字左邊界的距離,在渲染文字后可用;
- font_face->glyph->bitmap_top 這個參數是bitmap到文字上邊界的距離,在渲染文字后可用。
這幾個參數在排版時的關系如下:
(此圖有錯誤,horiadvance應該到最左邊。)
如果以左上角(x,y)為復制起點的話,為了對齊字符,那么復制點應該在:
pos_x = x + bitmap_left;
pos_y = y + ascender - bitmap_top;
換行和換列,分別對應的算式應該是:
x += horiAdvance;
y += height;
對於超出圖像寬度和高度的話,需要你自己限制一下。我自己做了一下,不夠字符的寬度的話,那么就會自動換行;圖片的高度不夠行數的話,余下的都會被忽略並不會被渲染。
輸出效果
獲得在程序中獲得這些信息后,可以在渲染的時候對其進行排版。不過如果用在游戲的文字顯示上的話,用FreeType一個個文字去渲染的方法重復渲染的次數會比較多,有比較好的方法就是統一做一張大的紋理,把用到的字都提前渲染好,需要的時候進行提取。程序的排版效果如下,比較簡單的內存輸出,不同寬度的、帶基線的文字都能正確顯示了: