第三阶段应用层——1.4 数码相册—FreeType介绍

数码相册——FreeType介绍


一、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
    通过查看官方文档可以知道:
    高度和宽度的单位是 1 64 \frac{1}{64} point,1 point = 1 72 =\frac{1}{72} inch,分辨率的单位是dpi——每英寸点数

    1 单位的高度或宽度 = 1 64 =\frac{1}{64} point,1 point = 1 72 =\frac{1}{72} inch,1 单位分辨率 = 1 d p i =1 d p i
    所以
    1 单位的高度或宽度的物理长度 = 1 64 72 =\frac{1}{64*72} inch

    x单位的高度或宽度,y单位分辨率,其字符高度的像素为
    = x ( 1 64 1 72 ) =\mathrm{x}^{*}\left(\frac{1}{64} * \frac{1}{72}\right) inch y d p i = x y 6 4 72 * \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;
	}

猜你喜欢

转载自blog.csdn.net/weixin_42813232/article/details/106956031