實作自訂字型

從 Android 15 開始,可變字型會在執行階段算繪,提供更高的效率和精細程度。本次更新中,由於 fonts.xml 即將淘汰,因此廠商必須將新的變數字型設定新增至 font_fallback.xml,而非 fonts.xml。詳情請參閱「支援可變字體」。

在 Android 11 以下版本中,如要更新 Android 開放原始碼計畫中裝置上安裝的裝置字型檔案 (位於 /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. 取代或修改其他字型檔案。

如果不是在 Android 開放原始碼計畫中修改表情符號字型,則無需採取任何行動。如要自訂表情符號字型,請按照下列各節中的操作說明進行。

將 NotoColorEmoji.ttf 替換為原始設備製造商 (OEM) 品牌的表情符號字型

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

  1. /system 分區中放置您自己的字型,名稱為 OEMCustomEmoji.ttf
  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 檔案的做法類似,可滿足當地市場需求。如果 Android 開放原始碼計畫在執行階段更新的不明字型檔案,系統會忽略且不會更新。Google 會忽略裝置上的不明字型。包括透過 Android 開放原始碼計畫的原始字型修改的字型檔案。

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

符合先決條件

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

簽署字型檔案

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

進行執行階段字型更新

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

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