================================== 字体(Fonts) ================================== 在LVGL中,字体是位图和呈现字母(字形)图像所需的其他信息的集合。字体存储在 ``lv_font_t`` 变量中,可以在样式的text_font字段中进行设置。例如: .. code-block:: c :linenos: lv_style_set_text_font(&my_style, LV_STATE_DEFAULT, &lv_font_montserrat_28); /*Set a larger font*/ 字体具有 **bpp(每像素位数)** 属性。它显示了多少位用于描述字体中的像素。为像素存储的值确定像素的不透明度。这样,如果bpp较高,则字母的边缘可以更平滑。可能的bpp值是1、2、4和8(值越高表示质量越好)。 bpp还会影响存储字体所需的内存大小。例如,bpp = 4使字体比bpp = 1大近4倍。 Unicode支持 ################################## LVGL支持 **UTF-8** 编码的Unicode字符。需要配置的编辑器,以将的代码/文本保存为 UTF-8 (通常是默认值),并确保在 lv_conf.h 中将 ``LV_TXT_ENC`` 其设置为: ``LV_TXT_ENC_UTF8``。(这是默认值) 测试一下试试: .. code-block:: c :linenos: lv_obj_t * label1 = lv_label_create(lv_scr_act(), NULL); lv_label_set_text(label1, LV_SYMBOL_OK); 如果一切正常,则应显示一个 ✓ 字符。 内置字体 ################################## 有几种不同大小的内置字体,可以通过 LV_FONT _... 定义在 ``lv_conf.h`` 中启用。 普通字体 ================================== 包含所有ASCII字符,度数符号(U + 00B0),项目符号(U + 2022)和内置符号(请参见下文)。 - ``LV_FONT_MONTSERRAT_12`` 12 px font - ``LV_FONT_MONTSERRAT_14`` 14 px font - ``LV_FONT_MONTSERRAT_16`` 16 px font - ``LV_FONT_MONTSERRAT_18`` 18 px font - ``LV_FONT_MONTSERRAT_20`` 20 px font - ``LV_FONT_MONTSERRAT_22`` 22 px font - ``LV_FONT_MONTSERRAT_24`` 24 px font - ``LV_FONT_MONTSERRAT_26`` 26 px font - ``LV_FONT_MONTSERRAT_28`` 28 px font - ``LV_FONT_MONTSERRAT_30`` 30 px font - ``LV_FONT_MONTSERRAT_32`` 32 px font - ``LV_FONT_MONTSERRAT_34`` 34 px font - ``LV_FONT_MONTSERRAT_36`` 36 px font - ``LV_FONT_MONTSERRAT_38`` 38 px font - ``LV_FONT_MONTSERRAT_40`` 40 px font - ``LV_FONT_MONTSERRAT_42`` 42 px font - ``LV_FONT_MONTSERRAT_44`` 44 px font - ``LV_FONT_MONTSERRAT_46`` 46 px font - ``LV_FONT_MONTSERRAT_48`` 48 px font 特殊字体 ================================== - ``LV_FONT_MONTSERRAT_12_SUBPX`` 与常规12像素字体相同,但具有亚像素渲染 - ``LV_FONT_MONTSERRAT_28_COMPRESSED`` 与普通的28 px字体相同,但压缩字体为3 bpp - ``LV_FONT_DEJAVU_16_PERSIAN_HEBREW`` 正常范围内的16像素字体+希伯来语,阿拉伯语,Perisan字母及其所有形式 - ``LV_FONT_SIMSUN_16_CJK`` 16 px字体,具有正常范围+ 1000个最常见的CJK部首 - ``LV_FONT_UNSCII_8`` 仅包含ASCII字符的8 px像素完美字体 内置字体是全局变量,其名称像 ``lv_font_montserrat_16`` 一样,代表 16 px 高的字体。要以某种样式使用它们,只需添加一个指向如上所示的字体变量的指针。 内置字体的 bpp = 4,包含 ASCII 字符并使用 Montserrat 字体。 除了 ASCII 范围,以下符号也从 FontAwesome 字体添加到内置字体中。 .. figure:: http://photos.100ask.net/lvgl/03_overview/07_font/01_symbols.png LVGL的内置符号 这些符号可以这样使用: .. code-block:: c :linenos: lv_label_set_text(my_label, LV_SYMBOL_OK); 或与字符串一起使用: .. code-block:: c :linenos: lv_label_set_text(my_label, LV_SYMBOL_OK "Apply"); 或更多个符号一起使用: .. code-block:: c :linenos: lv_label_set_text(my_label, LV_SYMBOL_OK LV_SYMBOL_WIFI LV_SYMBOL_PLAY); 特殊功能 ################################## 双向支持 ================================== 大多数语言使用从左到右(简称LTR)的书写方向,但是某些语言(例如希伯来语,波斯语或阿拉伯语)使用从右到左(简称RTL)的书写方向。 LVGL不仅支持RTL文本,而且还支持混合(又称双向,BiDi)文本渲染。一些例子: .. figure:: http://photos.100ask.net/lvgl/03_overview/07_font/02_bidi.png LVGL的双向文字范例 可以通过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**: A自动检测基准方向 - **LV_BIDI_DIR_INHERIT**: 从父级继承基本方向(非屏幕对象的默认方向) 此列表总结了RTL基本方向对对象的影响: 默认情况下在右侧创建对象 - ``lv_tabview`` : displays tabs from right to left - ``lv_checkbox`` : Show the box on the right - ``lv_btnmatrix``: Show buttons from right to left - ``lv_list``: Show the icon on the right - ``lv_dropdown`` : Align the options to the right - ``lv_table`` , ``lv_btnmatrix`` , ``lv_keyboard`` , ``lv_tabview`` , ``lv_dropdown`` , ``lv_roller`` 中的文本为“ BiDi处理”,可以正确显示 阿拉伯语和波斯语支持 ================================== 显示阿拉伯字符和波斯字符有一些特殊规则:字符的形式取决于它们在文本中的位置。如果隔离,开始,中间或结束位置,则需要使用同一字母的不同形式。除了这些合取规则外,还应考虑其他规则。 如果启用了 ``LV_USE_ARABIC_PERSIAN_CHARS`` ,则 LVGL 支持应用这些规则。 但是,存在一些限制: - 仅支持显示文本(例如在标签上),文本输入(例如文本区域)不支持此功能 - 静态文本(即const)不会被处理。例如,由 ``lv_label_set_text()`` 设置的文本将被处理为“阿拉伯语”,但 ``lv_lable_set_text_static()`` 不会。 - 文本获取函数(例如 ``lv_label_get_text()`` )将返回处理后的文本。 亚像素渲染 ================================== 亚像素渲染意味着通过在红色,绿色和蓝色通道而不是像素级别上渲染将水平分辨率提高三倍。它利用了每个像素的物理颜色通道的位置。这样可以产生更高质量的字母抗锯齿。在这里学习更多。 亚像素渲染需要生成具有特殊设置的字体: - 在网络转换器勾选 ``Subpixel`` 框 - 在命令行工具中使用 ``--lcd`` 标志。请注意,生成的字体大约需要3倍的内存。 仅当像素的颜色通道具有水平布局时,子像素渲染才有效。也就是说,R,G,B通道彼此相邻而不位于彼此之上。颜色通道的顺序也需要与库设置匹配。默认情况下,LVGL 采用 ``RGB`` 顺序,但是可以通过在 lv_conf.h 中将 ``LV_SUBPX_BGR`` 设置为 **1** 来交换它。 压缩字体 ================================== - 字体的位图可以通过以下方式压缩 - 勾选 ``Compressed`` 在线转换器中的复选框 - 不将 ``--no-compress`` 标志传递给脱机转换器(默认情况下应用压缩) 较大的字体和较高的bpp压缩更有效。但是,渲染压缩字体的速度要慢30%。因此,建议仅压缩用户界面的最大字体,因为  - 他们需要最多的内存 - 他们可以更好地压缩 - 并且它们的使用频率可能不如中等大小的字体。(因此性能成本较小) 添加新字体 ################################## 有几种方法可以向项目中添加新字体: 1. 最简单的方法是使用在线字体转换器(https://lvgl.io/tools/fontconverter)。只需设置参数,单击“转换”按钮,将字体复制到的项目中并使用它。**请务必仔细阅读该网站上提供的步骤,否则转换时会出错。** #. 使用脱机字体转换器(https://github.com/lvgl/lv_font_conv)。 (需要安装Node.js) #. 如果要创建类似内置字体(Roboto字体和符号)但大小和/或范围不同的东西,可以在 ``lvgl/scripts/built_in_font`` 文件夹中使用 ``built_in_font_gen.py`` 脚本。(它需要安装 ``Python`` 和 ``lv_font_conv`` ) 要在文件中声明字体,请使用 ``LV_FONT_DECLARE(my_font_name)`` 。 要使字体在全局范围内可用(如内置字体),请将它们添加到 lv_conf.h 中的 ``LV_FONT_CUSTOM_DECLARE`` 中。 添加新符号 ################################## 内置符号是从FontAwesome字体创建的。 1. 在https://fontawesome.com上搜索符号。例如USB符号。复制它的Unicode ID,在这种情况下为 ``0xf287`` 。 #. 打开在线字体转换器。添加添加FontAwesome.woff。 。 #. 设置名称,大小, BPP 等参数。将使用此名称在代码中声明和使用字体。 #. 将符号的 Unicode ID 添加到范围字段。例如。 USB 符号为 ``0xf287`` 。可以用,枚举更多符号。 #. 转换字体并将其复制到的项目。确保编译字体的.c文件。 #. 使用 ``extern lv_font_t my_font_name11 声明字体;或者只是 ``LV_FONT_DECLARE(my_font_name)`` ;。 使用符号 ================================== 1. 将Unicode值转换为UTF8。可以在此网站上进行操作。对于 ``0xf287`` ,十六进制 UTF-8 字节为 ``EF 8A 87`` 。 #. 根据UTF8值创建定义: ``#define MY_USB_SYMBOL "\xEF\x8A\x87"`` #. 创建一个标签并设置文本。例如: ``lv_label_set_text(label, MY_USB_SYMBOL)`` 注- ``lv_label_set_text(label, MY_USB_SYMBOL)` 使用 ``style.text.font`` 属性中定义的字体搜索此符号。要使用该符号,可能需要对其进行更改。例如 ``style.text.font = my_font_name`` 在运行时加载字体 ################################## ``lv_font_load`` 可用于从文件中加载字体。要加载的字体需要具有特殊的二进制格式。 (不是TTF或WOFF)。使用带有 ``--format bin`` 选项的 `lv_font_conv`_ 生成与LVGL兼容的字体文件。 请注意,要加载字体,需要启用 `LVGL的文件系统`_,并需要添加驱动程序。 .. _LVGL的文件系统: http://lvgl.100ask.net/documentation/03_overview/09_file-system.html .. _lv_font_conv: https://github.com/lvgl/lv_font_conv/ 范例: .. code-block:: c :linenos: lv_font_t * my_font; my_font = lv_font_load(X/path/to/my_font.bin); /*Use the font*/ /*Free the font if not required anymore*/ lv_font_free(my_font); 添加新的字体引擎 ################################## LVGL的字体界面设计得非常灵活。不需要使用LVGL的内部字体引擎,但可以添加自己的字体。例如,使用 `FreeType`_ 从TTF字体实时渲染字形,或使用外部闪存存储字体的位图,并在库需要它们时读取它们。 可以在 `lv_freetype库`_ 中找到使用FreeType的传统。 .. _FreeType: https://www.freetype.org/ .. _lv_freetype库: https://github.com/lvgl/lv_lib_freetype 为此,需要创建一个自定义 ``lv_font_t`` 变量: .. code-block:: c :linenos: /*Describe the properties of a font*/ lv_font_t my_font; my_font.get_glyph_dsc = my_get_glyph_dsc_cb; /*Set a callback to get info about gylphs*/ my_font.get_glyph_bitmap = my_get_glyph_bitmap_cb; /*Set a callback to get bitmap of a glyp*/ my_font.line_height = height; /*The real line height where any text fits*/ my_font.base_line = base_line; /*Base line measured from the top of line_height*/ my_font.dsc = something_required; /*Store any implementation specific data here*/ my_font.user_data = user_data; /*Optionally some extra user data*/ ... /* Get info about glyph of `unicode_letter` in `font` font. * Store the result in `dsc_out`. * The next letter (`unicode_letter_next`) might be used to calculate the width required by this glyph (kerning) */ bool my_get_glyph_dsc_cb(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next) { /*Your code here*/ /* Store the result. * For example ... */ dsc_out->adv_w = 12; /*Horizontal space required by the glyph in [px]*/ dsc_out->box_h = 8; /*Height of the bitmap in [px]*/ dsc_out->box_w = 6; /*Width of the bitmap in [px]*/ dsc_out->ofs_x = 0; /*X offset of the bitmap in [pf]*/ dsc_out->ofs_y = 3; /*Y offset of the bitmap measured from the as line*/ dsc_out->bpp = 2; /*Bits per pixel: 1/2/4/8*/ return true; /*true: glyph found; false: glyph was not found*/ } /* Get the bitmap of `unicode_letter` from `font`. */ const uint8_t * my_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter) { /* Your code here */ /* The bitmap should be a continuous bitstream where * each pixel is represented by `bpp` bits */ return bitmap; /*Or NULL if not found*/ } 相关API ################################## TODO