基于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 为了防止几年后文章链接找不到,我把文章复制过来了 /***** ...
随机推荐
- solr4.5安装配置 linux+tomcat6.0+mmseg4j-1.9.1分词
首先先介绍下solr的安装配置 solr下载地址 (我这用的solr-4.5.0) 运行环境 JDK 1.5或更高版本 下载地址(Solr 4以上版本,要求JDK 1.6) 我用的JDK1.6 ) ...
- fly bird
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 【异常】No ManagedConnections available within configured blocking timeout
Caused by: org.jboss.util.NestedSQLException: No ManagedConnections available within configured bloc ...
- windows消息机制详解(转载)
消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了.例如,单击鼠标.改变窗口尺寸.按下键盘上的一个键都会使Windows发送一个消息给应用程序.消息本身是作为一个记录传递给应用程序的 ...
- bootstrap学习笔记【转】
bootstrap是由Twitter公司研发的一个基于HTML,CSS,JavaScript的开源框架,最重要的部分是它的响应式布局.(国内文档翻译官网:http://www.bootcss.com/ ...
- Docker中images无法使用apt-get update解决方案
问题描述:使用apt-get update一直fail 原因:DNS设置错误 解决办法: nm-tool #查看DNS后面的数(IPv4),将后面的数copy下来 sudo nano /etc/def ...
- c# 局域网文件传输实例
一个基于c#的点对点局域网文件传输小案例,运行效果截图 //界面窗体 using System;using System.Collections.Generic;using System.Compon ...
- STM32之DMA+ADC
借用小甲鱼的经典:各位互联网的广大网友们.大家早上中午晚上好..(打下小广告,因为小甲鱼的视频真的很不错).每次看小甲鱼的视频自学都是比较轻松愉快的..我在想,如果小甲鱼出STM32的视频,我会一集不 ...
- AmazeUI 框架知识点-元素
1.按钮 .am-btn 圆角按钮 .am-radius 椭圆形按钮 .am-round 按钮激活状态 .am-active 禁用状态 .am-disabled 2.按钮尺寸.am-btn-xl . ...
- 把C#程序(含多个Dll)合并成一个Exe的超简单方法
开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. 但是,很多时候我们本想开发一款只需要一个exe就能完美运行的小工具.那该怎么办呢? 下文介绍一种超 ...