第三階段應用層——1.4 數碼相冊—FreeType介紹

數碼相冊——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
    通過查看官方文檔可以知道:
    高度和寬度的單位是 164\frac{1}{64} point,1 point =172=\frac{1}{72} inch,分辨率的單位是dpi——每英寸點數

    1 單位的高度或寬度 =164=\frac{1}{64} point,1 point =172=\frac{1}{72} inch,1 單位分辨率 =1dpi=1 d p i
    所以
    1 單位的高度或寬度的物理長度 =16472=\frac{1}{64*72} inch

    x單位的高度或寬度,y單位分辨率,其字符高度的像素爲
    =x(164172)=\mathrm{x}^{*}\left(\frac{1}{64} * \frac{1}{72}\right) inch ydpi=xy6472* \mathrm{y} d p i=\frac{\mathrm{x}^{*} \mathrm{y}}{64^{*} 72} 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.加載字形圖像

這裏有兩種方法:

  1. 先調用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),將其轉換爲位圖
  2. 直接調用FT_Load_Char(face,text [n],FT_LOAD_RENDER),來替代上面的過程

7.簡單的文本渲染

可以採用如下方式;

  1. 設置旋轉角度angle = ( 0.0 / 360 ) * 3.14159 * 2,0.0代表旋轉0度,可以按照自己要求設置
  2. 設置矩陣(用來旋轉字體的時候用)
	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 );
  1. 設置字符原點
    注意:此時在FreeType中使用的是笛卡爾座標,而我們LCD中顯示的座標與轉換原理如下
    在這裏插入圖片描述
	pen.x = 300 * 64;
	pen.y = ( target_height - 200 ) * 64;
  1. 在循環中執行設置轉換參數、渲染文本、存儲文本點陣信息
	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;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章