|
特别说明:pdf版60期emWin教程已经发布:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=2932
armfly-x2,x3,v2,v3,v5开发板裸机和带系统的emWin工程已经全部建立,链接如下:
http://www.armbbs.cn/forum.php?mod=viewthread&tid=1830
本期主要讲如何将字库放置到外部存储器的方法,这里以放到SD卡为例,放到其他存储器是一样的。
其实用官方提供的XBF方式,将字库放到外部字库是最合适的,而且能够使用抗锯齿,暂时还没有调试出
来,后面有机会了再做尝试,这里用的外置字库的方法还是UCGUI时代遗留下来的。现在贴个图让大家看
一下实际的显示效果,有一点在这里必须的说明一下,外置字库到SD卡显示大字体的时候会非常的卡。
本期分为三个小节:
6. 1 移植方法
6. 2 点阵字体的说明
6. 3 将生成的字体移植到armfly - v5开发板上面
6. 4 实验总结
6. 1 移植方法
6.1.1 要添加两个文件,一个是 GUI_UC_EncodeNone.c 用于解码非unicode编码的字符,程序如下- #include "GUI_Private.h"
- /*********************************************************************
- *
- * Static code
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * _GetCharCode
- *
- * Purpose:
- * Return the UNICODE character code of the current character.
- */
- static U16 _GetCharCode(const char GUI_UNI_PTR * s) {
- if((*s) > 0xA0)
- {
- return *(const U16 GUI_UNI_PTR *)s;
- }
- return *(const U8 GUI_UNI_PTR *)s;
- }
- /*********************************************************************
- *
- * _GetCharSize
- *
- * Purpose:
- * Return the number of bytes of the current character.
- */
- static int _GetCharSize(const char GUI_UNI_PTR * s) {
- GUI_USE_PARA(s);
- if((*s) > 0xA0)
- {
- return 2;
- }
- return 1;
- }
- /*********************************************************************
- *
- * _CalcSizeOfChar
- *
- * Purpose:
- * Return the number of bytes needed for the given character.
- */
- static int _CalcSizeOfChar(U16 Char) {
- GUI_USE_PARA(Char);
- if(Char > 0xA0A0)
- {
- return 2;
- }
- return 1;
- }
- /*********************************************************************
- *
- * _Encode
- *
- * Purpose:
- * Encode character into 1/2/3 bytes.
- */
- static int _Encode(char *s, U16 Char) {
- if(Char > 0xA0A0)
- {
- *((U16 *)s) = (U16)(Char);
- return 2;
- }
- *s = (U8)(Char);
- return 1;
- }
- /*********************************************************************
- *
- * Static data
- *
- **********************************************************************
- */
- /*********************************************************************
- *
- * _API_Table
- */
- const GUI_UC_ENC_APILIST GUI__API_TableNone = {
- _GetCharCode, /* return character code as U16 */
- _GetCharSize, /* return size of character: 1 */
- _CalcSizeOfChar, /* return size of character: 1 */
- _Encode /* Encode character */
- };
- const GUI_UC_ENC_APILIST GUI_UC_None = {
- _GetCharCode, /* return character code as U16 */
- _GetCharSize, /* return size of character: 1 */
- _CalcSizeOfChar, /* return size of character: 1 */
- _Encode /* Encode character */
- };
复制代码 6.1.2 另一个要添加的文件主要是用于从外部存储器读取字体点阵数据,并提供为emWin提供相应的接口函数- #include <stddef.h> /* needed for definition of NULL */
- #include "GUI_Private.h"
- #include "ff.h"
- #include "bsp.h"
- #include "MainTask.h"
- /* 字模数据的暂存数组,以单个字模的最大字节数为设定值 */
- #define BYTES_PER_FONT 1024
- static U8 GUI_FontDataBuf[BYTES_PER_FONT];
-
- FIL fsrc; // 定义文件操作类
- FRESULT res; // 定义操作结果变量
- UINT bw1; // 定义读写数量变量
- /*---------------------------------------------------------------------------*/
- /*字库外部函数部分-----------------------------------------------------------*/
- void GUI_X_GetFontData(char* font, U32 oft, U8 *ptr, U16 bytes)
- {
- res = f_open(&fsrc, font, FA_OPEN_EXISTING | FA_READ); //打开字库文件
- if(res != FR_OK)
- {
-
- }
- res = f_lseek(&fsrc,oft); //找到首地址
- res = f_read(&fsrc, ptr, bytes, &bw1); //读取字库点阵数据
- res = f_close(&fsrc); //关闭字体
-
- }
- static void GUI_GetDataFromMemory(const GUI_FONT_PROP GUI_UNI_PTR *pProp, U16P c)
- {
- U16 BytesPerFont;
- U32 oft;
- 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)
- {
- oft = (c-0x20) * BytesPerFont;
- }
- else
- {
- /* 用于读取12*12 和 16*16点阵字符 */
- if(font[21] == '1')
- {
- /* 中文字符地址偏移算法包括符号 */
- oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xA1) * 94)* BytesPerFont;
- }
- /* 用于读取24*24 48*48 */
- else
- {
- /* 中文字符地址偏移算法包括符号 */
- oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xB0) * 94)* BytesPerFont;
- }
- }
- GUI_X_GetFontData(font, oft, GUI_FontDataBuf, BytesPerFont);
-
- }
-
- void GUIPROP_X_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, /* Bits per Pixel */
- BytesPerLine,
- &GUI_FontDataBuf[0],
- &LCD_BKCOLORINDEX
- );
- /* Fill empty pixel lines */
- 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); /* Restore draw mode */
- // if (!GUI_MoveRTL)
- GUI_pContext->DispPosX += pCharInfo->XDist * GUI_pContext->pAFont->XMag;
- }
- }
- /*********************************************************************
- *
- * GUIPROP_GetCharDistX
- */
- 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;
- }
复制代码 6.1.3 比如这里要显示12*12的点阵数据需要提供一个如下内容的文件- #include "GUI.h"
- extern void GUIPROP_X_DispChar(U16P c);
- extern int GUIPROP_X_GetCharDistX(U16P c);
- GUI_CONST_STORAGE GUI_CHARINFO GUI_FontHZ12_CharInfo[2] =
- {
- { 6, 6, 1, (void *)"0:/system/gui_font/ASC6x12.bin"},
- { 12, 12, 2, (void *)"0:/system/gui_font/HZ12x12.bin"},
- };
- GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ12_PropHZ= {
- 0xA1A1,
- 0xFEFE,
- &GUI_FontHZ12_CharInfo[1],
- (void *)0,
- };
- GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontHZ12_PropASC= {
- 0x0000,
- 0x007F,
- &GUI_FontHZ12_CharInfo[0],
- (void GUI_CONST_STORAGE *)&GUI_FontHZ12_PropHZ,
- };
- GUI_CONST_STORAGE GUI_FONT GUI_FontHZ12 =
- {
- GUI_FONTTYPE_PROP_USER,
- 12,
- 12,
- 1,
- 1,
- (void GUI_CONST_STORAGE *)&GUI_FontHZ12_PropASC
- };
- GUI_CONST_STORAGE GUI_FONT GUI_FontHZ12x2 =
- {
- GUI_FONTTYPE_PROP_USER,
- 12,
- 12,
- 2,
- 2,
- (void GUI_CONST_STORAGE *)&GUI_FontHZ12_PropASC
- };
复制代码 6.1.4 还有一个重要的问题就是需要在GUI_Typ.h文件里面添加如下的声明
#define GUI_FONTTYPE_PROP_USER \
GUIPROP_X_DispChar, \
GUIPROP_X_GetCharDistX, \
GUIMONO_GetFontInfo, \
GUIMONO_IsInFont, \
(GUI_GETCHARINFO *)0, \
(tGUI_ENC_APIList*)0
6. 2 点阵字体的说明
关于点阵字体,这里有一点需要特别的说明:
12*12点阵汉字和字符 使用的是UCDOS里面的,半角和全角字符显示都正常,汉字也正常
偏移地址计算:oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xA1) * 94)* BytesPerFont;
16*16点阵汉字和字符 使用的是UCDOS里面的,半角和全角字符显示都正常,汉字也正常
偏移地址计算:oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xA1) * 94)* BytesPerFont;
24*24点阵汉字和字符 使用的是UCDOS里面的,半角显示正常,字库里面全角字符,需要单独添加。
偏移地址计算:oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xB0) * 94)* BytesPerFont; 注意和前两个的不同
主要是因为这个里面只有汉字。最重要的是这个字体居然显示的时候是躺在的,而且上下镜像。
所以24*24的点阵是用软件《字模3》生成的。
48*48点阵汉字和字符 使用的是UCDOS里面的,半角显示正常,字库里面全角字符,需要单独添加。
偏移地址计算:oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xB0) * 94)* BytesPerFont; 注意和前两个的不同
主要是因为这个里面只有汉字。
提供一下我从网上下载的UCDOS字体
ABC 英文字库文件
ASC12 ASCII字库文件12X6
ASC16 ASCII字库文件16X8
ASC48 ASCII字库文件48X24
Hzk12 汉字库宋体12X12
Hzk16 汉字库宋体16X16
hzk16F 汉字库仿宋16X16
HZK24F 汉字库仿宋24X24
HZK24H 汉字库黑体24X24
HZK24K 汉字库楷体24X24
HZK24S 汉字库宋体24X24
HZK24T 全角字符库24X24
HZK24Z 汉字库篆体24X24
HZK40S 汉字库宋体40X40
HZK40T 全角字符库40X40
HZK48S 汉字库宋体48X48
HZK48S 全角字符库48X48
字库UCDOS.zip
(3.26 MB, 下载次数: 2168)
6. 3 将生成的字体移植到armfly - v5开发板上面
根据上面的说明将其添加到工程中即可,通过截图,实际显示效果如下:
6. 4 实验总结
实际使用中,从SD卡读取大点阵的数据并显示,显示速度比较的慢,不能满足实际的应用,所以建议大字体存储到内部flash(当然是只生产部分字体)。
还有一个比较郁闷的地方是,以前我用字模提取软件《字模3》非常的好用,字体能够在UCGUI上面正常的显示,现在用emWin,32*32以上的点阵就是无法显示,
下面这个图就是以前用UCGUI时的显示效果,软件《字模3》生成的汉字前面没有全角字符,这点一定要注意,也就是说里面只有汉字。
SD卡根目录要放的文件
system.zip
(1.29 MB, 下载次数: 2535)
程序下载
STemWin5.20+uCOS-III+FatFS.zip
(15.97 MB, 下载次数: 9422)
|
|