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 文書を目視したところ、確認できるような差異がでていないのでいったんヨシとしています。

関連

WezTerm ターミナルエミュレータを導入

Ubuntu ではターミナルエミュレータとして長らく Alacritty を使わせていただいていたのですが、WezTerm も良さそうな感じがしましたので使ってみることにしました。

カスタマイズできる項目が非常に多く、こだわりのターミナル環境がつくれそうです。

WezTerm

WezTerm is a powerful cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust

実行環境ですが、Ubuntu 22.04 LTS の X11 セッションにて、ターミナルワークスペースの Zellij と組み合わせで使っています。ちなみに自分の環境だと Flatpack 版で Ibus の接続が「時折」うまくいかなくなる事象がでていたので deb 版を使っています。 IME がうまく切り替わらない問題は deb 版でも発生するようです。原因調査中。

X11 環境下でも IME 変換窓がずれない

Alacritty/X11 だと変換窓がウインドウの下にずれてしまうのですが、WezTerm/X11 は正しい位置に表示されていい感じです。

自分は、OBS Studio の対応などの関係で Wayland に移行できておらず X11 なのでタスカルラスカル。

壁紙が設定できる

画像のオフセット指定や、複数枚指定などこだわりの壁紙設定が可能です。良い。

(壁紙は Atelier Ryza 3: Alchemist of the End & the Secret Key | #WelcomebackRyzaEU Campaign Overview より)

ショートカットキーでフォントの大きさを操作できる

実はこの機能が欲しくて WezTerm にたどり着いたのですが、ショートカットキー CTRL + SHIFT + – などで表示フォントの大きさが素早く変更できます。

自分はよくあるのですが、他の方への説明で、見やすいように一時的にフォントを大きくしたいケースで便利です。

その他にも、ショートカットキーにはさまざまな機能をバインドできるようです。

高いカスタマイズ性

コンフィグレーションは .lue 言語を使ってできるので、プログラマルにいろいろなことができそうです。

以下は単純な設定ですが、参考までに自分の現在のところの .wezterm.lua を添付します。

local wezterm = require 'wezterm'
local config = {}

-- ime
config.use_ime = true
config.xim_im_name = 'ibus'

-- font
config.font = wezterm.font 'HackGen Console NF'
config.font_size = 12.0
-- CTRL + - などでのフォント変更時にウインドウサイズを変更しない
config.adjust_window_size_when_changing_font_size = false

-- window
config.initial_cols = 150
config.initial_rows = 52
config.window_padding = {
  left = 0,
  right = 0,
  top = 0,
  bottom = 0,
}
-- タブバーをタブがひとつの時は表示しない
config.hide_tab_bar_if_only_one_tab = true

-- color
config.colors = {
  foreground = "#c5c8c6",
  background = "#181818",
  visual_bell = '#202020',
}
-- デフォルトカラースキームから選択
config.color_scheme = 'Darcula (base16)'

-- backgound
config.background = {
  {
    source = {
      File = '/home/hiromasa/Documents/images/ryza/Ryza3Wallpaper3_iPhone2.jpg'
    },
    hsb =  { brightness = 0.02 },
    opacity = 1.0,
    attachment = { Parallax = 0.5 },
    horizontal_offset = 0,
    vertical_offset = -800,
  }
}

-- disable bell
config.audible_bell = "Disabled"
config.visual_bell = {
  fade_in_duration_ms = 75,
  fade_out_duration_ms = 75,
  target = 'CursorColor',
}

return config

その他の自分の気になり機能としては、シリアルポートサポートがあったり、

wezterm serial /dev/ttyUSB0

Sixel や iTerm 形式の画像表示に対応していたり、

wezterm imgcat /path/to/image.png

等々、非常に多機能です。素晴らしい…! 継続して使っていきたいと思います。

関連

WSL2/WSLg にインストールすると便利な Ubuntu アプリケーション

Windows の WSL2/WSLg を使うと Linux の GUI アプリが活用できて良い感じです。近年の Linux GUI アプリは使い勝手もグッドで、Windows よりもフォントが綺麗に出力できるなど利点も多いです。コマンド 1行で導入できるのも手軽です。

ということでこの記事では自分が普段使っているソフトウェアを紹介したいと思います。日本語の「入力」はいくつか問題があるので、行わなくても問題がないシチュエーションで使えるものを選択しています。

導入は WSL2/Ubuntu 22.04 LTS を想定です。また、この記事のスクリーンショットでは Ubuntu 標準テーマのダークモードを設定しています。GNOME/GTK テーマの設定方法は末尾の関連記事に掲載しました。

なお、WSL2 は Windows 側のファイルシステム(/mnt/c) を扱うと動作が遅くなりますので、なるべく /home/username 配下など Linux 側のファイルシステムを使うように運用すると良いと思います。また、4K モニター使用時などで Windows 側でしているスケーリング設定は WSL2 側には反映せず、.wslgconfig ファイルで行えるスケーリングもまだ完全には動作しないようです。

準備

Windows の Powershell 窓などで WSLg が入っていることを確認のこと。

❯ wsl --version
WSL バージョン: 1.2.5.0
カーネル バージョン: 5.15.90.1
WSLg バージョン: 1.0.51
MSRDC バージョン: 1.2.3770
Direct3D バージョン: 1.608.2-61064218
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22621.1992

入っていなければ、確認の上 wsl --update でアップデートします。

❯ wsl --update
更新プログラムを確認しています。
Linux 用 Windows サブシステムの最新バージョンは既にインストールされています。

日本語フォントの導入。 Ubuntu 上で以下のコマンドで入ります。

$ sudo apt install fonts-noto-*

お使いの Ubuntu の活用範囲で問題なければ、日本語ロケールも設定しておくと良いかもしれません。

$ sudo apt -y install language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF8

nemo ファイルマネージャ

ファイルマネージャの nemo です。GNOME の Files アプリよりもペイン分割(F3キー)や、キーボード押下からの先頭文字ジャンプなどが標準で使えて便利です。

導入。

$ sudo apt install nemo

コマンドラインだとワイルドカード選択が難しいパターンなどの操作で、次のようにカレントディレクトリ . などを指定して nemo を起動するとすっ飛べて良いと思います。

$ nemo .

GNOME 画像ビュアー(Eye of GNOME Image Viewer)

nemo と一緒に GNOME 画像ビュアーを入れておくと、nemo のファイルダブルクリックから画像ファイルが開けます。また PDF の表示もいけます。

$ sudo apt install eog

PDF では FreeType フォントレンダラが選択されますので、通常の Windows ウェブブラウザによる PDF 表示よりも美しいです。

Meld

フォルダ単位で diff がとれる Meld。導入。

$ sudo apt install meld

こちらもコマンドラインから次のように引数でディレクトリ指定して起動すると便利です。

$ meld dir1/ dir2/

ソースコードフォントには HackGen を使わせていただいております。(メニュー Meld -> 設定より)

なお、Ubuntu へのフォントの導入は /usr/share/fonts/truetype/ にディレクトリを作成しフォントを配置して、 fc-cache コマンドでシステムに認識されるようになります。

$ ls -l /usr/share/fonts/truetype/hackgen/
合計 49968
-rw-r--r-- 1 hiromasa hiromasa 13060044  5月  3 17:51 HackGen35ConsoleNF-Bold.ttf
-rw-r--r-- 1 hiromasa hiromasa 12520684  5月  3 17:51 HackGen35ConsoleNF-Regular.ttf
-rw-r--r-- 1 hiromasa hiromasa 13061184  5月  3 17:51 HackGenConsoleNF-Bold.ttf
-rw-r--r-- 1 hiromasa hiromasa 12519656  5月  3 17:51 HackGenConsoleNF-Regular.ttf
$ fc-cache
$  fc-list | grep hack
/usr/share/fonts/truetype/hackgen/HackGen35ConsoleNF-Bold.ttf: HackGen35 Console NF:style=Bold
/usr/share/fonts/truetype/hackgen/HackGenConsoleNF-Bold.ttf: HackGen Console NF:style=Bold
/usr/share/fonts/truetype/hackgen/HackGen35ConsoleNF-Regular.ttf: HackGen35 Console NF:style=Regular
/usr/share/fonts/truetype/hackgen/HackGenConsoleNF-Regular.ttf: HackGen Console NF:style=Regula

RSS リーダー NewsFlash

モダンでナイスな RSS リーダー NewsFlash です。こちらも FreeType/Noto で表示できるので綺麗です。また、RSS のソースコードブロックがいい感じにレンダリングされるのでお気に入りです。

このアプリは snap 提供があるので snap で導入してみました。Ubuntu の snap を使う場合は WSL2/Ubuntu を systemd 起動にする必要があります。(Flatpack 版がオフィシャルのようなので systemd 起動をしたくない方はそちらで…!)

WSL2/Ubuntu の systemd を有効にします。ファイルがない方は新規作成のこと。

$ cat /etc/wsl.conf
[user]
default=hiromasa
[boot]
systemd=true

いったん WSL2 を再起動します。これで systemd が有効になった Ubuntu になりますので snap が使えるようになります。(わずかに Ubuntu の起動が遅くなります)

> wsl --shutdown

NewsFlash 導入。

$ sudo snap install newsflash

起動して RSS URL を登録後、フィードタイトルペインの上にあるリロードボタンを押すと時間を置かずにフィードを取得してくれるようです。

Windows のタスクバーにアプリを登録したい

Windows のタスクバーに Ubuntu アプリを登録するには次のように操作します。アイコンが選べない、アプリによってはペンギンアイコンになって識別しにくいなどまだ少し癖がありますが、RSS リーダなどは登録しておくと便利です。

Windows のスタートメニューを押してお目当てのアプリを検索で選択し「スタートにピン止めする」を選択します。

関連