目录
1. 修改默认字体
2. 修改字体
3. 特殊字体
3.1 SUBPX字体
3.2 28像素压缩字体
3.3 16像素希伯来语/阿拉伯语/Perisan字母
3.4 16像素中文字体
3.5 8像素Ascii字体
3.6 16像素Ascii字体
3.7 内置图标
4. 超大字体
5. 编码方式
6. 添加字体
6.1 在线字体转换器
6.2 载入字体
7. 加载二进制字体文件
字体是位图和呈现字母(字形)图像所需的其他信息的集合。LVGL的字库信息保存在lv_font_t的变量中。LVGL默认使用ASCII范围(包含所有ASCII字符,度数符号(U + 00B0),项目符号(U + 2022)和内置图标)的一组字体,在lv_conf.h中有相关的宏定义可以使能相应大小的字体,默认使用LV_FONT_MONTSERRAT_14,这里的14指的是字体大小。数字越大,字体的像素越大,占用的空间越大。
/*Montserrat fonts with ASCII range and some symbols using bpp = 4
*https://fonts.google.com/specimen/Montserrat*/
#define LV_FONT_MONTSERRAT_8 0
#define LV_FONT_MONTSERRAT_10 0
#define LV_FONT_MONTSERRAT_12 0
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 0
#define LV_FONT_MONTSERRAT_18 0
#define LV_FONT_MONTSERRAT_20 0
#define LV_FONT_MONTSERRAT_22 0
#define LV_FONT_MONTSERRAT_24 0
#define LV_FONT_MONTSERRAT_26 0
#define LV_FONT_MONTSERRAT_28 0
#define LV_FONT_MONTSERRAT_30 0
#define LV_FONT_MONTSERRAT_32 0
#define LV_FONT_MONTSERRAT_34 0
#define LV_FONT_MONTSERRAT_36 0
#define LV_FONT_MONTSERRAT_38 0
#define LV_FONT_MONTSERRAT_40 0
#define LV_FONT_MONTSERRAT_42 0
#define LV_FONT_MONTSERRAT_44 0
#define LV_FONT_MONTSERRAT_46 0
#define LV_FONT_MONTSERRAT_48 0
1. 修改默认字体
如果要修改默认字体,可以在lv_conf.h中添加LV_FONT_DEFAULT的宏定义,LVGL默认的是LV_FONT_MONTSERRAT_14。
#define LV_FONT_DEFAULT &lv_font_montserrat_14
对比14和24的字体
2. 修改字体
字体信息也是保存在Style中,对应的API是
void lv_style_set_text_font(lv_style_t * style, const lv_font_t * value)
测试代码如下,显示字符串“Hello World!”, 使用24的字体,显示效果同上图第二个Rect。
static lv_obj_t *label1 = lv_label_create(btn1);
static lv_style_t style1;
lv_style_init(&style1);
lv_style_set_text_font(&style1, &lv_font_montserrat_24);
lv_obj_add_style(label1, &style1, LV_STATE_DEFAULT);
lv_obj_set_size(label1, LV_PCT(100), LV_PCT(80));
lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);
lv_label_set_text(label1, "Hello World!");
还有一个API函数是直接修改对象的字体:
void lv_obj_set_style_text_font(struct _lv_obj_t * obj, const lv_font_t * value, lv_style_selector_t selector)
测试代码如下
static lv_obj_t *label1 = lv_label_create(btn1);
lv_obj_set_size(label1, LV_PCT(100), LV_PCT(80));
lv_obj_set_style_text_font(label1, &lv_font_montserrat_24, LV_PART_MAIN);
lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);
lv_label_set_text(label1, "Hello World!");
3. 特殊字体
在lv_conf.h中还有6个特殊字体,其宏定义如下:
#define LV_FONT_MONTSERRAT_12_SUBPX 1
#define LV_FONT_MONTSERRAT_28_COMPRESSED 1 /*bpp = 3*/
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1 /*Hebrew, Arabic, Perisan letters and all their forms*/
#define LV_FONT_SIMSUN_16_CJK 1 /*1000 most common CJK radicals*/
#define LV_FONT_UNSCII_8 1
#define LV_FONT_UNSCII_16 0
3.1 SUBPX字体
LV_FONT_MONTSERRAT_12_SUBPX和LV_FONT_MONTSERRAT_12是一样的,区别是SUBPX具有亚像素渲染,即产生更高质量的字母抗锯齿效果,不过对比2者的显示效果:
选择SUBPX并没有任何显示,比较奇怪。
3.2 28像素压缩字体
与普通的28 px字体相同,但压缩字体为3 bpp(每像素位数)。
2者对比如下(左边是28px字体,右边是压缩字体):
区别是字体文件大小不同,可以节约空间,但是牺牲速度。
3.3 16像素希伯来语/阿拉伯语/Perisan字母
lv_obj_set_size(label1, LV_PCT(100), LV_PCT(80));
lv_obj_set_style_text_font(label1, &lv_font_dejavu_16_persian_hebrew, LV_PART_MAIN);
lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);
lv_label_set_text(label1, "Hello World! - مرحبا");
测试阿拉伯语,显示效果一样。
这部分显示规则需要设置LV_USE_BIDI为1,即支持双向文本。
3.4 16像素中文字体
该字体包含1000个最常见的CJK部首。CJK,是CJK Unified Ideographs的缩写,意思是“中日韩统一表意文字”,把分别来自中文、日文、韩文、越文中,本质、意义相同、形状一样或稍异的表意文字赋予相同编码。
lv_obj_set_size(label1, LV_PCT(100), LV_PCT(80));
lv_obj_set_style_text_font(label1, &lv_font_simsun_16_cjk, LV_PART_MAIN);
lv_obj_align(label1, LV_ALIGN_CENTER, 0, 0);
lv_label_set_text(label1, "Hello World! - 你好");
3.5 8像素Ascii字体
UNSCII_8和UNSCII_16字体都是1bpp,适合单色屏使用,占用的空间比较小。
3.6 16像素Ascii字体
3.7 内置图标
内置图标是和字体相关的,例如lv_font_unscii_16就没有这些图标。
显示这些图标,可以直接使用LVGL定义好的宏定义,例如:
lv_label_set_text_fmt(label1, LV_SYMBOL_OK"Hello World!%d", 12);
4. 超大字体
当需要使用大字体时需要将宏定义LV_FONT_FMT_TXT_LARGE设置为1。2者的区别如下:
#if LV_FONT_FMT_TXT_LARGE == 0
uint32_t bitmap_index : 20; /**< Start index of the bitmap. A font can be max 1 MB.*/
uint32_t adv_w : 12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored).*/
uint8_t box_w; /**< Width of the glyph's bounding box*/
uint8_t box_h; /**< Height of the glyph's bounding box*/
int8_t ofs_x; /**< x offset of the bounding box*/
int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
#else
uint32_t bitmap_index; /**< Start index of the bitmap. A font can be max 4 GB.*/
uint32_t adv_w; /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored).*/
uint16_t box_w; /**< Width of the glyph's bounding box*/
uint16_t box_h; /**< Height of the glyph's bounding box*/
int16_t ofs_x; /**< x offset of the bounding box*/
int16_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
#endif
5. 编码方式
#define LV_TXT_ENC LV_TXT_ENC_UTF8
LVGL支持2种编码方式,LV_TXT_ENC_UTF8和LV_TXT_ENC_ASCII。ASCII码只能支持英文,UTF8可以支持所有的文字显示。
6. 添加字体
6.1 在线字体转换器
https://lvgl.io/tools/fontconverterhttps://lvgl.io/tools/fontconverter
字体名字对应生成的文件名和字体变量名。
const lv_font_t lv_font_alibaba_regular_12 =
Range是Unicode范围,这是如果填入0xff00到0xffff就会提示错误。
编码范围 | 字符数量 | 编码内容 |
---|---|---|
0x0020-0x007F | 96 | ASCII码 |
0x0080-0x00BF | 64 | ASCII码增补(™ © ) |
0x2600-0x26FF | 256 | 各种符号(☆ ♂ ♫ ♡ ) |
0x3000-0x301F | 32 | CJK符号(《 【 ) |
0x3040-0x309F | 94 | 日文平假名 |
0x30A0-0x30FF | 94 | 日文片假名 |
0x4E00-0x9FAF | 20902 | 所有简体、繁体、日文汉字 |
0xAC00-0xD7A3 | 11172 | 韩文音节 |
0xFF00-0xFF64 | 100 | 全角英文数字与标点 |
Symbols是将需要的文字填入即可。
6.2 载入字体
将生成的c文件加入工程,然后在lv_conf.h中找到LV_FONT_CUSTOM_DECLARE添加这个字体
#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(lv_font_montserrat_24)
多个字体则空格连续添加即可。
这个字体没有对应的图标,所以 LV_SYMBOL_OK并没有显示对。
7. 加载二进制字体文件
LVGL默认是用c文件导入到工程中实现字体的加载。如果使用外部存储的话,需要动态加载二进制文件的方式实现。
lv_font_t * lv_font_load(const char * font_name)
注意,要加载字体,需要启用LVGL的文件系统,并添加驱动程序。