FreeType编译与使用
FreeType是一款免费用于渲染字体的开源库。
在使用该类库时,最好先过一遍官方文档,其中FreeType Glyph Conventions部分的文章必读。
编译
我们可以进入下载界面,点击任意一个地址下载源码。
这里笔者使用的是2.13.2版本,解压后会获得一个freetype-2.13.2文件夹。 进入目录freetype-2.13.2\builds\windows\vc2010
,然后点击freetype.sln即可打开工程。
编译后进入freetype-2.13.2\objs\x64\Release
可以获得freetype.dll以及 freetype.lib。
使用
静态链接Freetype
新建一个C++工程。将freetype.lib复制到工程目录下,接着右键工程->属性->VC++目录->头文件目录。这里添加freetype-2.13.2\include
目录。(如果编译的是Debug,那么配置也需要是Debug。Release同理),复制freetype.lib
文件到工程目录下面,并且对main函数所在代码添加#pragma comment(lib, "freetype.lib")
指令。
然后复制#include <ft2build.h> #include FT_FREETYPE_H
到main函数所在的代码。如果编译通过,表示工程已经正确加载freetype库。
渲染准备
在渲染字体之前,我们首先需要声明一个FT_Library类型的变量library ,然后对其调用FT_Init_FreeType初始化一下FreeType。FT_Init_FreeType( &library )
。
然后通过调用FT_New_Face函数初始化FT_Face类型的对象,这样我们就加载了对应的字体文件。
在渲染之前,我们还需要指定字体或者像素的大小。这里我们选择FT_Set_Pixel_Sizes
函数直接设置像素的大小。
FT_Library library; /* handle to library */
FT_Face face; /* handle to face object */
error = FT_Init_FreeType( &library );
error = FT_New_Face( library,"/usr/share/fonts/truetype/arial.ttf", 0, &face );
error = FT_Set_Pixel_Sizes(face, 0, 24); //0表示宽度和长度一样
渲染文字
最后在渲染之前我们需要设置需要渲染的字符的编码,默认编码是Unicode。
我们选择“中"这个字符来渲染,他的编码是0x4E2D,我们可以通过编码网站来查询对应字符的编码。
得到编码之后,我们需要将调用FT_Get_Char_Index
将字符编码转化为字符图形的索引glyph_index = FT_Get_Char_Index( face, charcode );
获得索引后,我们就可以调用FT_Load_Glyph
将字符图形(glyph image)加载到face->glyph中。这个字符图形可以是点阵图,轮廓线或者其他格式。
加载图形后,我们可以通过face−>glyph−>format
查看图片的格式,如果它不是FT_GLYPH_FORMAT_BITMAP
点阵图,那么我们可以接着通过FT_Render_Glyph
函数将其转化为点阵图。
详细过程可以查看FreeType获取字符图形
int charcode = 0x4E2D;
auto glyph_index = FT_Get_Char_Index(face, charcode);
int load_flags = FT_LOAD_DEFAULT;
error = FT_Load_Glyph(
face, /* handle to face object */
glyph_index, /* glyph index */
load_flags); /* load flags, see below */
FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
error = FT_Render_Glyph(face->glyph, /* glyph slot */
render_mode); /* render mode */
这个时候我们就已经获得了点阵图,可以通过face->glyph->bitmap获取,并且通过ConsoleRenderGlyph
函数将其输出到控制台。具体代码看下面的完整代码小节。
完整代码
#include <iostream>
#include <ft2build.h>
#include FT_FREETYPE_H
#pragma comment(lib, "freetype.lib")
FT_Library library; /* handle to library */
FT_Face face; /* handle to face object */
void ConsoleRenderGlyph(FT_GlyphSlot slot)
{
for (int y = 0; y < slot->bitmap.rows; ++y)
{
for (int x = 0; x < slot->bitmap.width; ++x)
putchar(" .:ioVM@"[slot->bitmap.buffer[y * slot->bitmap.width + x] >> 5]);
putchar('\n');
}
}
int main()
{
auto error = FT_Init_FreeType(&library);
error = FT_New_Face(library,"simsun.ttc", 0, &face);
error = FT_Set_Pixel_Sizes(face, 0, 24);
int charcode = 0x4E2D;
auto glyph_index = FT_Get_Char_Index(face, charcode);
int load_flags = FT_LOAD_DEFAULT;
error = FT_Load_Glyph(
face, /* handle to face object */
glyph_index, /* glyph index */
load_flags); /* load flags, see below */
FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
error = FT_Render_Glyph(face->glyph, /* glyph slot */
render_mode); /* render mode */
ConsoleRenderGlyph(face->glyph);
//std::cout << "Hello World!\n";
}
其他
字体对象
FT_Face face是 FT_FaceRec的句柄,一个字体对象存储了这个字体的全部全局信息。比如,我们可以通过face->num_glyphs获取该字体有几个字符图形。