新闻  |   论坛  |   博客  |   在线研讨会
在uC/GUI中实现汉字显示
tvb2058 | 2007-12-08 13:20:50    阅读:4798   发布文章

以人为本的系统开发观念不断深入人心,GUI做为典型的人机交互接口,在系统开发工程中具有不可动摇的地位。易用的操作界面已成为衡量产品开发成功的重要因素。据统计,系统工程师要花去近三分之一的时间用于GUI系统的开发。完善的GUI开发系统,把设计人员从繁重的低层图形界面设计中解放出来,使其有更多的时间用于系统性能的提高。这极大的缩短了开发周期,使产品在激烈的市场竞争中抢占先机。

uC/GUI是Micrium公司专门针对嵌入式系统开发的一款通用图形界面开发系统。它提供高效的图形LCD管理,可以嵌于单任务和多任务嵌入式系统中。在小模式(small system)下,只需要100 B的RAM+500 B的STACK(RAM)+10~25 KB的ROM,全部代码用C语言完成,具有良好的可移植性,适用于各种CPU。
uC/GUI是一款非常简洁的图形界面开发系统,但是它缺乏对中文汉字的支持,严重阻碍了在国内的使用。本文结合工程实践,着重讲述汉字在uC/GUI上的实现过程,汉字字库的创建方法及其相关程序代码。
1uC/GUI中字体系统结构
uC/GUI中字体的显示是通过查找字模的方式实现的。字体库中的每一个字母都有其对应的字模,所有的字母的字模由GUI_FONT和GUI_FONT_PROP这两个结构体来进行统一管理。GUI_FONT结构体中定义了该字母的点阵大小(比如16×16或者8×8)和GUI_FONT_PROP结构体的入口地址。GUI_FONT_PROP这个结构体建立了字库中字母编码(比如字母A在ASCII中的字母编码为33)和字模数据存放地址的映像。值得一提的是,GUI_FONT_PROP中pNext指针指向下一个GUI_FONT_PROP数据的入口地址,这为解决在字母编码不连续的情况下,保证字模数据在程序段的存储连续这一问题提供了一个良好的解决方案。设计人员可以定义多个GUI_FONT_PROP结构,只要使上一个结构体的pNext指针指向下一个GUI_FONT_PROP结构体,并且保证该指针的最终指向零地址空间即可。
2汉字编码
(1) 汉字字模的获取
在工程中出于节省程序存储空间的需要, GB231280(国标字符集也就是常说的国标码)中的3755个一级常用汉字足以满足实际需求。如果通过单字手工取模的方式,工作量是不可想象的,所幸有了电脑,又有了汉字库,可以编程解决。找个标准的汉字库,比如UCDOS中的HZK16就可以,但是在HZK16中字模是按区位码的顺序排列的。只要把汉字内码的高低位都减去0xA0后,就得到了汉字的区位码。一级常用汉字的内码范围是高字节0xB0~0xD7,低字节0xA1~0xFE。以下是提取HZK16文件中的一级常用汉字的部分代码:
for(i=0;i<=(0xD7-0xB0);i++)
for(j=0;j<=(0xFE-0xA1);j++)
if(fseek(fin,((i+0xB0-0xA1)*94+(j+0xA1-0xA1))*32L,SEEK_SET))
printf("seek err\\n");
fread(buffer,32,1,fin);
(2) 程序中直接输入汉字的实现
uC/GUI手册中介绍的用unicode编码进行输入的方法相当烦琐,当需要输入大量汉字时,这一问题就更加突出。经过分析内核代码,会发现程序中输入的unicode码其实就是字库中GUI_FONT_PROP定义的该字映像地址。在程序中,直接输入字母后计算机获得的是汉字内码,所以只要把GUI_FONT_PROP中的映像地址改为字母的内码就可以了,对于英文字母就是其ASCII编码,而汉字就是汉字内码。下面是uC/GUI中F16_1HK.C文件中定义的GUI_FONT_PROP结构体对象,通过注释了解映像地址和字模数据存储地址的对应关系。
GUI_FLASH const GUI_FONT_PROP GUI_Font16_1HK_Prop1 = {
0x3041/* 映像地址起始位置*/
,0x3093/* 映像地址结束位置*/
,&GUI_Font16_HK_CharInfo\[0\] /*字模代码的入口地址*/
,(void GUI_FLASH *)&GUI_Font16_1HK_Prop2/* 下一个GUI_FONT_PROP的地址*/
};
3新建汉字字库
在uC/GUI中动态地读取字模是无法实现的,即当程序运行时动态地从汉字库中读取所需字母的字模,因此只有把所有一级常用汉字的字模全部读出,按照uC/GUI中字库创建的标准去创建新的字库就可以了。下面以在F16_HZ_ALL.C中创建字体GUI_Font16_HZ为例来说明具体的步骤。
第一步:声明全局字体结构体对象GUI_Font16_HZ,该声明必须在GUI.H文件中加以声明。
extern const GUI_FONT GUI_Font16_HZ;
第二步:定义一个用于存放字模数据的数组。
GUI_FLASH const unsigned char acFont16HZ\[\]\[32\] ={{/*单字字模数据1*/},……,{/*单字字模数据n*/}};
第三步:定义一个GUI_CHARINFO的结构体对象数组,用于说明每个字母的字模数据在程序段存储的方式。
GUI_FLASH const GUI_CHARINFO GUI_Font16_HZ_CharInfo\[3760\]={
{16,16,2,(void GUI_FLASH *)&acFont16HZ\[0\],……,16,16,2,(void GUI_FLASH *)&acFont16HZ\[3759\] },};
第四步:按汉字内码的高位来定义多个结构体GUI_FONT_PROP对象。
GUI_FLASH const GUI_FONT_PROP GUI_Font16_HZ_Prop0 = {
0xb0a1,
0xb0fe,
&GUI_Font16_HZ_CharInfo\[0\],
(void GUI_FLASH *)&GUI_Font16_HZ_Prop1
};
第五步:把创建的汉字字库文件F16_HZ_ALL.C添加到uC/GUI的工程中,通过以下语句实现在LCD上显示汉字:
GUI_SetFont(&GUI_Font16_HZ);
GUI_DispStringAt(GUI_UC_START
"成都理工大学"
GUI_UC_END
,20,10);
结语
本文介绍了怎样在uC/GUI中解决汉字的显示问题,作者的汉字字库文件全部通过C语言程序创建,字库文件在uC/GUI的评估软件simulation上编译通过,读者可以根据实际的需求创建自己的字库,以适应项目的需求。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客