字体¶
1. 支持的字体 ¶
Solution 当前支持以下字体能力:
提供两种字体实现方式:点阵字体(bitmap)和 FreeType 字体。
点阵字体支持 LVGL 生成的 bitmap 格式。
FreeType 字体当前仅支持
.ttf格式。支持同时使用多个 bitmap 字体和多个 FreeType 字体。
支持标准 Emoji。
支持为指定对象(obj)固定字体。
提供可免费使用的 tiny 压缩字体,字重为 55,支持 27000+ 简繁体汉字,占用空间约 1.06 MB。
语言 |
Language |
|---|---|
印地语 |
Hindi |
马拉地语 |
Marathi |
梵语 |
Sanskrit |
尼泊尔语 |
Nepali |
迈蒂利语 |
Maithili |
孔卡尼语 |
Konkani |
多格拉语 |
Dogri |
博多语 |
Bodo |
Solution V2.6.0 及以后版本可通过打开
PKG_USING_HARFBUZZ宏支持以下已适配语种的变形(shape):
文字系统 |
已适配语种 |
Language |
|---|---|---|
Devanagari |
印地语、马拉地语、尼泊尔语 |
Hindi, Marathi, Nepali |
Bengali |
孟加拉语、阿萨姆语 |
Bengali, Assamese |
Gurmukhi |
旁遮普语 |
Punjabi |
Gujarati |
古吉拉特语 |
Gujarati |
Oriya/Odia |
奥里亚语 |
Odia |
Tamil |
泰米尔语 |
Tamil |
Telugu |
泰卢固语 |
Telugu |
Kannada |
卡纳达语 |
Kannada |
Malayalam |
马拉雅拉姆语 |
Malayalam |
Sinhala |
僧伽罗语 |
Sinhala |
Thai |
泰语 |
Thai |
Lao |
老挝语 |
Lao |
Khmer |
高棉语 |
Khmer |
Myanmar |
缅甸语 |
Burmese |
Tibetan |
藏语 |
Tibetan |
Mongolian |
蒙古语 |
Mongolian |
Arabic |
阿拉伯语、波斯语、乌尔都语 |
Arabic, Persian/Farsi, Urdu |
Hebrew |
希伯来语 |
Hebrew |
Syriac |
叙利亚语 |
Syriac |
说明: 使用 Solution V2.6.0 及以后版本新增的语种变形能力时,需要使能 FreeType,并打开 PKG_USING_HARFBUZZ 宏;USE_HARFBUZZ_HINDI_SHAPER 为隐藏自动项,在依赖满足后会默认开启,无需用户单独打开。Code Size 需要增加 850KB。字体本身仍需包含对应语种的 glyph 以及 GSUB/GPOS 等 OpenType 数据。如果需要支持其他需要 shape 的语言,需由客户自行提供支持变形算法及对应 .ttf 的方案。

2. 字体放置目录¶
在 Solution 方案中,资源统一存放在 resource 目录下,字体文件需要放在 resource/fonts 目录中。

3. .ttf 字体的增删¶
新增字体:将新的
.ttf文件放到具体产品工程的resource/fonts/freetype目录下,例如solution/examples/watch/resource/fonts/freetype。调整顺序:编辑
ttf_order.txt,将新增字体加入文件并设置顺序。UI 显示文字时,会按照ttf_order.txt中的顺序遍历字体并查找字形。删除字体:删除对应的
.ttf文件即可。
4. .ttf 字体选择¶
可通过 Butterfli 工具的 UI 选择需要参与编译的字体。

⚠️ 注意
具体产品工程的
resource/fonts/freetype目录(例如solution/examples/watch/resource/fonts/freetype)下,除_tiny55_full、_tiny55_lite、hindi_ttf外,其余.ttf字体仅用于功能展示。若客户需要商用,请务必确认字体版权。
5. .ttf 字号设置¶
5.1 默认字号¶
lvsf_font.h 中定义了默认字号,可通过修改对应宏进行调整。

5.2 自定义字号¶
如果项目需要使用不同字号,可按以下步骤配置:
从
solution/framework/__template__/project目录中复制子目录__applicaiton_private__到对应的 HCPU 和 Simulator 目录。在
menuconfig中使能FT_SIZE_SELF_DEFINED。修改
__applicaiton_private__/ft_size_custom_reg.h中的字号定义。

ft_size_custom_reg.h 示例:
/**
* @brief Register fonts through this interface.
* The font size must be arranged from small to large.
* Because font is searched from small to large.
*/
#ifdef FT_SIZE_SELF_DEFINED
typedef enum
{
FONT_SMALL = 16,
FONT_NORMAL = 20,
FONT_SUBTITLE = 24,
FONT_TITLE = 28,
FONT_BIGL = 36,
FONT_HUGE = 56,
FONT_SUPER = 72,
} FONT_SIZES;
#define LVSF_FREETYPE_FONT_REGISTER(freetype_font) \
extern lv_font_freetype_lib_dsc_t CONCAT_2(freetype_font, _lib); \
SECTION_ITEM_REGISTER(FONT_SECTION_NAME, static const font_desc_t CONCAT_2(freetype_font, _reg_list)[]) = \
{ \
LVSF_FONT_REGISTER(freetype_font, 10), \
LVSF_FONT_REGISTER(freetype_font, 11), \
LVSF_FONT_REGISTER(freetype_font, 12), \
LVSF_FONT_REGISTER(freetype_font, 13), \
LVSF_FONT_REGISTER(freetype_font, 14), \
LVSF_FONT_REGISTER(freetype_font, 15), \
LVSF_FONT_REGISTER(freetype_font, 16), \
LVSF_FONT_REGISTER(freetype_font, 17), \
LVSF_FONT_REGISTER(freetype_font, 18), \
LVSF_FONT_REGISTER(freetype_font, 19), \
LVSF_FONT_REGISTER(freetype_font, 20), \
LVSF_FONT_REGISTER(freetype_font, 21), \
LVSF_FONT_REGISTER(freetype_font, 22), \
LVSF_FONT_REGISTER(freetype_font, 23), \
LVSF_FONT_REGISTER(freetype_font, 24), \
LVSF_FONT_REGISTER(freetype_font, 25), \
LVSF_FONT_REGISTER(freetype_font, 26), \
LVSF_FONT_REGISTER(freetype_font, 27), \
LVSF_FONT_REGISTER(freetype_font, 28), \
LVSF_FONT_REGISTER(freetype_font, 29), \
LVSF_FONT_REGISTER(freetype_font, 30), \
LVSF_FONT_REGISTER(freetype_font, 31), \
LVSF_FONT_REGISTER(freetype_font, 32), \
LVSF_FONT_REGISTER(freetype_font, 33), \
LVSF_FONT_REGISTER(freetype_font, 34), \
LVSF_FONT_REGISTER(freetype_font, 35), \
LVSF_FONT_REGISTER(freetype_font, 36), \
LVSF_FONT_REGISTER(freetype_font, 37), \
LVSF_FONT_REGISTER(freetype_font, 38), \
LVSF_FONT_REGISTER(freetype_font, 39), \
LVSF_FONT_REGISTER(freetype_font, 40), \
LVSF_FONT_REGISTER(freetype_font, 41), \
LVSF_FONT_REGISTER(freetype_font, 42), \
LVSF_FONT_REGISTER(freetype_font, 43), \
LVSF_FONT_REGISTER(freetype_font, 44), \
LVSF_FONT_REGISTER(freetype_font, 45), \
LVSF_FONT_REGISTER(freetype_font, 46), \
LVSF_FONT_REGISTER(freetype_font, 47), \
LVSF_FONT_REGISTER(freetype_font, 48), \
LVSF_FONT_REGISTER(freetype_font, 49), \
LVSF_FONT_REGISTER(freetype_font, 50), \
LVSF_FONT_REGISTER(freetype_font, 51), \
LVSF_FONT_REGISTER(freetype_font, 52), \
LVSF_FONT_REGISTER(freetype_font, 53), \
LVSF_FONT_REGISTER(freetype_font, 54), \
LVSF_FONT_REGISTER(freetype_font, 55), \
LVSF_FONT_REGISTER(freetype_font, 56), \
LVSF_FONT_REGISTER(freetype_font, 57), \
LVSF_FONT_REGISTER(freetype_font, 58), \
LVSF_FONT_REGISTER(freetype_font, 59), \
LVSF_FONT_REGISTER(freetype_font, 60), \
};
#endif
6. Emoji 字体的增删¶
新增 Emoji:将新增的 Emoji 图片放在具体产品工程的
resource/images_emoji/common/ezip目录下,例如solution/examples/watch/resource/images_emoji/common/ezip。图片命名格式必须为
emoji_xxx.png。其中
xxx为 Emoji 的 Unicode 编码。例如,Unicode 为
1f46d的 Emoji,应命名为emoji_1f46d.png。
删除 Emoji:删除对应图片即可。
7. 字体显示流程¶
为支持多语言,通常需要多个 .ttf 组合使用,才能覆盖全部语言字符。字体显示流程如下:
设置字体(
.ttf)顺序,并注册字体链表font_list。创建空的缓存链表
cache_list。按照文本中的每个 Unicode 逐个获取 bitmap。
如果在
cache_list中找到对应 Unicode 的 bitmap,则直接调用lv_draw_letter显示。如果未找到,则先存入
cache_list,再调用lv_draw_letter显示。如果存入时发现超出缓存容量,则会清除部分缓存后再继续写入。
显示速度取决于:
该 Unicode 位于
font_list中靠前还是靠后;该字形是否已经命中
cache_list。
也就是说,如果 Unicode 对应字形位于前面的字体中,或者能够在缓存中直接命中,则显示速度更快;否则需要进入 FreeType 查找并渲染字形,速度会略慢。
8. 代码中使用 .ttf 字体¶
8.1 自动选择字体¶
接口:lv_ext_set_local_font(lv_obj_t *obj, uint16_t size, lv_color_t color)
lv_obj_t *calorie = lv_label_create(bg_img);
lv_ext_set_local_font(calorie, FONT_SUBTITLE, lv_color_make(255, 255, 255));
lv_label_set_text(calorie, app_get_str(key_calorie, "calorie"));
8.2 指定字体名称¶
接口:lv_ext_label_set_indicated_font(lv_obj_t *obj, uint16_t size, lv_color_t color, const char *font_name)
lv_obj_t *calorie_lab = lv_label_create(bg_img);
lv_ext_set_local_font(calorie_lab, FONT_SUBTITLE, lv_color_make(255, 255, 255));
lv_ext_label_set_indicated_font(calorie_lab, FONT_SUBTITLE, lv_color_make(255, 255, 255), "HarmonyOS_Sans_SC_Bold");
8.3 指定字体名称并设置粗体 / 斜体¶
说明: 以下 FreeType 样式接口从 Solution V2.6 之后的版本开始支持,需要使能 FreeType,并且必须选择
FREETYPE_NORMAL_FONT,否则不支持粗体 / 斜体效果。
8.3.1 接口区别与适用场景¶
以下四个接口都只影响传入的对象,不会改变全局字体配置。它们可以分为两类:
设置字体时同时设置效果:
lv_ext_label_set_indicated_font_with_style、lv_ext_label_set_indicated_font_with_transform内部会先为 label 设置指定
font_name、字号和颜色,再设置对应效果。适用于创建 label 时已经确定字体名称和显示效果的场景,例如标题文本固定使用指定字体并加粗,或者某个固定文案需要倾斜显示。
对已经设置字体的对象设置效果:
lv_ext_obj_set_freetype_style、lv_ext_obj_set_freetype_transform不负责设置字号和颜色,调用前需要对象已经设置 FreeType 字体。
既可以在对象初始化创建时使用,也可以在运行过程中追加或更新效果。初始化创建时的调用顺序通常是:先调用
lv_ext_set_local_font或lv_ext_label_set_indicated_font设置字体,再调用对象级接口设置效果。适用于希望将“设置字体”和“设置效果”拆开处理的场景,例如字体通过
lv_ext_set_local_font自动选择,但仍希望对该对象加粗或倾斜;也适用于根据业务状态动态切换效果的场景,例如焦点态加粗、消息列表中特定内容倾斜显示。
同时,style 和 transform 的作用不同:
lv_ext_label_set_indicated_font_with_style与lv_ext_obj_set_freetype_style用于设置 FreeType 粗体 / 斜体样式。lv_ext_label_set_indicated_font_with_transform与lv_ext_obj_set_freetype_transform用于设置 FreeType 字体变换矩阵,可实现缩放、倾斜等效果。
例如,lv_ext_label_set_indicated_font_with_transform 与 lv_ext_obj_set_freetype_style 的区别是:前者会设置指定字体并应用变换矩阵,主要用于创建时直接得到倾斜 / 缩放字体;后者只对已经设置字体的对象设置粗体 / 斜体,不会设置字体、字号和颜色,但也可以在初始化创建阶段紧跟在设置字体之后调用。lv_ext_obj_set_freetype_transform 与 lv_ext_label_set_indicated_font_with_style 的区别是:前者只对已经设置字体的对象更新变换矩阵;后者会设置指定字体并应用粗体 / 斜体样式。
8.3.2 lv_ext_label_set_indicated_font_with_style¶
接口:lv_ext_label_set_indicated_font_with_style(lv_obj_t *obj, uint16_t size, lv_color_t color, const char *font_name, bool bold_enable, uint16_t bold_strength_26dot6, bool italic_enable)
接口说明:在设置 label 指定字体、字号和颜色的同时,设置该 label 绑定的 FreeType 粗体 / 斜体样式。不同 label 使用同一基础字体时,可以分别设置不同样式。
适用场景:创建文本对象时就确定需要使用指定字体并加粗 / 倾斜,例如标题、按钮重点文案、电子书章节标题等。
font_name:字体名称。bold_enable:是否启用粗体。bold_strength_26dot6:粗体强度,使用 FreeType 26.6 像素格式,32表示0.5 px。该接口中,当bold_enable为true且该值小于32时,会按32处理。italic_enable:是否启用斜体。
效果图:
示例:
以下例程用于创建一个标题 label,并在设置指定字体、字号和颜色的同时,将该标题显示为粗体。
lv_obj_t *title = lv_label_create(bg_img);
lv_ext_label_set_indicated_font_with_style(title, FONT_TITLE, LV_COLOR_WHITE,
"HarmonyOS_Sans_SC_Bold", true, 32, false);
lv_label_set_text(title, "Bold title");
8.3.3 lv_ext_obj_set_freetype_style¶
接口:lv_ext_obj_set_freetype_style(lv_obj_t *obj, const char *font_name, bool bold_enable, uint16_t bold_strength_26dot6, bool italic_enable)
接口说明:对已经设置 FreeType 字体的对象,单独设置对象绑定的粗体 / 斜体样式。调用前需要先为对象设置 FreeType 字体。
适用场景:既可用于初始化创建阶段,也可用于运行过程中动态切换样式。初始化创建时,适合先通过
lv_ext_set_local_font自动选择字体,或先通过lv_ext_label_set_indicated_font设置字体,再调用该接口设置粗体 / 斜体;运行过程中可用于选中态文字加粗、阅读器标题动态加粗、焦点切换时修改文字样式等。font_name:需要匹配的字体名称。传入NULL或空字符串时,表示作用于该对象使用的所有 FreeType 字体;传入非空字体名称时,只作用于匹配的字体。bold_enable:是否启用粗体。bold_strength_26dot6:粗体强度,使用 FreeType 26.6 像素格式,16表示0.25 px,32表示0.5 px。设置为0时使用默认粗体强度。italic_enable:是否启用斜体。
示例:
以下例程用于先创建普通用户名 label,并在初始化创建阶段将该 label 设置为斜体显示。该方式不重新设置字号和颜色,只要求在调用前已经为对象设置 FreeType 字体。
lv_obj_t *name = lv_label_create(bg_img);
lv_ext_label_set_indicated_font(name, FONT_SUBTITLE, LV_COLOR_WHITE, "HarmonyOS_Sans_SC_Bold");
lv_label_set_text(name, "User name");
lv_ext_obj_set_freetype_style(name, "HarmonyOS_Sans_SC_Bold", false, 0, true);
lv_obj_invalidate(name);
8.4 指定字体名称并设置字体变换¶
说明: 以下 FreeType 变换接口从 Solution V2.6 之后的版本开始支持,需要使能 FreeType,并且必须选择
FREETYPE_NORMAL_FONT,否则不支持字体变换矩阵效果。
8.4.1 lv_ext_label_set_indicated_font_with_transform¶
接口:lv_ext_label_set_indicated_font_with_transform(lv_obj_t *obj, uint16_t size, lv_color_t color, const char *font_name, bool transform_enable, int32_t xx_16dot16, int32_t xy_16dot16, int32_t yx_16dot16, int32_t yy_16dot16)
接口说明:在设置 label 指定字体、字号和颜色的同时,设置该 label 绑定的 FreeType 字体变换矩阵。可用于轻微拉伸、倾斜等效果。
适用场景:创建文本对象时就确定需要使用指定字体并做矩阵变换,例如固定提示文案倾斜显示、特殊标题做轻微拉伸或斜切效果。
transform_enable:是否启用字体变换。xx_16dot16、xy_16dot16、yx_16dot16、yy_16dot16:FreeType 16.16 定点格式的矩阵参数,其中0x10000表示1.0。矩阵计算方式为x' = xx * x + xy * y,y' = yx * x + yy * y。
效果图:
示例:
以下例程用于创建一个内容 label,并在设置指定字体、字号和颜色的同时,通过变换矩阵让文本做轻微倾斜显示。
lv_obj_t *content = lv_label_create(bg_img);
lv_ext_label_set_indicated_font_with_transform(content, FONT_TITLE, LV_COLOR_WHITE,
"HarmonyOS_Sans_SC_Bold", true,
LV_FREETYPE_TRANSFORM_IDENTITY_16D16, 0x04000L,
0, LV_FREETYPE_TRANSFORM_IDENTITY_16D16);
lv_label_set_text(content, "Transform text");
8.4.2 lv_ext_obj_set_freetype_transform¶
接口:lv_ext_obj_set_freetype_transform(lv_obj_t *obj, const char *font_name, bool enable, int32_t xx_16dot16, int32_t xy_16dot16, int32_t yx_16dot16, int32_t yy_16dot16)
接口说明:对已经设置 FreeType 字体的对象,单独设置对象绑定的字体变换矩阵。调用前需要先为对象设置 FreeType 字体。
适用场景:既可用于初始化创建阶段,也可用于运行过程中动态调整字体变换。初始化创建时,适合先通过
lv_ext_set_local_font自动选择字体,或先通过lv_ext_label_set_indicated_font设置字体,再调用该接口设置变换矩阵;运行过程中可用于消息通知内容统一做倾斜处理、焦点态做轻微拉伸、特定语言或排版场景临时调整显示效果。font_name:需要匹配的字体名称。传入NULL或空字符串时,表示作用于该对象使用的所有 FreeType 字体;传入非空字体名称时,只作用于匹配的字体。enable:是否启用字体变换。xx_16dot16、xy_16dot16、yx_16dot16、yy_16dot16:FreeType 16.16 定点格式的矩阵参数,其中0x10000表示1.0。
示例:
以下例程用于先创建通知内容 label 并设置常规字体,然后在初始化创建阶段对该对象应用倾斜 / 拉伸矩阵。该方式适合在字体由 lv_ext_set_local_font 自动选择时,为当前对象单独追加字体变换效果。
lv_obj_t *notify_content = lv_label_create(bg_img);
lv_ext_set_local_font(notify_content, FONT_TITLE, LV_COLOR_WHITE);
lv_label_set_text(notify_content, "Message content");
lv_ext_obj_set_freetype_transform(notify_content, NULL, true,
0x10CCDL, 0x04000L,
0, LV_FREETYPE_TRANSFORM_IDENTITY_16D16);
lv_obj_invalidate(notify_content);
注意: 字体变换可能影响 glyph 的边界和排版效果,建议在产品中使用验证过的固定参数。
8.5 设置全局 FreeType 字体效果¶
除上述对象级接口外,也可以使用 lv_freetype_set_style 和 lv_freetype_set_style_transform 设置 FreeType 字体的全局规则。
对象级接口与全局接口的主要区别如下:
lv_ext_label_set_indicated_font_with_style、lv_ext_obj_set_freetype_style、lv_ext_label_set_indicated_font_with_transform、lv_ext_obj_set_freetype_transform只影响传入的对象,适用于单个 label 或单个控件需要独立字体效果的场景。lv_freetype_set_style、lv_freetype_set_style_transform会按字体名称配置全局规则,后续使用匹配字体渲染的对象都会受影响,适用于同一字体在某个页面、某种语言或某类产品配置中需要统一效果的场景。font_name传入NULL或空字符串时,表示设置所有 FreeType 字体的默认规则;传入非空字体名称时,只作用于匹配的字体名称,并且指定字体名称的规则优先级高于默认规则。调用全局接口后,受影响的 glyph 缓存会被清除,因此建议在页面初始化、语言切换、主题切换等低频场景中调用,避免在频繁刷新的流程中反复调用。
8.5.1 lv_freetype_set_style¶
接口:lv_freetype_set_style(bool bold_enable, uint16_t bold_strength_26dot6, bool italic_enable, const char *font_name)
接口说明:设置 FreeType 字体的全局粗体 / 斜体规则。
适用场景:需要让某个字体在全局或某个页面中统一加粗 / 倾斜,例如当前语言使用的字体整体偏细,需要统一加粗显示;或者某个主题中要求指定字体统一使用斜体效果。
bold_enable:是否启用粗体。bold_strength_26dot6:粗体强度,使用 FreeType 26.6 像素格式,16表示0.25 px,32表示0.5 px。设置为0时使用默认粗体强度。italic_enable:是否启用斜体。font_name:需要匹配的字体名称。传入NULL或空字符串时,表示设置所有 FreeType 字体的默认规则。
示例:
以下例程用于在进入某个页面时,将 HarmonyOS_Sans_SC_Bold 这个字体统一加粗显示。后续该页面中使用该字体创建的文本都会按该规则渲染。
lv_freetype_set_style(true, 32, false, "HarmonyOS_Sans_SC_Bold");
lv_obj_t *title = lv_label_create(bg_img);
lv_ext_label_set_indicated_font(title, FONT_TITLE, LV_COLOR_WHITE, "HarmonyOS_Sans_SC_Bold");
lv_label_set_text(title, "Global bold title");
如果需要恢复该字体的普通样式,可关闭粗体和斜体:
lv_freetype_set_style(false, 0, false, "HarmonyOS_Sans_SC_Bold");
8.5.2 lv_freetype_set_style_transform¶
接口:lv_freetype_set_style_transform(bool enable, int32_t xx_16dot16, int32_t xy_16dot16, int32_t yx_16dot16, int32_t yy_16dot16, const char *font_name)
接口说明:设置 FreeType 字体的全局变换矩阵规则。
适用场景:需要让某个字体统一做矩阵变换,例如某种语言的通知内容统一倾斜显示、指定字体整体做轻微横向拉伸,或者产品主题要求某个字体统一使用斜切效果。
enable:是否启用字体变换。设置为false时,会关闭变换并恢复为单位矩阵。xx_16dot16、xy_16dot16、yx_16dot16、yy_16dot16:FreeType 16.16 定点格式的矩阵参数,其中0x10000表示1.0。矩阵计算方式为x' = xx * x + xy * y,y' = yx * x + yy * y。font_name:需要匹配的字体名称。传入NULL或空字符串时,表示设置所有 FreeType 字体的默认规则。
示例:
以下例程用于在进入通知页面时,对所有 FreeType 字体统一应用轻微倾斜 / 拉伸矩阵。后续页面中新创建或刷新显示的 FreeType 文本都会按该矩阵渲染。
lv_freetype_set_style_transform(true,
0x10CCDL, 0x04000L,
0, LV_FREETYPE_TRANSFORM_IDENTITY_16D16,
NULL);
lv_obj_t *notify_content = lv_label_create(bg_img);
lv_ext_set_local_font(notify_content, FONT_TITLE, LV_COLOR_WHITE);
lv_label_set_text(notify_content, "Global transform text");
如果需要恢复默认变换,可关闭变换并传入单位矩阵:
lv_freetype_set_style_transform(false,
LV_FREETYPE_TRANSFORM_IDENTITY_16D16, 0,
0, LV_FREETYPE_TRANSFORM_IDENTITY_16D16,
NULL);
注意: lv_freetype_set_style 和 lv_freetype_set_style_transform 适用于 FREETYPE_NORMAL_FONT 方式;字体效果会影响渲染缓存,建议在页面初始化或配置切换时统一设置。
9. 代码中重新设置字体顺序¶
以下接口只能在 GUI 线程中使用,不能跨线程调用。
9.1 lvsf_font_set_order(char **font_name, uint16_t font_num)¶
接口说明:调整字体顺序,将
font_name指定的字体移动到最前面。font_name:字符串数组,表示需要前置的字体。font_num:需要调整顺序的字体个数。
示例:
假设当前字体列表为 tiny5_full、hindi、arab、HarmonyOS_Sans_SC_Bold,需要将 arab 和 hindi 调整到最前面,适用于语言切换时优化字体访问顺序。
char *font_name[32] = {"arab", "hindi"};
uint16_t font_num = 2;
lvsf_font_set_order(font_name, font_num);
调整后的结果为:arab、hindi、tiny5_full、HarmonyOS_Sans_SC_Bold
9.2 lvsf_font_set_order_reverse(char **font_name, uint16_t font_num)¶
接口说明:调整字体顺序,将
font_name指定的字体移动到最后面。
示例:
假设当前字体列表为 tiny5_full、hindi、arab、HarmonyOS_Sans_SC_Bold,需要将 arab 调整到最后面。
char *font_name[32] = {"arab"};
uint16_t font_num = 1;
lvsf_font_set_order_reverse(font_name, font_num);
调整后的结果为:tiny5_full、hindi、HarmonyOS_Sans_SC_Bold、arab
9.3 lvsf_font_reset_order(void)¶
接口说明:将字体顺序恢复为开机时的默认顺序。
10. 重新设置某个字体支持的字号¶
以下接口只能在 GUI 线程中使用,不能跨线程调用。
10.1 lvsf_set_font_size_by_name(char *font_name, int *size)¶
接口说明:调整指定字体支持的字号。
注意:字号必须按从小到大的顺序排列。
示例:
假设字体当前支持的字号为 16、20、24、28、36、56,分别对应 FONT_SMALL、FONT_NORMAL、FONT_SUBTITLE、FONT_TITLE、FONT_BIGL、FONT_HUGE。
char *font_name = "arab";
int size[] = {20, 22, 0}; /* 以 0 结尾 */
lvsf_set_font_size_by_name(font_name, size);
调整后的结果为:20、22、24、28、36、56。即该字体的 FONT_SMALL 变为 20,FONT_NORMAL 变为 22。
10.2 lvsf_reset_font_size_by_name(char *font_name)¶
接口说明:将指定字体的字号恢复为开机时的默认值。
11. 设置支持 bitmap(点阵字体)¶
Solution 通过如下
menuconfig配置使能 bitmap。

以 watch 产品为例,点阵字体生成的
.c文件通常放在如下目录(其他产品目录类似)。

代码中调用 bitmap 的示例:
lv_ext_set_local_bitmap_font
lv_obj_t *keybord = lv_keyboard_create(parent);
lv_obj_set_width(keybord, LV_HOR_RES_MAX);
lv_keyboard_set_mode(keybord, LV_KEYBOARD_MODE_TEXT_LOWER);
lv_keyboard_set_textarea(keybord, ta);
lv_obj_align_to(keybord, ta, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
#ifdef USING_BITMAP_FONT
lv_ext_set_local_bitmap_font(keybord, LV_COLOR_BLACK, lv_font_montserrat_16);
#else
lv_ext_set_local_font(keybord, FONT_NORMAL, lv_color_make(0xFF, 0x00, 0x00));
#endif
lv_obj_refr_size(keybord);
lv_obj_add_event_cb(ta, setting_bt_name_ta_event_cb, LV_EVENT_ALL, keybord);
注意:
在 Solution 中通过上述配置即可使用点阵字体,无需在 SDK 中额外配置 bitmap。
使用
lv_ext_set_local_bitmap_font调用点阵字体(例如示例中的lv_font_montserrat_16)时,需要确保resource/fonts/bitmap中存在对应字体定义。
12. 引用外置 .ttf 字体¶
除内置字体外,Solution 还支持使用外置字体,例如:
通过蓝牙 / Wi-Fi 推送到文件系统中的字体;
直接访问 U 盘 / TF 卡中的字体。
相关接口如下:
int lvsf_font_load_ex(char *font_path, uint16_t *size)
从指定路径font_path加载字体。可加载该目录下全部字体,也可以通过完整文件路径(含.ttf后缀)加载单个字体。加载后字体会插入字体链表,但默认处于未启用状态。加载完成后,可通过lvsf_font_trav_ex查询已加载的外置字体。int lvsf_font_set_enable(char *font_name, int enable)
启用或禁用指定名称font_name的字体。启用后会占用内存,尤其在 NAND Flash / eMMC 方案中更明显,因此需控制加载数量,特别是大字体文件。void lvsf_font_unload_ex(char *font_path)
从字体链表中卸载指定路径font_path下的全部字体,或通过完整文件路径卸载单个字体(含.ttf后缀)。char *lvsf_font_trav_ex(rt_list_t **list, int ex)
遍历字体链表,获取所有已加载的外置字体信息。
13. UNKNOWN 字的显示¶
参照字体显示流程,当某个字符无法在当前 .ttf 中找到时,系统会显示 UNKNOWN 字。通常情况下,UNKNOWN 字显示为方块 □。
在某些场景下,客户可能需要自定义 UNKNOWN 字的显示方式。例如:
中文环境下显示为中文问号
?也可以显示为英文问号
?或替换为其他字符
为此,Solution 提供了以下接口:lv_freetype_set_unknown_font_mode
/**
* @brief Configure how missing glyphs are handled by the FreeType-backed font renderer.
*
* @param mode
* - 0: render a replacement glyph using @p unknown_font_unicode
* - 1: ignore missing glyphs (nothing will be drawn)
* @param unknown_font_unicode Replacement Unicode code point used only when @p mode is 0.
*
* @note This API name contains a historical typo ("unkown"). Prefer
* `lv_freetype_set_unknown_font_mode()` for new code.
*/
void lv_freetype_set_unkown_font_mode(int mode, uint32_t unknown_font_unicode);
代码调用位置:sdk/middleware/lvgl/lvsf/lvsf_font.c 中的 ft_callback_reg。
示例:
将 UNKNOWN 字显示为
?(中文问号)
lv_freetype_set_unkown_font_mode(0, 0xFF1F); /* "?" U+FF1F (0xFF1F) */
将 UNKNOWN 字显示为
?(英文问号)
lv_freetype_set_unkown_font_mode(0, 0x3F); /* '?' U+003F (0x3F) */
说明: 该功能仅在 Solution V2.5 及以上版本支持。如需在旧版本中支持,请联系 FAE 升级 PATCH。
14. 提升字体显示速度¶
使用 FreeType 进行字体显示时,通常需要先查找 glyph 再进行渲染。一个字符首次显示时,耗时通常为毫秒级。为提升显示速度,Solution 提供以下两种方法。
注意:
Font_gen工具不能从tiny55_full.ttf和hindi.ttf中抽取静态字体。如果需要使用
hindi.ttf(印地语),印地语显示仍需通过hindi.ttf实现,因此抽取出的字体风格(粗细)应与hindi.ttf保持一致。
14.1 使用 Font_gen 从 multi_language_table.xlsx 抽取静态字体到一个 .ttf 文件¶
工具位置:
solution/tools/Font_gen/font_gen.exe使用示例:
font_gen.exe -i multi_language_table.xlsx -i unicode 0x02-0xff HarmonyOS_Sans_SC_Bold.ttf arab.ttf
生成 static_font.ttf 后,可按以下方式使用:
放入具体产品工程的
resource/builtin/freetype/目录(如果工程使用该目录组织 builtin 字体资源)编译时会将
static_font.ttf转换为.c文件并编译进代码。这种方式会增加一些内存占用,但字体显示速度更快。
放入具体产品工程的
resource/fonts/freetype目录,例如solution/examples/watch/resource/fonts/freetype将其作为普通
.ttf字体参与方案。这种方式不会额外占用代码空间,但显示速度相比
builtin字体略慢。
注意: 如果方案中仍需使用 tiny55_full.ttf,则该方法通常不适用。原因包括:
抽取字体的风格通常与
tiny55_full.ttf不一致;当代码中的静态文本发生变化时,作为文件存在的
.ttf也需要同步升级。
14.2 使用 Font_gen 从 multi_language_table.xlsx 抽取静态字体到 bitmap 文件¶
相比 static_font.ttf,bitmap 文件能更有效地解决 FreeType 字体渲染耗时较长的问题。
使用前提:
multi_language_table.xlsx中需准确填写Bitmap_fontsize列,明确每行文字对应的显示字号。工具位置:
solution/tools/Font_gen/font_gen.exe使用示例:
font_gen.exe -i multi_language_table.xlsx -i unicode 0x02-0xff HarmonyOS_Sans_SC_Bold.ttf arab.ttf -ttf2bitmap 2将
solution/framework/__template__/project下的__applicaiton_private__复制到工程project目录下(与hcpu目录同级)。将生成的静态字体 C 文件(文件名通常形如 static_font_xx.c,由工具按字号生成)复制到
project/__applicaiton_private__/目录下。所有静态字体显示统一使用
lv_ext_set_local_bitmap_font接口。
说明: 使用该方法时,方案仍可保留 tiny55_full.ttf 作为动态字库,用于消息、电子书、实时生成信息等场景,从而实现静态字库与 tiny55_full.ttf 的混合使用,并允许静态文本与动态文本采用不同字体风格。
说明: 该功能仅在 Solution V2.5 及以上版本支持。