以下は、DOS版のソースに付属していたドキュメントの一部です。
-------------------------------------------------------------------------------
		<<<　dviout/dviprt のプログラムの解説　>>>

		【主要なデータ用のバッファ】

                     Far Heap             Heap

フォントデータ  FONT_INFO_REC's  ->       name    フォント名
                  ｜     ｜      ->       k_dir   2 byte フォント拡張データ
                  ｜     ｜
                  ↓     ｜
pk_buf         pk, dir   ｜  ロードしたフォントファイル（packed）
(Font file buffer)       ｜
                         ｜
                       ↓↓↓
raster_buf        CHAR_INFO_REC's        文字データの情報
(Expanded font buffer)   ↓
raster_buf     文字のラスター・データ（unpacked）

bit_map_buf    表示／印刷イメージが展開されるバッファ
(Bit map buffer)

view_buf       縮小イメージ保存用バッファ



		【フォントデータのリンク】

１．各フォントに対し、フォントの情報の node の FONT_INFO_REC が、DVI ファイル
のフォント情報に現れる順に、リンクの形式で構成される

first_font_info -> FONT_INFO_REC -> FONT_INFO_REC -> ････


２．次に、FONT_INFO_REC は、フォント番号の順にソートされ、最適化された binary
tree が作成される。

                                                ｜―→  FONT_INFO_REC ...
                               ―→  FONT_INFO_REC
                             ｜                 ｜―→  FONT_INFO_REC ...
font_info_root -> FONT_INFO_REC 
                             ｜                 ｜―→  FONT_INFO_REC ...
                               ―→  FONT_INFO_REC
                                                ｜―→  FONT_INFO_REC ...


３．2 byte 文字の JTM ファイルがロードされたとき、同じキャラクタコードなら同じ
ラスターデータを持つもの同士で、グループを作り、リンクが作成される（トップが、
k_top で、次への pointer が、k_next

FONT_INFO_REC -> ･･･ -> FONT_INFO_REC  FONT_INFO_REC -> ･･･ -> FONT_INFO_REC



４．各文字のラスターデータを展開して得たとき、その文字の情報が、フォント別に、
しかも文字の最後の 4bits によって異なる root からなる binary tree のリンク形式
で、格納される。そこに、その文字のラスター・データへの pointer もある

              ->                              ｜――→ CHAR_INFO_REC->raster
              ->          ――→ CHAR_INFO_REC->raster
              ->         ｜                   ｜――→ CHAR_INFO_REC->raster
FONT_INFO_REC -> CHAR_INFO_REC->raster 
              ->         ｜                   ｜――→ CHAR_INFO_REC->raster
              ->          ――→ CHAR_INFO_REC->raster
              ･･                              ｜――→ CHAR_INFO_REC->raster
              ･･              ｜――
              -> CHAR_INFO_REC->raster
                              ｜――



		【フォントデータの情報】

struct FONT_INFO_REC {
  int		font_code;	/* フォント番号				*/

  int		font_type;	/* フォント・ファイルの種類		*/
				/* PXL100,.., ROM_FONT,... etc.		*/

  int		f_goth;		/* ゴシック、倍角のフラグ		*/

  char		*name;		/* フォントの名前 cmr10, min10 etc.	*/

  char far	*pk;		/* ロードしたフォント・ファイルのアドレス */

  struct CHAR_INFO_REC far	*char_info[16];
	/* 各文字のデータへの tree の roots の pointer 			*/
	/* 文字コードの下位の 4 bits で分けている			*/

  struct FONT_INFO_REC far	*k_top;
	/* 2 バイト文字でのグループ分けのトップ 			*/
	/* 同一のラスター・データを用いるものが、同じグループ（同じフォ */
	/* ント・ファイルを用い、倍角かどうかが同じ。疑似ゴシックは、ビ	*/
	/* ットマップバッファに展開時に処理するので、区別しない）	*/

  struct FONT_INFO_REC far	*k_next;
	/* 2 バイト文字でのグループ分けでの次へのリンク			*/

  long	size_para		/* デザイン・サイズ			*/

  strcut FONT_INFO_REC far	*next_font;
	/* 次の FONT_INFO_REC へのリンク				*/

  strcut FONT_INFO_REC far	*before_font;
	/* FONT_INFO_REC の tree の前の node への pointer		*/

  strcut FONT_INFO_REC far	*after_font;
	/* FONT_INFO_REC の tree の後ろの node への pointer		*/

  int	k_width;
	/* 2 byte 文字の標準の横幅の許容ドット数、JFM ファイルを基にする */

  int	k_height;
	/* 2 byte 文字の標準の縦幅の許容ドット数、JFM ファイルを基にする */

  int	last_code;
	/* 2 byte 文字の場合、フォント・ファイルに含まれる最後の文字の	*/
	/* JIS CODE							*/

  long	c;	/* DVI から読んだ TFM/JFM ファイルのチェックサム	*/

  union EXT {
    char far*	dir;
	/* 英字フォントのとき、メモリーにロードしたフォントデータの各文 */
	/* 字のアドレス・テーブルへのポインタ				*/

    union KFONT *kdir;
	/* ROM_FONT 以外の 2 byte 文字のとき使う KFONT へのポインタ	*/
};

  struct KFONT {
    int		width;		/* ドット単位での横幅（倍角を考慮せず）	*/
				/* 縦組み和文ではフォントの高さを示す   */
    int		height;		/* ドット単位での高さ			*/
    				/* 縦組み和文ではフォントの幅を示す。	*/
　　int		size;		/* (width+7)/8*height			*/
    int		base;		/* ベースラインより下げるドット数	*/
    int		fh;		/* ファイル・ハンドルの番号		*/
    char	*name;		/* フォント・ファイル名			*/
	/* 異なるフォントでも同一のフォント・ファイルを用いるときは、同 */
	/* じファイル・ハンドルを使う					*/
  };


struct CHAR_INFO_REC {
    int code;			/* 文字コード				*/

    CHAR_INFO_REC far	*next_char;	/* 次の文字の node の pointer	*/

　　CHAR_INFO_REC far	*former_char;	/* 前の文字の node の pointer	*/

    struct PREAMBLE_REC pre {
	/* Expanded font buffer に展開されたフォントの情報		*/
	/* 倍角は処理されているが、疑似ゴシックは処理されていない	*/

      int	width;		/* ドット単位での文字幅			*/
      int	height;		/* ドット単位での高さ			*/
      				/* これらは組方向によらない。*/
      int	pitch_offset;	/* 文字送り方向の offset		*/
      int	depth_offset;	/* 文字の深さ調整方向 offset		*/
      char far *raster;		/* ラスター・データへのポインタ		*/
      long	tfm_width;	/* scaled point 単位での文字送り幅	*/
      int 	byte_width;	/* (width+7)/8				*/
};


			【dviout/dviprt の処理の流れ】
o 初期化

  dvifile_open()
  コマンドラインにより、dvi ファイルをオープンする
  このとき、拡張子が付いていなければ、.dvi を補う（name_link）

  initialize()
    dviout.cfg/dviprt.cfg のパスを環境変数 TEXCFG から決定し、次の処理を順に
　　行う（read_post, set_config, set_option, set_dimension, make_font_list,
    make_page_index, pixel_init, buffer_init, stack_init, decode_init）

    read_post()
    dviファイルが正当なものかどうかチェックし POSTAMBLE から情報を読む
   （num, den, mag, l, u:ページの大きさ, s:スタックの大きさ, t:ページ数）

    set_config()
    dviout.par/dviprt.par のオプション・パラメータを読む

    set_option()
    起動時のオプション・パラメータを読む

    set_dimension()
    scaled point と pixel との変換比を縦横別に求め、変換をする関数（横 sptopxl,
    縦 vtopxl）に、set_convert で、渡す
    テキストの縦と横の pixel でのサイズをもとめる。但し、縦は、HeaderとFooterの
    サイズを除く

    make_font_list()
    環境変数 TEXPK と、dviファイルの fnt_def に基づいて、font_define で、フォン
    ト・ファイルを捜し、フォントのサーチがしやすいように font_sort で処理する
    但し、2バイト文字のフォントの場合は、jfm ファイルを捜す

      font_define()
      dviファイルの font_def を読み、フォント名と解像度などの情報を得る

        make_font()
        実際の解像度を求め、font_name_check によってフォント・ファイルを捜し、
        フォントの情報を FONT_INFO の形式で記録する（far メモリー）
        見つからなければエラーメッセージを表示する

          font_name_check()
          環境変数 TEXPK, フォント名、解像度、代替フォントの指定をみて、捜すべ
　　　　　きファイル名を fill_name_and_fig で作成し、%g が無い場合 access で、
　　　　　ある場合 accgth でフォント・ファイルを捜す
          見つからないフォントの、捜したファイル名を表示

            accgth()
            FARファイルか、GTHファイルかを ID を調べて決定し、求めるフォント・
            ファイルが含まれているかどうかチェックし、含まれていれば、それのあ
            る位置とサイズを求める

      font_sort()
      フォントのリストをフォント番号でソートし、捜し易いように make_font_tree
      で binary tree を作る

    make_page_index()
    dviファイルを読んで、各ページの先頭の dviファイルでの位置の表を作る

    pixel_init()
    3つのバッファのサイズを決定し、Bit map buffer の大きさから、1ページが分割さ
    れる数と、そこに展開される横と縦の pixel 単位の大きさを set_size により求め
    る

    buffer_init()
    3つの huge バッファを確保し、必要なら load_fc によってフォントキャシュ・フ
    ァイルを load_fc で、ロードする

      load_fc()
      フォントキャシュ・ファイルの整合性をチェック（いくつかのオプション・フラ
      グ、拡大率、huge バッファの位置とサイズ、フォント・ファイルのリストのチェ
      ックサムなど)し、各文字の情報とラスター・データを Expanded font buffer に
      ロードし、フォントリストも読んで、各文字の情報へのノードや、2 byte 文字の
      フォントのグループと疑似ゴシックのフラグをコピーする

    stack_init()
      dviファイルのデータに基づいて、スタック領域を確保する

    decode_init()
      現在は、何もしていない
-------------------------------------------------------------------------------
o 主要部分（-f と指定しなかった場合）

put_dvi()
-o によるページの進め方を読み、device_init のあと、-B オプション、あるいは、出
力ページ指定の起動時のパラメータを search_page で解釈して、print_page によって
出力する
最後に、device_end を呼ぶ

  device_init()
    dviout では、起動時のパラメータによってスクロール・スピードを設定し、-B オ
  プションがあれば、メモリーを読んで最初のページを設定する
　GDCのクロック、裏の GVRAM の存在を調べ、グラフィック画面を初期化する。また、
　表示する部分の大きさをもとに、画面のどの位置に表示するか決める
  View モードのときの表示位置、枠、それを記録するためのバッファを決める
    dviprt では、-O のパラメータをもとに、出力すべきデバイスを必要ならオープン
  し初期化のコードを送る

  print_page()
  指定された範囲のページを出力する
　処理中すべきページの指定された部分（dviout では、その番号を表示）を interpret
  で、Bit map buffer に展開し、device_clear を呼んだ後、現在のページの場所の番
  号を表示し、device_out で出力する。それからの戻り値で、次の部分を求めて同様の
  処理をする、あるいは抜けでる。ページが変わるときは、 pr_new_page を呼ぶ。

    set_output_size()
    展開する Bit map buffer は、一種のウインドウであるので、ページの中での位置
　　やサイズなどを split などを考慮して求める

    init_output()
    出力するページの先頭の dviファイルに於ける位置を求め、stackを元に戻し、Bit
    map buffer をクリアーし、Bit map buffer に関するポインタや定数をアクセスし
　　やすい形に bitmap_init でセットする

    interpret()
    変数の初期化の後、dviファイルのページ記述部分まで進んで、work によりそれを
　　を解釈して、Bit map buffer というウインドウに展開する

      work()
      dviファイルのページ記述部分を読み、コードに応じて、それを処理する関数を
　　　呼ぶ（font_change フォントの選択、cput 文字の印字、rput 罫線の印字、カレ
　　　ント・ポイントの移動、変数の push, pop、special コマンドなど）
      cput を呼んだ場合は、それの戻り値だけ水平方向にポインタを進める
      EOP に出会うまで続ける

        xxx1()
        \special コマンドは何もせず、必要なだけ読みとばす

        font_change()
        フォント番号のフォントをフォント・リストの中から捜し、そのアドレスを求
　　　　める
　　　　ゴシックかどうかのフラグをセットする

        rput()
        印字すべき box のサイズを、pixel 単位で求め、write_rule で、 Bit map 
        buffer に書く
        幅、高さが１以下になった場合でも、１とする

        cput()
        get_font で、その文字に関する大きさの情報とラスターデータを求め、
        sptopixel, vtopixel で印字すべき位置を、pixel 単位で求め、write_fontで
　　　　Bit map buffer に印字する
        ゴシックのフラグがあれば、横に 1 pixel ずらして同じものを印字する
        その文字に関する情報を読んで、横幅を scaled point 単位で返す

          get_font()
          要求された文字が Expanded font buffer に既に展開されているかどうか調
　　　　　べ、展開されていれば、その情報のあるアドレスを返す。存在しないとき:
          get_pk で、Font file buffer にロードされたフォント・ファイル（1 byte
          文字の時は、フォントのラスターデータが圧縮されて入っているファイル、
          2 byte文字の時は JFM ファイル）のその文字のある部分のアドレスを返す。
　　　　　その文字の情報を set_preamble で、Expanded font buffer に領域を確保し
　　　　　て書く。
          2 byte文字の時は、そのフォントのラスター・データが既に Expanded font
          buffer に存在するかどうか調べ、存在すれば、上の文字情報に書き加える。
　　　　　それ以外では、Expanded font buffer にその文字を展開し（倍角になって
　　　　　いれば、それを処理）、フォントの文字情報のリンクに加えて、そのアドレ
　　　　　スを返す。

            get_pk()
            Font file buffer に対応するフォント・ファイルがロードされていなけ
　　　　　　れば、load_pk でロードし、その ID を調べて、フォントの情報を FONT_
            INFO_REC に書く。JFM ファイルであって、さらに、フォントのラスター
　　　　　　データ・ファイルがまだオープンされていないときは、open_kfont で、
　　　　　　それをオープンし（このとき、どういうデータを使うかが決まる。ドット
　　　　　　サイズや、ROM_FONT を使うかどうか、疑似ゴシックにするかどうか）、
　　　　　　フォント情報を記録する。必要ならフォントのチェックサムの整合性を調
            べる。
            文字コードの正当性を調べて、その文字のデータのある部分のアドレスを
　　　　　　返す。

              load_pk()
              （バッファが足りないときは、バッファをフラシュしてから）
              与えられたファイル名のフォント・ファイルを load_pk_data で、
　　　　　　　Expanded font buffer にロードする（GTH あるいは FAR ファイルのと
　　　　　　　きは、対応する部分のみロードする）。

              open_kfont()
              環境変数 TEXKNJ にしたがって、最適の横幅の 2 byte 文字のラスター
　　　　　　　データのファイルを捜す。そのファイルが、他のフォントで、オープン
　　　　　　　されていなければ、オープンする。
　　　　　　　ROM_FONT になるか、倍角を使うか、ここで決まる。また、同一のグル
　　　　　　　ープにすべきものがあるかどうか、チェックし、情報も記録する。

            set_preamble()
              文字情報用の領域を Expaneded font buffer に確保し、ラスターデータ
　　　　　　　に関するデータ（pixel 単位での幅、高さ、オフセットの他に、文字ピ
　　　　　　　ッチ（tfm width）の \magstep などで補正されたものを計算して）記
　　　　　　　録し、そのアドレスを返す

      write_font()
      キャラクタの一部でも、現在の Bit map buffer というウインドウ内に入るかど
　　　うか調べ、入ってた部分のみ w_font によって、適当なビットをずらして Bit 
      map buffer に書き込む

    device_clear()
    dviout では、変数を初期化し、split番号が１以上なら表示に用いる GVRAM をク
　　リアーする。テキスト画面もクリアーしてカーソルを消す

    device_out()
    Bit map buffer のデータを各デバイスに出力し、必要な処理を行う

    pr_new_page()
    dviout では、何もしない。dviprt では、-nf に応じて、改ページコード、または
　　複数の改行コードを送る

  device_end()
  dviout.exe では、グラフィック画面の消去やグラフィック画面を元に戻す等の処理、
  dviprt.exe では、改ページや、プリンタを通常モードに戻すなどの処理を行う

-------------------------------------------------------------------------------
o 後処理

  save_fc()
  -r でファイル名が指定されていて、Expanded font buffer が起動時に比べて更新さ
　れており、フラッシュしていなければ、Expanded font buffer のデータ、フォント・
　リストのデータ、整合性チェックのための情報をファイルにセーブする

  information_out()
  フォントの使用状況などを表示する

  dvifile_close()
  dvi ファイル、2 byte 文字のフォント・ラスター・データ・ファイルをクローズする

  buffer_information()
  バッファの使用状況を表示する



			【移植のためのヒント】

１．PC-9801 の場合、グラフィック・ビデオ・ラムをバッファに用いることができるよ
うになっているが、これを禁止する。

２．CPU が 8086系 ならば、アセンブラのプログラム（*.asm）は、そのまま使えるで
あろう（dviprt.exe で使われる p_sub.asm, p_subnec.asm は、char *pr_buf, 
int pr_buf_len, pr_flush() を参照しているので注意）。
そのとき、dviprt.exe では pr_flush() のみが、hard ware dependent である。
dviout.exe では、device.c が、hard ware dependent である。
本質的には、上の、device_init(), device_cear(), device_out(), device_end() が
ハードに依存する部分（但し、オプションパラメータには、PC-9801 のみ有効なものも
ある）。

３．他の CPU の場合は、例えば、int が、16 bits でない場合などは、訂正すべき部
分が、いくつかあるであろう。

---
January 28, 1990, written by SHIMA
