字体的 build 配置有三个基本层:
背景
将一系列字体添加到 Fuchsia build 的设置 非常困难。这是因为
- Fuchsia 的开发者指南倾向于将预构建的二进制文件保留在 CIPD 中, 不在 Git 代码库中
 - Fuchsia 的字体文件来自各种来源。
 - 在运行的 Fuchsia 系统上,仅仅为客户提供
目录中包含 
.ttf个文件。 - 字体元数据冗长、经常重复,并且容易维护。它 最好为每个常用字体仅定义一次此元数据 而非询问产品定位和 单独的组件来管理自己的副本。
 
通用基础架构和元数据
第一层为资产和元数据建立目录, 可用于 Fuchsia 产品 build。
字体数据存储区
字体文件的元数据和外部源列表保存在
字体数据代码库。对于 Fuchsia 的开源字体,您可以在以下位置找到该字体:
//fontdata。
每当字体数据代码库的内容发生变化时,Furchsia 的 自动化基础架构会自动对其进行检查, 代码库描述的字体文件,并将它们捆绑到 CIPD 软件包中 并上传到 Fuchsia 的 CIPD 服务器。
字体数据存储区包含以下文件:
manifest.xml
这是一个 Jiri 清单文件。 在本示例中,它由 Git 代码库和修订版本 ID 列表组成,其中包含 所需的字体文件
每个导入的代码库都列在 <project> 元素中。
示例条目:
<project
    name="github.com/googlefonts/noto-cjk"
    path="github.com/googlefonts/noto-cjk"
    remote="https://fuchsia.googlesource.com/third_party/github.com/googlefonts/noto-cjk"
    remotebranch="upstream/master"
    revision="be6c059ac1587e556e2412b27f5155c8eb3ddbe6"/>
name:任意名称(不会影响任何内容)path:确定代码库相对于根的检出位置 checkout 目录。remote:远程代码库的 Git 网址remotebranch:远程代码库中的分支名称revision:用于固定检出的 Git 提交哈希值
contents.json
这些是供 Fuchsia 的基础架构从
checkout 目录进入暂存目录 (staging directory)。{destination,
files} 的每个条目都定义了暂存目录中的顶级文件夹,并且
文件。
示例条目:
{
    "destination": "material",
    "files": [
      "github.com/google/material-design-icons/iconfont/MaterialIcons-Regular.ttf",
      "github.com/google/material-design-icons/LICENSE"
    ]
}
${catalog_name}.font_catalog.json
字体目录文件是人工编写的,包含所有字体的元数据, 系列、资源和字体。
为便于修改,我们提供了 .font_catalog.json 文件的 JSON 架构
在
/src/fonts/tools/schemas/font_catalog.schema.json.
规范架构为
在 Rust 中定义。
packing_script.py
Fuchsia 的基础架构会在填充预演条件后调用此脚本 目录。
脚本:
- 将暂存目录中的所有字体和许可文件复制到输出中 目录。
 - 在以下文件中生成 
${catalog_name}.font_pkgs.json文件: 输出目录中。 
此脚本通常不需要修改。
基础架构配方
如上所述,无论何时,只要
fontdata 的修改。这个食谱:
- 使用 
jiri init和jiri update检出引用的代码库。 - 根据 
contents.json暂存已签出的文件。 - 调用打包脚本以将文件写入输出 目录。
 - 将输出目录的内容上传到 CIPD。
 
CIPD 软件包
系统会将开放源代码字体包上传到
fuchsia/third_party/fonts CIPD 软件包。
Jiri 预构建
CIPD 软件包的内容通过
prebuilts jiri 清单:
    <!--   Fonts -->
    <package name="fuchsia/third_party/fonts"
             version="git_revision:a10ce51e308f48c5e6d70ab5777434af46a5ddb8"
             path="prebuilt/third_party/fonts"/>
可以获取 fuchsia/third_party/fonts 软件包的 version ID
通过“代码”菜单集群上的最新实例
“CIPD 软件包”页面。

全局 GN 参数
//src/fonts/build/font_args.gni 进行声明
几个与字体相关的构建参数。其中最重要的两个选项是
font_catalog_paths:所有选定项目的位置.font_catalog.json文件。font_pkgs_paths:所有.font_pkgs.json的位置 文件。
*.font_pkgs.json 个文件
按照设计,这些文件可以通过 GN 的简单 JSON 解析器解析,
read_file。
它们包含以下形式的条目列表:
    {
      "file_name": "AlphaSans-Regular.ttf",
      "safe_name": "alphasans-regular-ttf",
      "path_prefix": "alpha"
    },
file_name:字体文件资源文件的名称。这是规范的 的标识符,从而获取此对照表中的键。safe_name:文件名的转换版本:转换为小写形式。 并将所有特殊字符替换为连字符。它可用于命名 Fuchsia 软件包。path_prefix:素材资源父级目录的位置(相对于该目录)//prebuilt/third_party/fonts。
在 //src/fonts/build/fonts.gni 中,
.font_pkgs.json 文件合并为单个 GN 作用域,
用作对照表
字体包
除了直接向字体提供程序的命名空间提供字体资源之外,
还可以选择创建单字体的 Fuchsia 软件包。这是
顾名思义,就是一个 package,它只包含一种字体,
仅 resources,不执行任何其他操作。
这可用于结合临时字体传递
fuchsia.pkg.FontResolver。(待办事项:链接到更多文档。)
所有可能的字体包都已在
//src/fonts/packages/BUILD.gn。
- 每个软件包名称均采用 
font-package-<font-safe-name>格式(请参阅safe_name),例如font-package-roboto-regular-ttf。 - 因此,软件包的 GN 目标为
//src/fonts/packages:<package-name>,例如//src/fonts/packages:font-package-roboto-regular.ttf。 - 每个包的网址都采用以下格式
fuchsia-pkg://fuchsia.com/<package-name>,例如fuchsia-pkg://fuchsia.com/font-package-roboto-regular-ttf。 
local_font_bundle
在 fonts.gni 中定义
本地字体包是一组直接放置在
使用
config_data()。
大多数本地字体包都是在
//src/fonts/collections/BUILD.gn。
示例:
local_font_bundle("small-open-fonts-local") {
  asset_names = [
    "MaterialIcons-Regular.ttf",
    "Roboto-Regular.ttf",
    "Roboto-Light.ttf",
    "Roboto-Medium.ttf",
    "RobotoMono-Regular.ttf",
    "RobotoSlab-Regular.ttf",
  ]
}
产品特定的字体配置
最后,每个 主推产品组 需要配置特定的字体资源, 元数据。
字体产品配置文件
.fontcfg.json(或 .fontcfg.json5)文件包含一组人工编写的
产品特定的字体设置。这里有
JSON 架构适用于
更好的编辑器体验
目前,此文件的主要用途是定义一种 链,即在与 客户端的字体请求不可用。
以下是一个后备广告链的基本示例,
//src/fonts/collections/open-fonts-collection.fontcfg.json5:
fallback_chain: [
        ///
        ///
        /// SANS SERIF LATIN
        "Roboto-Regular.ttf",
        "Roboto-Black.ttf",
        "Roboto-BlackItalic.ttf",
        "Roboto-Bold.ttf",
        "Roboto-BoldItalic.ttf",
        "Roboto-Italic.ttf",
        "Roboto-Light.ttf",
        "Roboto-LightItalic.ttf",
        "Roboto-Medium.ttf",
        "Roboto-MediumItalic.ttf",
        "Roboto-Thin.ttf",
        "Roboto-ThinItalic.ttf",
        "RobotoCondensed-Regular.ttf",
        "RobotoCondensed-Bold.ttf",
        "RobotoCondensed-BoldItalic.ttf",
        "RobotoCondensed-Italic.ttf",
        "RobotoCondensed-Light.ttf",
        "RobotoCondensed-LightItalic.ttf",
        "DroidSans-Regular.ttf",
        "DroidSans-Bold.ttf",
        ///
        ///
        /// SANS-SERIF NON-LATIN
        "NotoNaskhArabicUI-Regular.ttf",
        "NotoSansArmenian-Regular.ttf",
        "NotoSansEthiopic-Regular.ttf",
        "NotoSansGeorgian-Regular.ttf",
        "NotoSansHebrew-Regular.ttf",
        "NotoSansThaiUI-Regular.ttf",
        // All Indian scripts should come after Devanagari, due to shared danda characters.
        "NotoSansDevanagariUI-Regular.ttf",
        "NotoSansBengaliUI-Regular.ttf",
        "NotoSansGujaratiUI-Regular.ttf",
        "NotoSansKannada-Regular.ttf",
        "NotoSansMalayalamUI-Regular.ttf",
        "NotoSansTamilUI-Regular.ttf",
        "NotoSansTelugu-Regular.ttf",
        ///
        ///
        /// SANS SERIF CJK
        {
            full_name: "Noto Sans CJK SC",
        },
        {
            full_name: "Noto Sans CJK TC",
        },
        {
            full_name: "Noto Sans CJK HK",
        },
        {
            full_name: "Noto Sans CJK KR",
        },
        {
            full_name: "Noto Sans CJK JP",
        },
        {
            full_name: "Noto Sans CJK SC Bold",
        },
        {
            full_name: "Noto Sans CJK TC Bold",
        },
        {
            full_name: "Noto Sans CJK HK Bold",
        },
        {
            full_name: "Noto Sans CJK KR Bold",
        },
        {
            full_name: "Noto Sans CJK JP Bold",
        },
        {
            full_name: "Noto Sans CJK SC Black",
        },
        {
            full_name: "Noto Sans CJK TC Black",
        },
        {
            full_name: "Noto Sans CJK HK Black",
        },
        {
            full_name: "Noto Sans CJK KR Black",
        },
        {
            full_name: "Noto Sans CJK JP Black",
        },
        {
            full_name: "Noto Sans CJK SC DemiLight",
        },
        {
            full_name: "Noto Sans CJK TC DemiLight",
        },
        {
            full_name: "Noto Sans CJK HK DemiLight",
        },
        {
            full_name: "Noto Sans CJK KR DemiLight",
        },
        {
            full_name: "Noto Sans CJK JP DemiLight",
        },
        {
            full_name: "Noto Sans CJK SC Light",
        },
        {
            full_name: "Noto Sans CJK TC Light",
        },
        {
            full_name: "Noto Sans CJK HK Light",
        },
        {
            full_name: "Noto Sans CJK KR Light",
        },
        {
            full_name: "Noto Sans CJK JP Light",
        },
        {
            full_name: "Noto Sans CJK SC Medium",
        },
        {
            full_name: "Noto Sans CJK TC Medium",
        },
        {
            full_name: "Noto Sans CJK HK Medium",
        },
        {
            full_name: "Noto Sans CJK KR Medium",
        },
        {
            full_name: "Noto Sans CJK JP Medium",
        },
        {
            full_name: "Noto Sans CJK SC Thin",
        },
        {
            full_name: "Noto Sans CJK TC Thin",
        },
        {
            full_name: "Noto Sans CJK HK Thin",
        },
        {
            full_name: "Noto Sans CJK KR Thin",
        },
        {
            full_name: "Noto Sans CJK JP Thin",
        },
        ///
        ///
        /// SERIF LATIN
        "RobotoSlab-Regular.ttf",
        "RobotoSlab-Bold.ttf",
        "RobotoSlab-Light.ttf",
        "RobotoSlab-Thin.ttf",
        "DroidSerif-Regular.ttf",
        "DroidSerif-Bold.ttf",
        "DroidSerif-BoldItalic.ttf",
        "DroidSerif-Italic.ttf",
        ///
        ///
        /// SERIF CJK
        {
            full_name: "Noto Serif CJK SC",
        },
        {
            full_name: "Noto Serif CJK TC",
        },
        {
            full_name: "Noto Serif CJK KR",
        },
        {
            full_name: "Noto Serif CJK JP",
        },
        {
            full_name: "Noto Serif CJK SC Bold",
        },
        {
            full_name: "Noto Serif CJK TC Bold",
        },
        {
            full_name: "Noto Serif CJK KR Bold",
        },
        {
            full_name: "Noto Serif CJK JP Bold",
        },
        {
            full_name: "Noto Serif CJK SC Black",
        },
        {
            full_name: "Noto Serif CJK TC Black",
        },
        {
            full_name: "Noto Serif CJK KR Black",
        },
        {
            full_name: "Noto Serif CJK JP Black",
        },
        {
            full_name: "Noto Serif CJK SC ExtraLight",
        },
        {
            full_name: "Noto Serif CJK TC ExtraLight",
        },
        {
            full_name: "Noto Serif CJK KR ExtraLight",
        },
        {
            full_name: "Noto Serif CJK JP ExtraLight",
        },
        {
            full_name: "Noto Serif CJK SC Light",
        },
        {
            full_name: "Noto Serif CJK TC Light",
        },
        {
            full_name: "Noto Serif CJK KR Light",
        },
        {
            full_name: "Noto Serif CJK JP Light",
        },
        {
            full_name: "Noto Serif CJK SC Medium",
        },
        {
            full_name: "Noto Serif CJK TC Medium",
        },
        {
            full_name: "Noto Serif CJK KR Medium",
        },
        {
            full_name: "Noto Serif CJK JP Medium",
        },
        {
            full_name: "Noto Serif CJK SC SemiBold",
        },
        {
            full_name: "Noto Serif CJK TC SemiBold",
        },
        {
            full_name: "Noto Serif CJK KR SemiBold",
        },
        {
            full_name: "Noto Serif CJK JP SemiBold",
        },
        ///
        ///
        /// MONOSPACE LATIN
        "RobotoMono-Bold.ttf",
        "RobotoMono-BoldItalic.ttf",
        "RobotoMono-Italic.ttf",
        "RobotoMono-Light.ttf",
        "RobotoMono-LightItalic.ttf",
        "RobotoMono-Regular.ttf",
        "RobotoMono-Medium.ttf",
        "RobotoMono-MediumItalic.ttf",
        "RobotoMono-Thin.ttf",
        "RobotoMono-ThinItalic.ttf",
        "DroidSansMono-Regular.ttf",
        ///
        ///
        /// MONOSPACE CJK
        {
            full_name: "Noto Sans Mono CJK SC",
        },
        {
            full_name: "Noto Sans Mono CJK TC",
        },
        {
            full_name: "Noto Sans Mono CJK HK",
        },
        {
            full_name: "Noto Sans Mono CJK KR",
        },
        {
            full_name: "Noto Sans Mono CJK JP",
        },
        {
            full_name: "Noto Sans Mono CJK SC Bold",
        },
        {
            full_name: "Noto Sans Mono CJK TC Bold",
        },
        {
            full_name: "Noto Sans Mono CJK HK Bold",
        },
        {
            full_name: "Noto Sans Mono CJK KR Bold",
        },
        {
            full_name: "Noto Sans Mono CJK JP Bold",
        },
        ///
        ///
        /// CURSIVE LATIN
        "Quintessential-Regular.ttf",
        ///
        ///
        /// EMOJI
        "NotoColorEmoji.ttf",
        ///
        ///
        /// SYMBOLS
        "NotoSansSymbols-Regular.ttf",
        "NotoSansSymbols2-Regular.ttf",
    ]
如果资源文件包含多个字型,则同一种字型 使用 JSON 对象(而不仅仅是文件名)进行引用:
fallback_chain: [
    "SomeCompleteFont-Bold.ttf",
    { file_name: "NotoSansCJK-Regular.ttc", index: 1},
]
后备链是由手动定义的。请遵循以下准则:
- 为每种受支持的脚本添加至少一种字体。(支持的 脚本因产品而异)。
 - 尽量至少覆盖 
sans-serif、serif和monospace字体 。 - 当覆盖范围重叠时,将更具体的素材资源放在 列表。例如,所有 Noto Sans 脚本专用字体都有字形 ,但应首先显示 Noto Sans Latin 变体。
 - 当有重叠的覆盖区域时,将较小的字体文件放在 列表。这可以减少加载后备字体时的界面卡顿。
 
font_collection
在 fonts.gni 中定义
在完成任何所需的 local_font_bundle 和/或字体 packages 之后
它们会汇编到 font_collection 中。
输入
(如需查看完整文档,请参阅 fonts.gni。)
font_packages:字体为package的 GN 标签 位于目标商品的universe_package_labels中。local_font_bundles:目标的local_font_bundle的 GN 标签 产品。这些内容将包含在字体提供程序的配置数据中。local_asset_names:本地字体素材资源名称列表(用于创建临时local_font_bundle)。product_config_path:包含以下内容的 JSON 文件的路径 产品专用的字体配置,包括后备字体 。manifest_prefix:生成的字体清单文件名称的前缀。 默认设置为"all"。
内部原理
font_collection 会遍历所有字体资源和传递闭包,
其中包含的所有软件包它会收集其 GN
元数据
构建映射到本地文件中字体包的字体列表。
模板会将此信息传递给字体清单生成器 (GN 模板、 Rust 源代码)以及 字体目录和所有字体资产。
清单生成器从字体目录中选择预定义的元数据
。font_collection它还读了
从每个包含的字体文件中提取
码位(字符集)。
所有这些数据都会汇聚到一个 .font_manifest.json 文件中,
使用 config_data 规则提供给字体提供程序服务。
输出
font_collection 会生成以下工件:
<manifest-prefix>.font_manifest.json:这是元数据的集合 。它通过使用config_data规则。font_packages.json。此文件列出了包含的所有单字体 Fuchsia 软件包,并使用config_data规则提供给pkg-resolver。这个 用于确定通过fuchsia.pkg.FontResolver公开的字体包。
由 font_collection 创建的 GN 目标包含config_data
上述两个 JSON 文件,以及本地字体资源的 config_data 目标。
如果商品仅使用本地字体,则添加本地字体就足够了。
font_collection 定位到产品的依赖项标签(通常
base_package_labels)。
如果产品还使用字体 package,则必须明确添加这些目标
更改为
base_package_labels 或
universe_package_labels,
具体取决于软件包是否为临时资源