UI 向け日本語フォントを考える

By ftake @ 2016-08-20 15:34

Google と Adobe によって開発された Noto Sans フォント(源ノ角フォント)がリリースされ、openSUSE に取り込まれてからだいぶ経ちました。openSUSE では Noto シリーズのフォントに UI フォントを統一しようという流れが出てきています。Noto フォントの魅力は、幅広い言語の文字をサポートしている上に、様々なウェイト(太さ)をサポートしていることです。

一方で、Noto フォントはスマートフォンやタブレットなどの高解像度のディスプレイに合わせて開発されたせいなのか、KDE や GNOME アプリケーションでは、行の高さが大きすぎて、ちょっと微妙なレンダリング結果になるようです。

ここでは、現在の日本語フォント IPA Pゴシック、Noto Sans CJK Regular、Migu 1C Regular を比較してみます。Leap 42.1 に採用されている古い fontconfig はマルチウェイトフォントを正しく検索できないため、M17N リポジトリからの 2.12.0 を使いました。

また、サブピクセルレンダリングの効果を試すため、サブピクセルレンダリングを有効化※し、自分でビルドした FreeType 2.6.5 を使いました。
※特許で保護されているため、openSUSE では無効化されている

ft-view で比較

font-comparison-ft-view

まずは、ft-view によるレンダリングの比較です。上3つが Noto Sans CJK JP のレンダリング結果です。最上段の左と右はサブピクセルレンダリングの有無の比較です。「編」の字の縦棒がサブピクセルレンダリングの効果で分かりやすくなっていますが、劇的には変化はないようです。

Noto Sans の1段目と2段目はヒンティングの有無の比較です。「設」の字が分かりやすいのですが、ヒンティングを有効にすると、各文字が全体的に縦長に見える傾向があります。

3段目は IPA Pゴシックと、Migu 1C のレンダリング結果です。IPA Pゴシックは、他の2つのフォントに比べて、明らかに行の高さが小さくなっています。特に印刷物で使うには、行間が狭すぎることが多いです。一方、UI で使うときは、低解像度のディスプレイに文字を詰め込むために、この行間に慣れているのではないかと思います。

Migu 1C は M+ 1c ベースのフォントで、ひらがな・カタカナの字幅を小さくしたり、濁点・半濁点を大きくし読みやすくしたフォントです。横方向を狭くして詰め込む方法もまた、長らく使われてきた習慣だと思います。一方で、縦方向の行間は比較的広めで、Noto フォントと同じくらいです。

GTK アプリケーションのメニューのレンダリング比較

行の高さはアプリケーションの余白に大きく影響します。次の図は、GNOME の Nautilus で、動画ファイルを右クリックしたときに表示されるメニューの比較です。同じフォントサイズを指定しても、3つのフォントで1行分以上の差が出ます。

font-comparison-gnome-shell

ここで不思議なのが、Noto Sans と Migu 1C が、ft-view では差があまり無かったのにもかかわらず、メニューの高さはだいぶ異なるようです。フォントメトリックスの何かの違いが影響を与えていると思いますので、このあたりは今後調査してみます。

KDE の Kickoff ラウンチャー

最も差が出るのが、昔の KDE のラウンチャーの Kickoff です。Plasma 5 を使用している場合は、メニューのアイコンを右クリックして「Alternatives」から切り替えることができます。

font-comparison-plasma

ここまで差があると、不具合のような気もしますが、Noto Sans では、多くのノートPCの縦解像度 768 px を超えて、800 px ギリギリまで到達してしまいました。(この PC は 800 px あります)

まとめ

openSUSE では、さざなみフォントの後、IPA フォントが長らく使われてきましたが、FreeType との相性が悪い文字・記号や、太字が無いため、どこかで他のフォントに切り替えないといけないと考えています。

Noto Font は強力な候補なのですが、行間問題は様々なアプリケーションに影響がありそうなため、調査と対策が必用そうです。

M+ 系の(Bold がある)フォントも、本家 M+ フォントが10年の歳月をかけてJIS 第1水準を超えており、日本語のフォントという観点では引き続き選択肢となりそうです。

今日は Windows や Mac でおなじみの商用のアンチウイルスソフト Sophos Antivirus の個人向け無償版のを Leap 42.1 にインストールする方法を紹介します。

まずはダウンロードします。以下の URL からダウンロードできます。
https://www.sophos.com/ja-jp/products/free-tools/sophos-antivirus-for-linux.aspx

ダウンロードまでの間に、氏名とメールアドレスなどを2回求められます。2回目は米国輸出管理法の輸出先の確認のためのようです。職業は「個人利用者」、会社名は「個人」とでもしておけばよいでしょう。

ここからはターミナルで作業です。ファイルを回答してインストーラーを走らせるだけです

tar xvf sav-linux-free-9.tgz
cd sophos-av
sudo install.sh

ここからはインストーラの指示に従って作業を進めます。まずは使用許諾契約に同意します。Enter キーを押して契約書を表示して、読んだあとに、Yキーで同意します。

ライセンス内容に同意しますか? はい(Y)/いいえ(N) [N]
> y

次にインストール先を求められます。特にこだわりがなければそのままで問題ありませんので、何も入力せずにEnterを押します。なお、インストール先には1GB程度の空き容量が必要なようです。

Sophos Anti-Virus のインストール先を指定してください。 [/opt/sophos-av]
>

アプリケーションからファイルにアクセスしたときに検索を行う、オンアクセス検索を有効にします。

オンアクセス検索を有効にしますか? はい(Y)/いいえ(N) [Y]
>

アップデートのダウンロード元です。そのままでOKです。

オートアップデートの種類を選択してください: ソフォス(s)/自社サーバー(o)/なし(n) [s]
>

今回は無償版を使うので f を入力します。

SAV for Linux の無償バージョン (f) と サポート対応付きバージョン (s) のどちらをインストールしますか? [s]
> f

プロキシは必要に応じて設定してください。

ソフォスからアップデートを行うためにプロキシが必要ですか? はい(Y)/いいえ(N) [N]
>

しばらくすると、インストールが終わります。動いているかを確認するには、savdstatus コマンドを使います。

sudo /opt/sophos-av/bin/savdstatus
Sophos Anti-Virus はアクティブで、オンアクセス検索を実行中です

openSUSE にこの方法でインストールすると、オンアクセス検索を行うために、fanotify とよばれるファイルへのアクセスイベントを捉える仕組みが使われます。現時点では fanotify を使った検索が、NFS と CIFS (Samba) で有効になっていると問題があるようです:
https://www.sophos.com/ja-jp/support/knowledgebase/14377.aspx

対策としては、NFS や CIFS でマウントしたディレクトリを検索対象から除外すれば良いようです。どうやって除外するかというと、savconfig コマンドの ExcludeFilePaths で、除外するファイルまたはディレクトリのパスを指定します。複数のパスを追加したいときは、繰り返しsavconfigを実行します:

sudo /opt/sophos-av/bin/savconfig add ExcludeFilePaths /path/to/dir1/
sudo /opt/sophos-av/bin/savconfig add ExcludeFilePaths /path/to/dir2/

除外する範囲は、ファイルシステム名でも指定できるようです。ExcludeFilesystems で除外するファイルシステムを指定します。ファイルシステムの名前は /proc/filesystems に書かれたものを入力すればよいそうです。

sudo /opt/sophos-av/bin/savconfig add ExcludeFilesystems nfs

autoyastがほぼうまくいった

By ribbon @ 2016-05-15 18:10

ほぼ、autoyast がうまくいきました。

うまくいかなかった原因はいくつかありますが、おそらく、openSUSEインストール時に作成するautoinst.xmlがバグってます。たぶん。

通常はインストールするパッケージがずらっと並ぶのですが、なぜか、そのパッケージを*削除*する一覧がくっついているのですね。こんな感じで。

<patterns config:type=”list”>
<pattern>yast2_basis</pattern>
<pattern>x11</pattern>
<pattern>sw_management</pattern>
<pattern>lxde</pattern>
<pattern>fonts</pattern>
<pattern>enhanced_base</pattern>
<pattern>apparmor</pattern>
<pattern>base</pattern>
<pattern>multimedia</pattern>
<pattern>remote_desktop</pattern>
</patterns>
<remove-packages config:type=”list”>
<package>zypp-plugin-python</package>
<package>zisofs-tools</package>
<package>ypbind</package>
<package>yp-tools</package>
<package>yast2-vm</package>
<package>yast2-users</package>
<package>yast2-tune</package>
….

これじゃ、パッケージの依存関係が正しくなるわけがありません。セクションを手動で削ったらほぼうまくいきました。あと、セクションもうまくハンドリング出来ないので、ここも削ります。

ただ、lxde環境だと、更に問題があります。起動時にlxdmが設定されません。xdm になってしまいます。しかし、kde環境を指定してインストールすると、ちゃんとkdm が指定されて、起動するので、lxdmに設定するという部分が抜けちゃっているのだと思います。

 

autoyastがうまくいかない(状況)

By ribbon @ 2016-05-06 22:40

autoyastを使って自動インストールをしようとしていますがうまくいきません。普通にインストールするとき、インストールした状況を/root/autoinst.xml というファイルに書き込むように指示出来るのですが、そのファイルを自動インストール時に使ってもインストール途中に、パッケージの依存関係解決に失敗します。

そもそも、インストールパッケージに不要なものが入ってしまいます。たとえばこんな感じで、本来DVDに入っていないパッケージが入ってしまっています。

autoyastbad01

試しにこれらのファイルを手でautoinst.xml から取り除いても結果は同じでした。途中でこんな感じになります。

autoyastbad02

bashはインストールされ、存在するパッケージなのですが、なぜか依存関係が破綻していると思われています。理由は謎です。

 

openSUSE mini sumitでも話ましたが、openSUSEを自動インストールしようとして試行錯誤しています。すべて仮想環境でテストしているのですが、なかなかうまくいきません。

仮想環境は、debian ベースの proxmoxVEを使っています。これが、なかなか便利で、Webベースで仮想マシンを立てたりつぶしたり、VNC経由で仮想マシンとサクッと繋がる、バックアップも取れる、やろうと思えば高可用性構成も取れるなど、便利な機能がてんこ盛りです。VMware ESXi と比べると、機能的に劣るところもありますが、個人ベースで使うには十分すぎるくらいです。

ただ、この仮想環境、ちょっと変わったところがあって、仮想OS用のBIOSに、iPXEが組み込まれているのですね。PXEではなくて。なので、ネットワークブートを行う時は、PXEのノウハウがあまり使えません。とりあえず、今やっていることをメモとして書いておきます。


準備

◆1 dhcpの設定

iPXEを使う時には、dhcpで、インストールサーバの情報を設定する必要があります。dhcpの設定はyastからも出来ますが、今回は直接 /etc/dhcpd.conf を設定しました。こんな感じになります。

default-lease-time 14400;
subnet 192.168.10.0 netmask 255.255.255.0 {
range 192.168.10.101 192.168.10.127;
default-lease-time 14400;
max-lease-time 172800;
}
if exists user-class and option user-class = “iPXE” {
filename  “iPXE/boot.ipxe”;
}
else  {
filename “iPXE/undionly.kpxe”;
}
next-server 192.168.10.41;

この設定により、iPXEが、OSを起動するための初期スクリプト boot.ipxeをダウンロードすることが出来ます。

◆2 tftpの設定

tftpの設定はyast から行います。特に標準のままで問題ありません。なお、tftpはxinetd配下から起動することになります。

◆3 httpdの設定

httpdを設定します。rootディレクトリは、/srv/tftpboot/install/ にします。

◆4 OSイメージの展開

yast の、インストールサーバ設定から、OSイメージを展開します。サブディレクトリは、leap42にしてみます。

◆5 OSイメージの配置

/srv/tftpboot 配下にOSのISOイメージを置きます。

◆6 boot.ipxe の作成

ひな形は、ここにあります。こんな感じになっています。

#!ipxe
menu Please choose an operating system to install
item –gap openSUSE
item isolinux isolinux boot
item efi efi boot
item iso iso boot
item –gap ipxe shell
item shell       Drop to iPXE shell

choose target && goto ${target}

:failed
echo Booting failed, dropping to shell
goto shell

:shell
echo Type ‘exit’ to get the back to the menu
shell
set menu-timeout 0
set submenu-timeout 0
goto start

:isolinux
kernel http://192.168.10.41/install/leap42/CD1/boot/x86_64/loader/isolinux.bin initrd=http://192.168.10.41/install/leap42/CD1/boot/x86_64/loader/initrd install=http://192.168.10.41/install/leap42/CD1/
initrd http://192.168.10.41/install/leap42/CD1/boot/x86_64/loader/initrd
boot || goto failed

:efi
chain   /install/leap42/CD1/EFI/BOOT/bootx64.efi initrd=initrd install=/install/132/CD1
initrd  /install/leap42/CD1/boot/x86_64/loader/initrd
boot || goto failed

:iso
sanboot http://192.168.10.41/leap42.iso
boot || goto failed


やってみました

◆1 isolinux でブートする

展開されたISOイメージ内にはisolinux.bin があります。これを直接指定してみます。結果は

isolinux-bad

と、あえなく撃沈。

◆2 EFIでブートする

展開されたISOイメージ内にはEFI用のブートコードがあります。これを指定してみます。結果は

efi-bad

と、これも撃沈。

◆3 ISOイメージをブートする

iPXEには、SANからブートする機能があります。この機能を使うと、ISOイメージをそのままブートすることが出来ます。結果は、

iso-ok-01

と、ISOブートと同じ画面が出ます。ただ、この後そのまま続行しても、インストールデータがネットワークブートしたkernelから直接読めるわけではないので、

iso-ok-02

と、インストールデータがある場所を要求してきます。ここに、httpで取得出来るURLを入れてあげればそのまま続行出来ます。

とりあえずここまでは出来ています。

 

VNCからXDMCP接続画面につなぐ

By ribbon @ 2016-01-11 17:12

昔は、リモートからXを使う場合、手元のマシンにXサーバを入れてつないでいました。LinuxをはじめとするUnix系OSであれば、標準でXが入っているため問題はなかったのですが、Windows OSの場合は、Xサーバソフトを入れないと使えません。Windows用Xサーバソフトは現在も何社から販売されていますが、そこそこな値段がするため(数万以上)おいそれと使うわけにはいきません。そこで、自由に(=無償で)使える、VNCを使って同等の事が出来るようにしてみました。

作業手順については、
https://www.ibm.com/developerworks/jp/opensource/library/os-multiuserloginsvnc/ にほとんどまとまっています。ここに書いてある通りにすれば、間違いなく動きます。

ただ、1つ注意すべき事があります。いくつかあるディスプレイマネージャのうち、LXDEはXDMCPプロトコルに対応していません。ですので、VNCから使おうとしても繋がりません。GDMかKDMに切り換える必要があります。

最近の OSC のセミナーで紹介していた Snapper で作成した Btrfs ファイルシステムのスナップショットを Samba で公開し、「以前のバージョン」のファイルにアクセスできるファイルサーバーが、CentOS でも 7.2 になって構築できるようになりました。

Snapper は openSUSE 傘下のプロジェクトで、設定しておいたルールに応じて、自動的にファイルシステムのスナップショットを撮ってくれます。Samba 4.2 以降で、Samba と Snapper が vfs_snapper で連携できるようになりました。細かい話は OSC 京都のスライドをチェックして下さい。

では早速インストールしてみましょう。ポイントは SELinux への対応です。(まさか、無効にしていないですよね?) ここは openSUSE ユーザ会の Blog ということで、細かい CentOS の解説は行わないことにします。

とりあえず、samba と snapper をインストールします:

$ sudo yum install samba snapper

共有するディレクトリ /srv/share を作成します。以前のバージョンに対応した共有ディレクトリは Btrfs の(サブ)ボリュームである必要がありま。アクセス権は実際に使用する環境に合わせて変更して下さい:

$ sudo btrfs subvol create share
$ sudo chgrp -R geeko share
$ sudo chmod g+w share

SELinux で Samba サーバーが /srv/share にアクセスできるようにします:

# semanage がインストールされていない場合
$ sudo yum install policycoreutils-python

# ラベル設定
$ sudo semanage fcontext -a -t samba_share_t /srv/share
$ sudo restorecon /srv/share/

Samba サーバーの設定をします。今回は /etc/samba/smb.conf に次のような設定を追加します。
最後の vfs objects の設定がミソです:

[share]
 comment = Shared Directory
 browseable = yes
 writable = yes
 guest ok = no
 path = /srv/share
 vfs objects = btrfs snapper

Snapper の設定をします。スナップショットの残し方の設定は openSUSE と共通なので、スライドを参照して下さい:

$ sudo snapper -c smb-share create-config /srv/share

ユーザアカウント geeko がスナップショットにアクセスできるようにします。設定ファイルの直接編集も可能です:

$ sudo snapper -c smb-share set-config ALLOW_USERS=geeko

Samba サーバーを立ち上げましょう。まずはファイアウォールを開けて:

$ sudo firewall-cmd --add-service=samba --permanent
$ sudo firewall-cmd --reload

サービスの自動起動設定をし、smb サービスを開始します:

$ sudo systemctl enable smb.service
$ sudo systemctl start smb.service

ユーザー geeko を Samba サーバーのユーザーに追加し、パスワードを設定してログインできるようにします。

sudo pdbedit -a geeko

あとは Windows からアクセスして、右クリックして、「以前のバージョン」タブを開くだけ…なのですが、なんと Samba サーバーが Snapper に接続する際に、SELinux が拒否してしまいます。次のようなログが /var/log/audit/audit.log にしっかり記録されています:

type=USER_AVC msg=audit(1452273485.220:943): pid=534 uid=81 auid=4294967295 ses=4294967295 subj=system_u:system_r:system_dbusd_t:s0-s0:c0.c1023 msg='avc: denied { send_msg } for msgtype=method_call interface=org.opensuse.Snapper member=ListConfigs dest=org.opensuse.Snapper spid=16293 tpid=16588 scontext=system_u:system_r:smbd_t:s0 tcontext=system_u:system_r:snapperd_t:s0-s0:c0.c1023 tclass=dbus exe="/usr/bin/dbus-daemon" sauid=81 hostname=? addr=? terminal=?'

Samba から Snapper にアクセスを許可するポリシーを作成してみます。次のような samba-snapper.te を作成し

module samba-snapper 1.0;
require {
  type smbd_t;
  type snapperd_t;
  class dbus { send_msg };
}

allow smbd_t snapperd_t:dbus { send_msg };

ルールをビルドします:

# Makefile がインストールされていない場合
$ sudo yum install selinux-policy-devel

# ビルド
$ make -f /usr/share/selinux/devel/Makefile

作成した samba-snapper.pp をシステムにインストールすると、以前のバージョンにアクセスできるようになります。

sudo semodule -i samba-snapper.pp

CentOS で以前のバージョンに対応したファイルサーバーを構築する方法を紹介しました。ぜひ、スライドで紹介している openSUSE で YaST を使った設定と比べてみて下さい。