| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2020-12-18 | yang | 初次建立 | ===== 实验二十二:Fonts字体(Overview) ===== ==== 一、字体 ==== 在 LVGL 中,字体是位图的集合以及渲染字母图像所需的其他信息。字体存储在 **lv_font_t** 变量中,可以在样式的 **text_font** 字段中设置。例如: /* 设置样式的字体为28号 */ lv_style_set_text_font(&my_style, LV_STATE_DEFAULT, &lv_font_montserrat_28); 字体具有 bpp(bits per pixel每像素比特数)属性。它代表用了多少位来描述字体中的像素。这样,如果 bpp 较高,则字母的边缘更平滑,没有毛刺,界面更加美观。 bpp 的值可以是 1、2、4 和 8(值越高表示质量越好)。不过 bpp 值也影响字体所需的存储空间。例如,bpp = 4 所需空间比 bpp = 1 大近 4 倍。 除了存储消耗变大之外,bpp 值越大 , 在界面上进行字体渲染时 , 绘制速度也会越慢。 ==== 二、编码支持 ==== LVGL 支持 **ASCII** 编码与**UTF-8** 编码的 Unicode 字符。 UTF-8 编码可以支持全球所有字符的显示,例如中文、图标字体等。编码的选择要在 lv_conf.h 头文件中的 **LV_TXT_ENC** 宏配置,默认为UTF-8编码。为了开发方便,最好把集成开发工具的编码也改成 UTF-8以将代码/文本保存为 UTF-8 格式。 /* 使用UTF-8编码 */ #define LV_TXT_ENC LV_TXT_ENC_UTF8 /* 或者使用ASCII编码 */ #define LV_TXT_ENC LV_TXT_ENC_ASCII ==== 三、内置字体 ==== 有几种不同大小的内置字体,可以通过 **LV_FONT_...** 定义在 lv_conf.h 中启用。 LV_FONT_MONTSERRAT_12 12像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_14 14像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_16 16像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_18 18像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_20 20像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_22 22像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_24 24像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_26 26像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_28 28像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_30 30像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_32 32像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_34 34像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_36 36像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_38 38像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_40 40像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_42 42像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_44 44像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_46 46像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_48 48像素ASCII字符 + 内置符号 LV_FONT_MONTSERRAT_12_SUBPX 具有亚像素渲染的 12 像素字体 LV_FONT_MONTSERRAT_28_COMPRESSED 28像素压缩字体和 3 bpp LV_FONT_DEJAVU_16_PERSIAN_HEBREW 16像素希伯来语,阿拉伯语,波斯字母及其所有形式 LV_FONT_SIMSUN_16_CJK 16像素 1000 个最常见的中日韩文字 LV_FONT_UNSCII_8 8 像素像素完美字体 内置字体是全局变量,其名称类似于 **lv_font_montserrat_16** 代表字体有16 像素高。要在某种样式中使用它们,只需使用文章开头的命令 **lv_style_set_text_font(&my_style, LV_STATE_DEFAULT, &lv_font_montserrat_16)** ,添加一个指向字体变量的指针。 内置字体的 bpp = 4,包含 ASCII 字符并使用 Montserrat 字体。 除了 ASCII 范围,以下符号也从 FontAwesome 字体添加到内置字体中。 {{ :icore4t:icore4t_rtt_lvgl_22_1.png?direct |}} 符号可以单独使用,例如下面的代码,将显示一个✓字符。 {{ :icore4t:icore4t_rtt_lvgl_22_2.png?direct |}} void lv_gui_run(void){ lvgl2rtt_init("lcd"); /* 初始化lvgl2rtt */ lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(label1, LV_SYMBOL_OK); lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0); } 或与字符串一起使用: {{ :icore4t:icore4t_rtt_lvgl_22_3.png?direct |}} void lv_gui_run(void){ lvgl2rtt_init("lcd"); /* 初始化lvgl2rtt */ lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(label1, LV_SYMBOL_OK"Apply"); lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0); } 或更多符号一起使用: {{ :icore4t:icore4t_rtt_lvgl_22_4.png?direct |}} void lv_gui_run(void){ lvgl2rtt_init("lcd"); /* 初始化lvgl2rtt */ lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(label1, LV_SYMBOL_OK LV_SYMBOL_WIFI LV_SYMBOL_PLAY); lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0); } ==== 四、特殊功能 ==== === 4.1、双向支持 === 大多数语言使用从左到右(简称** LTR**)的书写方向,但是某些语言(例如希伯来语,波斯语或阿拉伯语)使用从右到左(简称 **RTL**)的书写方向。LVGL 不但支持 RTL 文本,而且还支持混合文本渲染(BiDi)。例如: {{ :icore4t:icore4t_rtt_lvgl_22_5.png?direct |}} 用户可以配置 lv_conf.h 中 **LV_USE_BIDI** 启用 BiDi 支持。 所有文本都有一个基本方向(LTR 或 RTL),该方向确定一些渲染规则和文本的默认对齐方式(左或右)。但是,在 LVGL 中基本方向不仅适用于标签,这是可以为每个对象设置的常规属性。如果未设置,则它将从父级继承。因此,设置屏幕的基本方向就足够了,每个对象都会继承它。 屏幕的默认基本方向可以通过 lv_conf.h 中的 **LV_BIDI_BASE_DIR_DEF** 来设置,其他对象将从其父对象继承基本方向。要设置对象的基本方向,使用 **lv_obj_set_base_dir(obj, base_dir)** 。可能的基本方向参数是: * **LV_BIDI_DIR_LTR** 从左到右基本方向 * **LV_BIDI_DIR_RTL** 从右到左基本方向 * **LV_BIDI_DIR_AUTO** 自动检测基准方向 * **LV_BIDI_DIR_INHERIT** 从父级继承基本方向(非屏幕对象的默认方向) 下面的列表总结了 RTL 基本方向对对象的影响效果: * 默认情况下在右侧创建对象 * lv_tabview :从右到左排列选项卡 * lv_checkbox :选择框在右侧显示 * lv_btnmatrix :从右到左显示按钮 * lv_list :在右侧显示图标 * lv_dropdown :将选项向右对齐 * 文本在 lv_table、 lv_btnmatrix、 lv_keyboard、 lv_tabview、 lv_dropdown、 lv_roller、中被BiDi处理以正确显示。 === 4.2、阿拉伯语和波斯语支持 === 显示阿拉伯和波斯字符有一些特殊规则:字符的形式取决于它们在文本中的位置。如果隔离,开始,中间或结束位置,则需要使用同一字母的不同形式。除了这些连接规则外,还应考虑其他规则。 若要使LVGL 支持这些规则,需要启用 **LV_USE_ARABIC_PERSIAN_CHARS** 。不过该方法存在如下限制: * 仅支持显示文本(例如在标签上),文本输入(例如文本区域)不支持此功能。 * 静态文本(即 const)不会被处理。例如,由 **lv_label_set_text()** 设置的文本将被 处理,但 **lv_lable_set_text_static()** 不会。 * 文本获取函数(例如 **lv_label_get_text()** )将返回处理后的文本。 === 4.3、亚像素渲染 === 亚像素渲染意味着通过在红色,绿色和蓝色通道而不是像素级别上渲染将水平分辨率提高三倍。它利用了每个像素的物理颜色通道的位置,这样可以产生更高质量的字体抗锯齿。 亚像素渲染需要生成具有特殊设置的字体: 在LVGL官网在线字体生成时,勾选 Subpixel 选项框。 * 在命令行工具中使用 --lcd 标志。请注意,生成的字体大约需要 3 倍的内存。 * 仅当像素的颜色通道具有水平布局时,亚像素渲染才有效。也就是说,R,G,B 通道彼此相邻而不位于彼此之上。颜色通道的顺序也需要与库设置匹配。默认情况下,LVGL 采用 RGB 顺序,但是可以通过在 lv_conf.h 中设置 **LV_SUBPX_BGR** 为 1 来交换顺序。 === 4.4、压缩字体 === 字体的位图可以通过以下方式压缩 * 在LVGL官网在线字体生成时,勾选在线转换器中的 Compressed 复选框。 * 在命令行工具中不将 --no-compress 标志传递给脱机转换器(默认情况下应用压缩)。 较大的字体和较高的 bpp 压缩更有效。但是,渲染压缩字体的速度要慢 30%。因此,建议仅压缩用户界面的最大字体,因为 * 他们需要最多的内存。 * 他们可以更好地压缩。 * 并且它们的使用频率可能不如中等大小的字体。(因此性能成本较小)。 ==== 五、添加新字体、符号 ==== 在LVGL中有几种方法可以向项目中添加新字体: - 最简单的方法是使用官网在线字体转换器。只需设置参数,单击“转换”按钮,将字体复制到项目中并使用它。网址为:[[https://littlevgl.com/ttf-font-to-c-array]] 请务必仔细阅读该站点上提供的步骤,否则转换时会出错。 - 使用脱机字体转换器。(需要安装 Node.js)。 - 如果要创建类似内置字体(Roboto 字体和符号)但大小和/或范围不同的内容,则可以使用文件夹 lvgl/scripts/built_in_font 中的 built_in_font_gen.py 脚本。(需要 Python 环境并安装lv_font_conv )网址:[[https://github.com/lvgl/lv_font_conv]] 。 添加的新字体在使用前需要声明,否则就会报找不到字体的错误,要在文件中声明字体,可以使用 **LV_FONT_DECLARE(my_font_name)** 。 为了避免在每个地方都要去申明一次字体, 我们可以直接利用 lv_conf.h 文件中的 **LV_FONT_CUSTOM_DECLARE** 配置宏来进行全局申明: #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \ LV_FONT_DECLARE(my_font_2) 符号字体就是图标,在LVGL中既可以作为字体来显示,也可以作为图片来显示。LVGL中有一些从 FontAwesome 字体创建的内置符号,用户也可以添加新的符号字体,添加新字符与添加新字体我们在下一章节进行详细介绍,在此只简要介绍。 ==== 六、动态加载字体 ==== 函数 lv_font_load 可用于从文件加载字体,要加载的字体需要具有特殊的二进制格式。(不是 TTF 或 WOFF)。使用 lv_font_conv 工具与选项 --format bin 生成 LVGL 兼容的字体文件。lv_font_conv 工具网址:[[https://github.com/lvgl/lv_font_conv]] 。 请注意,要动态加载字体,需要启用 LVGL 的文件系统,并需要添加驱动程序。例如: #lv_font_t * my_font; /* 创建新字体 */ my_font = lv_font_load(X/path/to/my_font.bin); /* 加载字库文件 */ lv_font_free(my_font); /* 如果不再需要,则释放字体 */ ==== 七、添加新的字体引擎 ==== LVGL 的字体界面设计得非常灵活。用户不使用 LVGL 的内部字体引擎也可以添加自己的字体。例如,使用 FreeType 从 TTF 字体实时渲染字形,或者使用外部闪存存储字体的位图,并在库需要它们时读取它们。 若要添加一个新的字体引擎需要创建一个自定义变量 **lv_font_t** ,详情请参考LVGL官方文档Fonts章节。