LVGL学习笔记8 - 字体

31 篇文章 96 订阅

目录

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-0x007F96ASCII码
0x0080-0x00BF64ASCII码增补( ©
0x2600-0x26FF256各种符号(   )
0x3000-0x301F32CJK符号( 
0x3040-0x309F94日文平假名
0x30A0-0x30FF94日文片假名
0x4E00-0x9FAF20902所有简体、繁体、日文汉字
0xAC00-0xD7A311172韩文音节
0xFF00-0xFF64100全角英文数字与标点

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的文件系统,并添加驱动程序。

以下是一个用于读取SD卡中图片并显示在LCD上的代码示例: ``` #include <SD.h> #include <Adafruit_ILI9341.h> #include <Adafruit_GFX.h> #define TFT_CS 10 #define TFT_RST 9 #define TFT_DC 8 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST); void setup() { // 初始化SD卡 if (!SD.begin(4)) { tft.println("SD卡初始化失败"); return; } // 初始化LCD tft.begin(); tft.fillScreen(ILI9341_BLACK); tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); tft.setTextSize(2); tft.setCursor(10, 10); tft.println("正在读取图片..."); // 打开图片文件 File imageFile = SD.open("image.bmp"); if (!imageFile) { tft.println("打开图片失败"); return; } // 读取图片文件头信息 uint32_t imageSize = imageFile.size(); uint32_t imageOffset = (uint32_t)imageFile.position(); uint32_t imageStart = imageOffset + 54; // 假设图片文件头为54字节 // 将文件指针移到图片数据开始处 imageFile.seek(imageStart); // 读取图片数据并在LCD上显示 uint16_t imageColor; for (uint32_t i = imageStart; i < imageSize; i += 2) { uint8_t colorBuf[2] = {0}; imageFile.read(colorBuf, 2); imageColor = makeColor(colorBuf[0], colorBuf[1]); // 自定义函数用于将两个字节转换为16位颜色值 tft.drawPixel(x, y, imageColor); // 更新坐标 x++; if (x >= tft.width()) { x = 0; y++; } } // 关闭文件 imageFile.close(); tft.println("图片读取完成"); } void loop() { // 程序循环主体 } uint16_t makeColor(uint8_t r, uint8_t g, uint8_t b) { return tft.color565(r, g, b); } ``` 以上代码使用了Arduino的SD库和Adafruit公司的ILI9341库来实现对SD卡中图片的读取以及在LCD上的显示。首先,代码需要初始化SD卡和LCD。然后,它会打开指定的图片文件,并读取文件头信息以确定图片数据的起始位置。接下来,代码通过读取图片数据并使用`drawPixel`函数将每个像素点显示在LCD上。最后,文件被关闭并在LCD上显示读取完成的提示信息。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值