二进制字体
本节描述如何在TouchGFX中使用二进制字体。 第一部分包含TouchGFX中关于字体和文本系统的一些深度信息,在使用二进制字体时有助于加深理解。 第二部分说明如何使用二进制字体。
二进制字体可用作将字体信息编译并链接到应用(generated/fonts/src
中的.cpp文件)的传统方式的替代方案。 此方法的主要优势是应用的二进制数据量更少,在为设备提供不同字体集合方面具有灵活性。 例如,可以为要销往中国的设备提供中文字体,并为要销往日本的设备提供日文字体。 此方法的缺点是需要将整个二进制字体加载到RAM(或存储器映射闪存),在字体较大时会面临困难。
将字体链接到应用的基本原则的主要优势是应用始终会自动包含应用中使用的更新文本和字体排印。 因此,使用起来十分容易和安全。 其缺点在于字体会使应用的体积变大。
字体和文本系统类
在默认配置中,TouchGFX为应用中使用的所有文本和字体生成.cpp文件。 这些文件连同生成的UI和应用代码一起被编译和链接到应用中。
在UI的TextArea等区域显示文本时,用TypedTextId引用文本。 控件使用此TypedTextId查找文本中的实际字母。 控件将通过framework/include/touchgfx/Texts.hpp
中的touchgfx::Texts类访问文本。
Text类包含指针阵列,指针指向应用中每种语言的翻译表。 翻译表基本上是语言中使用的所有字符串的集合:
此表使TouchGFX能够在选中语言中找到给定文本。
每当您在TouchGFX 设计器中更改文本或直接在 texts.xml
文件中更改文本并生成应用程序时,都会重新生成表格。
我们需要先知道文本要使用的字体,然后才能在屏幕上绘制。 文本与字体之间的映射由TypedTextDatabase类(generated/texts/include/texts/TypedTextDatabase.hpp
)控制。
在TouchGFX Designer的文本选项卡上,可以指定每种文本的字体排印、书写顺序(从左向右或从右向左)和对齐方式(左、右和中心)。 文本的每种翻译文件的字体排印、书写顺序和对齐方式可能不同。 此信息被编译到每种语言特定的表格中。 因此,TouchGFX很容易找出要对给定文本使用的字体、对齐方式和书写方式。
在上图中,TypedTextData表有指向三个阵列的指针, 每个对应于应用中的一种语言。 每个阵列有3个元素,每个元素对应于系统中的一种文本。 每个元素都描述了字体、阅读顺序和对齐方式。 我们看到,在这个例子中,三种语言的文本使用相同的字体,但文本使用不同的字体(F1或F2)。 应用中有两种字体,因此字体表有两个指针。
当TouchGFX要在屏幕上绘制文本时,会查找TypedTextData获取给定文本。 此数据包含TouchGFX 设计器或xml中规定的文本字体索引、字母顺序(LTR/RTL)和水平对齐方式(左、右和中心)。 TouchGFX使用TypedTextData(F1或F2)中的字体索引查找文本的正确字体。
在将字体编译到应用中时,所有这些操作都会自动发生。
使用二进制字体
当应用使用许多不同字体的许多字母时,应用的大小会大大增加。
为了缓解这个问题,TouchGFX允许应用使用二进制字体。 这些字体不链接到应用,而是独立于应用保存为单独的文件。 应用在运行时间将这些文件加载并提供给TouchGFX。 举例来说,应用可以从外部存储器(如SD卡)加载字体,也可以从互联网下载字体。
在加载字体后,应用可以要求TouchGFX安装字体系统中的二进制字体:
这里的自带Font2被应用加载的Binaryfont替代。 此后,TouchGFX将不使用内联Font2。
请注意,文本表中没有任何更改。 仍然通过索引来引用相同的字体(F1和F2)。
配置字体转换器以生成二进制字体
为了生成二进制字体,必须配置字体转换器。 这在TouchGFX设计器中很容易做到。 转至“配置”选项卡,选择“文本配置”,然后点击“二进制字体文件”:
在重新生成代码时,TouchGFX将在generated/fonts/bin/
文件夹中生成二进制字体,并清空generated/fonts/src/
文件夹中普通文件中的字体.
生成的代码将TouchGFX配置为使用空字体。 应用程序需要在运行时安装二进制字体。
手动配置
如果不使用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闪存等可寻址内存中可用(可通过指针直接访问)。 通常会涉及从文件或块存储(如:emmc flash)复制数据。 也可能发生在生产过程中,二进制字体闪存到存储映射闪存中的预定义地址。
当应用程序将二进制字体加载到内存中时(如果还不可用),应用程序必须创建并安装一个BinaryFont
对象,引用TouchGFX中的数据。 然后,TouchGFX将使用该字体而不是编译的字体。
二进制字体需要在用于绘制引用字体的文本之前安装,但不需要在启动后立即安装。 FrontApplication.cpp
中的FrontendApplication::FrontendApplication(Model&m,FrontendHeap&heap)构造函数可用于安装字体。 将在绘制任何内容之前执行此构造函数。
字体也可以安装在setupScreen()
法中。 如果您的字体仅在特定屏幕中使用,这会非常有用。 然后可以在tearDownScreen()
中卸载字体
以下是将二进制字体从文件系统加载到内部RAM的示例:
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的TypedTextDatabase
。
调用setFont后,TouchGFX将使用二进制字体而不是编译字体(DEFAULT)在屏幕上绘制文本。
重置字体
在使用二进制字体后,有时会想要恢复编译到应用中的原始字体。 例如,在更改语言时,想要使用默认字体。 TypedTextDatabase中的resetFont()
函数将重置指向自带字体的字体指针:
//reset to original font
TypedTextDatabase::resetFont(DEFAULT);
在调用后,应用可以重复使用被二进制字体占用的存储空间,以便分配新字体或用于其他用途。
在另一个项目中生成二进制字体
某些情况下,您希望在项目中同时使用普通字体和二进制字体。 例如,您希望在设备中使用普通编译字体的英文字母,但可以选择使用二进制字体的中文和日语字符。 此设置在TouchGFX设计器中不可配置。
此时,建议创建两个TouchGFX项目。 在第一个项目(您的普通应用程序)中,您拥有所有使用普通字体的应用程序代码和UI。 在第二个项目中,您只有足够的文本(或通配符)来生成二进制字体。
在第一个项目中,取消选择“二进制字体文件”。 在第二个项目中,选择“二进制字体文件”。
当您在第二个TouchGFX项目中生成代码时,将生成二进制字体。 然后,可以将二进制字体复制到第一个项目(在您方便的文件夹中),并在如上所示的代码中使用。