FreeType矢量字符库的介绍、交叉编译以及安装

ops/2024/12/28 11:17:58/

FreeType矢量字符库的介绍

FreeType 是一个开源的跨平台字体引擎库,广泛用于 Linux 嵌入式系统中实现字符显示的功能。它提供了高效的 TrueType、OpenType 和其他字体格式的解析和渲染功能,在嵌入式开发中尤其适合用来绘制矢量字体和位图字体。

FreeType 的特点

  1. 多字体格式支持

    • 支持 TrueType (TTF)、OpenType (OTF)、PostScript 字体等主流字体格式。
    • 可解析嵌入式字体文件或通过文件系统加载字体。
  2. 高可移植性

    • FreeType 是纯 C 实现,可以轻松移植到各种嵌入式平台。
  3. 轻量级

    • 设计简洁,适用于资源受限的嵌入式设备。
  4. 渲染能力强

    • 支持矢量字体的抗锯齿渲染。
    • 支持位图字体的缩放和变形。
    • 提供字形的详细轮廓信息,可用于高级排版需求。

使用 FreeType 的流程

FreeType 的基本用法分为以下几个步骤:

  1. 初始化 FreeType 库
    使用 FT_Init_FreeType() 函数创建并初始化库对象。

  2. 加载字体
    使用 FT_New_Face() 加载字体文件,创建一个字体 face 对象。

  3. 设置字体大小
    调用 FT_Set_Pixel_Sizes()FT_Set_Char_Size() 设置字符的像素大小。

  4. 加载字符字形
    使用 FT_Load_Char() 加载单个字符,并获取它的字形信息。

  5. 渲染字形
    调用 FT_Render_Glyph() 将字形转换为位图数据,随后可以将位图数据绘制到显示设备。

  6. 释放资源
    释放 face 和库对象。


示例代码

以下是一个简单的使用 FreeType 渲染字符的示例代码:

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

嵌入式开发中的注意事项

  1. 字体资源的管理

    • 嵌入式设备通常存储空间有限,应选择合适的字体文件(例如简化版的 TTF 文件)。
    • 可以将字体文件存储在只读文件系统或嵌入程序中。
  2. 字符渲染的性能优化

    • 避免频繁加载字体文件。
    • 可预渲染常用字符到缓存中以减少实时渲染的开销。
  3. 显示设备适配

    • FreeType 输出的是字形的位图数据,需要结合显示设备的驱动将其绘制到屏幕上。
  4. 国际化支持

    • 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:                             ELF32Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              DYN (Shared object file)Machine:                           ARMVersion:                           0x1Entry point address:               0x6c60Start of program headers:          52 (bytes into file)Start of section headers:          2719560 (bytes into file)Flags:                             0x5000400, Version5 EABI, hard-float ABISize of this header:               52 (bytes)Size of program headers:           32 (bytes)Number of program headers:         5Size of section headers:           40 (bytes)Number of section headers:         35Section 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

在这里插入图片描述
这样就完成了库文件的放置。


http://www.ppmy.cn/ops/145639.html

相关文章

全面Kafka监控方案:从配置到指标

文章目录 1.1.监控配置1.2.监控工具1.3.性能指标系统相关指标GC相关指标JVM相关指标Topic相关指标Broker相关指标 1.4.性能指标说明1.5.重要指标说明 1.1.监控配置 开启JMX服务端口&#xff1a;kafka基本分为broker、producer、consumer三个子项&#xff0c;每一项的启动都需要…

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 这两个条件之间的区别

文章目录 1、什么是空字符串&#xff1f;2、两个引号之间加上空格 好的&#xff0c;我们来详细解释一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 这两个条件之间的区别&#xff0c;以及它们在 SQL 查询中的作用&#xff1a; 1. we_chat_union_id IS NOT NULL 含…

计算机的错误计算(一百九十三)

摘要 用两个大模型化简计算 其中有关数字取弧度&#xff0c;结果保留5位有效数字。一个大模型进行了一次化简&#xff0c;另外一个大模型没有化简。两个大模型​​​​​均给出错误结果。 例1. 化简计算 其中有关数字取弧度&#xff0c;结果保留5位有效数字。 下面是与一个…

es6 字符串每隔几个中间插入一个逗号

const insertCommaEveryNChars (str, n) > {// 将字符串转换为数组&#xff0c;以便我们可以更容易地操作每个字符const chars str.split();// 使用map遍历数组&#xff0c;并在每隔n个字符后插入逗号const result chars.map((char, index) > {// 检查当前位置是否是n…

网络安全等级自我评价

大家查看之后觉得有意义及帮助记得关注加点赞&#xff01;&#xff01;&#xff01; 很多人觉得网络安全很模糊&#xff0c;很多从事网络安全的同僚&#xff0c;觉得网络安全很杂、自己也不知道自己到底处在哪一阶层&#xff0c;我通过百度、行业了解整理、专业人士的沟通和探…

4-Gin HTML 模板渲染 --[Gin 框架入门精讲与实战案例]

HTML 模板渲染 下面是使用 Gin 框架在 Go 语言中进行 HTML 模板渲染的四个示例。每个示例都包含了必要的注释来解释代码的作用。 示例1&#xff1a;基本模板渲染 package mainimport ("github.com/gin-gonic/gin""net/http" )func main() {r : gin.Defa…

CUDA基础编程:开启深度学习 GPU 加速之门

文章结尾有最新热度的文章,感兴趣的可以去看看。 本文是经过严格查阅相关权威文献和资料,形成的专业的可靠的内容。全文数据都有据可依,可回溯。特别申明:数据和资料已获得授权。本文内容,不涉及任何偏颇观点,用中立态度客观事实描述事情本身 文章有点长(字),期望您能坚…

TCP/IP原理

TCP/IP 是互联⽹的基础&#xff0c;其中 TCP 和 IP 是两个主要的协议。以下是它们的基本原理以及 TCP 的状态。 TCP/IP 原理&#xff1a; 1. IP (Internet Protocol): 它是⼀个⽹络层协议&#xff0c;负责将数据报⽂从源地址发送到⽬标地址。它不保证数 据报⽂的有序到达或完…