欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32F407 添加GBK32 字体显示

程序员文章站 2024-02-23 20:27:46
...

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就绘一个点。

如下图:

STM32F407 添加GBK32 字体显示

STM32F407 添加GBK32 字体显示

可以用“点阵字库生成器V3.8”生成

测试可用勾选“小字库”

STM32F407 添加GBK32 字体显示

输入一个“青”字

STM32F407 添加GBK32 字体显示

对应的“点阵字节数组”为:

STM32F407 添加GBK32 字体显示

2.2 GBK字库

所谓字库,其实就是上面“点阵字节数组”的集合,GBK中的每个汉字都对应一个“点阵字节数组”,这些“点阵字节数组”是按GBK编码顺序排列的,所以到取汉字所对应的“点阵字节数组”,则先要获得汉字在GBK编码中所对应的偏移量

即:(汉字GBK编码)-0x8140

所以在STM32 LCD上显示一个汉字的过程为:

1.获取汉字的GBK编码--->2.获取该汉字在GBK编码库中的偏移量-->3.利用偏移量,从GBK字库中获得该汉字的“点阵字节数组”-->利用“点阵字节数组”在LCD上一个点一个点的将该汉字显示出来。

3.自建GBK字库

4.原代码修改

先写到这里,有空再补