マクロツイーター

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

pxchfon の directunicode について語ってみる

pxchfon パッケージには「directunicode」という機能が存在する。これは「フォントにあるはずの文字が出力できない」という問題を(部分的に)解決するためのもので、正しく使うことができれば強力な機能である。その反面、種々の事情のために仕様が極めて複雑であり、非常に把握しづらいものとなっている。この記事では、directunicode 機能について少し詳しく解説する。

※基本的に upLaTeX を前提にして解説する。必要に応じて pLaTeX についての補足を入れる。

※アタリマエであるが、フォントがサポートしていない文字は、何をどうしても出力できない。

※改めて念を押しておくが、upTeX の Unicode 直接出力にしても、japanese-otf パッケージ(OTF パッケージ)にしても、対象となるのは和文(扱いの)文字のみである。また“自分で TFM や VF を作る”ことをしない限りは、全角幅*1のグリフしか利用できない。本記事ではその状況を前提とする。

なぜ directunicode なのか

directunicode 機能は次の 2 つの問題に対する解決策となる。

  1. 「upLaTeX で Unicode できない」問題
  2. 「upLaTeX で AI0 フォントできない」問題
「upLaTeX で Unicode できない」問題

この問題については以前の記事で解説した。

大雑把にいうと、次のような問題である。

  • フォントに字形が存在する Unicode 文字であっても、以下のような理由で、upLaTeX の標準和文フォントや japanese-otf の \UTF 命令で出力できない。
    • Adobe-Japan1(AJ1)のグリフ集合にない文字である.
    • BMP 外の文字である。
  • 具体的にどの文字が使える・使えないかについては次の記事を参照してほしい。とにかく複雑である。
  • japanese-otf についての話は pLaTeX でもそのまま当てはまる。
\documentclass[uplatex,a4paper]{jsarticle}
\usepackage{otf}
\begin{dpcument}

まず🍣より始めよ。% ダメ

まず\UTF{1F363}より始めよ。% ダメ

\end{document}
「upLaTeX で AI0 フォントできない」問題

OpenType フォント*2の中には“CID-keyed”という形式のものがある。CID-keyed な日本語フォントは通常は Adobe-Japan1(AJ1)のグリフエンコーディング*3に従っている。ところが最近は、AJ1 でない独自のグリフエンコーディング(これを「Adobe-Identity0(AI0)」と呼ぶ*4)をもつ日本語 OpenType が登場している。例えば、Adobeフリーフォント「Source Han Sans(源ノ角ゴシック)」や macOSSierra 以降)付属の「游明朝体」などである。*5upLaTeX の標準和文フォントや japanese-otf の和文フォントは「CID-keyed な日本語フォントは AJ1 に従う」ことを仮定しているため、“AI0 なフォント”は使えないのである。

\documentclass[uplatex,a4paper]{jsarticle}
\usepackage[noalphabet]{pxchfon}
% "AI0なフォント"は使えない
\setminchofont{SourceHanSerif-Regular.otf}% ダメ
\setgothicfont{SourceHanSans-Regular.otf}% ダメ
\begin{dpcument}
{\TeX}\textsf{アレ}\end{document}

directunicode で何かできるか

directunicode とは「特定のフォントのグリフアクセスの方法を“AJ1 経由”から“Unicode 直接”に切り替える」ことを指す。これ以上の詳細については煩雑になるため省略するが、とにかく、フォントを“Unicode 直接”に切り替えると先に示したような問題が起こらなくなるわけである。

※“Unicode 直接”を指定できるのは“TeX において Unicode で扱われている”フォントに限られる。つまり、pTeX の標準和文フォント(これは“JIS で扱われる”フォントである)や japanese-otf の \CID 命令のフォントは“Unicode 直接”を指定できない。

directunicode オプション

pxchfon のパッケージオプションに directunicode を指定すると、japanese-otf の \UTF のフォントに対して“Unicode 直接”が指定される。これにより、\UTF での入力に関しては「AJ1 にないので Unicode できない」問題が解決する。ただし「BMP にないので Unicode できない」問題は残る。((つまり、\UTF の対応範囲が「AJ1 にあるもの」から「AJ1 または BMP にあるもの」に拡大される。))

\documentclass[uplatex,a4paper]{jsarticle}
\usepackage[directunicode,noalphabet]{pxchfon}% directunicode した!
\setminchofont{SomeFont.ttf}% ちゃんと使えるやつ
\begin{document}

% これは元々OK(AJ1にある)
ゆきだるま☃! % OK
ゆきだるま\UTF{2603}% OK

% AJ1になくても \UTF なら使える
黒ゆきだるま\UTF{26C7}% OK

% AJ1にもBMPにもないのはダメ
スシ\UTF{1F363}% ダメ

% 直接入力には効果無し
黒ゆきだるま⛇! % ダメ
スシ🍣! % ダメ

\end{document}

ちなみに、「AI0 できない」問題の方にも効果はあるが、例えば directunicode を指定した上で \setgothicfont で AI0 なフォントを割り当てたとすると、「ゴシックでは \UTF 入力しかできない」ことになるので、あまり実用的ではないかも知れない。

Unicode 直接”方式の副作用

Unicode 直接”に切り替えると使える文字の範囲が拡がるが、イロイロな副作用がある。

  • 90JIS/2004JIS 字形の切替の機能(pxchfon の prefer2004jis、japanese-otf の jis2004)が無効になる。
  • 縦組時に、縦組用字形への切替(〈「〉→〈﹁〉)が効かなくなる。
    • ただし、縦組用字形をもつ文字の多くは約物であり、\UTF約物の出力には元々不適であることにも注意すべき。
  • 自分も完全に把握しているわけでないので、他に何かあるかも知れない。

directunicode の効力を \UTF だけに留めているのはこの副作用を勘案したためである。

\diruni 命令

しかし、directunicode の効果が \UTF にしか及ばないのは不便でもある。この問題を解決するのが \diruni 命令である。これを実行すると、以降の Unicode 直接入力で全ての Unicode 文字が使えるようになる。((なお、directunicode(または後述の directunicode*)を指定しない場合は \diruni 命令は使えない。))

\diruni は“宣言型命令”で、(\rmfamily 等と同様に)適用範囲をグループに入れて用いる。\diruni に対応する引数型命令の \textdiruni も存在する。

\diruni の効力は非常に強力で、本当に全ての Unicode 文字が使用できる。

\documentclass[uplatex,a4paper]{jsarticle}
\usepackage[directunicode,noalphabet]{pxchfon}
\setminchofont{SomeFont.ttf}
\begin{document}

まず{\diruni 🍣}より始めよ。 % OK
まず\textdiruni{🍣}より始めよ。 % OK

\end{document}

その反面、副作用も強力であり、“Unicode 直接”の通常の副作用に加えて、以下の現象が発生する。

  • 文字が完全にベタ組になる。つまり約物組版が異常になる。

従って、\diruni は適用範囲を明確に決めて使うべきである。

directunicode* オプション

最新版(0.9 版)の pxchfon パッケージ(恐らく近日中に TeX Live で使えるようになる)では、directunicode* というオプションが導入された。これは、\UTF のフォントに加えて、upLaTeX の標準和文フォント(Unicode 直接入力)にも“Unicode 直接”を適用するというものである。

この機能は、どちらかというと、「AI0 できない」問題の解決のためのものである。すなわち、directunicode* を指定しておくと、“AI0 なフォント”を \set〜font で割り当てて普通に使うことができる。

\documentclass[uplatex,a4paper]{jsarticle}
\usepackage[directunicode*,noalphabet]{pxchfon}% directunicode* した
% "AI0なフォント"が使える
\setminchofont{SourceHanSerif-Regular.otf}
\setgothicfont{SourceHanSans-Regular.otf}
\begin{dpcument}
{\TeX}\textsf{アレ}\end{document}

Unicode 直接入力の「Unicode できない」問題については、使える文字の範囲が多少拡大される。例えば AJ1 にない BMP の漢字が使えるようになる。(\UTF 入力については directunicode と同じ。)

補足:pLaTeX の場合は

pLaTeX の直接入力に対するフォントは“JIS で扱われる”ため、directunicode 機能の適用対象外である。\UTF 入力のフォントについては upLaTeX と全く同じ結果になる。

まとめ

pxchfon の directunicode 機能は……ヤヤコシイ。


例の記事に倣って、表にまとめてみた。

  • A: AJ1 のグリフに対応する文字
  • B: A ではないが、A が属するブロックの 1 つにある文字
  • C: A でも B でもない文字
分類BMPBMP副作用AI0なフォント
ABCABC
🈓🉆🍣
【デフォルト】
Unicode 直接入力××××不可
\UTF 入力××××不可
directunicode 指定時】
Unicode 直接入力××××不可
\UTF 入力××
\diruni 適用
directunicode* 指定時】
Unicode 直接入力××
\UTF 入力××
\diruni 適用

“※”の部分は状況により異なる。具体的には、直接入力に対応する論理フォント(TFM)が例の記事の表の (i)、(ii)、(iii) の何れであるかにより決まる。

*1:半角カナは例外的に半角幅。これは「物理フォントにおいて全角幅・半角幅」の意味である。

*2:TrueType グリフのものも含める。なお、TrueType グリフの OpenType フォントは CID-keyed ではない。

*3:よく解らない人は、取りあえず「“CID-keyed”(という形式)な OpenType フォントは“グリフエンコーディング”(という何か)を持っている」と考えておけばよい。

*4:AJ1 はある特定のグリフエンコーディングを表す識別子であるが、AI0 は「フォントがそれ独自のグリフエンコーディングをもつ」ことを表す識別子である。

*5:なお、ここで例に挙げたフォントは「OpenType Collection(OTC)形式」であることでも有名であるが、これとグリフエンコーディングの話は無関係である。