完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
转stemwin教程
本期教程主要讲如何将字库放置到外部存储器的方法,这里以放到SD卡为例,放到其他存储器是一样的。本章教程提供的方法是以前UCGUI时代遗留下来的,这种方法相对于后面要讲到的XBF方式还是有差距的(官方推荐方式)。不过为了照顾以前从UCGUI转战过来的,写了这么一期教程。 19. 1 移植方法 19. 2 总结 19.1 移植方法 19.1.1 第一步:添加相关文件 在工程的emWin文件夹中新建一个HanZi文件夹,主要有以下几个文件: |
|
相关推荐
|
|
19.1.3 第三步:GUI_UC_EncodeNone.c文件内容
复制代码 #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 */ }; /********************************************************************* * * Exported code * ********************************************************************** */ /********************************************************************* * * GUI_UC_SetEncodeNone */ //void GUI_UC_SetEncodeNone(void) { // GUI_LOCK(); // GUI_pContext->pUC_API = &GUI__API_TableNone; // GUI_UNLOCK(); //} |
|
|
|
|
|
19.1.4 第四步:GUICharPEx.c文件内容
复制代码 #include #include "GUI_Private.h" #include "ff.h" #include "bsp.h" #include "MainTask.h" #include "string.h" /* 字模数据的暂存数组,以单个字模的最大字节数为设定值 */ #define BYTES_PER_FONT 1024 static U8 GUI_FontDataBuf[BYTES_PER_FONT]; /* 用于12*12和16*16电子汉字的路径部分,要和其它汉字路径作区分 使用sizeof的时候,得指定数组的大小。 */ const char FontEx_HZ[22] = {"0:/system/gui_font/HZ1"}; 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); //读取32个字库点阵数据 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 { if(strncmp(FontEx_HZ, font, sizeof(FontEx_HZ)) == 0) (1) { /* 中文字符地址偏移算法包括符号 */ oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xA1) * 94)* BytesPerFont; } 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; } |
|
|
|
|
|
1. 这个地方非常重要,讲之前先介绍下外置到SD卡中的字体。
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; 注意和前两个的不同。主要是因为这个里面只有汉字。最重要的是这个字体居然显示的时候是躺在的,而且上下镜像。 48*48点阵汉字和字符 使用的是UCDOS里面的,半角显示正常,字库里面全角字符,需要单独添加。 偏移地址计算:oft = ((((c >> 8)-0xA1)) + ((c & 0xFF)-0xB0) * 94)* BytesPerFont; 注意和前两个的不同。主要是因为这个里面只有汉字。 SD卡中存放的字库如下(路径0:/system/gui_font): 特别注意24*24和48*48汉字点阵库中没有加全角字符,而12*12和16*16中添加了,所以就出现了上面程序中的区别对待。用路径的前22个字符0:/system/gui_font/HZ1就可以区分开。 |
|
|
|
|
|
19.1.5 第五步:字库文件
下面的是GUI_Font12.c中的内容,其它类似: 复制代码 #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] = (1) { { 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 }; 1. 要修改文件存放的路径,需要修改这里和GUICharPEx文件中的: const char FontEx_HZ[22] = {"0:/system/gui_font/HZ1"}; |
|
|
|
|
|
19.1.6 第六步:在GUI_Type.h中添加声明
添加如下内容,声明一种新的字体结构 复制代码 #define GUI_FONTTYPE_PROP_USER GUIPROP_X_DispChar, (GUI_GETCHARDISTX *) GUIPROP_X_GetCharDistX, GUIMONO_GetFontInfo, GUIMONO_IsInFont, (GUI_GETCHARINFO *)0, (tGUI_ENC_APIList*)0 |
|
|
|
|
|
19.1.7 第七步:添加主函数
复制代码 #include "includes.h" #include "MainTask.h" extern GUI_CONST_STORAGE GUI_FONT GUI_FontHZ48; /* ********************************************************************************************************* * 对话框信息 ********************************************************************************************************* */ static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { { FRAMEWIN_CreateIndirect, "armfly", 0, 0, 0, 800,480,FRAMEWIN_CF_MOVEABLE,0}, { BUTTON_CreateIndirect, "安富莱电子armfly", GUI_ID_BUTTON0, 40,320,700,100,0,0}, { BUTTON_CreateIndirect, "世界人民欢迎你Eric2013", GUI_ID_BUTTON1, 40,200,700,100,0,0}, { TEXT_CreateIndirect, "armfly安富莱电子armfly", GUI_ID_TEXT0, 5, 10, 200, 33, 0,0}, { TEXT_CreateIndirect, "armfly安富莱电子armfly", GUI_ID_TEXT1, 5, 40,200, 33, 0,0}, { TEXT_CreateIndirect, "安富莱电子armfly", GUI_ID_TEXT2, 5, 80,360, 72, 0,0}, }; /* ********************************************************************************************************* * 函 数 名: PaintDialog * 功能说明: 重绘 * 形 参:pMsg 消息指针 * 返 回 值: 无 ********************************************************************************************************* */ void PaintDialog(WM_MESSAGE * pMsg) { WM_HWIN hWin = pMsg->hWin; } /* ********************************************************************************************************* * 函 数 名: InitDialog * 功能说明: 对话框初始化 * 形 参:pMsg 消息指针 * 返 回 值: 无 ********************************************************************************************************* */ void InitDialog(WM_MESSAGE * pMsg) { WM_HWIN hWin = pMsg->hWin; // //FRAMEWIN // FRAMEWIN_SetFont(hWin,&GUI_Font32B_ASCII); FRAMEWIN_SetTextAlign(hWin,GUI_TA_VCENTER|GUI_TA_CENTER); FRAMEWIN_AddCloseButton(hWin, FRAMEWIN_BUTTON_RIGHT, 0); FRAMEWIN_AddMaxButton(hWin, FRAMEWIN_BUTTON_RIGHT, 1); FRAMEWIN_AddMinButton(hWin, FRAMEWIN_BUTTON_RIGHT, 2); FRAMEWIN_SetTitleHeight(hWin,35); // //GUI_ID_BUTTON0 // BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON0),&GUI_FontHZ48); BUTTON_SetFont(WM_GetDialogItem(hWin,GUI_ID_BUTTON1),&GUI_FontHZ48); // //GUI_ID_TEXT0 // TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT0), GUI_RED); TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT0),&GUI_FontHZ12); TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT1), GUI_GREEN); TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT1),&GUI_FontHZ16); TEXT_SetTextColor(WM_GetDialogItem(hWin,GUI_ID_TEXT2), GUI_BLUE); TEXT_SetFont(WM_GetDialogItem(hWin,GUI_ID_TEXT2),&GUI_FontHZ24); } /* ********************************************************************************************************* * 函 数 名: _cbCallback * 功能说明: 对话框回调函数 * 形 参:pMsg 消息指针 * 返 回 值: 无 ********************************************************************************************************* */ static void _cbCallback(WM_MESSAGE * pMsg) { int NCode, Id; WM_HWIN hWin = pMsg->hWin; switch (pMsg->MsgId) { case WM_PAINT: PaintDialog(pMsg); break; case WM_INIT_DIALOG: InitDialog(pMsg); break; case WM_KEY: switch (((WM_KEY_INFO*)(pMsg->Data.p))->Key) { case GUI_KEY_ESCAPE: GUI_EndDialog(hWin, 1); break; case GUI_KEY_ENTER: GUI_EndDialog(hWin, 0); break; } break; case WM_NOTIFY_PARENT: Id = WM_GetId(pMsg->hWinSrc); NCode = pMsg->Data.v; switch (Id) { case GUI_ID_OK: if(NCode==WM_NOTIFICATION_RELEASED) GUI_EndDialog(hWin, 0); break; case GUI_ID_CANCEL: if(NCode==WM_NOTIFICATION_RELEASED) GUI_EndDialog(hWin, 0); break; } break; default: WM_DefaultProc(pMsg); } } /* ********************************************************************************************************* * 函 数 名: MainTask * 功能说明: GUI主函数 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void MainTask(void) { GUI_Init(); WM_SetDesktopColor(GUI_WHITE); /* Automacally update desktop window */ WM_SetCreateFlags(WM_CF_MEMDEV); /* Use memory devices on all windows to avoid flicker */ PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX); FRAMEWIN_SetDefaultSkin(FRAMEWIN_SKIN_FLEX); PROGBAR_SetDefaultSkin(PROGBAR_SKIN_FLEX); BUTTON_SetDefaultSkin(BUTTON_SKIN_FLEX); CHECKBOX_SetDefaultSkin(CHECKBOX_SKIN_FLEX); DROPDOWN_SetDefaultSkin(DROPDOWN_SKIN_FLEX); SCROLLBAR_SetDefaultSkin(SCROLLBAR_SKIN_FLEX); SLIDER_SetDefaultSkin(SLIDER_SKIN_FLEX); HEADER_SetDefaultSkin(HEADER_SKIN_FLEX); RADIO_SetDefaultSkin(RADIO_SKIN_FLEX); GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), &_cbCallback, 0, 0, 0); while(1) { GUI_Delay(10); } } |
|
|
|
|
|
实际显示效果如下:
特别注意,如果使用的是800*480分辨率的屏可以完全显示出来,如果是小于这个分辨率的屏只能显示出一部分,大家可以按照上面的设计方法做一个适合自己屏大小的显示或者直接拖动这个对话框即可。 |
|
|
|
|
|
19.2 总结
本期教程就为大家讲这么多,这种方法大家有个了解即可,由于考虑到还有很多从UCGUI转战过来的,而且很多项目都是用的这种方式,所以特此做了本期教程。如果对这个方法没有了解的,可以放弃这种显示方法了,因为有更好的XBF方式。 |
|
|
|
|
|
386 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1670 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
1123 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
1005 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
1229 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12019 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 14:35 , Processed in 0.857665 second(s), Total 85, Slave 67 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号