37. XBF格式字体显示

本文详细介绍了如何使用SEGGER的字体转换器生成XBF格式的中文字体,这种字体格式适合在RAM有限的嵌入式系统中使用。通过选择字体类型、大小,保存为XBF文件,然后利用GUI_XBF_CreateFont()创建字体,并通过回调函数从文件中获取数据。文章还展示了如何在STM32系统中从SPI Flash或SD卡加载XBF字体,以及处理Unicode编码问题以确保在emWin界面上正确显示中文。
摘要由CSDN通过智能技术生成

上一章讲了很多emWin支持的字体形式,从本章开始我们讲解如果利用这些字体形式来做中文显示。

首先讲解XBF格式字体的使用。XBF格式,又称为外部位图字体(External Bitmap Font)格式, 是一种包含字体信息的二进制数据块,可以使用emWin配套的字体转换器生成。使用XBF字体时字体文件不需要全部加载到内存中, 保留在任何外部存储器上即可。它的数据访问是由一个“GetData”回调函数完成的。也就是说XBF格式字体的优点是可以在RAM很少的系统上使用大规模字库。

并且XBF格式字体中的字符并不是直接按顺序排列的,而是带有一个内存偏移量,因此每个字符可以在相同的时间内找到。

具体来说,首先,它包含一小块一般的字体信息,包括最低字符码和最高字符码。然后接一个访问表, 其中包含最低和最高字符代码之间所有字符的偏移量和数据大小信息。如果某个字符不存在,则对应字符的此信息为零。 访问表后面是包含像素数据和字符大小信息的所有字符的数据。

37.1. 字体转换器
字体转换器是SEGGER公司为emWin开发的一种主要用于将安装在Windows系统中的字体转换为emWin支持的字体的软件, 仅支持Windows系统环境。软件界面如图 字体转换器外观 所示。
在这里插入图片描述
字体转换器可以从SEGGER官网的emWin页面下载,也可以在STM32的CUBE库中找到。转换器在CUBE库中的路径如下:

STM32Cube_FW_F4_V1.24.1\Middlewares\ST\STemWin\Software\FontCvtST.exe

注意:字体转换器没有附带任何字体或使用任何PC安装字体进行转换的权限或许可。使用者有责任在使用字型时不侵犯任何第三者的知识产权, 并在字型的合法拥有人要求时取得授权。

37.2. 生成XBF字库
下面我们以思源黑体为例,讲解如何使用字体转换器生成XBF格式字库。

  1. 选择需要生成的字体类型。双击FontCvtST.exe打开字体转换器,在弹出来的对话框中选择Extended, antialised, 2bpp, 也就是带2bpp抗锯齿的扩展比例位图字体,然后编码格式选择16Bit UNICODE,见图 选择emWin字体类型 。
    在这里插入图片描述
  2. 点击OK后,选择字体为思源黑体,字形常规,大小36,尺寸单位选择Pixels, 见图 选择字体和大小 。

在这里插入图片描述
3) 保存字库文件。选择找字体类型和大小之后,点击字体转换器左上角的File, 然后选择Save As,见图 保存字库文件 。

在这里插入图片描述
4) 然后选择保存路径,设置文件名为思源黑体36_2bpp, 保存文件格式为.xbf,见图 选择保存路径 。
在这里插入图片描述
5) 最后,等待字体转换器转换完成。完成后会在窗口左下角显示“Ready”, 见图 等待转换完成 。
在这里插入图片描述
至此,一个XBF格式的字库就生成完毕了,使用相同的方法再制作一个新宋体18.xbf,和思源黑体36_2bpp.xbf一起放到SD卡的Font目录下。

有一点需要注意,字体转换器里设置的字体大小是包括字体上下边界的总大小,而不同的字体有着不同尺寸的上下边界, 例如思源黑体这样的字体上下边界就很宽,而新宋体的上下边界就比较窄。这也是为什么明明两种字体生成的都是同一种大小,显示出来却不一样大。

37.3. XBF字体显示相关API
在这里插入图片描述
37.3.1. GUI_XBF_CreateFont()
通过向回调函数传递指针来创建和选择字体,回调函数负责从XBF字体文件获取数据。

代码清单:XBF-1 函数原型

int GUI_XBF_CreateFont(GUI_FONT *pFont, GUI_XBF_DATA *pXBF, const
                    GUI_XBF_TYPE *pFontType, GUI_XBF_GET_DATA_FUNC
                    *pfGetData, void *pVoid);
  1. pFont: 指向RAM中由该函数填充的GUI_FONT结构的指针;

  2. pXBF_Data: 指向RAM中由该函数填充的GUI_XBF_DATA结构的指针;

  3. pFontType: 字体类型,见;

  4. pfGetData: 指向回调函数的指针,该回调函数负责从字体文件中获取数据;

  5. pVoid: 应用程序定义的指针传递给’ GetData ‘回调函数。

返回值:字体创建成功时返回0,在字体创建失败时返回1。

在这里插入图片描述
参数pfGetData应该指向一个应用程序定义的回调例程,它负责从字体获取数据。当请求字体数据时, 参数pVoid被传递给回调函数。例如,可以使用它将文件句柄传递给回调函数。

该函数需要指向GUI_FONT结构和GUI_XBF_DATA结构。该函数将用字体信息填充这些结构。在使用字体期间, 这些结构的内容必须保持有效。该函数不知道应用程序要创建什么样的XBF字体, 因此必须使用参数pFontType来告诉函数要创建的字体的类型。这样做是为了避免不必要的代码链接。

37.3.2. GUI_XBF_DeleteFont()
删除参数pFont指向的XBF字体。

代码清单:XBF-2 函数原型

void GUI_XBF_DeleteFont(GUI_FONT * pFont);
  1. pFont: 指向要删除的字体的指针。

使用GUI_XBF_CreateFont()创建的字体之后,如果不再使用,应该删除该字体。

37.4. XBF格式字体显示实验
接下来我们通过一个实验来讲解如何使用已经生成好的XBF格式字体,更多相关内容的演示实验可参考官方例程FONT_ShowXBF.c,例程路径如下:

SeggerEval_WIN32_MSVC_MinGW_GUI_V548\Sample\Tutorial\FONT_ShowXBF

37.4.1. 代码分析
在本实验中我们提供了两种字库存放区域,一种是SPI FLASH的非文件系统区域, 一种是SD卡文件系统区域,如 代码清单:XBF-3 所示。

代码清单:XBF-3 字库存放位置(GUIFont_Create.h文件)

//设置XBF字体存储的位置:
//FLASH非文件系统区域(推荐)USE_FLASH_FONT  0
//SD卡文件系统区域          USE_SDCARD_FONT 1
#define XBF_FONT_SOURCE       1

/*
(速度最快)字库在FLASH的非文件系统区域,使用前需
要往FLASH特定地址拷贝字体文件 */
#define USE_FLASH_FONT        0
/*
(速度中等)字库存储在SD卡文件系统区域,调试比较
方便,直接使用读卡器从电脑拷贝字体文件即可 */
#define USE_SDCARD_FONT       1

上述代码中,XBF_FONT_SOURCE决定着程序从什么位置读取字库数据,为0时,从SPI FLASH中读取字库;为1时, 则从SD卡中读取字库。在GUIFont_Create.c文件中,提供了从SPI_FLASH或者SD卡读取字库数据的函数。我们选择从SD卡读取字库。

如果从SPI FLASH中读取字库,请先运行《刷外部FLASH程序(烧录STemWIN资源文件)》例程, 将emWin相关的资源烧录到SPI FLASH中,否则字库实验无法进行。

37.4.1.1. 创建字体
代码清单:XBF-4 Create_XBF_Font函数(GUIFont_Create.c文件)

/* 字库结构体 */
GUI_XBF_DATA  XBF_XINSONGTI_18_Data;
GUI_FONT      FONT_XINSONGTI_18;

GUI_XBF_DATA  XBF_SIYUANHEITI_36_Data;
GUI_FONT      FONT_SIYUANHEITI_36;

/* SD卡中的字库路径 */
static const char FONT_STORAGE_ROOT_DIR[] = "0:";
static const char FONT_XINSONGTI_18_ADDR[] = "0:/Font/新宋体18.xbf";
static const char FONT_SIYUANHEITI_36_ADDR[] = "0:/Font/思源黑体36_2bpp.xbf";

/**
* @brief  创建XBF字体
* @param  无
* @retval 无
*/
void Create_XBF_Font(void
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值