版主
最后登录1970-1-1
在线时间 小时
注册时间2018-12-17
|
本帖最后由 ZZZ_XXJ 于 2020-5-18 00:25 编辑
由于软硬件平台的差异,emwin模拟器工程显示中文的方法与在stm32上用的方法有所不同。在VS2019中,根据想模拟的内容和实现方法大致可以分成两种方法,下面就来讲下具体怎么显示。
1. 在讲之前需要先对VS2019进行一些设置,首先打开emwin模拟器工程,在界面左上角点击文件->高级保存选项。如果没有这个选项的可以照这个链接进行设置:VS2019 设置显示”高级保存选项“
2. 在高级保存选项中,选择编码为:Unicode(UTF-8带签名),这里设置的是包含待显示中文字符的文件,比如MainTask.c中要显示中文,则必须在VS2019主界面切换到该文件后再设置。
3. 右键模拟器工程名,在弹出的菜单中点击属性。
4. 在弹出来的属性页面中,点击C/C++左边的箭头,找到命令行页面,然后在其他选项里添加:/utf-8
到这准备工作就做完了。
第一种方法很简单,只需要用字体转换软件FontCvST生成.c格式字库,然后把字库文件添加到模拟工程中就可以了。如果能确定界面需要的中文字符个数,推荐方法一。如果不能确定中文字符个数,那只能用方法二。
FontCvST的使用方法已经在野火《emWin 应用开发实战》的第38章第1小节有详细讲解,在这里就不重复讲了。c字库文件的生成步骤和教程中基本一致,唯一不同的是保存。
1. 保存c格式字库到emwin模拟器工程的Sample文件夹下,保存类型选择c-files,文件名不能有中文和空格。
2. 把生成好的字库文件添加模拟器工程中,添加步骤在野火《emWin 应用开发实战》第4章第4小节有详细介绍,在此不再重复。
打开字库文件可以看到有个变量GUI_FontSiyuanheiti_Medium64,这个就是用来给其他文件调用的字体变量
3. 把字体变量添加到需要显示中文的文件中,这里直接上代码。添加好之后在MainTask函数中启用UTF-8编码,然后像选择普通字体一样选择GUI_FontSiyuanheiti_Medium64,就可以显示中文了。
- #include "GUI.h"
- /*********************************************************************
- *
- * Static data
- *
- **********************************************************************
- */
- GUI_CONST_STORAGE GUI_FONT GUI_FontSiyuanheiti_Medium64;
- /*********************************************************************
- *
- * Static code
- *
- **********************************************************************
- */
- /**
- * [url=home.php?mod=space&uid=41770]@brief[/url] GUI主任务
- * @note 无
- * @param 无
- * @retval 无
- */
- void MainTask(void)
- {
- GUI_Init();
- /* 启用UTF-8编码 */
- GUI_UC_SetEncodeUTF8();
- /* 选择字体 */
- GUI_SetFont(&GUI_FontSiyuanheiti_Medium64);
- GUI_SetColor(GUI_CYAN);
- GUI_DispString("VS2019上的emwin模拟器中文显示示例");
- while(1)
- {
- GUI_Delay(100);
- }
- }
复制代码
显示效果
把stm32的emWin中文显示例程直接移植到模拟器上,就可以用第一种方法。
只添加MainTask.c到工程,把文件中所有跟emwin无关的头文件和代码全部删除,MainTask函数中创建字体的函数也删掉,然后按照上面的步骤即可。
如果不确定仿真界面的中文字符数量,那么就只能用方法二。这种方法因为涉及到Win32 API, 所以要复杂些,但是好处是不限制字库文件格式,XBF、SIF,甚至TTF格式都能显示。其实说复杂也不复杂,就只是把外部字库显示例程里的GUIFont_Create.c的文件读取部分修改下即可,我就直接上代码了。
首先是XBF格式的文件读取部分:
- /* 字库文件路径,最长不超过260字符 */
- char FONT_XINSONGTI_18_ADDR[_MAX_PATH] = { "Sample\\新宋体18.xbf" };
- char FONT_SIYUANHEITI_36_ADDR[_MAX_PATH] = { "Sample\\思源黑体36_2bpp.xbf" };
- /**
- * @brief 获取字体数据的回调函数
- * @param Offset:要读取的内容在XBF文件中的偏移位置
- * @param NumBytes:要读取的字节数
- * @param pVoid:自定义数据的指针
- * @param pBuffer:存储读取内容的指针
- * @retval 0 成功, 1 失败
- */
- static int _cb_FONT_XBF_GetData(U32 Offset, U16 NumBytes, void* pVoid, void* pBuffer)
- {
- HANDLE hFile;
- DWORD NumBytesRead;
- /* 打开文件 */
- hFile = CreateFile((char*)pVoid, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- /* 指针偏移 */
- if (SetFilePointer(hFile, Offset, 0, FILE_BEGIN) == 0xFFFFFFFF) {
- return 1; // Error
- }
- /* 读取文件内容 */
- if (!ReadFile(hFile, pBuffer, NumBytes, &NumBytesRead, 0)) {
- return 1; // Error
- }
- if (NumBytesRead != NumBytes) {
- return 1; // Error
- }
- CloseHandle(hFile);
- return 0; // Ok
- }
- else
- return 1;
- }
复制代码
然后是SIF格式:
- /* 字库文件路径,最长不超过260字符 */
- char FONT_XINSONGTI_18_ADDR[_MAX_PATH] = { "Sample\\新宋体18_4bpp.sif" };
- char FONT_SIYUANHEITI_36_ADDR[_MAX_PATH] = { "Sample\\思源黑体36_4bpp.sif" };
- /* 字库缓冲区 */
- char* SIFbuffer36;
- char* SIFbuffer18;
- /**
- * @brief 加载字体数据到SDRAM
- * @note 无
- * @param res_name:要加载的字库文件名
- * @retval Fontbuffer:已加载好的字库数据
- */
- void* FONT_SIF_GetData(const char* res_name)
- {
- char* Fontbuffer;
- GUI_HMEM hFontMem;
- HANDLE hFile;
- DWORD NumBytesRead;
- DWORD FileSize;
- /* 打开文件 */
- hFile = CreateFile(res_name, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- /* 获取文件大小 */
- FileSize = GetFileSize(hFile, NULL);
- /* 申请一块动态内存空间 */
- hFontMem = GUI_ALLOC_AllocZero(FileSize);
- /* 转换动态内存的句柄为指针 */
- Fontbuffer = GUI_ALLOC_h2p(hFontMem);
- /* 读取文件内容 */
- if (!ReadFile(hFile, Fontbuffer, FileSize, &NumBytesRead, 0)) {
- return 1; // Error
- }
- CloseHandle(hFile);
- return Fontbuffer; //OK
- }
- else
- return 1;
- }
复制代码
最后是TTF格式:
- /* 字库文件路径,最长不超过260字符 */
- char FONT_TTF_ADDR[_MAX_PATH] = { "Sample\\DroidSansFallbackFull.ttf" };
- /**
- * @brief 获取字体数据
- * @note 无
- * @param res_name:要读取的文件名
- * @retval 无
- */
- static char FONT_TTF_GetData(const char* res_name)
- {
- HANDLE hFile;
- DWORD NumBytesRead;
- DWORD FileSize;
- /* 打开文件 */
- hFile = CreateFile(res_name, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- if (hFile != INVALID_HANDLE_VALUE)
- {
- /* 获取文件大小 */
- FileSize = GetFileSize(hFile, NULL);
- /* 申请一块动态内存空间 */
- hFontMem = GUI_ALLOC_AllocZero(FileSize);
- /* 转换动态内存的句柄为指针 */
- TTFfont_buffer = GUI_ALLOC_h2p(hFontMem);
- /* 读取文件内容 */
- if (!ReadFile(hFile, TTFfont_buffer, FileSize, &NumBytesRead, 0)) {
- return 1; // Error
- }
- CloseHandle(hFile);
- /* 配置属性 */
- ttf_data.pData = TTFfont_buffer;
- ttf_data.NumBytes = FileSize;
- /* 配置字体参数 */
- cs0.pTTF = &ttf_data;
- cs0.PixelHeight = 24;
- cs0.FaceIndex = 0;
- cs1.pTTF = &ttf_data;
- cs1.PixelHeight = 48;
- cs1.FaceIndex = 0;
- cs2.pTTF = &ttf_data;
- cs2.PixelHeight = 72;
- cs2.FaceIndex = 0;
- cs3.pTTF = &ttf_data;
- cs3.PixelHeight = 96;
- cs3.FaceIndex = 0;
- cs4.pTTF = &ttf_data;
- cs4.PixelHeight = 120;
- cs4.FaceIndex = 0;
- }
- else
- return 1;
- }
复制代码
如果觉得自己改太麻烦,还可以到这里下载源文件,和stm32例程是兼容的,通过GUIFont_Create.h里的宏USE_WIN32来切换
emwin模拟器中文显示程序.7z
(4.5 KB, 下载次数: 59)
下面是VS2019模拟器跑XBF、SIF和TTF格式字库例程的效果
WIN32 API的一些参考资料:
ReadFile function
CreateFileA function
Win32 文件的读写操作
[API档案] ReadFile 函数说明
[WinAPI] API 10 [创建、打开、读写文件,获取文件大小]
|
|