FreeType矢量字符库的介绍、交叉编译以及安装
FreeType矢量字符库的介绍
FreeType 是一个开源的跨平台字体引擎库,广泛用于 Linux 嵌入式系统中实现字符显示的功能。它提供了高效的 TrueType、OpenType 和其他字体格式的解析和渲染功能,在嵌入式开发中尤其适合用来绘制矢量字体和位图字体。
FreeType 的特点
-
多字体格式支持:
- 支持 TrueType (TTF)、OpenType (OTF)、PostScript 字体等主流字体格式。
- 可解析嵌入式字体文件或通过文件系统加载字体。
-
高可移植性:
- FreeType 是纯 C 实现,可以轻松移植到各种嵌入式平台。
-
轻量级:
- 设计简洁,适用于资源受限的嵌入式设备。
-
渲染能力强:
- 支持矢量字体的抗锯齿渲染。
- 支持位图字体的缩放和变形。
- 提供字形的详细轮廓信息,可用于高级排版需求。
使用 FreeType 的流程
FreeType 的基本用法分为以下几个步骤:
-
初始化 FreeType 库:
使用FT_Init_FreeType()
函数创建并初始化库对象。 -
加载字体:
使用FT_New_Face()
加载字体文件,创建一个字体 face 对象。 -
设置字体大小:
调用FT_Set_Pixel_Sizes()
或FT_Set_Char_Size()
设置字符的像素大小。 -
加载字符字形:
使用FT_Load_Char()
加载单个字符,并获取它的字形信息。 -
渲染字形:
调用FT_Render_Glyph()
将字形转换为位图数据,随后可以将位图数据绘制到显示设备。 -
释放资源:
释放 face 和库对象。
示例代码
以下是一个简单的使用 FreeType 渲染字符的示例代码:
#include <ft2build.h>
#include FT_FREETYPE_H
void render_text(const char *font_path, const char *text, int font_size) {
FT_Library library;
FT_Face face;
// 初始化 FreeType 库
if (FT_Init_FreeType(&library)) {
printf("Could not initialize FreeType library\n");
return;
}
// 加载字体
if (FT_New_Face(library, font_path, 0, &face)) {
printf("Could not load font\n");
FT_Done_FreeType(library);
return;
}
// 设置字体大小
FT_Set_Pixel_Sizes(face, 0, font_size);
// 遍历渲染每个字符
for (const char *p = text; *p; p++) {
if (FT_Load_Char(face, *p, FT_LOAD_RENDER)) {
printf("Could not load character '%c'\n", *p);
continue;
}
// 获取字形位图
FT_GlyphSlot slot = face->glyph;
FT_Bitmap bitmap = slot->bitmap;
// 处理 bitmap 数据(例如绘制到屏幕)
printf("Rendered character '%c' with width %d and height %d\n",
*p, bitmap.width, bitmap.rows);
}
// 释放资源
FT_Done_Face(face);
FT_Done_FreeType(library);
}
嵌入式开发中的注意事项
-
字体资源的管理:
- 嵌入式设备通常存储空间有限,应选择合适的字体文件(例如简化版的 TTF 文件)。
- 可以将字体文件存储在只读文件系统或嵌入程序中。
-
字符渲染的性能优化:
- 避免频繁加载字体文件。
- 可预渲染常用字符到缓存中以减少实时渲染的开销。
-
显示设备适配:
- FreeType 输出的是字形的位图数据,需要结合显示设备的驱动将其绘制到屏幕上。
-
国际化支持:
- FreeType 提供 Unicode 支持,可以方便地显示多语言文本。
- 开发时需注意字符编码的转换。
FreeType的交叉编译
01-确认交叉编译器gcc中有zlib库和libpng库
freetype 依赖于 libpng,libpng 又依赖于 zlib,所以我们应该:先编译
安装 zlib,再编译安装 libpng,最后编译安装 freetype。
但是,有些交叉编译器工具链里已经有 zlib库和freetype,所以我们需要确认下我们的gcc编译器工具链中有没有zlib库和libpng库,怎么看呢?
看交叉编译器工具链里有没有zlib库和libpng库的方法见下面这篇博文:
https://blog.csdn.net/wenhao_ir/article/details/144752237
确认有zlib库和libpng库后方可进行下面的操作。
如果没有zlib库和libpng库,则两个库的源码如下:
zlib库的源码下载链接:
https://pan.baidu.com/s/1Mn7AZZbXGJm-ajK04-zK3w?pwd=cmkv
libpng库的源码下载链接:
https://pan.baidu.com/s/10MG29Bw1-H88NkKlc-Aydw?pwd=kgbu
02-源码下载并解压
freetype-2.10.2源码下载地址:
https://pan.baidu.com/s/1rcAnUxwmugiMrNuR4UDsCg?pwd=hr5u
源码下载好后放到目录/home/book/usedlib
下
然后解压:
说明:以下编译、配置、安装过程参考我的另一篇博文:
tslib(触摸屏输入设备的轻量级库)的学习、编译及测试记录
03-编译配置(生成Makefile文件)
cd /home/book/usedlib/freetype-2.10.2
./configure --host=arm-buildroot-linux-gnueabihf --prefix=/
04-make及make install
首先确认交叉编译器gcc中有zlib库和libpng库
freetype 依赖于 libpng,libpng 又依赖于 zlib,所以我们应该:先编译
安装 zlib,再编译安装 libpng,最后编译安装 freetype。
但是,有些交叉编译器工具链里已经有 zlib库和freetype,所以我们需要确认下我们的gcc编译器工具链中有没有zlib库和libpng库,怎么看呢?
看交叉编译器工具链里有没有zlib库和libpng库的方法见下面这篇博文:
https://blog.csdn.net/wenhao_ir/article/details/144752237
确认有zlib库和libpng库后方可进行make的操作。
如果没有zlib库和libpng库,则两个库的源码如下:
zlib库的源码下载链接:
https://pan.baidu.com/s/1Mn7AZZbXGJm-ajK04-zK3w?pwd=cmkv
libpng库的源码下载链接:
https://pan.baidu.com/s/10MG29Bw1-H88NkKlc-Aydw?pwd=kgbu
确认有zlib库和libpng库后方可进行make的操作。
make
然后 make install
make install DESTDIR=$PWD/tmp
05-检查生成的动态库文件是否是运行于目标架构之上的
完成之后首先用readelf
命令检查下生成的so动态库文件是否是运行于ARM架构的,有时候我们在编译配置阶段提供的gcc编译前缀是错的,但此种情况下系统make时不会报错,而会去用系统默认的编译器。
cd /home/book/usedlib/freetype-2.10.2/tmp/lib
readelf -h /home/book/usedlib/freetype-2.10.2/tmp/lib/libfreetype.so
运行结果如下:
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: ARM
Version: 0x1
Entry point address: 0x6c60
Start of program headers: 52 (bytes into file)
Start of section headers: 2719560 (bytes into file)
Flags: 0x5000400, Version5 EABI, hard-float ABI
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 5
Size of section headers: 40 (bytes)
Number of section headers: 35
Section header string table index: 34
从结果截图可以清晰看出这个ELF的动态库文件是32位还是64位,并且还是运行于ARM架构上的动态库文件。
06-把头文件和库文件放到gcc交叉编译器能扫描到的位置
头文件放到指定目录
/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include
命令如下:
cp -rd /home/book/usedlib/freetype-2.10.2/tmp/include/freetype2 /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include/
库文件放到指定目录
在这里,我们把它复制到目录/usr/local/lib中,并重命为freetypelib,这样编译器编译别的工程时就能用到这个库了,这里得能命令复制,因为目录/usr/local/lib不是能随便写文件的,运行下面的命令:
sudo cp -rfd /home/book/usedlib/freetype-2.10.2/tmp/lib /usr/local/lib/freetypelib
这样就完成了库文件的放置。