| # 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" |
| |
| # Default name of the Fuchsia package containing the font service component. |
| _default_font_service_pkg = "fonts" |
| |
| 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 |
| # |
| # font_service_pkg |
| # Optional: Name of the Fuchsia package containing the font service |
| # component, used in `config_data` rules to provide data files to that |
| # package. |
| # Default: "fonts" |
| # Type: string |
| template("font_collection") { |
| forward_variables_from(invoker, |
| [ |
| "font_packages", |
| "local_font_bundles", |
| "local_asset_names", |
| "product_config_path", |
| "manifest_prefix", |
| "font_service_pkg", |
| ]) |
| |
| 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(font_service_pkg)) { |
| font_service_pkg = _default_font_service_pkg |
| } |
| |
| 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 = font_service_pkg |
| 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) |
| # |
| # font_service_pkg |
| # Optional: Name of the Fuchsia package containing the font service |
| # component, used in `config_data` rules to provide data files to that |
| # package. |
| # Default: "fonts" |
| # Type: string |
| template("local_font_bundle") { |
| forward_variables_from(invoker, |
| [ |
| "asset_names", |
| "font_service_pkg", |
| ]) |
| assert(defined(asset_names)) |
| |
| if (!defined(font_service_pkg)) { |
| font_service_pkg = _default_font_service_pkg |
| } |
| |
| 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 = font_service_pkg |
| 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 = [] |
| } |
| } |
| } |