字体¶
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 及以后版本新增支持以下语种的变形(shape):
语言 |
Language |
|---|---|
孟加拉语 |
Bengali |
阿拉伯语 |
Arabic |
波斯语 |
Persian/Farsi |
说明: 使用 Solution V2.6.0 及以后版本新增的语种变形能力时,Code Size 需要增加 850KB。如果需要支持其他需要 shape 的语言,需由客户自行提供支持变形算法及对应 .ttf 的方案。

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

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

⚠️ 注意
solution/examples/xxx/resource/fonts/freetype目录下的.ttf文件中,除_tiny55_full、_tiny55_lite、hindi_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 图片放在
solution/examples/xxx/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");
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 / 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 后,可按以下方式使用:
放入
solution/examples/xxx/resource/builtin/freetype/目录编译时会将
static_font.ttf转换为.c文件并编译进代码。这种方式会增加一些内存占用,但字体显示速度更快。
放入
solution/examples/xxx/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 及以上版本支持。