給原生 Android 加入 Noto Sans CJK 全套字重 (已過時)

Toby Tso
汚音屋 × UJAM
Published in
14 min readJul 19, 2016

--

此方法需要 root 目錄讀寫權限.

適用於 Android Lollipop, Android Marshmallow.

適用於 Android Nougat, 但 Android Nougat 上有更好的方法實現.

Google 自 Android 5.0 Lollipop 起為 CJK 語言 (Chinese, Japanese, Korean) 啟用 Noto Sans CJK (思源黑體) 作為顯示字型. Noto Sans CJK 較以前的 Android 中文字型 Droid Sans Fallback 而言, 解決了不同地區的漢字書寫方式問題. 這是很大的一個進步, 然而, 不曉得 Google 是處於怎樣的考量 (估計是出於體積大小考量), 僅在 Android 上內建了 NotoSansJP-Regular, NotoSansKR-Regular, NotoSansSC-Regular, NotoSansTC-Regular 字型, 也就是說, JP (日文), KR (韓文), SC (簡體中文), TC (繁/正體中文) 四種語言都只有 Regular 一個字重. 這就導致了系統全局預設下的 CJK 字符都只能顯示為 Regular 字重, 因為沒有其它字重可用.

本文主要的目的就是詳細介紹如何為你的 Android 加入缺失的 Noto Sans CJK 全套字重.

文中涉及編輯設定檔的操作, 你可以先將設定檔導到電腦上 (方法請自尋), 用電腦編輯完成後再進行原文件覆寫. 使用帶有語法高亮的編輯器對設定檔進行修改可以最大程度地減少由於「看走眼」等失誤造成的毀滅性損失.

需要改動的目錄或檔案

  • /system/fonts
  • /system/etc/fallback_fonts.xml
  • /system/etc/fonts.xml

具體操作及原理解釋

加入字型檔

首先我們需要把缺失字重的字型檔下載下來. 你可以在 googlei18n/noto-cjk 這個 GitHub Repository 下找到. 由於 Android 預設內建的 Noto Sans CJK 都是 Region specific OTF subsets 版本的, 因此此處我們也同樣採用 Region specific OTF subsets 版本的字型檔.

如果你不曉得 googlei18n/noto-cjk 下哪些是 Region specific OTF subsets 版本的字型, 請參閱 Google 的 Noto Sans CJK GitHub Repository 裡面都是三洨? 這篇文章.

如果你不曉得如何從 GitHub Repository 中下載你想要的檔案, 請參閱如何從GitHub下載檔案? / How to Download Files in GitHub? 這篇文章.

下載完成後, 應是如下的這些字型檔 , 一共 28 個:

NotoSansJP-Black.otf
NotoSansJP-Bold.otf
NotoSansJP-DemiLight.otf
NotoSansJP-Light.otf
NotoSansJP-Medium.otf
NotoSansJP-Regular.otf
NotoSansJP-Thin.otf

NotoSansKR-Black.otf
NotoSansKR-Bold.otf
NotoSansKR-DemiLight.otf
NotoSansKR-Light.otf
NotoSansKR-Medium.otf
NotoSansKR-Regular.otf
NotoSansKR-Thin.otf

NotoSansSC-Black.otf
NotoSansSC-Bold.otf
NotoSansSC-DemiLight.otf
NotoSansSC-Light.otf
NotoSansSC-Medium.otf
NotoSansSC-Regular.otf
NotoSansSC-Thin.otf

NotoSansTC-Black.otf
NotoSansTC-Bold.otf
NotoSansTC-DemiLight.otf
NotoSansTC-Light.otf
NotoSansTC-Medium.otf
NotoSansTC-Regular.otf
NotoSansTC-Thin.otf

/system/fonts 是 Android 存放字型檔的目錄. 我們把剛剛下載的 24 個字型檔全部放入到這個目錄下. 請不要破壞上面所示的命名規則!

調整字型設定檔

/system/etc/fallback_fonts.xml/system/etc/fonts.xml 是 Android 的字型設定檔, 我們接下來需要調整這兩個設定檔來使剛剛加入的字型檔得以被 Android 正確地調用.

我們從 /system/etc/fallback_fonts.xml 開始.

我們需要調整的地方在這個設定檔的末尾, 含有 lang=”zh-Hans”, lang=”zh-Hant”, lang=”ja”, lang=”ko” 的那幾行:

<family>
<fileset>
<file lang="zh-Hans">NotoSansSC-Regular.otf</file>
</fileset>
</family>
<family>
<fileset>
<file lang="zh-Hant">NotoSansTC-Regular.otf</file>
</fileset>
</family>
<family>
<fileset>
<file lang="ja">NotoSansJP-Regular.otf</file>
</fileset>
</family>
<family>
<fileset>
<file lang="ko">NotoSansKR-Regular.otf</file>
</fileset>
</family>

我們只需在每個 Regular 的指定語句下面加一行 Bold 的指定語句就行. 因為 /system/etc/fallback_fonts.xml 是已經過時的字型設定檔, 僅為 SDK 版本很低的 app 而留. 它只支援調用 regular, bold, italicbold-italic 四個字重. 我們只能捨去 Noto Sans CJK 剩下的幾個字重. 而 Noto Sans CJK 沒有原生的 Italic 字重, 因此我們只能指定 RegularBold 兩個字重.

修改後的代碼如下:

<family>
<fileset>
<file lang="zh-Hant">NotoSansTC-Regular.otf</file>
<file lang="zh-Hant">NotoSansTC-Bold.otf</file>
</fileset>
</family>
<family>
<fileset>
<file lang="zh-Hans">NotoSansSC-Regular.otf</file>
<file lang="zh-Hans">NotoSansSC-Bold.otf</file>
</fileset>
</family>
<family>
<fileset>
<file lang="ja">NotoSansJP-Regular.otf</file>
<file lang="ja">NotoSansJP-Bold.otf</file>
</fileset>
</family>
<family>
<fileset>
<file lang="ko">NotoSansKR-Regular.otf</file>
<file lang="ko">NotoSansKR-Bold.otf</file>
</fileset>
</family>

你可能注意到我將 zh-Hans (簡體中文) 和 zh-Hant (繁/正體中文) 兩種語言的順序調換過來了. 這是為了方便將系統語言設為英文的台灣使用者們. 這樣一來, 當在使用不支援同時設定多種語言 (我之所以要這樣描述, 是因為 Android 7.0 Nougat 已經支援該特性) 的 Android 6.x Marshmallow 英文版需要顯示漢字時, 會首選 NotoSansTC (繁/正體中文版思源黑體) 而不是 NotoSansSC (簡體中文版思源黑體). NotoSansSC 同時支援符合中國大陸 GB18030 標準的簡繁漢字, 若將 NotoSansSC 排列在前, 台灣的英文系統環境使用者將會得到很不舒服和反習慣的漢字視覺體驗.

如果你希望在英文環境下得到中國大陸 GB18030 標準的漢字 (涵蓋簡/繁漢字) 體驗, 將

<file lang="zh-Hant">NotoSansTC-Regular.otf</file>
<file lang="zh-Hant">NotoSansTC-Bold.otf</file>

<file lang="zh-Hans">NotoSansSC-Regular.otf</file>
<file lang="zh-Hans">NotoSansSC-Bold.otf</file>

的順序調換回去即可.

/system/etc/fonts.xml 是 Android 5.0 Lollipop 開始加入的新版字型設定檔. 相比已經過時的 /system/etc/fallback_fonts.xml, 你可以在這個設定檔中指定更多字重, 且支援命名空間.

我們需要調整的地方同樣在這個設定檔的末尾, 含有 lang=”zh-Hans”, lang=”zh-Hant”, lang=”ja”, lang=”ko” 的那幾行:

<family lang="zh-Hans">
<font weight="400" style="normal">NotoSansSC-Regular.otf</font>
</family>
<family lang="zh-Hant">
<font weight="400" style="normal">NotoSansTC-Regular.otf</font>
</family>
<family lang="ja">
<font weight="400" style="normal">NotoSansJP-Regular.otf</font>
</family>
<family lang="ko">
<font weight="400" style="normal">NotoSansKR-Regular.otf</font>
</family>

參照 Google Fonts: Early AccessNotoSansTCCSS 定義Source Han Sans 與 Noto Sans CJK 之字重對應這篇文章, 我們的調整如下:

<family lang="zh-Hant">
<font weight="100" style="normal">NotoSansTC-Thin.otf</font>
<font weight="300" style="normal">NotoSansTC-Light.otf</font>
<font weight="350" style="normal">NotoSansTC-DemiLight.otf</font>
<font weight="400" style="normal">NotoSansTC-Regular.otf</font>
<font weight="500" style="normal">NotoSansTC-Medium.otf</font>
<font weight="900" style="normal">NotoSansTC-Black.otf</font>
<font weight="700" style="normal">NotoSansTC-Bold.otf</font>
</family>
<family lang="zh-Hans">
<font weight="100" style="normal">NotoSansSC-Thin.otf</font>
<font weight="300" style="normal">NotoSansSC-Light.otf</font>
<font weight="350" style="normal">NotoSansSC-DemiLight.otf</font>
<font weight="400" style="normal">NotoSansSC-Regular.otf</font>
<font weight="500" style="normal">NotoSansSC-Medium.otf</font>
<font weight="900" style="normal">NotoSansSC-Black.otf</font>
<font weight="700" style="normal">NotoSansSC-Bold.otf</font>
</family>
<family lang="ja">
<font weight="100" style="normal">NotoSansJP-Thin.otf</font>
<font weight="300" style="normal">NotoSansJP-Light.otf</font>
<font weight="350" style="normal">NotoSansJP-DemiLight.otf</font>
<font weight="400" style="normal">NotoSansJP-Regular.otf</font>
<font weight="500" style="normal">NotoSansJP-Medium.otf</font>
<font weight="900" style="normal">NotoSansJP-Black.otf</font>
<font weight="700" style="normal">NotoSansJP-Bold.otf</font>
</family>
<family lang="ko">
<font weight="100" style="normal">NotoSansKR-Thin.otf</font>
<font weight="300" style="normal">NotoSansKR-Light.otf</font>
<font weight="350" style="normal">NotoSansKR-DemiLight.otf</font>
<font weight="400" style="normal">NotoSansKR-Regular.otf</font>
<font weight="500" style="normal">NotoSansKR-Medium.otf</font>
<font weight="900" style="normal">NotoSansKR-Black.otf</font>
<font weight="700" style="normal">NotoSansKR-Bold.otf</font>
</family>

同樣調換了 zh-Hanszh-Hant 兩種語言的順序, 理由同上, 有需要的話可以自行將順序調換回去.

至於為何要將 font weight=“900” 寫在 font weight=“700” 之前, 這是因為 /system/etc/fonts.xml 內的先後順序決定了字重的匹配. Noto Sans CJK 沒有 font weight=“800” 的字重, 當程式或網頁要求 font weight=“800” 的時候, 系統可以匹配到效果更好的 font weight=“900” (Black).

至此, 設定檔的調整已經完成, 你要做的最後一步則是重啟你的裝置. 重啟之後, 打開 Play Store 的應用詳情頁, 你可以看到非常明顯的效果.

--

--