続・玩式草子 ―戯れせんとや生まれけん―

第61回grubテーマの遊び方(その2)

この連載でも何度か生存報告的に紹介してきたPlamo Linux 8.2を去る5月7日にリリースしました。8.1をリリースしたのが2023年6月だったので、約2年ぶりのバージョンアップとなります。もっとも連載中でも触れてきたように、最近では互換性を維持しつつ各パッケージが更新され続けているので、⁠正式リリース」と言っても何か大きな変更があるわけではなく、ある時点でのFTPサイトにあるパッケージ群をisoイメージに固めた、程度の意味しかありません。

しかしながら、⁠正式リリース」版のisoイメージを放置したままだと、そのイメージを使った新規インストール後のアップデート作業が大変になるので、やはり年に一度くらいは更新しておかないといけないな…… と反省しているところです。

さて、Plamo-8.2に関してはまた別の機会に取りあげることとして、今回はgrubのテーマ設定の続きです。

grubテーマの構成要素

前回も紹介しましたが、図1はtheme.txtの機能を使っていないPlamo Linuxのデフォルトの起動メニュー画面です。この画面を構成している各パーツを模式図で示すと図2のようになります。

図1 theme.txtを使っていない起動メニュー画面
theme.txtを使っていない起動メニュー画面
図2 起動メニュー画面の各パーツ
起動メニュー画面の各パーツ

grub.cfgに登録されている、各カーネルをロードするための⁠menuentry⁠あるいは⁠submenu⁠の各項目はメニューアイテムと呼ばれ、起動メニュー画面ではメニューボックスの中に一覧表示されます。メニューボックスの中では、選択対象となった項目を明示するための選択ボックスが用意され、フォントや背景色を変えて選択項目を強調できるようになっています。theme.txtの役割は、起動メニュー画面を構成するこれら各パーツの色やサイズ、使うフォント、位置等を設定することです。

これらのパーツにはそれぞれデフォルト値が用意されており、theme.txtを使わなくてもそれなりの見栄えで表示されるのは図1に示す通りです。一方、それらの値を変更する、すなわち図2のタイトルラベルを書き変えるにはtheme.txtでの設定が必要になります。実のところ、この「ラベル」の部分にPlamo Linux用の注意書きを入れたいな、というのがtheme.txtを調べるきっかけでした。

theme.txtを調べる前は、⁠ラベル」という概念を知らなかったので、注意書きは背景画像に埋めこんで誤魔化してました(苦笑⁠⁠。

さて、まずはtheme.txtの大まかな構成を紹介しましょう。theme.txtで設定できるメニュー画面のパーツは、ルート要素(root element⁠⁠、ブートメニュー(boot menu⁠⁠、タイムアウト表示(timeout indicator⁠⁠、ラベル(label⁠⁠、イメージ(image⁠⁠、縦ボックス(vbox⁠⁠、横ボックス(hbox⁠⁠、キャンバス(canvas⁠⁠」の8種類です。

「タイムアウト表示」には横棒(progress bar)型と周回(circular animation)型の2種があります。

それぞれのパーツの役割は以下の通りです。

  • ルート要素:メニュー画面の背景部を担当し、タイトル表示や背景色、背景画像、コンソール画面を装飾
  • ブートメニュー:起動するカーネルを選択するメニューボックスの表示、選択内容の強調等
  • タイムアウト表示:デフォルトのメニューアイテムが実行されるまでの残り時間表示
  • ラベル:画面上に表示する文字列の設定
  • イメージ:画面上に表示する画像の設定
  • 縦ボックス:複数のパーツ(ラベルやイメージ)を縦に並べて表示するためのコンテナ
  • 横ボックス:複数のパーツを横に並べて表示するためのコンテナ
  • キャンバス:複数のパーツを任意の位置に表示するためのコンテナ

これらがどのように設定されるのかを前回利用した"starfield"テーマのtheme.txtを元に紹介しましょう。多くの設定ファイル同様、⁠#⁠で始まる行はコメントです。

$ cat -n /usr/share/grub/themes/starfield/theme.txt
...
  23  #general settings
  24  message-font: "DejaVu Sans Regular 12"
  25  message-color: "#000"
  26  message-bg-color: "#fff"
  27  terminal-box: "terminal_box_*.png"
  28  terminal-font: "DejaVu Sans Regular 12"
  29  desktop-image: "starfield.png"

最初に設定されているのがルート要素です。後述する他のパーツは⁠+ パーツ名 { ... }⁠の形で指定するのに対し、⁠ルート要素」の設定は中括弧で包まずに記述します。また、他のパーツでは⁠item = content⁠⁠=(イコール)⁠で値を定義するのに対し、⁠ルート要素」では⁠item : content⁠⁠:(コロン)⁠で値を定義します。設定内容については改めて触れる予定なので、ここではフォントの種類や色、背景画像等を指定している、程度にご理解ください。

  31  #help bar at the bottom
  32  + label {
  33          top = 100%-25
  34          left = 0
  35          width = 100%
  36          height = 20
  37          text = "@KEYMAP_MIDDLE@"
  38          align = "center"
  39          font = "DejaVu Sans Regular 10"
  40          color = "#FFF"
  41  }

この部分ではラベルを設定しています。⁠top⁠⁠left⁠でテキストの表示位置を、⁠font⁠⁠color⁠で使うフォントの種類や色を指定しているのは想像できるでしょう。表示すべきテキストの中身である⁠@KEYMAP_MIDDLE@⁠はあらかじめ設定されている文字列で、⁠Enter キーで選択した OS を起動します。…」と表示される操作方法の解説です。

  43  #boot menu
  44  + boot_menu {
  45          left = 10%
  46          width = 80%
  47          top = 20%
  48          height = 50%    
  49          item_font = "DejaVu Sans Regular 12"
  50          item_color = "#000"
  51          selected_item_font = "DejaVu Sans Bold 14"
  ...   
  62          scrollbar_thumb = "slider_*.png"
  63          menu_pixmap_style = "boot_menu_*.png"
  64  }
  65  

途中は省略しましたが、この部分は起動するカーネルを選択するためのメニューボックスに関する設定です。ここでも表示の位置や使うフォント、色等が設定されています。

  66  #progress bar
  67  + progress_bar {
  68          id = "__timeout__"
  69          left = 15%
  70          top = 80%
  71          height = 20
  72          width = 70%
  73          font = "DejaVu Sans Regular 12"
  74          text_color = "#000"
  75          fg_color = "#fff"
  76          bg_color = "#6ac"
  77          border_color = "#fff"
  78          text = "@TIMEOUT_NOTIFICATION_LONG@"
  79  }

横棒形式のタイムアウト表示に関する設定です。ここでも表示位置やフォント、色等を設定しています。id = "__timeout__"は、デフォルトのメニューアイテムを実行するまでのカウントダウン表示を意味します。

カウントダウンに使われる秒数は、grub.cfgの⁠set timeout=60⁠の指定を受け取ります。"@TIMEOUT_NOTIFICATION_LONG@"もあらかじめ設定されている文字列で、⁠ハイライトされた項目がxx秒後に自動実行されます。」旨の文言になります。

以上見てきたように、サンプルとして用意されている⁠starfield⁠テーマのtheme.txtでは、⁠ルート要素⁠⁠、⁠ラベル⁠⁠、⁠ブートメニュー⁠⁠、⁠タイムアウト」の4つのパーツを設定しています。

grub-mkfontとPF2フォント

さて実際にtheme.txtを変更する前に、grubが画面表示に使うフォントについて触れておきましょう。

grubが扱えるのはPF2と呼ばれる独自形式のビットマップフォントのみです。筆者のように古くからX Window Systemを使っている人間は、⁠ビットマップフォント」と聞くと⁠BDF⁠⁠PCF⁠といった懐しい形式を連想するものの、これら古い形式ではUNICODEを扱うのが困難なため、新しい形式を考案したそうです。

PF2形式のフォントを作成するにはgrub-mkfontというコマンドを用います。⁠grub-mkfont⁠は、ベクトルフォントを指定したサイズにレンダリングしてビットマップ化し、PF2フォーマットで保存します。

昔のXを使っていた人はご存知のように、ビットマップフォントは固定サイズなので、使いたいサイズごとにフォントデータを用意する必要があります。とりあえずPlamo Linuxで標準的に使っているMigMixフォントから、3サイズほどPF2形式のビットマップフォントを作ってみます。

$ for i in 16 20 24 ; do
>   grub-mkfont -v -s $i /usr/share/fonts/TTF/migmix-1m-regular.ttf -o migmix-1m-$i.pf2
> done
Font name: MigMix 1M Regular 16
Max width: 16
Max height: 21
Font ascent: 17
Font descent: 5
Number of glyph: 12832
Font name: MigMix 1M Regular 20
Max width: 20
..
$ ls -lh *pf2
-rw-r--r-- 1 kojima users 524K  5月 27日  07:31 migmix-1m-16.pf2
-rw-r--r-- 1 kojima users 694K  5月 27日  07:31 migmix-1m-20.pf2
-rw-r--r-- 1 kojima users 902K  5月 27日  07:31 migmix-1m-24.pf2

それでは、これら新しく作ったフォントも使いつつtheme.txtを編集してみましょう。

theme.txtの簡単な設定例

theme.txtの設定例として、まずはわかりやすいパーツである「ルート要素」⁠ラベル」⁠イメージ」を試してみます。

準備として、先に作成した新しいPF2フォントをtheme.txtファイルと同じ場所に配置します。今回はUSBメモリ上のgrubから起動しているので、コピー先はUSBメモリ上の/grub/themes/starfield/となります。

$ cp migmix-2p-*.pf2 /run/media/kojima/11B4-4E49/grub/themes/starfield/

ついでに「イメージ」のサンプル画像として、最近ChatGPTに作ってもらったPlamo Linuxのロゴ画像をコピーしておきます。

$ cp Plamo_logo_s.png /run/media/kojima/11B4-4E49/grub/themes/starfield/

これらを使うためのtheme.txtは以下のようにしてみました。

$ cat -n /run/media/kojima/11B4-4E49/grub/themes/starfield/theme.txt
     1  title-font: "MigMix 1M Regular 24"
     2  title-text: "GRUBテーマの設定例"
     3  title-color: "tomato"
     4  desktop-color: "cornflowerblue"
     5  
     6  + label {
     7          top = 100%-50
     8          left = 0
     9          width = 100%
    10          height = 30
    11          text = "画面最下部に表示されるラベル"
    12          align = "center"
    13          font = "MigMix 1M Regular 20"
    14          color = "256, 256, 128"
    15  }
    16  
    17  + image {
    18          top = 100%-256
    19          left = 100%-256
    20          file = "Plamo_Logo_s.png"
    21  }
    22  
    23  + boot_menu {
    24          left = 10%
    25          width = 80%
    26          top = 20%
    27          height = 50%    
    28          item_font = "DejaVu Sans Regular 12"
    ...
    41          scrollbar_thumb = "slider_*.png"
    42          menu_pixmap_style = "boot_menu_*.png"
    43  }
    44  

設定項目の詳細は次回以降説明することにして、ここでは簡単に概要だけ紹介しておきます。

1から4行目が「ルート要素」の設定で、タイトルの文字列とフォント、色、および背景色を指定しています。

6から15行目が「ラベル」の設定で、表示位置と表示する文字列、使うフォント、色、アライメント等を指定しています。

17から21行目が「イメージ」の設定で、⁠256x256⁠という画像サイズを前提に、⁠file = ...⁠で指定した画像ファイルが画面の右下に来るよう調整しています。

23行め以降は「メニューボックス(ブートメニュー⁠⁠」の表示で、これは元の設定をそのまま流用しています。

theme.txtで使うフォントはgrub.cfgで読み込んでおく必要があります。本来は⁠grub-mkconfig⁠を再実行し、必要なフォントファイルを読み込むようなgrub.cfgを再作成すべきものの、今回は変則的な使い方をしているので、直接grub.cfgに必要な設定を追加しました。

$ cat -n /run/media/kojima/11B4-4E49/grub/grub.cfg
 ...
 103  loadfont ($root)/grub/themes/starfield/migmix-1m-16.pf2
 104  loadfont ($root)/grub/themes/starfield/migmix-1m-20.pf2
 105  loadfont ($root)/grub/themes/starfield/migmix-1m-24.pf2
 ...

以上の設定を追加して、VirtualBoxを起動しUSBメモリ上のgrubを呼び出すと、図3のようなメニュー画面が表示できました。

図3 サンプルtheme.txtを使った起動メニュー画面
サンプルtheme.txtを使った起動メニュー画面

今回は起動メニュー画面の構成や概要紹介に紙幅を費してしまったので、各パーツに用意されたさまざまな機能については説明できませんでした。それらは次回のお楽しみ、とするものの、次回を待てない方にいくつか注意点を述べておきます。

  • 色の指定にはHTML風の⁠#RGB⁠スタイル(ex:"#8899FF"⁠⁠、コンマでRGBを10進数で指定するスタイル(ex:"128,128,255"⁠⁠、⁠SVG 1.0⁠で定義されている色名(ex:"cornflowerblue")の3種が利用できます。

  • grubが扱える画像はPNG形式です。JPEGを扱う機能もあるものの、色数が制限される等、結構面倒なので、使いたい画像はPNGにしておきましょう。

  • 起動メニュー画面はハードウェア環境に応じて解像度や縦横比が変り、背景画像等もそれに合わせて変形されます。

  • 「ラベル」「イメージ」の位置は、画面左上隅を原点とし、そこからどれだけ離れているかを⁠top=..⁠⁠、⁠left=...⁠で指定します。⁠top⁠⁠、⁠left⁠はドット数で指定することも可能ですが、表示画面の解像度はハードウェア環境によって変わるので、⁠top=50% left=50%⁠のように割合(⁠⁠%⁠⁠)で示す方が便利です。例に使っている⁠top =100%-256⁠「画面の底辺(top=100%)から、256ドット分戻った位置」を意味します。

  • theme.txtで定義した各パーツの表示順は下から上(最後に定義したものが最初に描かれる)になります。画像ファイルを利用する場合、透過PNGを使えば重ね合わせの表現も可能です。

おすすめ記事

記事・ニュース一覧