blob: 1a55bc0e05801cd5c4533fe9759005309b487b9e [file] [log] [blame]
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config.gni")
import("//src/fonts/build/font_args.gni")
import("//src/fonts/build/font_manifest.gni")
################################################################################
# Merge the contents of all the .font_pkgs.json files
################################################################################
font_pkg_entries = []
all_font_file_paths = []
# Default prefix for the manifest file name in /config/data.
_default_manifest_prefix = "all"
foreach(font_pkgs_path, font_pkgs_paths) {
parsed = {
}
parsed = read_file(font_pkgs_path, "json")
foreach(entry, parsed.packages) {
# GN doesn't support real set operations and removing an item that's not
# already in the list is an error, so to deduplicate, we add one instance,
# remove all instances, and then add again.
font_pkg_entries += [ entry ]
font_pkg_entries -= [ entry ]
font_pkg_entries += [ entry ]
path_prefix = entry.path_prefix
if (path_prefix != "") {
path_prefix = "${path_prefix}/"
}
all_font_file_paths += [ "${fonts_dir}/${path_prefix}${entry.file_name}" ]
}
}
# Generate all of the `config_data` targets needed for a target product's font
# collection.
#
# This can be a combination of font `package`s and local font bundles.
#
# Parameters
#
# font_packages
# Optional: GN labels of font `package`s and/or `font_package_group`s that
# are in `universe_package_labels` for the target product.
# Type: list(label)
#
# local_font_bundles
# Optional: GN labels of `local_font_bundle`s (or `group`s thereof) for the
# target product. These will be included in the font server's
# "/config/data".
# Type: list(label)
#
# local_asset_names
# Optional: List of local font file names. These will be included in the
# font server's "/config/data". If `local_font_bundles` is defined,
# `local_asset_names` will simply be added on as another bundle.
# Type: list(file)
#
# product_config_path:
# Optional: Path to a JSON file containing product-specific font
# configuration, including a fallback chain.
# Type: file
#
# manifest_prefix
# Optional: Prefix for the generated manifest file name.
# Default: "all"
# Type: string
#
# empty
# Optional: If set to true, indicates that this collection is intentionally
# empty.
# Type: boolean
#
# testonly
# Optional: If set to true, config_data will *not* be generated for
# pkg_resolver, which doesn't support loading arbitrary font package
# registry files.
# Type: boolean
template("font_collection") {
forward_variables_from(invoker,
[
"font_packages",
"local_font_bundles",
"local_asset_names",
"product_config_path",
"manifest_prefix",
])
if (!defined(font_packages)) {
font_packages = []
}
if (!defined(local_font_bundles)) {
local_font_bundles = []
}
if (!defined(manifest_prefix)) {
manifest_prefix = _default_manifest_prefix
}
if (!defined(invoker.empty)) {
invoker.empty = false
}
if (!defined(invoker.testonly)) {
invoker.testonly = false
}
assert(
!(invoker.testonly && manifest_prefix == _default_manifest_prefix),
"Can't use default manifest_prefix '${manifest_prefix}' with a testonly font_collection.")
# The font resolver in pkg_resolver expects a hard-coded location in
# /config/data for the file font_packages.json. To avoid collisions from
# multiple definitions of that file, we don't add it to config_data when
# building tests.
generate_pkg_resolver_config_data = !invoker.testonly
if (defined(local_asset_names)) {
bundle_name = "_${target_name}_local_font_bundle"
local_font_bundle(bundle_name) {
asset_names = local_asset_names
}
local_font_bundles += [ ":${bundle_name}" ]
}
# `fx format-code` insists on removing clarifying parentheses here.
assert(font_packages + local_font_bundles == [] == invoker.empty,
"An empty font_collection must explicitly declare `empty = true`")
##############################################################################
# Generate font_packages.json, used by pkg-resolver to know which Fuchsia
# packages are font packages.
##############################################################################
pkg_resolver_registry_path =
"${target_gen_dir}/${target_name}_font_packages.json"
pkg_resolver_registry_label = "${target_name}_font_packages.json"
pkg_resolver_config_data_label =
"${target_name}_pkg_resolver_font_packages_config_data"
_group_visibility = ":${target_name}"
generated_file(pkg_resolver_registry_label) {
forward_variables_from(invoker, [ "testonly" ])
deps = font_packages
if (generate_pkg_resolver_config_data) {
visibility = [ ":${pkg_resolver_config_data_label}" ]
not_needed([ "_group_visibility" ])
} else {
visibility = [ _group_visibility ]
not_needed([ "pkg_resolver_config_data_label" ])
}
data_keys = [ "fuchsia_package_urls" ]
walk_keys = [ "font_barrier" ]
output_conversion = "json"
outputs = [ pkg_resolver_registry_path ]
}
if (generate_pkg_resolver_config_data) {
config_data(pkg_resolver_config_data_label) {
for_pkg = "pkg-resolver"
# This output name is fixed.
# There can be only one instance of this target included in any product.
outputs = [ "font_packages.json" ]
sources = [ pkg_resolver_registry_path ]
}
}
##############################################################################
# Generate all_fonts.json, used by the manifest generator to know the
# list of font files available in the product.
##############################################################################
_all_fonts_json_path = "${target_gen_dir}/${target_name}_all_fonts.json"
_all_fonts_json_label = "${target_name}_all_fonts.json"
generated_file(_all_fonts_json_label) {
forward_variables_from(invoker, [ "testonly" ])
deps = font_packages
data_keys = [ "font_file_names" ]
walk_keys = [ "font_barrier" ]
output_conversion = "json"
outputs = [ _all_fonts_json_path ]
}
##############################################################################
# Generate local_fonts.json, used by the manifest generator to know which font
# files are available in the font server's /config/data directory.
##############################################################################
_local_fonts_json_path = "${target_gen_dir}/${target_name}_local_fonts.json"
_local_fonts_json_label = "${target_name}_local_fonts.json"
generated_file(_local_fonts_json_label) {
forward_variables_from(invoker, [ "testonly" ])
deps = local_font_bundles
data_keys = [ "local_font_file_names" ]
walk_keys = [ "font_barrier" ]
output_conversion = "json"
outputs = [ _local_fonts_json_path ]
}
##############################################################################
# Generate the .font_manifest.json file and config_data target
##############################################################################
manifest_file_label = "${target_name}_manifest_file"
manifest_file_path = "${target_out_dir}/${target_name}_all.font_manifest.json"
font_manifest(manifest_file_label) {
forward_variables_from(invoker, [ "testonly" ])
all_fonts_path = _all_fonts_json_path
local_fonts_path = _local_fonts_json_path
font_files = all_font_file_paths
deps = [
":${_all_fonts_json_label}",
":${_local_fonts_json_label}",
]
output = manifest_file_path
pretty_print = is_debug
}
# Will appear at "/config/data/${manifest_prefix}.font_manifest.json"
font_manifest_config_data_label = "${target_name}_font_manifest_config_data"
config_data(font_manifest_config_data_label) {
forward_variables_from(invoker, [ "testonly" ])
for_pkg = "fonts"
deps = [ ":${manifest_file_label}" ]
sources = get_target_outputs(":${manifest_file_label}")
outputs = [ "${manifest_prefix}.font_manifest.json" ]
}
group(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
deps = local_font_bundles + [ ":${font_manifest_config_data_label}" ]
if (generate_pkg_resolver_config_data) {
deps += [ ":${pkg_resolver_config_data_label}" ]
} else {
deps += [ ":${pkg_resolver_registry_label}" ]
}
}
}
# Define a `group` consisting of the font `package`s for each of the given
# `asset_names`.
#
# Parameters
#
# asset_names
# Required: List of font file names, e.g. ["Roboto-Regular.ttf"], to be
# included in this group.
# Type: list(file)
#
template("font_package_group") {
forward_variables_from(invoker, [ "asset_names" ])
assert(defined(asset_names))
font_package_labels = []
not_found_asset_names = []
foreach(asset_name, asset_names) {
found = false
foreach(entry, font_pkg_entries) {
if (asset_name == entry.file_name) {
found = true
font_package_labels +=
[ "//src/fonts/packages:font-package-${entry.safe_name}" ]
}
}
if (!found) {
not_found_asset_names += [ asset_name ]
}
}
assert(not_found_asset_names == [],
"font_pkg_entries not found for ${not_found_asset_names}")
group(target_name) {
forward_variables_from(invoker,
[
"visibility",
"testonly",
])
deps = font_package_labels
}
}
# Define a `config_data` target to bundle all of the given font files into the
# font server's "/config/data".
#
# Parameters
#
# asset_names
# Required: List of font file names, e.g. [ "Roboto-Regular.ttf" ]
# Type: list(file)
template("local_font_bundle") {
forward_variables_from(invoker, [ "asset_names" ])
assert(defined(asset_names))
local_asset_paths = []
not_found_asset_names = []
foreach(asset_name, asset_names) {
found = false
foreach(entry, font_pkg_entries) {
if (asset_name == entry.file_name) {
found = true
asset_path = entry.path_prefix
if (asset_path != "") {
asset_path = "${asset_path}/"
}
asset_path = "${fonts_dir}/${asset_path}${entry.file_name}"
local_asset_paths += [ asset_path ]
}
}
if (!found) {
not_found_asset_names += [ asset_name ]
}
}
assert(not_found_asset_names == [],
"font_pkg_entries not found for ${not_found_asset_names}")
config_data_label = "_${target_name}_config_data"
config_data(config_data_label) {
forward_variables_from(invoker, [ "testonly" ])
for_pkg = "fonts"
sources = local_asset_paths
outputs = [ "assets/{{source_file_part}}" ]
}
group(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
deps = [ ":${config_data_label}" ]
metadata = {
local_font_file_names = asset_names
font_barrier = []
}
}
}