DVI format


January 23, 2003

   目 次

1. DVIファイルのフォーマット
     プリアンブル
     ページ数の個数のページ記述部
     ポストアンブル
2. フォントの定義とDVIware
3. DVI命令
     DVI命令一覧
4. pTeX における縦書きと横書きの切替
5. DVIファイルと可読テキスト形式ファイルとの間の変換
     
   関連リンク
Windows 95/98/Me/NT/2000/XP における TeX システムのインストール
dvioutのインストール
TFMファイルとJFMファイル


1. DVIファイルのフォーマット

プリアンブル

pre(247) で始まり,寸法の単位や,DVIを作成したTeXのコメント文がある() pre i[1] num[4] den[4] mag[4] k[1] x[k] (15+k) byte i[i] DVIのバージョン番号で現在 2 num[4] スケールファクター(32bit符号無し整数) 通常 25400000 den[4] デザインサイズ(32bit符号無し整数) 通常 473628672 = 7227x216 DVIファイルにおける寸法の単位を,num/den x 10-7 m にする 通常 1 sp(scaled point) = 2-16 pt = 1.525...x10-5 pt = 5.362...x10-9 m = 0.0000053..mm 232 (=4294967296) sp = 23.03...m 1 inch = 2.54cm = 72.27 pt mag[4] 拡大率(32bit符号無し整数) 上記で決めた寸法を mag/1000 倍して使用 拡大縮小を行わないときは,mag = 1000 k[1] コメント文の長さ(0 - 255) x[k] コメント文

ページ数の個数のページ記述部

最初のページ) bop(149) で始まるヘッダ bop c0[4] c1[4] c2[4] c3[4] c4[4] c5[4] c6[4] c7[4] c8[4] c9[4] p[4] (45 byte)     c0[4],... TeX において \shipout が実行されたときの \cout0,... の値のコピー c0 は,TeXにおける頁番号.c1,...,c9 は通常 0 p[4] 直前のページのbopの位置 最初のページでは,NULLポインタを表す -1 の値が入っている ページの内容の記述 移動命令,フォント定義命令,文字や箱の描画命令など eop(140) ページの終わり eop (1 byte) 次のページ(最初のページと同様) bop(149) で始まるヘッダ bop c0[4] c1[4] c2[4] c3[4] c4[4] c5[4] c6[4] c7[4] c8[4] c9[4] p[4] (45 byte) ページの内容の記述 移動命令,フォント定義命令,文字や箱の描画命令など eop(140) ページの終わり eop (1 byte) ... 最後のページ bop(149) 始まるヘッダ bop c0[4] c1[4] c2[4] c3[4] c4[4] c5[4] c6[4] c7[4] c8[4] c9[4] p[4] (45 byte) ページの内容の記述 移動命令,フォント定義命令,文字や箱の描画命令など eop(140) ページの終わり eop (1 byte)

ポストアンブル

post(248) で始まるヘッダpost p[4] num[4] den[4] mag[4] l[4] u[4] s[2] t[2] (29 byte) p[4] 最後のページの bop の位置 num[4], den[4], mag[4] preamble におけるのと同じ値 l[4] ページにおける高さと深さの最大値の和 u[4] ページの幅の最大値 s[2] スタックの最大レベル t[2] 全ページ数(すなわち,bop命令の数) フォント定義命令(これがフォントの数だけ並ぶ) fntdef1(243), fntdef2(244), fntdef3(245), fntdef4(246) のいずれかで始まるフォント定義 fntdefx k[x] c[4] s[4] d[4] a[1] l[1] n[a+l] (15+x+a+l byte) k[x] フォント番号 c[4] フォント(TFMファイル)のチェックサム s[4] スケールファクター d[4] デザインサイズ a[1] フォントのディレクトリ名の部分の長さ(通常 0) l[1] フォントの名前の部分の長さ n[a+l] フォント名の文字列 ... フォント定義命令 fntdefx k[x] c[4] s[4] d[4] a[1] l[1] n[a+l] post_post(249) で始まる末尾 post_post q[4] i[1] 223,...,223 (10 - 13 byte) q[4] post の位置 i[1] フォーマットの ID(通常 2 だが,pTeX の縦書きでは 3) 223 ... 223 DVIファイルサイズが 4 の倍数となるよう 4 - 7個の 223 を置く

2. フォントの定義とDVIware

DVIファイルを読んで表示・印刷などを行う DVIware は,次のようにしてDVIファイルを解釈することができます.
  1. DVIファイルの先頭の 1 byte が pre で,その次の 1 byte が 2 でないと通常のDVIファイルとは認められない.
  2. DVIファイルを,末尾からさかのぼって 223 以外の値を得るまで,バイト単位で読みます.
  3. 223 の個数が 4個から 7個までの間でないと不正
  4. 上記の 223 以外の値が 2 なら通常の DVI ファイル,3 なら縦書きを含む pTeX,それ以外ならばエラー
  5. そこから前の 4 byte を読んで q[4] すなわち post の位置を得る.
  6. その位置の 1 byte が post でなければエラー
  7. post の次からの 28 byte を読んで p[4] num[4] den[4] mag[4] l[4] u[4] s[2] t[2] を得る.
    ・ num den mag から,DVIファイルでの長さの単位と拡大率を得る.
    ・ s からスタックのために確保すべき領域サイズを得る(4 x 6 x s byte).
    ・ t は総ページ数
    ・ p は最後のページの bop の位置
  8. post の 29 byte 後からはフォント定義命令が続いているので,フォント定義命令が終了するまで(すなわち post_post まで)読んで,DVIファイルで使われる全フォントの情報を得る.
  9. 各ページの bop から数えて 41 byte からの 4 byte の p[4] は,その前のページの bop の位置であるので,最終ページから逆にたどることによって,各ページの bop の位置が分かる.
    ・ 実際に bop が存在すること,最初のページに書かれた p[4] が -1 であることをチェックしておく.
    ・ bop の次の 4 byte c0[4] は TeX におけるページ番号として用いられているので,利用できる.
  10. 必要なページを,そのページの bop の 45 byte 後から順に,ページの終わりの eop に出会うまで,解釈する(DVI命令を翻訳して出力する).

3. DVI命令

変数役割
hカレントポイントの水平位置
vカレントポイントの垂直位置
w水平移動量の変数
x
y垂直移動量の変数
z
fカレントフォント
1つのページ記述部は,bop 命令で始まり,eop 命令で終わります.

そこでは右の7つの変数 h, v, w, x, x, y, z, f が使用されますが,それらは f を除いて各ページの始まりで 0 に初期化されます.ただし,f のみは未定義,となります.

座標の原点は,用紙の左上端から右へ 1 inch, 下へ 1 inch の用紙内部にあり,座標 (h,v) の点とは,そこから右へ h,下へ v の位置の点を表します.

描画は,常にカレントポイント (h,v) という座標の点を基準になされ, 「高さ a,幅 b の箱の描画」とは, 「カレントポイントが箱の左下端となるような中の詰まった箱の描画」を表します. 例えば罫線は,その太さを高さに,長さを幅に設定して描画されます.

以下に,DVI命令の一覧を載せます.そこでは,

DVI命令一覧
コード命令引数[符号付bytes] 意味
   0setchar0    なし 文字 ch(f,0) を (h,v) に描画,h ← h + w(f,0)
  ...setcharxx    なし 文字 ch(f,xx) を (h,v) に描画,h ← h + w(f,xx)
127 setchar127    なし 文字 ch(f,127) を (h,v) に描画,h ← h + w(f,127)
128 set1 c[1] 文字 ch(f,c) を (h,v) に描画,h ← h + w(f,c)
129 set2 c[2]
130 set3 c[3]
131 set4 c[4]
132 setrule a[4] b[4] 高さ a,幅 b で箱を (h,v) に描画,h ← h+b
133 put1 c[1] 文字 ch(f,c) を (h,v) に描画
134 put2 c[2]
135 put3 c[3]
136 put4 c[4]
137 putrule a[4] b[4] 高さ a,幅 b で箱を (h,v) に描画
138 nop    なし 何もしない
139 bop c0[4] ... c9[4] p[4] ページの始まり,(h,v,w,x,y) ← 0,スタックを空に
140 eop    なし ページの終わり
141 push    なし   (h,v,w,x,y,z) をスタックに待避
142 pop    なし   (h,v,w,x,y,z) をスタックから戻す
143 right1 b[1]   h ← h+b
144 right2 b[2]
145 right3 b[3]
146 right4 b[4]
147 w0    なし   h ← h+w
148 w1 b[1]   h ← h+b,w ← b
149 w2 b[2]
150 w3 b[3]
151 w4 b[4]
152 x0    なし   h ← h+x
153 x1 b[1]   h ← h+b, x ← b
154 x2 b[2]
155 x3 b[3]
156 x4 b[4]
157 down1 a[1]   v ← v+a
158 down2 a[2]
159 down3 a[3]
160 down4 a[4]
161 y0    なし   h ← h+y
162 y1 a[1]   h ← h+a,y ← a
163 y2 a[2]
164 y3 a[3]
165 y4 a[4]
166 z0    なし   h ← h+z
167 z1 a[1]   h ← h+a,z ← a
168 z2 a[2]
169 z3 a[3]
170 z4 a[4]
171 fntnum0    なし   f ← 0
  ... fntnumyy    なし   f ← yy
234 fntnum63    なし   f ← 63
235 fnt1 k[1]   f ← k
236 fnt2 k[2]
237 fnt3 k[3]
238 fnt4 k[4]
239 xxx1 k[1] x[k] special の文字列 x,意味は任意
240 xxx2 k[2] x[k]
241 xxx3 k[3] x[k]
242 xxx4 k[4] x[k]
243 fntdef1 k[1] c[4] s[4] d[4] a[1] l[1] n[a+l]                   フォント k の定義
244 fntdef2 k[2] c[4] s[4] d[4] a[1] l[1] n[a+l]                   フォント k の定義
245 fntdef3 k[3] c[4] s[4] d[4] a[1] l[1] n[a+l]                   フォント k の定義
246 fntdef4 k[4] c[4] s[4] d[4] a[1] l[1] n[a+l]                   フォント k の定義
247 pre i[1] num[4] den[4] mag[4] k[1] x[k]                 プリアンブル始まり
248 post p[4] num[4] den[4] mag[4] l[4] u[4] s[2] t[2]    ポストアンブル始まり
249 post_post q[4] i[1] 223 ... 223 ポストアンブル終わり
250 opcode    - 未定義
  ... opcode    -
254 opcode    -
255 diro[1] 横書き/縦書き切替(pTeX),元来は未定義

4. pTeX における縦書きと横書きの切替

5. DVIファイルと可読テキスト形式ファイルとの間の変換

dvispc

  • dv2dt/dt2dv より読みやすいテキスト形式(3. DVI命令 で述べた形 --- pdvitype などと同じ --- に対応,さらに意味を示すコメントも付加可能)が用いられていますが,dv2dt/dt2dv の可読テキスト形式での入出力もでき,dv2dt/dt2dv よりも高速です.

  • ソースをコンパイルすれば,Unix 等でも使用可能です.

  • 応用として,たとえば以下のようにすれば foo.dvi の 1ページ目と20ページ以降を抜き出した foo2.dvi が作成されます.
       dvispc -atpT3/20-L foo.dvi | dvispc -x foo2.dvi
    
    ここで,-a: DVI → Text変換   -t: DTL形式(出力サイズが小さくなる)   -pT3/20-L: 出力箇所の指定で,T はプリアンブル,3 20- は 3ページ目,20ページ目以降,L はポストアンブルを,それぞれ表し,-x: は TeX → DVI変換 の指定を表す.

    awk スクリプトなどのフィルターを間に挟むと,様々な加工が可能です. 例えば,foo.dvi の special を全て削除した foo2.dvi は以下のように作成できます.

       dvispc -aj foo.dvi | grep -v ^xxx | dvispc -x foo2.dvi
    
  • 以下に -avl というパラメータでの TeX → DVI変換 の一部を載せます(dviout のパッケージに付属の epsfdoc.dvi を用いた例).
    プリアンブル
    0: pre 2/id 25400000/num 473628672/den 1000/mag 27/len ' TeX output 2000.02.21:0054'
    
    上に引き続く最初のページ
     [1]
    42: bop 1/page 0 0 0 0 0 0 0 0 0 -1/former_bop
    87: down4 46202880
    92: push
    93: down4 -45613056
    98: push
    99: push
    100: right3 1114112
    104: xxx1 17/len 'color push  Black'
    123: right4 27394048
    128: xxx1 9/len 'color pop'
    139: pop
    140: pop
    141: down4 43646976
    146: push
    147: down4 -38549854
    152: push
    153: push
    154: push
    155: right4 9009997
    160: xxx1 17/len 'color push  Black'
    179: xxx1 9/len 'color pop'
    190: pop
    191: pop
    192: right4 9337677
    197: fntdef1 33 0x44D3ED74/c-sum 1132462/s-size 1132462/d-size 0/dir 5/name 'cmr17'
    218: fntnum33
    219: setchar68
     "D"
    220: right2 -29583
    223: setchar86
    224: setchar73
    225: setchar79
    226: setchar85
    227: setchar84
     "VIOUT"
    ...
    465: fntdef1 49 0xE99FD0F6/c-sum 943718/s-size 655360/d-size 0/dir 6/name 'goth10'
    487: fntnum49
    488: set2 0x244f "は"
    491: set2 0x2438 "じ"
    494: set2 0x2461 "め"
    497: set2 0x244b "に"
    500: pop
    501: z3 1474560
    ...
    5200: eop        最初のページ終わり
    
    2ページ目
     [2]
    5201: bop 2/page 0 0 0 0 0 0 0 0 0 42/former_bop
    ...
    
    ...
    26001: eop       7ページ目の終わり
    
    8ページ目(最後のページ)
     [8]
    26002: bop 8/page 0 0 0 0 0 0 0 0 0 21404/former_bop
    ...
    26786: pop
    26787: right4 27394048
    26792: xxx1 9/len 'color pop'
    26803: pop
    26804: pop
    26805: eop       最後のページ終わり
    
    ポストアンブル
    26806: post 26002/final_bop 25400000/num 473628672/den 1000/mag 46202880/h+d 28508160/w 13/stack 8/pages
    26835: fntdef1 54 0xC2D64EA0/c-sum 786432/s-size 786432/d-size 0/dir 6/name 'cmbx12'
    26857: fntdef1 53 0xDFEA3C78/c-sum 655360/s-size 655360/d-size 0/dir 6/name 'cmtt10'
    26879: fntdef1 51 0xC2D64EA0/c-sum 943718/s-size 786432/d-size 0/dir 6/name 'cmbx12'
    26901: fntdef1 49 0xE99FD0F6/c-sum 943718/s-size 655360/d-size 0/dir 6/name 'goth10'
    ...
    27196: fntdef1 7 0x4BF16079/c-sum 655360/s-size 655360/d-size 0/dir 5/name 'cmr10'
    27217: fntdef1 6 0xD993A052/c-sum 458752/s-size 458752/d-size 0/dir 4/name 'cmr7'
    27237: post_post 26806/post 2/id 223 223 223 223 223            DVIファイルの終わり