C/C++ 利用FreeType提取字体文件的字形

10 篇文章 0 订阅

一 前言

该项目主要是利用freetype来提取字体文件的字形,得到outline,再利用FT_Outline_Decompose函数得到svg可以使用的path值。

二 介绍

FreeType2库是一个完全免费(开源)的、高质量的且可移植的字体引擎,它提供统一的接口来访问多种字体格式文件,包括TrueTypeOpenType, Type1, CID, CFF, Windows FON/FNT, X11 PCF等。

下载地址:freetype-2.10.4.tar.xz

三 效果图

四 编译FreeType库

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。

五 配置FreeType库

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项目就配置完成了。

六 使用FreeType库

1)freetype头文件

#include <ft2build.h>
#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;

FreeType-2.4.10 API Reference

参考博文

vs中c++添加lib库和头文件(外部依赖项)

freetype库实现文字显示

使用freetype提取字形

项目下载

convertFonts.rar

 

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
这份文档提供了FreeType 2函数库设计与实现的细节。本文档的目标是让开发人员更好的理解FreeType 2是如何组织的,并让他们扩充、定制和调试它。 首先,我们先了解这个库的目的,也就是说,为什么会写这个库: * 它让客户应用程序方便的访问字体文件,无论字体文件存储在哪里,并且与字体格式无关。 * 方便的提取全局字体数据,这些数据在平常的字体格式中普遍存在。(例如:全局度量标准,字符编码/字符映射表,等等) * 方便的提取某个字符的字形数据(度量标准,图像,名字,其他任何东西) * 访问字体格式特定的功能(例如,SFNT表,多重控制,OpenType轮廓表) Freetype 2的设计也受如下要求很大的影响: * 高可移植性。这个库必须可以运行在任何环境中。这个要求引入了一些非常激烈的选择,这些是FreeType2的低级系统界面的一部分。 * 可扩展性。新特性应该可以在极少改动库基础代码的前提下添加。这个要求引入了非常简单的设计:几乎所有操作都是以模块的形式提供的。 * 可定制。它应该能够很容易建立一个只包含某个特定项目所需的特性的版本。当你需要集成它到一个嵌入式图形库的字体服务器中时,这是非常重要的。 * 简洁高效。这个库的主要目标是只有很少cpu和内存资源的嵌入式系统。 这份文档的其他部分分为几个部分。首先,一些章节介绍了库的基本设计以及Freetype 2内部对象/数据的管理。 接下来的章节专注于库的定制和与这个话题相关的系统特定的界面,如何写你自己的模块和如何按需裁减库初始化和编译。
首先,谢谢你提供的信息。根据提供的内容,我能理解你正在描述一个关于构建一个目标为'/home/book/nfs_rootfs/10_freetype/freetype-2.10.2/objs/l'的配方或步骤。 要构建目标为'/home/book/nfs_rootfs/10_freetype/freetype-2.10.2/objs/l'的配方,你可以按照以下步骤进行操作: 1. 首先,确保你的操作系统中安装了所需的开发工具和依赖项。这些工具可能包括编译器、构建工具(如make)、库文件等。可以通过使用适当的包管理器来安装这些工具和依赖项。 2. 下载或获取freetype-2.10.2源代码的压缩包。你可以从官方网站或源代码存储库中获取。 3. 解压源代码压缩包,并进入解压后的目录。 4. 在源代码目录中查找一个名为'objs/l'的目录。确保该目录存在并为空。 5. 接下来,你可以根据特定的构建系统和编译器来选择合适的构建命令。常见的构建命令包括'make'和'cmake'。使用适当的命令,以能够生成目标为'/home/book/nfs_rootfs/10_freetype/freetype-2.10.2/objs/l'的目标文件。 6. 在构建过程中,如果遇到错误或警告信息,请根据提示进行适当的调整或修复。这可能包括安装缺少的依赖项、更新构建脚本或相关文件等。 7. 当构建成功完成后,确认'/home/book/nfs_rootfs/10_freetype/freetype-2.10.2/objs/l'目录中生成了预期的构建目标或文件。 这些步骤提供了一般的构建配方,以创建目标为'/home/book/nfs_rootfs/10_freetype/freetype-2.10.2/objs/l'的构建文件。但具体的步骤可能因操作系统、编译器和构建系统的差异而有所不同。可以根据具体的环境和要求进行适当的调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值