實作自訂字型

從 Android 15 開始,系統會在執行階段以更高的效率和精細度算繪可變字型。本次更新後,供應商必須將新的可變字型設定新增至 font_fallback.xml,而非 fonts.xml,因為 fonts.xml 即將淘汰。詳情請參閱「支援可變字型」。

在 Android 11 以下版本中,如要更新 AOSP (位於 /system/fonts 分區) 或供應商分區 (位於 /product/fonts/system/fonts 分區) 中裝置安裝的字型檔案,必須由原始設備製造商 (OEM) 提供系統更新。這項規定對表情符號的相容性有重大影響。在 Android 12 中,您可以使用 FontManager 系統服務管理已安裝的字型檔案,並更新裝置上安裝的字型檔案,不必更新系統。

Android 12 提供三種程序互動方式:FontManagerServiceFont UpdaterApplication

FontManagerService 是系統伺服器中的中央管理系統。 FontManagerService 會儲存最新的使用者系統字型設定。

FontUpdater 是可外掛的字型更新程式,受到 signature|privileged 權限檢查信任。FontUpdater 會與 FontManagerService 通訊,以取得、安裝、移除或更新目前的系統字型設定。FontUpdater 可以透過程序間通訊 (IPC) 機制傳遞新的字型檔案內容。FontManagerService 會將內容儲存至可供全域讀取的儲存位置,例如 /data/fonts 檔案。這個儲存空間受到保護。只有 FontManagerService 可以寫入,SELinux 政策也可以寫入。

Application 類別啟動時,會將系統字型設定做為 bindApplication 方法的引數傳遞,然後初始化字型設定,供應用程式程序使用。

支援變數字型

從 Android 15 開始,變數字型設定會以以下格式在 font_fallback.xml 中指定:

<family lang="und-Ethi" supportedAxes="wght,ital">
    <font>NotoSansEthiopic-VF.ttf</font>
</family>

在這個格式中,可變字型具有靜態字型的所有屬性,以及額外的 supportedAxes 屬性。supportedAxes 屬性是以半形逗號分隔的支援軸標記清單。在 Android 15 中,只能指定 wghtital 軸。

如果未指定 supportedAxes 屬性,font 節點會做為靜態字型,也就是以 axis 子項指定的單一可變字型例項。

如果指定 supportedAxes 屬性,系統會在執行階段動態建立指定權重和樣式值的字型例項。

開發人員可以使用 android.graphics.fonts.SystemFonts#getAvailableFonts Java API 或 ASystemFontIterator_open NDK API,取得系統安裝的字型檔案清單。如要瞭解支援這項更新的開發人員 API,請參閱「改良的 OpenType 變數字型 API」和 buildVariableFamily

自訂字型

部分原始設備製造商 (OEM) 會在 Android 開放原始碼計畫 (AOSP) 中安裝或替換字型檔案,以顯示自家品牌。 Android 12 支援這項功能,但新增了在裝置中更新表情符號字型的規定。如果 OEM 未修改或更新表情符號字型檔案,就不需要使用這項功能。

Google 會透過 GMS Core 更新字型檔案,尤其是 NotoColorEmoji 檔案,因此請勿修改或移除 /system 分割區中的 NotoColorEmoji.ttf 檔案,也不要從 /frameworks/base/data/fonts/fonts.xml 中移除該檔案。請注意,你可以透過下列三種方式自訂字型:

  1. NotoColorEmoji.ttf 檔案替換為 OEM 品牌的表情符號字型。
  2. 根據當地市場需求修改 NotoColorEmoji.ttf 檔案。
  3. 取代或修改其他字型檔案。

如果您未在 AOSP 中修改表情符號字型,則不必採取任何行動。如要自訂表情符號字型,請按照下列章節的說明操作。

將 NotoColorEmoji.ttf 換成 OEM 品牌的表情符號字型

如要以 OEM 品牌的表情符號字型檔案取代 NotoColorEmoji.ttf 檔案,請將表情符號字型放在字型備援鏈之前:

  1. 將您自己的字型 (名為 OEMCustomEmoji.ttf) 放在 /system 分割區中。
  2. 按照下列程式碼修改 /frameworks/base/data/fonts/fonts.xml (以及 Android 15 以上版本的 /frameworks/base/data/fonts/font-fallback.xml):

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

根據當地市場需求修改 NotoColorEmoji.ttf

如要根據當地市場需求進行自訂,請按照下列步驟操作:

  1. 建立自己的 NotoColorEmoji 檔案,並使用其他名稱,例如 Modified\_NotoColorEmoji.ttf
  2. 將其放在原始 NotoColorEmoji.ttf 檔案之前。

執行步驟 2 後,系統會顯示 Modified\NotoColorEmoji.ttf 支援的修改字形,而非原始字形 NotoColorEmoji.ttf。Google 建議採取以下做法:

  • 這個字型只包含必要的字形。
  • 將未修改的字形委派給原始 NotoColorEmoji.ttf 檔案,這樣裝置就能接收日後發布的表情符號設計修正。

移除字形:如要從 NotoColorEmoji.ttf 檔案移除字形,請按照步驟 1 和 2 操作,並在 cmap 中指定 glyph ID = 0

使用區域旗幟:如果目標字形是區域旗幟,請將字形 ID 指定為不明國家/地區代碼。(使用 country code = "ZZ"。)

製作豆腐字元:如要使用豆腐字元,可以明確指定豆腐字元 ID。指定 glyphID = 0 時,相關應用程式會將其解讀為「字形無法使用」。舉例來說,使用這項屬性時,Paint#hasGlyph 應用程式會傳回 false

取代或修改其他字型檔案

如要替換或修改其他字型,自訂方式與修改當地市場需求的 TTF 檔案類似。系統會忽略在執行階段更新的 AOSP 不明字型檔案,且不會更新這些檔案。Google 會忽略裝置中的不明字型。包括從 Android 開放原始碼計畫的原始字型修改而來的字型檔案。

雖然字型更新是由 GMS Core 中的 Google 完成,但一般字型更新機制對所有原始設備製造商 (OEM) 開放。原始設備製造商 (OEM) 可以按照「符合必要條件」、「簽署字型檔案」和「在執行階段更新字型」一節中的步驟,安裝其他字型更新程式。

符合必要條件

字型更新機制會使用 fs-verity Linux 核心功能。確認裝置fs-verity符合規定,並在裝置中加入憑證。

簽署字型檔案

由於字型檔案是危險資源,因此必須使用信任的金鑰進行驗證。請仔細檢查所有要更新的字型檔案,然後使用私密金鑰簽署。簽章必須fs-verity相容。

更新執行階段字型

FontManager 系統應用程式會執行字型更新。「FontManager」應用程式會提供最新安裝的系統字型狀態,並可更新附有簽章的字型檔案。如要呼叫更新應用程式,請將 UPDATE_FONT signature|privileged 權限新增至應用程式許可清單資訊清單

UPDATE_FONT signature|privileged 權限提供給應用程式的更新程式函式。