Ubuntu コンテナの日本語フォントをデスクトップ版と合わせる

コンテナー版の Ubuntu は日本語フォントのデフォルトが通常の日本語設定されたデスクトップ版の Ubuntu と異なっており、特にシステム日本語フォントを使って処理をする帳票などで出力が異なる動作となる場合があります。

今回は、UML 画像の出力を行う Java の PlantUML ライブラリにて、デスクトップ版とコンテナ版の Ubuntu 22.04 でレンダリングに差異がでるという事象として確認しました。

具体的には、デスクトップ版 ja_JP.UTF-8 設定の Ubuntu 22.04 では正しく PDF レンダリングができる Asciidoc/PlantUML 文書を、GitHub Actions 上の Ubuntu コンテナでビルドさせると「日本語フォント幅が短くなって崩れる」対応になります。(この事象は、WSL2 上で動作する Ubuntu 22.04 のデフォルト状態でも発生すると思います)

PlantUML の出力する SVG の日本語フォント部分の幅計算がおかしくなるの図:

調べてみると PlantUML はデフォルトで sans-serif などのデフォルトフォント名をもとにフォント幅を計算するようでした。(追記)PlantUML のデフォルトフォントは Dialog のようです。

コンテナとデスクトップ版で fc-match を比較。

# デスクトップ版 Ubuntu
$ fc-match sans-serif
NotoSansCJK-Regular.ttc: "Noto Sans CJK JP" "Regular"
$ fc-match Dialog
NotoSansCJK-Regular.ttc: "Noto Sans CJK JP" "Regular"
# コンテナ版 Ubuntu
$ fc-match sans-serif
DejaVuSans.ttf: "DejaVu Sans" "Book"
$ fc-match Dialog
DejaVuSans.ttf: "DejaVu Sans" "Book"

というわけで、PlantUML にレンダリングシステムフォント名を指定するか、sans-serif などの標準的なフォント名を Noto Sans CJK JP で引けるようにするかで解決しそうです。今回は後者の方法を選択しました。

コンテナ版 Ubuntu で次のようにするとデスクトップ版と同じように sans-serifNoto Sans CJK JP になります。

apt-get -y update
apt-get -y upgrade
apt-get -y install language-pack-ja fonts-noto* fontconfig language-selector-common
update-locale LANG=ja_JP.UTF8
fc-cache -f # 念の為

LANGja_JP.UTF-8 の場合に Noto Sans CJK JP が選択されるように language-selector が組まれています。

$ export LANG=ja_JP.UTF-8
$ fc-match sans-serif
NotoSansCJK-Regular.ttc: "Noto Sans CJK JP" "Regular"
$ fc-match Dialog
NotoSansCJK-Regular.ttc: "Noto Sans CJK JP" "Regular"
$ export LANG=C
$ fc-match sans-serif
DejaVuSans.ttf: "DejaVu Sans" "Book"
$ fc-match Dialog
DejaVuSans.ttf: "DejaVu Sans" "Book"

なお、コンテナ全体の LANG 設定は大きな変更となりますので、既に動作しているコンテナの場合は、起動するアプリケーションごとに範囲を絞って設定したほうが良いかもしれません。

GitHub Actions の該当部分:

    - name: Setup Environment (Ubuntu)
      if: startsWith(matrix.os, 'ubuntu')
      run: |
        sudo apt update
        sudo apt upgrade
        sudo apt install language-pack-ja-base language-pack-ja
        sudo update-locale LANG=ja_JP.UTF8
        sudo apt install fonts-noto* language-selector-common
        export LANG=ja_JP.UTF-8
        fc-cache -f
        fc-match Dialog | grep "Noto Sans CJK JP"

また、クラウド IDE である Gitpod のコンテナでは初期化を次のようにすると内部ターミナルの再起動を行って場合でも LANG が設定されるようにできます。

image: gitpod/workspace-full
tasks:
  - name: Setup
    before: |
      sudo apt-get -y update
      sudo apt-get -y upgrade
      sudo apt-get -y install language-pack-ja graphviz fonts-noto* language-selector-common
      sudo update-locale LANG=ja_JP.UTF8
      echo 'export LANG=ja_JP.UTF-8' >> ~/.bashrc
      export LANG=ja_JP.UTF-8
      fc-cache -f
      fc-match Dialog | grep "Noto Sans CJK JP"

そんなこんなで、GitHub Actions 上で Ubuntu, Windows, macOS の 3環境 x Java 11, 17 の 2環境、合計 6 環境で Asciidoc/PlantUML 文書のビルド・テストができるようになりました。良い。:D

今回の例だと本来的には、SVG を PDF にレンダリングするフォントと、

  • 各 OS の Dialog フォント設定を一致させるか、
  • PlantUML 自体に Dialog ではなく、PDF レンダリングフォントを使うように指示して フォント幅計算をさせる

のが正しい処理と思いますが、各環境のビルド結果の PDF 文書を目視したところ、確認できるような差異がでていないのでいったんヨシとしています。

関連

コメントを残す