使用各种嵌入式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:字体与汉字相关推荐

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

    VGL 使用各种嵌入式GUI时,总会遇到"汉字显示""字体"这些关卡. 阅读本文前,最好已经了解Uincode,UTF-8,UTF-16,GBK,gb2312相 ...

  2. c语言输出不同字体的汉字,【】c语言中输出汉字的编码

    []c语言中输出汉字的编码 (2012-03-25 22:10:04) 标签: c语言 汉字编码 杂谈 分类: C语言 C语言中,我们用整数输出字符得到的就是该字符的ASII码,如用整数输出a,得到9 ...

  3. 精简TTF字体、汉字字体瘦身 FontPruner,并转化为Base64编码

    网上比应用比较多的 字蛛 http://font-spider.org/ 本文使用了本机安装软件,得到瘦身后的 TTF 字体文件 一.使用FontPruner为字体瘦身 准备工具: python : ...

  4. 【原创】在RT1050 LittleVgl GUI中嵌入中文输入法框架

    时隔一年多终于又冒泡了,哎,随着工作越来越忙,自己踏实坐下来写点东西真是越来越费劲,这篇文章也是准备了好久好久才打算发表出来(不瞒大家,东西做完好久了,文章憋了一年了,当真"高产" ...

  5. 查看linux主机是否安装宋体码,Linux 安装宋体字体的简单办法

    1. 今天同事说测试环境(CentOS) 打印有异常,无法将汉字正常打印出来. 2. 开发同事提供的思路是安装上宋体的字体再进行尝试,并且给出了一个解决方案的地址: https://blog.csdn ...

  6. 在.Net Micro Framework中显示汉字

    摘要:MF平台支持的字体是专有格式,扩展名为tinyfnt,需要用专门的转化工具才能把windows平台上的字体转换为tinyfnt字体.在.Net Micro Framework SDK中提供了一个 ...

  7. 汉字笔画数据_把所有汉字叠起来会怎样?

    本文基于对此话题的知乎回答补充而成: https://www.zhihu.com/question/394175264/answer/1221223455 背景介绍 「把所有汉字叠写起来会怎么样呢?」 ...

  8. 基于springMVC的汉字与数学计算的图片验证码

    @RequestMapping(value = URLConsts.UserLoginH5Controller.GET_CODE) public void getCode(HttpServletReq ...

  9. python 生成文字图片_[ImageFont] 如何利用字体生成文字图片

    在OCR识别.检测的数据生成过程当中,我们经常会需要利用字体生成汉字的图片,在Python当中,这一部分的操作通常是通过Pillow 模块提供的ImageFont 模块来完成,下面我们用一个例子,介绍 ...

最新文章

  1. 中班音乐 机器人教案_幼儿园中班音乐活动教案《机器人》
  2. Spring学习(8)--- @Autowired注解(一)
  3. 入职五年回顾(十六) 2013年11月
  4. 国内电商场景大战中,企业如何寻找有效增长点?这里有答案了
  5. 【数据分析】《唐探3》口碑急转直下?看看影迷们到底都说了些啥
  6. python列表元组_Python列表元组操作
  7. sql net message from client
  8. Linux /etc/login.defs配置文件
  9. 从Web抓取信息的几个常用方法
  10. 使用R语言中的spgwr包进行GWR模型的相关运算
  11. vb.net 教程 1-20 例
  12. 鼠标测试软件m,[论坛]魔技无线激光鼠标测试心得(二)
  13. android 4.4新功能介绍(Kitkat)
  14. 舱机器人尾巴毛茸茸_这个毛茸茸的机器人不仅可撸,还会摇尾巴
  15. Hulu:视频广告系统中的算法实践
  16. 将任意自然数分解为质数的乘积(Java实现)
  17. python去除最后的逗号_Python如何从打印中删除最后一个逗号(string,end=“,”)...
  18. 经典的运维脚本三步曲
  19. 如何有效实现软件的需求管理 - 8 (全文完)
  20. 技术文摘5 发展 礼品

热门文章

  1. 1.15.ARM汇编指令3之逻辑指令
  2. 台达PLC通讯程序,PLC采用台达,触摸屏采用中达电通触摸屏软件编辑
  3. chkdsk磁盘修复
  4. 磁盘管理虚拟磁盘服务器,云服务器磁盘管理工具
  5. 20个月股票投资经验全面总结,买格力电器也能亏钱,牛逼企业的股票,竟然由傻瓜在定价
  6. unity塔防游戏怪物转向_怪兽塔防手机版下载-怪兽塔防游戏下载v1.4 安卓版
  7. Spring MVC 入门概要 1
  8. DRF(django restframework)-数据库查询结果序列化
  9. live555源码分析----关于mp3的处理
  10. JAVA poi合并任意列 相同数据单元格