このテキストについて
このテキストは次の授業で使用されている標準化された教材です。
- Linux基礎
実際の授業では解説が加わる上に、生徒様に合わせて教材は制作・調整されるため、 このテキストよって得られる理解がMimir Yokohamaの授業のすべてではないことを予めご理解ください。
Linuxとフォント
Linuxでのフォントの扱いはX Window Systemによって提供されています。
古のUnix
かつてUnixでは主に点描であるビットマップフォントを扱っていました。
早い時期に線で書かれたアウトラインフォントが採用されましたが、 基本的にはビットマップを中心とした考え方はかわらず、 「フォントサイズごとにビットマップフォントを指定する」という仕組みを採用していました。
PCFビットマップフォントはX Serverの実装であるX11によってサポートされているビットマップフォントです。 これは次のような論理名を持っていました。
-adobe-courier-bold-o-normal--14-100-100-100-m-90-iso8859-1
これは
- adobe: 提供者
- courier: フォント名
- bold: フォントの太さ
- o: フォントの傾き
- normal: フォントの幅
- 14: ピクセルサイズ
- 100: ポイントサイズ
- 100: X解像度
- 100: Y解像度
- m: スペーシング
- 90: 平均フォント幅
- iso8859-1: 文字集合
となっています。
アウトラインフォントではないため、どう考えてもピクセル数とポイント数が釣り合いませんが、 そもそもUnixではビットマップフォントをスケーリングすることはできなかったため、 「14ピクセルで表示するときは14ピクセルのフォント、16ピクセルなら16ピクセルのフォント」が必要でした。
なお、画面上の点を示す“Pixel”という言葉は“Picture Element”または“Picture Cell”に由来すると言われています。
Unixでのアウトラインフォントは.pfa
という拡張子でしたが、これはPostScriptフォントであり、 Windowsで採用されていたpfbフォントと同様のものです。 ただし、アウトラインフォントを使用する場合でも、ピクセル数ごとに指定する必要がありました。
表示するに当たっては必ずなんらかのフォントが指定されている必要があったのですが、例えば長く日本語対応のターミナルエミュレータとして親しまれてきたktermでのフォント指定においては
kterm -fn '-*-fixed-*--16-*' -fk '-*-fixed-*--16-*'
のようにして指定していました。この場合、16ピクセルの任意のフォントのうち、Xが列挙するフォントで最初に出現する ものを使用します。
フォントを要求するプログラムはそれぞれデフォルトで、あるいは設定ファイルによって要求すべきフォントが定められており、プログラムの起動時に常に指定する必要はありません。
この機能は“XCore”というフォントシステムです。
ちょっと昔のLinux
フォント周りに関しては乱立していた時代があります。
優勢だったのはクライアント/サーバーシステムをとるXftというフォント管理システムを利用することです。 XftのフォントサーバーはXfsといい、各プログラムはXfsにフォントを要求し、そうするとXfsがXftを利用してフォントを得る仕組みです。得てきたフォントはFreeTypeフォントレンダリングエンジンによって描画されます。
ただし、実際はこんなに単純な話ではありません。極めて複雑な仕組みでした。 Linuxのフォント設定は
- Xfsの設定
- アウトラインフォントのためのFreetypeの設定
- ビットマップフォントのためのXCoreの設定
の3つがあり、高機能な分、非常に専門的な情報を扱う必要がありました。
このような仕組みは無駄だと考えられ、X向けのグラフィックスライブラリであるcairoはXftを使用せず、直接FreeTypeでのレンダリングを行うようになりました。
このことから、「Xfsを使うものと使わないものがあり、Xfsを使うものはXfsのフォント設定が反映されるが使わないものには反映されない」という状況がありました。
現在のLinux
Xfsは廃止に向かっています。
FreeTypeはFreeType2となりました。 今や、GtkあるいはQtで書かれたソフトウェアを扱う限りはFreeType2のことだけを考えていれば良いでしょう。 Cairo, Pango, QtのいずれもWaylandに対応しており、その上でFreeType2もWaylandに対応しているため、 もし仮にX window systemが使われなくなる日がきたとしても問題ありません。
むしろ、「X window systemに依存しない、FreeType直接の取り扱い」というのはWaylandにつながる道だとも言えます。
ではその内容を見ていきましょう。
まず、Cairoとはクロスプラットフォームでデバイスに依存しないベクトルベースの2D描画ライブラリです。 Cairoを使うことでプログラムは様々な事情を気にせずベクトルベースのグラフィックスを描画できます。
PangoはGtk用のテキスト組版ライブラリです。 ここでいう組版は画面上の話であり、行列を持って文字を並べる、という機能があります。 Pangoには縦書き機能もあります。1
QtはPangoを利用しておらず、独自にテキストレイアウトを行っています。
さらに、FLOSSにおけるテキスト標準化の取り組みとしてHarfBuzz2があり、HarfBuzzの成果はPangoとQtの共通ライブラリとして採用され、現在はPango, Qtの共通ライブラリとして使用されています。
現在、描画やフォントに関することでX window systemの存在を気にする必要はありません。 気にする必要があるのはこのようなライブラリであり、 もしこれらのライブラリが変更されることがあれば劇的な違いとなって現れるでしょう。
しかし、PangoやCairoをユーザーが意識することはありません。 FreeTypeですらあまり気にする必要はなく、FreeTypeのフォント設定ライブラリであるFontConfigだけを気にすることになるでしょう。
ここまで言葉のおさらいです。
名前 | 現用 | 機能 |
---|---|---|
FreeType | yes | フォントレンダリングエンジン(大抵は2のこと) |
FreeType2 | yes | フォントレンダリングエンジンの新しいバージョン |
Xft/Xfs | no | FreeTypeを使ったフォントサーバー |
XCore | no | X window system本来のフォント機能 |
Cairo | yes | グラフィックス描画用のライブラリ |
Pango | yes | Gtkでテキストをレイアウトするためのライブラリ |
Qt | yes | GUIツールキット。テキストレイアウト機能もある |
HarfBuzz | yes | テキストレイアウトエンジン。PangoとQtで使われている |
FontConfig | yes | フォント設定用ライブラリ |
PangoとHarfBuzzの関係ですが、QtとPangoはHarfBuzzをベースにしつつ、 それぞれが従来もっていてHarfBuzzにない機能を追加したものになっており、 例えばPangoでは縦書きができますが、HarfBuzzではできません。 そのため、Pango, QtともにHarfBuzzを使っていますが、縦書きが可能なのはPangoを使用するGtkだけです。
他環境とLinuxのフォントの美しさについて
ここではフォントレンダリングエンジンの話をしますが、フォントレンダリングエンジンと、フォントレンダラ、そしてフォントラスタライザという言葉は全て同じものを指しています。
レンダリングとは描画することをいいます。 ラスタライズとはベクターグラフィックスをラスター(点描)に変換することをいいます。
Linuxのフォント表示は美しいと言われています。 これはFreeType採用によってアンチエイリアス機能が採用されたためです。
アンチエイリアスとはなんでしょうか。 ディスプレイの特性上、表示されているものは点描であり、ピクセルよりも小さな単位で表示することができません。 そのため、アウトラインフォントを使ってもどうしてもギザギザに見えることとなり、特に小さなフォントではそれが目立ちます。 そこで本来描画すべき点の周囲に淡い色で描画を行い、視覚上「にじませる」ことでギザギザを目立たなくするものです。
美しいフォントレンダリングといえば、Core Textを採用するMac OS Xがあります。 アンチエイリアスが美しいとされ、現在においても表示の最高峰となっています。 ごく一時期リリースされていたWindows版SafariにはCore Textが搭載され、話題となりました。 Linuxで使われているFreeTypeは、Core Textに倣ったものです。
線数の多い和文においては可読性が求められる一方で、醜さも目立ちます。 アンチエイリアスのにじみによってアルファベットが解読不能になるのはよほど小さな文字であるときだけなのに対し、日本語であれば簡単に読めなくなります。 ところが、アンチエイリアスを有効にし、求めてきたのは日本人です。
一方で実用主義者はこれに賛同しません。ビットマップフォントはそもそもが点描であり、サイズも固定です。ビットマップフォントが適切なサイズで表示される限りはそもそも変換する必要がなく、そのサイズで可読性が確保されるように制作されており、どれほど小さい文字であっても(美しさはさておき)判別可能となっています。
そのため、実用主義者はディスプレイでの日常的サイズではビットマップフォントを使えば良いし、大きな文字を表示させるときにはアウトラインフォントを使えば良いのだ、と考えています。現在は高解像ディスプレイが普及し、ピクセルサイズで固定されたビットマップフォントは物理的に小さく表示されて読めないという問題がありますが、実用主義者は「物理的にピクセルが小さいのであればアンチエイリアスなどいらない」と主張しています。3
GDIというフォントレンダラを使うWindowsのフォントレンダリングはかつてはひどいの一言でした。
ClearTypeはWindowsの新しいフォントレンダリングエンジンです。 WindowsはWindows 7でDirectWriteというテキストレンダリングAPIを用意しました。 これは、レンダリング自体はDirectXによって行うのですが、これがClearTypeが機能するための条件でした。
GDI++というライブラリがあり、これはフォントにこだわるWindowsユーザーの間で流行したものです。 GDI++はWindowsのフォントレンダリングエンジンを置き換え、割り込んでWindowsの標準レンダラーに変わって描画します。
GDI++やMacTypeのようなWindows向けのサードパーティのフォントレンダリングエンジンはWindows 10で排除されましたが、Windowsのフォントレンダリングは、Windows 7でClearType採用にも関わらずひどいままだったものの、これについては改善の方向にあります。
「Windowsのフォントレンダリングが汚い」ということはMicrosoftも認めており、 しかし一部のソフトウェアはWindowsに頼らずフォントレンダリングをしていることから(例えば一時期のSafariや、現在のSlaipnirブラウザなど)システムレベルでのフォントレンダリングの変更は古いアプリケーションで支障をきたす可能性があるために変更できない、ということです。
ただし、実際はMicrosoft内部にフォントの改善に否定的な勢力がいることが大きな理由であることは間違いありません。 実際のところ、ウェブブラウザなど利用頻度の高いソフトウェアが独自にフォントレンダリングを行っており、新しいプログラム、特に「Windowsアプリ」として提供されているプログラムは表示が改善していることから改善の見通しに乏しい状況でもあります。
そもそもWindowsのフォントが汚かったのは、記帳なコンピュータリソースをフォント表示に割いてしまわないためで、意図的なものでした。 現在は比較的新しい環境で作られたプログラムはClearTypeが美しく機能するようになっている。この修正は2016年に行われ、さらに現在はアンチエイリアスの調整もできるようになっている。
MacTypeはWindows向けに移植されたFreeTypeを利用するプログラムです。 MacTypeは開発凍結ののち、現在は再始動していますが、Windows 10があまりシステムに関わるプログラムを受け入れないため、難しいところです。
アンチエイリアスの問題は、そもそも「物理的に点が小さくなれば問題自体が縮小する」というものであり、高解像ディスプレイが普及しつつある現状においては目立たなくなりつつあるのも事実です。 しかし、300ppiを越える高解像度液晶においてさえ、依然としてアンチエイリアスは有効です。
Inifnality
InfinalityはFreeTypeにおけるレンダリングを改善するためのパッチです。 Mac OS Xのレンダリングをエミュレーションし、美しい見た目を得ることができます。
フォント表示を改善するテクニックとして「Infinalityパッチの当たったFreeTypeを使う」という手法は長く親しまれてきましたが、 FreeType 2.7においてInfinality相当の機能が取り込みとなりました。
これにより、Infinalityパッケージはobsolateとなり、 /etc/profile.d/freetype.sh
において
truetype:interpreter-version=38
とすることでInfinality相当のサブピクセルレンダリングを行います。
FontConfig
FontConfigの役割
FontconfigはLinuxのフォント設定ライブラリです。
Fontconfigはフォントを使用するアプリケーションに対して「何のフォントを」「どのように表示すべきか」という情報を提供します。
この大きな意味としてはフォントの物理名のほかに論理名を与えることができるということです。 代表的なものとして、以下の論理フォント名が使われています
- sans-serif
- serif
- monospace
これらはフォントの形状の名前であり、フォントの名前ではありません。 例えばmonospaceは等幅フォントを意味しており、monospaceという名前のフォントが存在しているわけではないのです。 しかし、アプリケーションは予めどのフォントを選択すべきかという情報を与えられなくても適切に表示できるよう、このような論理フォント名によるアクセスを行います。
私の環境でmonospace
フォントは次のように選択されています。
$ fc-match monospace
VL-Gothic-Regular.ttf: "VL ゴシック" "regular"
つまり、アプリケーションがmonospace
を要求すると、FontConfigはVL-Gothic-Regular.ttf
ファイルに定義されているVL ゴシック
を表示するように指示するわけです。
また、Yahoo Japanのページを見ると、表示フォントとして次のような指定がなされています。
MS PGothic
はMicrosoft WindowsにバンドルされているMS Pゴシック
フォント、 Hitagino Kaku Gothic ProN
及びOsaka
はMacにバンドルされているフォントです。
最終的にはsans-serif
が指定されていますから、ウェブブラウザは当該論理名のフォントがなければ最終的にsans-serif
を使用します。 では、sans-serif
の指定がなかったらどうなるのでしょうか?4 この場合、ウェブブラウザはFirefoxでもChromeでもウェブブラウザが当該要素におけるデフォルトのフォントを要求します。 これは通常の段落内のフォントであるため、Firefoxはserif
を、Chromeはsans-serif
を要求します。
このフォント選択においては、ウェブブラウザは論理名があるかどうかだけを確認しており、その論理名のフォントを要求していません。 実際にFontConfigに対して要求するのはsans-serif
あるいはserif
ということになります。 では、アプリケーションがMS PGothic
を要求した場合はどうなるのでしょう。
その場合、FontConfigは「それっぽいフォントを適当に見繕って」返します。 明示的に指定されている場合は、sans-serif
, serif
, monospace
のいずれかのフォントを返すことがほとんどです。 ただし、Courier New
を要求したときに、当該フォントがなければCourier
を返す、といった挙動を示す場合もあります。
もちろん、FontConfigの設定によって、特定の論理名に対して特定のフォントを返すようにすることもできます。
FontConfigがどのようなフォントを選択するかについては、fc-match
コマンドで確認することができます。
$ fc-match Courier
NimbusMonoPS-Regular.otf: "Nimbus Mono PS" "Regular"
また、fc-list
コマンドによってFontConfigが認識しているフォントを列挙することもできます。
FontConfigの設定
FontConfigの設定は多くの場合、/etc/fonts/conf.avail
ディレクトリにインストールされています。 有効な設定は/etc/fonts/conf.d
です。
/etc/font/conf.d
内に/etc/font/conf.avail
ディレクトリ内のファイルへのシンボリックリンクを張ることでその設定を有効化することができます。 また、/etc/fonts/conf.d
からリンクを削除することで設定を無効化できます。
日本語の場合は65-nonlatin.conf
を有効にするほうが良いでしょう。 また、ビットマップフォントを嫌うのなら70-yes-bitmaps.conf
を無効化し、70-no-bitmaps.conf
を有効化します。
ユーザーごとの設定ファイルは$XDG_CONFIG_HOME/fontconfig/fonts.conf
にあります。 設定ファイルはXML形式で、
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<!-- settings go here -->
</fontconfig>
という形式になっています。例えばMS PGothic
をUme P Gothic S5
に置き換えるには次のようにします。
<match target="pattern">
<test qual="any" name="family">
<string>MS Pゴシック</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>Ume P Gothic S5</string>
</edit>
</match>
OsakaやMS PGothicを要求されるとぐちゃぐちゃなフォントが表示される場合があるため、置き換えておいたほうが良いかもしれません。 次の例は実際に私が使用しているfonts.conf
ファイルです。
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
<!-- ########## RENDERING OPTIONS ########## -->
<match target="pattern">
<edit mode="assign" name="dpi">
<double>103</double>
</edit>
</match>
<match target="font">
<edit mode="assign" name="autohint">
<bool>false</bool>
</edit>
</match>
<match target="font">
<edit mode="assign" name="lcdfilter">
<const>lcddefault</const>
</edit>
</match>
<!-- ########## BASIC FONT ALIASES ########## -->
<match target="pattern">
<test qual="any" name="family">
<string>sans-serif</string>
</test>
<edit mode="assign" name="family" binding="strong">
<string>Sen</string>
<string>Source Han Sans JP</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>sans</string>
</test>
<edit mode="assign" name="family" binding="strong">
<string>Sen</string>
<string>Source Han Sans JP</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>serif</string>
</test>
<edit mode="assign" name="family" binding="strong">
<string>Source Han Serif JP</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>monospace</string>
</test>
<edit mode="assign" name="family" binding="strong">
<string>Monoid</string>
<string>Migu 1M</string>
</edit>
</match>
<!-- ########## SUBSTITUDE POPULAR FONTS ########## -->
<match target="pattern">
<test qual="any" name="family">
<string>MS Pゴシック</string>
</test>
<edit mode="assign" name="family" binding="same">
<string>Sawarabi Gothic</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>MS PGothic</string>
</test>
<edit mode="assign" name="family" binding="same">
<string>Sawarabi Gothic</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Osaka</string>
</test>
<edit mode="assign" name="family" binding="same">
<string>MotoyaLCeder</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Helvetica</string>
</test>
<edit mode="assign" name="family" binding="same">
<string>Raleway-v4020</string>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Arial</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Raleway-v4020</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>0</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Segoe UI</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Selawik</string>
</edit>
</match>
<!-- ########## Kana Only fonts ########## -->
<match target="pattern">
<test qual="any" name="family">
<string>imagine YOKOHAMA</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>imagine YOKOHAMA</string>
<string>Source Han Serif JP</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>0</int>
</edit>
</match>
<!-- ########## Latin monospace fonts ########## -->
<match target="pattern">
<test qual="any" name="family">
<string>Envy Code R</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Envy Code R</string>
<string>Migu 1M</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Hack</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Hack</string>
<string>Migu 1M</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Hermit</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Hermit</string>
<string>Migu 1M</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Input Mono</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Input Mono</string>
<string>VL Gothic</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>monofur</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>monofur</string>
<string>HC Maru Gothic</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>agave</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>agave</string>
<string>HC Maru Gothic</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Anka/Coder Condensed</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Anka/Coder Condensed</string>
<string>Migu 1M</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Anka/Coder Narrow</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Anka/Coder Narrow</string>
<string>Migu 1M</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>NovaMono Regular</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>NovaMono Regular</string>
<string>Migu 1M</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>NovaMono</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>NovaMono</string>
<string>Migu 1M</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<!-- composited Latin + Japanese font -->
<match target="pattern">
<test qual="any" name="family">
<string>Input Sans Condensed</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Input Sans Condensed</string>
<string>MotoyaLMaru</string>
<string>MotoyaLCeder</string>
<string>MMCeder P</string>
<string>Migu 1C</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<match target="pattern">
<test qual="any" name="family">
<string>Input Serif Condensed</string>
</test>
<edit mode="prepend" name="family" binding="same">
<string>Input Serif Condensed</string>
<string>Source Han Serif JP</string>
</edit>
<edit mode="assign" name="spacing" binding="strong">
<int>90</int>
</edit>
</match>
<dir>~/.fonts</dir>
<match target="font">
<edit mode="assign" name="hinting">
<bool>true</bool>
</edit>
</match>
<match target="font">
<edit mode="assign" name="hintstyle">
<const>hintslight</const>
</edit>
</match>
<match target="font">
<edit mode="assign" name="rgba">
<const>rgb</const>
</edit>
</match>
</fontconfig>
詳しい情報はArchWikiを見ると良いでしょう。
フォントのインストール
システムのフォントは/usr/share/fonts
以下にインストールされます。 再帰的に検索されるため、ディレクトリを作っても構いません。
ユーザーのフォントディレクトリは$HOME/.fonts
です。 システムにない独自のフォントを使用する場合はこのディレクトリに放り込むことになります。
Javaにおけるフォントレンダリング
Javaの標準ツールキットであるAwtが独自にフォントレンダリングを行うため、 アンチエイリアス設定が反映されません。
Awtでアンチエイリアスを有効にするにはJavaのオプションとして
-Dawt.useSystemAAFontSettings=lcd -Dawt.useSystemAAFontSet
tings=on -Dswing.aatext=true -Dsun.java2d.opengl=true
を渡します。 これを環境変数$_JAVA_OPTIONS_
に設定するのが一般的です。
DPI
1inchあたり(平方インチではなく)にいくつのドットがあるか、ということを指してDPI(Dot Per Inch)あるいはPPI(Pixel Per Inch)といいます。
長年、Macでは72dpi, Windowsでは96dpiという暗黙の了解がありましたが、現在は実際はそのような値からはかけ離れています。
一般的なモニタのおおよそのDPIは次のようになっています。5
ディスプレイサイズ | FWXGA (1366x768) | FullHD (1920x1080) | WQHD (2560x1440) | 4k (3840x2160) |
---|---|---|---|---|
4.7 | 333 | 469 | ||
5 | 313 | 441 | 587 | 881 |
5.5 | 285 | 401 | 534 | 801 |
6 | 261 | 367 | 490 | 734 |
10.1 | 155 | 218 | 291 | 436 |
12.1 | 130 | 182 | 243 | 364 |
13.3 | 118 | 166 | 221 | 331 |
14.0 | 112 | 157 | 210 | 315 |
15.6 | 100 | 141 | 188 | 282 |
21.5 | 73 | 102 | 137 | 205 |
24 | 65 | 92 | 122 | 184 |
27 | 58 | 82 | 109 | 163 |
31.5 | 50 | 70 | 93 | 140 |
Linuxシステムでは設定されていなければ96DPIであるとみなします。 フォントサイズ「ポイント」は物理的な大きさであり、いくつ点があればその物理的な大きさに達するかはDPIを元に計算します。
1ポイントは0.0138889インチです。 10ポイントは0.138インチ、1インチで96の点を描くのですから、10ポイントの領域には13.248個の点、ピクセルは半端な数は書けないので13個のピクセルを描くことになります。 この計算によって、DPIが設定されていない限り、物理的にどのようなモニターを使用していたとしても13ピクセルを描画します。
さて、あなたがDell XPS13の4kモデルを使用していたとします。DPIは331です。 「10ポイント」と思って描いた13ピクセルは、実際は0.04インチまで縮小してしまいます。 0.04インチとは2.88ポイントです。 10ポイントの文字ならば小さいものの読める文字ですが、2.88ポイントは虫眼鏡が必要かもしれません。 これは、誤ったDPI設定の結果「10ポイント」と指定して描画した文字は2.88ポイントで描画されるということです。
これを修正するために、最近のデスクトップ環境ではフォントのDPIを設定することができるようになっています。 これは、FontConfigの設定に反映する形で行います。
しかし、実のところ問題は決して文字だけではありません。 実際のDPIが設定されたDPIの倍になれば、アイコンもボタンもその面積は1/4になるということです。 これはとても不便です。120DPI程度までであればそれほど苦労しませんが、140DPIにもなると「明らかに小さい」と感じます。
DPIの設定はX.Orgも保有しています。 X.OrgサーバーはDDC(VESA Display Data Channel)によって正しい画面サイズを自動検出しますが、できていない場合も多々あります。
$ xdpyinfo | grep -B2 resolution
ひとつの方法として、X.Orgの設定ファイルとしてディスプレイのサイズを記述するという方法があります。
あるいは、Xrandrツールを使用できる環境であれば、これを使う方法もあります。 (永続化するためにはXProfileとして記載します。)
$ xrandr --dpi 331
GtkやQtなどにおいて物理的な寸法で記述されているパーツはこのDPI変更によって自動的にスケールされます。 Qtにおいてはこれだけで問題を解決することができます。
Gtk3は$GDK_SCALE
及び$GDK_DPI_SCALE
環境変数で調整できますが、あまりうまくいきません。 しかも、UIコンポーネントを設定する$GDK_SCALE
は2倍、3倍という単位でしか調節できません。
さらにデスクトップ環境によってはFontConfigで明示的にDPIを指定する必要がある場合もあります。
このようなHiDPIサポートはWindowsよりMacより先にLinuxが行っているにも関わらず、あまり快適に動作しません。 最も良い解決方法は(GTKアプリケーションを使う場合であっても)KDE Plasmaを使用するという方法です。
KDE Plasmaを使用する場合は次の方法でほとんどの環境で良い動作を得られます。
- ディスプレイサイズを設定する
- KCMから明示的にフォントのDPIを設定する
ただし、この場合でもlightdm greeterのサイズは別問題となります。 greeterの設定を変更してこの問題を改善できます。 gtk-greeterを使用している場合は、
/etc/lightdm/lightdm-gtk-greeter.conf
に
xft-dpi=331
のように記述を追加します。
未来
HarfBuzzはHarfBuzz-NGとして再構築を行っています。
X window systemを廃止してWaylandに移行する動きがあります。
Waylandはディスプレイへの描画を管理するものであり、ウィンドウの位置や重なりを管理し、適切に重って表示されるようにします。 WaylandはX window systemのようなものではなく、あくまでディスプレイ上での表示の管理しか行いません。 ウィンドウマネージャがグラフィックスハードウェアとのやりとりや、アプリケーションとのやりとりをする際にXを介する構造ではなく直接やりとりをするようになります。 キーボードなどの入力ハードウェアの管理もWaylandは行いません。
WaylandはX window systemのようなロスがなく、優れた応答性と低負荷が期待されています。 その仕組み自体はWindowsに近いものです。 しかし、大部分を外部に頼る仕組み上、入力処理やハードウェアリソースの管理においてライブラリが乱立してしまうと、 まともに機能せず、設定も散らばってしまう可能性があります。
また、X window systemの便利な機能は使えなくなります。
Pangoという名前はギリシャ語で「全て」を表すPanに、日本語の「語(Go)」を組み合わせたものです。↩
こちらはペルシャ語です。↩
これはある程度正しい主張です。判別しやすさはアンチエイリアスがない方が良好であり、300ppiあるようなディスプレイではアンチエイリアスはないほうが読みやすく疲れにくいという主張があります。一方、300ppiあってもアンチエイリアスは有効であるほうが美しく感じるということも分かっています。↩
日本語のページであるにも関わらず、欧文フォントであるArialを指定しているのは、非常に「悪い」ことだと考えられます。↩
“網膜の解像度は300DPIなので、300DPIに達するとドットを視認できなくなる”という説があります。しかし、実際はディスプレイと目の距離もありますし、そうはいきません。しかし300DPI前後に到達すると非常になめらかに見えるのは事実です。↩