文章、見えてますか?
コンピュータは機械的に文章を表示します。
この文章が表示されるまでにも様々な処理を経ているわけです。
今回は、その処理をざっくりと説明します。
(昨日のアドベントカレンダーの1.と2.の内容に相当します)
アプリやブラウザ上に文字を表示させることは多いと思いますが、これは画像の表示に比べるとずっと曖昧でふんわりとしたものです。
つまり、非常に複雑な処理が発生しています。
なぜ文字が見えるのか?
ではどうしてディスプレイには文字が表示されているのでしょうか。
ここで重要な役割を果たすのが
- 文字コード
- フォント
- 文字列描画システム
この2つです。
1.文字コード
これは機械を使う人同士でのプロトコルです。
つまり、この値はこの文字に相当するものとして扱いましょうという約束です。
ただし、世界にはこうした約束がいくつもあります。
世で一般にテキストファイル(*.txt
)と呼ばれるものは、こうしたいくつもある約束のいずれかに則ってデータを書き込んでいるわけです。
ただ、ここで問題になるのが、そのテキストファイルが一体どの文字コードで書かれているのかという点です。
つまり、もっと具体的に言うと、テキストファイルはUTF-8
なのかShift_JIS
なのかということです。
これを機械側が確実に知るのは難しく、また、人間にも難しい問題です。
これがよくいう「文字化け」の原因です。
(UnicodeのテキストならいわゆるBOMと呼ばれるものがあると非常に助かります)
この文字コードに従ったバイナリ情報を人間の目と脳に優しい画像情報にするための情報が詰まっているのがフォントです。
2. フォント
フォントは上に出てきた文字コードに準って、ディスプレイ上に適切な文字を表示するためのデータが含まれたファイルです。
つまり、
- コードポイントをフォント中のグリフIDに変換する(OpenTypeの
cmap
)- 全てのコードポイントに対応しているわけではない
-
cmap
は文字コードや役割で複数あったりもする
- IDに対応するグリフには文字を描画するための情報が格納されている
- OpenTypeフォントではPostScript系、TrueType系の2種類のアウトラインデータフォーマットがある
- ビットマップフォントも存在しうる(Windowsのカクカクしたやつ)
- カラー絵文字も存在しうる(PNGだったりアウトラインデータと色情報だったり色々)
-
SVG
も存在しうるようになった(つらい)
- さらに文字と文字の配置を調整したり、適切に変形させたりする情報もある(オプション)
- 特に
GSUB
,GPOS
が様々な仕事をする - 最近はバリアブルフォントというのも出た
- 特に
ところで先ほどは文字化けの話をしましたが、実はもう一つ文字化けと呼ばれるだろう事象がフォントの世界にもあります。
\
と¥
さてここのサブタイトルは、同じ文字でしょうか、違う文字でしょうか。
Qiitaのフォント指定がいい感じならほとんどの環境で違う文字に見えていると思います。
もし、Windowsの方がいればこの**\と¥**をコピーしてメモ帳などに貼り付けてみましょう。
どうなるでしょうか?
Windowsのレガシーな文字コードではバイナリで言うところの0x5C
は各地の通貨記号でローカライズすることが多く、日本もその例外ではありませんでした。
つまり、UnicodeでのREVERSE SOLIDUS (U+005C) に対応するコードポイントが円記号(中国元の記号でもある)に置き換えられていました。
日本語のWindowsのファイルパスでよく見るやつですね。
これはWindowsに収録されているフォントの0x5C
に対応するグリフがShift_JISだけではなくUnicodeのcmap
でも同じく円記号にマップされているために起こる問題です。
つまり、文字コードではなくフォントへの信頼が仇となるパターンです。
少し似た問題として、全角チルダ/波ダッシュ問題というものもあります。
気になる方は調べてみましょう。
文字列描画システム
文字コードとフォントだけがあってもそれらを人間が感じ取って脳内で適切に理解することは難しいです。
そのため誰かが両方の仕様を把握し、コンピュータに処理させて人間の理解できる出力に変換しなければいけません。
それが文字列描画エンジンです。
つまり、何かしらの文字コードに従った文字列を、フォントの情報を適切に解釈して画像にしてくれるのが文字列描画エンジンです。
GUIな環境を持つOSや各種ブラウザなどがこれを持っています(TATEditorも)。
適切に解釈すると言うのは具体的には、縦書き日本語で縦書き用にグリフを変更したり、英語で文字間の距離を調整したりfiを一つのグリフで表示したり、アラビア語で単語の頭と中間と末尾で違うグリフを使ったりしないといけません。(もっと詳しいことはまたいずれ話せたらいいなあ)
フォントフォールバック
ひとつのフィントに収録できるグリフの最大数は仕様上65536個までです。
そのため、昨今の多言語化する情報をすべて表示するためには数が足りません。
そこで多くの文字列描画システムは、対応するグリフが存在しない場合には他のフォントからグリフを持ってきて穴埋めすると言う処理を行います。
これがフォントフォールバックです。
ところでここのフォントは何?
難しい質問ですね。
Chromeの拡張機能などは使用されているフォントを教えてくれたりしますが、厳密に知りたいのであれば役には立ちません。表示されているグリフがどのフォント由来なのかを確実に確かめる方法は現状ほぼ皆無です。
これは上で述べたようなフォントフォールバックのシステムがあるためです。
HTML/CSSではどのフォントを優先して使用してほしいという指定はできますが、それがなければ代替フォントが使用されるのでブラウザの描画処理を直接追わないといけません。少なくともCSS 2.2の仕様では、指定されたフォントとデフォルトフォントでマッチするグリフがなければブラウザ側で適当に処理してもいいと書いてある。
つまり闇の技術です。
ちなみにTATEditorならどのフォントのどのグリフが使われているのか簡単にわかりますよ(宣伝)。
一番下のU+xxxxの後ろがフォント番号とグリフID。
おわりに
今日も今日とて当日に書いた記事になってしまいました(2230から書いてます)。
明日も何か書きます。