|
我对老式裸奔下的GB2312汉字显示很熟悉,N年前用19264液晶,自己做的各种等宽字体字库,现在改用SPI接口的TFT了,目前已经通过485接口把自己做的字库BIN文件下发到W25Q128上,并且裸奔的情况下已经能够用自己写的函数显示半角字符和全角字符和汉字了,之后成功移植uC/OS-II + emWin了,能在TFT上显示emWin自带的ASCII字符,下一步准备把GB2312全字库移植到emWin下,参考的是安富莱emWin2.0 GB2312全字库移植教程,下面是裸奔情况下自己写的显示半角和全角字符的函数,测试没有任何问题:
/*
********************************************************************************
* .读出1个16*16字符的点阵数据(包括全角和半角)
* .pChar - 传入的字符指针,比如"a","啊"
* .说明:读出的点阵数据固定存储到数组uCharDotArray[]中
********************************************************************************
*/
void ReadChar16X(char *pChar)
{
u32 addr;
if(pChar[0] <= 0x80) //半角字符
{
addr = 4096 + (pChar[0] - 0x20)*16L;
W25Q_ReadData(addr, uCharDotArray, 16);
}
else //全角字符
{
if(pChar[0] <= 0xa9)
{
addr = 4096 + 1520 + ((pChar[0]-0xa1)*94 + (pChar[1]-0xa1))*32L;
}
else
{
addr = 4096 + 1520 + ((pChar[0]-0xa7)*94 + (pChar[1]-0xa1))*32L;
}
W25Q_ReadData(addr, uCharDotArray, 32);
}
}
/*
********************************************************************************
* .在(x,y)处显示一个16X字符
*
* .pChar - 目标字符
* x - 起点x坐标
* y - 起点y坐标
* fColor - 前景色
********************************************************************************
*/
void ShowChar16X_1P77(char *pChar, u16 x, u16 y, u16 fColor)
{
u8 m;
u16 i, j;
ReadChar16X(pChar);
LCD1P77_SelectWindow(0,LCD1P77_WIDTH-1,0,LCD1P77_HEIGHT-1);
if(pChar[0] <= 0x80) //半角字符
{
LCD1P77_SelectWindow(x, x+8, y, y+16);
for(i=0; i<16; i++)
{
m = 0x80;
for(j=0; j<8; j++)
{
if(uCharDotArray[i] & m)
{
LCD1P77_DrawPixel(x+j, y+i, fColor);
}
m >>= 1;
}
}
}
else //全角字符
{
LCD1P77_SelectWindow(x, x+16, y, y+16);
for(i=0; i<16; i++)
{
//汉字左半部分
m = 0x80;
for(j=0; j<8; j++)
{
if(uCharDotArray[i] & m)
{
LCD1P77_DrawPixel(x+j, y+i, fColor);
}
m >>= 1;
}
//汉字右半部分
m = 0x80;
for(j=0; j<8; j++)
{
if(uCharDotArray[i+16] & m)
{
LCD1P77_DrawPixel(x+8+j, y+i, fColor);
}
m >>= 1;
}
}
}
}
现在想把上面显示汉字的函数移植到emWin下,参考安富莱移植GB2312全字库的例程,GUI_UC_EncodeNone.c文件原封不动的加入到工程里
GUI_Font16.c文件里的内容基本没有改动,该文件里的所有内容贴在下面:
#include "GUI.h"
#include "GUI_Type.h"
extern void GUIPROP_X_DispChar(U16P c);
extern int GUIPROP_X_GetCharDistX(U16P c);
GUI_CONST_STORAGE GUI_CHARINFO GUI_FontHZ16_CharInfo[2] =
{
{ 8, 8, 1, (void *)"A16"},
{16, 16, 2, (void *)"H16"},
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ16_PropHZ =
{
0xA1A1,
0xFEFE,
&GUI_FontHZ16_CharInfo[1],
(void *)0,
};
GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ16_PropASC =
{
0x0000,
0x007F,
&GUI_FontHZ16_CharInfo[0],
(void GUI_CONST_STORAGE *)&GUI_FontHZ16_PropHZ,
};
GUI_CONST_STORAGE GUI_FONT GUI_FontHZ16 =
{
GUI_FONTTYPE_PROP_USER,
16,
16,
1,
1,
(void GUI_CONST_STORAGE *)&GUI_FontHZ16_PropASC,
};
GUI_CONST_STORAGE GUI_FONT GUI_FontHZ16x2 =
{
GUI_FONTTYPE_PROP_USER,
16,
16,
2,
2,
(void GUI_CONST_STORAGE *)&GUI_FontHZ16_PropASC
};
GUICharPEx.c文件里的内容做了比较大的改动,下面贴出该文件的完整内容:
#include "GUI.h"
#include "GUI_Type.h"
#include "GUI_Private.h"
#include "string.h"
#include "stm32f4xx.h"
//extern GUI_SADDR GUI_CONTEXT * GUI_pContext;
extern u8 uCharDotArray[72]; //存储16*16或者24*24点阵数据
extern void W25Q_ReadData(u32 address, u8 *pHead, u16 len);
extern void ShowChar16X_1P77(char *pChar, u16 x, u16 y, u16 fColor);
void GUI_GetDataFromMemory(const GUI_FONT_PROP GUI_UNI_PTR *pProp, U16P c);
void GUIPROP_X_DispChar(U16P c);
int GUIPROP_X_GetCharDistX(U16P c);
/*
*********************************************************************************************************
* 函 数 名: GUI_GetDataFromMemory
* 功能说明: 读取点阵数据
* 形 参: pProp GUI_FONT_PROP类型结构
* c 字符
* 返 回 值: 无
*********************************************************************************************************
*/
void GUI_GetDataFromMemory(const GUI_FONT_PROP GUI_UNI_PTR *pProp, U16P c)
{
U32 addr;
U8 pChar[2];
char *font = (char *)pProp->paCharInfo->pData;
pChar[0] = (u8)(c >> 8);
pChar[1] = (u8)(c);
//半角字符
if(c <= 0x80)
{
//6*12
if(strncmp("A12", font, 3) == 0)
{
}
//8*16
else if(strncmp("A16", font, 3) == 0)
{
addr = 4096 + (pChar[0] - 0x20)*16L;
//读取点阵数据
W25Q_ReadData(addr, uCharDotArray, 16);
}
//12*24
else if(strncmp("A24", font, 3) == 0)
{
}
//16*32
else if(strncmp("A32", font, 3) == 0)
{
}
}
//全角字符
else
{
//12*12
if(strncmp("H12", font, 3) == 0)
{
}
//16*16
else if(strncmp("H16", font, 3) == 0)
{
if(pChar[0] <= 0xa9)
{
addr = 4096 + 1520 + ((pChar[0]-0xa1)*94 + (pChar[1]-0xa1))*32L;
}
else
{
addr = 4096 + 1520 + ((pChar[0]-0xa7)*94 + (pChar[1]-0xa1))*32L;
}
//读取点阵数据
W25Q_ReadData(addr, uCharDotArray, 32);
}
//24*24
else if(strncmp("H24", font, 3) == 0)
{
}
//32*32
else if(strncmp("H32", font, 3) == 0)
{
}
}
}
/*
*********************************************************************************************************
* 函 数 名: GUIPROP_X_DispChar
* 功能说明: 显示字符
* 形 参: c 显示的字符
* 返 回 值: 无
*********************************************************************************************************
*/
void GUIPROP_X_DispChar(U16P c)
{
char pChar[2];
GUI_DRAWMODE OldDrawMode;
GUI_DRAWMODE DrawMode = GUI_pContext->TextMode;
const GUI_FONT_PROP GUI_UNI_PTR *pProp = GUI_pContext->pAFont->p.pProp;
const GUI_CHARINFO GUI_UNI_PTR * pCharInfo = pProp->paCharInfo;
pChar[0] = (u8)(c >> 8);
pChar[1] = (u8)(c);
OldDrawMode = LCD_SetDrawMode(DrawMode);
ShowChar16X_1P77(pChar, GUI_pContext->DispPosX, GUI_pContext->DispPosY, 0xffff);
LCD_SetDrawMode(OldDrawMode);
GUI_pContext->DispPosX += pCharInfo->XDist * GUI_pContext->pAFont->XMag;
}
/*
*********************************************************************************************************
* 函 数 名: GUIPROP_X_GetCharDistX
* 功能说明: 获取字符的X轴间距
* 形 参: c 字符
* 返 回 值: 无
*********************************************************************************************************
*/
int GUIPROP_X_GetCharDistX(U16P c)
{
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;
}
在该文件里,实际上GUI_GetDataFromMemory()函数我移植了,但是在GUIPROP_X_DispChar(U16P c)函数里根本就没调用这个函数,而直接调用了连读字模带显示的函数ShowChar16X_1P77()
上面移植OK了,然后就是调用,在调用显示的头文件里声明了外部字体 extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ16;
然后在main()主函数里调用:
GUI_Init();
//横屏
LCD1P77_WriteReg8(0x36);
LCD1P77_WriteData8(0x78);
GUI_SetBkColor(0x07E0);
GUI_Clear();
GUI_SetDefaultFont(&GUI_FontHZ16); //1处
//LCD1P77_ClearScreen(GREEN);
GUI_DispStringAt("012", 00, 0); //2处
GUI_DispStringAt("祖国", 00, 0); //3处
ShowChar16X_1P77("5", 0, 0, 0xffff); //4处
ShowChar16X_1P77("张", 0, 16, 0xffff); //5处
上面的代码,1处设置默认字体为前面前面创建的字体GUI_FontHZ16,执行2处代码之后,能正确显示字符“012”,执行到3处的时候,汉字“祖国”并没有显示出来,执行到4和5处的时候,能用自己写的裸奔函数显示出“5”和“张”,这说明1处修改默认字体的动作并没有成功,回头再调试,执行3处代码的时候,发现并没有运行到GUIPROP_X_DispChar()函数里,也就是说emWin压根儿就没搭理自定义的字体函数,硬汉和各位GUI高手能不能帮我分析下原因,XBF和SIF字体方式我很不习惯,还是习惯老式的GB2312方式
|
|