STM32F407 添加GBK32 字体显示
1.背景
原示例代码中只支持最大24的字体,32*32的字体,需要自己做字库。
理论上既然示例代码支持24的字体,只要把源代码搞懂,再增加自己的32字库的代码,应该是可行的。
不过在此之前,先要搞懂什么是字库。
2.GBK字库
要搞懂字库,先搞懂GBK编码,及点阵字节数组
2.1 GBK编码
GBK 采用双字节表示,总体编码范围为 0x8140-0xFEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。
全部编码分为三大部分:
....以下省略几千字(请自行百度)
重点是0x8140
这个是编码的基址,用于将GBK编码 换算成字库中该字所对应点阵字节数组在字库中的偏移量。
2.2 点阵字节数组
所为点阵字节数组, 即程序在显示汉字里所使用的数据。具体怎么使用呢?看源代码:
void gui_show_ptfont(u16 x,u16 y,u16 xend,u16 yend,u16 offset,u16 color,u16 size,u8* chr,u8 mode)
{
u8 temp;
u8 t1,t;
u16 tempoff;
u16 y0=y;
u8 dzk[128];
u8 csize=(size/8+((size%8)?1:0))*(size);
if(size!=12&&size!=16&&size!=24&&size!=32)return;
Get_HzMat(chr,dzk,size);
tempoff=offset;
for(t=0;t<csize;t++)
{
if(x>xend)break;
temp=dzk[t];
if(tempoff==0)
{
for(t1=0;t1<8;t1++)
{
if(y<=yend)
{
if(temp&0x80)
{
if(mode==0x02)gui_draw_bigpoint(x,y,color);
else gui_phy.draw_point(x,y,color);
}else if(mode==0)gui_phy.draw_point(x,y,gui_phy.back_color);
}
temp<<=1;
y++;
if((y-y0)==size)
{
y=y0;
x++;
break;
}
}
}else
{
y+=8;
if((y-y0)>=size)
{
y=y0;
tempoff--;
}
}
}
}
点阵字节数组在代码中对应的就是 dzk[128]数组,这里我将原来的dzk[72]改为了dzk[128],因为32*32个点,对应的字节数是32*32/8=128。
绘字体的关键就是用draw_point函数,一个点一个点的绘制。一个bit对应一个点。遇0则不绘,遇1就绘一个点。
如下图:
可以用“点阵字库生成器V3.8”生成
测试可用勾选“小字库”
输入一个“青”字
对应的“点阵字节数组”为:
2.2 GBK字库
所谓字库,其实就是上面“点阵字节数组”的集合,GBK中的每个汉字都对应一个“点阵字节数组”,这些“点阵字节数组”是按GBK编码顺序排列的,所以到取汉字所对应的“点阵字节数组”,则先要获得汉字在GBK编码中所对应的偏移量。
即:(汉字GBK编码)-0x8140
所以在STM32 LCD上显示一个汉字的过程为:
1.获取汉字的GBK编码--->2.获取该汉字在GBK编码库中的偏移量-->3.利用偏移量,从GBK字库中获得该汉字的“点阵字节数组”-->利用“点阵字节数组”在LCD上一个点一个点的将该汉字显示出来。
3.自建GBK字库
4.原代码修改
先写到这里,有空再补