最近接触LVGL,这是一个轻量级的图形库,在Arduino框架下依赖TFT_eSPI库支持,今天研究一下TFT_eSPI的字库格式,或许可以在一些更轻量的单片机应用中借鉴。
目前TFT_eSPI库使用四种格式的字库,我姑且这样命名:
- 标准字库
- RLE字库
- GFX字库
- 自定义字库
标准字库
这中格式是我们平时最常用的。每个字符根据点阵大小,占用固定储存空间。
例如Font16.c
,该字库每个字符为8x16点阵,每个点对应一个二进制位,所以一个字符占用16字节。
在这里就不进一步分析了。
RLE字库
这也是点阵字库,不过使用了RLE压缩编码来减小内存占用。
在字库文件名中以rle结尾,例如Font32rle.c
RLE即Run-Length Encoding,RLE编码的原理就是将连续相同的内容进行压缩,
我们看实例来理解:
Font32rle.h
中有以下宏定义:
#define chr_hgt_f32 26
表明本字体字符高度是26个点。
Font32rle.c
中有每个字符宽度的表
PROGMEM const unsigned char widtbl_f32[96] = // character width table
{
5, 8, 8, 19, 14, 21, 17, 6, // char 32 - 39
上面数组的前两个数据5
和8
分别是空格
和!
的字符宽度,
而下面两个数组分别是空格
和!
的字模信息
PROGMEM const unsigned char chr_f32_20[] =
{
0x7F, 0x1
};
PROGMEM const unsigned char chr_f32_21[] =
{
0x0A, 0x81, 0x05, 0x81, 0x05, 0x81, 0x05, 0x81,
0x05, 0x81, 0x05, 0x81, 0x05, 0x81, 0x05, 0x81,
0x05, 0x81, 0x05, 0x81, 0x05, 0x81, 0x05, 0x81,
0x05, 0x81, 0x15, 0x81, 0x05, 0x81, 0x05, 0x81,
0x3A
};
首先计算空白符
的点阵的宽高分别是’5’,‘26’,那一共就是5x26=130点;
然后解析数据,空白符
的第一个数据是0x7f
,当数据的bit7位为0
时表示接下来出现的字符点为0
(背景色),bit6-bit0共7位二进制,其10进制值加1为0
将连续出现的次数,在这里0x7f=127(D) 加一就是128。也就是0
会连续出现128次。现在先连续从左到右,从上到下画128个底色点。再接着分析第二个数据0x1
,解析得知还需画2个底色点,这样一共就是130个点,正好填充本字符所有点阵,本字符处理完成。
我们再来分析一下接着的字符!
的数据:
我提前给出解析的点阵图,然后来解释
00000000 //第1行
00011000 //第2行
00011000 //第3行
...
00011000 //第13行
00000000 //第14行
00000000 //第15行
00011000 //第16行
00011000 //第17行
00000000 //第18行
...
00000000 //第26行
点阵宽为8,高为26,所以是一个8列26行的点的矩阵。
第一个数据0x0a
,所以点阵是连续11个0
(底色)。对应矩阵第一行的8个0
和第二行前3个0
,第二个数据为0x81
,最高位(bit7)为1
,那么接下来的点为1
(前景色),bit6-0为1加1等于2,也就是说接着是2个点的前景色,对应矩阵第二行的中间两个1
。按照这个规则解析后面的数据,完成整个数据数组的解析。