| **银杏科技有限公司旗下技术文档发布平台** ||||
|技术支持电话|**0379-69926675-801**|||
|技术支持邮件|Gingko@vip.163.com|||
^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^
| V1.0 | 2020-12-20 | yang | 初次建立 |
===== 实验二十三:lv_font中文内部字体、字符 =====
==== 一、创建新字体、字符 ====
在LVGL中,字体文件分为内部字体和外部字体,内部字体就是将字模信息以大数组的形式写在 .c 文件内,只需将该文件添加进工程中声明一下即可使用,不过内部字体只适用于显示少量字体。外部字体则将字模信息写入 .bin 文件并存储在大容量的外部存储器中,同时在对应的 .c 文件中完善外读外部存储器的函数。本章主要介绍内部中文字体的创建。
为若要让图形界面显示中文就要创建中文字体,在LVGL中创建内部字体,需要以下几步:
- 获得字库文件。
- 将字库文件添加进工程,并声明新字体。
- 调用新字体。
==== 二、获取字库文件 ====
获取字库文件主要有**官方在线字体转换工具**、**官方离线字体转换工具**、**字体转换软件**三种方法。其中官方在线字体转换工具的网页打开速度和转换速度都太慢,经常转换失败。而官方离线字体转换工具需要node.js 运行环境,命令行操作略显复杂。相比之下,网络上许多字体转换软件既简单又好用,因此推荐使用字体转换软件。
对于字符(图标)来说,LVGL自带的字体中给我们提供了一些常用的图标,但有些时候没有我们想要的,这时就要我们自己创建新字符了。字体的创建与普通字体的创建类似,区别就是获取 ttf/woff/woff2 格式字符文件的方式不同。我们可以从“阿里巴巴矢量图标库”获取想要的字符,操作很简单,只需挑选出需要的图标将其添加到创建的图标项目中,点击“下载至本地”按钮,就可以下载相应的.ttf图标字体文件。
其官方网址为:https://www.iconfont.cn 。
=== 2.1、官方在线字体转换工具 ===
官方提供的字体在线转换工具提供了图形操作界面,使用简单,此转换工具的在线网址为: https://littlevgl.com/ttf-font-to-c-array 。打开网页之后,界面如下所示:
{{ :icore4t:icore4t_rtt_lvgl_23_1.png?direct |}}
页面上面介绍了在线转换工具的使用方法,还说明了怎样将生成的 .c 字库文件添加进LVGL工程中。需要上传的 .ttf 文件每台windows电脑上都有,win10的字体文件路径为:“**C:\Windows\Fonts**”。
{{ :icore4t:icore4t_rtt_lvgl_23_2.png?direct |}}
=== 2.2、官方离线字体转换工具 ===
LVGL的作者也推出了离线版本的字体转换工具,github 链接为: https://github.com/littlevgl/lv_font_conv ,这是用 node.js 写的,没有图形化界面,需要在命令行下使用,比在线转换工具要复杂点,不过转换速度快。
离线工具是用 node.js 开发出来的,所以需要先安装 node.js 的运行环境,详细安装过程请参考教程:https://www.runoob.com/nodejs/nodejs-install-setup.html ,在安装完 node.js(会附带把 npm 包管理器给装好)之后,还要安装 lv_font_conv 离线转换工具,首先按win徽标键+R 打开运行界面,输入cmd 打开命令窗口,然后输入 npm i lv_font_conv -g 命令,回车运行就会安装 lv_font_conv 。 lv_font_conv 的主要命令行参数如下:
* **--bpp**: 抗锯齿大小,可选值为 1-4
* **--size**: 字体的大小,是指字符的高度
* **-o**(或者--output): 输出路径,比如为C:\Users\Administrator\Desktop\yahei_24.c
* **--format**: 输出格式,可选值有 dump、bin、lvgl,我们要用 lvgl
* **--font**: ttf/woff/woff2 字体文件的路径
* **--no-compress**: 禁止进行 RLE 压缩,我们在生成字体时,请禁止进行压缩
* **-r**(或--range): 所需字符的 unicode 编码范围,可选值为单个字符,字符范围,加可选的映射地址,首先你得必须保证你所需要的字符范围在 --font 指定的字体文件中能找得到,-r 命令行参数可以在一条命令中多次出现,如下面例子所示:
-r 0xF450 单个字符,十六进制和十进制都行
-r 0xF450-0xF470 字符范围
-r '0xF450=>0x81' 单个字符加映射地址
-r '0xF450-0xF470=>0x81' 字符范围加映射地址
-r 0xF450 -r 0xF451-0xF470 一下使用 2 次-r 命令行参数
-r 0xF450,0xF451-0xF470 用单个-r 表示多种可选值
上面所说的映射地址只有在多个字体进行合并时才会用得到 , 比 如 前 面 所 说 的 lv_font_roboto_16 字体,那就是 Roboto 字体文件和 FontAwesome 图标字体文件合并而成的。
* **--symbols**: 和-r 的作用差不多,都是用来指示所要用到的字符,不过他们的表达形式不一样,对--symbols 而言,它是接受字符的字面量形式,而-r 是接受字符的编码形式,--symbols 和 -r 可以同时使用,也可以只使用它们其中的一个,例如:
--symbols 0123456789 中 ABCD 国 EFG
上面是常用的重要参数,剩下不常用的参数--autohint-off, --autohint-strong,
--force-fast-kern-format, --no-prefilter, --no-kerning, --full-info这些可以进入 lv_font_conv 的 github 地址自行了解。
下面是一条完整的创建新字体命令示例:
lv_font_conv --no-compress --format lvgl --font C:\User\Desktop\yahei.ttf -o
C:\User\Desktop\my_font.c --bpp 4 --size 30 --symbols 银杏科技 -r 0x20-0x7F
=== 2.3、字体转换软件 ===
网络上的字体转换软件又很多,这里给大家推荐一个好用的,软件放在该工程的代码包中,操作方法如下图所示:
{{ :icore4t:icore4t_rtt_lvgl_23_3.png?direct |}}
按照上图所示步骤即可得到中文字体文件,这里得到的是 hei_20.c 文件。字符图标可以和中文字体生成于同一个字体文件中,添加字符图标的步骤如下图所示:
{{ :icore4t:icore4t_rtt_lvgl_23_4.png?direct |}}
==== 三、添加进工程并声明新字体 ====
将字库添加到工程中,首先需要将 hei_20.c 另存为UTF-8编码格式,并复制到工程 **packages\LVGL2RTT-master\lvgl\src\lv_font** 下。然后在工程中加入 hei_20.c 文件,如下图所示:
{{ :icore4t:icore4t_rtt_lvgl_23_5.png?direct |}}
新字体的声明有两种方法,第一种是在需要使用新字体的源文件头部声明,不过只可以在该文件内调用新字体,如下所示:
/* 例如gui.c */
LV_FONT_DECLARE(hei_20); /* 文件头部声明 */
void lv_gui_run(void){
...
lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &hei_20); /* 在此处调用 */
...
}
另一种方法是在 lv_conf.h 文件中进行全局声明,如下所示:
/* lv_conf.h */
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(hei_20) /* 全局声明新字体 */
==== 四、调用新字体 ====
新字体声明后,就可以被用户调用。一般使用函数 **lv_obj_set_style_local_text_font(obj, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &hei_20)** 为对象设置新字体。下面是一个小例子,创建一个标签并显示黑体20号中文和同高的字符图标。
{{ :icore4t:icore4t_rtt_lvgl_23_6.png?direct |}}
void lv_gui_run(void){
lvgl2rtt_init("lcd"); /* 初始化lvgl2rtt */
lv_obj_t * label = lv_label_create(lv_scr_act(), NULL); /* 创建子标签 */
lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &hei_20); /* 设置显示字体 */
lv_label_set_text(label, "你好,这是一个中文显示测试! \uF164\uF21C");/* 设置内容 */
}