實作自訂字型

自 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) 會在 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) 品牌的表情符號字型

如要將 NotoColorEmoji.ttf 檔案替換為 OEM 品牌表情符號字型檔案,請將表情符號字型放在字型備用鏈結之前:

  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 會忽略裝置中的不明字型。包括從 AOSP 原始字型修改而來的字型檔案。

雖然 Google 會在 GMS Core 中執行字型更新,但一般字型更新機制對所有原始設備製造商 (OEM) 皆開放。原始設備製造商 (OEM) 可以按照「符合先決條件」、「簽署字型檔案」和「執行時字型更新」中的步驟,安裝其他字型更新器。

符合先決條件

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

簽署字型檔案

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

進行執行階段字型更新

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

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