LittleVGL (LVGL)干貨入門教程四之制作和使用中文漢字字庫
前言:
閱讀前,請確保你至少擁有以下條件:
- 已實作顯示API(教程一已實作, 鏈接:LittleVGL (LVGL)入門教程一之移植到stm32芯片)
- 已實作輸入設備API(教程二已實作,鏈接:LittleVGL (LVGL)干貨入門教程二之LVGL的輸入設備(indev)API對接,)
- 已實作檔案系統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可使用此buff
static 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;
else
memset(__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 必須要為static
lv_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_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
下一篇
待續,,,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/254818.html
標籤:其他
