數碼相冊——FreeType介紹
- 硬件平臺:韋東山嵌入式Linxu開發板(S3C2440.v3)
- 軟件平臺:運行於VMware Workstation 12 Player下UbuntuLTS16.04_x64 系統
- 參考資料:《嵌入式Linux應用開發手冊》、《嵌入式Linux應用開發手冊第2版》、【FreeType教程】、【FreeType2使用總結】
- 開發環境:Linux 3.4.2內核、arm-linux-gcc 4.3.2工具鏈
目錄
一、FreeType簡要介紹
FreeType是一個軟件字體引擎,被設計成小、高效、可定製和可移植,同時能夠產生高質量的輸出(字形圖像)。它可以用於圖形庫、顯示服務器、字體轉換工具、文本圖像生成工具以及許多其他產品。
支持單色位圖、反走樣位圖的渲染。FreeType庫是高度模塊化的程序庫,雖然它是使用ANSI C開發,但是採用面向對象的思想,因此,FreeType的用戶可以靈活地對它進行裁剪。
在嵌入式環境中,可以只編譯那些你的嵌入式工程或環境需要的模塊,從而有效的減小FreeType 2 的代碼大小。
廢話少說,下面結合FreeType的官方教程來進行代碼介紹與編程步驟總結。
二、簡單的字形裝載過程的描述
1.頭文件
- 在使用時候,需要包含下列頭文件:
在FreeType中有許多頭文件的宏定義,需要添加ft2build.h
文件纔可以使用這些宏定義。
#include <ft2build.h>
#include FT_FREETYPE_H
2.庫初始化
這調用的函數爲FT_Init_FreeType()
- 原型
FT_Init_FreeType( FT_Library *alibrary );
- 參數解析
·FT_Library * alibrary:A handle to a new library object.(一個新庫對象的句柄) - 返回值
成功執行:0,錯誤執行:FreeType error code(錯誤碼) - 調用案例
FT_Library library;
...
error = FT_Init_FreeType( &library );
if ( error )
{
... an error occurred during library initialization ...
}
3.加載字體
- 函數原型
FT_New_Face( FT_Library library,
const char* filepathname,
FT_Long face_index,
FT_Face *aface );
- 參數
- FT_Library library — A handle to the library resource(庫資源的句柄).
- const char * filepathname — A path to the font file(字體文件的路徑).
- FT_Long face_index — The index of the face within the font. The first face has index 0(字體中face的索引。第一個face的索引爲0).
- FT_Face * aface — A handle to a new face object. If ‘face_index’ is greater than or equal to zero, it must be non-NULL. See FT_Open_Face for more details(一個新face對象的句柄。如果FACE_INDEX大於或等於零,則必須爲非NULL).
- 返回值
成功執行:0,錯誤執行:FreeType error code(錯誤碼) - 調用案例
FT_Library library; /* handle to library */
FT_Face face; /* handle to face object */
error = FT_Init_FreeType( &library );
if ( error ) { ... }
error = FT_New_Face( library,
"/usr/share/fonts/truetype/arial.ttf",
0,
&face );
if ( error == FT_Err_Unknown_File_Format )
{
... the font file could be opened and read, but it appears
... that its font format is unsupported
}
else if ( error )
{
... another error code means that the font file could not
... be opened or read, or that it is broken...
}
4.訪問face數據
可以通過face
句柄進行訪問
- 原型
typedef struct FT_FaceRec_
{
FT_Long num_faces;
FT_Long face_index;
FT_Long face_flags;
FT_Long style_flags;
FT_Long num_glyphs;
FT_String* family_name;
FT_String* style_name;
FT_Int num_fixed_sizes;
FT_Bitmap_Size* available_sizes;
FT_Int num_charmaps;
FT_CharMap* charmaps;
FT_Generic generic;
/*# The following member variables (down to `underline_thickness') */
/*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size */
/*# for bitmap fonts. */
FT_BBox bbox;
FT_UShort units_per_EM;
FT_Short ascender;
FT_Short descender;
FT_Short height;
FT_Short max_advance_width;
FT_Short max_advance_height;
FT_Short underline_position;
FT_Short underline_thickness;
FT_GlyphSlot glyph;
FT_Size size;
FT_CharMap charmap;
/*@private begin */
FT_Driver driver;
FT_Memory memory;
FT_Stream stream;
FT_ListRec sizes_list;
FT_Generic autohint; /* face-specific auto-hinter data */
void* extensions; /* unused */
FT_Face_Internal internal;
/*@private end */
} FT_FaceRec;
5.設置字體像素大小
這裏也有兩種方式:
1、調用FT_Set_Char_Size()
函數
- 原型:
FT_Set_Char_Size( FT_Face face,
FT_F26Dot6 char_width,
FT_F26Dot6 char_height,
FT_UInt horz_resolution,
FT_UInt vert_resolution );
- 參數解析
- char_width(字符的寬度):The nominal width, in 26.6 fractional points. 設置爲0時,char_width = char_height
- char_height(字符的高度):The nominal height, in 26.6 fractional points. 設置爲0時,char_width = char_height
- horz_resolution(水平方向的分辨率):The horizontal resolution in dpi. 設置爲0時,horz_resolution = vert_resolution
- vert_resolution (垂直方向的分辨率):The vertical resolution in dpi. 設置爲0時,horz_resolution = vert_resolution
通過查看官方文檔可以知道:
高度和寬度的單位是 point,1 point inch,分辨率的單位是dpi——每英寸點數
即
1 單位的高度或寬度 point,1 point inch,1 單位分辨率
所以
1 單位的高度或寬度的物理長度 inch
則
x單位的高度或寬度,y單位分辨率,其字符高度的像素爲
inch pixel - 調用實例
error = FT_Set_Char_Size(
face, /* handle to face object */
0, /* char_width in 1/64th of points */
16*64, /* char_height in 1/64th of points */
300, /* horizontal device resolution */
300 ); /* vertical device resolution */
2、對於上面的函數太過複雜,若只關心像素大小,可以使用FT_Set_Pixel_Sizes()
- 原型
FT_Set_Pixel_Sizes( FT_Face face,
FT_UInt pixel_width,
FT_UInt pixel_height );
- face(目標對象face的句柄):A handle to the target face object.
- pixel_width(寬度,單位爲像素):The nominal width, in pixels. 設置爲0時,pixel_width= pixel_height
- pixel_height(高度,單位爲像素):The nominal height, in pixels. 設置爲0時,pixel_width= pixel_height
此時設置pixel_width = 100,其高度像素就是100pixel,沒有複雜的轉換公式了。
6.加載字形圖像
這裏有兩種方法:
- 先調用
glyph_index = FT_Get_Char_Index( face, charcode )
得到當前字符在face
中的glyph
字形索引;後調用FT_Load_Glyph(face, glyph_index, load_flags )
,根據得到的glyph
字形索引,將字形圖像加載到slot
插槽中;最後調用FT_Render_Glyph(face-> glyph, render_mode)
,將其轉換爲位圖。 - 直接調用
FT_Load_Char(face,text [n],FT_LOAD_RENDER)
,來替代上面的過程。
7.簡單的文本渲染
可以採用如下方式;
- 設置旋轉角度:
angle = ( 0.0 / 360 ) * 3.14159 * 2
,0.0代表旋轉0度,可以按照自己要求設置 - 設置矩陣(用來旋轉字體的時候用):
matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L );
matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L );
matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L );
matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L );
- 設置字符原點
注意:此時在FreeType中使用的是笛卡爾座標,而我們LCD中顯示的座標與轉換原理如下:
pen.x = 300 * 64;
pen.y = ( target_height - 200 ) * 64;
- 在循環中執行設置轉換參數、渲染文本、存儲文本點陣信息
for ( n = 0; n < num_chars; n++ )
{
/* 設置轉換參數 */
/* set transformation */
FT_Set_Transform( face, &matrix, &pen );
/* FT_Load_Char == FT_Load_Glyph、FT_Get_Load_Char、FT_Get_Char_Index
* FT_LOAD_RENDER : 渲染 Glyph圖像立刻變爲位圖
*/
/* 得到字符點陣 */
/* load glyph image into the slot (erase previous one) */
error = FT_Load_Char( face, text[n], FT_LOAD_RENDER );
if ( error )
continue; /* ignore errors */
/* 存儲點陣信息 */
/* now, draw to our target surface (convert position) */
draw_bitmap( &slot->bitmap,
slot->bitmap_left, /* 笛卡爾座標的x */
target_height - slot->bitmap_top /* 笛卡爾座標的y */);
/* increment pen position */
pen.x += slot->advance.x;
pen.y += slot->advance.y;
}