基于stm32f4的ucGUI通过外部flash存储汉字库显示任意英文字符和汉字组合(控件可用)
在做一个用到ucGUI的项目的时候要用到不定的汉字和英文字符,但是ucGUI本身又不支持读取芯片外部flash的字库来显示,于是查了下资料,如下:
http://www.cnblogs.com/hiker-blogs/archive/2013/01/04/2843538.html
站在巨人的肩膀上,我找到了将汉字库写进flash后,通过ucGUI的控件显示出来的方法,但是至此,并不能在一个字符串里添加汉字和英文,用于同时显示,因为flash里面没有英文字符的模。
为了让一个控件同时显示汉字和英文,我们还是将目标瞄准ucGUI_Core文件夹中的GUICharP.c文件:
将函数void GUIPROP_DispChar(U16P c)修改成:
void GUIPROP_DispChar(U16P c) {
int BytesPerLine;
U8 BytesPerFont; //一个字的字节数
U32 base,oft; //字库的起始地址和偏移量
GUI_DRAWMODE DrawMode = GUI_Context.TextMode;
const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUIPROP_FindChar(GUI_Context.pAFont->p.pProp, c);
if (pProp) {
GUI_DRAWMODE OldDrawMode;
const GUI_CHARINFO GUI_UNI_PTR * pCharInfo;
//支持2种字体,flash空间有限,放不下第三种字体
if((GUI_Context.pAFont == &GUI_FontHZ16)||(GUI_Context.pAFont == &GUI_FontHZ24)/*||(GUI_Context.pAFont == &GUI_FontHZ32)*/)
{
pCharInfo = pProp->paCharInfo;
base = (U32)pProp->paCharInfo->pData;
BytesPerFont = GUI_Context.pAFont->YSize * pProp->paCharInfo->BytesPerLine; //每个字模的数据字节数
if (BytesPerFont > BYTES_PER_FONT)//BYTES_PER_FONT是一个汉字所占最大字节数,我这里最大显示点阵24x24的汉字,所以BYTES_PER_FONT大小是3x24
{
BytesPerFont = BYTES_PER_FONT;
}
if (c < 0x80) //英文字符显示部分
{
const GUI_FONT *EnglishFont;//定义一个字库指针,方便以后操作
if(GUI_Context.pAFont == &GUI_FontHZ16)//根据所用字库来给EnglishFont赋值,因为flash里面没有英文字符模,于是用ucGUI自带的
EnglishFont=&GUI_Font16_ASCII;
else
EnglishFont=&GUI_Font24_ASCII;
//BytesPerLine = GUI_Font24_ASCII.p.pProp->paCharInfo[c-0x20].BytesPerLine*GUI_Font24_ASCII.YSize;
//在这里,BytesPerLine就是所要显示的字符的模位数,就是GUI_CHARINFO结构体的BytesPerLine
BytesPerLine = EnglishFont->p.pProp->paCharInfo[c-0x20].BytesPerLine;
OldDrawMode = LCD_SetDrawMode(DrawMode);//写入新的模式,并保存旧的模式
//注:pCharInfo-> = EnglishFont.p.pProp->paCharInfo[c-0x20].
// GUI_Context.pAFont-> = 当前字体,比如 EnglishFont.
LCD_DrawBitmap( GUI_Context.DispPosX,
GUI_Context.DispPosY,
EnglishFont->p.pProp->paCharInfo[c-0x20].XSize,//GUI_CHARINFO的XSize,EnglishFont->p.pProp->paCharInfo[c-0x20]即相当于字库文件F16_ASCII.c中的GUI_CharInfo_Font16ASCII[c-0x20]
EnglishFont->YSize,//字库的参数
EnglishFont->XMag,
EnglishFont->YMag,
1, /* Bits per Pixel */
BytesPerLine,
EnglishFont->p.pProp->paCharInfo[c-0x20].pData,
&LCD_BKCOLORINDEX
);
/* Fill empty pixel lines */
if (EnglishFont->YDist > EnglishFont->YSize) { //用于字符对齐,删掉这里的if到return就可以指到效果了
int YMag = EnglishFont->YMag;
int YDist = EnglishFont->YDist * YMag;
int YSize = EnglishFont->YSize * YMag;
if (DrawMode != LCD_DRAWMODE_TRANS) {
LCD_COLOR OldColor = GUI_GetColor();
GUI_SetColor(GUI_GetBkColor());
LCD_FillRect(GUI_Context.DispPosX,
GUI_Context.DispPosY + YSize,
GUI_Context.DispPosX + pCharInfo->XSize,
GUI_Context.DispPosY + YDist);
GUI_SetColor(OldColor);
}
}
LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */
GUI_Context.DispPosX += EnglishFont->p.pProp->paCharInfo[c-0x20].XDist * EnglishFont->XMag;
return;
}
else //中文字符地址偏移算法
{
oft = base + (((c>>8) - 0xa1) * 94 + ((c&0xff) - 0xa1)) * BytesPerFont;
ucGUI_ReadFlashBit(oft, GUI_FontDataBuf, BytesPerFont);//取出字模数据
BytesPerLine = pCharInfo->BytesPerLine;
OldDrawMode = LCD_SetDrawMode(DrawMode);
LCD_DrawBitmap( GUI_Context.DispPosX,
GUI_Context.DispPosY,
pCharInfo->XSize,
GUI_Context.pAFont->YSize,
GUI_Context.pAFont->XMag,
GUI_Context.pAFont->YMag,
1, /* Bits per Pixel */
BytesPerLine,
GUI_FontDataBuf,
&LCD_BKCOLORINDEX
);
}
}
//--
else
{
pCharInfo = pProp->paCharInfo+(c-pProp->First);
BytesPerLine = pCharInfo->BytesPerLine;
OldDrawMode = LCD_SetDrawMode(DrawMode);
LCD_DrawBitmap( GUI_Context.DispPosX,
GUI_Context.DispPosY,
pCharInfo->XSize,
GUI_Context.pAFont->YSize,
GUI_Context.pAFont->XMag,
GUI_Context.pAFont->YMag,
1, /* Bits per Pixel */
BytesPerLine,
pCharInfo->pData,
&LCD_BKCOLORINDEX
);
}
/* Fill empty pixel lines */
if (GUI_Context.pAFont->YDist > GUI_Context.pAFont->YSize) {
int YMag = GUI_Context.pAFont->YMag;
int YDist = GUI_Context.pAFont->YDist * YMag;
int YSize = GUI_Context.pAFont->YSize * YMag;
if (DrawMode != LCD_DRAWMODE_TRANS) {
LCD_COLOR OldColor = GUI_GetColor();
GUI_SetColor(GUI_GetBkColor());
LCD_FillRect(GUI_Context.DispPosX,
GUI_Context.DispPosY + YSize,
GUI_Context.DispPosX + pCharInfo->XSize,
GUI_Context.DispPosY + YDist);
GUI_SetColor(OldColor);
}
}
LCD_SetDrawMode(OldDrawMode); /* Restore draw mode */
GUI_Context.DispPosX += pCharInfo->XDist * GUI_Context.pAFont->XMag;
}
}
void GUIPROP_DispChar(U16P c)函数只是用来显示数据的,为了让数据显示在控件中间,还要修改int GUIPROP_GetCharDistX(U16P c)为:
int GUIPROP_GetCharDistX(U16P c) {
if(c<0x80)//是英文
{
const GUI_FONT_PROP GUI_UNI_PTR * pProp;
if(GUI_Context.pAFont == &GUI_FontHZ16)//在GUI_FontHZ16中找到字符间距,用于控件字符水平对齐,防止英文字符宽度被认为跟汉字一样
{
pProp = GUIPROP_FindChar(GUI_Font16_ASCII.p.pProp, c);//在GUI_Font16_ASCII字库里面找字符c
return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Font16_ASCII.XMag : 0;//返回字符c的横坐标大小
}
else
{
pProp = GUIPROP_FindChar(GUI_Font24_ASCII.p.pProp, c);
return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Font24_ASCII.XMag : 0;
}
}
else
{
const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUIPROP_FindChar(GUI_Context.pAFont->p.pProp, c);
return (pProp) ? (pProp->paCharInfo+(c-pProp->First))->XSize * GUI_Context.pAFont->XMag : 0;
}
}
当这两个函数修改完毕,并且做好上面大牛的链接内容后,字体数据就放在外部flash中,显示器可以在控件上同时显示汉字和英文了。
http://pan.baidu.com/s/1pLFA739
这是我的工程源码,里面有将字体文件复制进SD卡的函数。我用的开发板是stm32f407,环境是keil5,在stm32f407板子上集成2M的flash,板子上面的SDIO接口连接了一个1G的SD卡,sd卡有font目录,里面放16HZK.bin和24HZK_B.bin文件,液晶驱动是ili9341.在这里感谢正点原子,很多驱动程序是他们提供的。
基于stm32f4的ucGUI通过外部flash存储汉字库显示任意英文字符和汉字组合(控件可用)的更多相关文章
- ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件
源:ucgui汉字库存放到外部的flash(控件可用)及写外部FLASH小软件 如何将ucgui的汉字库存放到外部的flash memory(ucgui)(汉字库)(外部flash) ucgui的字库
- Flash播放控件属性详解
Flash 播放控件属性详解 一.属性篇 1.AlignMode(读写) 语法:AlignMode As Long 说明:对齐方式(与SAlign 属性联动).当控件的长宽比例与影片不一致且WMo ...
- 玩转X-CTR100 l STM32F4 l W25Q64 SPI串行FLASH存储
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 板载FLA ...
- 智能设备逆向工程之外部Flash读取与分析篇
智能设备逆向工程之外部Flash读取与分析篇 唐朝实验室 · 2015/10/19 11:19 author: rayxcp 0x00 前言 目前智能家居设备的种类很多,本文内容以某智能豆浆机为例完成 ...
- flash存储原理
norflash 带有 SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内容每一字节:nandflash器件使用复杂的IO口串行的存取数据,读写操作采用512字节的块(也就是读/写某个字节,必 ...
- 218- VPX主板 基于5VFX70T的3U VPX 光纤数据采集存储板
基于5VFX70T的3U VPX 光纤数据采集存储板 1.板卡概述 本板卡是基于3U VPX架构,符合VITA46标准,实现了多种图形图像接口的采集与转换.图像数据的处理.宽带数据缓存.SATA存储主 ...
- External Configuration Store Pattern 外部配置存储模式
Move configuration information out of the application deployment package to a centralized location. ...
- STM32学习笔记(八) SPI总线(操作外部flash)
1. SPI总线简介 SPI全称串行外设接口,是一种高速,全双工,同步的外设总线:它工作在主从方式,常规需要至少4根线才能够正常工作.SPI作为基本的外设接口,在FLASH,EPPROM和一些数字通讯 ...
- RTThread DFS文件系统使用: 基于使用SFUD驱动的SPI FLASH之上的ELM FATFS文件系统
参考博文: 博文很长,但是实际要操作的步骤没几下. http://m.elecfans.com/article/730878.html 为了防止几年后文章链接找不到,我把文章复制过来了 /***** ...
随机推荐
- 让不支持h5新标签的浏览器支持新标签
把这段js加到页面的头部就可以了,创建想让浏览器支持的标签即可 //条件判断是否支持 h5 if(window.applicationCache){ alert("支持h5") } ...
- Solr DIH JDBC 源码解析
Solr DIH 源码解析 DataImportHandler.handleRequestBody()中的importer.runCmd(requestParams, sw) if (DataImpo ...
- 全本软件白名单 Quanben Software Whitelist
Windows应用软件 Windows Applications (TBU) 全本推荐微软Windows 10操作系统 Quanben recommends Microsoft Windows 10 ...
- windows消息机制详解(转载)
消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了.例如,单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.消息本身是作为一个记录传递给应用程序的 ...
- 关于dev无法更新、调试的问题
- [转]FINDSTR正则表达式小结
前言:最近写了一个bat用于快速编译swf至目标目录,想利用FINDSTR命令通过匹配目标目录名称,匹配数量大概600多个,发现匹配耗时比较久,大概花费10余秒,因此还是放弃字符匹配,乖乖拼出全称来定 ...
- Web前端开发推荐阅读书籍
前言 前端工程师在中国兴起也就5年左右,以前公司里没有专门前端工程师的这个职位,很多前端方面的任务都是由全栈工程师来完成,有的基础一点的后台或者设计的帮助分担一些.但是随着互联网的快速发展,特别是所谓 ...
- Windows下ADT环境搭建
1.JDK安装 下载JDK(点我下载),安装成功后在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量: JAVA_HOME值为C:\Program Files ...
- hdu 2037简单贪心--活动安排问题
活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子.该问题要求高效地安排一系列争用某一公共资源的活动.贪心算法提供了一个简单.漂亮的方法使得尽可能多的活动 ...
- Smart3D系列教程2之 《为什么三维重建效果这么差?——探探那些被忽略的拍照要求和技巧》
一.照片采集的实用概念 根据照片进行三维重建的过程中,有人没怎么遇到坑,有人被坑的不轻.可能是模型的纹理失真,模型的法线错了,模型会生成我们各种也想不到的结果,那么,是什么导致三维重建效果这么差的?是 ...