「インフォシーク isweb ライト」サービス終了に伴い、 本サイトは以下のURLに移転することになりました。
現在のサイトは、10月末を以て終了となります。
http://zrbabbler.sp.land.to/pxutil.html

PXutil パッケージ

pxutil は和文の仮想フォント(VF と JFM の組)を VPL 類似のテキスト形式である 「ZVP 形式」に変換/逆変換するツール(Perl スクリプト)である。 TeX 標準のツールである vftovp/vptovf の「和文版」といえる。 VF ファイルのみをテキスト形式に変換する機能もある。
変更履歴

概要

対応環境

このパッケージ中のソフトウェアを利用するには 以下のものが必要である。

  • Perl 5.8.1 版以降
  • ZRTeXtor 1.2.2 版以降
  • TeX の kpsewhich コマンド
  • pTeX の pltotf, tftopl コマンド
注意: ZRTeXtor 1.2.1 版には 「タイプ 0 のサブタイプが認識されない」というバグがあったので、 必ず 1.2.2 版以降を使うようにされたい。

ダウンロード

github のページから ZIP アーカイブをダウンロードできる。 (「Download ZIP」のボタンを押す。)

インストール

  • pxutil.zip に含まれる pxutil.pl を実行パスの通った ディレクトリに置く。
  • ZRTeXtor パッケージに含まれる ZRTeXtor.pm と ZRTeXtor.cfg を Perl の ライブラリ検索パス(@INC)または pxutil.pl と 同じディレクトリに置く。
  • ZRTeXtor.cfg を自分の環境に合うように編集する。 最近の W32TeX だと以下のようにする必要がある。
    pltotf = ppltotf
    tftopl = ptftopl
    
  • pxutil.pl を pxutil のコマンド名で実行できるようにする。 UNIX 系 OS なら周知の通り。 Windows なら pl2bat を使うなり、W32TeX の runscr.exe を 使う(pxutil.exe という名前のコピーを作る)なりする。

使用法

ZVP 形式と仮想フォント(VF+JFM)との間の変換

  # ZVP → VF + JFM の変換
pxutil zvp2vf <オプション> <入力.zvp> <出力.vf> <出力.tfm>
  # VF + JFM → ZVP の変換
pxutil vf2zvp <オプション> <入力.vf> <入力.tfm> <出力.zvp>

2 つ目以降のファイル名は省略できて、その場合は 1 つ目のファイルの 拡張子を変えたものになる。 オプションは次のものが使える(一部省略)。

--kanji=<値><値>jis, euc, sjis, utf8, none のいずれか)
外部文字コード(テキスト形式のファイルの文字コード)の指定。
--kanji-internal=<値><値>jis, unicode, none のいずれか)
内部文字コード(仮想ファイル中で用いられる文字コード)の指定。
-j
--kanji=jis --kanji-internal=jis と等価。
-u
--kanji=utf8 --kanji-internal=unicode と等価。
-E
--kanji=none --kanji-internal=none と等価。

--kanji--kanji-internal の既定値は ZRTeXtor.cfg で指定したものになる。 -E は仮想ファイルで使われる文字コードが何であるかを意識せず、 常に符号値そのものを扱いたい場合の設定である。 符号値を文字で指定(CHARSINTYPE とか整数の K 形式とか)したい のでなければ、-E を指定することを推奨する。

その他の変換

  # ZVP0 → VF の変換
pxutil zvp02vf <オプション> <入力.zvp0> <出力.vf>
  # VF → ZVP0 の変換
pxutil vf2zvp0 <オプション> <入力.vf> <出力.zvp0>
  # ZPL → JFM の変換
pxutil zpl2tfm <オプション> <入力.zpl> <出力.tfm>
  # JFM → ZPL の変換
pxutil tfm2zpl <オプション> <入力.tfm> <出力.zpl>

ZVP0 形式は ZVP (あるいは VPL)の中の VF に直接対応する要素だけを 抜き出したもので、VF 単体と相互変換できる。 ZPL 形式は逆に ZVP の中の JFM に直接対応する要素を 抜き出したもので、要するに JPL 形式を少しだけ拡張したものである。

とにかく使ってみる

テストケースとして次のようなことを実現してみる。

「縦書きの JIS メトリック和文フォント」である jis-v は ダブルクオーテーション〈“”〉がそのまま出力される (勿論この出力は使い物にならない)。 これをダブルミニュート〈〝〟〉に置き換えられる ようにする。 ダブルミニュートは upTeX のフォント uprml-v から持ってくる。

参考: pLaTeX2e の標準の縦書クラス (tarticle 等)で使われる和文フォント tmin10 では、 ダブルクオーテーションはダブルミニュートに置き換えられる。 新ドキュメントクラス(jsarticle 等)では既定で JIS メトリック の横書フォント jis が使われるが、縦書きに切り替えた時に 使われるのは jis-v ではなくやはり tmin10 である。 従って、普通に使われる設定では jis-v は使われない。

以下に jis-v を用いた例を示す。 当然、縦書きで使われないダブルクオーテーションは 横書き用の字形がそのまま出力されるので 奇妙な出力になってしまう。

(正しく出力されない例)
\documentclass[a4paper]{tarticle}
% 明朝フォントに jis / jis-v を指定
\DeclareFontFamily{JY1}{jmc}{}
\DeclareFontFamily{JT1}{jmc}{}
\DeclareFontShape{JY1}{jmc}{m}{n}{<->jis}{}
\DeclareFontShape{JT1}{jmc}{m}{n}{<->jis-v}{}
\renewcommand\mcdefault{jmc}
\normalfont
\begin{document}
本日は“豚天”なり。 %“ ”がそのまま出力される
\end{document}

なお、tmin10 で出力されるダブルミニュートは 秒記号〈″〉から合成されたものである。 従って、PDF 出力でのテキスト情報が正しくならない という短所をもつ。 ダブルミニュートのグリフはほぼ全ての日本語用 TrueType/OpenType フォント がもっているので、なるべくこれを使用したい。

手順の概略は次のようになる。

  • pxutil vf2zvp で jis-v の VF+JFM をテキスト形式 である ZVP 形式に変換。
  • 変換後の jis-v.zvp を目的に適うように 改変した mod-jis-v.zvp を作る。
  • pxutil zvp2vf で ZVP 形式を VF+JFM 形式に変換。

以下で、その手順を追っていくのに併せて、 pxutil コマンドの使い方や ZVP 形式の仕様の概要を説明していく ことにする。

ZVP 形式への変換

ZVP 形式は私が独自に定義した、和文用の仮想フォントを 表現するテキスト形式である。 欧文の VPL 形式の和文版に相当するもので、VF と JFM(和文TFM)の 組との相互変換が可能である。 この ZVP 形式を扱うコマンドが pxutil である。

適当な作業用ディレクトリで以下のコマンドを実行すると、 jis-v.vf と jis-v.tfm から jis-v.zvp が生成される。

pxutil vf2zvp -E jis-v
参考: TFM と VF ファイル の読込については Kpathsearch の検索の対象となる。 独自の形式(ZVP 等)は対象とならないので、読込の際には パスを指定(またはカレントに置く)必要がある。

ZVP 形式の仕様の概説

出力された jis-v.zvp を例にとって、 ZVP 形式の仕様の概説を行う。 ただし、 PL 形式JPL 形式の 仕様、および「そもそも VF は何なのか」については既知であることを想定する。 VPL 形式も知っていることが望ましいが、そうでなくても理解できるように 適宜補足していく。

以下、先頭から順を追って内容を解説していく。

(DIRECTION TATE)
(VTITLE )
(FAMILY JIS KANJI)
(FACE F MRR)
(CODINGSCHEME TEX KANJI TEXT)
(DESIGNSIZE R 10.0)
(CHECKSUM O 0)
(SEVENBITSAFEFLAG TRUE)

先頭の種々の設定については JPL 形式と同じである。 この中で、VTITLE は VF に記録された名前 (TeX システムの中では無意味)でこちらは VPL 形式と同じ。

(FONTDIMEN
   (SLANT R 0.0)
   (SPACE R 0.0)
   (STRETCH R 0.091641)
   (SHRINK R 0.0)
   (XHEIGHT R 0.916443)
   (QUAD R 0.962216)
   (EXTRASPACE R 0.229101)
   (EXTRASTRETCH R 0.183283)
   (EXTRASHRINK R 0.114551)
   )

JPL 形式と同じ FONTDIMEN 要素。 jis-v は min10 と同じく 0.962216 倍のスケールをもつ。

(MAPFONT D 1
   (FONTNAME rmlv)
   (FONTCHECKSUM O 0)
   (FONTAT R 0.962216)
   (FONTDSIZE R 10.0)
   )

MAPFONT 要素で仮想フォントが参照するフォントを指定する (VPL と同じ)。 ここでは rmlv を 0.962216 倍に縮小したものを指定している (FONTNAME, FONTAT)。 FONTCHECKSUM と FONTDSIZE は参照先の CHECKSUM と DESIGNSIZE と同じにする。 (チェックサムは参照元と参照先のどちらかの値が 0 ならば 異なっていてもよい。)

なお、後述するように、参照フォントは複数利用することができる。 従って、MAPFONT には参照フォントの番号を表す整数(ここでは 1) が指定される。

(GLUEKERN
   (LABEL D 0)
   (GLUE D 1 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 3 R 0.240554 R 0.0 R 0.240554)
   (STOP)
   (LABEL D 1)
   (GLUE D 3 R 0.240554 R 0.0 R 0.240554)
   (STOP)
   (LABEL D 2)
   (GLUE D 0 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 1 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 3 R 0.240554 R 0.0 R 0.240554)
   (GLUE D 5 R 0.481108 R 0.0 R 0.481108)
   (STOP)
   (LABEL D 3)
   (GLUE D 0 R 0.240554 R 0.0 R 0.240554)
   (GLUE D 1 R 0.240554 R 0.0 R 0.240554)
   (GLUE D 2 R 0.240554 R 0.0 R 0.240554)
   (GLUE D 3 R 0.481108 R 0.0 R 0.240554)
   (GLUE D 4 R 0.240554 R 0.0 R 0.240554)
   (GLUE D 5 R 0.240554 R 0.0 R 0.240554)
   (STOP)
   (LABEL D 4)
   (GLUE D 0 R 0.481108 R 0.0 R 0.0)
   (GLUE D 1 R 0.481108 R 0.0 R 0.0)
   (GLUE D 3 R 0.721662 R 0.0 R 0.240554)
   (GLUE D 5 R 0.481108 R 0.0 R 0.0)
   (STOP)
   (LABEL D 5)
   (GLUE D 1 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 3 R 0.240554 R 0.0 R 0.240554)
   (KRN D 5 R 0.0)
   (STOP)
   )

JPL 形式と同じ GLUEKERN 要素。

(CODESPACE GL94DB)

CODESPACE 要素は ZVP に特有のものである。 JFM では有効な符号位置として全ての 2 バイト値(0~0xFFFF)が 仮定されている(ただし pTeX がこの全てを使えるわけではない)のに対し、 VF では有効な符号位置は「文字パケット」(VPL の CHARACTER 要素)が あるものに限られる。 ZVP では有効な符号位置の集合(これを「符号空間」と呼ぶ)を 予め指定する方式をとっていて、これを指定するのが CODESPACE 要素である。 CODESPACE の引数は CHARSINTYPE のそれと同じ形式で指定する (後述の「文字リストの書式」を参照) が、次の 2 つの集合は名前が与えられていて、それで指定 することができる。

  • GL94DB: 上位バイト、下位バイトが 0x21~0x7E の 範囲にある 2 バイト値全体。 (ISO 2022 の 94² 文字集合を GL に呼び出した時の符号位置の集合。)
  • UNICODE-BMP: 0~0xFFFF の範囲の値。 Unicode の BMP 内のスカラー値全体。
(CHARSINTYPE D 1
   X2146 X2148 X214A X214C X214E X2150 X2152 X2154 X2156 X2158 X215A
   )
(CHARSINTYPE D 2
   X2122 X2124 X2147 X2149 X214B X214D X214F X2151 X2153 X2155 X2157
   X2159 X215B
   )
(CHARSINTYPE D 3
   X2126 X2127 X2128
   )
(CHARSINTYPE D 4
   X2123 X2125
   )
(CHARSINTYPE D 5
   X213D X2144 X2145
   )

JPL 形式と同様の CHARSINTYPE 要素の指定である。 ここで Xxxxxxxxx は 16 進数) は Jxxxx 形式 (あるいは upTeX 用のツールで使える Uxxxx 形式)と 同様に符号値の数値指定を表すが、これらと異なり 「外部・内部の文字コード設定に依存せずその数値自体を表す」 という規定である (「文字リストの書式」を参照)。

(TYPE D 0
   (CHARWD R 0.962216)
   (CHARHT R 0.458222)
   (CHARDP R 0.458222)
   (MAP
      (SETCHAR)
      )
   )

JPL 形式と同様の TYPE 要素だが、中に MAP 要素をもっている。 これは VPL の MAP と同じく、仮想フォントの文字が呼び出されたときに、 それをどのように出力するかを DVI 命令で表したものである。 VPL の SETCHAR は (SETCHAR <整数>) の 書式をもち、参照フォント中の <整数> の符号位置の 文字を出力することを意味する。 ZVP ではここで引数なしの (SETCHAR) の形式が使え、 これは仮想フォントで呼び出された符号位置と同じ値を用いる ことを表す。

従って、この指定の下でたとえば jis-v の位置 0x3021 の文字を 出力するには、rmlv (参照フォント)の位置 0x3021 の文字を 出力すればよいことになる (JIS 符号なので 0x3021 は〈亜〉)。

(TYPE D 1
   (CHARWD R 0.481108)
   (CHARHT R 0.458222)
   (CHARDP R 0.458222)
   (MAP
      (MOVERIGHT R -0.481109)
      (SETCHAR)
      )
   )

続いて、タイプ 1 に対応する TYPE 要素である。 (MOVERIGHT <実数>)<実数> だけ出力位置を「右」に移動することを示す。 (縦書きの場合は「右」は実際には下方向になる。) 単位は DESIGNSIZE である(ここでは 10pt)。 このフォントの全角幅(FONTDIMEN 中の QUAD の値)が 0,962216 である から、「半角幅戻ってから呼び出された符号位置の文字を出力」 することになる。 タイプ 1 に属するのは〈(〉のような開き括弧の類である。 jis-v ではこれは半角幅の文字と規定されるが、 等幅のフォント(参照先の rmlv)では「 (」の ように「左」に半角分の空きを込めた形にデザインされている。 従って、出力する前に「左」に戻ることで目的の字形と合わせている。

(TYPE D 2
   (CHARWD R 0.481108)
   (CHARHT R 0.458222)
   (CHARDP R 0.458222)
   (MAP
      (SETCHAR)
      )
   )
(TYPE D 3
   (CHARWD R 0.481108)
   (CHARHT R 0.458222)
   (CHARDP R 0.458222)
   (MAP
      (MOVERIGHT R -0.240554)
      (SETCHAR)
      )
   )
(TYPE D 4
   (CHARWD R 0.481108)
   (CHARHT R 0.458222)
   (CHARDP R 0.458222)
   (MAP
      (SETCHAR)
      )
   )
(TYPE D 5
   (CHARWD R 0.962216)
   (CHARHT R 0.458222)
   (CHARDP R 0.458222)
   (MAP
      (SETCHAR)
      )
   )

以降、同様の TYPE 要素の記述が続いている。

仮想フォントの改変

さて、目標はダブルクオーテーション〈“”〉 (JIS符号位置 0x2148/0x2149)を ダブルミニュート〈〝〟〉 (Unicode位置 0x301D/0x301F)に置き換えることである。 まずは、〈“〉(JIS 0x2148)について考えることにする。 これはタイプ 1 (開き括弧類)に属しているので、 次のような MAP が指定されていることになる。

(MAP
   (MOVERIGHT R -0.481109)     半角幅「左」に移動
   (SETCHAR H 2148)            rmlv の〈“〉を出力
   )

ダブルミニュートは JIS X 0208 にはないので、Unicode フォント から借りてくることにする。 前述のようにここでは upTeX の標準の縦書き和文フォントの uprml-v を 用いることにする。

参考: 他の選択としては、 OTF パッケージの otf-ujmr-v、 UTF パッケージの unijmin-v 等が考えられる。 名前の違いを除けば後の作業内容に違いはない。

ダブルミニュートも「開き括弧類」なので、等幅フォントでの デザインの仕方については元のダブルクオーテーションと同じである。 従って、「rmlv の位置 0x2148 の文字」の代わりに 「uprml-v の位置 0x301D の文字」を出せばいいことになる。

参考: フォントの文字コードが何で あるかは特に ZVP 中に記述することはない。 rmlv は JIS 符号のフォントなので rmlv の 0x2148 には 「JIS の 0x2148 の文字」があるはずであり、 同様に、uprml-v の 0x301D には「Unicode 0x301D の文字」が あるはずである。

参照フォントの追加

今まで、参照フォントとして rmlv だけを用いていたが、これに uprml-v が加わるので、次のような MAPFONT 要素を 既存の rmlv に対する MAPFONT より後に追加する。 (実際には追加する場所は既存の要素の外側ならどこでもよい のだが、後述の理由があるため。)

(MAPFONT D 2
   (FONTNAME uprml-v)
   (FONTDSIZE R 10.0)
   (FONTAT R 0.962216)
   )

uprml-v は rmlv と同じく、DESIGNSIZE = 10pt、QUAD = 1.0 となって いるので、rmlv と全く同じ設定になる。 参照フォントの番号は既に使われているもの(rmlv = 1)と 重ならなければよい(可能な値は 0~255)。 ここでは 2 とする。

MAP 中の参照フォントの切替

MAP 要素中で参照フォントを切り替えるには、SELECTFONT 要素を用いる。 (SELECTFONT <整数>) で番号が <整数> のフォントに切り替える。 従って、開きダブルミニュートを出力する MAP は次のようになる。

(MAP
   (MOVERIGHT R -0.481109)     半角幅「左」に移動
   (SELECTFONT D 2)            uprml-v に切り替える
   (SETCHAR H 301D)            〈〝〉を出力
   )
参照: MAP 内での初期の参照フォントは 「ZVP で最初に現れた MAPFONT」である。 (「1 番」とか「0 番」という規定ではないことに注意。) 従って、新規の MAPFONT を追加する際には 先頭の MAPFONT さえ変更しなければ、 既存の MAP には影響がないことになる。

サブタイプの指定

ではこの MAP をどこに記述するかを考える。 今までの解説に従うと、MAP は TYPE の中に書くことになるので、 0x2148 のタイプを従来の 1 から新規のもの(6 とする)に 変更すればよいことになる。

(…タイプ 1 から X2148 を除去…)
(CHARSINTYPE D 6          0x2148 をタイプ 6 にする
   X2148
   )
(TYPE D 6                 タイプ 6 の規定
   (CHARWD R 0.481108)
   (CHARHT R 0.458222)
   (CHARDP R 0.458222)
   (MAP
      (MOVERIGHT R -0.481109)
      (SELECTFONT D 2)
      (SETCHAR H 301D)
      )
   )

ただ、このように新しいタイプを設定すると、 それに対して GLUEKERN を指定する必要が生じる。 このタイプ 6 は MAP 指定を除けばメトリックも GLUEKERN も タイプ 1 と全く同じ振る舞いをするはずなので、 これはいかにも面倒である。

そこで、ZVP では 1 つのタイプの中で異なる MAP を もつことを認めて、タイプの中で同じ MAP をもつ文字の集合 として「サブタイプ」という概念を導入している。 すなわち、ここでは 0x2148 を「サブタイプ 1」とし、 それ以外のタイプ 1 の文字(元々の TYPE D 1 の MAP をもつ)を「サブタイプ 0」とすればよい。

サブタイプの指定は (CHARSINSUBTYPE <タイプ値> <サブタイプ値> <文字リスト>) の書式で行う。 つまり、「サブタイプ 1」の文字の指定は次のようになる。

(CHARSINSUBTYPE D 1 D 1
   X2148
   )

そして、CHARSINSUBTYPE 要素に現れなかった文字は 自動的に「サブタイプ 0」になるので、 サブタイプ 0 のリストは書かなくてよい。 (CHARSINTYPE にない文字がタイプ 0 になるのと同様。)

サブタイプに対する MAP を指定するには、SUBTYPE 要素を 使用する。

(SUBTYPE D 1 D 1
   (MAP
      (MOVERIGHT R -0.481109)
      (SELECTFONT D 2)
      (SETCHAR H 301D)
      )
   )

ここでも、「TYPE 要素の中の MAP はサブタイプ 0 に対するもの」 というルールがあるので、サブタイプ 0 に対する SUBTYPE 要素は 書かなくてよい。 また、サブタイプ毎に異なるのは MAP だけなので、 SUBTYPE の中に書けるのは MAP だけであることにも注意してほしい。 (補足: ZRTeXtor 1.3.0 版への改版で、 メトリックが異なるサブタイプが作れるようになった。 詳しくは「サブタイプ毎のメトリックの指定」を参照。)

まとめ

以上をまとめて、また閉じのダブルミニュートに対する設定も 加えると、以下の記述を追加すれば所望の改変が実現できることになる。

(MAPFONT D 2
   (FONTNAME uprml-v)
   (FONTDSIZE R 10.0)
   (FONTAT R 0.962216)
   )
(CHARSINSUBTYPE D 1 D 1
   X2148
   )
(SUBTYPE D 1 D 1
   (MAP
      (MOVERIGHT R -0.481109)
      (SELECTFONT D 2)
      (SETCHAR H 301D)
      )
   )
(CHARSINSUBTYPE D 2 D 1
   X2149
   )
(SUBTYPE D 2 D 1
   (MAP
      (SELECTFONT D 2)
      (SETCHAR H 301F)
      )
   )

ZVP 形式から仮想フォントを生成する

改変したものが元のフォント名のままではまずいので、 上記の改変を加えた ZVP のファイル名を mod-jis-v.zvp とする。 ここで再び pxutil を使って、仮想フォント、すなわち VF と JFM の組を生成することができる。

pxutil zvp2vf mod-jis-v.zvp
# (mod-jis-v.tfm と mod-jis-v.vf が生成される)

生成された mod-jis-v が望み通り機能するかをチェックする ために以下の文書を組版してみる。

\documentclass[a4paper]{tarticle}
\DeclareFontFamily{JY1}{jmc}{}
\DeclareFontFamily{JT1}{jmc}{}
\DeclareFontShape{JY1}{jmc}{m}{n}{<->jis}{}
\DeclareFontShape{JT1}{jmc}{m}{n}{<->mod-jis-v}{} % mod-jis-v を指定
\renewcommand\mcdefault{jmc}
\normalfont
\begin{document}
本日は“豚天”なり。
\end{document}

きちんとダブルミニュートが出力されていることがわかる。

参照: DVI ウェアは仮想フォント を参照フォントで置き換えるので、DVI ウェアのフォント設定は 仮想フォントには必要がない。 つまり、この場合、rmlv と uprml-v に対して適切な設定が 行われていれば、DVI ウェアは新しくできた mod-jis-v も扱うことが できるはずである。

CHARACTER 要素

ZVP の説明をするために、以上では MAP を変更する文字に 対してサブタイプを設定したが、 実は ZVP では CHARACTER 要素を用いて、特定の文字の MAP 設定を 変えることができる。 CHARACTER 要素を用いた場合、mod-jis-v を作る為の改変部分は 以下のようになる。

(MAPFONT D 2
   (FONTNAME uprml-v)
   (FONTDSIZE R 10.0)
   (FONTAT R 0.962216)
   )
(CHARACTER H 2148
   (MAP
      (MOVERIGHT R -0.481109)
      (SELECTFONT D 2)
      (SETCHAR H 301D)
      )
   )
(CHARACTER H 2149
   (MAP
      (SELECTFONT D 2)
      (SETCHAR H 301F)
      )
   )

CHARACTER 要素の中に含められるのは MAP だけで、 タイプは指定する前と変わらない(つまり 0x2148 はタイプ 1)。 「1 文字だけのサブタイプ」を作ったのと同じ動作になる。

サブタイプ毎のメトリックの指定

ZRTeXtor 1.3.0 版以降を用いている場合は、 サブタイプの指定(SUBTYPE 要素)で MAP の他に メトリック(CHARWD/CHARHT/CHARDP/CHARIC)が(仮想的に) 指定できるようになった。 すなわち、「タイプ」で共通しているのは GLUEKERN 指定だけとなり、 1 つのタイプの中で共通の MAP とメトリックをもつ文字の集合が 「サブタイプ」となる。 ただし、和文 TFM の仕様として「1 つのタイプは 1 つのメトリックをもつ」 と決められているので、メトリックの異なるサブタイプについては、 ZRTeXtor 内部において、共通の GLUEKERN をもつ別の新しいタイプに 分離させている。 その関係で、この機能は ZVP → VF/TFM の変換の時のみ働き、 逆方向への変換では考慮されない (分離されてできたタイプがそのまま現れる)。

異なるメトリックのサブタイプを利用する例として次のケースを考える。

従来の jis.tfm のメトリックでは和文のハイフン〈‐〉 (JIS X 0208 の 1-30)は全角幅で出力されるが、 これを四分幅で出力されるように変更する。 ただし、元の(VF 参照先の)等幅フォントでは ハイフンは四分幅の横棒が全角幅の中央に配置されるような デザインであることを想定する。
谷山‐志村予想の完全な証明が成されたのはその6年後のことであった。
従来のjisではハイフンが全角幅、修正後は四分幅。

参考: ここで問題にしているのは「和文のハイフン」 のことである。 和文におけるハイフンの使用は欧文のそれに比べて かなり少ない。 「谷山‐志村予想」のようなものを書く場合でも、 実際には和文ハイフンでなく中黒〈・〉や 二重二分ハイフン〈゠〉(JIS X 0208 にない) を用いることの方が多い。 (ただし、外国人の名前の場合、後者は複姓の間の区切りと解釈されうる。)

欧文ハイフンは LaTeX では ASCII の HYPHEN-MINUS〈-〉 により入力される(少なくとも 8 ビット欧文 TeX の場合)。 その字幅は欧文フォントにより異なる。

「日本語組版処理の要件」に従うと、 行組版における空き調整に関する限りはハイフンは普通の和文文字 (漢字・かな)と同じ振る舞いになる (勿論ハイフンは禁則の対象ではある)。 加えて、jis.tfm では字幅を全角幅として扱うので、結果的に、 ハイフンは普通の文字と同じタイプ 0 となっている。 そこで、次のような修正を行えばよいことになる。

  • タイプ 0 についてサブタイプ 1 を新設し、ハイフンをそこに所属させる (CHARSINSUBTYPE)。
  • サブタイプ 1 の SUBTYPE 要素にハイフンのための 記述を行う。 字幅を四分にし、従来のハイフンを移動して出力する MAP を置く。

では以下で実際にその修正を行う。 まず、jis.tfm を ZVP 形式に変換する。

pxutil vf2zvp -E jis

生成された jis.zvp に以下の記述を追加したものを jis-hyph.zvp として保存する。

(CHARSINSUBTYPE D 0 H 1
   X213E
   )
(SUBTYPE D 0 H 1
   (CHARWD R 0.240554)
   (MAP
      (MOVERIGHT R -0.360831)
      (SETCHAR)
      )
   )

CHARSINSUBTYPE 要素では、ハイフン(JIS の符号位置 0x213E) をタイプ 0 のサブタイプ 1 に所属させている。 そのサブタイプに対する設定が次の SUBTYPE 要素に書かれている。 字幅を四分(= 0.240554 単位;QUAD の 1/4)とする。 全角幅の中央に四分幅の横棒がある場合、左側の空きは 全角の 3/8(= 0.360831 単位)なので、 まずこの幅だけ左に移動したあと、元の(全角幅の)字形を 出力している(入力と同じ文字なので SETCHAR の引数を省略)。

注意: SUBTYPE 要素でメトリック指定(CHARWD/CHARHT/CHARDP/CHARIC) を省略した場合は元のタイプにおける値が使われる。 メトリックが完全に一致するサブタイプが複数あった場合は、 その間では内部でのタイプ分離処理は行われない。 従って、サブタイプでのメトリック変更を伴わない場合は、 ZRTeXtor 1.3.0 版以前の場合と同じ結果が得られることになる。 (ただし他にも細かな修正点があるので全く同一のファイル が得られるとは限らない。)

jis-hyph.zvp を VF+TFM の組に変換する。

pxutil zvp2vf jis-hyph

テスト用の文書。

\documentclass[a4paper]{jarticle}
\DeclareFontFamily{JY1}{jmc}{}
\DeclareFontFamily{JT1}{jmc}{}
\DeclareFontShape{JY1}{jmc}{m}{n}{<->jis-hyph}{}
\DeclareFontShape{JT1}{jmc}{m}{n}{<->jis-v}{}
\renewcommand\mcdefault{jmc}
\normalfont
\begin{document}
谷山‐志村予想の完全な証明が成されたのはその6年後のことであった。
\end{document}
「谷山‐志村予想の完全な証明が成されたのはその6年後のことであった。」
ハイフンが四分幅に組まれている。

参考: 生成された jis-hyph.vf/.tfm をもう一度 pxutil vf2zvp -E で ZVP に戻してみると 以下のようになる。 これを見ると、「タイプ 6」が新しくできていて、 タイプ 0 のサブタイプ 1 がタイプ 6 に移動していることが判る。

……(略)……
(GLUEKERN
   (LABEL D 0)
   (LABEL D 6)
   (GLUE D 1 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 3 R 0.240554 R 0.0 R 0.240554)
   (STOP)
   (LABEL D 1)
   (GLUE D 3 R 0.240554 R 0.0 R 0.240554)
   (STOP)
   (LABEL D 2)
   (GLUE D 0 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 6 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 1 R 0.481108 R 0.0 R 0.481108)
   (GLUE D 3 R 0.240554 R 0.0 R 0.240554)
   (GLUE D 5 R 0.481108 R 0.0 R 0.481108)
   (STOP)
……(略)……
(CHARSINTYPE D 6
   J213E
   )
……(略)……
(TYPE D 6
   (CHARWD R 0.240554)
   (CHARHT R 0.777588)
   (CHARDP R 0.138855)
   (MAP
      (MOVERIGHT R -0.360831)
      (SETCHAR)
      )
   )

付録

文字リストの書式

文字集合を指定する要素、すなわち

(CODESPACE <文字リスト>)
(CHARSINTYPE <タイプ> <文字リスト>)
(CHARSINSUBTYPE <タイプ> <サブタイプ> <文字リスト>)

<文字リスト> の部分には 以下の書式に従う符号位置指定を空白区切りで複数並べて書く。

  1. 文字そのもの: その文字の内部符号位置。非 ASCII 文字に限る。
  2. Jxxxx 形式: JIS コード値が xxxx である文字の内部符号位置。
  3. Uxxxx 形式: Unicode 値が xxxx である文字の内部符号位置。
  4. Xxxxx 形式: 整数 xxxx 自身を表す。
  5. PL の整数表現: 例えば H 1234 など。その値を表す。
  6. (CTRANGE <値1> <値2>)<値1> 以上 <値2> 以下 の整数値全部の指定。

ここで、「内部符号位置」とは内部文字コード (-kanji-internal)における符号位置 のことである。 また、xxxx は 1~6 桁の 16 進数を表す。 なお、従来の JPL の場合、pTeX の pltotf では 1 と 2 が、 upTeXの pltotf では加えて 3 が使用できる。 4~6 は ZVP の独自仕様となる。

1~3 は内部文字コードに依存する。 さらに、1 は文字を読む必然性から外部文字コードにも依存する。 これらの形式に関しては、場合によっては JIS と Unicode の 間のコード変換が行われていることになる。 例えば、内部文字コードが unicode の時、J2228 は「JIS 0x2228 = 〈※〉 = Unicode 0x203B」より 0x203B と 解釈される。 これを利用して、 1 つの ZVP から JIS と Unicode の 2 種類の仮想フォントを 得るという使い方が考えられるが、 これには「JIS と Unicode の間の変換は不安定である (複数の方式が混在している)」という問題がつきまとう。 pxutil は JIS が定めるものを基礎とするマッピングに 従っているが、DVI ウェアの中には異なるマッピングを用いる ものもある。 この理由により、私は JIS と Unicode の間の変換を 利用することを推奨していない。 符号系を関知しない -E オプションを 勧めているのも同じ理由である。

MAP 内で使用する要素

「ZVP 独自仕様」と断っているもの以外は VPL と共通である。

(SETCHAR <符号位置>)
文字を出力。ZVP 独自仕様として、符号位置を省略した場合は 仮想フォントで呼び出された符号位置を使う。
(MOVEUP <長さ>)
(MOVEDOWN <長さ>)
(MOVELEFT <長さ>)
(MOVERIGHT <長さ>)
出力位置を「上」/「下」/「左」/「右」に移動。 (縦書きでは時計回り90度分ずれる。)
(PUSH)
現在の出力位置を保存(スタックにプッシュ)。
(POP)
現在の出力位置を復帰(スタックからポップ)。 PUSH と POP は対である必要がある。 フォント指定は保存されないことに注意。
(SELECTFONT <フォント番号>)
参照フォントの切替。
(DIR <整数>)
ZVP 独自仕様。 書字方向の切替で、1 が縦書、0 が横書。 pTeX DVI の dir 命令に対応する。
(SPECIAL <文字列>)
(SPECIALHEX <16進数字列>)
special 命令。