マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

XeLaTeX での結合文字(および NFD)の扱い

XeTeX 自体は文字合成に対応しているので、「が」等の分解可能な文字(和文でも欧文でも)が「基底文字 + 結合文字」の列で表されていても、フォントが対応している限り、正常な出力が得られるはずである。(Unicode の正規化方式 NFD では分解した形が用いられる。)さらに、和文の処理のために \XeTeXlinebreaklocale "ja" を指定しても文字合成は影響を受けない。


% XeLaTeX 文書; 文字コードUTF-8; NFC で表現
\documentclass[a4paper]{article}
\usepackage{fontspec}
\setmainfont[RawFeature=-palt]{IPAexMincho}
\begin{document}
\XeTeXlinebreaklocale "ja"
\XeTeXlinebreakskip 0pt plus 1pt
\begin{itemize}
% 〈ど〉を合成済文字(U+3069)で表した
\item これはひどい
% 〈ど〉を分解した形〈3068 3099〉で表した
% U+3099 = COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK
\item これはひと^^^^3099い
% U+3099 = COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
\item コ^^^^309aレハヒ^^^^309aト^^^^309aイ
\end{itemize}
\end{document}

上の例で ^^^^3099 は U+3099 の文字を直接入力したのと同値であるので、〈と^^^^3099〉は〈ど〉を NFD で書いたのと同じことになる。また、〈コ゚〉等の一部の文字は Unicode に合成済文字が登録されていないので、必然的に(つまり NFC でも NFD でも)〈30B3 309A〉という分解した形で表すことになる。ここで用いたフォント「IPAex明朝」は U+3099、U+309A の合成をサポートしているので、正常な出力が得られることがわかる。

しかし、xeCJK パッケージを用いた場合は、文字合成が失敗してしまう(従って、xeCJK を土台にしている zxjatype パッケージでも同様に失敗する)。


% XeLaTeX 文書; 文字コードUTF-8; NFC で表現
\documentclass[a4paper]{article}
\usepackage{xeCJK}
\setCJKmainfont[RawFeature=-palt]{IPAexMincho}
\begin{document}
\begin{itemize}
\item これはひどい
\item これはひと^^^^3099い
\item コ^^^^309aレハヒ^^^^309aト^^^^309aイ
\end{itemize}
\end{document}

これの原因は、xeCJK が結合文字の U+3099 を普通の和文文字(文字クラス 1)と全く同じように扱うため、〈と〉と U+3099 の間にグルーを入れてしまうからである。結合文字の文字クラス(\XeTeXcharclass の値)は本来 256 とするのが正しいので、上の例でプレアンブルの最後に


\XeTeXcharclass"3099=256
\XeTeXcharclass"309A=256

を追加すれば正常になる。

……ということは判っているのだが、恐らく xeCJK は「文字クラス 256」の使用を想定していないと思われるので、この設定で問題が起こる可能性が残っている。どうしたものか。