news 2026/5/5 22:27:54

LVGL-02 本地字库添加和加载操作指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LVGL-02 本地字库添加和加载操作指南

LVGL 本地字库添加和加载操作指南

前言

该文章目的是为了记录,为上一篇搭建的工程项目中,增加中文字体的支持,使用字库文件。
在嵌入式或图形界面开发中,LVGL(Light and Versatile Graphics Library)因其轻量化和跨平台特性被广泛应用。当项目需要支持多语言(尤其是中文)时,本地字库的加载成为关键需求。本指南详细介绍了如何在LVGL工程中集成和管理本地字库文件(如.ttf或.otf格式),包括配置宏开关、文件系统初始化、字体缓存优化及动态加载的实现方法。
该文章是在上篇文章,工程目录搭建的基础上继续的。

一、LVGL SDK 需要开启的宏开关

lvgl_sdk/include/lv_conf.h中需要开启以下宏:

1. 启用 Tiny_TTF 支持

#defineLV_USE_TINY_TTF1

2. 启用 Tiny_TTF 文件支持(从文件加载字体)

#ifLV_USE_TINY_TTF#defineLV_TINY_TTF_FILE_SUPPORT1#defineLV_TINY_TTF_CACHE_GLYPH_CNT128// 字形缓存数量#defineLV_TINY_TTF_CACHE_KERNING_CNT256// 字距缓存数量#endif

3. 启用 POSIX 文件系统驱动(Tiny_TTF 需要文件系统支持)

#defineLV_USE_FS_POSIX1#ifLV_USE_FS_POSIX#defineLV_FS_POSIX_LETTER'A'// 驱动字母标识符#defineLV_FS_POSIX_PATH""// 工作目录(空表示使用绝对路径)#defineLV_FS_POSIX_CACHE_SIZE0// 缓存大小#endif

总结:需要开启LV_USE_TINY_TTFLV_TINY_TTF_FILE_SUPPORTLV_USE_FS_POSIX三个宏。


二、文件结构

my_app/ ├── res/ │ ├── res_conf.h # 资源路径配置 │ └── font/ │ ├── font_conf.h # 字体配置文件 │ ├── font_utils.h # 字体工具函数头文件 │ ├── font_utils.c # 字体工具函数实现 │ └── *.otf / *.OTF # 字体文件(如 SOURCEHANSANSCN_REGULAR.OTF) └── main.c # 主程序

三、配置文件说明

1.res/res_conf.h- 资源路径配置

#ifndefPROJECT_RES_URL#definePROJECT_RES_URL"./res/"// 资源文件路径(相对于可执行文件)#endif#defineFONT_PATHPROJECT_RES_URL"font/"// 字体文件路径

2.res/font/font_conf.h- 字体配置

// 定义字体类型枚举typedefenum{FONT_TYPE_CN=0,// 中文字体FONT_TYPE_CN_LIGHT,// 细体中文字体FONT_TYPE_LETTER,// 字母字体FONT_TYPE_LETTER_LIGHT,// 细体字母字体FONT_TYPE_NUMBER,// 数字字体}FONT_TYPE;// 定义各类型字体的文件路径#defineFONT_TYPE_CN_PATHFONT_PATH"SOURCEHANSANSCN_REGULAR.OTF"#defineFONT_TYPE_CN_LIGHT_PATHFONT_PATH"SOURCEHANSANSCN_LIGHT.OTF"// ... 其他字体路径// 字体初始化宏#defineFONT_INIT()\do{\add_font(FONT_TYPE_CN,FONT_TYPE_CN_PATH);\add_font(FONT_TYPE_CN_LIGHT,FONT_TYPE_CN_LIGHT_PATH);\// ... 添加其他字体}while(0)

四、使用流程

步骤 1:初始化 LVGL 和文件系统

main.c的初始化函数中:

voidapp_init(void){lv_init();// 初始化 LVGL#ifLV_USE_FS_POSIXlv_fs_posix_init();// 初始化 POSIX 文件系统驱动(重要!)#endifFONT_INIT();// 初始化字体(注册字体路径)lv_port_disp_init();lv_port_indev_init();}

关键点:

  • lv_fs_posix_init()必须在FONT_INIT()之前调用
  • 这是 Tiny_TTF 能够读取字体文件的前提

步骤 2:使用字体

在创建 UI 元素时:

voidlv_example_hello_world(void){// 创建标签lv_obj_t*label=lv_label_create(lv_scr_act());lv_obj_align(label,LV_ALIGN_CENTER,0,0);// 获取字体(类型、大小)lv_font_t*font=get_font(FONT_TYPE_CN,20);// 获取中文字体,大小20// 设置字体if(font!=NULL){lv_obj_set_style_text_font(label,font,0);}// 设置文本(支持中文)lv_label_set_text(label,"你好,世界!Hello, World!");}

API 说明:

  • get_font(type, size): 获取指定类型和大小的字体
    • type: 字体类型(FONT_TYPE_CN等)
    • size: 字体大小(像素)

五、实现原理

1.add_font()- 注册字体路径

voidadd_font(inttype,constchar*font_url);
  • 功能:将字体类型和文件路径注册到字体类型列表
  • 参数:
    • type: 字体类型枚举值
    • font_url: 字体文件路径(如"./res/font/SOURCEHANSANSCN_REGULAR.OTF"

2.get_font()- 获取字体对象

lv_font_t*get_font(inttype,uint16_tsize);
  • 功能:根据类型和大小获取字体对象(如果不存在则创建)
  • 实现流程:
    1. 检查字体对象缓存中是否已存在
    2. 如果不存在,调用create_font_obj()创建
    3. 使用lv_tiny_ttf_create_file()加载字体文件
    4. 返回lv_font_t*指针

3. 路径解析机制

font_utils.c实现了智能路径解析:

  1. 优先查找构建目录:build/host/res/font/(如果从构建目录运行)
  2. 备选查找源码目录:my_app/res/font/
  3. 路径规范化:使用realpath()消除路径中的...
  4. LVGL 文件系统格式:转换为"A:绝对路径"格式(A:是 POSIX 驱动标识符)

六、字体文件路径格式

由于使用了 LVGL 文件系统抽象层,路径需要特殊格式:

普通路径:/home/user/app/res/font/font.otf
LVGL 路径:A:/home/user/app/res/font/font.otf

其中A:是在lv_conf.h中定义的LV_FS_POSIX_LETTER(这里是 ‘A’)。

font_utils.c会自动处理这个转换。


七、CMake 配置

CMakeLists.txt中需要:

  1. 复制字体文件到构建目录:
# 复制字体文件到 build/host/res/font/ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/res/font) file(COPY ${CMAKE_SOURCE_DIR}/res/font/ DESTINATION ${CMAKE_BINARY_DIR}/res/font/ FILES_MATCHING PATTERN "*.otf" PATTERN "*.OTF" PATTERN "*.ttf" PATTERN "*.TTF" )
  1. 链接数学库(Tiny_TTF 需要):
target_link_libraries(${PROJECT_NAME} PRIVATE m)

八、完整示例

// main.cintmain(void){// 1. 初始化 LVGLlv_init();// 2. 初始化文件系统驱动(必须!)#ifLV_USE_FS_POSIXlv_fs_posix_init();#endif// 3. 初始化字体(注册字体路径)FONT_INIT();// 4. 初始化显示和输入设备lv_port_disp_init();lv_port_indev_init();// 5. 创建 UI(使用字体)lv_obj_t*label=lv_label_create(lv_scr_act());lv_font_t*font=get_font(FONT_TYPE_CN,20);if(font!=NULL){lv_obj_set_style_text_font(label,font,0);}lv_label_set_text(label,"你好,世界!");// 6. 主循环while(1){lv_timer_handler();usleep(5000);}return0;}

九、注意事项

  1. 文件系统驱动必须先初始化lv_fs_posix_init()必须在FONT_INIT()之前调用
  2. 字体文件路径:确保字体文件在运行时能够访问(建议使用 CMake 复制到构建目录)
  3. 字体格式:支持 TTF 和 OTF 格式
  4. 内存管理:字体对象会被缓存,相同类型和大小的字体只会加载一次
  5. 字体大小:可以在运行时指定任意大小(Tiny_TTF 支持动态缩放)

十、调试技巧

如果字体加载失败,检查:

  1. 宏是否开启:LV_USE_TINY_TTFLV_TINY_TTF_FILE_SUPPORTLV_USE_FS_POSIX
  2. 文件系统是否初始化:确认lv_fs_posix_init()被调用
  3. 字体文件是否存在:检查路径是否正确,文件是否存在
  4. 查看日志输出:font_utils.c中有详细的调试信息
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/5 8:08:38

GeoTools:解锁地理空间数据的Java全能工具箱

GeoTools:解锁地理空间数据的Java全能工具箱 【免费下载链接】geotools Official GeoTools repository 项目地址: https://gitcode.com/gh_mirrors/ge/geotools 在当今数据驱动的世界中,地理空间信息已成为决策制定的关键要素。GeoTools作为一个成…

作者头像 李华
网站建设 2026/4/27 12:17:25

5、深入理解 iptables 防火墙:配置、激活与测试

深入理解 iptables 防火墙:配置、激活与测试 1. 网络地址转换(NAT) 在构建 iptables 策略时,网络地址转换(NAT)是关键的最后一步。其主要目的是将不可路由的内部地址(如 192.168.10.0/24)转换为可路由的外部地址(如 71.157.X.X)。这一转换适用于外部客户端对内部 W…

作者头像 李华
网站建设 2026/4/26 11:13:39

Llama-Factory如何保障多用户并发训练的稳定性?

Llama-Factory如何保障多用户并发训练的稳定性? 在大模型时代,越来越多团队希望基于LLaMA、Qwen等主流架构定制专属语言模型。然而现实往往并不理想:一个研究人员刚启动微调任务,另一个用户的训练就因显存溢出而崩溃;不…

作者头像 李华
网站建设 2026/4/27 15:57:22

28、Linux网络服务与Samba配置全解析

Linux网络服务与Samba配置全解析 1. 网络信息服务(NIS)相关操作 在完成NIS配置的部分步骤后,还需进行一些验证操作。首先,点击“Open Port in Firewall”复选框,然后点击“Finish”。接着,为确保NIS服务器正在运行,可在终端中输入 ypwhich 并按下回车键,查看显示信…

作者头像 李华
网站建设 2026/5/5 9:31:33

C++ Primer 中文版:初学者终极完整学习指南

想要快速掌握C编程语言?这份高清带目录的《C Primer》中文版电子书是您的理想选择!作为最受推崇的C入门书籍,它以其系统性和实用性成为无数编程学习者的首选C学习资源。 【免费下载链接】CPrimer中文版-高清带目录 C Primer 中文版 - 高清带目…

作者头像 李华
网站建设 2026/5/1 14:55:26

32、深入探究openSUSE Linux系统的性能调优与问题解决

深入探究openSUSE Linux系统的性能调优与问题解决 1. 系统监控与初步操作 首先,登录运行GNOME的openSUSE Linux机器。在终端中输入 gnome-system-monitor 并按下回车键,随后花费几分钟时间查看各个选项卡,尤其关注每个进程所使用的内存量。完成后,关闭终端窗口并关闭虚…

作者头像 李华