字体文件子集化(Font Subsetting)是指从一个完整的字体文件中提取出仅包含特定字符集的子集,以减小字体文件的大小。这在网页设计、移动应用开发和嵌入式系统中非常有用,可以显著减少加载时间和资源占用。

1. 字体子集化的基本原理

字体子集化的核心步骤包括:

  1. 确定需要的字符集:根据文本内容提取出需要使用的字符。

  2. 从原始字体文件中提取字形数据:仅保留与目标字符相关的字形数据。

  3. 生成新的字体文件:将提取的字形数据打包成一个新的字体文件。

2. 字体文件的基本结构

字体文件通常由以下几个部分组成:

2.1. 文件头(Header)

文件头包含字体的基本信息,如字体版本、表数量、校验和等。

  • 主要字段

    • sfntVersion:字体格式标识(如 \x00\x01\x00\x00 表示 TrueType)。

    • numTables:字体中包含的表的数量。

    • searchRangeentrySelectorrangeShift:用于快速查找表的元数据。

2.2. 表目录(Table Directory)

表目录列出了字体文件中所有表的名称、偏移量和长度。

  • 每个表目录项包含

    • tag:表的名称(如 headglyf 等)。

    • checksum:表的校验和。

    • offset:表在文件中的偏移量。

    • length:表的长度。

2.3. 表数据(Tables)

字体文件的核心数据存储在多个表中。以下是一些重要的表:


3. 主要表(Tables)介绍

3.1. head 表(字体头表)
  • 作用:存储字体的全局信息。

  • 重要字段

    • unitsPerEm:每个 EM 单位的坐标数。

    • xMinyMinxMaxyMax:字体的全局边界框。

    • indexToLocFormat:字形位置数据的格式(0 表示短格式,1 表示长格式)。

3.2. hhea 表(水平头表)
  • 作用:存储水平排版的相关信息。

  • 重要字段

    • ascentdescent:字体的上升和下降值。

    • lineGap:行间距。

    • numberOfHMetrics:水平度量值的数量。

33. maxp 表(最大需求表)
  • 作用:存储字体的最大值信息。

  • 重要字段

    • numGlyphs:字体中包含的字形数量。

3.4. cmap 表(字符映射表)
  • 作用:将字符代码映射到字形索引。

  • 重要字段

    • 多个子表,支持不同的字符编码格式(如 Unicode、ASCII 等)。

3.5. glyf 表(字形数据表)
  • 作用:存储字形的轮廓数据。

  • 重要字段

    • 每个字形的轮廓数据(包括点坐标、标志等)。

    • 复合字形(Composite Glyphs)的引用信息。

3.6. loca 表(字形位置表)
  • 作用:存储每个字形在 glyf 表中的偏移量。

  • 重要字段

    • 根据 head 表中的 indexToLocFormat 字段,使用短格式或长格式存储偏移量。

3.7. hmtx 表(水平度量表)
  • 作用:存储每个字形的水平度量值。

  • 重要字段

    • advanceWidth:字形的水平步进宽度。

    • leftSideBearing:字形的左侧间距。

3.8. name 表(命名表)
  • 作用:存储字体的元数据,如字体名称、版本、作者等。

  • 重要字段

    • 多个字符串记录,支持多种语言和平台。

4 子集化步骤

        在 TTF 字体文件中,数据量较大的表主要包括 locaglyfhmtx。对这些表进行紧凑化处理,可以显著减小字体文件的大小。

        例如,一个包含 1 万个字符的字体文件,其 loca 表需要存储 1 万个字符的字形轮廓地址。如果对该字体进行子集化,仅保留 10 个字符,那么 loca 表就只需存储这 10 个字符的轮廓地址,文件大小会按比例大幅缩减。

   glyf 表用于存储每个字符的轮廓数据,通常占用较大空间。在子集化过程中,只需保留所需字符的轮廓数据即可。

        从原理上讲,子集化字体文件并不复杂。然而,字体文件中的各个表之间存在紧密的关联。一旦处理不当,很容易导致字体文件失效。因此,自行编写一个字体子集化程序难度较大。

        由于工作需要,我必须处理字体子集化问题,但未能找到合适的开源代码。于是,我查阅了大量资料,参考了多种源码,最终自己编写了一个字体子集化程序。该程序具有以下优势:

  1. 纯 C# 开发:完全使用 C# 编写,不依赖任何第三方库,支持跨平台运行。

  2. 性能优化:在子集化过程中,采用了多种优化策略,每秒可处理数千次字体子集化操作。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐