絵文字フォントとHTMLの関係
初回投稿日時: 2004年08月16日00時48分48秒
最終更新日時: 2004年08月16日03時30分53秒
カテゴリ: HTML
固定リンク: id=2004081600
SNS:
(list)
最近、為になるような情報が全然無いので、えむもじらのシンボルフォントのまとめを技術的に解説して、少し、このWeblogに肉をつけておきましょう(笑)
最初に謝っておきます。ごめんなさい。Web標準普及プロジェクトに追記した内容は間違ってます。まだ文字コードにあまり詳しくない時に記述したので誤解を記述してました。こちらで書く情報の方が正確です。(訂正しておかなくては……)
では本題。HTMLというのはISO 10646、いわゆるUnicodeで処理すべきであることはもう説明の必要も無いかと思います。これに従うという意味合いと、アプリケーションの国際化のためにMozillaやOperaといったアプリケーションはUnicodeを処理基準として設計されています。それに対してlevelさんの検証結果を見る限り、IEはそのような設計ではないようです。じゃ、どういった設計なのかということですが、いまいちその詳細がパッと見では分かりません。しかし、最終処理であるテキストの表示処理は、Win32SDKでANSIと呼ばれるCPに依存した処理が行われているようです。つまり、日本語の場合はCP932、Shift_JISのWindows版で処理されていると思われます。
このように、IEの処理はいまいち分からないのですが、Mozilla/Operaの表示結果は非常に分かり易い素直な結果です。理由はこの後述べますが、Mozilla/Operaの表示が普通の結果です。では、levelさんが検証に使われたテストケースを引用しておきましょう。これを元に解説してみます。
<font face="Wingdings">JKL</font>
この例はUnicode変換を行うことで次のように記述しなおせます。
<font face="Wingdings">JKL</font>
Unicodeにおいて、U+004A
、U+004B
、U+004C
というのはBasic Latinにあたります。
さて、ここでWin32プログラミングについての話をしておきましょう。Win32プログラムはフォントの情報をWin32APIを介して取得できます。その中にフォントに含まれるグリフの情報を示すCharSetという情報があります。この情報は複数のフラグの組み合わせで取得することができ、その種類の中にISO 8859-1の文字列を表すANSI_CHARSET
、(特殊)記号を表すSYMBOL_CHARSET
というものがあります。
文字表示をUnicodeに完全に対応させるにはひとつのフォントだけで表示しようとするのは賢明ではありません。ひとつのフォントで全ての文字列を含んでいることはまず、無いからです。しかし、実用レベルで考えるなら、CharSet単位でなら、その範囲の文字を全て持っていると仮定できます(逆に言えば、そうでは無いフォントは使い物にならない)。これだけの情報があればWin32プログラムの文字表示の仕組みが分かってくると思います。
さて、話を元に戻してみましょう。上記例で表示しようとした文字はなんだったでしょうか?
そう、UnicodeのBasic Latinです。これはCharSetで言うと、ANSI_CHARSET
にあたります。上記例を表示しようとするロジックを机上でシミュレートしてみましょう。
まず、利用するフォントはWingdings
という指定があります。ここでプログラムはWingdings
にANSI_CHARSET
が含まれているのか確認する必要があります。すると、Wingdings
はANSI_CHARSET
を持っていません。
Unicode対応のフォントビューアで確認するとわかるのですが、Wingdings
はBasic Latinにあたる領域に絵文字を持っているのですが、CharSetにはANSI_CHARSET
のフラグを持ちません。つまり、Win32プログラムから見ると、このフォントはBasic Latinのグリフを持っていないのです。
では、シミュレーションを再開しましょう。Wingdings
が持っているフラグはSYMBOL_CHARSET
ですのでBasic Latinの表示には使えません。そこで、ANSI_CHARSET
フラグを持つ別のフォントを探すことになります。この探すロジックはプログラミングに依存しますが、通常、ユーザが設定しているフォントをまず調べます。すると、普通、常用されるようなフォントはANSI_CHARSET
フラグを持っているので、そのフォントを代替フォントとして利用し、描画を行うことができます。ほら、そうすると、Mozilla/OperaのようにJKLと表示されたでしょう?
なんだかノリが変になってきましたが、こういうことです。要約すると、
- 表示しようとした文字は
ANSI_CHARSET
にあたる、"JKL
"
- その表示に指定されたフォントは
Wingdings
Wingdings
はCharSetにSYMBOL_CHARSET
しか持たない
Wingdings
はJKL
の表示には使えない
- 代わりのフォントを探すと、通常はアルファベットのJ、K、Lというグリフを持つフォントが見つかり、そのフォントで表示を行う
となります。