2007年9月14日金曜日

Mac OS X上のUnicode

http://labs.unoh.net/2007/09/unicode-on-mac.htmlより
Mac OS Xでは、ファイルシステムでUnicodeが用いられています。いわゆるUTF-8なのですが、一般に言うところのUTF-8とは違います。 Macをお持ちの方は、「iconv -l」とTerminalからコマンドを実行してみてください。「UTF-8-MAC」という表示が見つかるかと思います。

一般的なUTF-8では、文字はNormalization Form C(NFC)で 符号化正規化されています。しかし、Mac OS Xのファイルシステムで用いられているUTF-8 (以下、便宜的にUTF-8-MACと呼びます)では、文字はNormalization Form D(NFD)で符号化正規化されます。日本語を扱う際にNFCとNFDでどこが違うかというと、ひらがな・カタカナの濁点・半濁点の扱いです。 UTF-8では「が」は「U+304C」(HIRAGANA LETTER GA)ですが、 UTF-8-MACでは「U+304B U+3099」(HIRAGANA LETTER KA、COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK)となります。
(中略)
しかもややこしいことに、UTF-8で濁点をあらわすコードは「U+309B」(KATAKANA-HIRAGANA VOICED SOUND MARK)で、 UTF-8-MACから送信される「U+3099」(COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK)とは別物です。サーバ側できちんと変換できればよいのですが、 PHPのmbstringモジュールはUTF-8-MACをサポートしていません。(Javaの場合、Java SE 6から導入された java.text.Normalizerクラス を使えば一発で変換できますね。)

また、Mac上で動作する他のブラウザの挙動を調査したところ(「サンバの季節」というファイルをタイトルを変更せずにアップロードした場合)、それぞれの挙動が異なることがわかりました。

ブラウザ フォーム上のタイトル表記 登録されたタイトル
Safari サンバの季節 サンハ
Firefox サンバの季節 サンバの季節
Opera サンハ゛の季節 サンハ

Firefoxは内部的に変換処理を行うようになっているようです。問題はSafariとOperaですね。選択されたファイルのパスからJavaScriptでファイル名を抜き出してタイトルに設定する部分で、正しく扱えるような文字コードに変換することにしたいと思います。

基本的な流れとしては、UTF-8-MAC特有の「U+3099」(COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK)、「U+309A」(COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK)がファイル名に含まれている場合は、その前の文字と結合して濁音・半濁音の文字にしてあげればいいでしょう(ひらがな・カタカナのみの暫定的な対処に過ぎませんが)。

で、この件に関してhttp://d.hatena.ne.jp/odz/20070904/1188884960
何のことを言っているか分からない人のために。

Unicode では、濁音/半濁音/アクセント記号(ウムラウト等)がついた文字を合成文字1文字(ガ(U+30AC))で表すことも、基底文字 + 結合文字(カ(U+30AB) + ゛(U+3099))で表すこともできる。前者の方法で正規化したものを NFC(Normalization Form Composition)、後者で正規化したものを NFD(Normalization Form Decomposition)という。他にも NFKC と NKFD があるが略。これは文字の表現形式の話で、エンコーディングとは違うレイヤの問題なんだけども、非 Unicode のエンコーディングには結合文字というのがないのが普通なので、NFD のままだとエンコーディングの変換に失敗したりする。

でまぁ、普通に入力するとたいてい NFC になっているので問題にならないが、Mac OS X のファイルシステムはファイル名を NFD で格納するので、Mac OS X のファイルを扱うと問題になったりするわけだ。Mac OS X も普通に入力したテキスト自体は NFC になっている。

0 件のコメント: