|
本帖最后由 薪火相传 于 2024-7-22 15:10 编辑
参考安福莱emwin教程文档,生成12/16/24的GB2312字体库,中文都能正常显示,但是20*20显示的中文字符不对,比如下面显示“中文”变成了其他,数字倒是正常

生成过程如下
利用下面这个软件生成20*20的中文字体库

按照如下生成ascii库

最终和其他字库合在一起
其中代码如下
GUI_Font20.c
[C] 纯文本查看 复制代码 #include "GUI.h"
#include "GUI_Type.h"
GUI_CONST_STORAGE GUI_CHARINFO GUI_FontHZ20_CharInfo[2] =
{
{ 10, 10, 2, (void *)"A20"},
{ 20, 20, 3, (void *)"H20"},
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ20_PropHZ= {
0x4081,
0xFEFE,
&GUI_FontHZ20_CharInfo[1],
(void *)0,
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ20_PropASC= {
0x0000,
0x007F,
&GUI_FontHZ20_CharInfo[0],
(void GUI_CONST_STORAGE *)&GUI_FontHZ20_PropHZ,
};
GUI_CONST_STORAGE GUI_FONT GUI_FontHZ20 =
{
GUI_FONTTYPE_USER,
20,
20,
1,
1,
(void GUI_CONST_STORAGE *)&GUI_FontHZ20_PropASC
};
GUI_CONST_STORAGE GUI_FONT GUI_FontHZ20x2 =
{
GUI_FONTTYPE_USER,
20,
20,
2,
2,
(void GUI_CONST_STORAGE *)&GUI_FontHZ20_PropASC
};
[C] 纯文本查看 复制代码
#include "GUI.h"
#include "GUI_Private.h"
#include "GUIDRV_Lin.h"
#include "sys_gui.h"
/* 点阵数据缓存, 必须大于等于单个字模需要的存储空间*/
#define BYTES_PER_FONT 512
static U8 GUI_FontDataBuf[BYTES_PER_FONT];
void sf_ReadBuffer(uint8_t * _pBuf, uint32_t _uiReadAddr, uint32_t _uiSize)
{
/* 如果读取的数据长度为0或者超出串行Flash地址空间,则直接返回 */
if ((_uiSize == 0) ||(_uiReadAddr + _uiSize) > 0x800000)
{
return;
}
memcpy(_pBuf,(const void *)(FONT_ADDR+4+_uiReadAddr),_uiSize);
}
/*
*********************************************************************************************************
* 函 数 名: GUI_GetDataFromMemory
* 功能说明: 读取点阵数据
* 形 参: pProp GUI_FONT_PROP类型结构
* c 字符
* 返 回 值: 无
*********************************************************************************************************
*/
static void GUI_GetDataFromMemory(const GUI_FONT_PROP GUI_UNI_PTR *pProp, U16P c)
{
U16 BytesPerFont;
U32 oft = 0, BaseAdd;
U8 code1,code2;
char *font = (char *)pProp->paCharInfo->pData;
/* 每个字模的数据字节数 */
BytesPerFont = GUI_pContext->pAFont->YSize * pProp->paCharInfo->BytesPerLine;
if (BytesPerFont > BYTES_PER_FONT)
{
BytesPerFont = BYTES_PER_FONT;
}
/* 英文字符地址偏移计算 */
if (c < 0x80)
{
if(strncmp("A12", font, 3) == 0) /* 6*12 ASCII字符 */
{
BaseAdd = 0x00000000;
}
else if(strncmp("A16", font, 3) == 0) /* 8*16 ASCII字符 */
{
BaseAdd = 0x00000C00;
}
else if(strncmp("A20", font, 3) == 0) /* 16*20 ASCII字符 */
{
BaseAdd = 0x00001C00;
}
else if(strncmp("A24", font, 3) == 0) /* 12*24 ASCII字符 */
{
BaseAdd = 0x00004400;
}
else if(strncmp("A32", font, 3) == 0) /* 24*48 ASCII字符 */
{
BaseAdd = 0x00007400;
}
else if(strncmp("A48", font, 3) == 0) /* 32*64 ASCII字符 */
{
BaseAdd = 0x0000B400;
}
oft = c* BytesPerFont + BaseAdd;
}
/* 汉字和全角字符的偏移地址计算 */
else
{
if(strncmp("H12", font, 3) == 0) /* 12*12 字符 */
{
BaseAdd = 0x00014400;
}
else if(strncmp("H16", font, 3) == 0) /* 16*16 字符 */
{
BaseAdd = 0x000A0860;
}
else if(strncmp("H20", font, 3) == 0) /* 20*20 字符 */
{
BaseAdd = 0x0015B8E0;
}
else if(strncmp("H24", font, 3) == 0) /* 24*24 字符 */
{
BaseAdd = 0x001DCFD0;
}
// else if(strncmp("H32", font, 3) == 0) /* 32*32 字符 */
// {
// BaseAdd = 0x002FDE00;
// }
/* 根据汉字内码的计算公式锁定起始地址 */
code2 = c >> 8;
code1 = c & 0xFF;
/* 由于字符编码是安顺序存储的,先存储到高位(区号),然后是低位(位号)。而我们用的是小端格式,
一个汉字两个字节,获取的16位变量,正好相反,16位变量的高位是位号,低位是区号。
*/
oft = ((code1 - 0x81) * 190 + (code2- 0x40) - (code2 / 128))* BytesPerFont + BaseAdd;
}
/* 读取点阵数据 */
sf_ReadBuffer(GUI_FontDataBuf, oft, BytesPerFont);
}
/*
*********************************************************************************************************
* 函 数 名: GUIUSER_DispChar
* 功能说明: 显示字符
* 形 参: c 显示的字符
* 返 回 值: 无
*********************************************************************************************************
*/
void GUIUSER_DispChar(U16P c)
{
int BytesPerLine;
GUI_DRAWMODE DrawMode = GUI_pContext->TextMode;
const GUI_FONT_PROP GUI_UNI_PTR *pProp = GUI_pContext->pAFont->p.pProp;
/* 确定显示的字符是否在有效范围内 */
for (; pProp; pProp = pProp->pNext)
{
if ((c >= pProp->First) && (c <= pProp->Last))break;
}
/* 字符有效,进行显示 */
if (pProp)
{
GUI_DRAWMODE OldDrawMode;
const GUI_CHARINFO GUI_UNI_PTR * pCharInfo = pProp->paCharInfo;
GUI_GetDataFromMemory(pProp, c);
BytesPerLine = pCharInfo->BytesPerLine;
OldDrawMode = LCD_SetDrawMode(DrawMode);
LCD_DrawBitmap(GUI_pContext->DispPosX, GUI_pContext->DispPosY,
pCharInfo->XSize, GUI_pContext->pAFont->YSize,
GUI_pContext->pAFont->XMag, GUI_pContext->pAFont->YMag,
1,
BytesPerLine,
&GUI_FontDataBuf[0],
&LCD_BKCOLORINDEX
);
/* 填充背景 */
if (GUI_pContext->pAFont->YDist > GUI_pContext->pAFont->YSize)
{
int YMag = GUI_pContext->pAFont->YMag;
int YDist = GUI_pContext->pAFont->YDist * YMag;
int YSize = GUI_pContext->pAFont->YSize * YMag;
if (DrawMode != LCD_DRAWMODE_TRANS)
{
LCD_COLOR OldColor = GUI_GetColor();
GUI_SetColor(GUI_GetBkColor());
LCD_FillRect(GUI_pContext->DispPosX, GUI_pContext->DispPosY + YSize,
GUI_pContext->DispPosX + pCharInfo->XSize,
GUI_pContext->DispPosY + YDist);
GUI_SetColor(OldColor);
}
}
LCD_SetDrawMode(OldDrawMode);
// if (!GUI_MoveRTL)
GUI_pContext->DispPosX += pCharInfo->XDist * GUI_pContext->pAFont->XMag;
}
}
/*
*********************************************************************************************************
* 函 数 名: GUIUSER_X_GetCharDistX
* 功能说明: 获取字符的X轴间距
* 形 参: c 字符
* 返 回 值: 无
*********************************************************************************************************
*/
int GUIUSER_GetCharDistX(U16P c, int * pSizeX)
{
const GUI_FONT_PROP GUI_UNI_PTR * pProp = GUI_pContext->pAFont->p.pProp;
for (; pProp; pProp = pProp->pNext)
{
if ((c >= pProp->First) && (c <= pProp->Last))break;
}
return (pProp) ? (pProp->paCharInfo)->XSize * GUI_pContext->pAFont->XMag : 0;
}
哪位大佬指点一下?
|
|