实现自定义字体

在 Android 11 及更低版本中,更新 AOSP(在/system/fonts分区中)或供应商分区(在/product/fonts/system/fonts分区中)中设备安装的字体文件需要 OEM 进行系统更新。此要求对表情符号兼容性有重大影响。在 Android 12 中,您可以使用FontManager系统服务来管理已安装的字体文件并更新设备安装的字体文件,而无需进行系统更新。

Android 12 具有三种进程交互功能; FontManagerServiceFont UpdaterApplication

FontManagerService是系统服务器中的中央管理系统。 FontManagerService存储最新的每用户系统字体设置。

FontUpdater是一个可插入字体更新程序,由signature|privileged权限检查信任。 FontUpdaterFontManagerService通信以获取、安装、删除或更新当前系统字体设置。 FontUpdater可以通过进程间通信 (IPC) 机制传递新的字体文件内容。 FontManagerService将内容保存到世界可读的存储位置,例如/data/fonts文件中。该存储受到保护。根据 SELinux 策略,它只能FontManagerService编写。

Application类启动时,它会将系统字体设置作为bindApplication方法的参数传递;然后它初始化应用程序进程使用的字体设置。

自定义字体

一些 OEM 在 AOSP 中安装或替换字体文件以显示其品牌。 Android 12 支持此功能,但增加了在设备中保持表情符号字体更新的要求。不修改或更新表情符号字体文件的 OEM 不需要使用此功能。

Google 通过 GMS Core 更新字体文件,尤其是NotoColorEmoji文件,因此请勿从/system分区修改或删除NotoColorEmoji.ttf文件,也不要从/system/etc/fonts.xml中删除它。请注意以下三种自定义字体的方法:

  1. NotoColorEmoji.ttf文件替换为 OEM 品牌的表情符号字体。
  2. 根据您当地市场的需求修改NotoColorEmoji.ttf文件。
  3. 替换或修改其他字体文件。

如果您不在 AOSP 中修改表情符号字体,则无需采取任何操作。如果您想自定义表情符号字体,请使用以下部分中的说明。

将 NotoColorEmoji.ttf 替换为 OEM 品牌的表情符号字体

要将NotoColorEmoji.ttf文件替换为 OEM 品牌的表情符号字体文件,请将表情符号字体放在字体后备链之前:

  1. 将您自己的字体(名为OEMCustomEmoji.ttf )放置在/system分区中。
  2. 修改/system/etc/fonts.xml ,如下代码:

    <family lang="ko">
    <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
    </family>
    <!-- ADD FOLLOWING LINE -->
    <family lang="und-Zsye">
       <font weight="400" style="normal">OEMCustomEmoji.ttf</font>
    </family>
    <!-- END OF MODIFICATION -->
    <family lang="und-Zsye">
       <font weight="400" style="normal">NotoColorEmoji.ttf</font>
    </family>
    <family lang="und-Zsym">
       <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted2.ttf</font>
    </family>
    

修改NotoColorEmoji.ttf以满足本地市场需求

请按照以下步骤进行定制,以满足您当地市场的需求:

  1. 使用不同的名称创建您自己的NotoColorEmoji文件;例如,将其命名Modified\_NotoColorEmoji.ttf
  2. 将其放在原始NotoColorEmoji.ttf文件之前。

执行步骤 2 后,将显示Modified\NotoColorEmoji.ttf支持的修改字形,而不是原始NotoColorEmoji.ttf 。谷歌建议如下:

  • 此字体中仅具有必要的字形。
  • 将未修改的字形委托给原始NotoColorEmoji.ttf文件,以便您的设备接收未来表情符号版本中所做的任何设计修复。

删除字形:要从NotoColorEmoji.ttf文件中删除字形,请按照步骤 1 和 2 操作,并在 cmap 中指定glyph ID = 0

使用区域标志:如果目标字形是区域标志,请将字形 ID 指定为未知国家/地区代码。 (使用country code = "ZZ" 。)

制作豆腐字形:如果您想使用豆腐字形,可以显式指定豆腐字形 ID。当您指定glyphID = 0时,相关应用程序会将其解释为“字形不可用”。例如,当您使用此属性时, Paint#hasGlyph应用程序将返回false

替换或修改其他字体文件

替换或修改其他字体的定制方式与针对本地市场需求修改TTF文件的定制方式类似。运行时在 AOSP 中更新的未知字体文件将被忽略,并且不会更新。 Google 会忽略您设备中的未知字体。这包括从 AOSP 中的原始字体修改而来的字体文件。

虽然字体更新是由 Google 在 GMS Core 中完成的,但通用的字体更新机制是向所有 OEM 开放的。 OEM 可以使用满足先决条件签署字体文件进行运行时字体更新中的步骤安装其他字体更新程序。

满足先决条件

字体更新机制使用fs-verity Linux 内核功能。验证您的设备是否符合fs-verity并将证书包含在您的设备中。

签名字体文件

由于字体文件是有风险的资源,因此必须使用可信密钥对其进行验证。仔细检查所有要更新的字体文件,并使用您的私钥进行签名。签名必须与fs-verity兼容。

进行运行时字体更新

FontManger系统应用程序执行字体更新。 FontManager应用程序提供最新安装的系统字体状态以及使用签名更新字体文件的功能。要调用更新应用程序,请将UPDATE_FONT signature|privileged权限添加到您的应用程序白名单清单中

向您的应用程序的更新程序功能提供UPDATE_FONT signature|privileged权限。