不自行繪製文字,而是交給平台處理的理由
你是否曾遇過韓文字看起來很正常,只有漢字莫名顯得陌生?當我們決定不親自繪製文字,而是交給平台的文字引擎時,我們的工作就不再是「要畫什麼」,而是「該要求使用哪種字型」。

文字要顯示在畫面上,需要經過許多處理。必須將字元轉換成形狀、進行換行,再繪製成像素。從韓文字組合到漢字、表情符號、阿拉伯文字,以及字型回退,全都必須處理。
我們沒有重新打造這套流程。我們把它交給了 Linux 的 Pango 與 HarfBuzz、Windows 的 DirectWrite,以及 macOS 的 TextKit 2。
因為這是作業系統長期以來持續打磨的領域。若由我們自行打造,在 CJK 字元或無障礙功能等棘手之處,品質反而很可能變差。我們也認為,產品的差異化並不在於渲染器本身,而在於排版與符合各平台習慣的使用體驗。
不過,何時建立則由我們決定
建立文字版面配置需要時間與記憶體。大型文件可能有數萬行,因此無法全部建立。
所以,我們只建立畫面上可見的行及其周邊內容。離開畫面較遠的行則立即丟棄。即使長時間捲動一份 1MB 的文件,仍然存活的版面配置也只有大約四十到六十個。
尚未建立的行會先預估高度。因為捲軸必須知道整份文件的總長度。
當然,預估有時也會出錯。若重新計算出的高度與預期不同,畫面就可能位移。這時會在同一影格內,依照差值修正捲動位置。在使用者眼中,應該像什麼事都沒發生一樣。
正在組合韓文字的行會不加任何樣式地繪製。因為如果輸入過程中插入粗體或隱藏等屬性,輸入法所知道的字元數可能會與畫面上的字元數不同。
最先遇到的問題,是漢字的面貌
交給平台處理,也就會連平台的預設值一起採用。
Ubuntu 的預設 UI 字型不包含韓文字。因此,系統改為選用的字型是 Noto Sans CJK JP。韓文字顯示正常,但部分漢字卻以日式字形呈現。這是因為即使是相同的 Unicode 字元,在韓國與日本也可能有不同的字形。
解決方法很簡單。我們在 UI 字型清單中把 Noto Sans CJK KR 放到前面。
但另有一點更為重要。如果我們不制定標準,平台就會以自身的預設值,而不是使用者的語言來作答。
透過字型順序呈現各語言的字形
字型堆疊會從前往後尋找字元。只有第一個字型中不存在的字元,才會交給下一個字型。
利用這項特性,就能讓英文以襯線體顯示、韓文字以無襯線體顯示。只需一行設定,即可為不同語言搭配合適的字型。
如果閱讀字型留空,就會直接使用內文字型。若另外指定,則只會在閱讀模式下變更。原始碼模式則使用程式碼字型。
字體大小會遵循作業系統的無障礙設定。在系統中放大文字的使用者,不需要在每個應用程式裡重新設定。

螢幕閱讀器也會利用相同的基礎。平台的文字層級已經連接無障礙功能,因此我們只需準確傳遞系統所要求之行的內容即可。
缺少翻譯時,建置就會失敗
UI 句子以英文撰寫,並將該句子用作翻譯表的鍵。如果沒有翻譯,畫面上就會直接顯示英文。
問題在於它不會發生錯誤。即使缺少翻譯,英文也只會悄悄混入其中。
因此,我們製作了檢查指令碼。它會收集程式碼中實際使用的句子,並與 12 種語言的翻譯表進行比較。如果只在某一種語言中新增句子,或漏掉翻譯,建置就會失敗。
每份翻譯表有 304 個鍵,程式碼中實際使用的句子則有 282 個。支援的語言包括 English、한국어、日本語、简体中文、繁體中文、Deutsch、Français、Español、Português (Brasil)、Русский、Italiano、Polski。

切換語言時,會以同一份文件開啟新視窗,再關閉原有視窗。如果逐一翻譯已經顯示的數百個小工具,很可能有所遺漏。我們判斷,與其維護一條幾乎不會使用的複雜路徑,不如在切換語言的瞬間重新開啟一次視窗,會更加安全。
交給平台處理,結果也會帶有平台的樣貌
即使是同一份文件,在不同作業系統上的像素也不會完全相同。因為文字的修飾方式與預設字型各不相同。
我們不會勉強讓它們變得一致。取而代之的是,維持字體大小比例、行高與留白等文件基準的一致性。
字型回退的結果也可能因已安裝的字型而異。因此,我們不承諾特定結果,而是公開顯示字型的請求順序。使用者也可以自行變更。
不親自繪製,並不代表責任也隨之消失。我們反而必須更精確地決定要委託哪些工作,以及應以何種順序提出要求。