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

ESC/P系制御コード

ESC/P

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

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

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

バイナリパラメーターの難しさ

たとえば、PC PR201で絶対位置指定する場合、ESC F 0484 という風に、パラメーターは基本的にテキストで指定します。なので、COBOLで制御するのであれば、

	01 MEI1.
		03 FILLER	PIC X(01) VALUE X"1B".
		03 FILLER	PIC X(01) VALUE "F".
		03 FILLER	PIC 9(04) VALUE 484.

というふうに、比較的容易に設定できます。

ところが、ESC/Pではパラメーターをバイナリで扱うため、たとえば絶対位置を指定するにしても、

	01 MEI1. 
		03 FILLER	PIC X(01) VALUE X"1B".
		03 FILLER	PIC X(01) VALUE "$".
		03 MEI1B-1	PIC X(02).

としておき、別途

	01 BINH			PIC 9(05) COMP.
	01 FILLER REDEFINES BINH.
		03 FILLER	PIC X(01).
		03 BINH2	PIC X(02).
	01 FILLER REDEFINES BINH.
		03 FILLER	PIC X(01).
		03 BINHA	PIC X(01).
		03 BINHB	PIC X(01).
	01 BINHC		PIC X(02).

                        :
                    (省略)
                        :

	BINCONV.
		MOVE	BINHA TO BINHC.
		MOVE	BINHB TO BINHA.
		MOVE	BINHC TO BINHB.

のように変換しなければなりません。

COBOLでは、9(04) COMPとすると、9999までの値(270F)しか代入できず、9(05) COMPすると3バイト確保されてしまいます。また、ESC/Pでは2バイト以上のパラメーターをリトルエンディアンで指定しなければなりませんが、COBOLではCOMPと指定するとビッグエンディアンで格納されるため、リトルエンディアンに変換する必要があります。

また、パラメーターによっては、パラメーターがシフトJISの第1バイト(80H〜9FH、E0H〜FFH)とバッティングしてしまい、プリンタードライバーが勝手に [漢字ON] JISコード [漢字オフ] に変換してしまいます。したがって、プリンタードライバーの方で、送信されてきたデーターを解析して、送られてきたデーターがシフトJISコードの漢字(2バイト文字の上位バイト)ではなく、パラメーターの一部であると認識させなければなりませんでした。

東芝J-3100付属のESC/Pプリンタードライバーでは、 ESC/Pコマンドを解析してJISコード変換を行わないバイト数を決定するような事はせず、 単に「漢字変換を行わない」という割り込みを新設するだけでした。 なので、DOS/Vで使おうとすると、引数にバイナリを使うコマンドを使う事ができず、 ESC/Pプリンターで細かい位置合わせができませんでした。そこで、ESC/Pコマンドの解析機能を有するプリンタードライバーの作成が急務となりました。当サイトで掲載しているプリンタードライバー(EPRINTER.SYS)はそのために生まれました。

ESCシーケンス

ESC に続いてコマンド、引数を送信します。☆マークのついたコマンドは、当サイトで掲載しているプリンタードライバーで対応しておらず、使うとパラメーターをシフトJISの1バイト目だと思ってJISコードに誤変換してしまう場合があります。

ANK文字間ピッチの調整
ESC スペース(1B 20)
半角文字の文字間を調整します。といっても、既定値よりも詰めることはできず、既定値に何ドット足すかの指定です。ESC スペースに続いて、1バイトのバイナリで指定します。デフォルトは0です。

ANK印字モード一括指定
ESC !(1B 21)
ANKの印字モードを一括で指定します。パラメーターは1バイトですが、それぞれのビットに意味があって、
0 ・・・ プロポーショナルピッチ時、1:12CPI 0:10CPI
1 ・・・ 1:プロポーショナルピッチ 0:固定ピッチ
2 ・・・ 1:横幅縮小 0:縮小しない
3 ・・・ 1:強調印字 0:強調しない
4 ・・・ 1:二重印字 0:一重印字
5 ・・・ 1:横幅拡大 0:拡大しない
6 ・・・ 1:イタリック 0:イタリックにしない
7 ・・・ 1:アンダーライン 0:アンダーライン引かない

絶対位置指定
ESC $(1B 24)
ヘッドを指定位置まで移動させます。1/60インチ単位で指定できます。パラメーターは2バイトのバイナリで、リトルエンディアンで指定します。8086アセンブラならDW、C言語ならshortで定義すれば良いのですが、COBOLやFM-7等のモトローラー系のアセンブラ等のビッグエンディアンで変数が格納される言語では、変換する必要があります。

ダウンロード文字/内蔵フォントの切り替え
ESC %(1B 25)
ESC %に続いてパラメーターを1バイトのバイナリで指定します。
00 内蔵フォントを使う
01 ダウンロード文字を使う

ダウンロード文字の登録
ESC & NUL(1B 26 00)
ダウンロード文字を登録します。ESC & NULL に続いて、 登録開始コード、登録終了コード、左側スペース、文字幅、右側スペース、データー・・・と指定します。左右のスペースは、ドラフトなら9、高品位文字なら29、プロポーショナルなら37まで指定できます。

データーは、縦1列につき3バイト必要なので、1文字につき文字幅x3バイト必要です。ただし、スーパースクリプト文字の場合は文字幅x2バイトになります。ドライバーの方でスーパースクリプトなのか否かを、ESC Sが送信されたかどうかで判断しています。

;-------- ESC S スーパーサブスクリプト
CHK19		=	$
		CMP	CS:[KAKO2],BYTE PTR 1BH
		JNE	CHK20
		CMP	CS:[KAKO1],BYTE PTR "S"
		JNE	CHK20
		MOV	CS:[SUPER],BYTE PTR 1

;-------- ESC T スーパーサブスクリプト解除
CHK20		=	$
		CMP	CS:[KAKO2],BYTE PTR 1BH
		JNE	CHK21
		CMP	CS:[KAKO1],BYTE PTR "T"
		JNE	CHK21
		MOV	CS:[SUPER],BYTE PTR 0

したがって、バイナリデーターが来るバイト数は、
・普通の文字
 → ([終了コード] - [開始コード] +1) x 文字幅 x 3
・スーパーサブスクリプト文字の場合、
 → ([終了コード] - [開始コード] + 1) x 文字幅 x 3
で求められます。

;--------------------------------------------------------------------------
;            現在透過モード3ダウンロード文字セット
;--------------------------------------------------------------------------
TOUKA_MODE3_IN  =       $
                MOV     CS:[TOUKA_P],WORD PTR 0
                MOV     CS:[TOUKA_F],BYTE PTR 3
                MOV     CS:[KAKO1],BYTE PTR 0
                MOV     CS:[KAKO2],BYTE PTR 0
                MOV     CS:[KAKO3],BYTE PTR 0
                MOV     CS:[KAKO4],BYTE PTR 0
                MOV     CS:[KAKO5],BYTE PTR 0
                MOV     CS:[KAKO6],BYTE PTR 0
                MOV     CS:[a0],BYTE PTR 0
                MOV     CS:[a1],BYTE PTR 0
                MOV     CS:[a2],BYTE PTR 0

;               a1〜a3のエリアにはまだ何も入ってないことを示す
                MOV     CS:[ACNT],BYTE PTR 0

;               何文字送られてくるのかを計算する
                MOV     BH,CS:[KAKO1]
                SUB     BH,CS:[KAKO2]
                ADD     BH,1
                MOV     CS:[MOJISUU],BH

;               今どの文字を定義中なのか?の初期値をセット
                MOV     BL,CS:[KAKO2]
                MOV     CS:[IMANOMOJI],BL

;               a0〜a2のエリアに転送
TOUKA_MODE3     =       $
                CMP     CS:[ACNT],BYTE PTR 0
                JE      TM3_0
                CMP     CS:[ACNT],BYTE PTR 1
                JE      TM3_1
                CMP     CS:[ACNT],BYTE PTR 2
                JE      TM3_2
                JMP     TM3_3
TM3_0:          MOV     CS:[a0],AL
                ADD     CS:[ACNT],BYTE PTR 1
                CALL    MATU
                JMP     ORG_INT17H
TM3_1:          MOV     CS:[a1],AL
                ADD     CS:[ACNT],BYTE PTR 1
                CALL    MATU
                JMP     ORG_INT17H
TM3_2:          MOV     CS:[a2],AL
                ADD     CS:[ACNT],BYTE PTR 1

;------------透過にする量を計算
;スーパーサブか?
                CMP     CS:[SUPER],BYTE PTR 0
                JE      NORMAL
                CMP     CS:[IMANOMOJI],BYTE PTR 20H
                JB      NORMAL
                CMP     CS:[IMANOMOJI],BYTE PTR 7EH
                JA      NORMAL
                JMP     SPMOJI

;普通の文字(透過にする量はa1×3)
NORMAL          =       $
                PUSH    AX
                MOV     AL,CS:[a1]
                MOV     AH,0
                MOV     BX,3
                MUL     BX
                MOV     CS:[TOUKA_P],AX
                POP     AX
                CALL    MATU
                JMP     ORG_INT17H
;スクリプト文字(透過にする量はa1×2)
SPMOJI          =       $
                PUSH    AX
                MOV     AL,CS:[a1]
                MOV     AH,0
                MOV     BX,2
                MUL     BX
                MOV     CS:[TOUKA_P],AX
                POP     AX
                CALL    MATU
                JMP     ORG_INT17H

しかし、なぜこんな複雑な計算をドライバーの方でしないといけないのか・・・。ESCシーケンスの方で、スーパーサブスクリプトかどうかのフラグとか、なん文字送信するのかとか、それぐらい引数に含めても良かったんじゃないかと。とにかく、ESC/Pはドライバー泣かせのシーケンスだったりします。

フォントデーターは、PR201と違って上が上位ビットです。PR201のつもりで送信すると文字が8ドットごとに逆さまになるので注意してください。



イメージ印刷
<1B> * モード ドット列数 データー … … …

モードは16進数1バイトで指定します。以下のものがあります。

モード 1列あたりの
ドット数
ドット密度
00 8 60×60
01 8 120×60
02 8 120×60
03 8 240×60
04 8 80×60
06 8 90×60
20 24 60×180
21 24 120×180
26 24 90×180
27 24 180×180
28 24 360×180

ドット列数は16進数2バイトで指定しますが、リトルエンディアンなので、下位バイト・上位バイトの順です。8086アセンブラならDW、C言語ならshortと定義すれば良いのですが、COBOLや6809アセンブラ等のビッグエンディアンの言語では、上位バイトと下位バイトを反転させる必要があります。

データーは、24ドットイメージの場合、1列に対して3バイト分のデーターを用意します。ダウンロード文字の説明でも述べた通り、ESC/Pでは上位ビットが上になっているため、ドットがあればSTC、なければCLCとしてキャリーフラグをセットした後、キャリーフラグを含んで左シフトしながら3バイト分ローテーションさせて作成します。

SETL		=	$
		STC
		RCL	BYTE PTR [LDAT3],1
		RCL	BYTE PTR [LDAT2],1
		RCL	BYTE PTR [LDAT1],1
		RET
RESETL		=	$
		CLC
		RCL	BYTE PTR [LDAT3],1
		RCL	BYTE PTR [LDAT2],1
		RCL	BYTE PTR [LDAT1],1
		RET

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

バイナリバイトは、モードが20H未満なら、ドット列数x1、モードが20H以上ならドット列数x3になります。ちなみに、ドライバー内では次のように計算しています。

;-------- ESC * イメージ転送
CHK30		=	$
		CMP	CS:[KAKO3],BYTE PTR 1BH
		JNE	CHK30_1
		CMP	CS:[KAKO2],BYTE PTR "*"
		JNE	CHK30_1
		JMP	HORYU
CHK30_1		=	$
		CMP	CS:[KAKO4],BYTE PTR 1BH
		JNE	CHK30_2
		CMP	CS:[KAKO3],BYTE PTR "*"
		JNE	CHK30_2
		JMP	HORYU
CHK30_2		=	$
		CMP	CS:[KAKO5],BYTE PTR 1BH
		JNE	CHK31
		CMP	CS:[KAKO4],BYTE PTR "*"
		JNE	CHK31

		CMP	CS:[KAKO3],BYTE PTR 30
		JAE	CHK30_3
		MOV	BH,CS:[KAKO1]
		MOV	BL,CS:[KAKO2]
		ADD	BX,1
		MOV	CS:[TOUKA_P],BX
		JMP	TOUKA_MODE_IN
CHK30_3		=	$
		PUSH	AX
		MOV	AH,CS:[KAKO1]
		MOV	AL,CS:[KAKO2]
		MOV	BX,3
		MUL	BX
		ADD	AX,1
		MOV	CS:[TOUKA_P],AX
		POP	AX
		JMP	TOUKA_MODE_IN

改行ピッチ n/360インチ ☆
ESC + (1B 2B)
改行ピッチを1/360インチ単位で設定できます。パラメーターは1バイトのバイナリで指定します。(00〜FF) したがって、シフトJISの第一バイトと重なってしまう可能性もあるのですが、このコマンドができたのがプリンタードライバーを作った時期よりも後なので、当サイトで掲載しているプリンタードライバーで対応していません。申し訳ありませんが、細かい改行幅の調整は、後述のn/180インチ改行の方を使っていただけないでしょうか?

どうも、ESC/Pのドライバーはほぼ全てのコマンドが引数をバイナリで指定するため、新しいコマンドが新設される毎にドライバーもバージョンアップしないといけないのが辛いです。ちなみに、こちらにはもうMS-DOSソフトの開発環境がありませんのでこちらではバージョンアップできません。

それと、よっぽど印字位置にうるさい人でなければ、1/180インチ単位の微調整で十分だと思うんですけど、いかがなもんでしょう?

ANKアンダーライン
ESC - (1B 2D)
半角ANK文字をアンダーライン付きにします。ESC - につづいて、00か01かを指定します。01でアンダーライン設定、00でアンダーライン解除です。

改行ピッチ1/8インチ
ESC 0(1B 30)
改行ピッチは先に述べたESC+を使って、ESC + 2D(45/360)としても良いのですが、縦罫線を繋げたい場合は、このコマンドの方が短くて便利です。

改行ピッチ1/6インチ
ESC 1(1B 31)
改行ピッチを1/6インチにします。という事は、つまり電源投入時の設定に戻します。

改行ピッチ n/180インチ
ESC 3(1B 33)
改行ピッチを1/180インチ単位で設定できます。ESC 3に続いて1バイトのバイナリで指定します。こちらはちゃんとプリンタードライバーの方で透過に設定してますので、ESC 3の後に思う存分(?)シフトJISの1バイト目とかぶる値を指定できます。

;-------- ESC 3 n/180改行設定
CHK6		=	$
		CMP	CS:[KAKO3],BYTE PTR 1BH
		JNE	CHK7
		CMP	CS:[KAKO2],BYTE PTR "3"
		JNE	CHK7
		MOV	CS:[TOUKA_P],WORD PTR 1
		JMP	TOUKA_MODE_IN

イタリック指定
ESC 4(1B 34)
半角文字だけでなく全角文字もイタリックになります。ただし、グラフィック罫線キャラクターはイタリックにはなりません。また、漢字縦書き印字モードの時もイタリックにはなりません。

イタリック指定解除
ESC 5(1B 35)

文字セットのコピー
ESC :(1B 3A)
ダウンロード文字を使うモードにすると、登録されてない文字は空白になってしまいます。そこで、一部だけダウンロード文字にしたい場合は、このコマンドを使って内蔵フォントをダウンロード文字のメモリーにコピーしておきます。

ESC : に続いて、バイナリで書体番号を送信します。(00〜06)。ただし、プリンターによっては、書体が6種類も入ってないものもあり、入ってない書体番号を指定してもも存在するフォントがセットされるのではなく、このコマンド自体が無効になります。

リセット
ESC @(1B 40)
プリンターを電源投入時の状態に戻します。外字やダウンロード文字はそのままメモリーに残ります。

垂直タブ
ESC B(1B 42)
垂直タブを設定します。ESC B に続いて、垂直タブに設定したい行をバイナリで指定します。垂直タブは16個まで設定できます。パラメーターの最後に、NULL(00H)を送ります。

したがって、NULLコードが来るまでは、送信されるデーターがシフトJISコードの第一バイトとかぶる場合があり、当プリンタードライバーでは「NULLコードが来るまで透過」として判断しています。

;-------- ESC B 垂直タブ設定
CHK8		=	$
		CMP	CS:[KAKO3],BYTE PTR 1BH
		JNE	CHK9
		CMP	CS:[KAKO2],BYTE PTR "B"
		JNE	CHK9
		JMP	TOUKA_MODE2_IN

       (省略)

;-----------------------------------------------------------------------------
;		現在透過モード2(Nulが来るまで透過)
;-----------------------------------------------------------------------------
TOUKA_MODE2_IN	=	$
		MOV	CS:[TOUKA_F],BYTE PTR 2
		MOV	CS:[KAKO1],BYTE PTR 0
		MOV	CS:[KAKO2],BYTE PTR 0
		MOV	CS:[KAKO3],BYTE PTR 0
		MOV	CS:[KAKO4],BYTE PTR 0
		MOV	CS:[KAKO5],BYTE PTR 0
		MOV	CS:[KAKO6],BYTE PTR 0
TOUKA_MODE2	=	$
		CMP	AL,0
		JE	TOUKA2_1
		JMP	TOUKA2_2
TOUKA2_1	=	$
		MOV	CS:[TOUKA_F],BYTE PTR 0
TOUKA2_2	=	$
		CALL	MATU
	        JMP	ORG_INT17H

ページ長設定
ESC C(1B 43)
1ページの行数を設定します。引数はバイナリですが、設定できる値が7Fまでとなっており、シフトJISコードの第一バイトとかぶる心配はありません。

ページ長設定(インチ単位)
ESC C NULL (1B 43 00)
1ページの長さをインチ単位で設定します。ESC C NULLに続いてページ長をバイナリで指定します。しかし、設定できる値は16Hまでとなており、シフトJISコードの第一バイトとかぶる心配はありません。

設定できる値が80H未満のコマンドでは、ドライバー内で透過処理を行っておりません。どうか、範囲を越えた値を指定しないようにお願いします。

垂直タブ
ESC D(1B 44)
垂直タブを設定します。ESC Dに続いてバイナリで垂直タブをキャラクター単位で設定します。垂直タブは最大で32箇所まで設定でき、パラメーターの最後にNULLを送信します。ドライバー内ではNULLが来るまでは透過処理を行っています。

強調文字
ESC E(1B 45)
強調文字の指定が解除されるまでの間は太字になります。

強調文字解除
ESC F(1B 46)

二重印字
ESC G(1B 47)
文字を二重印字します。しかし、ドットプリンター以外ではあまり意味がないかと思われます。レーザープリンターでは二重印字のコマンドを受信すると強調印字と同じ動作をするものもあります。

二重印字解除
ESC H(1B 48)

順方向改行
ESC J(1B 4A)
1/180インチ単位で改行幅を設定できます。ESC Jに続いて1バイトで改行幅を指定します。このコマンドでは、1回改行するだけで、改行幅が永続的に変わったりはしません。

文字間ピッチ12CPI
ESC M(1B 4D)
半角の文字間ピッチを12CPIにします。つまり、半角のドットピッチを15にします。全角の文字間ピッチはデフォルトで13.3CPIですが、全角:半角を2:1にするためには、全角のドットピッチを30ドットピッチにする必要があります。そのため、当ドライバーでは12CPIモードを指定すると全角文字の左右に3ドットずつ余白を追加しています。



ミシン目スキップ
ESC N(1B 4E)
用紙の印字位置がページ長を越えた場合に、何行紙送りをするかを指定します。ESC Nに続いて行数をバイナリで指定します。また、改ページ(0CH)を受信すると、用紙はページ長コマンドの設定に従って一番下+ミシン目スキップの分だけ送られます。

しかし、このコマンドはドットプリンターで、連続用紙(ストックフォーム)を使っている場合以外は意味がないと思われます。

ミシン目スキップ解除
ESC O(1B 4F)

文字間ピッチ10CPI
ESC P(1B 50)
半角の文字間ピッチを10CPIにします。つまり、18ドットピッチにします。全角はデフォルトで13.3CPIですが、全角:半角のピッチを2:1にするためには全角のドットピッチを36ドットにする必要があり、左右余白の合計を12ドットにする必要があります。

当ドライバーでは10CPIモードを指定すると、全角文字の左右に6ドットずつ余白を追加します。



右マージンの設定
ESC Q(1B 51)
右マージンの量をキャラクター単位で設定します。ただし、右端からの余白の量ではなく、左端からの印字できる範囲を指定します。ここで「左端」とは、左マージンを含まない値です。

ESC Qに続いて、左端から印字可能な幅をバイナリで指定します。ここで設定した値は、半角文字間ピッチの設定の影響を受けます。ただし、プロポーショナルピッチが指定されている時は、10CPIとして計算されます。

国セットの選択
ESC R(1B 52)
半角文字のうち、一部に国ごとに使う文字が異なる部分があります。具体的には、半角の¥やカタカナの部分が日本以外の国では別の文字になります。ESC Rにづついて以下のいずれかを送信します。

00 ・・・ アメリカ
01 ・・・ フランス
02 ・・・ ドイツ
03 ・・・ イギリス
04 ・・・ デンマーク
05 ・・・ スウェーデン
06 ・・・ イタリア
07 ・・・ スペイン
08 ・・・ 日本
09 ・・・ ノルウェー
0A ・・・ デンマーク その2
0B ・・・ スペイン その2
0C ・・・ ラテンアメリカ
0D ・・・ 韓国
40 ・・・ リーガル

ただし、プリンターによっては入ってないものもあり、その場合指定は無視されます。

スーパースクリプト、サブスクリプト文字の指定
ESC S(1B 53)
ESC Sに続いてスーパースクリプトか、サブスクリプトかを指定します。00でスーパースクリプト、01でサブスクリプトになります。スーパースクリプトは通常文字の上端に合わせて印字されます。また、サブスクリプトは通常文字の下端に合わせて印字されます。

スーパースクリプト、サブスクリプト文字の解除
ESC T(1B 54)

横2倍角
ESC W(1B 57)
ESC Wに続いて、01で横2倍角になります。また、00で横2倍角解除になります。

相対位置移動
ESC ¥(1B 5C)
印字ヘッドを現在の位置からの相対位置に移動します。ESC ¥に続いて符号付き2バイトのリトルエンディアンで指定します。なので、ビッグエンディアンの言語を使っている場合は変換する必要があります。

プラスは左、マイナスは右への移動になります。指定できる範囲は-2448〜+2447までです。つまり、F670H〜098FHまでです。左へ移動する際に、アンダーラインモードになっている時はアンダーラインも引かれます。

文字間ピッチ15CPI
ESC g(1B 67)
半角の文字間ピッチを15CPIにします。

半角フォントの指定
ESC k(1B 6B)
半角フォントを指定します。ESC kに続いて以下を送信します。

00 ・・・ ローマン
01 ・・・ サンセリフ
02 ・・・ クーリエ
03 ・・・ プレステージ
04 ・・・ スクリプト
05 ・・・ OCR-B
06 ・・・ OCR-A

ただし、プリンターによっては全てのフォントが入っていない場合があり、その場合入ってないフォントが指定された時は無視されます。

左マージン設定
ESC I(1B 6C)
左マージンを設定します。ESC Iにつづいて左マージンの量をキャラクター単位でバイナリで指定します。

プロポーショナルピッチ指定、解除
ESC p(1B 70)
ESC p に続いて01で指定、00で解除されます。

文字修飾
ESC q(1B 71)
文字修飾を指定します。ESC qにづついて以下から選択します。

00 ・・・ 通常文字(デフォルト)
01 ・・・ 袋文字
02 ・・・ 影文字
03 ・・・ 袋+影文字

色指定
ESC r(1B 72)
文字の色を指定します。FM-PR201やPC-PR201のコード体系とは異なり、CYMKで指定するのではなく、色そのものを指定します。モノクロプリンターでは無理されます。

00 ・・・ 黒
01 ・・・ マゼンダ
02 ・・・ シアン
03 ・・・ 青紫
04 ・・・ 黄色
05 ・・・ 赤
06 ・・・ 緑

ただし、当サイトで掲載しているカラーハードコピードライバーでは、CYMを重ねて印字しています。

SET_YELLOW	DB	1BH,72H,04H
SET_MAGEBTA	DB	1BH,72H,01H
SET_CYAN	DB	1BH,72H,02H

カナ/グラフィックキャラクターの選択
ESC t(1B 74)
半角文字のカナの部分をグラフィックキャラクターにするかどうかの選択をします。

00 ・・・ グラフィックキャラクター
03 ・・・ カナ(デフォルト)

半角縦倍角
ESC w(1B 77)
半角文字を縦に2倍拡大します。ESC wに続いて01で縦2倍、00で解除になります。

半角高品位文字
ESC x(1B 78)
半角文字を高品位文字にするか、ドラフト文字にするかを選択します。ESC xに続いて01で高品位文字、00でドラフト文字になります。デフォルトは高品位文字です。

ドラフト文字にするとドットが粗くなって文字が薄くなるかわりに高速で印字されます。といっても、ドットプリンター以外ではあんまり意味はないものと思われます。

FSシーケンス

FS に続いてコマンド、引数を送信します。

半角漢字オン
FS SI(1C 0F)
漢字(マルチバイト文字)が、半角文字の大きさ/文字間ピッチで印字されます。

半角漢字オフ
FS DC2(1C 12)

漢字印字モードの一括指定
FS !(1C 21)
漢字(マルチバイト文字)の文字修飾等を一括で指定します。FS !に続いて1バイトで指定します。

ビット
7 ・・・ 1:アンダーライン 0:解除
6 ・・・ リザーブ
5 ・・・ 1:上付き 0:下付き
4 ・・・ 1:上付きor下つき開始 0:解除
3 ・・・ 1:横2倍 0:解除
2 ・・・ 1:縦2倍 0:解除
1 ・・・ 1:半角漢字 0:解除
0 ・・・ 1:縦書き 0:横書き

漢字オン
FS &(1C 26)
漢字モードになります。以後に受信する20H以上のコードはJISコードとみなされ、2バイトで1つのマルチバイト文字として印字されます。

漢字アンダーライン解除
FS -(1C 2D)
漢字のアンダーラインを解除します。

漢字オフ
FS .(1C 2E)
漢字モードを解除します。以後に受信する20H以上のコードは1バイト文字とみなされます。

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

FS 2(1C 32) に続いて、文字コード、パターンデーターという順に送信します。外字として登録できるコードは7721〜777Eです。ただし、ATOKでは外字エリアは7F21からなので、ATOKの外字をプリンターに登録するのであれば、ATOKの外字コードから800Hを引く必要があります。また、文字コードはビッグエンディアンで指定するため、8086アセンブラでMOVする前に上位バイトと下位バイトを逆転させておく必要があります。

外字データーは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>を受信するまで)は同一コードで異なるパターンの外字はないものとして、改行コードが来るまでは同一コードでの外字登録はしないようにしています。

といいますか、JFGAIJ.UFOから登録するのであれば、同一文書内で同じコードに別の文字パターンを当てはめるような事はしないと思われます。

縦書き漢字モード
FS J(1C 4A)
漢字(マルチバイト文字)を縦書きで印字します。PC PR-201とは異なり、このコマンドが「漢字オン」を兼ねているわけではありません。あくまでも漢字ONの状態の時に縦書きになります。

縦書き漢字モード解除
FS K(1C 48)

組み込み文字指定
FS D(1C 44)
漢字ONモードで、縦書き漢字モードの時に、半角漢字を2文字セットで1文字として印字します。FS Dに続いて左側の半角漢字、右側の半角漢字をそれぞれ2バイトずつ送信します。



漢字文字間ピッチ
FS S(1C 53)
漢字の文字間ピッチを調整します。といっても、24ドットピッチよりも詰める事はできず、24ドットピッチの他に左右になんドット分の余白を足すかを指定します。FS Sに続いて左スペース、右スペースをそれぞれ1バイトのバイナリで指定します。電源投入時は、左0ドット、右3ドット(27ドットピッチ)になっています。

半角漢字文字間ピッチ
FS T(1C 54)
半角漢字に対して文字間ピッチを調整する事以外は、FS Sと同じです。電源投入時は左0ドット、右2ドットになってします。

漢字4倍角
FS W(1C 57)
漢字(マルチバイト文字)が縦横2倍になります。FS Wに続いて01で指定、00で解除になります。

漢字フォント
FS k(1C 68)
漢字のフォントを設定します。FS kに続いて00で明朝体、01でゴシック体になります。デフォルトは明朝体です。

上付き/下付き文字
FS r(1C 72)
漢字(マルチバイト文字)を1/4に縮小して、上付きまたは下付きで印字します。FS rに続いて00で上付き、01で下付きになります。なお、このコマンドには専用の「解除」命令がありませんで、半角漢字解除(1C 12)で解除します。

文字間ピッチの調整

半角スペース量補正オン
FS U(1C 55)

半角スペース量補正オフ
FS V(1C 56)

ESC/Pでは13.3CPIで印字するためには、半角文字1文字につき13.5ドットピッチで印字する必要があります。しかしながら、13.5ドットピッチという指定はありません。

そのため、13.3CPIで印字するためには、半角の文字間ピッチを15CPI(12ドットピッチ)、半角文字間スペース1にした後、半角スペース量補正オンを送信して、2文字に1回文字間に1ドット付加するように設定します。

ESC g ・・・ 半角を15CPIにする
ESC sp 01 ・・・文字間に1ドット付加する。
FS U ・・・ 半角スペース補正オン

これにより、半角の文字は1文字につき13ドットピッチで、2文字に1回1ドット足すようになります。


全角文字は電源投入時にデフォルトで13.3CPI(27ドットピッチ)ですが、他の(行儀の悪い)アプリがプリンターの設定をデフォルトに戻さないままにしてしまう可能性があるので、13.3CPIで印字するアプルを作るのであれば、あらかじめFS S コマンドを使って全角の文字間を左に0、右に3と指定した方が良いでしょう。(でないと、使う前にいったんプリンターの電源を入れ直さないといけなくなるので)

FS S 00 03 ・・・ 全角の左余白を0、右余白を3ドットにする。(デフォルトの設定)

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


参考文献
Microline5320SE 取扱説明書 OKI
VP-800取扱説明書 EPSON
BIJ1350 ESC/Pユーザーズガイド Canon
スポンサーリンク