マクロツイーター

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

pxchfon がまた新しくなった話

先日、pxchfon パッケージの 0.7f 版をリリースした。

以下ではこの版での新機能について解説する。

\diruni・\textdiruni 命令
  • \diruni: “AJ1 の制限”を撤廃して「任意の Unicode 文字」を(使っている物理フォントに全角幅のグリフがあれば)使えるようにする。その代わり、約物(句読点)が正常に出力されなくなる。
  • \textdiruni{<テキスト>}: 引数のテキストを \diruni の状態で出力する。
  • これらの命令は、upLaTeX 上で otf パッケージを使用し、かつ pxchfon で directunicode オプションを指定する場合にのみ利用できる。また、otf を pxchfon より前に読み込む必要がある。

以前の記事で説明した通り、pTeX 系の“Unicode の論理フォント”(otf パッケージの \UTF 命令で使われるフォントも含む)は、dvipdfmx の内部では Adobe-Japan-1(AJ1)のコードに変換される関係で、任意の Unicode 文字を扱えるわけではない。例えば以下に示すソースでは🍣が出力されない。


% upLaTeX 文書
\documentclass[a4paper,uplatex]{jsarticle}
\usepackage[deluxe]{otf}
\usepackage[ipaex]{pxchfon}
\setmarugothicfont{wlcmaru2004emoji.ttf}% 丸ゴシック→和田研中丸ゴシック
\begin{document}
両手に\textmg{🍣}% ダメ
\end{document}

ところがここで🍣に対して \diruni\textdiruni)を適用すると、ちゃんと🍣が出るようになる。


% upLaTeX 文書
\documentclass[a4paper,uplatex]{jsarticle}
\usepackage[deluxe]{otf}
\usepackage[ipaex,directunicode]{pxchfon}% directunicode を付ける
\setmarugothicfont{wlcmaru2004emoji.ttf}% 丸ゴシック→和田研中丸ゴシック
\begin{document}
両手に\textmg{\textdiruni{🍣}}% OK
% これでもよい
両手に{\mgfamily\diruni 🍣}
\end{document}
詳細

“AJ1 の制限”を取り払うことを企図して、以前(v0.7)に directunicode オプションというものが導入されている。パッケージ読込時にこのオプションを指定すると、\UTF での入力で使われる論理フォントについて、「内部を AJ1 で扱う」挙動を「内部で Unicode で扱う」挙動に変更する。だから、次の例のように〈⛄〉(U+26C4)〈⛇〉(U+26C7)などの“AJ1 にない文字”が無事に出力できるようになる。(なお〈☃〉(U+2603)は AJ1 に含まれる文字である。)

% pLaTeX 文書
\documentclass[a4paper]{jsarticle}
\usepackage[deluxe]{otf}
\usepackage[ipaex,directunicode]{pxchfon}
\setmarugothicfont{wlcmaru2004emoji.ttf}% ゴシック→和田研中丸ゴシック
\begin{document}
\mgfamily\UTF{2603}\UTF{26C4}\UTF{26C7}
\end{document}

pLaTeX の場合、「AJ1 にない文字」は必然的に*1 \UTF で入力することになるのでこれで十分である。ところが、upLaTeX の場合はこれだけでは不便なのである。上の文書ソースは(\documentclass の行だけ変えれば)upLaTeX でも通用する。しかし、「Unicode 文字が直接入力できる」はずの upLaTeX なのだから、\UTF ではなくて「☃⛄⛇」のように直接入力をするのが合理的であろう。しかし pxchfon の仕様では、「Unicode 直接入力」には directunicode は効かないのである。「直接入力」というのは要するに普通に文章を綴る際に使われるフォントなので、そこに“特殊な設定”を適用したくない、というのが理由である。*2

従来の directunicode にはもう一つ問題がある。それは「BMP 外の文字には(実質的に)効かない」ことである。例の記事の言葉でいうと、directunicode は「フォントマップの問題」の方を解決するが、「論理フォントの問題」の方はそのまま残っている。そして、otf パッケージ読込時の直接入力に対する論理フォントでは「AJ1 でも BMP でもない文字」はサポートされない。なので結局、〈🍣〉(U+1F363) を出力することはできないのである。

これまで、\asUTF 命令のようなアドホックな解決法を試してきたが、例のアレの実装にヒントを得て、“割とまともな”解決方法を思いついた。それを実現したのが \diruni 命令である。

解決方法は割と単純である。要するに、\diruni の状態のために別に論理フォントを用意するわけであるが、そのフォントとして \UTF 入力に対する VF の参照先である TFM(otf-ujmr-h 等)を指定するのである。論理フォントは VF でなく TFM なので文字範囲の制限がなく(例の記事の脚注を参照)、また directunicode 指定時は当該の otf-ujmr-h 等が“directunicode の状態”*3になるのでここでも文字範囲の制限がない。すなわち、⛄でも🍣でも出力できる、というわけである。

*1:AJ1 にない文字は JIS コード(JIS X 0208)にもないので直接入力はできない。

*2:directunicode を適用すると、縦組でも横組用の字形のまま出力されるようになる。従って、「直接入力」に適用するのは、少なくとも縦組では不適当である。横組における具体的な不具合は知られていない。

*3:つまりフォントマップで CMap 値が unicode である。