littlevGL:字体与汉字
使用各种嵌入式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"可赋值为该地址。原理都是一样的。
littlevGL:字体与汉字相关推荐
- littlevgl抗锯齿_「VGL」littlevGL:字体与汉字 - seo实验室
VGL 使用各种嵌入式GUI时,总会遇到"汉字显示""字体"这些关卡. 阅读本文前,最好已经了解Uincode,UTF-8,UTF-16,GBK,gb2312相 ...
- c语言输出不同字体的汉字,【】c语言中输出汉字的编码
[]c语言中输出汉字的编码 (2012-03-25 22:10:04) 标签: c语言 汉字编码 杂谈 分类: C语言 C语言中,我们用整数输出字符得到的就是该字符的ASII码,如用整数输出a,得到9 ...
- 精简TTF字体、汉字字体瘦身 FontPruner,并转化为Base64编码
网上比应用比较多的 字蛛 http://font-spider.org/ 本文使用了本机安装软件,得到瘦身后的 TTF 字体文件 一.使用FontPruner为字体瘦身 准备工具: python : ...
- 【原创】在RT1050 LittleVgl GUI中嵌入中文输入法框架
时隔一年多终于又冒泡了,哎,随着工作越来越忙,自己踏实坐下来写点东西真是越来越费劲,这篇文章也是准备了好久好久才打算发表出来(不瞒大家,东西做完好久了,文章憋了一年了,当真"高产" ...
- 查看linux主机是否安装宋体码,Linux 安装宋体字体的简单办法
1. 今天同事说测试环境(CentOS) 打印有异常,无法将汉字正常打印出来. 2. 开发同事提供的思路是安装上宋体的字体再进行尝试,并且给出了一个解决方案的地址: https://blog.csdn ...
- 在.Net Micro Framework中显示汉字
摘要:MF平台支持的字体是专有格式,扩展名为tinyfnt,需要用专门的转化工具才能把windows平台上的字体转换为tinyfnt字体.在.Net Micro Framework SDK中提供了一个 ...
- 汉字笔画数据_把所有汉字叠起来会怎样?
本文基于对此话题的知乎回答补充而成: https://www.zhihu.com/question/394175264/answer/1221223455 背景介绍 「把所有汉字叠写起来会怎么样呢?」 ...
- 基于springMVC的汉字与数学计算的图片验证码
@RequestMapping(value = URLConsts.UserLoginH5Controller.GET_CODE) public void getCode(HttpServletReq ...
- python 生成文字图片_[ImageFont] 如何利用字体生成文字图片
在OCR识别.检测的数据生成过程当中,我们经常会需要利用字体生成汉字的图片,在Python当中,这一部分的操作通常是通过Pillow 模块提供的ImageFont 模块来完成,下面我们用一个例子,介绍 ...
最新文章
- 在云中进行灾难恢复的五种有效方式
- 用C#制作新闻阅读器(电脑报2005年3月14日 第10期)
- 【机器学习】正则化的线性回归 —— 岭回归与Lasso回归
- LightOJ - 1071 Baker Vai(最大费用最大流+拆点)
- 前端怎么获取cookie的值_京东购物小程序cookie方案实践(附Demo)
- linux ubuntu 12.04 下默认是安装了openjdk的
- 映射网络驱动器 net use
- 在php定界符中,PHP中的定界符 - ho俊的个人空间 - OSCHINA - 中文开源技术交流社区...
- 15个非常有用的Adobe Flex教程
- WinEdt中xelatex.exe等exe did not succeed问题
- 关于 appium 启动 app 后闪退的问题 - (已解决)
- 霍夫斯特拉大学计算机科学专业排名,霍夫斯特拉大学排名 - hofstra computer science怎么样...
- 自定义绘制三阶B样条曲线
- 水桶分水问题详解(C++实现)
- NosqlBooster For MongoDB解决License问题
- read-shrinkwrap This version of npm is compatible with lockfileVersion@1, but package-lock.json was
- 程序猿生存指南-57 故友来京
- [Servlet] HttpServletRequest
- veracrypt加密mysql_VeraCrypt使用教程,VeraCrypt文件硬盘加密使用教程
- Html中img自带属性有哪些,HTMLIMG标签的属性是有哪些?了解IMG标签的用法
热门文章
- msfvenom木马生成工具
- WiFi无线网络显示红叉
- 完美解决 bash: /dev/fd/63: No such file or directory
- 共享EXCEL工作簿实现协同录入(转)
- java中UDP实例代码
- #游戏unity-VR场景漫游#有关VR环境的搭建【HTC vive】
- RFC4385:PWE3 Control Word for Use over an MPLS PSN读书笔记
- 数据结构第二版(朱昌杰版)习题五答案
- NLP-预训练模型-2019:ALBert【 轻Bert;使用 “输入层向量矩阵分解”、“跨层参数共享” 减少参数量;使用SOP代替NSP】【较Bert而言缩短训练及推理时间】
- [分享] - (开源)PHP高级境界-网络操作系统(eyeOS)