■                                                                    ■
■                dviprt 新プリンタ定義ファイル 仕様書                ■
■                            version S.2                             ■

                          Copyright (C) 1994 淺山和典 (ASAYAMA Kazunori)
                                                    TPM03937@pcvan.or.jp
                                               GHF01532@niftyserve.or.jp

========================================================================
● １． 概要
========================================================================

  この文書は、dviprt の新しいプリンタ定義ファイルの仕様書です。

========================================================================
● ２． プリンタ定義ファイルのソースファイル (*.src) の仕様
========================================================================

-----------
★ 2.1 項目
-----------

従来の項目については、そのまま継承する。それ以外に、以下の項目を追加。

 ・ encode
      ビットイメージデータのエンコードの種類。FAX, HEX (upper_position
    の HEX_MODE と同値), PCL1 などを指定する。
 ・ y_dpi (version 2)
      縦方向の解像度。dviprt の -DPI オプションに対応。

また、従来、必須だった以下の項目をオプションに変更。

 ・ maximal_unit
      未指定時には、十分に大きな値。

 ・ minimal_unit
      未指定時には、出力コードの大きさが最小になるであろう値。

-----------------------------
★ 2.2 数値の出力フォーマット
-----------------------------

  従来のフォーマットの上位互換とする。

  従来の \b2,\B2,\d3,\d4,\d5,\d? を拡張して、以下のようなフォーマットを
用意する。 この中で 'n' はその桁数を表すものとし、1 <= n <= 7、または n
== ? であるものとする。

(1) \bn  バイナリ 下位 -> 上位バイト
(2) \Bn  バイナリ 上位 -> 下位バイト
(3) \on   8 進 ASCII テキスト
(4) \dn  10 進 ASCII テキスト
(5) \hn  16 進 ASCII テキスト (小文字)
(6) \Hn  16 進 ASCII テキスト (大文字)
(7) \st  文字列を「式」の値の回数だけ出力 (詳しくは後述)

---------------
★ 2.3 式の表記
---------------

  式は以下の要素から成る。

(1) 整数
     ・ 'x' または 'X' で始まる数     16 進表記
          x 一文字だけ書いた場合、後述の「水平方向の絶対位置」とみなされ
        てしまうので注意すること。
     ・ '0' で始まる数                 8 進表記
     ・ '0' 以外の数字で始まる数      10 進表記
(2) 内部変数
     ・ w  出力幅 (dots)
     ・ h  出力高 (dots)
     ・ r  横方向の解像度 (dpi)
     ・ R  縦方向の解像度 (dpi)
     ・ p  通しページ番号
     ・ v  pins の項目の値を 8 で割ったもの (旧バージョンとの互換のため
        に用意)
     ・ c  constant の項目で定義された値 (旧バージョンとの互換のために用
        意)
     ・ s  出力データのバイト数
          send_bit_image, bit_row_header, after_bit_image の中でのみ使え
        る。
     ・ d  横方向の送り (印字データや水平スキップの水平方向のドット数)
          send_bit_image, bit_row_header, after_bit_image, skip_spaces
        の中でのみ使える。
     ・ x  水平方向の絶対的な印字位置 (dot)
          コードを出力する直前の印字位置を指している。従って、
        send_bit_image, bit_row_header,after_bit_image,skip_spaces 中で
        印字位置が移動した後の位置が欲しければ x の代わりに (x+d) を用い
        ること。x の値は after_bit_image や skip_spaces を出力した後に更
        新される。ただし NON_MOVING のプリンタの場合、after_bit_image の
        後では更新はされず skip_spaces を出力したあとにのみ更新される
        (つまり実際のプリンタの状態に一致するということ)。
     ・ y  垂直方向の絶対的な印字位置 (dot)
          x 同様、コードを出力する直前の位置を指している。値は line_feed
        を一回出力するごとに更新され、form_feed を出力した直後に 0 にリ
        セットされる。
(3) 演算子
         + 加算          | 論理和
         - 減算          & 論理積
         * 乗算          ^ 排他的論理和
         / 除算          > 右シフト
         % 剰余          < 左シフト
(4) 開き括弧 '(' と 閉じ括弧 ')'

  これらを組み合わせて「式」を形成する。「式」の表記の途中に空白文字を含
んではならない。

  式は、通常の中置記法で記述する。ただし、演算子の間に「優先順位はなく」、
左側から順に解釈される。例えば、以下のようなものが「式」の例。

  例 1).  p
  例 2).  (w+7)/8
  例 3).  r+R*128

  最後の例は、慣例的には r+(R*128) の意味であるが、ここでは、(r+R)*128
と解釈される。前者のように解釈させたいのであれば、括弧を用いて r+(R*128)
と明示的に演算順序を指定するか、R*128+r とすればよい。

  従来の書式オプション、'D'、'DD'、'DDD'、'T'、'M'、に関しては式による表
現で同じ結果を得ることが可能 (optcfg でこれらを処理すると、式による表現
に変換される)。

  例 1). \b2DDD
         \b2,d>3
  例 2). \d?M
         \d?,d*c
  例 3). \d4DDT
         \d4,(d*v)>3

  演算は、アプリケーション内部では符号なしの 2 byte で計算される。従って、
2 byte 符号なし整数で表される範囲からはみ出すような演算についてはその結
果は保証されない。

---------------------------
★ 2.4 式を用いた数値の出力
---------------------------

  実際に send_bit_image などで指定するには、一般的には、

    format,expr

と、書式と式を ',' で区切って記述する。',' の前後には空白文字を置いては
ならない。

  例 \d?,(w+7)/8

従来通りの値 (内部変数 d の値) を出力する場合には format のみを指定すれ
ばよい (つまり従来通りの指定方法)。

  例 \b2DDD

  ただし、format が \st の場合には、式を評価結果した結果を数値として出力
するのではなく、それを回数の指定であるとみなしてその回数分、指定された文
字列を出力する。

  この場合、出力フォーマットの指定の方法が異なり、

    \st,expr,"strings"

のように、最後に 「,"strings"」 が必要になる。この strings の部分が出力
する文字列の指定で、ダブルクウォーテーション 「"」で囲む。"strings" の内
部は基本的にエスケープシーケンスなどの「"」の外側と同じ記法が使え、空白
文字は無視される。ただし、「"」そのものを出力文字列に含めたい場合には
「\"」のように「\」でエスケープする必要がある。また、文字列中では書式指
定による数値の出力は指定できない。

  例えば、

    bit_row_header :  \st,"This \s is \s a \s pen.\n"

と書いておけば、ラスタ行の先頭に、その幅のドット数回だけ 「This is a
pen.」という文字列が出力される。


---------------------------------
★ 2.5 エスケープシーケンスの拡張
---------------------------------

  従来、\SP と \ESC が利用可能だったが、新たに次の C 言語 like なものも
使えるようにする。ただし、\ の一文字に限っては '\' そのものを表す、とい
う従来の仕様を引き継ぐ ('\' そのものを表すには C 言語では \\ と 2 つ重ね
る必要がある)。

    \n  LF          \t  H-TAB
    \r  CR          \s  SPACE
    \f  FF          \e  ESC
    \v V-TAB        \"  文字 "

-----------------------
★ 2.6 定義ファイルの例
-----------------------

 ・ PBM raw フォーマット

        name            : PBM image format
        upper_position  : LEFT_IS_HIGH
        pins            : 8
        minimal_unit    : 10000
        maximal_unit    : 10000
        bit_image_mode  : P4 \n \d?,w \s \d?,h \n
                   ;            ^^^^^    ^^^^^
                   ;            幅        高さ
        normal_mode     :
        send_bit_image  :
        after_bit_image :
        skip_spaces     :
        line_feed       :
        form_feed       :
        dpi             : 118

 ・ StarFax フォーマット

        name            : Starfax format
        upper_position  : LEFT_IS_HIGH
        pins            : 8
        minimal_unit    : 10000
        maximal_unit    : 10000
        bit_image_mode  : SF \x01 \x00 \x00 \x00 \x00 \x00
                          \x00 \x40 \x00 \x00 \x00 \x00 \x00
        normal_mode     : \x00 \x08 \x80 \x00 \x08 \x80 \x00 \x08 \x80
        send_bit_image  :
        after_bit_image :
        skip_spaces     :
        line_feed       :
        form_feed       : \x00 \x08 \x80 \x00 \x08 \x80 \x00 \x08 \x80
        dpi             : 208
        encode          : FAX   1728;2280
                   ;      ^^^   ^^^^^^^^^
                   ;      FAX出力   -FAXオプションのデフォルト引数

========================================================================
● ３． プリンタ定義ファイルのバイナリ (*.cfg)の仕様
========================================================================

  プリンタ定義ファイル中の整数値 (オフセット、バイト数など) は、そのバイ
ト数に関らず、下位バイト -> 上位バイトの順に記録されている。なお、全ての
整数値は符号なし。

  設定項目は、整数型、文字列型、プリンタコード型の 3 種類が有り、それぞ
れ、型毎に 0〜254 の項目番号を持っている。

  項目名と項目番号の対応は、ヘッダ s_cfg.h を参照のこと。

-----------------
★ 3.1 全体の構造
-----------------

    +----------------------+
    |       ヘッダ部       |
    +----------------------+
    |         任意         |
    +----------------------+
    |      整数型項目      |
    +----------------------+
    |         任意         |
    +----------------------+
    |     文字列型項目     |
    +----------------------+
    |         任意         |
    +----------------------+
    | プリンタコード型項目 |
    +----------------------+
    |         任意         |
    +----------------------+

---------------
★ 3.2 ヘッダ部
---------------

    オフセット  バイト数
            0          2   マジックナンバー
            2          2   バージョンナンバー
            4          4   数値型の項目値の位置のオフセット (ファイル先頭から)
            8          4   文字列型の項目値の位置のオフセット
           12          4   プリンタコード型の項目値の位置のオフセット
           16          1   文字 'S'
           17          1   値 0xFF
           18          1   値 0xFF

-----------
★ 3.3 任意
-----------

  何を何バイト書き込んでいてもよい。例えば、コメントや特定アプリケーショ
ンのための情報など。ただし、後者については互換性の関係上、プリンタコード
の生成に影響する情報を含めることは好ましくない。

-------------------
★ 3.4 整数型の項目
-------------------

    オフセット  バイト数
             0         1   整数型の項目の数 (0 〜 255)
             1         3   1 番目の項目
             4         3   2 番目の項目
             7         3   3 番目の項目
             :         :         :

各整数型の項目は、

         <- 1 byte -><------ 2 byte ------>
         +----------+----------+----------+
         | 項目番号 |         値          |
         +----------+----------+----------+
  項目番号とファイル中の順序とは一致しているとは限らない。また、項目番号
は、連続しているとも限らない。アプリケーション側では、必ず項目番号を確か
めて値を読み込む必要がある。他の型の項目についても同様。

  pins の項目は ピンの数を 8 で割った値が記録されている。upper_position
の項目は、以下のようなビットフィールドとして見る。

          15            8     7   6   5   4           0
         +-----------------+--------+---+---------------+
         |      未使用     |ピン配列|   |    未使用     |
         +-----------------+--------+---+---------------+
                                      ↑
                                   NON_MOVING
         ピン配列の意味は以下のとおり。
              +------ ビット順の反転
              | +---- 行優先
              | |
              0 0   HIGH_BIT
              0 1   LEFT_IS_HIGH
              1 0   LOW_BIT
              1 1   LEFT_IS_LOW

---------------------
★ 3.5 文字列型の項目
---------------------

    オフセット  バイト数
             0         1   文字列型の項目の数
             1       3+n   0 番目の項目 (n は文字列の長さ)
             :         :         :

各文字列型の項目は、

         <- 1byte  -><------ 2byte -------><--------- n bytes --------->
         +----------+----------+----------+----------+---- ..... ------+
         | 項目番号 |        長さ(n)      |            値              |
         +----------+----------+----------+----------+---- ..... ------+
文字列の最後には、null 文字は付加されていない。

-----------------------------
★ 3.6 プリンタコード型の項目
-----------------------------

    オフセット  バイト数
             0         1   プリンタコード型の項目の数
             1       3+n   0 番目の項目 (n はプリンタコードの長さ)
             :         :         :

各文字列型の項目は、

         <- 1byte  -><------ 2byte -------><--------- n bytes --------->
         +----------+----------+----------+----------+---- ..... ------+
         | 項目番号 |        長さ(n)      |            値              |
         +----------+----------+----------+----------+---- ..... ------+

「値」は、次の 2 種類のブロックが 1 次元的に n バイト並んでいる。

(1) 生データ
      そのままプリンタに送るコード。プリンタ定義のソース中の、\b2 などの
    書式付き出力以外の部分。 127 バイトを超える場合には分割される。

             <- 1byte  -><--------- m bytes --------->
             +----------+----------+---- ..... ------+
             |  長さ(m) |            値              |
             +----------+----------+---- ..... ------+
            ただし、長さ m は、 1 <= m <= 127。

(2) 書式付き出力
      式を評価し、その結果を指定された書式に従ってプリンタに送る。プリン
    タ定義のソース中の \b2 などの部分。

             <- 1byte  -><- 1byte -><--------- n bytes --------->
             +----------+----------+----------+---- ..... ------+
             |   書式   |  長さ(m) |            式              |
             +----------+----------+----------+---- ..... ------+

      「書式」は必ず、最上位ビットが立っている。従って、1 バイト目の最上
    位ビットを見れば生データなのか書式付き出力なのかの区別ができる。

      また、生データの場合と合わせると各ブロックの先頭バイトは 1 以上
    255 以下の値を取り、0 となることはない (生データは必ず 1 バイト以上
    含まれており、書式は最上位ビットが立っている)。従って、このことを利
    用して、*.cfg 読み込み時にコードの最後に 0 を 1 バイト付け加えて置け
    ば、出力時には 0 で始まるブロックに出会うまでプリンタコード型のデー
    タの処理を続ければよいことになり、処理が簡単になる。

    長さ m が 255 を超えるような式は記述できない。長さが 255 バイトの式
    とは、数 128、演算子数 127 という演算であり、これでも表現できないよ
    うな式は必要ないであろう。

    (A) 書式
          各ビットは以下のようになっている。

                   <--1--><--- 3 ---><-1--><--- 3 --->
                   +-----+----------+-----+----------+
                   |  1  |   形式   | ISO |   桁数   |
                   +-----+----------+-----+----------+
                   「形式」は、
                       バイナリ 下位バイト -> 上位バイト
                       バイナリ 上位バイト -> 下位バイト
                       ASCII テキスト 8 進数
                       ASCII テキスト 10 進数
                       ASCII テキスト 16 進数 大文字
                       ASCII テキスト 16 進数 小文字
                       文字列 (特殊形)
                   「桁数」 (形式が特殊形以外の場合に有効)
                       1 〜 7   桁数
                            0   可変長 (形式が ASCII テキストの場合のみ)
                   「ISO」 (形式が ASCII テキストの場合にのみ有効)
                       この bit が 1 かつ、「形式」が ASCII TEXT のとき、
                       出力の最終桁の文字コードに 16 (10h)を加える。例えば、
                       1000 という数値を 10 進 ASCII で出力したい場合、ISO
                       ビットが立っていると "100@" という ASCII 文字列が出力
                       される。

    (B) 式
          1 バイトを単位として以下のような逆ポーランド記法で m バイトの
        長さだけ記されている。

        (a) 0 〜 127   数値。そのまま整数として処理すればよい。
        (b) 128 〜 159   内部変数。解像度など。番号で指定される。
        (c) 160 〜 191   現在未使用。(予約済)
        (d) 192 〜 255   演算子。番号で指定される。

          数値は 127 までしか表せないが、これは optcfg 側で 127 以下の数
        を組み合わせて、同じ値を生成するような式に変換される。例えば、16
        進 7ff0 は、

                      x1<14|x7f<7|x70

                   ( C 言語の式で表せば、 (0x01 << 14) | (0x7f << 7) | 0x70 )

        という式で *.cfg 中に保存される。従って、アプリケーション側では
        特別な処理を行う必要はなく、他の演算同様に処理すればよい (そもそ
        もアプリケーション側からは見分けがつかない)。

          式の評価は以下のようにして行えばよい。

          まず、ある程度の深さを持ったスタックを用意し、次のことを「式」
        の最後まで繰り返す。(スタックの深さは、あらかじめ決めておき、ス
        タックがあふれるような複雑な計算は optcfg でチェックして跳ねてお
        く)

        (a) 数値 (最上位ビットが立っていない) であればその値をそのままス
            タックに積む。
        (b) 変数 (最上位ビットが立っておりその次のビットが立っていない)
            であれば、その値をスタックに積む。
        (c) 演算子 (上位 2 ビットが立っている) であれば、スタックトップ
            から 2 つの数をとってきて演算を行い、結果をスタックに積む。

          最終的にスタックトップにあるものを「書式」に従って出力すればよ
        い (optcfg でチェックを行っておくので スタックに余分な " ごみ "
        が残ることはありえない。同様にスタックがアンダーフローすることも
        ありえない ... チェックの必要なし)。

    (C) 特殊な「書式」
         ・ 文字列出力
              書式部の「形式」の値が 7 である場合にのみ、式の指定の後に
            文字列の指定が続く。文字列指定部は、

                         <- 1byte  -><--------- n bytes --------->
                         +----------+----------+---- ..... ------+
                         |  長さ(m) |            値              |
                         +----------+----------+---- ..... ------+
                          ただし、長さ m は、 0 <= m <= 255。

            という形をしている。「形式」が 7 の時には式を評価した結果を
            数値として出力する代わりに、式の評価結果を回数の指定とみなし、
            その回数だけここで指定された文字列をプリンタに送る (ソースフ
            ァイル中の書式 \st に対応)。


========================================================================
● ４． *.src <--> *.cfg 相互変換プログラム (optcfg)
========================================================================

  dviprt は バイナリ形式のファイル、*.cfg しか解釈できません。テキスト形
式のファイル (*.src) を dviprt で使う場合には必ず optcfg で *.cfg に変換
してください。この仕様において拡張されたものを用いた *.src の変換には
optcfg の version 3.0 以降が必要です。

-------------
★ 4.1 使い方
-------------

   optcfg [オプション]  SRCファイル1 [SRCファイル2 ... SRCファイルN]

  '[' と ']' で囲まれた部分は省略が可能なことを表しています。一度に複数
のファイルを変換する場合にはファイル名をならべてください。入力ファイルの
拡張子がデフォルト (バイナリは *.cfg、ソースは *.src) と同じ場合には省略
が可能です。

  例 1). escp_24.src -> escp_24.cfg の変換を行う

  optcfg escp_24.src

  例 2). 寡黙モードで escp_24.cfg と pc-pr_24.cfg をソースファイルに変換

  optcfg -r -q escp_24 pc-pr_24

---------------------
★ 4.2 オプション一覧
---------------------

 ・ -r   *.cfg -> *.src 変換を行います。*.cfg は旧仕様のものも受け付けま
    すが生成される *.src は新仕様のものです。
 ・ -q   寡黙モード。*.cfg -> *.src 変換の際にファイルの上書きの確認を求
    めません。

-----------------
★ 4.3 コンパイル
-----------------

  optcfg.c dviprcfg.c s_cfg.h s_cfgblt.h をカレントディレクトリにおいて、
C コンパイラに optcfg.c を処理させます (dviprcfg.c と s_cfg.h s_cfgblt.h
は optcfg.c から include されます)。

  例 1). bcc optcfg.c
  例 2). cc -O -o optcfg optcfg.c

  optcfg.c は UN*X の cc でもコンパイルできることを意図して書かれていま
すが実際にコンパイルのテストを行ったわけでは有りません。不具合があればご
一報ください。

=========================== End of document ============================
