3. TouchGFX字体生成工具:FontConverter深度解析

做嵌入式UI,字体这块儿坑特别多。我见过不少团队,界面逻辑写得挺漂亮,一上真机,中文字体要么缺笔画,要么内存直接爆了。说白了,问题都出在字体生成这一步。

TouchGFX里负责字体生成的,就是 FontConverter。这工具看着不起眼,但它是整个字体资源管线的起点。你后面所有关于字体的优化、压缩、部署,都得先过它这一关。

核心观点:FontConverter 不是简单的“字体转格式”工具。它决定了你的字库有多大、渲染效果好不好、运行时占多少内存。理解它的每个参数,是字体优化的基本功。

3.1 FontConverter 是什么?

FontConverter 是 TouchGFX Designer 自带的一个命令行工具。它能把 TrueType (.ttf) 或 OpenType (.otf) 字体文件,转换成 TouchGFX 引擎能直接用的 .ttf 和 .bpp 文件。

你可以在 TouchGFX Designer 的安装目录下找到它:

TouchGFX/4.xx.x/app/fontconverter/bin/fontconverter.exe

我个人习惯把它加到系统环境变量里,这样在任意目录都能直接调。省得每次都要敲完整路径。

它的工作流程其实很简单:

  1. 读入:加载你指定的 .ttf/.otf 字体文件
  2. 解析:根据你给的参数,提取指定字符的轮廓信息
  3. 光栅化:把矢量轮廓转成像素点阵
  4. 打包:输出 TouchGFX 能识别的字体资源文件

嗯,这里要注意:它不会帮你“创造”字体。你给什么字体,它就处理什么字体。所以源字体的质量,直接决定了最终效果。

3.2 字体配置参数详解

FontConverter 的参数很多,但真正关键的,其实就下面这几个。我按重要程度排个序:

参数 说明 我的建议
--font-file 源字体文件路径 尽量用 .ttf,兼容性最好
--output-dir 输出目录 单独建一个 fonts 文件夹,别跟代码混一起
--glyph-range 字符范围 这是最关键的参数,后面细说
--size 字体大小(像素) 跟 UI 设计稿保持一致
--bpp 每个像素的位数 2 或 4,看你的抗锯齿需求
--format 输出格式 一般用 1(标准格式)

3.2.1 glyph-range:字符范围

这个参数,说白了就是告诉 FontConverter:“我只要这些字符,其他的别管。”

为什么重要?因为中文字体动辄几千上万个字符。如果你不指定范围,它会把整个字体文件都处理一遍。结果就是:生成的 .ttf 文件巨大,MCU 根本塞不下。

我在项目中遇到过,一个 16x16 的宋体,全字库生成出来 2MB 多。而我的 Flash 总共才 4MB,还要放图片和代码。后来我把字符范围缩小到只包含 UI 上用到的 200 多个汉字,文件直接降到 80KB。

指定范围有两种方式:

  • 单个字符:--glyph-range=0x4E2D (“中”字的 Unicode)
  • 连续范围:--glyph-range=0x4E00-0x9FFF (CJK 统一汉字区)

你想想看,如果你的界面只有“开始”、“停止”、“设置”这几个词,那只需要十几个字符就够了。没必要把整个汉字区都包含进来。

我的小技巧:写一个脚本,自动扫描 UI 代码里用到的所有中文字符,然后生成对应的 glyph-range 参数。这样既不会漏字,也不会多占空间。

3.2.2 bpp:每个像素的位数

bpp 控制的是字体的抗锯齿效果。常见的有:

  • 1 bpp:纯黑白,没有灰度过渡。文件最小,但锯齿明显
  • 2 bpp:4 级灰度。折中选择,我大部分项目都用这个
  • 4 bpp:16 级灰度。效果最好,但文件大小翻倍

我曾经在一个 320x240 的屏上试过 1 bpp 的 12 号字体。显示出来,那个锯齿啊,简直没法看。后来换成 2 bpp,效果好了很多,文件大小也只增加了 30%。

所以我的建议是:小字体(<20px)用 2 bpp,大字体(>20px)用 4 bpp。小字体本身像素就少,1 bpp 的锯齿太明显;大字体像素多,4 bpp 的平滑效果能体现出来。

3.2.3 size:字体大小

这个参数直接对应 UI 设计稿里的字号。注意,单位是 像素,不是点(pt)。

我见过有人把 size 设成 12,但设计稿里用的是 12pt。结果在 96 DPI 的屏幕上,实际显示大小差了 1.5 倍。所以一定要跟设计师确认好单位。

3.3 生成流程

好,参数都讲完了。咱们走一遍完整的生成流程。

假设我有一个 SourceHanSansSC-Regular.ttf 字体,UI 上只用到了“开始”、“停止”、“设置”这三个词。我需要生成一个 16px、2 bpp 的字体资源。

第一步:确定字符范围。这三个词包含的汉字是:开、始、停、止、设、置。对应的 Unicode 是:

开 0x5F00
始 0x59CB
停 0x505C
止 0x6B62
设 0x8BBE
置 0x7F6E

第二步:写命令。我习惯用批处理文件,方便重复执行:

fontconverter.exe ^
  --font-file=SourceHanSansSC-Regular.ttf ^
  --output-dir=./output ^
  --glyph-range=0x5F00,0x59CB,0x505C,0x6B62,0x8BBE,0x7F6E ^
  --size=16 ^
  --bpp=2 ^
  --format=1

第三步:运行。几秒钟后,在 ./output 目录下会生成两个文件:

  • SourceHanSansSC-Regular_16_2.ttf:字体数据文件
  • SourceHanSansSC-Regular_16_2.bpp:像素数据文件

嗯,这里要注意:这两个文件是配套的,缺一不可。拷贝的时候一定要一起拷。

3.4 输出文件详解

生成的 .ttf 和 .bpp 文件,到底存了什么?我简单说一下:

文件 内容 存放位置
.ttf 字符的度量信息(宽度、高度、基线偏移等) Flash(只读)
.bpp 每个字符的像素点阵数据 Flash(只读)

运行时,TouchGFX 引擎会把这两个文件加载到内存中。注意,是 全部加载。所以文件越小,占用的 RAM 就越少。

避坑指南:我曾经犯过一个错——把 .ttf 文件当成普通的 TrueType 字体,想用系统字体库去加载。结果当然失败了。TouchGFX 的 .ttf 文件是经过重新编码的,只能由 TouchGFX 引擎解析。别搞混了。

3.5 知识体系总览

为了让你对整个流程有个直观印象,我画了一张图:

FontConverter 字体生成流程 源字体文件 .ttf / .otf 配置参数 glyph-range | size | bpp | format 字符范围 | 字号 | 灰度 | 格式 FontConverter 处理 解析 → 光栅化 → 打包 .ttf 文件 字符度量信息 .bpp 文件 像素点阵数据 两个文件配套使用,缺一不可。运行时全部加载到 RAM 中。

从这张图可以看得很清楚:输入是源字体 + 配置参数,经过 FontConverter 处理,输出两个配套文件。整个流程是线性的,没有分支。所以只要参数配对了,结果就是确定的。

3.6 一些实战建议

最后,分享几个我在实际项目中总结出来的经验:

  • 版本控制:把 fontconverter 命令写进 Makefile 或 bat 脚本,跟代码一起提交。这样换电脑或换人时,能保证生成结果一致。
  • 增量更新:如果 UI 改了,只重新生成新增的字符。别每次都全量生成,浪费时间。
  • 验证工具:生成后,用 TouchGFX Designer 的字体预览功能看一眼。确认每个字符的显示效果都正常,再集成到项目中。

嗯,关于 FontConverter 的基本用法,就讲到这里。记住一句话:参数决定质量,范围决定大小。把这两个点抓住了,字体这块儿就不会出大问题。