このエントリーをはてなブックマークに追加
スポンサーリンク

ESC/P系制御コード

ESC/P

ESC/Pとは、かつて各社(NEC、富士通、東芝など)でそれぞれ独自の制御コードを作っていた時代に、エプソンのプリンターに搭載されていた制御コードです。なので、当時はいくつかある制御コード体系のうちの1つでした。その後、DOS/VがESC/Pのプリンタードライバーを標準で搭載したことで、事実上DOS/Vでは標準で使われるようになりました。

ESC/Pの特徴としては、バイナリで直にデーターを送出するものが多いという事で、実際、富士通やNEC系のコード体系では、イメージ印刷や外字登録ぐらいでしかバイナリデーターの送出はしない(富士通の場合は外字登録すらバイナリではない)のですが、ESC/Pではイメージ印字はもちろん、印字位置絶対指定などの引数を指定する場合にもバイナリで指定する事が多いです。

そのため、プリンタードライバーを作成するにあたって、シフトJISからJISコードに変換する際に、それがシフトJISコードとして送出されたものなのか、コマンドの引数として送出されたものなのかを、ドライバーの方で解析する必要があります。

ESC/Pではバイナリでパラメーターを設定するケースが多いため、バイナリコードは16進数(0x00)で表記します。

漢字オン、漢字オフ

<1C> & ・・・漢字オン
<1C> . ・・・・漢字オフ

プリンターの制御コードで「漢字」と言えば、ひらがなや全角カタカナ、全角記号を含めた全角文字全般の事をさします。漢字オンコマンド送出によって、全角モードとなり以降を全角のJISコードと解釈して全角文字を出力します。

NEC系では漢字モードを解除するために半角のいずれかのピッチを指定しましたが、ESC/Pではそうではなく漢字モードを解除するコマンドを送出します。すると漢字モードを指定する直前のピッチの半角モードになります。

文字間ピッチの指定

ESC/Pでは基本的に180DPIで扱います。ただし、それはESC/P制定時の規格であり、レーザープリンターでのエミュレーションはもちろん、後開発の高品位印字モードでは実際のドット数はが異なる場合があります。あくまで規格上に話として以下の説明をご覧ください。

10CPIにする

ESC/Pでは1ドットを180DPIで扱いますので、10CPIにするために半角ドットピッチを18ドットにする必要があります。といっても、デフォルトはこの値になっています。プリンタードライバー内では10CPIモードが指定された場合、全角文字印字の前に10CPI指定を送出しています。

<1B> P ・・・半角を10CPIにする

全角はデフォルトで13.3CPIですが、10CPIにするためにはドットピッチを36ドットにする必要があり、左右余白の合計を12ドットにする必要があります。ドライバーでは10CPIモードを指定すると左右に6ドットずつ余白を指定しています。

<1C> S 0x06 0x06 ・・・・・・全角の左右の余白に6ドットずつ余白を付加する



12CPIにする

ESC/Pでは1ドットを180DPIで扱いますので、12CPIにするために半角ドットピッチを15ドットにする必要があります。

<1B> M ・・・半角を12CPIにする

全角はデフォルトで13.3CPIですが、12CPIにするためにはドットピッチを30ドットにする必要があり、余白を6ドットにする必要があります。ドライバーでは12CPIモードを指定すると左右に3ドットずつ余白を指定しています。


13.3CPIにする

ESC/Pでは1ドットを180DPIで扱いますので、1.3CPIにするために半角ドットピッチを13ドットにする必要があります。そのためには、いったん15CPIを指定して半角1文字を12ドットにしておき、文字間に1ドット付加するように設定します。

<1B> g ・・・ 半角を15CPIにする
<1B> 0x20 0x01 ・・・文字間に1ドット付加する。

ただし、半角2文字につき1ドット補正しないと、半角2文字につき1ドットズレてしまいます。そのため、半角2文字につき補正ドット1ドットをあけるコマンドを送出します。

<1C> U ・・・ 半角スペース量補正オン
<1C> V ・・・ 半角スペース量補正オフ

全角はデフォルトの状態が13.3CPIです。ただし、さまざまなアプリで同じプリンターを電源を投入したまま継続して使用すると思いますので、他のアプリ終了後に電源を入れ直す必要がないように、あらかじめ<1C> S コマンドを使って左に0、右に3の余白を指定しておきます。

<1C> S 0x00 0x03 ・・・・・・全角の左余白を0、右余白を3ドットにする。(※デフォルトの設定)

※当プリンタードライバーでは、ESC/P用では引数による13.3CPIには対応していません。CPI指定なしてドライバーを組み込んだ後に、アプリ側で13.3CPIで印刷するコマンドを送出してください。

行間ピッチの指定

改行幅はデフォルトでは1/6インチです。ただし、罫線の縦をつなげたい場合などの際に、改行幅を1/8にする事ができます。
<1B> 0 ・・・ 1/8インチ改行幅設定
<1B> 2 ・・・ 1/6インチ改行幅設定(デフォルト)

その他に以下の指定もできます。
<1B> 3 0xXX ・・・ XX/180インチ改行幅設定
<1B> A 0xXX ・・・XX/60インチ改行幅設定

また、ドットインパクトプリンターで感圧紙やカーボン紙などの伝票の指定位置に文字を打ちたい場合には、XX/180インチ改行を使って印字位置を微調整する事もできます。

<1B> J 0x00〜0xff ・・・ n/180インチ改行
<1B> j 0x00〜0xff ・・・ n/180インチバック改行

このコマンドは改行コードがなくても単体で改行を行います。バック改行は、レーザープリンターでESC/Pエミュレーションで印刷する場合は、位置あわせがやりやすくなり重宝しますが、ドットプリンターでバック改行を行うと大抵は帳票がスプロケットから脱線する(これを「ジャムる」という)ので、やめた方が良いでしょう。

イメージ印字

プリンタにイメージを送信します。

書式
<1B> * モード ドット列数 データー … … …

モードは16進数1バイトで指定します。以下のものがあります。
モード 1列あたりの
ドット数
ドット密度
0x00 8 60×60
0x01 8 120×60
0x02 8 120×60
0x03 8 240×60
0x04 8 80×60
0x06 8 90×60
0x20 24 60×180
0x21 24 120×180
0x26 24 90×180
0x27 24 180×180
0x28 24 360×180
ドット列数は16進数2バイトで指定しますが、リトルエンディアンなので、下位バイト・上位バイトの順で送信します。8086アセンブラを使う場合は、そのままMOVコマンドでセットすれば良いのですが、MicroFocus COBOLなど一部バイナリデーターをビッグエンディアンで扱う言語では、上位バイトと下位バイトを反転させるなどの工夫が必要です。

データーの作成方法
24ドットイメージの場合、1列に対して3バイト分のデーターを用意します。ESC/Pでは上位ビットが上になっているため、ドットを上から下へキャリーフラグを含んで左シフトしながら3バイト分ローテーションさせて作成します。



例)
ドットの検査、ドットがあればSTC、なければCLCした後、
RCL BYTE PTR [LDAT3],1
RCL BYTE PTR [LDAT2],1
RCL BYTE PTR [LDAT1],1
を、ドットを縦に検査しながら24ドット分繰り返します。

できあがった1列分データーを必要な列分作成して、プリンターに送信します。プリンタードライバー(EPRINTER.SYS)では、ドット列数とバイナリバイト数分だけ透過モードとなり、シフトJIS→JISコードへの変換を行わなくなります。

外字印字

プリンターに内蔵されていないフォントを、外字として登録する事ができます。EPRINTER.SYSでは、/UFOオプションを指定することでJFGAIJ.UFOファイルを読み込んで外字エリアに転送を行う事ができます。

書式
<1C> 2 文字コード パターン

文字コード
外字を登録できるコードは7721〜777Eです。ただし、ATOK側では外字エリアはJISコードに直すと7F21からなので、0x0800を引く必要があります。また、文字コードはビッグエンディアンで指定するため、8086アセンブラでMOVする前に上位バイトと下位バイトを逆転させておく必要があります。

例)
MOV AX,[ADDR2]
SUB AX,0800H
XCHG AH,AL
MOV [ADDR],AX

外字データー
外字データーは72バイトのバイナリで指定します。JFGAIJ.UFOなどのフォントパターンは通常1バイトが横1スライスになっています。しかしこのコマンドでは1バイトが縦1スライスで指定するため、プリンターに転送する前に横スライスを縦スライスに変換する必要があります。

画面用フォントパタンを上から順に左にシフトしていき、1シフトごとにそれぞれキャリーフラグに押し出されたビットを、プリンター用フォントにシフトして読み込みませます。ESC/Pでは上が上位ビットであるため、左にシフトする必要があります。
;==============================================================================
;           画面用フォント  →  プリント用フォント
;==============================================================================
HENKAN		=	$
		MOV	SI,OFFSET KANPAT  ;SI ・・・・・・・ 表示用先頭アドレス
		MOV	DI,OFFSET PRPAT	  ;DI ・・・・・・・ プリント用先頭アドレス
		MOV	[KAISU1],BYTE PTR 8
		MOV	[KAISU2],BYTE PTR 3

;		上8ドット
UEPUT		=	$
		SHL	BYTE PTR [SI+00],1
		RCL	BYTE PTR [DI+00],1
		SHL	BYTE PTR [SI+03],1
		RCL	BYTE PTR [DI+00],1
		SHL	BYTE PTR [SI+06],1
		RCL	BYTE PTR [DI+00],1
		SHL	BYTE PTR [SI+09],1
		RCL	BYTE PTR [DI+00],1
		SHL	BYTE PTR [SI+12],1
		RCL	BYTE PTR [DI+00],1
		SHL	BYTE PTR [SI+15],1
		RCL	BYTE PTR [DI+00],1
		SHL	BYTE PTR [SI+18],1
		RCL	BYTE PTR [DI+00],1
		SHL	BYTE PTR [SI+21],1
		RCL	BYTE PTR [DI+00],1

;		まん中8ドット
NAKAPUT		=	$
		SHL	BYTE PTR [SI+24],1
		RCL	BYTE PTR [DI+01],1
		SHL	BYTE PTR [SI+27],1
		RCL	BYTE PTR [DI+01],1
		SHL	BYTE PTR [SI+30],1
		RCL	BYTE PTR [DI+01],1
		SHL	BYTE PTR [SI+33],1
		RCL	BYTE PTR [DI+01],1
		SHL	BYTE PTR [SI+36],1
		RCL	BYTE PTR [DI+01],1
		SHL	BYTE PTR [SI+39],1
		RCL	BYTE PTR [DI+01],1
		SHL	BYTE PTR [SI+42],1
		RCL	BYTE PTR [DI+01],1
		SHL	BYTE PTR [SI+45],1
		RCL	BYTE PTR [DI+01],1

;		下5ドット
SITAPUT		=	$
		SHL	BYTE PTR [SI+48],1
		RCL	BYTE PTR [DI+02],1
		SHL	BYTE PTR [SI+51],1
		RCL	BYTE PTR [DI+02],1
		SHL	BYTE PTR [SI+54],1
		RCL	BYTE PTR [DI+02],1
		SHL	BYTE PTR [SI+57],1
		RCL	BYTE PTR [DI+02],1
		SHL	BYTE PTR [SI+60],1
		RCL	BYTE PTR [DI+02],1
		SHL	BYTE PTR [SI+63],1
		RCL	BYTE PTR [DI+02],1
		SHL	BYTE PTR [SI+66],1
		RCL	BYTE PTR [DI+02],1
		SHL	BYTE PTR [SI+69],1
		RCL	BYTE PTR [DI+02],1

		ADD	DI,3

;		前半8ドット分終った?
		SUB	[KAISU1],BYTE PTR 1
		CMP	[KAISU1],BYTE PTR 0
		JE	ZENHANE
		JMP	UEPUT

ZENHANE		=	$
		ADD	SI,1
		MOV	[KAISU1],BYTE PTR 8

;		後半8ドット終った?
		SUB	[KAISU2],BYTE PTR 1
		CMP	[KAISU2],BYTE PTR 0
		JE	KOUHANE
		JMP	UEPUT

KOUHANE		=	$

		RET

ESC/P特有の注意点
ESC/Pの一部プリンターでは、同一コードの外字データーを複数回受信するとヘッドがキャリッジリターンしてしまうため、最悪の場合1文字印刷するごとにヘッドが左端に戻ってしまい印刷が非常に低速になってしまいます。

これを防ぐために、EPRINTER.SYSでは、同じ行内(つまり<CR><LF>を受信するまで)は同一コードで異なるパターンの外字はないものとして、改行コードが来るまでは複数回の外字登録はしないようにしています。

その他のコマンド

片方向印字
<1B> 0x55 0x00 (または<1B> 0x55 0x30) ・・・片方向印字解除(デフォルト)
<1B> 0x55 0x01 (または<1B> 0x55 0x31) ・・・片方向印字設定

シリアルドットプリンターでは、大抵はヘッドが左右に往復しながら印刷を行うわけですが、ヘッドが右から左へ移動する場合と、左から右へ移動する場合で印刷位置がズレてしまう場合があります。現在はステップモーターの制度が非常に上がっているので、ヘッドが左右に動きながら印刷を行っても印刷位置がズレる事はまずありませんが、当時のシリアルドットプリンターでは縦の罫線やハードコピーをズレずに印刷する時に、片方向印字を指定する必要がありました。

片方向を指定すると、ヘッドが左から右へ移動する時のみ印刷を行うようになります。ハードコピードライバーGRAPHES.COMではデフォルトでは片方向印字コマンドを送信しています。これは、オプションで変更する事もできます。インクジェットプリンターの中にはこのコマンド自体受け付けず、強制両方向印刷を行うものもあります。

絶対位置指定
<1B> $ 0x00 0x00 〜0x02 0x7c

ヘッドを左端からn/60インチに設定します。nは2桁の16進数で指定しますが、ビッグエンディアンで指定するため、8086アセンブラでMOVする前に上位バイトと下位バイトを逆転させておく必要があります。昔は、感圧紙の伝票の印刷アプリをこのコードを駆使して作っていたのですが、印刷位置を合わせるのが大変すぎて泣けてきました。

半角文字間指定
<1B> P ・・・ 10CPI指定(デフォルト)
<1B> M ・・・ 12CPI指定
<1B> g ・・・ 15CPI指定
<1B> p 0x00 (または <1B> p 0x30) ・・・ プロポーショナル解除 (デフォルト)
<1B> p 0x01 (または <1B> p 0x31) ・・・ プロポーショナル設定
<1B> 0x20 0x00〜00x7f ・・・半角文字間に付加するドットスペース量設定
<1C> T 左スペース 右スペース ・・・文字の左右の文字間スペースを指定(0x00〜0x7f)
<1C> U ・・・ 半角文字間補正ドット設定
<1C> V ・・・ 半角文字間補正ドット解除

半角のドットピッチを指定します。今でこそプロポーショナルピッチで印刷するのが当たり前ですが、当時は帳票を印刷する際に項目の印刷位置をスペースを送ることで調整していたため、半角は固定ピッチで全角の半分のピッチで印刷する場合がほとんどでした。なので、プロポーショナルはほとんど使われませんでした。

全角文字間指定
<1C> S 左スペース 右スペース ・・・文字の左右の文字間スペースを指定(0x00〜0x7f デフォルトは0x00 0x03)

拡大印刷
<1B> w 0x00 (または<1B> w 0x30) ・・・ ANK横2倍解除(デフォルト)
<1B> w 0x01 (または<1B> w 0x31) ・・・ ANK横2倍設定
<1B> W 0x00 (または<1B> w 0x30) ・・・ 横2倍解除(デフォルト)
<1B> W 0x01 (または<1B> w 0x31) ・・・ 横2倍設定
<1C> W 0x00 (または<1C> W 0x30) ・・・ 4倍角解除(デフォルト)
<1C> W 0x01 (または<1C> W 0x31) ・・・ 4倍角設定

縦書き
<1C> J ・・・ 全角縦書き設定
<1C> K ・・・ 全角横書き設定(デフォルト)
<1C> D ・・・ 半角縦書き組文字設定
半角縦書き組文字を設定すると、半角文字2文字ペアになって縦に印刷されます。

文字色指定
<1B> r 色
色はバイナリで指定しますが、資料不足のため指定方法は不明です。モノクロプリンターでは無視されます。

強調印刷
<1B> 0x2d 0x00 (または<1B> 0x2d 0x30) ・・・ アンダーライン解除(デフォルト)
<1B> 0x2d 0x01 (または<1B> 0x2d 0x31) ・・・ アンダーライン設定
<1B> 4 ・・・ イタリック設定
<1B> 5 ・・・ イタリック解除(デフォルト)
<1B> E ・・・ 強調印刷設定
<1B> F ・・・ 強調印刷解除(デフォルト)
<1B> G ・・・ 2度打ち設定
<1B> H ・・・ 2度打ち解除(デフォルト)
<1C> n 0x00 ・・・ 全角アンダーライン解除
<1C> n 0x01 ・・・ 全角アンダーライン細線指定
<1C> n 0x02 ・・・ 全角アンダーライン太線指定

特殊文字
<1B> q 0x00 ・・・ 特殊文字解除(デフォルト)
<1B> q 0x01 ・・・ 縁取り文字
<1B> q 0x02 ・・・ 影文字
<1B> q 0x03 ・・・ 縁取り影文字

一括指定
<1B> ! 0xXX
XXの内容
ビット0 ・・・ 0:10CPI 1:12CPI
ビット1 ・・・ 0:プロポーショナル解除 1:プロポーショナル指定
ビット2 ・・・ 0:ANK縮小解除 1:ANK縮小設定
ビット3 ・・・ 0:強調文字解除 1:強調文字設定
ビット4 ・・・ 0:2度打ち解除 1:2度打ち指定
ビット5 ・・・ 0:横拡張解除 1:横拡張設定
ビット6 ・・・ 0:イタリック解除 1:イタリック設定
ビット7 ・・・ 0:ANKアンダーライン解除 1:ANKアンダーライン設定

<1C> ! 0xXX
XXの内容
ビット0 ・・・ 0:全角横書き 1:全角縦書き
ビット1 ・・・ 0:全角半角文字モード解除 1:全角半角文字モード設定
ビット2 ・・・ 0:横2倍解除 1:横2倍設定
ビット3 ・・・ 0:全角縦倍解除 1:全角縦倍設定
ビット4 ・・・ 0:1/4倍解除 1:1/4倍設定
ビット5 ・・・ 0:上付1/4倍解除 1:上付1/4倍設定
ビット6 ・・・ 未使用
ビット7 ・・・ 0:全角アンダーライン解除 1:全角アンダーライン設定

参考文献
Microline5320SE 取扱説明書 OKI
VP-800取扱説明書 EPSON

スポンサーリンク