初探FreeType
前言
繪圖API並不支援畫字型的功能,以前使用Direct2D搭配DirectWrite來畫字型,但不幸地現在繪圖引擎要跨平台,Direct2D的方法最多只能在Windows平台使用,FreeType就是我找到的可以跨平台的畫字型方法,這裡把學習心得做個紀錄。內容
首先先來說說"建置",FreeType自帶的建置個人覺得實在是不怎麼好用,Windows版的建置是由官方給個Visual studio專案直接開啟後建置即可,但Linux的建置就完全不一樣,是類似透過Shell script的方式來建置,Android則是透過NDK的專案來建置,最後我並沒選擇官方的建置是因為FreeType在下載時是在Windows平台,所以裡面的文字檔的換行是"\r\n",結果當我在Ubuntu建置時都會報錯,也就是說跟建置相關的檔案絕不能在Windows的環境編輯,不然上傳後就沒辦法用了。解決的方案很簡單,就是自己建置,還記得官方有自帶一個Visual studio專案嗎?我依據該專案的建置方案來製作Linux與Android的建置,這方法有風險,但我還是做了,幸運的是Linux與Android的建置與Windows是差不多,差別的地方是Linux與Android版並沒有所謂的"Debug"版,編譯時不用加"FT_DEBUG_LEVEL_ERROR"與"FT_DEBUG_LEVEL_TRACE"編譯,其它的部分和Windows版是一樣的。接著來看看如何使用,先看以下範例
#include "ft2build.h" #include FT_FREETYPE_H int main() { //... // FT_Library library; FT_Error error=FT_Init_FreeType(&library); if(error!=0) return 1; // //... //Free FT_Done_FreeType(library); return 0; }
這個範例會去製造FT_Library,整個程式應該只要製造一個,在程式要結束時,透過FT_Done_FreeType()來釋放。FT_Library製造完後就可以來讀取font檔,範例如下
#include "ft2build.h" #include FT_FREETYPE_H int main() { //... // FT_Library library; FT_Error error=FT_Init_FreeType(&library); if(error!=0) return 1; //Load font file FT_Face face; error=FT_New_Face(library,"arial.ttf",0,&face); //... //Free FT_Done_Face(face); FT_Done_FreeType(library); return 0; }
讀取的方法很簡單,透過FT_New_Face()來讀取,透過FT_Done_Face()來釋放。在Android時,由於Android的Asset不提供Handle,如果要將Font檔放在Asset的話,就要透過FT_New_Memory_Face()來讀取。接下來就來讀取字型的資料,範例如下
#include "ft2build.h" #include FT_FREETYPE_H int main() { //... // FT_Library library; FT_Error error=FT_Init_FreeType(&library); if(error!=0) return 1; //Load font file FT_Face face; error=FT_New_Face(library,"arial.ttf",0,&face); //Set font size error=FT_Set_Pixel_Sizes(face,0,60); //Load glyph FT_UInt glyphIndex=FT_Get_Char_Index(face,'a'); if(glyphIndex==0) return 1; error=FT_Load_Glyph(face,glyphIndex,FT_LOAD_DEFAULT); if(face->glyph->format!=FT_GLYPH_FORMAT_BITMAP) { error=FT_Render_Glyph(face->glyph,FT_RENDER_MODE_MONO); if(error!=0) return 1; } //Get glyph bitmap data from face->glyph->bitmap.buffer //... //Free FT_Done_Face(face); FT_Done_FreeType(library); return 0; }
透過FT_Set_Pixel_Sizes()來設定字型的大小,接著透過Glyph index來寫資料到"buffer"裡,"buffer"在哪呢?透過face->glyph->bitmap.buffer來取得。
Buffer的資料就是一張圖,整個Buffer的資料的大小為face->glyph->bitmap.pitch*face->glyph->bitmap.rows,"face->glyph->bitmap.rows"就是高,但"face->glyph->bitmap.pitch"並不是寬,每個Pitch指的是把寬度以每8個Pixel存成一個Byte來計算的話會有幾個Byte,如果寬度是60Pixel,Pitch值為8,如果寬度是40Pixel,Pitch值為5,依此類推。
參考資料
FreeType官網Text Rendering with Direct2D and DirectWrite
沒有留言:
張貼留言