littlevgl抗锯齿_「VGL」littlevGL:字体与汉字 - seo实验室

这篇博客详细介绍了如何在littlevGL中使用和自定义字体,包括内置字体的配置、自定义字体的生成与应用,以及通过外置字体实现大字体在MCU上的显示,特别提到了抗锯齿和汉字支持。

VGL

使用各种嵌入式GUI时,总会遇到“汉字显示”“字体”这些关卡。

阅读本文前,最好已经了解Uincode,UTF-8,UTF-16,GBK,gb2312相关知识,不懂最好网络搜索相关知识。

1.内置字体

littlevGL内置了好几种字体。在lv_conf.h中开关相关字体

/*==================

* FONT USAGE

*===================*/

/* More info about fonts: https://littlevgl.com/basics#fonts

* To enable a built-in font use 1,2,4 or 8 values

* which will determine the bit-per-pixel */

#define USE_LV_FONT_DEJAVU_10 0

#define USE_LV_FONT_DEJAVU_10_LATIN_SUP 0

#define USE_LV_FONT_DEJAVU_10_CYRILLIC 0

#define USE_LV_FONT_symbol_10 0

#define USE_LV_FONT_DEJAVU_20 4

#define USE_LV_FONT_DEJAVU_20_LATIN_SUP 0

#define USE_LV_FONT_DEJAVU_20_CYRILLIC 0

#define USE_LV_FONT_SYMBOL_20 4

#define USE_LV_FONT_DEJAVU_30 0

#define USE_LV_FONT_DEJAVU_30_LATIN_SUP 0

#define USE_LV_FONT_DEJAVU_30_CYRILLIC 0

#define USE_LV_FONT_SYMBOL_30 0

#define USE_LV_FONT_DEJAVU_40 0

#define USE_LV_FONT_DEJAVU_40_LATIN_SUP 0

#define USE_LV_FONT_DEJAVU_40_CYRILLIC 0

#define USE_LV_FONT_SYMBOL_40 0

#define USE_LV_FONT_MONOSPACE_8 0

其中0代表不使用,1,2,4,8使能并设置抗锯齿值。

字体文件在lv_fonts文件夹下。

littlevGL支持UTF-8。在lv_conf.h中开启UTF8

/*Text settings*/

#define LV_TXT_UTF8 1 /*Enable UTF-8 coded unicode character usage */

2.自定义字体

littlevGL支持自定义字体。

官方字体生成网站:https://littlevgl.com/ttf-font-to-c-array

不知为何作者没有发布离线字体生成工具。我打算过段时间有空就自己用C#写一个。

生成的字体文件类似于lv_fonts文件夹下面的各种字体文件,使用方式也一样。

使用之前需要把源文件转为UTF8格式。

//myfont是自定义的字体

void lv_tutorial_fonts(void)

{

static lv_style_t style1;

char *str="我的祖国\nis 好好的!";

/*Create a style and use the new font*/

lv_style_copy(&style1, &lv_style_plain);

style1.text.font = &myfont;

/*Create a label and set new text*/

lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);

lv_obj_set_pos(label, 100, 10);

lv_label_set_style(label, &style1);

lv_label_set_text(label, str );

}

3.外置字体

上面的方法只适合字体文件比较小的情况,要是字体太大,放不进MCU,那就需要更进一步。

对源文件的显示字体源码分析后,发现关键在于字体结构

typedef struct _lv_font_struct

{

uint32_t unicode_first;

uint32_t unicode_last;

const uint8_t * glyph_bitmap;

const lv_font_glyph_dsc_t * glyph_dsc;

const uint32_t * unicode_list;

const uint8_t * (*get_bitmap)(const struct _lv_font_struct *,uint32_t); /*Get a glyph's bitmap from a font*/

int16_t (*get_width)(const struct _lv_font_struct *,uint32_t); /*Get a glyph's with with a given font*/

struct _lv_font_struct * next_page; /*Pointer to a font extension*/

uint32_t h_px :8;

uint32_t bpp :4; /*Bit per pixel: 1, 2 or 4*/

uint32_t monospace :8; /*Fix width (0: normal width)*/

uint16_t glyph_cnt; /*Number of glyphs (letters) in the font*/

} lv_font_t;

打开一个字体文件,其中字体定义

lv_font_t lv_font_dejavu_20 = {

.unicode_first = 32, /*First Unicode letter in this font*/

.unicode_last = 126, /*Last Unicode letter in this font*/

.h_px = 20, /*Font height in pixels*/

.glyph_bitmap = lv_font_dejavu_20_glyph_bitmap, /*Bitmap of glyphs*/

.glyph_dsc = lv_font_dejavu_20_glyph_dsc, /*Description of glyphs*/

.glyph_cnt = 95, /*Number of glyphs in the font*/

.unicode_list = NULL, /*Every character in the font from 'unicode_first' to 'unicode_last'*/

.get_bitmap = lv_font_get_bitmap_continuous, /*Function pointer to get glyph's bitmap*/

.get_width = lv_font_get_width_continuous, /*Function pointer to get glyph's width*/

#if USE_LV_FONT_DEJAVU_20 == 1

.bpp = 1, /*Bit per pixel*/

#elif USE_LV_FONT_DEJAVU_20 == 2

.bpp = 2, /*Bit per pixel*/

#elif USE_LV_FONT_DEJAVU_20 == 4

.bpp = 4, /*Bit per pixel*/

#elif USE_LV_FONT_DEJAVU_20 == 8

.bpp = 8, /*Bit per pixel*/

#endif

.monospace = 0,

.next_page = NULL, /*Pointer to a font extension*/

};

上面代码,lv_font_get_bitmap_continuous()函数为字体点阵获取函数,返回的是对应字符在点阵数组的位置。

另外还有些字体使用的是lv_font_get_bitmap_sparse();这两个函数功能是一样的。

由此,我们可以仿照此函数,想办法从外部存储器获得某个字符的点阵数据,并且保存在一个静态数组里,最后返回此数组首地址即可。

要完成这些,前提是1.把字符的点阵数组转化为BIN文件(去原子的论坛搜索下载C2B 1.1版本,2.0版本有BUG);2.把此文件弄到外置存储器。

对于第2点。有很多方法。比如通过写一个PC串口助手把文件发送烧写进SPI flash(W25QXX之类);或者直接使用专门的烧录工具写进SPI flash;或者偷懒,直接放在SD卡里让MCU调用。

这里我使用偷懒的方法,把字体文件放到SD卡里,以文件的形式读取数据。必须要说明,此方法频繁地进行文件操作,速度不咋地(最好把堆栈调大些,否则可能溢出)。

内置的字体点阵获取函数

/**

* Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)

* @param font pointer to font

* @param unicode_letter an unicode letter which bitmap should be get

* @return pointer to the bitmap or NULL if not found

*/

const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unicode_letter)

{

/*Check the range*/

if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) return NULL;

uint32_t i;

for(i = 0; font->unicode_list[i] != 0; i++) {

if(font->unicode_list[i] == unicode_letter) {

return &font->glyph_bitmap[font->glyph_dsc[i].glyph_index];

}

}

return NULL;

}

仿照上面,自定义的函数

//look above

const uint8_t * ex_lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unicode_letter)

{

uint8_t * pval=NULL;

uint32_t i;

/*Check the range*/

if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last){ return NULL;}

for(i = 0; font->unicode_list[i] != 0; i++)

{

if(font->unicode_list[i] == unicode_letter)

{

FIL Binfile;

FRESULT res;

uint32_t br,fsize;

i=font->glyph_dsc[i].glyph_index;

res=f_open(&Binfile, (const TCHAR*)font->glyph_bitmap ,FA_OPEN_EXISTING|FA_READ);

if(res != FR_OK) { return NULL;}

fsize = Binfile.fsize ;

if(i+LetterSIZE <= fsize)

{

f_lseek(&Binfile,i );

res = f_read(&Binfile, letterBuff ,LetterSIZE ,&br);

if( res == FR_OK && ( br == LetterSIZE || br == LetterSIZE/2 ) || br==0 )

{

pval=letterBuff;

}

}

f_close(&Binfile);

return pval;

}

}

return NULL;

}

然后要把字体的点阵数组删除,在字体定义里修改.glyph_bitmap和.glyph_bitmap成员。如下

lv_font_t myfont =

{

.unicode_first = 32, /*First Unicode letter in this font*/

.unicode_last = 40664, /*First Unicode letter in this font*/

.h_px = 37, /*Font height in pixels*/

.glyph_bitmap = "0:/FONT/HZ1A.bin", /*Bitmap of glyphs*/

.glyph_dsc = glyph_dsc, /*Description of glyphs*/

.unicode_list = unicode_list, /*List of unicode characters*/

.get_bitmap = ex_lv_font_get_bitmap_sparse, /*Function pointer to get glyph's bitmap*/

.get_width = lv_font_get_width_sparse, /*Function pointer to get glyph's width*/

.bpp = 1, /*Bit per pixel*/

.next_page = NULL, /*Pointer to a font extension*/

};

"0:/FONT/HZ1A.bin"是字体文件路径。

再次说明,此方法不应该在实际项目中使用,效率不好。建议把字体文件按地址烧录进SPI flash,需要的时候再按照地址直接读取。上面的".glyph_bitmap"可赋值为该地址。原理都是一样的。

19f9923721a1c899325ea0fe7dca21f0.png

相关阅读

一、Qt环境设置文件从window上传到Ubuntu后会显示乱码,原因是因为ubuntu环境设置默认是utf-8,Windows默认都是GBK.Windows环境下,

免费轻松识别手写汉字工具-python话不多说,先上效果图!开发过程小工具打包为.exe程序了。[下载连接](https://download.csdn.net/do

首先,什么是Unicode,百科知识:Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等;Unicode

背景:

对接第三方接口需要传个age和ageTyoe字段,其中age字段为integer型,ageType取“岁/月/天”,但是我们系统存的年龄格式为N岁M月,

1.

/**

*PHP汉字转拼音

*@authorJerryli(hzjerry@gmail.com)

*@versionV0.20140715

*@packageSPFW.core.lib.final

*@globa

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值