2007年5月4日金曜日

Unicode正規化 その4

引き続き引用
http://http://tama-san.com/document06.html

Unicode正規化の種類
これまでの流れだと「Unicode正規化」イコール「結合文字列を合成すること」と思ってしまうでしょうけど、すこし違います。Unicode正規化は合成するだけでなく、分解することにも使われるからです。

Unicode Consortium は、Unicode正規化を4種類に分けて規定しています。

 NFC Normalization Form C
 NFD Normalization Form D
 NFKC Normalization Form KC
 NFKD Normalization Form KD

「Normalization Form」は 正規形 と訳されています。「正規化した状態」というような意味です。つまりこの4つは、文字を

 合成(Composition)する
 分解(Decomposition)する
 互換分解(K(C)ompatibility Decomposition)してから合成(Composition)する
 互換分解(K(C)ompatibility Decomposition)する

ための方法であるということです。

ここでは、あまり深く掘り下げないことにしているので、「互換分解」には触れません。さらに、話を簡潔にするため、私たちの目的に直接関わる「NFC」だけに限定して見て行くことにします。

テキストエディットに「NFC」がない理由
OS Xには、Unicode正規化のAPIが用意されています。ですから、ソフトウェアにUnicode正規化の機能を実装する場合、そのAPIを利用するだけで簡単にできてしまいます。「その1」の簡単なソフトも、そうやって作りました。

それでは、どうしてOS Xの標準エディタであるテキストエディットに、ユーザが「NFC」を適用できる機能がないのでしょうか?

それは、一見とても便利そうな「NFC」に大きな問題があるからです。逆に、NFCを「結合文字列を合成するためだけに使う」商用ソフトは、その開発体制にひどい欠陥があると見て間違いないでしょう。

NFCの大きな問題
私は上記でNFCを「文字を合成する方法」と書きましたが、実際には予想外の処理をしています。すなわち、これが「NFC」のやっていることです。

 「分解(Decomposition)してから合成(Composition)する」
 

「その1」に登場したこの文字で見てみます。まず、この3つはまったく同じ字形ですが、データ上は
「01D6」「00FC 0304」「0075 0308 0304」
とどれも異なります。それぞれにNFCを適用してみます。

「01D6」→ 00FC 0304 → 0075 0308 0304 → 00FC 0304 → 01D6
「00FC 0304」→ 0075 0308 0304 → 00FC 0304 → 01D6
「0075 0308 0304」→ 00FC 0304 → 01D6

結果としてはいずれも単一の「01D6」になるのですが、はじめから「01D6」になっている文字も、徹底的に分解されて、再度また合成されます。つまり、分解マッピングで分解可能な文字は、それが単一コードであってもNFCでは分解されているということです。

そして、分解された文字がすべて元通りに合成されれば問題はないのですが、「すべて元通りに合成されるわけではない」ところにNFCの大きな問題があります。つまり、合成をしようとしてNFCを適用したら、かえって1文字がバラバラになったり、別の1文字に変わってしまう文字があるということです。(「その3」でも少し触れましたが、「分解」という用語は、1文字をバラバラにするだけでなく、別の1文字にする意味でも使われます)

「分解したあとに合成しない」ことを「合成除外 Composition Exclusion」といいます。Unicode Consortium の「CompositionExclusions.txt」はその合成除外文字の一覧です。一見すると少なそうですが、全部で1000文字以上もあります。

どうしてこんな文字があるのか、調べてみると理由はいくつかあり、なるほどと思うものもあれば、私では理解できないものもあります(チベット語とかヘブライ語なんて分かりませんし…)。そしてこれが遠い外国の文字だけなら、日本で作られるテキストにNFCを適用してもさして問題はないかなとも思うのですが、実は合成除外にもっとも多いのが「漢字」なのですから、困るのです。

次回は、この不遇な扱いを受ける漢字について見ていきます。

0 件のコメント: