(原创)如何将ucgui的汉字库存放到外部的flash memory(ucgui)(汉字库)(外部flash)...

摘要:

    在ARM7系统中,都不会有足够大的程序存储器来存放大容量的汉字库,因此当系统中要用到汉字库时,需要将其存储在外部的FLASH Memory,而ucgui的字符显示函数是直接从程序存储器取数据的,因此需要在原始代码里增加一个接口,来指向外部的FLASH Memory。

简介: 

   ucgui中,字符显示的底层函数是 GUICharP.c 中的 void GUIPROP_DispChar(U16P c) 函数,我们将这个函数修改如下:

 
  
/* ********************************************************************
*
* GUIPROP_DispChar
*
* Purpose:
* This is the routine that displays a character. It is used by all
* other routines which display characters as a subroutine.
*/


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;
// 支持3种字体==
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)
{
BytesPerFont
= BYTES_PER_FONT;
}
if (c < 0x80 ) // 英文字符地址偏移算法
{
oft
= base + (c - 0x20 ) * BytesPerFont; // 计算出字码在flash中的偏移地址
}
else // 中文字符地址偏移算法
{
oft
= base + (((c >> 8 ) - 0xa1 ) * 94 + ((c & 0xff ) - 0xa1 )) * BytesPerFont;

}
LCD_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;
}
}

然后再加入FLASH操作的底层驱动(这里用的是SPI FLASH)

 
  
/* ********************************************************************
*
* Static code
*
**********************************************************************
*/
// 字模数据的暂存数组,以单个字模的最大字节数为设定值
#define BYTES_PER_FONT 4*32 // 最大支持32*32的汉字
static U8 GUI_FontDataBuf[BYTES_PER_FONT];


/* ********************************************************************
*
* 读FLASH中的字库
*/
#include
" spi_flash.h "
#include
" ssp.h "

void LCD_ReadFlashBit(U32 addr,U8 * buf,U8 Bytes)
{
U8 i;
SPI_FLASH_StartReadSequence(addr);
// 设置起始地址
for (i = 0 ;i < Bytes;i ++ )
{
buf[i]
= SPI_FLASH_SendByte( 0xa5 );
}
SPI_FLASH_CS_HIGH();
}

我们知道,ucgui访问字库的时候,是根据字库文件的索引表来查找汉字数据地址的,因此汉字库文件中的索引也要修改,以汉字库32为例

 
  
/*
******************************************************


File Name : hzk32.C
Compiler :
Author : Liu_xf
Version : V1.0
Date : 2011-3-28 11:25:54
Description :
ucgui的中文字库,与uc工具生成的字库文件不同的是,可以将
大容量的汉字数组存入到外部的FALSH里
当然这个也是由uc工具生成的文件修改而来的。
*******************************************************
Structure :

History:

*******************************************************
*/

#include
" ..\core\GUI.H "
#ifndef GUI_FLASH
#define GUI_FLASH
#endif
extern GUI_FLASH const GUI_FONT GUI_FontHZ32;

/*
GUI_FLASH const GUI_CHARINFO GUI_FontHZ32_CharInfo[] = {
{ 10, 10, 1, (void GUI_FLASH *)0}, // 字符在FLASH中的偏移量
{ 16, 16, 2, (void GUI_FLASH *)3840}, //汉字在FLASH中的偏移量
};
*/

GUI_FLASH
const GUI_CHARINFO GUI_FontHZ32_CharInfo[] = {
// Y X X_BYTE
{ 16 , 8 , 1 , ( void GUI_FLASH * ) 0 }, // FLASH里没有存字符,这里为0
{ 32 , 32 , 4 , ( void GUI_FLASH * )GUI_FontHZ32_Flash_BaseAddr}, // GUI_FontHZ32_Flash_BaseAddr在GUI.h中定义
};

// 汉字和字符索引表 //

/* 鳌--齄 */

GUI_FLASH
const GUI_FONT_PROP GUI_FontHZ32_Propf7a1 = {
0xf7a1 ,
0xf7fe ,
& GUI_FontHZ32_CharInfo[ 1 ],
(
void * ) 0
};

//.....这里省略若干,详见符件里的代码


/*  --〓 */
GUI_FLASH
const GUI_FONT_PROP GUI_FontHZ32_Propa1a1 = {
0xa1a1 ,
0xa1fe ,
& GUI_FontHZ32_CharInfo[ 1 ],
(
void * ) & GUI_FontHZ32_Propa2a1
};
// ASC字符
/*
-- */
GUI_FLASH
const GUI_FONT_PROP GUI_FontHZ32_Prop0020 = {
0x0020 ,
0x007f ,
& GUI_FontHZ32_CharInfo[ 0 ],
(
void * ) & GUI_FontHZ32_Propa1a1
};
GUI_FLASH
const GUI_FONT GUI_FontHZ32 = {
GUI_FONTTYPE_PROP_SJIS,
32 ,
32 ,
1 ,
1 ,
(
void GUI_FLASH * ) & GUI_FontHZ32_Prop0020
};

在GUI.H中添加汉字库在flash中的首地址,及字库声明

 
  
/* 汉字 */
// 汉字库在FLASH中的首地址
#define GUI_FontHZ16_Flash_BaseAddr 0x0
#define GUI_FontHZ24_Flash_BaseAddr 0x00045080
#define GUI_FontHZ32_Flash_BaseAddr 0x000E05A0

extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ16;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ24;
extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ32;

    然后将字库下载到SPI FLASH中,注意三个字库的起始地址与GUI.h中定义的应该是一样的。还有字库生成时,也应该是标准的汉字库,满足 oft = base + (((c>>8) - 0xa1) * 94 + ((c&0xff) - 0xa1)) * BytesPerFont; 的计算方式。

 

结语: 

   有了将汉字库定义到外部FLASH的方法,则可以定义任意汉字库,不受程序FLASH大小的限制了。

附件:

ucgui_hzk.rar

转载于:https://www.cnblogs.com/liu_xf/archive/2011/04/14/2015789.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值