矢量字体的使用不同于点阵字体,在矢量字体文件中存放的是字符的轮廓(字符关键点的相对位置),通常也称为 glyph,取得这些关键点后需要用某些数学函数将其描出。这对于普通用户的应用来说比较难,而 FreeType 库正好帮我们解决了这些问题。FreeType 库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括 TrueType、OpenType、 Type1、CID、CFF、Windows FON/FNT、X11 PCF 等。支持单色位图、反走样位图的渲染。
测试 FreeType 库(下述程序只是大致流程示意,并非最终代码):
/* 参考 freetype 库中例子程序 example.c */
void main(int argc, char *argv[])
{
FT_Library library; /* handle to library */
FT_Face face; /* handle to face object */
FT_GlyphSlot slot; /* glyph 插槽 */
FT_Vector pen;
int err;
if (argc != 2)
{
printf("Usage : %s \n", argv[0]);
return -1;
}
err = FT_Init_FreeType(&library); /* 初始化 FreeType 库 */
if(err)
{
printf("FT_Init_FreeType failed\n");
return -1;
}
err = FT_New_Face(library, font_name, 0, &face);
if(err)
{
printf("FT_New_Face failed\n");
return -1;
}
slot = face->glyph;
err = FT_Set_Pixel_Sizes(face, 24, 0); /* 设置字体大小 */
if(err)
{
printf("FT_Set_Pixel_Sizes failed\n");
return -1;
}
pen.x = 100 * 64; /* 26.6 pixel 即 1/64 pixel */
pen.y = 100 * 64;
FT_Set_Transform(face, 0, &pen); /* 位置转换 */
err = FT_Load_Char(face, code, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
if(err)
{
printf("FT_Load_Char failed\n");
return -1;
}
pen.x += slot->advance.x; /* 调整画笔 */
pen.y += slot->advance.y;
/* 将得到的位图在 LCD 上描画…… */
return 0;
}
FT_Set_Transform() 函数用来设置旋转和平移,如果未调用则认为原点为 (0, 0),slot(即 face->glyph)中的成员变量 bitmap_left 和 bitmap_top 的值都是基于该原点的相对偏移。该函数主要用于旋转字体时计算字符之间的距离,调用该函数后每显示一个字符,系统会自动将下一个字符的间距存入 slot->advance.x 和 slot->advance.y 中。
FT_Load_Char() 加载指定字符,该字符的 Unicode 码由 code 参数传入,FT_LOAD_RENDER 表示得到字符的 glyph 后直接渲染成位图(转结果存在 slot->bitmap),FT_LOAD_MONOCHROME 表示转换成单色位图。
当显示多行文字的时候,通常需要使用 FT_Glyph_Get_CBox() 函数来计算字符的最大间距。
FT_Glyph_Get_CBox( glyph, bbox_mode, &bbox );
width = bbox.xMax - bbox.xMin;
height = bbox.yMax - bbox.yMin;
下图中的所有坐标都是基于原点。
在 freetype 文档中经常会看到 26.6 pixel format,它是一种用定点来表示浮点的方法,32 位的整数低六位表示小数,因此忽略小数时应除以 2^6=64。
——忠于梦想 勇于实践 linux_xpj@opencores.org
阅读(4342) | 评论(1) | 转发(0) |