Files
cromite/build/patches/Android-fonts-fingerprinting-mitigation.patch
2026-05-19 10:48:25 +02:00

3334 lines
131 KiB
Diff

From: uazo <uazo@users.noreply.github.com>
Date: Sat, 15 Feb 2025 16:25:31 +0000
Subject: Android fonts fingerprinting mitigation
Replaces system fonts with a predefined set downloaded from www.cromite.org
License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
---
.../common/ProductionSupportedFlagList.java | 3 +
.../component_updater/registration.cc | 9 +
build/config/freetype/freetype.gni | 2 +-
.../java/res/xml/developer_preferences.xml | 5 +
chrome/browser/BUILD.gn | 7 +
.../browser/component_updater/registration.cc | 10 +
...droid-fonts-fingerprinting-mitigation.grdp | 9 +
chrome/browser/ui/prefs/prefs_tab_helper.cc | 9 +-
chrome/renderer/BUILD.gn | 4 +
.../installer_policies/BUILD.gn | 7 +
.../fonts_pack_component_installer.cc | 96 +
.../fonts_pack_component_installer.h | 60 +
components/services/font/BUILD.gn | 10 +
components/services/font/font_service_app.cc | 46 +
components/services/font/font_service_app.h | 1 +
.../services/font/public/cpp/font_loader.cc | 11 +
.../services/font/public/cpp/font_loader.h | 1 +
.../font/public/cpp/font_service_thread.cc | 48 +
.../font/public/cpp/font_service_thread.h | 5 +
.../font/public/mojom/font_service.mojom | 2 +
content/browser/BUILD.gn | 18 +
...der_process_host_impl_receiver_bindings.cc | 12 +
content/child/BUILD.gn | 7 +
content/renderer/BUILD.gn | 4 +
.../renderer/renderer_blink_platform_impl.cc | 55 +-
content/renderer/renderer_main.cc | 2 -
...ndroid-fonts-fingerprinting-mitigation.inc | 12 +
...ndroid-fonts-fingerprinting-mitigation.inc | 7 +
...ndroid-fonts-fingerprinting-mitigation.inc | 5 +
skia/BUILD.gn | 12 +
skia/ext/font_utils.cc | 1 +
.../freetype/config/ftoption.h | 2 +-
.../include/ports/SkFontConfigInterface.h | 2 +
.../skia/include/ports/SkFontMgr_android.h | 42 +-
.../skia/src/ports/SkFontConfigInterface.cpp | 5 +
.../ports/SkFontConfigInterface_direct.cpp | 5 +
.../src/ports/SkFontConfigInterface_direct.h | 1 +
.../skia/src/ports/SkFontMgr_android.cpp | 286 ++-
.../skia/src/ports/SkFontMgr_android_data.cpp | 1641 +++++++++++++++++
.../skia/src/ports/SkFontMgr_android_ndk.cpp | 2 +-
.../src/ports/SkFontMgr_android_parser.cpp | 69 +-
.../skia/src/ports/SkFontMgr_android_parser.h | 5 +-
42 files changed, 2451 insertions(+), 89 deletions(-)
create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp
create mode 100644 components/component_updater/installer_policies/fonts_pack_component_installer.cc
create mode 100644 components/component_updater/installer_policies/fonts_pack_component_installer.h
create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc
create mode 100644 cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc
create mode 100644 cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc
create mode 100644 third_party/skia/src/ports/SkFontMgr_android_data.cpp
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -998,6 +998,9 @@ public final class ProductionSupportedFlagList {
"Hides user preference on the system keyboard by setting the standard "
+ "eng layout and removing the layout information from the "
+ "javascript keyboard events."),
+ Flag.baseFeature(
+ "AndroidFontsFingerprintingMitigation",
+ "Android fonts fingerprinting mitigation: replaces all system fonts with the same for all devices.."),
Flag.baseFeature(
BlinkFeatures.ASYNC_SET_COOKIE,
"When enabled, the communication between renderer and network service is "
diff --git a/android_webview/nonembedded/component_updater/registration.cc b/android_webview/nonembedded/component_updater/registration.cc
--- a/android_webview/nonembedded/component_updater/registration.cc
+++ b/android_webview/nonembedded/component_updater/registration.cc
@@ -20,6 +20,9 @@
#include "components/component_updater/installer_policies/origin_trials_component_installer.h"
#include "components/update_client/update_client.h"
+#include "third_party/blink/public/common/features.h"
+#include "components/component_updater/installer_policies/fonts_pack_component_installer.h"
+
namespace android_webview {
void RegisterComponentsForUpdate(
@@ -36,6 +39,12 @@ void RegisterComponentsForUpdate(
std::vector<std::unique_ptr<component_updater::ComponentInstallerPolicy>>
component_installer_list_cromite;
+ if (base::FeatureList::IsEnabled(blink::features::kAndroidFontsFingerprintingMitigation)) {
+ component_installer_list_cromite.push_back(
+ std::make_unique<
+ component_updater::FontsPackComponentInstallerPolicy>());
+ }
+
component_installer_list.push_back(
std::make_unique<
component_updater::OriginTrialsComponentInstallerPolicy>());
diff --git a/build/config/freetype/freetype.gni b/build/config/freetype/freetype.gni
--- a/build/config/freetype/freetype.gni
+++ b/build/config/freetype/freetype.gni
@@ -24,5 +24,5 @@ declare_args() {
# This should be kept in sync with the value of `enable_pdf` in
# //pdf/features.gni, but for layering reasons,
# we can't import pdf's features.gni here.
- enable_freetype = !is_android && !is_ios && !is_castos && !is_fuchsia
+ enable_freetype = is_android || (!is_ios && !is_castos && !is_fuchsia)
}
diff --git a/chrome/android/java/res/xml/developer_preferences.xml b/chrome/android/java/res/xml/developer_preferences.xml
--- a/chrome/android/java/res/xml/developer_preferences.xml
+++ b/chrome/android/java/res/xml/developer_preferences.xml
@@ -28,4 +28,9 @@ found in the LICENSE file.
android:summary="@string/android_gpu_sandbox_summary"
app:featureName="android-gpu-sandbox"
app:needRestart="true" />
+ <org.chromium.components.browser_ui.settings.ChromeSwitchPreference
+ android:title="@string/android_fonts_fingerprinting_mitigation_title"
+ android:summary="@string/android_fonts_fingerprinting_mitigation_summary"
+ app:featureName="android-fonts-fingerprinting-mitigation"
+ app:needRestart="true" />
</PreferenceScreen>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -7326,6 +7326,13 @@ static_library("browser") {
]
}
+ if (is_android) {
+ deps += [
+ "//components/services/font:lib",
+ "//components/services/font/public/mojom",
+ ]
+ }
+
if (enable_chrome_notifications) {
assert(enable_message_center)
sources += [
diff --git a/chrome/browser/component_updater/registration.cc b/chrome/browser/component_updater/registration.cc
--- a/chrome/browser/component_updater/registration.cc
+++ b/chrome/browser/component_updater/registration.cc
@@ -103,6 +103,11 @@
#include "chrome/browser/component_updater/file_type_policies_component_installer.h"
#endif
+#if BUILDFLAG(IS_ANDROID)
+#include "components/component_updater/installer_policies/fonts_pack_component_installer.h"
+#include "third_party/blink/public/common/features.h"
+#endif
+
namespace component_updater {
namespace {
@@ -135,6 +140,11 @@ void DeleteOldComponents(const base::FilePath& user_data_dir) {
void RegisterComponentsForUpdate() {
auto* const cus = g_browser_process->component_updater();
+#if BUILDFLAG(IS_ANDROID)
+ if (base::FeatureList::IsEnabled(blink::features::kAndroidFontsFingerprintingMitigation)) {
+ RegisterFontsPackComponent(cus);
+ }
+#endif
if ((true)) return;
diff --git a/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp
new file mode 100644
--- /dev/null
+++ b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Android-fonts-fingerprinting-mitigation.grdp
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+ <message name="IDS_ANDROID_FONTS_FINGERPRINTING_MITIGATION_TITLE" desc="Text for 'Android fonts fingerprinting mitigation' settings option.">
+ Android fonts fingerprinting mitigation
+ </message>
+ <message name="IDS_ANDROID_FONTS_FINGERPRINTING_MITIGATION_SUMMARY" desc="Summary text for 'Android fonts fingerprinting mitigation' settings option.">
+ Replaces all system fonts with the same for all devices
+ </message>
+</grit-part>
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc
--- a/chrome/browser/ui/prefs/prefs_tab_helper.cc
+++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc
@@ -64,8 +64,7 @@
#include <windows.h>
#endif
-#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || \
- BUILDFLAG(IS_ANDROID) || BUILDFLAG(ENABLE_DESKTOP_ANDROID_EXTENSIONS)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX)
// If a font name in prefs default values starts with a comma, consider it's a
// comma-separated font list and resolve it to the first available font.
#define PREFS_FONT_LIST 1
@@ -447,9 +446,9 @@ void PrefsTabHelper::RegisterProfilePrefs(
value = gfx::FontList::FirstAvailableOrFirst(value);
}
#else // !PREFS_FONT_LIST
- DCHECK(!value.starts_with(','))
- << "This platform doesn't support default font lists. "
- << pref.pref_name << "=" << value;
+ // DCHECK(!value.starts_with(','))
+ // << "This platform doesn't support default font lists. "
+ // << pref.pref_name << "=" << value;
#endif // PREFS_FONT_LIST
registry->RegisterStringPref(pref.pref_name, value);
fonts_with_defaults.insert(pref.pref_name);
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -270,6 +270,10 @@ static_library("renderer") {
deps += [ "//components/strings" ]
}
+ if (is_android) {
+ deps += [ "//components/services/font/public/cpp" ]
+ }
+
if (enable_pdf) {
deps += [
"//components/pdf/renderer",
diff --git a/components/component_updater/installer_policies/BUILD.gn b/components/component_updater/installer_policies/BUILD.gn
--- a/components/component_updater/installer_policies/BUILD.gn
+++ b/components/component_updater/installer_policies/BUILD.gn
@@ -30,6 +30,13 @@ static_library("installer_policies_no_content_deps") {
"trust_token_key_commitments_component_installer_policy.h",
]
+ if (is_android) {
+ sources += [
+ "fonts_pack_component_installer.h",
+ "fonts_pack_component_installer.cc",
+ ]
+ }
+
deps = [
"//base",
"//components/autofill/core/browser",
diff --git a/components/component_updater/installer_policies/fonts_pack_component_installer.cc b/components/component_updater/installer_policies/fonts_pack_component_installer.cc
new file mode 100644
--- /dev/null
+++ b/components/component_updater/installer_policies/fonts_pack_component_installer.cc
@@ -0,0 +1,96 @@
+#include "fonts_pack_component_installer.h"
+
+#include <optional>
+#include <utility>
+
+#include "base/logging.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/functional/callback.h"
+#include "base/memory/ref_counted.h"
+#include "base/path_service.h"
+#include "base/values.h"
+#include "base/version.h"
+#include "components/component_updater/component_updater_paths.h"
+
+using component_updater::ComponentUpdateService;
+
+namespace component_updater {
+
+// The extension id is: gcmjkmgdlgnkkcocmoeiminaijmmjnii
+const uint8_t kFontsPackPublicKeySHA256[32] = {
+ 0x62, 0xc9, 0xac, 0x63, 0xb6, 0xda, 0xa2, 0xe2, 0xce, 0x48, 0xc8,
+ 0xd0, 0x89, 0xcc, 0x9d, 0x88, 0x02, 0x7c, 0x3e, 0x71, 0xcf, 0x5d,
+ 0x6b, 0xb5, 0xdf, 0x21, 0x65, 0x82, 0x08, 0x97, 0x6a, 0x26};
+
+const char kFontsPackSetFetcherManifestName[] =
+ "System Fonts Pack";
+
+FontsPackComponentInstallerPolicy::
+ FontsPackComponentInstallerPolicy() = default;
+
+FontsPackComponentInstallerPolicy::
+ ~FontsPackComponentInstallerPolicy() = default;
+
+bool FontsPackComponentInstallerPolicy::
+ SupportsGroupPolicyEnabledComponentUpdates() const {
+ return false;
+}
+
+bool FontsPackComponentInstallerPolicy::RequiresNetworkEncryption()
+ const {
+ return true;
+}
+
+update_client::CrxInstaller::Result
+FontsPackComponentInstallerPolicy::OnCustomInstall(
+ const base::DictValue& manifest,
+ const base::FilePath& install_dir) {
+ return update_client::CrxInstaller::Result(0); // Nothing custom here.
+}
+
+void FontsPackComponentInstallerPolicy::OnCustomUninstall() {}
+
+void FontsPackComponentInstallerPolicy::ComponentReady(
+ const base::Version& version,
+ const base::FilePath& install_dir,
+ base::DictValue manifest) {
+ DCHECK(!install_dir.empty());
+ LOG(INFO) << "Fonts Pack Version Ready: " << install_dir.value();
+}
+
+// Called during startup and installation before ComponentReady().
+bool FontsPackComponentInstallerPolicy::VerifyInstallation(
+ const base::DictValue& manifest,
+ const base::FilePath& install_dir) const {
+ return base::PathExists(install_dir);
+}
+
+base::FilePath
+FontsPackComponentInstallerPolicy::GetRelativeInstallDir() const {
+ return base::FilePath("fonts");
+}
+
+void FontsPackComponentInstallerPolicy::GetHash(
+ std::vector<uint8_t>* hash) const {
+ hash->assign(std::begin(kFontsPackPublicKeySHA256),
+ std::end(kFontsPackPublicKeySHA256));
+}
+
+std::string FontsPackComponentInstallerPolicy::GetName() const {
+ return kFontsPackSetFetcherManifestName;
+}
+
+update_client::InstallerAttributes
+FontsPackComponentInstallerPolicy::GetInstallerAttributes() const {
+ update_client::InstallerAttributes attributes;
+ return attributes;
+}
+
+void RegisterFontsPackComponent(ComponentUpdateService* cus) {
+ auto installer = base::MakeRefCounted<ComponentInstaller>(
+ std::make_unique<FontsPackComponentInstallerPolicy>());
+ installer->Register(cus, base::OnceClosure(), /*allowed*/true);
+}
+
+} // namespace component_updater
diff --git a/components/component_updater/installer_policies/fonts_pack_component_installer.h b/components/component_updater/installer_policies/fonts_pack_component_installer.h
new file mode 100644
--- /dev/null
+++ b/components/component_updater/installer_policies/fonts_pack_component_installer.h
@@ -0,0 +1,60 @@
+#ifndef COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_FONTS_PACK_COMPONENT_INSTALLER_H_
+#define COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_FONTS_PACK_COMPONENT_INSTALLER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/values.h"
+#include "components/component_updater/component_installer.h"
+
+namespace base {
+class FilePath;
+} // namespace base
+
+namespace component_updater {
+
+class ComponentUpdateService;
+
+// Component for receiving System fonts overrides.
+class FontsPackComponentInstallerPolicy
+ : public ComponentInstallerPolicy {
+ public:
+ static const char kManifestRulesetFormatKey[];
+ static const int kCurrentRulesetFormat;
+
+ FontsPackComponentInstallerPolicy();
+
+ FontsPackComponentInstallerPolicy(
+ const FontsPackComponentInstallerPolicy&) = delete;
+ FontsPackComponentInstallerPolicy& operator=(
+ const FontsPackComponentInstallerPolicy&) = delete;
+
+ ~FontsPackComponentInstallerPolicy() override;
+
+ private:
+ static std::string GetInstallerTag();
+
+ // ComponentInstallerPolicy implementation.
+ bool SupportsGroupPolicyEnabledComponentUpdates() const override;
+ bool RequiresNetworkEncryption() const override;
+ update_client::CrxInstaller::Result OnCustomInstall(
+ const base::DictValue& manifest,
+ const base::FilePath& install_dir) override;
+ void OnCustomUninstall() override;
+ bool VerifyInstallation(const base::DictValue& manifest,
+ const base::FilePath& install_dir) const override;
+ void ComponentReady(const base::Version& version,
+ const base::FilePath& install_dir,
+ base::DictValue manifest) override;
+ base::FilePath GetRelativeInstallDir() const override;
+ void GetHash(std::vector<uint8_t>* hash) const override;
+ std::string GetName() const override;
+ update_client::InstallerAttributes GetInstallerAttributes() const override;
+};
+
+void RegisterFontsPackComponent(ComponentUpdateService* cus);
+
+} // namespace component_updater
+
+#endif // COMPONENTS_COMPONENT_UPDATER_INSTALLER_POLICIES_FONTS_PACK_COMPONENT_INSTALLER_H_
diff --git a/components/services/font/BUILD.gn b/components/services/font/BUILD.gn
--- a/components/services/font/BUILD.gn
+++ b/components/services/font/BUILD.gn
@@ -23,6 +23,16 @@ source_set("lib") {
"//ui/gfx",
]
+ if (is_android) {
+ sources -= [
+ "fontconfig_matching.cc",
+ "fontconfig_matching.h",
+ ]
+ deps -= [
+ "//third_party/fontconfig",
+ ]
+ }
+
public_deps = [ "//skia" ]
if (enable_pdf && (is_linux || is_chromeos)) {
diff --git a/components/services/font/font_service_app.cc b/components/services/font/font_service_app.cc
--- a/components/services/font/font_service_app.cc
+++ b/components/services/font/font_service_app.cc
@@ -4,7 +4,9 @@
#include "components/services/font/font_service_app.h"
+#if !BUILDFLAG(IS_ANDROID)
#include <fontconfig/fontconfig.h>
+#endif
#include <set>
#include <utility>
@@ -26,6 +28,12 @@
#include "ui/gfx/font_fallback_linux.h"
#include "ui/gfx/font_render_params.h"
+#if BUILDFLAG(IS_ANDROID)
+#include "base/path_service.h"
+#include "base/files/file_util.h"
+#include "components/component_updater/component_updater_paths.h"
+#endif
+
#if BUILDFLAG(ENABLE_PDF)
#include "components/services/font/pdf_fontconfig_matching.h" // nogncheck
#endif
@@ -101,6 +109,7 @@ void FontServiceApp::BindReceiver(
void FontServiceApp::MatchFamilyName(const std::string& family_name,
mojom::TypefaceStylePtr requested_style,
MatchFamilyNameCallback callback) {
+#if !BUILDFLAG(IS_ANDROID)
TRACE_EVENT0("fonts", "FontServiceApp::MatchFamilyName");
SkFontConfigInterface::FontIdentity result_identity;
@@ -161,6 +170,7 @@ void FontServiceApp::MatchFamilyName(const std::string& family_name,
std::move(callback).Run(std::move(identity), result_family_cppstring,
std::move(style));
+#endif
}
void FontServiceApp::OpenStream(uint32_t id_number,
@@ -175,12 +185,43 @@ void FontServiceApp::OpenStream(uint32_t id_number,
std::move(callback).Run(std::move(file));
}
+void FontServiceApp::OpenStreamFromName(const std::string& name,
+ OpenStreamCallback callback) {
+#if BUILDFLAG(IS_ANDROID)
+ TRACE_EVENT0("fonts", "FontServiceApp::OpenStreamFromName");
+
+ base::File empty_file;
+
+ base::FilePath local_install_path;
+ if (!base::PathService::Get(component_updater::DIR_COMPONENT_USER, &local_install_path)) {
+ std::move(callback).Run(std::move(empty_file));
+ return;
+ }
+ local_install_path = local_install_path
+ .Append("fonts")
+ .Append("1.0.0")
+ .AppendASCII(name);
+
+ if (!base::PathExists(local_install_path)) {
+ LOG(ERROR) << "System font " << local_install_path << " not found";
+ std::move(callback).Run(std::move(empty_file));
+ return;
+ }
+
+ base::File font_file(local_install_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ std::move(callback).Run(std::move(font_file));
+#endif
+}
+
void FontServiceApp::FallbackFontForCharacter(
uint32_t character,
const std::string& locale,
FallbackFontForCharacterCallback callback) {
TRACE_EVENT0("fonts", "FontServiceApp::FallbackFontForCharacter");
+#if BUILDFLAG(IS_ANDROID)
+ std::move(callback).Run(nullptr, "", false, false);
+#else
gfx::FallbackFontData fallback_font;
if (gfx::GetFallbackFontForChar(character, locale, &fallback_font)) {
size_t index = FindOrAddPath(fallback_font.filepath);
@@ -195,6 +236,7 @@ void FontServiceApp::FallbackFontForCharacter(
} else {
std::move(callback).Run(nullptr, "", false, false);
}
+#endif
}
void FontServiceApp::FontRenderStyleForStrike(
@@ -238,6 +280,9 @@ void FontServiceApp::MatchFontByPostscriptNameOrFullFontName(
TRACE_EVENT0("fonts",
"FontServiceApp::MatchFontByPostscriptNameOrFullFontName");
+#if BUILDFLAG(IS_ANDROID)
+ std::move(callback).Run(nullptr);
+#else
std::optional<FontConfigLocalMatching::FontConfigMatchResult> match_result =
FontConfigLocalMatching::FindFontByPostscriptNameOrFullFontName(family);
if (match_result) {
@@ -249,6 +294,7 @@ void FontServiceApp::MatchFontByPostscriptNameOrFullFontName(
return;
}
std::move(callback).Run(nullptr);
+#endif
}
#if BUILDFLAG(ENABLE_PDF)
diff --git a/components/services/font/font_service_app.h b/components/services/font/font_service_app.h
--- a/components/services/font/font_service_app.h
+++ b/components/services/font/font_service_app.h
@@ -36,6 +36,7 @@ class FontServiceApp : public mojom::FontService {
mojom::TypefaceStylePtr requested_style,
MatchFamilyNameCallback callback) override;
void OpenStream(uint32_t id_number, OpenStreamCallback callback) override;
+ void OpenStreamFromName(const std::string& name, OpenStreamCallback callback) override;
void FallbackFontForCharacter(
uint32_t character,
const std::string& locale,
diff --git a/components/services/font/public/cpp/font_loader.cc b/components/services/font/public/cpp/font_loader.cc
--- a/components/services/font/public/cpp/font_loader.cc
+++ b/components/services/font/public/cpp/font_loader.cc
@@ -82,6 +82,17 @@ SkStreamAsset* FontLoader::openStream(const FontIdentity& identity) {
}
}
+SkStreamAsset* FontLoader::openStreamFromName(const char* filename) {
+ scoped_refptr<internal::MappedFontFile> mapped_font_file =
+ thread_->OpenStreamFromFile(filename);
+ if (!mapped_font_file)
+ return nullptr;
+
+ // Get notified with |mapped_font_file| is destroyed.
+ mapped_font_file->set_observer(this);
+ return mapped_font_file->CreateMemoryStream();
+}
+
sk_sp<SkTypeface> FontLoader::makeTypeface(const FontIdentity& identity,
sk_sp<SkFontMgr> mgr) {
TRACE_EVENT0("fonts", "FontServiceThread::makeTypeface");
diff --git a/components/services/font/public/cpp/font_loader.h b/components/services/font/public/cpp/font_loader.h
--- a/components/services/font/public/cpp/font_loader.h
+++ b/components/services/font/public/cpp/font_loader.h
@@ -56,6 +56,7 @@ class FontLoader : public SkFontConfigInterface,
SkFontStyle* out_style) override;
SkStreamAsset* openStream(const FontIdentity& identity) override
LOCKS_EXCLUDED(mapped_font_files_lock_);
+ SkStreamAsset* openStreamFromName(const char* filename) override;
sk_sp<SkTypeface> makeTypeface(const FontIdentity& identity,
sk_sp<SkFontMgr> mgr) override
LOCKS_EXCLUDED(typeface_cache_lock_);
diff --git a/components/services/font/public/cpp/font_service_thread.cc b/components/services/font/public/cpp/font_service_thread.cc
--- a/components/services/font/public/cpp/font_service_thread.cc
+++ b/components/services/font/public/cpp/font_service_thread.cc
@@ -258,6 +258,54 @@ void FontServiceThread::OpenStreamImpl(base::WaitableEvent* done_event,
done_event, output_file));
}
+scoped_refptr<MappedFontFile> FontServiceThread::OpenStreamFromFile(
+ const std::string& filename) {
+ DCHECK(!task_runner_->RunsTasksInCurrentSequence());
+
+ base::ElapsedTimer timer;
+
+ base::File stream_file;
+ // This proxies to the other thread, which proxies to mojo. Only on the
+ // reply from mojo do we return from this.
+ base::WaitableEvent done_event;
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&FontServiceThread::OpenStreamFromFileImpl, this,
+ &done_event, &stream_file, filename));
+ done_event.Wait();
+
+ base::UmaHistogramMicrosecondsTimes(
+ "Blink.Fonts.FontServiceThread.OpenStreamTime", timer.Elapsed());
+
+ if (!stream_file.IsValid()) {
+ // The font-service may have been killed.
+ return nullptr;
+ }
+
+ // Converts the file to out internal type.
+ scoped_refptr<MappedFontFile> mapped_font_file =
+ new MappedFontFile(0);
+ if (!mapped_font_file->Initialize(std::move(stream_file)))
+ return nullptr;
+
+ return mapped_font_file;
+}
+
+void FontServiceThread::OpenStreamFromFileImpl(base::WaitableEvent* done_event,
+ base::File* output_file,
+ const std::string& file) {
+ DCHECK(task_runner_->RunsTasksInCurrentSequence());
+
+ if (!font_service_.is_connected()) {
+ done_event->Signal();
+ return;
+ }
+
+ pending_waitable_events_.insert(done_event);
+ font_service_->OpenStreamFromName(
+ file, base::BindOnce(&FontServiceThread::OnOpenStreamComplete, this,
+ done_event, output_file));
+}
+
void FontServiceThread::OnOpenStreamComplete(base::WaitableEvent* done_event,
base::File* output_file,
base::File file) {
diff --git a/components/services/font/public/cpp/font_service_thread.h b/components/services/font/public/cpp/font_service_thread.h
--- a/components/services/font/public/cpp/font_service_thread.h
+++ b/components/services/font/public/cpp/font_service_thread.h
@@ -57,6 +57,8 @@ class FontServiceThread : public base::RefCountedThreadSafe<FontServiceThread> {
SkFontStyle* out_style);
scoped_refptr<MappedFontFile> OpenStream(
const SkFontConfigInterface::FontIdentity& identity);
+ scoped_refptr<MappedFontFile> OpenStreamFromFile(
+ const std::string& filename);
bool FallbackFontForCharacter(
uint32_t character,
@@ -121,6 +123,9 @@ class FontServiceThread : public base::RefCountedThreadSafe<FontServiceThread> {
void OpenStreamImpl(base::WaitableEvent* done_event,
base::File* output_file,
const uint32_t id_number);
+ void OpenStreamFromFileImpl(base::WaitableEvent* done_event,
+ base::File* output_file,
+ const std::string& filename);
void OnOpenStreamComplete(base::WaitableEvent* done_event,
base::File* output_file,
base::File file);
diff --git a/components/services/font/public/mojom/font_service.mojom b/components/services/font/public/mojom/font_service.mojom
--- a/components/services/font/public/mojom/font_service.mojom
+++ b/components/services/font/public/mojom/font_service.mojom
@@ -66,6 +66,8 @@ interface FontService {
// Returns a handle to the raw font specified by |id_number|.
OpenStream(uint32 id_number) => (mojo_base.mojom.ReadOnlyFile? font_handle);
+ OpenStreamFromName(string family_name) => (mojo_base.mojom.ReadOnlyFile? font_handle);
+
// Returns a fallback FontIdentity and Typeface style for the given character
// and locale. If no fallback font can be found, returns a null identity.
FallbackFontForCharacter(uint32 character, string locale)
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -2648,6 +2648,17 @@ source_set("browser") {
]
}
+ if (is_android) {
+ sources += [
+ "font_service.cc",
+ "font_service.h",
+ ]
+
+ deps += [ "//pdf:buildflags" ]
+
+ public_deps += [ "//components/services/font/public/mojom" ]
+ }
+
if (is_linux || is_chromeos) {
sources -=
[ "file_system_access/file_path_watcher/file_path_watcher_stub.cc" ]
@@ -2694,6 +2705,13 @@ source_set("browser") {
deps += [ "//components/services/font_data:lib" ]
}
+ if (is_android) {
+ deps += [
+ "//components/services/font:lib",
+ ]
+ public_deps += [ "//components/services/font/public/mojom" ]
+ }
+
if (allow_oop_video_decoder) {
sources += [ "media/oop_video_decoder_factory.cc" ]
deps += [ "//media/mojo/mojom" ]
diff --git a/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc b/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc
--- a/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc
+++ b/content/browser/renderer_host/render_process_host_impl_receiver_bindings.cc
@@ -56,6 +56,11 @@
#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
#endif // BUILDFLAG(IS_P2P_ENABLED)
+#if BUILDFLAG(IS_ANDROID)
+#include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck
+#include "content/browser/font_service.h" // nogncheck
+#endif
+
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck
#include "content/browser/font_service.h" // nogncheck
@@ -356,6 +361,13 @@ void RenderProcessHostImpl::IOThreadHostImpl::BindHostReceiver(
}
#endif
+#if BUILDFLAG(IS_ANDROID)
+ if (auto font_receiver = receiver.As<font_service::mojom::FontService>()) {
+ ConnectToFontService(std::move(font_receiver));
+ return;
+ }
+#endif
+
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
if (auto font_receiver = receiver.As<font_service::mojom::FontService>()) {
ConnectToFontService(std::move(font_receiver));
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn
--- a/content/child/BUILD.gn
+++ b/content/child/BUILD.gn
@@ -137,6 +137,13 @@ target(link_target_type, "child") {
]
}
+ if (is_android) {
+ deps += [
+ "//components/services/font/public/cpp",
+ "//components/services/font/public/mojom",
+ ]
+ }
+
if (is_win) {
sources += [
"child_process_sandbox_support_impl_win.cc",
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -351,6 +351,10 @@ target(link_target_type, "renderer") {
deps += [ "//services/screen_ai/public/mojom" ]
}
+ if (is_android) {
+ deps += [ "//components/services/font/public/cpp" ]
+ }
+
if (is_linux || is_chromeos) {
deps += [ "//components/services/font/public/cpp" ]
}
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -141,6 +141,23 @@
#include "content/common/android/sync_compositor_statics.h"
#endif
+#if BUILDFLAG(IS_ANDROID)
+#include "components/services/font/public/mojom/font_service.mojom.h" // nogncheck
+#include "components/services/font/public/cpp/font_loader.h"
+#include "content/browser/font_service.h" // nogncheck
+
+#include "base/path_service.h"
+#include "base/base_paths_android.h"
+#include "base/file_descriptor_store.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/files/file_path.h"
+#include "content/public/common/content_descriptor_keys.h"
+#include "skia/ext/font_utils.h"
+#include "third_party/skia/include/core/SkFontMgr.h"
+#include "third_party/skia/include/ports/SkFontMgr_android.h"
+#include "third_party/blink/public/platform/web_font_render_style.h"
+#endif
+
using blink::Platform;
using blink::WebAudioDevice;
using blink::WebAudioLatencyHint;
@@ -191,6 +208,37 @@ viz::command_buffer_metrics::ContextType ToVizContextType(
NOTREACHED();
}
+#if BUILDFLAG(IS_ANDROID)
+void InitializeCustomFonts() {
+ if (!base::FeatureList::IsEnabled(blink::features::kAndroidFontsFingerprintingMitigation)) {
+ return;
+ }
+ std::string font_config = "cromite_fonts.xml";
+ sk_sp<SkFontConfigInterface> fci(SkFontConfigInterface::RefGlobal());
+ SkStreamAsset* asset = fci->openStreamFromName(font_config.c_str());
+ if (!asset) {
+ LOG(ERROR) << "Unable to activate custom fonts.";
+ return;
+ }
+
+ std::string android_fonts_dir = "use_fd";
+
+ auto custom = std::make_unique<SkFontMgr_Android_CustomFonts>();
+ custom->fSystemFontUse =
+ SkFontMgr_Android_CustomFonts::SystemFontUse::kOnlyCustom;
+ custom->fBasePath = android_fonts_dir.c_str();
+ custom->fFontsXml = font_config.c_str();
+ custom->fFallbackFontsXml = font_config.c_str();
+ // If set to true the SkFontMgr will acquire all requisite
+ // system IO resources on initialization.
+ custom->fIsolated = false;
+
+ sk_sp<SkFontMgr> skia_font_manager =
+ SkFontMgr_New_Android(std::move(custom));
+ skia::OverrideDefaultSkFontMgr(std::move(skia_font_manager));
+}
+#endif
+
} // namespace
//------------------------------------------------------------------------------
@@ -204,18 +252,21 @@ RendererBlinkPlatformImpl::RendererBlinkPlatformImpl(
is_locked_to_site_(false),
main_thread_scheduler_(main_thread_scheduler),
next_frame_sink_id_(uint32_t{std::numeric_limits<int32_t>::max()} + 1) {
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
sk_sp<font_service::FontLoader> font_loader;
#endif
// RenderThread may not exist in some tests.
if (RenderThreadImpl::current()) {
-#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
mojo::PendingRemote<font_service::mojom::FontService> font_service;
RenderThreadImpl::current()->BindHostReceiver(
font_service.InitWithNewPipeAndPassReceiver());
font_loader = sk_make_sp<font_service::FontLoader>(std::move(font_service));
SkFontConfigInterface::SetGlobal(font_loader);
+#if BUILDFLAG(IS_ANDROID)
+ InitializeCustomFonts();
+#endif
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc
--- a/content/renderer/renderer_main.cc
+++ b/content/renderer/renderer_main.cc
@@ -183,8 +183,6 @@ int RendererMain(MainFunctionParams parameters) {
// On Linux, Windows, and ChromeOS, the font manager is overridden or
// specially handled in RendererBlinkPlatformImpl(). On other platforms,
// initialise the default one on a thread pool, to avoid blocking on it later.
- base::ThreadPool::PostTask(FROM_HERE,
- base::BindOnce([] { skia::DefaultFontMgr(); }));
#endif
// This function allows pausing execution using the --renderer-startup-dialog
diff --git a/cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc b/cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc
new file mode 100644
--- /dev/null
+++ b/cromite_flags/chrome/browser/about_flags_cc/Android-fonts-fingerprinting-mitigation.inc
@@ -0,0 +1,12 @@
+#if BUILDFLAG(IS_ANDROID)
+
+#ifdef FLAG_SECTION
+
+ {"android-fonts-fingerprinting-mitigation",
+ "Android fonts fingerprinting mitigation",
+ "Replaces all system fonts with the same for all devices.", kOsAndroid,
+ FEATURE_VALUE_TYPE(blink::features::kAndroidFontsFingerprintingMitigation)},
+
+#endif
+
+#endif
diff --git a/cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc b/cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc
new file mode 100644
--- /dev/null
+++ b/cromite_flags/third_party/blink/common/features_cc/Android-fonts-fingerprinting-mitigation.inc
@@ -0,0 +1,7 @@
+#if BUILDFLAG(IS_ANDROID)
+
+CROMITE_FEATURE(kAndroidFontsFingerprintingMitigation,
+ "AndroidFontsFingerprintingMitigation",
+ base::FEATURE_ENABLED_BY_DEFAULT);
+
+#endif
diff --git a/cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc b/cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc
new file mode 100644
--- /dev/null
+++ b/cromite_flags/third_party/blink/common/features_h/Android-fonts-fingerprinting-mitigation.inc
@@ -0,0 +1,5 @@
+#if BUILDFLAG(IS_ANDROID)
+
+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kAndroidFontsFingerprintingMitigation);
+
+#endif
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -446,6 +446,18 @@ component("skia") {
sources += skia_ports_fci_sources
}
+ if (is_android) {
+ sources += [
+ "//third_party/skia/src/ports/SkFontConfigInterface.cpp",
+ "//third_party/skia/src/ports/SkFontMgr_FontConfigInterface.cpp",
+ ]
+ public += [
+ "include/ports/SkFontConfigInterface.h",
+ "include/ports/SkFontMgr_FontConfigInterface.h",
+ ]
+ defines += [ "CROMITE_IS_ANDROID" ]
+ }
+
if (is_linux || is_chromeos || is_android) {
# Retain the files for the SkFontMgr_Android on linux to emulate android
# fonts. See content/zygote/zygote_main_linux.cc
diff --git a/skia/ext/font_utils.cc b/skia/ext/font_utils.cc
--- a/skia/ext/font_utils.cc
+++ b/skia/ext/font_utils.cc
@@ -60,6 +60,7 @@ SkFontMgr* g_fontmgr_override = nullptr;
#if BUILDFLAG(IS_ANDROID)
// https://crbug.com/461659286 Failure to create any font causes crash.
BASE_FEATURE(kUseAndroidNDKFontAPI, base::FEATURE_DISABLED_BY_DEFAULT);
+SET_CROMITE_FEATURE_DISABLED(kUseAndroidNDKFontAPI);
#endif
} // namespace
diff --git a/third_party/freetype/include/freetype-custom/freetype/config/ftoption.h b/third_party/freetype/include/freetype-custom/freetype/config/ftoption.h
--- a/third_party/freetype/include/freetype-custom/freetype/config/ftoption.h
+++ b/third_party/freetype/include/freetype-custom/freetype/config/ftoption.h
@@ -607,7 +607,7 @@ FT_BEGIN_HEADER
* module (namely TrueType~& OpenType).
*/
/* Not needed since PDFs do not support any of the color font formats. */
-/* #define TT_CONFIG_OPTION_COLOR_LAYERS */
+#define TT_CONFIG_OPTION_COLOR_LAYERS
/**************************************************************************
diff --git a/third_party/skia/include/ports/SkFontConfigInterface.h b/third_party/skia/include/ports/SkFontConfigInterface.h
--- a/third_party/skia/include/ports/SkFontConfigInterface.h
+++ b/third_party/skia/include/ports/SkFontConfigInterface.h
@@ -91,6 +91,8 @@ public:
*/
virtual SkStreamAsset* openStream(const FontIdentity&) = 0;
+ virtual SkStreamAsset* openStreamFromName(const char* filename) = 0;
+
/**
* Return an SkTypeface for the given FontIdentity.
*
diff --git a/third_party/skia/include/ports/SkFontMgr_android.h b/third_party/skia/include/ports/SkFontMgr_android.h
--- a/third_party/skia/include/ports/SkFontMgr_android.h
+++ b/third_party/skia/include/ports/SkFontMgr_android.h
@@ -9,6 +9,11 @@
#define SkFontMgr_android_DEFINED
#include "include/core/SkRefCnt.h"
+#include "include/core/SkStream.h"
+#include "src/core/SkTHash.h"
+
+#include "include/ports/SkFontConfigInterface.h"
+#include "include/ports/SkFontMgr_FontConfigInterface.h"
#include <memory>
@@ -40,9 +45,44 @@ struct SkFontMgr_Android_CustomFonts {
* system IO resources on initialization.
*/
bool fIsolated;
+
+ struct SkFontMgr_Android_CustomFonts_MappedData {
+ int fd;
+ int64_t offset;
+ size_t size;
+ };
+ skia_private::THashMap<std::string,
+ SkFontMgr_Android_CustomFonts_MappedData> platform_file_map;
+
+ void add_platform_file(std::string key, int fd, int64_t offset, size_t size) {
+ SkFontMgr_Android_CustomFonts_MappedData data = {fd, offset, size};
+ platform_file_map.set(key, std::move(data));
+ }
+
+ std::unique_ptr<SkStreamAsset> getPlatformFile(const char* filename) const {
+ // SkDebugf("-- open platform file '%s'\n", filename);
+ sk_sp<SkFontConfigInterface> fci(SkFontConfigInterface::RefGlobal());
+ SkStreamAsset* asset = fci->openStreamFromName(filename);
+ if (asset) {
+ return std::unique_ptr<SkStreamAsset>(asset);
+ }
+
+ const auto* it = platform_file_map.find(filename);
+ if (!it) {
+ return nullptr;
+ }
+ auto whole_data = SkData::MakeFromFD(it->fd);
+ auto data = SkData::MakeSubset(whole_data.get(), it->offset, it->size);
+ if (!data) {
+ return nullptr;
+ }
+ return std::unique_ptr<SkStreamAsset>(new SkMemoryStream(std::move(data)));
+ }
};
/** Create a font manager for Android. If 'custom' is NULL, use only system fonts. */
-SK_API sk_sp<SkFontMgr> SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom,
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Android(std::unique_ptr<SkFontMgr_Android_CustomFonts> custom);
+
+SK_API sk_sp<SkFontMgr> SkFontMgr_New_Android(std::unique_ptr<SkFontMgr_Android_CustomFonts> custom,
std::unique_ptr<SkFontScanner> scanner);
#endif // SkFontMgr_android_DEFINED
diff --git a/third_party/skia/src/ports/SkFontConfigInterface.cpp b/third_party/skia/src/ports/SkFontConfigInterface.cpp
--- a/third_party/skia/src/ports/SkFontConfigInterface.cpp
+++ b/third_party/skia/src/ports/SkFontConfigInterface.cpp
@@ -22,7 +22,12 @@ sk_sp<SkFontConfigInterface> SkFontConfigInterface::RefGlobal() {
if (gFontConfigInterface) {
return sk_ref_sp(gFontConfigInterface);
}
+#if defined(CROMITE_IS_ANDROID)
+ SkASSERT(false);
+ return nullptr;
+#else
return sk_ref_sp(SkFontConfigInterface::GetSingletonDirectInterface());
+#endif
}
void SkFontConfigInterface::SetGlobal(sk_sp<SkFontConfigInterface> fc) {
diff --git a/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp b/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp
--- a/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp
+++ b/third_party/skia/src/ports/SkFontConfigInterface_direct.cpp
@@ -715,3 +715,8 @@ bool SkFontConfigInterfaceDirect::matchFamilyName(const char familyName[],
SkStreamAsset* SkFontConfigInterfaceDirect::openStream(const FontIdentity& identity) {
return SkStream::MakeFromFile(identity.fString.c_str()).release();
}
+
+SkStreamAsset* SkFontConfigInterfaceDirect::openStreamFromName(const char* filename) {
+ SkASSERT(false);
+ return nullptr;
+}
diff --git a/third_party/skia/src/ports/SkFontConfigInterface_direct.h b/third_party/skia/src/ports/SkFontConfigInterface_direct.h
--- a/third_party/skia/src/ports/SkFontConfigInterface_direct.h
+++ b/third_party/skia/src/ports/SkFontConfigInterface_direct.h
@@ -29,6 +29,7 @@ public:
SkFontStyle* outStyle) override;
SkStreamAsset* openStream(const FontIdentity&) override;
+ SkStreamAsset* openStreamFromName(const char* filename) override;
protected:
virtual bool isAccessible(const char* filename);
diff --git a/third_party/skia/src/ports/SkFontMgr_android.cpp b/third_party/skia/src/ports/SkFontMgr_android.cpp
--- a/third_party/skia/src/ports/SkFontMgr_android.cpp
+++ b/third_party/skia/src/ports/SkFontMgr_android.cpp
@@ -16,6 +16,7 @@
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/ports/SkFontMgr_android.h"
+#include "include/ports/SkFontScanner_FreeType.h"
#include "include/private/base/SkFixed.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTDArray.h"
@@ -27,6 +28,7 @@
#include "src/core/SkTypefaceCache.h"
#include "src/ports/SkFontMgr_android_parser.h"
#include "src/ports/SkTypeface_proxy.h"
+#include "src/ports/SkFontScanner_FreeType_priv.h"
#include <algorithm>
#include <limits>
@@ -37,7 +39,95 @@ class SkData;
namespace {
-[[maybe_unused]] static inline const constexpr bool kSkFontMgrVerbose = false;
+static inline const constexpr bool kSkFontMgrVerbose = true;
+
+#include "SkFontMgr_android_data.cpp"
+
+class SkTypeface_AndroidSystemCustom : public SkTypeface_FreeType {
+public:
+ SkTypeface_AndroidSystemCustom(const SkString& pathName,
+ int index,
+ const SkFixed* axes, int axesCount,
+ const SkFontStyle& style,
+ bool isFixedPitch,
+ const SkString& familyName,
+ const TArray<SkLanguage, true>& lang,
+ FontVariant variantStyle,
+ const SkFontMgr_Android_CustomFonts* custom)
+ : INHERITED(style, isFixedPitch)
+ , fPathName(pathName)
+ , fFamilyName(familyName)
+ , fIndex(index)
+ , fAxes(axes, axesCount)
+ , fLang(lang)
+ , fVariantStyle(variantStyle)
+ , fFile(nullptr)
+ , custom_(custom) {}
+
+ std::unique_ptr<SkStreamAsset> makeStream() const {
+ if (custom_) {
+ return custom_->getPlatformFile(fPathName.c_str());
+ }
+ if (fFile) {
+ sk_sp<SkData> data(SkData::MakeFromFILE(fFile));
+ return data ? std::make_unique<SkMemoryStream>(std::move(data)) : nullptr;
+ }
+ return SkStream::MakeFromFile(fPathName.c_str());
+ }
+
+ void onGetFamilyName(SkString* familyName) const override {
+ *familyName = fFamilyName;
+ }
+
+ void onGetFontDescriptor(SkFontDescriptor* desc, bool* serialize) const override {
+ SkASSERT(desc);
+ SkASSERT(serialize);
+ desc->setFamilyName(fFamilyName.c_str());
+ desc->setStyle(this->fontStyle());
+ desc->setFactoryId(SkTypeface_FreeType::FactoryId);
+ *serialize = false;
+ }
+
+ std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override {
+ *ttcIndex = fIndex;
+ return this->makeStream();
+ }
+
+ std::unique_ptr<SkFontData> onMakeFontData() const override {
+ return std::make_unique<SkFontData>(
+ this->makeStream(), fIndex, 0, fAxes.begin(), fAxes.size(), nullptr, 0);
+ }
+
+ sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override {
+ SkFontStyle style = this->fontStyle();
+ std::unique_ptr<SkFontData> data = this->cloneFontData(args, &style);
+ if (!data) {
+ SkASSERT(false);
+ return nullptr;
+ }
+ return sk_make_sp<SkTypeface_AndroidSystemCustom>(
+ fPathName,
+ fIndex,
+ data->getAxis(),
+ data->getAxisCount(),
+ style,
+ this->isFixedPitch(),
+ fFamilyName,
+ fLang,
+ fVariantStyle, custom_);
+ }
+
+ const SkString fPathName;
+ const SkString fFamilyName;
+ int fIndex;
+ const STArray<4, SkFixed, true> fAxes;
+ const STArray<4, SkLanguage, true> fLang;
+ const FontVariant fVariantStyle;
+ SkAutoTCallVProc<FILE, sk_fclose> fFile;
+ const SkFontMgr_Android_CustomFonts* custom_;
+
+ using INHERITED = SkTypeface_FreeType;
+};
class SkTypeface_AndroidSystem : public SkTypeface_proxy {
public:
@@ -112,7 +202,8 @@ using StreamForPathCache = skia_private::THashMap<SkString, std::unique_ptr<SkSt
class SkFontStyleSet_Android : public SkFontStyleSet {
public:
explicit SkFontStyleSet_Android(const FontFamily& family, const SkFontScanner* scanner,
- const bool cacheFontFiles, StreamForPathCache& streamForPath) {
+ const bool cacheFontFiles, StreamForPathCache& streamForPath,
+ const SkFontMgr_Android_CustomFonts* custom) {
const SkString* cannonicalFamilyName = nullptr;
if (!family.fNames.empty()) {
cannonicalFamilyName = &family.fNames[0];
@@ -121,38 +212,60 @@ public:
// TODO? make this lazy
for (int i = 0; i < family.fFonts.size(); ++i) {
+ bool use_custom = false;
const FontFileInfo& fontFile = family.fFonts[i];
SkString pathName(family.fBasePath);
pathName.append(fontFile.fFileName);
- std::unique_ptr<SkStreamAsset>* streamPtr = streamForPath.find(pathName);
- if (!streamPtr) {
- streamPtr = streamForPath.set(pathName, SkStream::MakeFromFile(pathName.c_str()));
- }
- if (!*streamPtr) {
- SkDEBUGF("Requested font file %s cannot be opened.\n", pathName.c_str());
- continue;
- }
- std::unique_ptr<SkStreamAsset> stream = (*streamPtr)->duplicate();
- if (!stream) {
- SkDEBUGF("Requested font file %s could not be duplicated.\n", pathName.c_str());
- continue;
+ const int ttcIndex = fontFile.fIndex;
+ SkString familyName;
+ SkFontStyle fontStyle;
+ bool isFixedWidth;
+ SkFontScanner::AxisDefinitions axisDefinitions;
+ SkFontScanner::VariationPosition current;
+ SkFontArguments::VariationPosition position;
+
+ std::unique_ptr<SkStreamAsset> stream;
+ if (!custom && !fontFile.fFileName.startsWith('#')) {
+ std::unique_ptr<SkStreamAsset>* streamPtr = streamForPath.find(pathName);
+ if (!streamPtr) {
+ streamPtr = streamForPath.set(pathName, SkStream::MakeFromFile(pathName.c_str()));
+ }
+ if (!*streamPtr) {
+ SkDEBUGF("Requested font file %s cannot be opened.\n", pathName.c_str());
+ continue;
+ }
+ stream = (*streamPtr)->duplicate();
+ if (!stream) {
+ SkDEBUGF("Requested font file %s could not be duplicated.\n", pathName.c_str());
+ continue;
+ }
+ } else if (custom) {
+ use_custom = true;
+ if (!GetFontData(fontFile.fFileName,
+ &familyName, &fontStyle, &isFixedWidth, &axisDefinitions)) {
+ stream = custom->getPlatformFile(fontFile.fFileName.c_str());
+ }
+ pathName = fontFile.fFileName;
}
- SkFontArguments::VariationPosition position = {
- fontFile.fVariationDesignPosition.begin(),
- fontFile.fVariationDesignPosition.size()
+ sk_sp<SkTypeface> proxy;
+ position = {
+ fontFile.fVariationDesignPosition.begin(),
+ fontFile.fVariationDesignPosition.size()
};
// TODO: this creates the proxy with the given stream, so always cacheFontFiles.
- auto proxy = scanner->MakeFromStream(
- std::move(stream),
- SkFontArguments().setCollectionIndex(fontFile.fIndex)
- .setVariationDesignPosition(position));
- if (!proxy) {
- SkDEBUGF("Requested font file %s does not have valid font data.\n",
- pathName.c_str());
- continue;
+ if (!use_custom || stream) {
+ proxy = scanner->MakeFromStream(
+ std::move(stream),
+ SkFontArguments().setCollectionIndex(fontFile.fIndex)
+ .setVariationDesignPosition(position));
+ if (!proxy) {
+ SkDEBUGF("Requested font file %s does not have valid font data.\n",
+ pathName.c_str());
+ continue;
+ }
}
uint32_t variant = family.fVariant;
@@ -163,13 +276,25 @@ public:
// The first specified family name overrides the family name found in the font.
// TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return
// all of the specified family names in addition to the names found in the font.
- SkString familyName;
- proxy->getFamilyName(&familyName);
- if (cannonicalFamilyName != nullptr) {
- familyName = *cannonicalFamilyName;
- }
+ AutoSTMalloc<4, SkFixed> axisValues(axisDefinitions.size());
- SkFontStyle fontStyle = proxy->fontStyle();
+ if (!use_custom || stream) {
+ proxy->getFamilyName(&familyName);
+ if (cannonicalFamilyName != nullptr) {
+ familyName = *cannonicalFamilyName;
+ }
+ fontStyle = proxy->fontStyle();
+ isFixedWidth = proxy->isFixedPitch();
+ } else {
+ variant = kCompact_FontVariant | kElegant_FontVariant;
+ SkFontScanner_FreeType::computeAxisValues(
+ axisDefinitions,
+ SkFontArguments::VariationPosition{current.data(), current.size()},
+ position, axisValues, familyName, &fontStyle);
+ if (cannonicalFamilyName != nullptr) {
+ familyName = *cannonicalFamilyName;
+ }
+ }
int weight = fontFile.fWeight != 0 ? fontFile.fWeight : fontStyle.weight();
SkFontStyle::Slant slant = fontStyle.slant();
switch (fontFile.fStyle) {
@@ -180,6 +305,19 @@ public:
}
fontStyle = SkFontStyle(weight, fontStyle.width(), slant);
+ if (use_custom) {
+ fStyles.push_back().reset(
+ new SkTypeface_AndroidSystemCustom(pathName,
+ fontFile.fIndex,
+ axisValues.get(), axisDefinitions.size(),
+ fontStyle,
+ isFixedWidth,
+ familyName,
+ family.fLanguages,
+ variant,
+ custom));
+ continue;
+ }
fStyles.push_back(
SkTypeface_AndroidSystem::Make(proxy,
fontStyle, proxy->isFixedPitch(),
@@ -208,15 +346,18 @@ public:
return fStyles[index];
}
- sk_sp<SkTypeface_AndroidSystem> matchAStyle(const SkFontStyle& pattern) {
+ sk_sp<SkTypeface_AndroidSystemCustom> matchCromiteStyle(const SkFontStyle& pattern) {
+ return sk_sp_static_cast<SkTypeface_AndroidSystemCustom>(this->matchStyleCSS3(pattern));
+ }
+ sk_sp<SkTypeface_AndroidSystem> matchAndroidStyle(const SkFontStyle& pattern) {
return sk_sp_static_cast<SkTypeface_AndroidSystem>(this->matchStyleCSS3(pattern));
}
sk_sp<SkTypeface> matchStyle(const SkFontStyle& pattern) override {
- return this->matchAStyle(pattern);
+ return this->matchStyleCSS3(pattern);
}
private:
- TArray<sk_sp<SkTypeface_AndroidSystem>> fStyles;
+ TArray<sk_sp<SkTypeface>> fStyles;
SkString fFallbackFor;
friend struct NameToFamily;
@@ -237,24 +378,26 @@ struct NameToFamily {
class SkFontMgr_Android : public SkFontMgr {
public:
- SkFontMgr_Android(const SkFontMgr_Android_CustomFonts* custom,
+ SkFontMgr_Android(std::unique_ptr<SkFontMgr_Android_CustomFonts> custom_in,
std::unique_ptr<SkFontScanner> scanner)
: fScanner(std::move(scanner)) {
+ custom_ = std::move(custom_in);
+ auto* custom = custom_.get();
std::vector<std::unique_ptr<FontFamily>> families;
if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem != custom->fSystemFontUse) {
SkString base(custom->fBasePath);
SkFontMgr_Android_Parser::GetCustomFontFamilies(
- families, base, custom->fFontsXml, custom->fFallbackFontsXml);
+ families, base, custom, custom->fFontsXml, custom->fFallbackFontsXml);
}
if (!custom ||
(custom && SkFontMgr_Android_CustomFonts::kOnlyCustom != custom->fSystemFontUse))
{
- SkFontMgr_Android_Parser::GetSystemFontFamilies(families);
+ SkFontMgr_Android_Parser::GetSystemFontFamilies(families, custom);
}
if (custom && SkFontMgr_Android_CustomFonts::kPreferSystem == custom->fSystemFontUse) {
SkString base(custom->fBasePath);
SkFontMgr_Android_Parser::GetCustomFontFamilies(
- families, base, custom->fFontsXml, custom->fFallbackFontsXml);
+ families, base, custom, custom->fFontsXml, custom->fFallbackFontsXml);
}
this->buildNameToFamilyMap(families, custom ? custom->fIsolated : false);
this->findDefaultStyleSet();
@@ -309,33 +452,53 @@ protected:
}
using Matcher = bool (*)(const SkString& familyName, const NameToFamily&);
- static sk_sp<SkTypeface_AndroidSystem> find_family_style_character(
+ sk_sp<SkTypeface> find_family_style_character(
const SkString& familyName,
const TArray<NameToFamily, true>& nameToFamilyMap,
const SkFontStyle& style, bool elegant,
const SkString& langTag, SkUnichar character,
- Matcher matcher)
+ Matcher matcher) const
{
for (auto&& nameToFamily : nameToFamilyMap) {
if (!matcher(familyName, nameToFamily)) {
continue;
}
- sk_sp<SkTypeface_AndroidSystem> face(nameToFamily.styleSet->matchAStyle(style));
+ if (custom_) {
+ sk_sp<SkTypeface_AndroidSystemCustom> face(nameToFamily.styleSet->matchCromiteStyle(style));
+
+ if (!langTag.isEmpty() &&
+ std::none_of(face->fLang.begin(), face->fLang.end(), [&](const SkLanguage& lang){
+ return lang.getTag().startsWith(langTag.c_str());
+ }))
+ {
+ continue;
+ }
- if (!langTag.isEmpty() &&
- std::none_of(face->fLang.begin(), face->fLang.end(), [&](const SkLanguage& lang){
- return lang.getTag().startsWith(langTag.c_str());
- }))
- {
- continue;
- }
+ if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) {
+ continue;
+ }
- if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) {
- continue;
- }
+ if (face->unicharToGlyph(character) != 0) {
+ return face;
+ }
+ } else {
+ sk_sp<SkTypeface_AndroidSystem> face(nameToFamily.styleSet->matchAndroidStyle(style));
+
+ if (!langTag.isEmpty() &&
+ std::none_of(face->fLang.begin(), face->fLang.end(), [&](const SkLanguage& lang){
+ return lang.getTag().startsWith(langTag.c_str());
+ }))
+ {
+ continue;
+ }
+
+ if (SkToBool(face->fVariantStyle & kElegant_FontVariant) != elegant) {
+ continue;
+ }
- if (face->unicharToGlyph(character) != 0) {
- return face;
+ if (face->unicharToGlyph(character) != 0) {
+ return face;
+ }
}
}
return nullptr;
@@ -360,9 +523,9 @@ protected:
auto find = [this, &style, &character](const SkString& familyName,
const SkString& lang,
- bool elegant) -> sk_sp<SkTypeface_AndroidSystem>
+ bool elegant) -> sk_sp<SkTypeface>
{
- sk_sp<SkTypeface_AndroidSystem> matchingTypeface;
+ sk_sp<SkTypeface> matchingTypeface;
if (!familyName.isEmpty()) {
matchingTypeface = find_family_style_character(
familyName, fNameToFamilyMap, style, elegant, lang, character,
@@ -410,7 +573,7 @@ protected:
};
- sk_sp<SkTypeface_AndroidSystem> matchingTypeface;
+ sk_sp<SkTypeface> matchingTypeface;
// If familyName is empty, don't look through everything twice.
SkString familyNames[2] = { SkString(familyName), SkString() };
size_t familyNamesCount = familyNames[0].isEmpty() ? 1 : 2;
@@ -475,6 +638,7 @@ protected:
private:
std::unique_ptr<SkFontScanner> fScanner;
+ std::unique_ptr<SkFontMgr_Android_CustomFonts> custom_;
TArray<sk_sp<SkFontStyleSet_Android>> fStyleSets;
sk_sp<SkFontStyleSet> fDefaultStyleSet;
@@ -496,7 +660,7 @@ private:
}
sk_sp<SkFontStyleSet_Android> newSet =
- sk_make_sp<SkFontStyleSet_Android>(family, fScanner.get(), isolated, streamForPath);
+ sk_make_sp<SkFontStyleSet_Android>(family, fScanner.get(), isolated, streamForPath, custom_.get());
if (0 == newSet->count()) {
return;
}
@@ -542,7 +706,11 @@ static char const * const gSystemFontUseStrings[] = {
} // namespace
-sk_sp<SkFontMgr> SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* custom,
+sk_sp<SkFontMgr> SkFontMgr_New_Android(std::unique_ptr<SkFontMgr_Android_CustomFonts> custom) {
+ return SkFontMgr_New_Android(std::move(custom), SkFontScanner_Make_FreeType());
+}
+
+sk_sp<SkFontMgr> SkFontMgr_New_Android(std::unique_ptr<SkFontMgr_Android_CustomFonts> custom,
std::unique_ptr<SkFontScanner> scanner) {
if (custom) {
SkASSERT(0 <= custom->fSystemFontUse);
@@ -555,5 +723,5 @@ sk_sp<SkFontMgr> SkFontMgr_New_Android(const SkFontMgr_Android_CustomFonts* cust
custom->fFallbackFontsXml);
}
}
- return sk_make_sp<SkFontMgr_Android>(custom, std::move(scanner));
+ return sk_make_sp<SkFontMgr_Android>(std::move(custom), std::move(scanner));
}
diff --git a/third_party/skia/src/ports/SkFontMgr_android_data.cpp b/third_party/skia/src/ports/SkFontMgr_android_data.cpp
new file mode 100644
--- /dev/null
+++ b/third_party/skia/src/ports/SkFontMgr_android_data.cpp
@@ -0,0 +1,1641 @@
+// AUTOGENERATED
+//
+// SkString dumpAxis("axis|");
+// dumpAxis.appendS32(axisDefinitions.size());
+// dumpAxis.append("|");
+// for (auto& def : axisDefinitions) {
+// dumpAxis.appendS32(def.fTag);
+// dumpAxis.append("|");
+// dumpAxis.appendScalar(def.fMinimum);
+// dumpAxis.append("|");
+// dumpAxis.appendScalar(def.fDefault);
+// dumpAxis.append("|");
+// dumpAxis.appendScalar(def.fMaximum);
+// dumpAxis.append("|");
+// }
+// SkDEBUGF("font file='%s' familyName='%s' width=%d weight=%d slant=%d axisDefinitions=%d isFixedWidth=%d axis=%s\n",
+// pathName.c_str(),
+// familyName.c_str(),
+// style.width(),
+// style.weight(),
+// style.slant(),
+// axisDefinitions.size(),
+// (int)isFixedWidth,
+// dumpAxis.c_str());
+
+bool GetFontData(const SkString& file,
+ SkString* familyName,
+ SkFontStyle* style,
+ bool* isFixedPitch,
+ SkFontScanner::AxisDefinitions* axes) {
+ if (file.equals("CarroisGothicSC-Regular.ttf")) {
+ familyName->set("Carrois Gothic SC");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("ComingSoon.ttf")) {
+ familyName->set("Coming Soon");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("CutiveMono.ttf")) {
+ familyName->set("Cutive Mono");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = true;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("DancingScript-Bold.ttf")) {
+ familyName->set("Dancing Script");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("DancingScript-Regular.ttf")) {
+ familyName->set("Dancing Script");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("DroidSansMono.ttf")) {
+ familyName->set("Droid Sans Mono");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = true;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoColorEmoji.ttf")) {
+ familyName->set("Noto Color Emoji");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoColorEmojiFlags.ttf")) {
+ familyName->set("Noto Color Emoji Flags");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = true;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoColorEmojiLegacy.ttf")) {
+ familyName->set("Noto Color Emoji");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = true;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoNaskhArabic-Bold.ttf")) {
+ familyName->set("Noto Naskh Arabic");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoNaskhArabic-Regular.ttf")) {
+ familyName->set("Noto Naskh Arabic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoNaskhArabicUI-Bold.ttf")) {
+ familyName->set("Noto Naskh Arabic UI");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoNaskhArabicUI-Regular.ttf")) {
+ familyName->set("Noto Naskh Arabic UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansAdlam-VF.ttf")) {
+ familyName->set("Noto Sans Adlam");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansAhom-Regular.otf")) {
+ familyName->set("Noto Sans Ahom");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansAnatolianHieroglyphs-Regular.otf")) {
+ familyName->set("Noto Sans Anatolian Hieroglyphs");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansArmenian-VF.ttf")) {
+ familyName->set("Noto Sans Armenian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansAvestan-Regular.ttf")) {
+ familyName->set("Noto Sans Avestan");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBalinese-Regular.ttf")) {
+ familyName->set("Noto Sans Balinese");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBamum-Regular.ttf")) {
+ familyName->set("Noto Sans Bamum");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBassaVah-Regular.otf")) {
+ familyName->set("Noto Sans Bassa Vah");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBatak-Regular.ttf")) {
+ familyName->set("Noto Sans Batak");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBengaliUI-VF.ttf")) {
+ familyName->set("Noto Sans Bengali UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansBengali-VF.ttf")) {
+ familyName->set("Noto Sans Bengali");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansBhaiksuki-Regular.otf")) {
+ familyName->set("Noto Sans Bhaiksuki");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBrahmi-Regular.ttf")) {
+ familyName->set("Noto Sans Brahmi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBuginese-Regular.ttf")) {
+ familyName->set("Noto Sans Buginese");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansBuhid-Regular.ttf")) {
+ familyName->set("Noto Sans Buhid");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCanadianAboriginal-Regular.ttf")) {
+ familyName->set("Noto Sans Canadian Aboriginal");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCarian-Regular.ttf")) {
+ familyName->set("Noto Sans Carian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansChakma-Regular.otf")) {
+ familyName->set("Noto Sans Chakma");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCham-Bold.ttf")) {
+ familyName->set("Noto Sans Cham");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCham-Regular.ttf")) {
+ familyName->set("Noto Sans Cham");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCherokee-Regular.ttf")) {
+ familyName->set("Noto Sans Cherokee");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCJK-Regular.ttc")) {
+ familyName->set("Noto Sans CJK SC");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCoptic-Regular.ttf")) {
+ familyName->set("Noto Sans Coptic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCuneiform-Regular.ttf")) {
+ familyName->set("Noto Sans Cuneiform");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansCypriot-Regular.ttf")) {
+ familyName->set("Noto Sans Cypriot");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansDeseret-Regular.ttf")) {
+ familyName->set("Noto Sans Deseret");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansDevanagariUI-VF.ttf")) {
+ familyName->set("Noto Sans Devanagari UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansDevanagari-VF.ttf")) {
+ familyName->set("Noto Sans Devanagari");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansEgyptianHieroglyphs-Regular.ttf")) {
+ familyName->set("Noto Sans Egyptian Hieroglyphs");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansElbasan-Regular.otf")) {
+ familyName->set("Noto Sans Elbasan");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansEthiopic-VF.ttf")) {
+ familyName->set("Noto Sans Ethiopic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansGeorgian-VF.ttf")) {
+ familyName->set("Noto Sans Georgian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansGlagolitic-Regular.ttf")) {
+ familyName->set("Noto Sans Glagolitic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGothic-Regular.ttf")) {
+ familyName->set("Noto Sans Gothic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGrantha-Regular.ttf")) {
+ familyName->set("Noto Sans Grantha");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGujarati-Bold.ttf")) {
+ familyName->set("Noto Sans Gujarati");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGujarati-Regular.ttf")) {
+ familyName->set("Noto Sans Gujarati");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGujaratiUI-Bold.ttf")) {
+ familyName->set("Noto Sans Gujarati UI");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGujaratiUI-Regular.ttf")) {
+ familyName->set("Noto Sans Gujarati UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGunjalaGondi-Regular.otf")) {
+ familyName->set("Noto Sans Gunjala Gondi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansGurmukhiUI-VF.ttf")) {
+ familyName->set("Noto Sans Gurmukhi UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansGurmukhi-VF.ttf")) {
+ familyName->set("Noto Sans Gurmukhi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansHanifiRohingya-Regular.otf")) {
+ familyName->set("Noto Sans Hanifi Rohingya");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansHanunoo-Regular.ttf")) {
+ familyName->set("Noto Sans Hanunoo");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansHatran-Regular.otf")) {
+ familyName->set("Noto Sans Hatran");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansHebrew-Bold.ttf")) {
+ familyName->set("Noto Sans Hebrew");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansHebrew-Regular.ttf")) {
+ familyName->set("Noto Sans Hebrew");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansImperialAramaic-Regular.ttf")) {
+ familyName->set("Noto Sans Imperial Aramaic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansInscriptionalPahlavi-Regular.ttf")) {
+ familyName->set("Noto Sans Inscriptional Pahlavi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansInscriptionalParthian-Regular.ttf")) {
+ familyName->set("Noto Sans Inscriptional Parthian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansJavanese-Regular.otf")) {
+ familyName->set("Noto Sans Javanese");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansKaithi-Regular.ttf")) {
+ familyName->set("Noto Sans Kaithi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansKannadaUI-VF.ttf")) {
+ familyName->set("Noto Sans Kannada UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansKannada-VF.ttf")) {
+ familyName->set("Noto Sans Kannada");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansKayahLi-Regular.ttf")) {
+ familyName->set("Noto Sans Kayah Li");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansKharoshthi-Regular.ttf")) {
+ familyName->set("Noto Sans Kharoshthi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansKhmerUI-Bold.ttf")) {
+ familyName->set("Noto Sans Khmer UI");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansKhmerUI-Regular.ttf")) {
+ familyName->set("Noto Sans Khmer UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansKhmer-VF.ttf")) {
+ familyName->set("Noto Sans Khmer");
+ *style = SkFontStyle(90, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(2);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 26;
+ (*axes)[0].def = 90;
+ (*axes)[0].max = 190;
+ (*axes)[1].tag = SkSetFourByteTag('w', 'd', 't', 'h');
+ (*axes)[1].min = 70;
+ (*axes)[1].def = 100;
+ (*axes)[1].max = 100;
+ return true;
+ }
+ else if (file.equals("NotoSansKhojki-Regular.otf")) {
+ familyName->set("Noto Sans Khojki");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLao-Bold.ttf")) {
+ familyName->set("Noto Sans Lao");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLao-Regular.ttf")) {
+ familyName->set("Noto Sans Lao");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLaoUI-Bold.ttf")) {
+ familyName->set("Noto Sans Lao UI");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLaoUI-Regular.ttf")) {
+ familyName->set("Noto Sans Lao UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLepcha-Regular.ttf")) {
+ familyName->set("Noto Sans Lepcha");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLimbu-Regular.ttf")) {
+ familyName->set("Noto Sans Limbu");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLinearA-Regular.otf")) {
+ familyName->set("Noto Sans Linear A");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLinearB-Regular.ttf")) {
+ familyName->set("Noto Sans Linear B");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLisu-Regular.ttf")) {
+ familyName->set("Noto Sans Lisu");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLycian-Regular.ttf")) {
+ familyName->set("Noto Sans Lycian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansLydian-Regular.ttf")) {
+ familyName->set("Noto Sans Lydian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMalayalamUI-VF.ttf")) {
+ familyName->set("Noto Sans Malayalam UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansMalayalam-VF.ttf")) {
+ familyName->set("Noto Sans Malayalam");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansMandaic-Regular.ttf")) {
+ familyName->set("Noto Sans Mandaic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansManichaean-Regular.otf")) {
+ familyName->set("Noto Sans Manichaean");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMarchen-Regular.otf")) {
+ familyName->set("Noto Sans Marchen");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMasaramGondi-Regular.otf")) {
+ familyName->set("Noto Sans Masaram Gondi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMedefaidrin-VF.ttf")) {
+ familyName->set("Noto Sans Medefaidrin");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansMeeteiMayek-Regular.ttf")) {
+ familyName->set("Noto Sans Meetei Mayek");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMeroitic-Regular.otf")) {
+ familyName->set("Noto Sans Meroitic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMiao-Regular.otf")) {
+ familyName->set("Noto Sans Miao");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansModi-Regular.ttf")) {
+ familyName->set("Noto Sans Modi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMongolian-Regular.ttf")) {
+ familyName->set("Noto Sans Mongolian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMro-Regular.otf")) {
+ familyName->set("Noto Sans Mro");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMultani-Regular.otf")) {
+ familyName->set("Noto Sans Multani");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMyanmar-Bold.otf")) {
+ familyName->set("Noto Sans Myanmar");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMyanmar-Medium.otf")) {
+ familyName->set("Noto Sans Myanmar");
+ *style = SkFontStyle(500, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMyanmar-Regular.otf")) {
+ familyName->set("Noto Sans Myanmar");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMyanmarUI-Bold.otf")) {
+ familyName->set("Noto Sans Myanmar UI");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMyanmarUI-Medium.otf")) {
+ familyName->set("Noto Sans Myanmar UI");
+ *style = SkFontStyle(500, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansMyanmarUI-Regular.otf")) {
+ familyName->set("Noto Sans Myanmar UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansNabataean-Regular.otf")) {
+ familyName->set("Noto Sans Nabataean");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansNewa-Regular.otf")) {
+ familyName->set("Noto Sans Newa");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansNewTaiLue-Regular.ttf")) {
+ familyName->set("Noto Sans New Tai Lue");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansNKo-Regular.ttf")) {
+ familyName->set("Noto Sans NKo");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOgham-Regular.ttf")) {
+ familyName->set("Noto Sans Ogham");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOlChiki-Regular.ttf")) {
+ familyName->set("Noto Sans Ol Chiki");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOldItalic-Regular.ttf")) {
+ familyName->set("Noto Sans Old Italic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOldNorthArabian-Regular.otf")) {
+ familyName->set("Noto Sans Old North Arabian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOldPermic-Regular.otf")) {
+ familyName->set("Noto Sans Old Permic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOldPersian-Regular.ttf")) {
+ familyName->set("Noto Sans Old Persian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOldSouthArabian-Regular.ttf")) {
+ familyName->set("Noto Sans Old South Arabian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOldTurkic-Regular.ttf")) {
+ familyName->set("Noto Sans Old Turkic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOriya-Bold.ttf")) {
+ familyName->set("Noto Sans Oriya");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOriya-Regular.ttf")) {
+ familyName->set("Noto Sans Oriya");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOriyaUI-Bold.ttf")) {
+ familyName->set("Noto Sans Oriya UI");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOriyaUI-Regular.ttf")) {
+ familyName->set("Noto Sans Oriya UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOsage-Regular.ttf")) {
+ familyName->set("Noto Sans Osage");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansOsmanya-Regular.ttf")) {
+ familyName->set("Noto Sans Osmanya");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansPahawhHmong-Regular.otf")) {
+ familyName->set("Noto Sans Pahawh Hmong");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansPalmyrene-Regular.otf")) {
+ familyName->set("Noto Sans Palmyrene");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansPauCinHau-Regular.otf")) {
+ familyName->set("Noto Sans Pau Cin Hau");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansPhagsPa-Regular.ttf")) {
+ familyName->set("Noto Sans Phags Pa");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansPhoenician-Regular.ttf")) {
+ familyName->set("Noto Sans Phoenician");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansRejang-Regular.ttf")) {
+ familyName->set("Noto Sans Rejang");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansRunic-Regular.ttf")) {
+ familyName->set("Noto Sans Runic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSamaritan-Regular.ttf")) {
+ familyName->set("Noto Sans Samaritan");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSaurashtra-Regular.ttf")) {
+ familyName->set("Noto Sans Saurashtra");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSharada-Regular.otf")) {
+ familyName->set("Noto Sans Sharada");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansShavian-Regular.ttf")) {
+ familyName->set("Noto Sans Shavian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSinhalaUI-VF.ttf")) {
+ familyName->set("Noto Sans Sinhala UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansSinhala-VF.ttf")) {
+ familyName->set("Noto Sans Sinhala");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansSoraSompeng-Regular.otf")) {
+ familyName->set("Noto Sans Sora Sompeng");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSoyombo-VF.ttf")) {
+ familyName->set("Noto Sans Soyombo");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansSundanese-Regular.ttf")) {
+ familyName->set("Noto Sans Sundanese");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSylotiNagri-Regular.ttf")) {
+ familyName->set("Noto Sans Syloti Nagri");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSymbols-Regular-Subsetted.ttf")) {
+ familyName->set("Noto Sans Symbols");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSymbols-Regular-Subsetted2.ttf")) {
+ familyName->set("Noto Sans Symbols");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSyriacEastern-Regular.ttf")) {
+ familyName->set("Noto Sans Syriac Eastern");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSyriacEstrangela-Regular.ttf")) {
+ familyName->set("Noto Sans Syriac Estrangela");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansSyriacWestern-Regular.ttf")) {
+ familyName->set("Noto Sans Syriac Western");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansTagalog-Regular.ttf")) {
+ familyName->set("Noto Sans Tagalog");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansTagbanwa-Regular.ttf")) {
+ familyName->set("Noto Sans Tagbanwa");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansTaiLe-Regular.ttf")) {
+ familyName->set("Noto Sans Tai Le");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansTaiTham-Regular.ttf")) {
+ familyName->set("Noto Sans Tai Tham");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansTaiViet-Regular.ttf")) {
+ familyName->set("Noto Sans Tai Viet");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansTakri-VF.ttf")) {
+ familyName->set("Noto Sans Takri");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansTamilUI-VF.ttf")) {
+ familyName->set("Noto Sans Tamil");
+ *style = SkFontStyle(400, 2, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansTamil-VF.ttf")) {
+ familyName->set("Noto Sans Tamil");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansTeluguUI-VF.ttf")) {
+ familyName->set("Noto Sans Telugu UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansTelugu-VF.ttf")) {
+ familyName->set("Noto Sans Telugu");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSansThaana-Bold.ttf")) {
+ familyName->set("Noto Sans Thaana");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansThaana-Regular.ttf")) {
+ familyName->set("Noto Sans Thaana");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansThai-Bold.ttf")) {
+ familyName->set("Noto Sans Thai");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansThai-Regular.ttf")) {
+ familyName->set("Noto Sans Thai");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansThaiUI-Bold.ttf")) {
+ familyName->set("Noto Sans Thai UI");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansThaiUI-Regular.ttf")) {
+ familyName->set("Noto Sans Thai UI");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansTifinagh-Regular.otf")) {
+ familyName->set("Noto Sans Tifinagh");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansUgaritic-Regular.ttf")) {
+ familyName->set("Noto Sans Ugaritic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansVai-Regular.ttf")) {
+ familyName->set("Noto Sans Vai");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansWancho-Regular.otf")) {
+ familyName->set("Noto Sans Wancho");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansWarangCiti-Regular.otf")) {
+ familyName->set("Noto Sans Warang Citi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSansYi-Regular.ttf")) {
+ familyName->set("Noto Sans Yi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifArmenian-VF.ttf")) {
+ familyName->set("Noto Serif Armenian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifBengali-VF.ttf")) {
+ familyName->set("Noto Serif Bengali");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerif-Bold.ttf")) {
+ familyName->set("Noto Serif");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerif-BoldItalic.ttf")) {
+ familyName->set("Noto Serif");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifCJK-Regular.ttc")) {
+ familyName->set("Noto Serif CJK SC");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifDevanagari-VF.ttf")) {
+ familyName->set("Noto Serif Devanagari");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifDogra-Regular.ttf")) {
+ familyName->set("Noto Serif Dogra");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifEthiopic-VF.ttf")) {
+ familyName->set("Noto Serif Ethiopic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifGeorgian-VF.ttf")) {
+ familyName->set("Noto Serif Georgian");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifGujarati-VF.ttf")) {
+ familyName->set("Noto Serif Gujarati");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifGurmukhi-VF.ttf")) {
+ familyName->set("Noto Serif Gurmukhi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifHebrew-Bold.ttf")) {
+ familyName->set("Noto Serif Hebrew");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifHebrew-Regular.ttf")) {
+ familyName->set("Noto Serif Hebrew");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerif-Italic.ttf")) {
+ familyName->set("Noto Serif");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifKannada-VF.ttf")) {
+ familyName->set("Noto Serif Kannada");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifKhmer-Bold.otf")) {
+ familyName->set("Noto Serif Khmer");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifKhmer-Regular.otf")) {
+ familyName->set("Noto Serif Khmer");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifLao-Bold.ttf")) {
+ familyName->set("Noto Serif Lao");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifLao-Regular.ttf")) {
+ familyName->set("Noto Serif Lao");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifMalayalam-VF.ttf")) {
+ familyName->set("Noto Serif Malayalam");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifMyanmar-Bold.otf")) {
+ familyName->set("Noto Serif Myanmar");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifMyanmar-Regular.otf")) {
+ familyName->set("Noto Serif Myanmar");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifNyiakengPuachueHmong-VF.ttf")) {
+ familyName->set("Noto Serif Nyiakeng Puachue Hmong");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerif-Regular.ttf")) {
+ familyName->set("Noto Serif");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifSinhala-VF.ttf")) {
+ familyName->set("Noto Serif Sinhala");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifTamil-VF.ttf")) {
+ familyName->set("Noto Serif Tamil");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifTelugu-VF.ttf")) {
+ familyName->set("Noto Serif Telugu");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifThai-Bold.ttf")) {
+ familyName->set("Noto Serif Thai");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifThai-Regular.ttf")) {
+ familyName->set("Noto Serif Thai");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("NotoSerifTibetan-VF.ttf")) {
+ familyName->set("Noto Serif Tibetan");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("NotoSerifYezidi-VF.ttf")) {
+ familyName->set("Noto Serif Yezidi");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(1);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 400;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 700;
+ return true;
+ }
+ else if (file.equals("Roboto-Regular.ttf")) {
+ familyName->set("Roboto");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(3);
+ (*axes)[0].tag = SkSetFourByteTag('w', 'g', 'h', 't');;
+ (*axes)[0].min = 100;
+ (*axes)[0].def = 400;
+ (*axes)[0].max = 900;
+ (*axes)[1].tag = SkSetFourByteTag('w', 'd', 't', 'h');
+ (*axes)[1].min = 75;
+ (*axes)[1].def = 100;
+ (*axes)[1].max = 100;
+ (*axes)[2].tag = SkSetFourByteTag('i', 't', 'a', 'l');
+ (*axes)[2].min = 0;
+ (*axes)[2].def = 0;
+ (*axes)[2].max = 1;
+ return true;
+ }
+ else if (file.equals("RobotoStatic-Regular.ttf")) {
+ // see https://android.googlesource.com/platform/frameworks/base/+/89abe560d722a6f4136b7a05d80f23b269413aad
+ familyName->set("RobotoStatic");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("SourceSansPro-Bold.ttf")) {
+ familyName->set("Source Sans Pro");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("SourceSansPro-BoldItalic.ttf")) {
+ familyName->set("Source Sans Pro");
+ *style = SkFontStyle(700, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("SourceSansPro-Italic.ttf")) {
+ familyName->set("Source Sans Pro");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("SourceSansPro-Regular.ttf")) {
+ familyName->set("Source Sans Pro");
+ *style = SkFontStyle(400, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("SourceSansPro-SemiBold.ttf")) {
+ familyName->set("Source Sans Pro");
+ *style = SkFontStyle(600, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+ else if (file.equals("SourceSansPro-SemiBoldItalic.ttf")) {
+ familyName->set("Source Sans Pro");
+ *style = SkFontStyle(600, 5, SkFontStyle::kUpright_Slant);
+ *isFixedPitch = false;
+ axes->reset(0);
+ return true;
+ }
+
+ return false;
+}
diff --git a/third_party/skia/src/ports/SkFontMgr_android_ndk.cpp b/third_party/skia/src/ports/SkFontMgr_android_ndk.cpp
--- a/third_party/skia/src/ports/SkFontMgr_android_ndk.cpp
+++ b/third_party/skia/src/ports/SkFontMgr_android_ndk.cpp
@@ -996,7 +996,7 @@ public:
}
std::vector<std::unique_ptr<FontFamily>> xmlFamilies;
- SkFontMgr_Android_Parser::GetSystemFontFamilies(xmlFamilies);
+ SkFontMgr_Android_Parser::GetSystemFontFamilies(xmlFamilies, /*custom*/ nullptr);
skia_private::THashMap<SkString, std::unique_ptr<SkStreamAsset>> streamForPath;
diff --git a/third_party/skia/src/ports/SkFontMgr_android_parser.cpp b/third_party/skia/src/ports/SkFontMgr_android_parser.cpp
--- a/third_party/skia/src/ports/SkFontMgr_android_parser.cpp
+++ b/third_party/skia/src/ports/SkFontMgr_android_parser.cpp
@@ -713,14 +713,27 @@ static const XML_Memory_Handling_Suite sk_XML_alloc = {
*/
static int parse_config_file(const char* filename,
std::vector<std::unique_ptr<FontFamily>>& families,
- const SkString& basePath, bool isFallback)
+ const SkString& basePath, bool isFallback,
+ const SkFontMgr_Android_CustomFonts* custom = nullptr)
{
SkFILEStream file(filename);
-
- // Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml)
- // are optional - failure here is okay because one of these optional files may not exist.
- if (!file.isValid()) {
- SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' could not be opened\n", filename);
+ std::unique_ptr<SkStreamAsset> stream;
+ if (!custom && filename[0] != '#') {
+ // Some of the files we attempt to parse (in particular, /vendor/etc/fallback_fonts.xml)
+ // are optional - failure here is okay because one of these optional files may not exist.
+ if (!file.isValid()) {
+ SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' could not be opened\n", filename);
+ return -1;
+ }
+ stream = file.fork();
+ } else if (custom) {
+ stream = custom->getPlatformFile(filename);
+ if (!stream) {
+ SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' platform file map not found\n", filename);
+ return -1;
+ }
+ } else {
+ SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "'%s' custom fonts not set\n", filename);
return -1;
}
@@ -752,8 +765,8 @@ static int parse_config_file(const char* filename,
SkDebugf(SK_FONTMGR_ANDROID_PARSER_PREFIX "could not buffer enough to continue\n");
return -1;
}
- size_t len = file.read(buffer, bufferSize);
- done = file.isAtEnd();
+ size_t len = stream->read(buffer, bufferSize);
+ done = stream->isAtEnd();
XML_Status status = XML_ParseBuffer(parser, len, done);
if (XML_STATUS_ERROR == status) {
XML_Error error = XML_GetErrorCode(parser);
@@ -765,6 +778,23 @@ static int parse_config_file(const char* filename,
return -1;
}
}
+ if (custom) {
+ // remove NotoColorEmojiLegacy.ttf
+ for (int i = 0; i < families.size(); ++i) {
+ bool exists = false;
+ auto& family = families[i];
+ for (auto& font : family->fFonts) {
+ if (font.fFileName.equals("NotoColorEmojiLegacy.ttf")) {
+ exists = true;
+ break;
+ }
+ }
+ if (exists) {
+ families.erase(families.begin() + i);
+ break;
+ }
+ }
+ }
return self.fVersion;
}
@@ -827,8 +857,10 @@ static void append_fallback_font_families_for_locale(
static void append_system_fallback_font_families(
std::vector<std::unique_ptr<FontFamily>>& fallbackFonts,
- const SkString& basePath)
+ const SkString& basePath,
+ const SkFontMgr_Android_CustomFonts* custom)
{
+ if (custom) return;
parse_config_file(FALLBACK_FONTS_FILE, fallbackFonts, basePath, true);
append_fallback_font_families_for_locale(fallbackFonts,
LOCALE_FALLBACK_FONTS_SYSTEM_DIR,
@@ -837,8 +869,10 @@ static void append_system_fallback_font_families(
static void mixin_vendor_fallback_font_families(
std::vector<std::unique_ptr<FontFamily>>& fallbackFonts,
- const SkString& basePath)
+ const SkString& basePath,
+ const SkFontMgr_Android_CustomFonts* custom)
{
+ if (custom) return;
std::vector<std::unique_ptr<FontFamily>> vendorFonts;
parse_config_file(VENDOR_FONTS_FILE, vendorFonts, basePath, true);
append_fallback_font_families_for_locale(vendorFonts,
@@ -870,7 +904,8 @@ static void mixin_vendor_fallback_font_families(
}
void SkFontMgr_Android_Parser::GetSystemFontFamilies(
- std::vector<std::unique_ptr<FontFamily>>& fontFamilies) {
+ std::vector<std::unique_ptr<FontFamily>>& fontFamilies,
+ const SkFontMgr_Android_CustomFonts* custom) {
static constexpr char kFontFilePrefix[] = "/fonts/";
// Version 21 of the system font configuration does not need any fallback configuration files.
@@ -881,15 +916,16 @@ void SkFontMgr_Android_Parser::GetSystemFontFamilies(
// Product fonts (fonts_customization.xml) leverage <fonts-modification version="21">
// Therefore, we only attempt to parse them on modern devices (Android Lollipop+).
// Pre-21 systems fall through to the legacy fallback fonts handling below.
+ if (!custom)
SkFontMgr_Android_Parser::GetCustomFontFamilies(
- fontFamilies, basePath, PRODUCT_CUSTOMIZATION_FILE, nullptr, nullptr);
+ fontFamilies, basePath, custom, PRODUCT_CUSTOMIZATION_FILE, nullptr, nullptr);
return;
}
// Append all the fallback fonts to system fonts
std::vector<std::unique_ptr<FontFamily>> fallbackFonts;
- append_system_fallback_font_families(fallbackFonts, basePath);
- mixin_vendor_fallback_font_families(fallbackFonts, basePath);
+ append_system_fallback_font_families(fallbackFonts, basePath, custom);
+ mixin_vendor_fallback_font_families(fallbackFonts, basePath, custom);
fontFamilies.insert(fontFamilies.end(),
std::make_move_iterator(fallbackFonts.begin()),
std::make_move_iterator(fallbackFonts.end()));
@@ -898,15 +934,16 @@ void SkFontMgr_Android_Parser::GetSystemFontFamilies(
void SkFontMgr_Android_Parser::GetCustomFontFamilies(
std::vector<std::unique_ptr<FontFamily>>& fontFamilies,
const SkString& basePath,
+ const SkFontMgr_Android_CustomFonts* custom,
const char* fontsXml,
const char* fallbackFontsXml,
const char* langFallbackFontsDir)
{
if (fontsXml) {
- parse_config_file(fontsXml, fontFamilies, basePath, false);
+ parse_config_file(fontsXml, fontFamilies, basePath, false, custom);
}
if (fallbackFontsXml) {
- parse_config_file(fallbackFontsXml, fontFamilies, basePath, true);
+ parse_config_file(fallbackFontsXml, fontFamilies, basePath, true, custom);
}
if (langFallbackFontsDir) {
append_fallback_font_families_for_locale(fontFamilies,
diff --git a/third_party/skia/src/ports/SkFontMgr_android_parser.h b/third_party/skia/src/ports/SkFontMgr_android_parser.h
--- a/third_party/skia/src/ports/SkFontMgr_android_parser.h
+++ b/third_party/skia/src/ports/SkFontMgr_android_parser.h
@@ -17,6 +17,7 @@
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTDArray.h"
#include "src/core/SkTHash.h"
+#include "include/ports/SkFontMgr_android.h"
#include <climits>
#include <limits>
@@ -109,11 +110,13 @@ struct FontFamily {
namespace SkFontMgr_Android_Parser {
/** Parses system font configuration files and appends result to fontFamilies. */
-void GetSystemFontFamilies(std::vector<std::unique_ptr<FontFamily>>& fontFamilies);
+void GetSystemFontFamilies(std::vector<std::unique_ptr<FontFamily>>& fontFamilies,
+ const SkFontMgr_Android_CustomFonts* custom);
/** Parses font configuration files and appends result to fontFamilies. */
void GetCustomFontFamilies(std::vector<std::unique_ptr<FontFamily>>& fontFamilies,
const SkString& basePath,
+ const SkFontMgr_Android_CustomFonts* custom,
const char* fontsXml,
const char* fallbackFontsXml,
const char* langFallbackFontsDir = nullptr);
--