この日記はMozillaのプロダクトへの貢献者としての私の成果を中心に、気になったバグやWeb界隈の話題について書いていますが、 断り書きがある場合を除き、いかなる団体のオフィシャルな見解ではありません。あくまでも個人的なものです。 Mozilla Foundation、Mozilla Corporation、及び関連企業の公式情報ではないことに注意してください。

現在、XHTML 1.0 (もどき)から、HTML5なコンテンツに修正中です。古い日記は修正が完了していませんので表示が崩れます。 順次、修正していく予定ですのでしばらくお待ちください。

もずはっく日記(2004年8月)

2004年8月16日

絵文字フォントとHTMLの関係
初回投稿日時: 2004年08月16日00時48分48秒
最終更新日時: 2004年08月16日03時30分53秒
カテゴリ: HTML
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">&#x4A;&#x4B;&#x4C;</font>

Unicodeにおいて、U+004AU+004BU+004CというのはBasic Latinにあたります。

さて、ここでWin32プログラミングについての話をしておきましょう。Win32プログラムはフォントの情報をWin32APIを介して取得できます。その中にフォントに含まれるグリフの情報を示すCharSetという情報があります。この情報は複数のフラグの組み合わせで取得することができ、その種類の中にISO 8859-1の文字列を表すANSI_CHARSET、(特殊)記号を表すSYMBOL_CHARSETというものがあります。

文字表示をUnicodeに完全に対応させるにはひとつのフォントだけで表示しようとするのは賢明ではありません。ひとつのフォントで全ての文字列を含んでいることはまず、無いからです。しかし、実用レベルで考えるなら、CharSet単位でなら、その範囲の文字を全て持っていると仮定できます(逆に言えば、そうでは無いフォントは使い物にならない)。これだけの情報があればWin32プログラムの文字表示の仕組みが分かってくると思います。

さて、話を元に戻してみましょう。上記例で表示しようとした文字はなんだったでしょうか? そう、UnicodeのBasic Latinです。これはCharSetで言うと、ANSI_CHARSETにあたります。上記例を表示しようとするロジックを机上でシミュレートしてみましょう。

まず、利用するフォントはWingdingsという指定があります。ここでプログラムはWingdingsANSI_CHARSETが含まれているのか確認する必要があります。すると、WingdingsANSI_CHARSET持っていません

Unicode対応のフォントビューアで確認するとわかるのですが、WingdingsBasic Latinにあたる領域に絵文字を持っているのですが、CharSetにはANSI_CHARSETのフラグを持ちません。つまり、Win32プログラムから見ると、このフォントはBasic Latinのグリフを持っていないのです。

では、シミュレーションを再開しましょう。Wingdingsが持っているフラグはSYMBOL_CHARSETですのでBasic Latinの表示には使えません。そこで、ANSI_CHARSETフラグを持つ別のフォントを探すことになります。この探すロジックはプログラミングに依存しますが、通常、ユーザが設定しているフォントをまず調べます。すると、普通、常用されるようなフォントはANSI_CHARSETフラグを持っているので、そのフォントを代替フォントとして利用し、描画を行うことができます。ほら、そうすると、Mozilla/OperaのようにJKLと表示されたでしょう?

なんだかノリが変になってきましたが、こういうことです。要約すると、

  1. 表示しようとした文字はANSI_CHARSETにあたる、"JKL"
  2. その表示に指定されたフォントはWingdings
  3. WingdingsはCharSetにSYMBOL_CHARSETしか持たない
  4. WingdingsJKLの表示には使えない
  5. 代わりのフォントを探すと、通常はアルファベットのJKLというグリフを持つフォントが見つかり、そのフォントで表示を行う

となります。

関連するかもしれないエントリ

関連するかもしれないエントリを発見できませんでしたが、無いとは限りません。