基于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 为了防止几年后文章链接找不到,我把文章复制过来了 /***** ...
随机推荐
- oracle(sql)基础篇系列(五)——PLSQL、游标、存储过程、触发器
PL/SQL PL/SQL 简介 每一种数据库都有这样的一种语言,PL/SQL 是在Oracle里面的一种编程语言,在Oracle内部使用的编程语言.我们知道SQL语言是没有分支和循环的,而PL语 ...
- js中的日期控件My97 DatePicker---那些打酱油的日子
使用WdatePicker插件来渲染日期类型的页面. 以下代码用到的属性有: isShowClear是否显示清空按钮 skin皮肤的样式 readOnly是否只读 maxDate:最大的选择时间 &l ...
- oracle EXP导出一张表时使用query参数指定where条件
oracle exp 导出一个表的部分内容,使用query参数可加上SQL的where条件进行过滤 注意:如果需要使用到日期字符串格式等单引号,需要使用双引号将where条件括起来,而且双引号要用\做 ...
- Powershell脚本执行权限
Powershell脚本需要使用PS1扩展名 在加载脚本前需要确认是都有执行权限,默认是Restricted(受限的), 可以执行Get-ExecutionPolicy查看权限, 一般情况下使用 Re ...
- POJ 1979 题解
Red and Black Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 31722 Accepted: 17298 D ...
- bzoj1968真·想sha法bi题
本来想打表找规律的来着,,, 线性筛吗?一边筛一边累加答案?那不就不线性了吗...1e6悬啊 而且不是质因数个数而是因数个数,统计起来应该还要用数学方法 ...好尴尬 等一下,不要求质数的话我筛个p ...
- MVC Razor视图引擎的入门
首先我们来说说他的给我们开发者带来那些好处吧: Razor语法易于输入,易于阅读,微软当时是这样定义的:简洁,富有表现力和灵活性,支持所有文本编辑器,强大的智能提示功能,单元测试. Rozor文件类型 ...
- MongoDB的简单操作(asp.net)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using MongoDB.D ...
- MySQL表名和数据库关键字相同解决办法
今天改他们的代码的时候,遇到了MySQL表名和数据库关键字的问题. 由于表名是关键字,导致增删改查都报错. Hibernate: select leave0_.id as id22_, leave0_ ...
- Codeforces Round #361 (Div. 2) A
A - Mike and Cellphone Description While swimming at the beach, Mike has accidentally dropped his ce ...