LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库


前言:

阅读前,请确保你至少拥有以下条件:

  1. 已实现显示API(教程一已实现, 链接:LittleVGL (LVGL)入门教程一之移植到stm32芯片)
  2. 已实现输入设备API(教程二已实现,链接:LittleVGL (LVGL)干货入门教程二之LVGL的输入设备(indev)API对接。)
  3. 已实现文件系统API(教程三已实现,链接:LittleVGL (LVGL)干货入门教程三之LVGL的文件系统(fs)API对接)

这篇文章会讲

  • LVGL字库的制作
  • LVGL的字库的各种使用方式(本文重点)

目录:

  • LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库
      • 前言:
    • 一、LVGL字库的种类介绍。
    • 二、字库如何制作?
    • 三、如何使用字库?
      • (一)添加外部或内部字库。
        • (1)内部字库
        • (2)外部字库
      • (二)声明制作好的字库。
      • (三)对接字库API。
      • (四)使用字库
      • (五)KEIL MDK中文编译报错
    • 五、启动LVGL
  • 本篇完
  • 其他:
  • 下一篇

字库的原理就不赘述了,百度一大把,主要就是不同编码字库的每个字,都按照不同的方式排列,根据编码可以进行搜索和定位,最后提取字库并用点阵方式显示就行,PC上多用矢量字体(使用顶点和曲线),一般最简单的方法就是使用点阵字体(也是很常用的形式)。


一、LVGL字库的种类介绍。

  • 内部大数组(字体体量小时常用,如纯英文字体)
  • 外部bin文件(字体体量大时常用,如中文字体)

二、字库如何制作?

事实上,字库的制作有专用的工具,例如LVGL的官网提供在线字库转换工具(没网络就不行了,甚至经常抽风,本人就没有成功过,就不讲了,有兴趣可以自己试试)。
有兴趣的话也可以去LVGL官网了解字体相关的接口。
也有第三方大神制作的离线字库转换工具,并且非常简单实用。

可以去这个作者的网站下载:
LVGL字体转换工具:LvglFontTool
LVGL字体乱码:Lvgl之显示汉字出现乱码


三、如何使用字库?

(一)添加外部或内部字库。

(1)内部字库

直接把生成的C文件添加进项目编译即可,C文件里面包含了字库的查找函数和位图等,和一些LVGL的字库接口,当然不需要你亲自使用,只是为LVGL提供操作接口。

(2)外部字库

当你使用上述的LvglFontTool进行外部字体转换后,会得到两个文件,假如我的字体名为“font”,那么生成的这两个文件名为“font.c”和“font.bin”,C文件提供了字库的查找函数(不需要你使用,只是为LVGL提供操作接口)和使用字库的API(需要自行对接API),bin文件即字库文件。

(二)声明制作好的字库。

当你使用上述工具制作好字库后,会得到字库名,你可以通过三种方法调用这个字库:

第一种:

extern lv_font_t font_name;      /* 第一种 */

第二种:

LV_FONT_DECLARE(font_name);      /* 第二种,其实就是把第一种封装起来了 */

第三种(改lv_conf.h):
在 lv_conf.h 里找到宏定义 “LV_FONT_CUSTOM_DECLARE”:

/* 各种不同的声明,这里的字体名由你自己生成的字体名决定,可以自己添加修改 */
#define LV_FONT_CUSTOM_DECLARE  LV_FONT_DECLARE( ariblk_12 )            \LV_FONT_DECLARE( ariblk_14 )            \LV_FONT_DECLARE( ariblk_16 )            \LV_FONT_DECLARE( ariblk_36_num )        \LV_FONT_DECLARE(MSYH_BD_12_CN)

上面的操作仅仅是声明而已。

(三)对接字库API。

使用就基本没什么不同了,下文会统一说怎么使用,但区别在于,外部字库的C文件需要对接一个API,实现提取存储设备字库文件指定偏移内容的功能(例如把字库文件放在SD卡或者SPI Flash里,把里面的内容提取给LVGL使用)。

生成外部字库的C文件后,找到函数 “__user_font_getdata” 和数组 “__g_font_buf” 。

/* 如果你没有外部RAM(外部SRAM、SDRAM等),就取消__g_font_buf的注释 */
/* 这里的__g_font_buf大小为323,这个参数是转换工具自动生成的,不需要改, */
/* 不同大小的字体buf大小不同 */
static uint8_t __g_font_buf[323];   //如bin文件存在SPI FLASH可使用此buffstatic uint8_t *__user_font_getdata(int offset, int size) {/* 这里提供几种思路:* 一、 如果已加载字体文件到外部RAM,那么直接返回外部RAM字体文件的*     基址+offset。* 二、 如果你没有外部RAM,则有两种方法提取数据:*     1. 使用FS(文件系统)的API,如open、read等。*      2. 不使用FS(效率高),直接通过你实现的最底层读取函数提取offset位置的*        数据到__g_font_buf里* * 下面实现三种不同方法*//* 1 使用SDRAM,前提是你提前加载字体文件到SDRAM的某个地址 */return (uint8_t*)((uint32_t)(SDRAM_FONT_BASE_ADDR + offset)); /* 2 直接使用最底层FLASH读取函数 *//* spi flash读取指定偏移地址函数 */sf_of_read(__g_font_buf, offset, size);return __g_font_buf;/* 3 使用FATFS,这种方法效率极低,因为LVGL会在画面发生变化时频繁读取文件 *//* 阻塞情况非常严重,仅适用于RAM有限的情况,不然不是首选 */FRESULT fres = FR_NOT_READY;FIL file = {0};fres = f_open(&file, font_path, FA_OPEN_EXISTING | FA_READ);if (fres != FR_OK)goto __out;      // goto常用于错误处理fres = f_lseek(&file, offset);       // 寻址if (fres != FR_OK)goto __out;     fres = f_read(&file, __g_font_buf, NULL, NULL);if (fres == FR_OK)    // 成功则直接返回goto __out;       elsememset(__g_font_buf, 0, sizeof(__g_font_buf));  // 清空数组__out:if (file)f_close(&file);return __g_font_buf;
}

如果你完成了上述的API对接,那么接下来把C文件加入工程编译,并且把bin字库文件烧写到spi flash或者使用文件系统放入文件即可。

(四)使用字库

接下来算是重头戏了,就是如何使用字库,使用方面的话,无论是内部还是外部的字库,操作都是一样的,下面给出例程,例程创建了一个label,并用2种不同方式使用font,并居中显示中文文字:

#include <lvgl.h>
#include "main.h"#define LVGL_TICK    10/************************************************* @brief font example** @param method*        1: example 1*        0: example 2*************************************************/
static void lvgl_font_test(uint8_t method)
{static lv_style_t label_style ={ 0 }; // style 必须要为staticlv_obj_t* label1 = NULL;label1 = lv_label_create(lv_scr_act(), NULL);lv_label_set_recolor(label1, true);lv_label_set_text(label1, (LV_SYMBOL_HOME "你好 #ff0000 Trisuborn"));lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0);LV_FONT_DECLARE(font_name); // 声明过了就不用if ( method ) {lv_style_set_text_font(&label_style, LV_STATE_DEFAULT, &font_name);lv_obj_add_style(label1, LV_LABEL_PART_MAIN, &label_style);} else {lv_obj_set_style_local_text_font(label1,LV_LABEL_PART_MAIN,LV_STATE_DEFAULT,&font_name);}
}/* 文档里一种动态加载字体的方法 */
static void lvgl_font_test2(void)
{lv_font_t * my_font;my_font = lv_font_load(X/path/to/my_font.bin);/*Use the font*/lv_obj_t* label2 = lv_label_create(lv_scr_act(), NULL);lv_obj_set_style_local_text_font(label2,LV_LABEL_PART_MAIN,LV_STATE_DEFAULT,my_font);lv_label_set_text(label2, (LV_SYMBOL_HOME "你好 世界"));lv_obj_align(label2, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);/*Free the font if not required anymore*/lv_font_free(my_font);
}/* LVGL初始化 */
static void lvgl_init( void )
{lv_init();lv_port_disp_init();        // 显示器初始化lv_port_indev_init();       // 输入设备初始化lv_port_fs_init();          // 文件系统设备初始化
}/****************************************************************/
int main(void)
{lvgl_init();lvgl_font_test(1);// lvgl_font_test(0);// lvgl_font_test2();while(1) {lv_tick_inc(LVGL_TICK);lv_task_handler();delay_ms(LVGL_TICK);}
}
/****************************************************************/

(五)KEIL MDK中文编译报错

编译时,打开Option for target,打开C/C++选项卡,在 “Misc Controls”一栏填入 “–locale=english” 。


五、启动LVGL

参考我的第一篇文章即可:
LittleVGL (LVGL)干货入门教程一之移植到stm32芯片


本篇完


其他:

LittleVGL (LVGL)干货入门教程一之移植到stm32芯片

LittleVGL (LVGL)干货入门教程二之LVGL的输入设备(indev)API对接。

LittleVGL (LVGL)干货入门教程三之LVGL的文件系统(fs)API对接

个人Github页:https://github.com/Trisuborn


下一篇

待续。。。


LittleVGL (LVGL)干货入门教程四之制作和使用中文汉字字库相关推荐

  1. LittleVGL (LVGL)干货入门教程二之LVGL的输入设备(indev)API对接。

    LittleVGL (LVGL)干货入门教程二之LVGL的输入设备(indev)API对接 前言: 阅读前,请确保你拥有以下条件: 你已经完成"显示API"的移植. 你已经实现了一 ...

  2. docker 镜像修改的配置文件自动还原_原创 | 全网最实在的docker入门教程四

    作者:潘吉祥 上一篇我们学习了如何使用Dockerfile制作自己的镜像,不过这种方式更像纯粹的运维方式,作为开发者来说,未免有些小繁琐,一个不小心写错些命令就执行失败,我们还不知道错误在哪,这着实有 ...

  3. docker registry push 覆盖_原创 | 全网最实在的docker入门教程四

    原创头条号:码农code之路,作者:潘吉祥,转载请标明出处 上一篇我们学习了如何使用Dockerfile制作自己的镜像,不过这种方式更像纯粹的运维方式,作为开发者来说,未免有些小繁琐,一个不小心写错些 ...

  4. Python+Opencv图像处理新手入门教程(四):视频内容的读取与导出

    一步一步来吧 上一节: Python+Opencv图像处理新手入门教程(三):阈值与二值化 1.Intro 今天这节我们主要看怎么利用opencv读取并处理视频中的内容. 2.VideoCapture ...

  5. (原创)LEON3入门教程(四):基于AMBA APB总线的七段数码管IP核设计

    摘要:这一小节将介绍下如何设计用户自定义的APB IP,并将IP嵌入到SOPC中去.一个APB IP核的主要分为三个部分:逻辑单元.寄存器单元和接口单元.所设计的IP是一个简单的七段数码管显示IP,只 ...

  6. python画图颜色表示大小变化_python画图(线条颜色、大小、类型:点、虚线等)(图文详细入门教程四)...

    初衷 本人由于平常写论文需要输出一些结果图,但是苦于在网上搜python画图时,详细的教程非常多,但是就是找不到能马上解决自己问题那一行代码,所以打算写一些适合需求简单的朋友应急用的教程,应急就必须方 ...

  7. SpringCloud 入门教程(四): 分布式环境下自动发现配置服务

    前一章, 我们的Hello world应用服务,通过配置服务器Config Server获取到了我们配置的hello信息"hello world". 但自己的配置文件中必须配置co ...

  8. Spring Boot入门教程(四十):微信支付集成-刷卡支付

    分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 一:准备工作 使用微信支付需要先开通服务号,然后还要开通微信支付,最后还要配置一些开发参数,过程比较多. 申请服务号(企业 ...

  9. Spring Boot入门教程(四十一):微信支付集成-扫码支付

    分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 一:准备工作 使用微信支付需要先开通服务号,然后还要开通微信支付,最后还要配置一些开发参数,过程比较多. 申请服务号(企业 ...

最新文章

  1. silverlight、wpf中 dispatcher和timer区别
  2. OPenCv java 形态学操作(12)
  3. 复制活动记录记录的最简单方法是什么?
  4. 通用串行总线集线器(Universal SerialBus HUB)什么是USB集线器(USB HUB)?什么是USB根集线器(USB ROOT HUB)?如何判断一个USB口是独立的还是集线器上的?
  5. matlab 大括号
  6. 用 CSS 实现元素垂直居中,有哪些好的方案?
  7. snowflake 数据库_Snowflake数据分析教程
  8. 从没想过会有一个这样的机会|大疆招聘
  9. SQL Azure (15) SQL Azure 新的规格
  10. nodejs 游戏框架_Pomelo:网易开源基于 Node.js 的游戏服务端框架
  11. 在美国租房子需要考虑什么问题?
  12. ChinaSoft 论坛巡礼 | CCF-华为胡杨林基金-系统软件专项论坛
  13. python动画篮球大小_用Python把蔡徐坤打篮球视频转换成字符动画!
  14. 批量清理VS编译产生的文件
  15. NR协议学习——RLC
  16. 热插拔48块硬盘服务器,中云网眼WEM-SAN100/48B48盘位网络存储设备IP-SAN
  17. android system.err 是什么意思,android – java.lang.IllegalStateException是什么意思?
  18. 攻防世界 Pwn 进阶 第二页
  19. 人体的神经系统结构图,身体的神经系统图片
  20. 盘点那些产品经理经常逛的网站/论坛

热门文章

  1. xp计算机远程桌面设置密码,win7远程桌面连接xp 图解win7远程管理xp桌面
  2. ssm+jsp电影院在线订票选座管理系统 java
  3. 安全起见,如何修改ssh默认的22端口号
  4. 假设电话收费标准为: (1)国际长途1.00元/分钟,(2) 国内长途0.60元/分钟,(3)市话前3分钟0.20元,3分钟以后0.10元/分钟。现假设某话单文件中每条话单包含如下信息:通话日期(10
  5. Mac vmware 黑屏
  6. 用计算机打出自己的终身伴侣,ZT嫁人就要嫁玩CS的男人
  7. Hash(哈希(字符串哈希))模板和做题总结(详细易懂)
  8. mysql 数据筛选
  9. LSTM模型内部结构
  10. 前端开发指南:HTML5与CSS3知识点总结