マクロツイーター

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

きょうの e-TeX (5): \fontcharwd、\fontcharht 等

今日はこの 4 つ。((「寸法パラメタ(読専)」というのは参照できるが代入できない寸法値(dimen)のパラメタ(\lastkern と同じ)。正式な用語では「内部寸法(internal dimen)」と呼ぶようであるが、敢えてこの用語を用いる。))

  • \fontcharwd〈フォント〉〈符号位置〉 :[寸法パラメタ(読専)] 当該フォントの当該符号位置の文字の幅。
  • \fontcharht〈フォント〉〈符号位置〉 :[寸法パラメタ(読専)] 当該フォントの当該符号位置の文字の高さ。
  • \fontchardp〈フォント〉〈符号位置〉 :[寸法パラメタ(読専)] 当該フォントの当該符号位置の文字の深さ。
  • \fontcharic〈フォント〉〈符号位置〉 :[寸法パラメタ(読専)] 当該フォントの当該符号位置の文字のイタリック補正値。

〈フォント〉については、以前の \iffontchar の項目で述べた。((なお、\jfont\tfont に対してこれらの命令を用いた場合は \iffontchar と同様にデタラメな結果を返すようである。))例えば、次のコードは現在のフォントの〈A〉の幅を画面に表示させる:


\typeout{\the\fontcharwd\font`A} % ==> 7.50002pt (cmr10 の場合)

非 e-TeX の場合でも、箱に文字を入れて寸法を測れば同じことができそうである(ただし代入操作が必要)。


\setbox0\hbox{A}\typeout{\the\wd0} % ==> 7.50002pt (cmr10 の場合)

ところが実は「幅」に関しては両者が同じにならないことがある。


\font\grmn=grmn1000 \grmn % CB フォント (ギリシャ文字)
\typeout{\the\fontcharwd\font`s} % ==> 5.69305pt
\setbox0\hbox{s}\typeout{\the\wd0} % ==> 4.44336pt

この理由は、当該の箱を実際に出力(\copy0)させれば判る。grmn1000 の〈s〉(0x73)の位置にあるのは〈σ〉(U+03C3;語中形シグマ)だが、\hbox{s} で実際に出力されているのは〈ς〉(U+03C2;語末形シグマ)である(この文字はフォントの〈c〉(0x63)の位置にある)。この変換は「境界文字とのリガチャ」という仕組を用いて実現されている。境界文字を除去する命令 \noboundary を挿入すると \fontcharwd と同じ結果(つまり〈σ〉の幅)が得られる。


\setbox0\hbox{s\noboundary}\typeout{\the\wd0} % ==> 5.69305pt

XeTeX においてはもう一つ注意すべきことがある。XeTeX では OpenType の属性を有効にして出力するグリフを変更することができるが、\fontcharXX で計測される対象のグリフは常に属性が全く無効の状態のものになる。例えば、次の例では small-caps を有効にしたフォントを用いているが、箱を用いた場合は small-caps の〈f〉(つまり小さい〈F〉)の高さが得られるが、\fontcharht では普通の〈f〉の高さ(アセンダハイトに達する)が得られる。


% (XeLaTeX で実行)
\font\tgpagella="TeX Gyre Pagella:+smcp" \tgpagella
\typeout{\the\fontcharht\font`f} % ==> 7.0pt (アセンダハイト)
\setbox0\hbox{f}\typeout{\the\ht0} % ==> 4.52pt (エックスハイト)

先述の境界文字リガチャの場合と異なり、OpenType の処理は基本的にグリフの置換である。とすると、\tgpagella において、「文字〈f〉を出力すると別の文字が代わりに出る」のではなく、「文字〈f〉がエックスハイトのグリフをもつ」と考える方が合理的にも思える。もしそうであれば、\fontcharXX は有効な属性を考慮すべきであろう。では何故このような仕様になっているか。Jonathan Kew によると、「属性が有効な状態では、個々の文字のグリフは周りの文脈に依存する、従って単一の文字を対象とするインタフェースでは機能を完全に果たすことができない」((XeTeX ML での \XeTeXcharglyph に関する発言。\fontcharXX にも全く同じことがいえると思う。))という理由のようである。つまり、属性が有効なフォントを相手にするのなら \fonttextwd〈フォント〉{〈テキスト〉} のような命令が必要だということだろう。