2007-04-27

IPAフォントによるFirefoxの文字化け

以前から気になっていたIPAフォントを利用する際に発生するFirefoxの文字化け(グリフのコードポイント34個分のずれ)に関して、ttt: FreeBSDのMozilla Firefoxで文字化け (というかフォント化け?)にも触れられているが、再現できるわけでもなく、気付いたら発生していて、再起動したら直るという状況だったので、手がつけられないでいた。FreeBSDが悪いのか、Firefoxか、IPAフォントか、ライブラリか、それ以外の設定の問題かさえ、手がかりがなかった。

そんなおり、LANG=ja_JP.eucJPで起動してGoogle Calendarを開き、設定ページに行くと、タイムゾーン選択メニューのGMT+09:00がGM2+09:00に、下の方のGoogleがGMMgleに、確実に化けることがわかった。しかし、LANG=Cでは化けず、LANG=ja_JP.UTF-8やLANG=fooでは化け、意味わからず。しかもAJAXの奥底なので、htmlのコードが得られない。CSSViewerを入れて調べてみたフォントファミリをまねてarial,sans-serifのテキストを書いたりしても化けるわけでもなし。

その後、ここに行くと、起動したてのLANG=ja_JP.eucJP firefoxで確実に化けることを発見。道が開ける。試行錯誤により、LANGに関係なく、次のコードで文字化けさせられるようになった。

<html><head><title>test</title></head><body>
H g<br>
&icirc;<br>
DEFGHIJK defghijk<br>
<b>
DEFGHIJK defghijk<br>
</b>
</body></html>
スクリーンショットはこんな感じ。



つまり、IPAフォントが持っていないようなラテン文字が出てくると、それまでにキャッシュした分は化けないが、それ以外の文字のグリフがすべて34個分ずれる。フェイスが変わると化けない。ここには現れていないが、サイズを変えても化けたまま。Google Calendarの設定ページについても、上の方に言語や国の選択メニューがあり、そこのラテン文字が化けてそれ以降がおかしくなっていたようである。

で、まず、libXftに山のようにデバッグプリントを入れ、XFT_DEBUG=1023にして、ログをとったところ、グリフ番号をキャッシュするためのハッシュ部分は問題なく、文字コードをグリフ番号に変換する部分の問題らしいことをつきとめる。次に、libfontconfigのfcfreetype.cにあるFcFreeTypeCharIndex()にもデバッグプリントを入れ、デフォルトのunicodeエンコーディングでグリフがみつからないと、AdobeSymbol, AppleRomanの順にエンコーディングを試し、みつかるとそのフェイスに対してそのエンコーディングをデフォルトにしてしまうことがわかる。

この先は、フォントの中身まで調べなきゃいけなくなりそうで、結局手に負えないのだろうかと思いつつ、とりあえずfontconfigとipaでググると、fcFontDecodersとか書いてあるそれっぽいブログを一件だけ発見。ueno's codeblog (IPAフォントのグリフ化けを直す)その(2)である。

これによれば、IPAフォント中のグリフ番号が完全に狂ってるとのことで(よく理解してないけど)、親切にもそれを修正するrubyスクリプトまで置いてあった。さっそくありがたく使わせてもらい、ipagp.ttf, ipamp.ttf, ipagui.ttfを修正してみると、文字化けがピタリとおさまった。素晴らしい。化けるメカニズムについては、自分が追跡したことがだいたい合っていたようである。

ただ、'î' (&icirc; = iの上に^)とかが出せないが、どうすればいい?

0 件のコメント: