该项目主要是利用freetype来提取字体文件的字形,得到outline,再利用FT_Outline_Decompose函数得到svg可以使用的path值。
FreeType2库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueType, OpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。
下载地址:freetype-2.10.4.tar.xz
1)解压freetype-2.10.4.tar.xz
2)在目录\freetype-2.10.4\builds\windows\vc2010中找到vs工程
3)使用VS2010编译该项目,可以得到两个文件freetype.lib,freetype.dll
编译时可能会出现以下问题:
error MSB8008: 指定的平台工具集({0})未安装或无效。请确保选择受支持的 PlatformToolset 值。
但是按照网上的办法无法找到配置属性中的平台工具集,这时候关掉该项目,再重新打开一次,随便选中cff.c,接着:
项目(P)->freetype属性(P)->配置属性->常规->平台工具集,下拉框选中“V100”,点击应用,确定,再次编译。在\freetype-2.10.4\objs\Win32\Debug中找到两个文件freetype.lib,freetype.dll。
1)首先找到之前下载FreeType库中的文件夹include
2)新建一个vs项目
3)将FreeType库中的文件夹include和装有freetype.lib和freetype.dll两个文件的lib文件夹放到新建vs的工程项目中(lib文件夹是自己新建的)
4)VS项目添加外部依赖
1. 添加工程的头文件目录:工程---属性---配置属性---c/c++---常规---附加包含目录:加上头文件存放目录。
2. 添加文件引用的lib静态库路径:工程---属性---配置属性---链接器---常规---附加库目录:加上lib文件存放目录。
3. 然后添加工程引用的lib文件名:工程---属性---配置属性---链接器---输入---附加依赖项:加上lib文件名。
4. 添加工程引用的dll动态库: 工程---属性---配置属性---调试---环境,格式为 PATH=dll所在目录
这样,FreeType项目就配置完成了。
1)freetype头文件
#include
#include FT_FREETYPE_H
typedef unsigned short WORD;
FT_Face face = NULL;
float scale = 0.015625;//本身得到的path所显示的字符挺大的,所以乘以1/64
2)初始化库
FT_Library library = NULL;
FT_Error error = 0;
FT_Glyph glyph;
FT_Matrix matrix;
FT_Vector delta;
const FT_Fixed multiplier = 65536L;
//1.初始化一个freetype库
error = FT_Init_FreeType(&library);
if(error){
library = 0;
printf("There is some error when init library\n");
return -1;
}
3)加载字体样式
error = FT_New_Face(library, "xxx/TestFont5/TestFont5/fonts/MicrosoftYaHei-Bold.cff", 0, &face);
if (error==FT_Err_Unknown_File_Format)
{
printf("FT_New_Face: Unknown format\n");
return -1;
}else if(error){
printf("Open font failed\n");
return -1;
}
4)设置字体大小
error = FT_Set_Pixel_Sizes(face,25,0);//像素
5)设置字体的显示方向和原点
//4.翻转字体,设置原点
matrix.xx = 1L * multiplier;;
matrix.xy = 0L * multiplier;
matrix.yx = 0L * multiplier;
matrix.yy = -1L * multiplier;
delta.x = 0;
delta.y = 1100;
FT_Set_Transform(face,&matrix,&delta);
注意:字体文件中的Y轴正方向和我们要绘制的Y轴正方向相反,所以这里需要翻转一下
6)添加要显示字形的字符
wchar_t *wszString = L"版";
WORD word;
int wszStringLen = wcslen(wszString);
printf("wszStringLen: %d\n",wszStringLen);
memcpy(&word, wszString, 2);
7)通过索引,从face中加载字形
FT_Load_Glyph(face, FT_Get_Char_Index(face,word), FT_LOAD_DEFAULT|FT_LOAD_NO_BITMAP);
8)将字形图像存到glyph变量里
error = FT_Get_Glyph(face->glyph, &glyph);
9)解析字形到Path,从truetype字体文件中提取出贝塞尔曲线
ExtractOutline();
void ExtractOutline(){
FT_Outline_Funcs callbacks;
callbacks.move_to = moveto;
callbacks.line_to = lineto;
callbacks.conic_to = conicto;
callbacks.cubic_to = cubicto;
callbacks.shift = 0;
callbacks.delta = 0;
FT_GlyphSlot slot = face->glyph;
FT_Outline &outline = slot->outline;
FT_Error error = FT_Outline_Decompose(&outline, &callbacks, &ExtractOutline);
if (error)
{
printf("不可以提取轮廓");
}
}
int moveto(const FT_Vector* to, void* user){
printf("M%.2f %.2f", (to->x)*scale, (to->y)*scale);
return 0;
}
int lineto(const FT_Vector* to, void* user){
printf("L%.2f %.2f", (to->x)*scale, (to->y)*scale);
return 0 ;
}
int conicto(const FT_Vector* control, const FT_Vector* to,void* user){
printf("Q%.2f %.2f %.2f %.2f", control->x*scale, control->y*scale, (to->x)*scale, (to->y)*scale);
return 0;
}
int cubicto(const FT_Vector* control1,const FT_Vector* control2, const FT_Vector* to,void* user){
printf("C%.2f %.2f %.2f %.2f %.2f %.2f", control1->x*scale, control1->y*scale, control2->x*scale, control2->y*scale ,(to->x)*scale, (to->y)*scale);
return 0;
}
10)释放内存
// free glyph
FT_Done_Glyph(glyph);
glyph = NULL;
// free face
FT_Done_Face(face);
face = NULL;
// free FreeType Lib
FT_Done_FreeType(library);
library = NULL;
vs中c++添加lib库和头文件(外部依赖项)
freetype库实现文字显示
使用freetype提取字形
convertFonts.rar