二进制字体
本节描述如何在TouchGFX中使用二进制字体。 第一部分包含TouchGFX中关于字体和文本系统的一些深度信息,在使用二进制字体时有助于加深理解。 第二部分说明如何使用二进制字体。
二进制字体可用作将字体信息编译并链接到应用(generated/fonts/src
中的.cpp文件)的传统方式的替代方案。 此方法的主要优势是应用的二进制数据量更少,在为设备提供不同字体集合方面具有灵活性。 例如,可以为要销往中国的设备提供中文字体,并为要销往日本的设备提供日文字体。 此方法的缺点是需要将整个二进制字体加载到RAM(或存储器映射闪存),在字体较大时会面临困难。
将字体链接到应用的基本原则的主要优势是应用始终会自动包含应用中使用的更新文本和字体排印。 因此,使用起来十分容易和安全。 其缺点在于字体会使应用的体积变大。
字体和文本系统类
在默认配置中,TouchGFX为应用中使用的所有文本和字体生成.cpp文件。 这些文件连同生成的UI和应用代码一起被编译和链接到应用中。
在UI的TextArea等区域显示文本时,用TextId引用文本。 控件使用此TextId查找文本中的实际字母。 控件将通过touchgfx::Texts类framework/include/touchgfx/Texts.hpp
访问文本。
Text类包含指针阵列,指针指向应用中每种语言的翻译表。 翻译表基本上是语言中使用的所有字符串的集合:
此表使TouchGFX能够在选中语言中找到给定文本。
此表会在修改TouchGFX Designer中的文本和生成应用时重新生成。
我们需要先知道文本要使用的字体,然后才能在屏幕上绘制。 文本与字体之间的映射由TypedTextDatabase类(generated/texts/include/texts/TypedTextDatabase.hpp
)控制。
在TouchGFX Designer的文本选项卡上,可以指定每种文本的字体排印、书写顺序(从左向右或从右向左)和对齐方式(左、右和中心)。 文本的每种翻译文件的字体排印、书写顺序和对齐方式可能不同。 此信息被编译到每种语言特定的表格中。 因此,TouchGFX很容易找出要对给定文本使用的字体、对齐方式和书写方式。
在上图中,TypedTextData表有指向三个阵列的指针, 每个对应于应用中的一种语言。 每个阵列有3个元素,每个元素对应于系统中的一种文本。 每个元素都描述了字体、阅读顺序和对齐方式。 在本例中可以看到,三种语言的文本使用相同字体。 应用中有两种字体,因此字体表有两个指针。
当TouchGFX要在屏幕上绘制文本时,会查找TypedTextData获取给定文本。 此数据包含Excel表格中规定的文本字体索引、字母顺序(LTR/RTL)和水平对齐方式(左、右和中心)。 TouchGFX使用TypedTextData(F1或F2)中的字体索引查找文本的正确字体。
在将字体编译到应用中时,所有这些操作都会自动发生。
使用二进制字体
当应用使用许多不同字体的许多字母时,应用的大小会大大增加。
为了缓解这个问题,TouchGFX允许应用使用二进制字体。 这些字体不链接到应用,而是独立于应用保存为单独的文件。 应用在运行时间将这些文件加载并提供给TouchGFX。 举例来说,应用可以从外部存储器(如SD卡)加载字体,也可以从互联网下载字体。
在加载字体后,应用可以要求TouchGFX安装字体系统中的二进制字体:
这里的自带Font2被应用加载的Binaryfont替代。 此后,TouchGFX将不使用内联Font2。
配置字体转换器以生成二进制字体
为了生成二进制字体,必须配置字体转换器。 这在TouchGFXDesigner中很容易实现。 转至“配置”选项卡,选择“文本配置”,然后点击“二进制字体文件”:
在重新生成代码时,TouchGFX将在generated/fonts/bin/
文件夹中生成二进制字体,并清空generated/fonts/src/
文件夹中普通文件中的字体
手动配置
如果不使用TouchGFX Designer,仍然可以生成二进制字体。 在项目的application.config文件的text_configuration部分将选项“binary_fonts”更改为“yes”。
application.config
"text_configuration": {
"remap": "yes",
"a4": "yes",
"binary_translations": "no",
"binary_fonts": "yes",
"framebuffer_bpp": "16"
}
在下一次生成assets时,二进制字体将会出现在generated/fonts/bin
文件夹中。
安装二进制字体
必须先将二进制字体从文件复制到其他存储器,然后TouchGFX才能使用它。 必须在可寻址存储器,如RAM或QSPI闪存(可通过指针访问的位置)中提供字体。
如果应用已将二进制字体加载到存储器,则可以在TouchGFX中安装字体。 现在,TouchGFX将使用该字体而不是编译的字体。 在使用文本前,需安装二进制字体,但不必在启动后立即安装。 FrontApplication.cpp
中的FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)构造函数可用于安装字体。 将在绘制任何内容之前执行此构造函数。
下面为一个示例:
FrontendApplication.cpp
//read the file into this array in internal RAM
uint8_t fontdata[10000];
//binary font object using the data
BinaryFont bf;
FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)
: FrontendApplicationBase(m, heap)
{
//read the binary font from a file
FILE* font = fopen("generated/fonts/bin/Font_verdana_20_4bpp.bin", "rb");
if (font)
{
//read data from the file
fread(fontdata, 1, 10000, font);
fclose(font);
//initialize BinaryFont object in bf using placement new
new (&bf) BinaryFont((const struct touchgfx::BinaryFontData*)fontdata);
//replace application font 'DEFAULT' with the binary font
TypedTextDatabase::setFont(DEFAULT, &bf); //verdana_20_4bpp
}
}
打开文件和读取数据的具体代码将取决于文件系统和操作系统。 基本步骤是在存储器中提供字体数据,初始化具有指向数据的指针的BinaryFont对象,并最终将BinaryFont对象传递到TouchGFX。
在调用setFont后,TouchGFX将使用二进制字体在屏幕上绘制文本。
重置字体
在使用二进制字体后,有时会想要恢复编译到应用中的原始字体。 例如,在更改语言时,想要使用默认字体。 TypedTextDatabase中的resetFont()
函数将重置指向自带字体的字体指针:
//reset to original font
TypedTextDatabase::resetFont(DEFAULT);
在调用后,应用可以重复使用被二进制字体占用的存储空间,以便分配新字体或用于其他用途。