/*
 *		Routine to use scalable/downloaded font of LIPS3 (dviprt)
 *								30 June	1992, written by SHIMA
 *      modifed for ESC/Page by H.Tomiie, 18 August 1992
 *      slightly modifed by OkI 14 Nov. 1992
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#define _DEF_DOS_H_
#include "dd.h"
#include "prtout.h"
#include "err.h"
#include "prtctl.h"
#include "escpage.h"
/* escpage.c local */
static void pr_attr(int flag);
static int KetaSuu(PIXEL num);

/* p_out.c function */
static void escpage_init(void);
static void escpage_init2(int ff_rotate, int f_copy);
static void escpage_end();
static void set_escpage_font(FONT_INFO *fontc, KFONT *kf, int fg, int weight, int face);
static void move_cap(PIXEL v, PIXEL h);
static void move_homepoint(PIXEL v, PIXEL h);
static void pre_put_char(FONT_INFO *, PREAMBLE *, uint *, PIXEL *, PIXEL *);
static void put_jis_font(uint code);
static void put_dl_font(uint code);
static long get_dlhsize(int NumOfFonts);
static void pre_download(FONT_INFO *, DL_INFO *, int, int);
static void download_rastor(FONT_INFO *, DL_INFO *, uint, int);
static void post_download(FONT_INFO *dfont, DL_INFO *dl);
static void escpage_drawbox(PIXEL hs, PIXEL vs, PIXEL width, PIXEL height, int gray);
static void escpage_font_rotate(int);	/* フォント回転 (Deg.) */
static void tate_yoko(int);				/* 縦・横書き漢字フォント切換え */

static int j_lbp_font = -1;	/* current font in G1 */
static int HomePointBase;
static int MarginMaxPoint;

extern BOOL f_rotate; /* Landscape?  */
extern long ptex_dpi_adj;
extern int on_edge_font;	/* 紙面からぎりぎりはみ出したjis fontを示す*/
extern PIXEL vert_divide;

/* externals from prtinit.c */
extern char *youshi;	/* 用紙指定用コマンド文字列 */
#ifndef NO_NTTRPL
extern BOOL ntt_subst;
#endif

#ifndef NNSZ
extern int length_to_dot(char *, int *, int);
#endif


#ifdef FDOWN
extern int maxdwidth;	/* download font width limit */
extern int maxdheight;	/* download font height limit */
extern int maxdfont;	/* num of kinds of download limit*/
#endif

#ifdef	JDWN
extern int calc_realsize(PREAMBLE *, struct REAL_SIZE *);
extern int f_gaiji;
#endif

/* escpage_init で p_out の変数のデフォルトをセットする */
extern int weight_org;
extern int k_base_l;
extern int k_base_d;
extern int k_scale_l;
extern int lbp_orig_dpi;	/* ESCPAGE本来の dpi 値 */
#define	str_exp	tmp_buf
/* extern char str_exp[];	*/ /* 出力文字列作業用 */

/* externals from pret.c */
extern int g_font;

PREAMBLE *get_font(uint *, FONT_INFO *);

/* p_out.c routine call */
void pr_putnc(char *, int);
void pr_puts(char *);
void pr_putsn(char *, int);
void pr_putc(char);
void pr_int2(uint num);
void pr_int2n(uint num, int count);
void pr_int4(ulong num);

int AtoI(char **);

static struct LIPS_LFONT escpage_data[] =
{
	{"Mincho.J83", 10},
	{"Gothic.J83", 9},
	{"User", 10}
};
LBP_FUNC escpage_func =
{
	escpage_init,	/* 初期化ルーチン */
	escpage_init2,	/* 初期化ルーチンその2*/
	escpage_end,	/* 終了処理ルーチン */
	set_escpage_font,	/* 内蔵漢字フォントの設定 */
	move_cap,	/* CAPの絶対移動 */
	move_homepoint,	/* 描画原点の移動 */
	pre_put_char,	/* put_char 前処理 */
	put_jis_font,	/* put_char:jis漢字出力 */
	put_dl_font,	/* put_char:downloadフォント出力*/
	get_dlhsize,	/* dl data の ヘッダサイズ */
	pre_download,	/* download の前処理 */
	download_rastor,	/* ラスタイメージdownload */
	post_download,	/* download 後処理 */
	escpage_drawbox,	/* box 描画 -box オプション用 */
	escpage_font_rotate,	/* キャラクタを回転するコマンド */
	tate_yoko,	/* 縦書き・横書きフォント選択 */
	escpage_data	/* lips内蔵フォントデータ */
};

/* フラグに示されているモードにする*/
static void pr_attr(int flag)
{
	if (flag & F_GOTH)
		pr_puts(BOLD);
	if (flag & F_GGOTH)
		pr_puts(BBOLD);
}

static void escpage_init(void)
{
	char buf[256];
	char *s;
	int paper, yoko, tate, houkou, kyuushi, bin, c, landscape;

	if (lbp_orig_dpi == 0)
		lbp_orig_dpi = LBP_ORIG_DPI;	/* LIPS3本来のdpi値300 */
	if (k_base_l >= 10000) {
		k_base_l = (lbp_orig_dpi != 240) ? K_BASE_L300 : K_BASE_L240;
	}
	if (k_scale_l == 10000)
		k_scale_l = K_SCALE_L;

	k_base_d = K_BASE_D;
	/*	weight_org=WEIGHT; */

#ifdef FDOWN
	maxdwidth = MAXDWIDTH;		/* maximal width of download font cell */
	maxdheight = MAXDHEIGHT;	/* maximal height of download font cell */
	maxdfont = MAXDFONT;		/* maximal number of download font sets */
#ifdef JDWN
	if (f_gaiji) return;
#endif
#endif

	sprintf(buf
			,"\x1d" "rhE"
			"\x1d" "0;%smuE"
			"\x1d" "0;%u;%udrE"
			"\x1d" "1;%u;%udrE"
			"\x1d" "2;%u;%udrE"
			/* "\x1d" "8;0lpP" */
			"\x1d" "%u;0lpP"
			"\x1d" "1abP"
			"\x1d" "0;0;1clfP"
			"\x1d" "1pmP"
			"\x1d" "0;0pP"
			"\x1d" "511iaF"
			"\x1d" "511ifF"
			"\x1d" "1mmE"
			,(lbp_orig_dpi == 240) ? "0.3" : "0.24"
			,lbp_orig_dpi, lbp_orig_dpi
			,lbp_orig_dpi, lbp_orig_dpi
			,lbp_orig_dpi, lbp_orig_dpi
			,vert_divide
		);

	pr_puts(buf);

	/*************************************************************
	-y 指定による用紙指定
*/
	s = youshi;
init:
	paper = kyuushi = bin = 0;
	houkou = 0;
	landscape = f_rotate;
	while (*s) {
		switch (toupper(*(s++))) {
		  case '/':
			  goto init;
		  case 'A':
			  if ((c = *(s++)) == '5')
				  paper = 15;
			  else if (c == '3')
				  paper = 13;
			  else
				  paper = 14;
			  goto skip_num;
		  case 'B':
			  if (*(s++) == '4')
				  paper = 24;
			  else
				  paper = 25;
			  goto skip_num;
		  case 'H':
			  paper = 38;
skip_num:
		  	  landscape=f_rotate;
			  while (isdigit(*s))
				  s++;
			  houkou = 1;
			  break;
		  case 'T':
		  	  landscape=f_rotate;
			  paper = AtoI(&s);
			  houkou = 1;
			  break;
		  case 'F':
		  	  landscape=f_rotate;
			  paper = -1;
#ifdef	NNSZ
			  tate = 0;
			  yoko = AtoI(&s);
			  if (*s == ':' || *s == ';') {
				  s++;
				  tate = AtoI(&s);
			  }
#else
			  s += length_to_dot(s, &yoko, 0);
			  if (*s == ':' || *s == ';'){
				  s++;
				  s += length_to_dot(s, &tate, 1);
			  }
#endif
			  else {
				  tate = yoko;
			  }
			  houkou = 1;
			  break;
		  case 'L':
			  landscape=TRUE;
			  goto skip1;
		  case 'P':
		  	  landscape=FALSE;
skip1:
			  houkou = 1;
			  kyuushi = AtoI(&s);
			  if (*s == ':' || *s == ';') {
				  s++;
				  bin = AtoI(&s);
			  }
			  break;
		}
	}

	if (paper != 0) {
		if (paper != -1)
			sprintf(buf, "\x1d" "%upsE", paper);
		else
			sprintf(buf, "\x1d" "-1;%u;%upsE", yoko, tate);
		pr_puts(buf);
	}
	if (houkou != 0){
		pr_putsn("\x1d" "%upoE", (landscape==TRUE)?1:0);
	}
	if (bin == 0)
		bin = 1;
	if (kyuushi != 0 && lbp_orig_dpi != 240) {
		pr_putsn("\x1d" "%u;", kyuushi);
		pr_putsn("%uiuE", bin);
	}
	/*************************************************************
	pTeX の縦書き時の印字位置補正計算用
*/
	ptex_dpi_adj = (long)lbp_orig_dpi *100L;

	/*************************************************************
	ホームポイントの物理座標
		用紙の端から0.2インチの位置
		ライト、ボトムマージンを設定可能値最大にする
*/
	HomePointBase = (lbp_orig_dpi * 2) / 10;
	MarginMaxPoint = 50 * lbp_orig_dpi;	/* ESC/Page リファレントマニュアル第２版より */

	move_homepoint(0, 0);

}

static void escpage_end()
{
}

/* 内蔵フォントを割り付ける */
static void set_escpage_font(FONT_INFO *fontc, KFONT *kf, int fg, int weight, int face)
{

	int width, height;

	ENTER("set_escpage_font");

	/* アウトラインでは、２ドット小さい物を使う */
	if (fg & F_OUTLINE)
		kf->width -= 2;
	g_font = (fontc->f_goth & (F_ATTR | F_LBP));	/*内蔵フォントで使う属性を得る*/

	if ( fontc->f_goth & F_TATE ){
		width = kf->height;
		height = kf->width;
	}
	else{
		width = kf->width;
		height = kf->height;
	}
	pr_putsn(CHR_PITCH, height);	/* 高さの設定 select point */
	pr_putsn(CHR_SIZE, width);	/* 幅の設定   select point */
	pr_putsn(FACE, face);		/* フォント番号の設定  select face */
/*
/#ifndef NOTATEGAKI
	if (tategaki)
		pr_puts(TATEGAKI);
	else
#endif
*/
		pr_puts(YOKO);			/* 書体の設定 */
	if (fg & F_GOTH)
		pr_puts(BOLD);
	else if (fg & F_GGOTH)
		pr_puts(BBOLD);
	else
		pr_puts(NO_BOLD);
#ifndef NO_NTTRPL
	if (ntt_subst && (fontc->code_offset >= 0))
		pr_putsn(ASSIGN_G1, fontc->family_code);
	else
#endif
	pr_putsn(ASSIGN_G1, fontc->font_code);
	j_lbp_font = -1;
}

static int KetaSuu(PIXEL num)
{
	int Keta;

	if (num >= 0)
		Keta = 0;
	else {
		Keta = 1;
		num = (-num);
	}
	if (num < 10)
		return Keta + 1;
	else if (num < 100)
		return Keta + 2;
	else if (num < 1000)
		return Keta + 3;
	else if (num < 10000)
		return Keta + 4;
	return Keta + 5;
}

static void move_cap(PIXEL v, PIXEL h)
{
	static PIXEL last_v, last_h;
	PIXEL sub;

	if (v == -1 && !on_edge_font) {				/* reset last CAP position */
		last_v = last_h = -1;
		return;
	}
	if (last_v != v) {
		sub = v - last_v;
		if (KetaSuu(v) <= KetaSuu(sub) || last_v == -1)
			pr_putsn(SET_Y, v);
		else
			pr_putsn(MOVE_BELOW, sub);
		last_v = v;
	}
	if (last_h != h) {
		sub = h - last_h;
		if (KetaSuu(h) <= KetaSuu(sub) || last_h == -1)
			pr_putsn(SET_X, h);
		else
			pr_putsn(MOVE_RIGHT, sub);
		last_h = h;
	}
}

static void move_homepoint(PIXEL v, PIXEL h)
{
	pr_putsn("\x1d" "%u;", h + HomePointBase);	/* 論理原点の設定 */
	pr_putsn("%uloE", v + HomePointBase);
	pr_putsn("\x1d" "0tmE" "\x1d" "%ubmE", MarginMaxPoint);
	pr_putsn("\x1d" "0lmE" "\x1d" "%urmE", MarginMaxPoint);
	move_cap(-1, -1);
}

#define	PUSH_POS	pr_puts("\x1d" "1ppP");
#define	POP_POS		pr_puts("\x1d" "2ppP");

void MoveWrite(uint code, PIXEL h, PIXEL v)
{
	if (h != 0)
		pr_putsn("\x1d" "%dH", h);
	if (v != 9)
		pr_putsn("\x1d" "%dV", v);
	pr_int2(code);				/* output JIS code */
}

static int ass_f;
static int knjwidth;
static int last_d = -1;
static int font_angle = 0;
static int last_angle = 0;
static int jfont_mode = 0;

static void pre_put_char(FONT_INFO *font, PREAMBLE *pxl, uint *code, PIXEL *h, PIXEL *v)
{
#ifndef NO_NTTRPL
	if (ntt_subst && (font->code_offset >= 0)) ass_f = font->family_code;
	else
#endif
	ass_f = font->font_code;
	knjwidth = pxl->width;
	return;
}

static void escpage_font_rotate(int angle)
{
	font_angle = angle;
}

static void tate_yoko(int mode)
{
	/* mode : 0 = 横書きフォント 1 = 縦書きフォント */
	jfont_mode = mode;
}

static void put_jis_font(uint code)
{

	static int last_jfont_mode = 0;

	/* ＯｋＩによる適当なコーディングです．
	 * 無駄な部分がかなりあると思われるので，チューニングが必要です． */
	if (ass_f != j_lbp_font) {
		/* change G1 font */
		pr_putsn(CHANGE_G1, j_lbp_font = ass_f);
		goto label1; /* フォントタイプが変われば角度を再設定 */
	}
	if (last_angle != font_angle){
		label1:
		pr_putsn(KAITEN, last_angle = font_angle);
		goto label2; /* フォントの角度を設定したときは必ず縦横書きも再設定 */
	}

	if (last_jfont_mode != jfont_mode){
		label2:
		pr_puts( ((last_jfont_mode = jfont_mode) == 0)? YOKO : TATE);
	}

	if ((g_font & (F_SHADOW | F_OUTLINE)) == (F_SHADOW | F_OUTLINE)) {
		int Kage;

		PUSH_POS;
		MoveWrite(code, 0, -1);
		MoveWrite(code, 1, -1);
		MoveWrite(code, 1, 1);
		MoveWrite(code, -1, 1);
		MoveWrite(code, 0, 1);
		for (Kage = knjwidth >> 4; Kage > 0; Kage--)
			MoveWrite(code, 1, 1);	/* 横影 1,0 斜影 1,1 */
		POP_POS;
	}
	else if (g_font & F_SHADOW) {
		int Kage;

		PUSH_POS;
		for (Kage = knjwidth >> 4; Kage > 0; Kage--)
			MoveWrite(code, 1, 1);	/* 横影 1,0 斜影 1,1 */
		POP_POS;
	}
	else if (g_font & F_OUTLINE) {
		PUSH_POS;
		MoveWrite(code, 0, -1);
		MoveWrite(code, 1, -1);
		MoveWrite(code, 1, 1);
		MoveWrite(code, -1, 1);
		POP_POS;
	}
	if (g_font & (F_SHADOW | F_OUTLINE | F_FILL)) {
		if (g_font & F_FILL) {
			pr_puts("\x1d" "1tsE" "\x1d" "1;0;20spE" "\x1d" "1owE");
		}
		else {
			pr_puts("\x1d" "1tsE" "\x1d" "1;0;0spE" "\x1d" "1owE");
		}
		if (g_font & F_OUTLINE) {
			PUSH_POS;
			MoveWrite(code, 1, -1);
			POP_POS;
		}
		else
			pr_int2(code);		/* output JIS code */
		pr_puts("\x1d" "0tsE");
	}
	else {
		if (g_font & F_OUTLINE) {
			PUSH_POS;
			MoveWrite(code, 1, -1);
			POP_POS;
		}
		else
			pr_int2(code);		/* output JIS code */
	}
}

/*　ESC/Page では code 128 以上の文字もダウンロードできるが、ソースの修正を
　少なくするために、128 文字単位でダウンする。
　　LP7000 がコントロールキャラクタのコードを印字出来ないので、文字コードを
　シフトする。（128単位でダウンロードしていたので可能である）
*/
/* ESC/Pagfe メモリー節約のつもりでギリギリに割付る */
#define	SHIFT_ASSIGN 0x100
/* LP7000 がコントロールキャラを印刷できないのでシフトする */
#define	SHIFT_CHAR 0x20

static void put_dl_font(uint code)
{
	if (code & 0x80) {
		ass_f += SHIFT_ASSIGN;
	}
	if (ass_f != j_lbp_font) {	/* change G0 font */
		pr_putsn(CHANGE_G1, j_lbp_font = ass_f);
		goto label3;
	}

	if (last_angle != font_angle){
		label3:
		pr_putsn(KAITEN, last_angle = font_angle);
	}

	pr_putc((code & 0x7f) + SHIFT_CHAR);	/* output ASC code */
}

static long get_dlhsize(int NumOfFonts)
{
	return (long)NumOfFonts *D_CHAR + D_HEAD;
}

static void pre_download(FONT_INFO *dfont, DL_INFO *dl, int num_dfont, int flag)
{
	if (flag)
		dl->assign_num += SHIFT_ASSIGN;

	pr_putsn("\x1d" "134;%udh{F", dl->assign_num);	/*}*/
	/* assign a number to FONT */
	pr_int2(2);					/* 　ダウンロードフォーマット */
	pr_int2(0x86);				/* 　データ長 */
	pr_int2(USER_SYMBOLBASE + dl->assign_num);	/* ＊シンボルセット */
	pr_int2(1);					/* 　文字スペーシング */
	pr_int4(0x1000000L);		/* 　文字幅 */
	pr_int4((long)(dl->maxheight));	/* ＊文字高さ */
	pr_int2(USER_TYPEFACEBASE + dl->assign_num);	/* 　書体 */
	pr_int2n(0, 3);				/* 　線幅 */
								/* 　回転 */
								/* 　傾き */
	pr_int2(dl->maxcharcode + SHIFT_CHAR);	/* ＊最大キュラクターコード */
	pr_int2(dl->mincharcode + SHIFT_CHAR);	/* ＊最小キュラクターコード */
	pr_int2n(0, 6);				/* 　アンダーラインオフセット */
								/* 　アンダーライン線幅 */
								/* 　オーバーラインオフセット */
								/* 　オーバーライン線幅 */
								/* 　ストライクアウトオフセット */
								/* 　ストライクアウト線幅 */
	pr_int2(dl->maxwidth);		/* ＊キャラクタセル幅 */
	pr_int2(dl->maxheight);		/* ＊キャラクタセル高 */
	pr_int2(0);					/* 　キャラクタセル左オフセット */
	pr_int2(dl->maxheight);		/* ＊キャラクタセルアセンダ */
	pr_int4((long)(dl->maxwidth));	/* ＊固定ピッチ幅 */
	pr_putsc(dfont->name, 54);	/* ＊フォント名 */
	pr_putsc("TexFonts", 28);	/* ＊シンボルセット名 */
	pr_putsn("\035%udcF", dl->assign_num);	/* select download font for later use*/
}

#if 0
/* フォントのビットイメージをそのままダウンロード */
static void download_rastor(FONT_INFO *dfont, DL_INFO *dl, uint code, int flag)
{
	PREAMBLE *preamble;
	int bytesize;
	uint tmp;
	BUFFER *pat;

	tmp = flag + code;
	preamble = get_font(&tmp, dfont);
	bytesize = preamble->byte_width * preamble->height;
	sprintf(str_exp, "\x1d" "%udcF" "\x1d" "%u;%usc{F"	/* } */
			,dl->assign_num, 16 + bytesize, (code & 0x7f) + SHIFT_CHAR);
	pr_puts(str_exp);
	pr_putc(0x1);				/* 　フォーマット */
	pr_putc(0x10);				/* 　データディレクトリ長 */
	pr_int2(0);					/* 　キャラクターコード */
	pr_int2(preamble->width);	/* ＊ビットマップ幅 */
	pr_int2(preamble->height);	/* ＊ビットマップ高 */
	pr_int2(0);					/* 　ビットマップ左オフセット */
	pr_int2(preamble->height);	/* ＊ビットマップアセンダ */
	pr_int4((long)preamble->width);	/* ＊文字幅 */
	pat = preamble->raster;
	while (bytesize--)
		pr_putc(*pat++);
}
#else
/* フォントの余白を削ってダウンロード */
static void download_rastor(FONT_INFO *dfont, DL_INFO *dl, uint code, int flag)
{
	PREAMBLE *preamble;
	uint tmp;
	BUFFER *pat;
	BUFFER *pat0;
	struct REAL_SIZE size;
	int width, height, bit_off, bit_get, i;

	tmp = flag + code;
	preamble = get_font(&tmp, dfont);
	calc_realsize(preamble, &size);

	width = size.right - size.left;
	height = size.bottom - size.top;

	sprintf(str_exp, "\x1d" "%udcF" "\x1d" "%u;%usc{F"
			, dl->assign_num, 16 + (((width + 7)>>3) * height)
			, (code & 0x7f) + SHIFT_CHAR);
	pr_puts(str_exp);
	pr_putc(0x1);							/* 　フォーマット */
	pr_putc(0x10);							/* 　データディレクトリ長 */
	pr_int2(0);								/* 　キャラクターコード */
	pr_int2(width);							/* ＊ビットマップ幅 */
	pr_int2(height);						/* ＊ビットマップ高 */
	pr_int2(size.left);						/* ＊ビットマップ左オフセット */
	pr_int2(preamble->height - size.top);	/*＊ビットマップアセンダ */
	pr_int4((long)preamble->width);			/* ＊文字幅 */

	bit_off = size.left & 7;
	bit_get = 8 - bit_off;
	pat0 = preamble->raster + size.top*preamble->byte_width + size.left/8;
	while (height--){
		pat = pat0;
		for(i = width; i > 0; i -= 8){
			tmp = *pat++;
			if (bit_off){
				tmp <<= bit_off;
				if(i > bit_get) tmp |= ((uchar)*pat >> bit_get);
			}
			pr_putc(tmp & 0xff);
		}
		pat0 += preamble->byte_width;
	}
}
#endif

static void post_download(FONT_INFO *dfont, DL_INFO *dl)
{

	pr_putsn("\x1d" "%u;0ssF", USER_SYMBOLBASE + dl->assign_num);
	/*symbol set number*/
	pr_puts(NO_BOLD);			/* stroke weight */
	pr_putsn(KAITEN, 0);		/* rotation */
	pr_putsn(CHR_PITCH, dl->maxwidth);	/* character width */
	pr_putsn(CHR_SIZE, dl->maxheight);	/* character hight */
	pr_putsn("\x1d" "%utfF", USER_TYPEFACEBASE + dl->assign_num);
	/*style set */

	pr_putsn(ASSIGN_G1, dl->assign_num);

}

static void escpage_init2(int ff_rotate, int f_copy)
{
	if (ff_rotate) {
		pr_puts(ROTATE);
	}
	if (f_copy)
		pr_putsn(COPYS, f_copy);
}

static int graytab[] =
{0,	   /* 真っ白？（使っていない） */
 20,   /* 薄いグレー(20%)			*/
 40,   /* グレー(40%)				*/
 100,  /* 真っ黒？（使っていない） */
};

static void escpage_drawbox(PIXEL vs, PIXEL hs, PIXEL height, PIXEL width, int gray)
{
	int graylevel, ve, he;

#define SWAP(A,B)	{int tmp;tmp = A;A = B;B = tmp;}

	graylevel = graytab[gray];
	switch(font_angle){
	case   0:
		vs += (1 - height);
		break;
	case 270:
		SWAP(height,width);
		break;
#ifndef NOTPIC_EXTENSION
	case 90:
		SWAP(height,width);
		vs += (1 - height);
		hs += (1 - width);
		break;
	case 180:
		hs += (1 - width);
		break;
	default:
		{
			double angle;
			int sh,ch,sw,cw;

			angle = (double)font_angle * M_PI / 180.0;
			sh = (int)(sin(angle)*height);
			ch = (int)(cos(angle)*height);
			sw = (int)(sin(angle)*width);
			cw = (int)(cos(angle)*width);

			pr_puts("\x1d" "1tsE");

			/*  図形描画モード選択 */
			pr_puts("\x1d" "1dmG");
			/* スクリーンパターンの選択*/
			pr_putsn("\x1d" "0;0;%uspE", graylevel);
			/* 多角形描画 */
			pr_putsn("\x1d" "1;4;%u;",  hs);
			pr_putsn("%u;",				vs);
			pr_putsn("%u;",				hs - sh );
			pr_putsn("%u;",				vs - ch);
			pr_putsn("%u;",				hs + cw - sh);
			pr_putsn("%u;",				vs - sw - ch);
			pr_putsn("%u;",				hs + cw);
			pr_putsn("%upG",			vs - sw);
			pr_puts("\x1d" "0tsE");

		/*  図形描画モード選択 */
			pr_puts("\x1d" "0dmG");
			/* 線種選択 */
			pr_puts("\x1d" "0;0lpG");
			/* 多角形描画 */
			pr_putsn("\x1d" "1;4;%u;",	hs);
			pr_putsn("%u;",				vs);
			pr_putsn("%u;",				hs - sh );
			pr_putsn("%u;",				vs - ch);
			pr_putsn("%u;",				hs + cw - sh);
			pr_putsn("%u;",				vs - sw - ch);
			pr_putsn("%u;",				hs + cw);
			pr_putsn("%upG",			vs - sw);

			move_cap(-1, -1);
			return ;

		}
		break;
#endif
	}

	pr_puts("\x1d" "1tsE");

	/*  図形描画モード選択 */
	pr_puts("\x1d" "1dmG");
	/* スクリーンパターンの選択*/
	pr_putsn("\x1d" "0;0;%uspE", graylevel);
	/*	矩形描画 */
	pr_putsn("\x1d" "%u;", hs);
	pr_putsn("%u;", vs);
	pr_putsn("%u;", hs + width - 1);
	pr_putsn("%u;0rG", vs + height - 1);

	pr_puts("\x1d" "0tsE");

	/*  図形描画モード選択 */
	pr_puts("\x1d" "0dmG");
	/* 線種選択 */
	pr_puts("\x1d" "0;0lpG");
	/*	矩形描画 */
	pr_putsn("\x1d" "%u;", hs);
	pr_putsn("%u;", vs);
	pr_putsn("%u;", hs + width - 1);
	pr_putsn("%u;0rG", vs + height - 1);

	move_cap(-1, -1);
}
