[comp.sources.misc] v20i014: epsonps - Epson to Postscript converter, Part01/02

rjl@monu1.cc.monash.edu.au (Russell Lang) (05/23/91)

Submitted-by: Russell Lang <rjl@monu1.cc.monash.edu.au>
Posting-number: Volume 20, Issue 14
Archive-name: epsonps/part01

The program epsonps converts epson printer codes from an input file 
to PostScript. It is an excellent ASCII listing printer.
Command line options are provided for auto linefeed, auto carriage return, 
condensed mode, elite mode, output file name, IBM screen dump mode 
and paper type selection.

It is written in C and will compile and run on MS-DOS and Unix.  
A Unix makefile is provided.  
To compile for MS-DOS see the comments in the Unix makefile.

All Epson LX-800 and Star NL-10 codes are recognised except
    1: Download characters <ESC> %, <ESC> &
    2: Alignment <ESC> a
    3: Proportional printing <ESC> p
Most Epson LQ-800 printer codes are recognised.

Originally posted as "epson.c" in comp.lang.postscript on 4th March 1988
by Jon Greenblatt with the following copyright message:

    Copyright (c) 1988, Jonathan Greenblatt,
        <jonnyg@rover.umd.edu> (128.8.2.73)
        <jonnyg@umd5.umd.edu> (128.8.10.5)
        <pcproj@gymble.umd.edu> (128.8.128.16)
    This program may be redistributed in source form,
    provided no fee is charged and this copyright notice is preserved.

    Further contributions by:
       Mark Alexander <uunet!amdahl!drivax!alexande@umd5.UMD.EDU>


I have expanded the program and renamed it epsonps.c.
The copyright message still applies.

Russell Lang <rjl@monu1.cc.monash.edu.au>
Department of Electrical and Computer Systems Engineering
Monash University, Australia
-----
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README epsonps.c
# Wrapped by rjl@monu1 on Thu May 23 10:53:25 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(1339 characters\)
sed "s/^X//" >README <<'END_OF_README'
XThe program epsonps converts epson printer codes from an input file 
Xto PostScript. It is an excellent ASCII listing printer.
XCommand line options are provided for auto linefeed, auto carriage return, 
Xcondensed mode, elite mode, output file name, IBM screen dump mode 
Xand paper type selection.
X
XIt is written in C and will compile and run on MS-DOS and Unix.  
XA Unix makefile is provided.  
XTo compile for MS-DOS see the comments in the Unix makefile.
X
XAll Epson LX-800 and Star NL-10 codes are recognised except
X    1: Download characters <ESC> %, <ESC> &
X    2: Alignment <ESC> a
X    3: Proportional printing <ESC> p
XMost Epson LQ-800 printer codes are recognised.
X
XOriginally posted as "epson.c" in comp.lang.postscript on 4th March 1988
Xby Jon Greenblatt with the following copyright message:
X
X    Copyright (c) 1988, Jonathan Greenblatt,
X        <jonnyg@rover.umd.edu> (128.8.2.73)
X        <jonnyg@umd5.umd.edu> (128.8.10.5)
X        <pcproj@gymble.umd.edu> (128.8.128.16)
X    This program may be redistributed in source form,
X    provided no fee is charged and this copyright notice is preserved.
X
X    Further contributions by:
X       Mark Alexander <uunet!amdahl!drivax!alexande@umd5.UMD.EDU>
X
X
XI have expanded the program and renamed it epsonps.c.
XThe copyright message still applies.
X
XRussell Lang <rjl@monu1.cc.monash.edu.au>
X
END_OF_README
if test 1339 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f epsonps.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"epsonps.c\"
else
echo shar: Extracting \"epsonps.c\" \(44784 characters\)
sed "s/^X//" >epsonps.c <<'END_OF_epsonps.c'
X/*
X *  epsonps.c
X *  version 1.00   19910507
X *
X *  IBM Graphics printer to postscript translator.
X *
X *	Copyright (c) 1988, Jonathan Greenblatt,
X *		<jonnyg@rover.umd.edu> (128.8.2.73)
X *		<jonnyg@umd5.umd.edu> (128.8.10.5)
X *		<pcproj@gymble.umd.edu> (128.8.128.16)
X *      This program may be redistributed in source form,
X *      provided no fee is charged and this copyright notice is preserved.
X *
X *  DESCRIPTION:
X *	This program converts epson printer codes from an input file to
X *	PostScript on standard output.  Unknown, ignored or invalid epson
X *	codes are output to standard error output.
X *	This program is an excellent ASCII listing printer.
X *
X *	Usage:
X *	  epsonps [-L] -[R] [-c] [-d] [-e] [-lleft_margin] [-ooutfile] [-q] 
X *                [-s] [-tpaper_type] file
X *
X *  FILES:
X *	epsonps.c	This file.
X *	epsonps.pro	PostScript prolog.
X *	epsonps.1	Manual page.
X *	Makefile	Makefile for Unix
X *      README		
X *
X *  SUPPORTS:
X *	All Epson LX-800 and Star NL-10 codes except
X * 		1: Download characters <ESC> %, <ESC> &
X *		2: Alignment <ESC> a
X *		3: Proportional printing <ESC> p
X *	Most Epson LQ-800 printer codes.
X *
X *  CONTRIBUTIONS:
X *
X *	The Following was contributed by:
X *		 Mark Alexander <uunet!amdahl!drivax!alexande@umd5.UMD.EDU>
X *
X *  - Added 1/72 line-spacing support (ESC-A).  This required changing
X *    the scaling in the Y dimension to 792, so that we have 72 points
X *    per inch in Y, instead of 36.
X *  - Changed the BNDY definition to compute page breaks correctly
X *    when we're right at the page break.
X *  - If variable line spacing is being used to slew past the end
X *    of page, don't reset cy to the top of page; instead, set it
X *    to top of page + n, where n is the position it would have
X *    been on continuous paper in an Epson.
X *  - Allowed spaces to be underlined.
X *  - Added support for emphasized mode.  It's treated exactly
X *    the same way as doublestrike.
X *  - Added support for italics.  Italics-bold hasn't been tested, though.
X *  - Print unknown ESC codes on standard error.
X *  - Allow an optional input filename to specified on the command line.
X *  - Changed the indentation to make it more readable to me; you
X *    may not like my style at all (sorry).
X *
X *
X *  BUGS:
X *	1: Seems to timeout the apple laserwriter when I send large prinouts
X *	   through the tty line using no special line control.
X *	2: Underlining works, but the lines chop right through the descenders
X *	   on some lower case characters.  I haven't tried to fix this.
X *
X *  CONTRIBUTIONS:
X *
X *	The Following was contributed by:
X *		Russell Lang <rjl@monu1.cc.monash.edu.au>
X *		Graham Holmes <eln127v@monu1.cc.monash.edu.au>
X *		19910507
X *  - Compiles with Turbo C 2.0, Turbo C++ 1.01, MSC 5.10, cc.
X *  - Conforms with PostScript document structuring conventions.
X *  - Input file is now binary, input filename is now required.
X *  - Added output file.
X *  - Added many many "Ignoring ..." warnings.
X *  - Added paper type selection - default is A4  (80 chars * 70 lines).
X *    11" paper type not tested - all laserprinters here are A4!
X *  - Revised font selection.  Most font combinations are valid.
X *  - Corrected horizontal tab spacings.
X *  - Added graphic escapes.
X *  - Added margins, vertical tabs, macro, reset printer.
X *  - Added elite, condensed and enlarged modes.
X *  - Added input options 
X *  - Added 1/216" line spacing (and others).
X *  - Escape codes are a combination of Epson LX-800, Epson LQ-800, 
X *    Star NL-10 and Star NX-1000.  There are probably some incompatiblities.
X *  - Changed to single module source - set.c, set.h included in epsonps.c
X *  - Added IBM extended characters and international character sets.
X *  - Added Epson LQ-800 codes.
X *  - Added literal codes.
X *  - Added IBM screen dump mode.
X */
X
X#include	<stdio.h>
X
Xint debug = 1;		/* Print bad things to stderr */
Xint auto_lf = 0;	/* add line feed after carriage return */
Xint auto_cr = 0;	/* add carriage return after line feed */
Xint paper_type = 0;	/* default paper type a4 = 0, 11" = 4 */
Xint country_num = 0;	/* International character set */
Xint expand_print = 1;	/* print characters in range 0x80-0x9f */
Xint ibm_graphic = 1;	/* print IBM graphic characters in range 0x80-0xff */
Xint lq_mode = 0;	/* 0 = epson lx mode, 1 = epson lq mode */
Xint screendump_mode = 0;/* IBM screen dump mode */
Xchar prolog[] = "epsonps.pro";	/* prolog filename */
X
X#define READBIN "rb"	/* binary read mode for fopen() */
X
X#define INTS_IN_SET	16
Xtypedef unsigned int char_set[INTS_IN_SET];
X
X#ifdef __TURBOC__
X#define ANSI
X#endif
X
X/* prototypes */
X#ifdef ANSI
X#include <string.h>
X#include <stdlib.h>
Xint main(int, char*[]);
Xvoid new_page(void);
Xvoid end_page(void);
Xvoid set_font(void);
Xvoid eject_page(void);
Xvoid check_page(void);
Xvoid clear_set(char_set);
Xint in_set(char_set, unsigned char);
Xvoid str_add_set(char_set, char*);
Xvoid init_sets(void);
Xint get_pointx(int);
Xint get_pointy(int);
Xvoid init_tabs(void);
Xvoid reset_printer(void);
Xvoid pchar(unsigned char);
Xvoid putline(void);
Xvoid newline(void);
Xvoid ignore(char*);
Xvoid invalid(char*);
Xvoid hexout(unsigned char);
Xvoid debug_state(char*, unsigned char);
Xvoid dochar(unsigned char);
Xvoid init_printer(void);
Xvoid set_option(int*, char*);
Xvoid usage(char *);
X#else
Xint strlen();		/* from <string.h> */
Xint strcmp();		/* from <string.h> */
Xchar *strcat();		/* from <string.h> */
Xchar *strcpy();		/* from <string.h> */
Xint atoi();		/* from <stdlib.h> */
Xint exit();		/* from <stdlib.h> */
Xchar *malloc();		/* from <stdlib.h> */
Xvoid new_page();
Xvoid end_page();
Xvoid set_font();
Xvoid eject_page();
Xvoid check_page();
Xvoid clear_set();
Xint in_set();
Xvoid str_add_set();
Xvoid init_sets();
Xint get_pointx();
Xint get_pointy();
Xvoid init_tabs();
Xvoid reset_printer();
Xvoid pchar();
Xvoid putline();
Xvoid newline();
Xvoid ignore();
Xvoid invalid();
Xvoid hexout();
Xvoid debug_state();
Xvoid dochar();
Xvoid init_printer();
Xvoid set_option();
Xvoid usage();
X#endif
X
X
X/* Bounding Boxes */
X#define A4_LLX 22
X#define A4_LLY 16
X#define A4_URX 574
X#define A4_URY 826
X
X/* Letter (11"*8.5") bounding box NOT TESTED 19901123 */
X#define LTR_LLX 22
X#define LTR_LLY 16
X#define LTR_URX 590
X#define LTR_URY 784
X
Xstruct page_format {
X	char *name;
X	int llx,lly,urx,ury;	/* bounding box */
X	int nlines;		/* lines per page */
X	int nchars;		/* number of PICA characers across page */
X	int rotate;		/* rotate output ? */
X};
X
Xstruct page_format page_formats[] = {
X  {"a4",    A4_LLX,A4_LLY,A4_URX,A4_URY,70,80,0},   /* 297mm x 210mm */
X  {"a4-15w",A4_LLX,A4_LLY,A4_URX,A4_URY,66,132,1},  /* 11"*15" -> a4 rotated */
X  {"a4-12", A4_LLX,A4_LLY,A4_URX,A4_URY,72,80,0},   /* 12"*8.5" -> a4 */
X  {"a4-11", A4_LLX,A4_LLY,A4_URX,A4_URY,66,80,0},   /* 11"*8.5" -> a4 */
X  {"11", LTR_LLX,LTR_LLY,LTR_URX,LTR_URY,66,80,0},    /* 11"*8.5" */
X  {"11-15w",LTR_LLX,LTR_LLY,LTR_URX,LTR_URY,66,80,1}, /* 11"*15" -> 8.5"*11" */
X  {(char *)NULL,0,0,0,0,0,0,0}
X};
X
XFILE *infile;
XFILE *outfile;
XFILE *prologfile;
X#define EPSONBUFSIZE 20000
Xchar *buffer;
Xchar *progname;
X
Xint left = 0;		/* left margin (in PICA characters) */
Xint maxx, maxy;
Xint xstart, xstop, ystart, ystop, page_ystop;
X#define YSTART line_space;
X
Xint cx, cy;
Xint point_sizex, point_sizey, line_space;
Xint dotposition;
Xint page;
Xint eight_bit = 0;
Xint lcount;
X
X#define	BNDX	(cx > (xstop - point_sizex))
X#define	BNDY	(cy > ystop)
X
X#define	NUM_TABS	28
Xint tabs[NUM_TABS+1];
Xint tabindex;
X#define	NUM_VTABS	16
X#define NUM_VCHANNELS	8
Xint vtabs[NUM_VCHANNELS][NUM_VTABS+1];
Xint vtabchannel = 0;
Xint vsettabchannel = 0;
X
X#define MACROMAX 32
Xchar macro[MACROMAX+1];
Xint mindex;
X
X/* character sets */
Xchar_set printable_set; /* set of printable chararacters in normal font */
Xchar_set needesc_set;	/* set of characters that need to be \ quoted */
Xchar_set ibmgraph_set;	/* set of IBM graphic characters in ibmgraphfont */
Xchar_set ibmextend_set; /* set of IBM extended characters in normal font */
Xchar *printables =
X" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`,./\\[]=-!@#$%^&*()_+|{}:\"<>?~;'";
Xchar *needesc = "()\\";
Xchar *ibmextend1 =
X	"\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217";
Xchar *ibmextend2 =
X	"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\237";
Xchar *ibmextend3 =
X	"\240\241\242\243\244\245\246\247\250\255\256\257";
Xchar *ibmgraph1 =
X	"\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017";
Xchar *ibmgraph2 =
X	"\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037";
Xchar *ibmgraph3 =
X	"\177\236\251\252\253\254";
Xchar *ibmgraph4 =
X	"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277";
Xchar *ibmgraph5 =
X	"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317";
Xchar *ibmgraph6 =
X	"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337";
Xchar *ibmgraph7 = 
X	"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357";
Xchar *ibmgraph8 = 
X	"\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377";
X
Xchar *font_name[] = {
X	"normalfont","boldfont","italicfont","bolditalicfont","ibmgraphfont"};
Xint font_type = 0;
Xtypedef enum {NORMAL, IBMGRAPH, ITALIC} extend_modes;
Xextend_modes extend_mode = NORMAL;
X
X#define MAX_COUNTRY 12
Xchar *international[] = { 
X	"USA","France","Germany","UnitedKingdom","DenmarkI","Sweden", 
X	"Italy","SpainI","Japan","Norway","DenmarkII","SpainII",
X	"LatinAmerica"};
X
X/* width of fonts in characters per inch */
X#define PICA 10
X#define ELITE 12
X#define FIFTEEN 15
X/* height of font in characters per inch */
X#define FONTHEIGHT 6
X
X/* font variations */
Xint underline = 0;
Xint subscript =  0;
Xint doublewidth = 0;
Xint oneline_doublewidth = 0;
Xint highlight = 0;
Xint emphasize = 0;
Xint italic = 0;
Xint elite = 0;
Xint fifteen = 0;
Xint condensed = 0;
Xint doubleheight = 0;
Xint quadheight = 0;
Xint nlq_mode = 0;
X
X/* graphics */
Xint gcount;
Xint g_dpi;
Xint g_dpi_table[] = {60,120,120,240,80,72,90,180,360};
Xint g_mode;
Xint g_mode_k = 0;
Xint g_mode_l = 1;
Xint g_mode_y = 2;
Xint g_mode_z = 3;
Xint gwidth;
X
X
Xvoid
Xnew_page(void)
X{
X	page++;
X	cx = xstart;
X	cy = ystart;
X	fprintf(outfile,"%%%%Page: %d %d\n",page,page);
X	fputs("/saveobj2 save def\n",outfile);
X	set_font();
X}
X
Xvoid
Xend_page(void)
X{
X	fputs("showpage\nsaveobj2 restore\n",outfile);
X}
X
Xvoid
Xset_font(void)
X{
X	int	boldface;
X
X	boldface = highlight || emphasize;
X
X	font_type = 0;
X	if (italic)
X		font_type |= 2;
X	if (boldface)
X		font_type |= 1;
X	if (extend_mode == ITALIC)
X		font_type |= 2;
X	if (extend_mode == IBMGRAPH)
X		font_type = 4;
X
X	point_sizey = get_pointy(FONTHEIGHT);
X
X	if (elite) {
X		point_sizex = get_pointx(ELITE);
X		fputs("elite ",outfile);
X	}
X	else if (fifteen) {
X		point_sizex = get_pointx(FIFTEEN);
X		fputs("fifteen ",outfile);
X	}
X	else {
X		point_sizex = get_pointx(PICA);
X		fputs("pica ",outfile);
X	}
X	if (condensed) {
X		point_sizex = point_sizex * 3 / 5;
X		fputs("condensed ",outfile);
X	}
X	if (doublewidth || oneline_doublewidth) {
X		point_sizex = point_sizex * 2;
X		fputs("doublewidth ",outfile);
X	}
X	else if (doubleheight) {
X		fputs("doubleheight ",outfile);
X		point_sizex = point_sizex * 2;
X		point_sizey = point_sizey * 2;
X	}
X	else if (quadheight) {
X		fputs("quadheight ",outfile);
X		point_sizex = point_sizex * 4;
X		point_sizey = point_sizey * 4;
X	}
X
X	fprintf(outfile,"%s\n",font_name[font_type]);
X}
X
Xvoid
Xeject_page(void)
X{
X	end_page();
X	new_page();
X}
X
X/* Check if cy has gone past a page boundary, and skip to a new
X * page if necessary.  Set the new y-position not to the top of
X * page, but the point it would have been had this been a real
X * Epson printer with continuous forms.
X */
Xvoid
Xcheck_page(void)
X{
X	int oldcy;
X
X	if (BNDY) {
X		oldcy = cy;
X		eject_page();
X		cy = oldcy - ystop + ystart - YSTART;
X	}
X}
X
Xvoid
Xclear_set(set)
Xchar_set set;
X{
X	int i;
X	for (i = 0; i < INTS_IN_SET; i++) set[i] = 0;
X}
X
Xint
Xin_set(set,c)
Xchar_set set;
Xunsigned char c;
X{
X	c &= 0xff;
X	return ((set[c >> 4] & (1 << (c & 15))) != 0);
X}
X
Xvoid
Xstr_add_set(set,s)
Xchar_set set;
Xchar *s;
X{
X	unsigned char c;
X	while (*s) {
X		c = (unsigned char)*s++;
X		c &= 0xff;
X		set[c >> 4] |= 1 << (c & 15);
X	}
X}
X
Xvoid
Xinit_sets(void)
X{
X	clear_set(printable_set);
X	clear_set(needesc_set);
X	clear_set(ibmextend_set);
X	clear_set(ibmgraph_set);
X	str_add_set(printable_set,printables);
X	str_add_set(needesc_set,needesc);
X	str_add_set(ibmextend_set,ibmextend1);
X	str_add_set(ibmextend_set,ibmextend2);
X	str_add_set(ibmextend_set,ibmextend3);
X	str_add_set(ibmgraph_set,ibmgraph1);
X	str_add_set(ibmgraph_set,ibmgraph2);
X	str_add_set(ibmgraph_set,ibmgraph3);
X	str_add_set(ibmgraph_set,ibmgraph4);
X	str_add_set(ibmgraph_set,ibmgraph5);
X	str_add_set(ibmgraph_set,ibmgraph6);
X	str_add_set(ibmgraph_set,ibmgraph7);
X	str_add_set(ibmgraph_set,ibmgraph8);
X}
X
Xint
Xget_pointx(char_per_inch)
X{
X	if (lq_mode)
X		return(360/char_per_inch);
X	return(240/char_per_inch);
X}
X
Xint
Xget_pointy(char_per_inch)
X{
X	if (lq_mode)
X		return(360/char_per_inch);
X	return(216/char_per_inch);
X}
X
Xvoid
Xinit_tabs(void)
X{
Xint i;
X	for (i=0; i<NUM_TABS; i++)
X		tabs[i] = (i+1) * 8;
X	tabs[NUM_TABS] = -1;
X	for (vtabchannel=0; vtabchannel<NUM_VCHANNELS; vtabchannel++)
X		for (i=0; i<=NUM_VTABS; i++)
X			vtabs[vtabchannel][i] = 0;
X	vtabchannel = 0;
X}
X
Xvoid
Xreset_printer(void)
X{
X	end_page();
X
X	/* margins */
X	left = 0;
X	xstart = left * get_pointx(PICA);
X	xstop = maxx;
X	ystart = YSTART;
X	ystop = maxy;
X	page_ystop = ystop;
X
X	/* line spacing */
X	line_space = get_pointy(FONTHEIGHT);
X
X	/* current position */
X	cx = xstart;
X	cy = ystart;
X
X	/* fonts */
X	font_type = 0;
X	underline = 0;
X	subscript =  0;
X	doublewidth = 0;
X	oneline_doublewidth = 0;
X	highlight = 0;
X	emphasize = 0;
X	italic = 0;
X	elite = 0;
X	fifteen = 0;
X	condensed = 0;
X	doubleheight = 0;
X	quadheight = 0;
X
X	/* graphics */
X	g_mode_k = 0;
X	g_mode_l = 1;
X	g_mode_y = 2;
X	g_mode_z = 3;
X
X	/* tabs */
X	init_tabs();
X
X	/* other */
X	eight_bit = 0;
X	ibm_graphic = 1;
X	expand_print = 1;
X	country_num = 0;
X
X	new_page();
X	fprintf(outfile,"%s InternationalSet\n",international[country_num]);
X}
X
X#define	LINE_SIZE	256
Xunsigned char pline[LINE_SIZE];
Xint ptr = 0;
X
Xchar outline[LINE_SIZE+5];	/* used in putline() and main() */
X
Xvoid
Xpchar(c)
Xunsigned char c;
X{
X	if (eight_bit) {
X		if (eight_bit == 1)
X			c |= 0x80;
X		else
X			c &= 0x7f;
X	}
X	if (in_set(printable_set,c)) {
X		if (extend_mode != NORMAL) {
X			putline();
X			extend_mode = NORMAL;
X			set_font();
X		}
X		pline[ptr++] = c;
X	}
X	else if (ibm_graphic && in_set(ibmextend_set,c)) {
X		if (extend_mode != NORMAL) {
X			putline();
X			extend_mode = NORMAL;
X			set_font();
X		}
X		pline[ptr++] = c;
X	}
X	else if (ibm_graphic && in_set(ibmgraph_set,c)) {
X		if (extend_mode != IBMGRAPH) {
X			putline();
X			extend_mode = IBMGRAPH;
X			set_font();
X		}
X		pline[ptr++] = c;
X	}
X	else if (!ibm_graphic && in_set(printable_set,c&0x7f)) {
X		if (extend_mode != ITALIC) {
X			putline();
X			extend_mode = ITALIC;
X			set_font();
X		}
X		pline[ptr++] = c&0x7f;
X	}
X	else {
X		if (debug)
X		    fprintf(stderr,
X		      "Character 0x%02x is not printable\n",((int)c)&0xff);
X		if (extend_mode != NORMAL) {
X			putline();
X			extend_mode = NORMAL;
X			set_font();
X		}
X		pline[ptr++] = ' ';
X	}
X}
X
Xvoid
Xputline(void)
X{
X	unsigned char *s = pline;
X	int p;
X	int lx;
X
X	check_page();
X
X	/* Skip over leading spaces, unless underlining is enabled
X	 * (we want to underline spaces)
X	 */
X	if (underline == 0) {
X	    while (*s == ' ' && ptr > 0) {
X		s++;
X		ptr--;
X		if (BNDX) {
X			cx = xstart;
X			newline();
X		}
X		cx += point_sizex;
X	    }
X	}
X
X	while (ptr > 0) {
X	    p = 0;
X	    check_page();
X	    if (BNDX) {
X		cx = xstart;
X		newline();
X	    }
X	    lx = cx;
X	    while ((lx+point_sizex-1) < xstop && ptr > 0 && p < LINE_SIZE) {
X		if (*s>0x7f || *s<0x20) {
X			outline[p++] = '\\';
X			(void)sprintf(&outline[p],"%03o",*s++);
X			p+=3;
X		}
X		else {
X			if (in_set(needesc_set,*s))
X				outline[p++] = '\\';
X				outline[p++] = *s++;
X		}
X		ptr--;
X		lx += point_sizex;
X	    }
X	    outline[p] = 0;
X	    if (p > 0) {
X		int i = strlen(outline);
X		/* Forward slash won't work at the end of a string */
X		if (outline[i-1] == '/') {
X			outline[i] = ' ';
X			outline[i+1] = '\0';
X		}
X		if (subscript) {
X		  if (subscript == 1) /* Subscript */
X		    fprintf(outfile,"%d %d M gsave 1 .5 scale (%s) S grestore\n"
X			,cx,cy,outline);
X		  else   /* Superscript */
X		    fprintf(outfile,"%d %d M gsave 1 .5 scale (%s) S grestore\n"
X			,cx,(cy-(point_sizey>>1)),outline);
X		}
X		else /* Normal printing */
X		    fprintf(outfile,"%d %d M (%s) S\n",cx,cy,outline);
X		if (underline)
X		    fprintf(outfile,"%d %d M %d %d L stroke\n",
X			cx,cy+3,lx-1,cy+3);
X	    }
X	    cx = lx;
X	}
X}
X
Xvoid
Xnewline(void)
X{
X	cy += line_space;
X	if (doubleheight)
X		cy += get_pointy(FONTHEIGHT) * 2 / 3;
X	else if (quadheight)
X		cy += get_pointy(FONTHEIGHT) * 2;
X	check_page();
X}
X
Xvoid
Xignore(str)
Xchar *str;
X{
X	if (debug)
X		fprintf(stderr,"Ignoring %s sequence\n",str);
X}
X
Xvoid
Xinvalid(str)
Xchar *str;
X{
X	if (debug)
X		fprintf(stderr,"Invalid %s sequence\n",str);
X}
X
Xchar hextable[] = {'0','1','2','3','4','5','6','7','8','9',
X		'A','B','C','D','E','F'};
X
Xvoid
Xhexout(c)
Xunsigned char c;
X{
X	(void)fputc(hextable[ ((int)c>>4) & 0x0f ],outfile);
X	(void)fputc(hextable[ (int)c & 0x0f ],outfile);
X}
X
Xvoid
Xdebug_state(str,c)
Xchar *str;
Xunsigned char c;
X{
X	if (debug>=2)
X		fprintf(stderr,"%s: 0x%02x %c\n", str, c,
X#ifdef __TURBOC__
X			(c>=32 && c<127) || (c>=128) ? c : ' ');
X#else
X			(c>=32 && c<127) ? c : ' ');
X#endif
X}
X
Xtypedef enum {S_BASE,S_ESC,S_UNDERLINE,S_SUBSCRIPT,S_DOUBLE,S_NLQMODE,
X	S_LINESPACE,S_FINE_LINESPACE,S_LINEFEED,S_REV_LINEFEED,
X	S_IGNORE1,S_IGNORE2,S_IGNORE3,S_MASTER,S_ENLARGE,S_DOUBLEHEIGHT,
X	S_SETTAB,S_SETVTAB1,S_SETVTAB2,S_VTABCHANNEL,S_VSETTABCHANNEL,
X	S_TABINC,S_HTABINC,S_VTABINC,S_SKIP,S_HSKIP,S_VSKIP,
X	S_PAGELENGTH,S_PAGEINCH,S_BOTTOM,S_TOP,S_RIGHT,S_LEFT,
X	S_ABSOLUTE1,S_ABSOLUTE2,S_RELATIVE1,S_RELATIVE2,
X	S_MACRO,S_SETMACRO,S_IBM_MODE,S_INTERNATIONAL,
X	S_LITERAL,S_LITERAL1,S_LITERAL2,S_LITERAL_COUNT,S_SCREENDUMP,
X	S_GRAPHIC_MODE,S_GRAPHIC1,S_GRAPHIC2,S_GRAPHIC,
X	S_DEF_GRAPHIC,S_DEF_K,S_DEF_L,S_DEF_Y,S_DEF_Z,
X	S_GRAPHIC9_MODE,S_GRAPHIC9_1,S_GRAPHIC9_2,
X	S_GRAPHIC9_TOP,S_GRAPHIC9_BOTTOM,S_GRAPHIC24_2, 
X	S_GRAPHIC24_TOP,S_GRAPHIC24_MIDDLE,S_GRAPHIC24_BOTTOM} states;
X
Xstates state = S_BASE;
X
Xvoid
Xdochar(c)
Xunsigned char c;
X{
X	c &= 0xff;
X	if (ptr >= LINE_SIZE) putline();
X	switch (state)
X	{
X	case S_UNDERLINE:
X		debug_state("S_UNDERLINE",c);
X		state = S_BASE;
X		if (c == '\0' || c == '0')	underline = 0;
X		else if (c == '\1' || c == '1')	underline = 1;
X		break;
X	case S_DOUBLE:
X		debug_state("S_DOUBLE",c);
X		state = S_BASE;
X		if (c == '\0' || c == '0')	doublewidth = 0;
X		else if (c == '\1' || c == '1')	doublewidth = 1;
X		set_font();
X		break;
X	case S_SUBSCRIPT:
X		debug_state("S_SUBSCRIPT",c);
X		state = S_BASE;
X		if (c == '\0' || c == '0')	subscript = 2;
X		else if (c == '\1' || c == '1')	subscript = 1;
X		break;
X	case S_NLQMODE:
X		debug_state("S_NLQMODE",c);
X		state = S_BASE;
X		if (c == '\0' || c == '0')	nlq_mode = 0;
X		else if (c == '\1' || c == '1')	nlq_mode = 1;
X		break;
X	case S_LINESPACE:
X		debug_state("S_LINESPACE",c);
X		state = S_BASE;
X		if (lq_mode)
X			line_space = c * get_pointy(60); /* c/60 " */
X		else
X			line_space = 3 * c;		 /* c/72 " */
X		break;
X	case S_FINE_LINESPACE:
X		debug_state("S_FINE_LINESPACE",c);
X		state = S_BASE;
X		if (lq_mode)
X			line_space = c * get_pointy(180); /* c/180 " */
X		else
X			line_space = c;			 /* c/216 " */
X		break;
X	case S_LINEFEED:
X		debug_state("S_LINEFEED",c);
X		state = S_BASE;
X		if (lq_mode)
X			cy += c * get_pointy(180);
X		else
X			cy += c;
X		break;
X	case S_REV_LINEFEED:
X		debug_state("S_REV_LINEFEED",c);
X		state = S_BASE;
X		if (lq_mode)
X			cy -= c * get_pointy(180);
X		else
X			cy -= c;
X		break;
X	case S_IGNORE1:
X		debug_state("S_IGNORE1",c);
X		state = S_BASE;
X		break;
X	case S_IGNORE2:
X		debug_state("S_IGNORE2",c);
X		state = S_IGNORE1;
X		break;
X	case S_IGNORE3:
X		debug_state("S_IGNORE3",c);
X		state = S_IGNORE2;
X		break;
X	case S_MASTER:
X		debug_state("S_MASTER",c);
X		state = S_BASE;
X		elite = c & 0x01;
X		/* ignore proportional c & 0x02 */
X		condensed = c & 0x04;
X		emphasize = c & 0x08;
X		highlight = c & 0x10;
X		doublewidth = c & 0x20;
X		italic = c & 0x40;
X		underline = c & 0x80;
X		set_font();
X		break;
X	case S_ENLARGE:
X		debug_state("S_ENLARGE",c);
X		state = S_BASE;
X		switch(c) {
X			case 0:
X				doubleheight = 0;
X				quadheight = 0;
X				set_font();
X				break;
X			case 1:
X				doubleheight = 1;
X				quadheight = 0;
X				cy += get_pointy(FONTHEIGHT) * 2 / 3;
X				set_font();
X				break;
X			case 2:
X				doubleheight = 0;
X				quadheight = 1;
X				cy += get_pointy(FONTHEIGHT) * 2;
X				set_font();
X				break;
X			default:
X				ignore("<ESC> h n");
X				break;
X		}
X		break;
X	case S_DOUBLEHEIGHT:
X		debug_state("S_DOUBLEHEIGHT",c);
X		state = S_BASE;
X		if (c == '\0' || c == '0')	doubleheight = 0;
X		else if (c == '\1' || c == '1')	doubleheight = 1;
X		set_font();
X		break;
X	case S_SETTAB:
X		debug_state("S_SETTAB",c);
X		if (c == 0) {
X			state = S_BASE;
X			for (; tabindex <= NUM_TABS; tabindex++)
X				tabs[tabindex] = -1;
X		}
X		else {
X			if ( tabindex < NUM_TABS )
X				tabs[tabindex++] = c;
X		}
X		break;
X	case S_VSETTABCHANNEL:
X		debug_state("S_VSETTABCHANNEL",c);
X		state = S_SETVTAB1;
X		if (c > 7) {
X			invalid("<ESC> b n");
X			vsettabchannel = 0;
X		}
X		else
X			vsettabchannel = c;
X		break;
X	case S_SETVTAB1:
X		debug_state("S_SETVTAB1",c);
X		if (c == 0) { /* no vtabs */
X			state = S_BASE;
X			vtabs[vsettabchannel][tabindex] = 0;
X		}
X		else {
X			state = S_SETVTAB2;
X			vtabs[vsettabchannel][tabindex++] = c;
X		}
X		break;
X	case S_SETVTAB2:
X		debug_state("S_SETVTAB2",c);
X		if (c == 0) {
X			state = S_BASE;
X			for (; tabindex <= NUM_VTABS; tabindex++)
X				vtabs[vsettabchannel][tabindex] = -1;
X		}
X		else {
X			if ( tabindex < NUM_VTABS )
X				vtabs[vsettabchannel][tabindex++] = c;
X		}
X		break;
X	case S_VTABCHANNEL:
X		debug_state("S_VTABCHANNEL",c);
X		state = S_BASE;
X		if (c > 7)
X			invalid("<ESC> / n");
X		else
X			vtabchannel = c;
X		break;
X	case S_TABINC:
X		debug_state("S_TABINC",c);
X		if (c == '\0' || c == '0')
X			state = S_HTABINC;
X		else if (c == '\1' || c == '1')	
X			state = S_VTABINC;
X		else {
X			state = S_IGNORE1;
X			invalid("<ESC> e n");
X		}
X	case S_HTABINC:
X		debug_state("S_HTABINC",c);
X		state = S_BASE;
X		{
X		int i;
X		for (i=0; i<NUM_TABS; i++)
X			tabs[i] = (i+1) * c;
X		tabs[NUM_TABS] = -1;
X		}
X		break;
X	case S_VTABINC:
X		debug_state("S_VTABINC",c);
X		state = S_BASE;
X		{
X		int i;
X		for (i=0; i<NUM_VTABS; i++)
X			vtabs[vtabchannel][i] = (i+1) * c;
X		vtabs[vtabchannel][NUM_VTABS] = -1;
X		}
X		break;
X	case S_SKIP:
X		debug_state("S_SKIP",c);
X		if (c == '\0' || c == '0')
X			state = S_HSKIP;
X		else if (c == '\1' || c == '1')	
X			state = S_VSKIP;
X		else {
X			state = S_IGNORE1;
X			invalid("<ESC> f n");
X		}
X	case S_HSKIP:
X		debug_state("S_HSKIP",c);
X		state = S_BASE;
X		{
X		int i;
X		for (i=0; i<c; i++)
X			dochar(' ');
X		}
X		break;
X	case S_VSKIP:
X		debug_state("S_VSKIP",c);
X		state = S_BASE;
X		{
X		int i;
X		for (i=0; i<c; i++)
X			newline();
X		}
X		break;
X	case S_PAGELENGTH:
X		debug_state("S_PAGELENGTH",c);
X		if (c !=0) {
X			state = S_BASE;
X			ystop = c * line_space;
X			page_ystop = ystop;
X		}
X		else {
X			state = S_PAGEINCH;
X		}
X		break;
X	case S_PAGEINCH:
X		debug_state("S_PAGEINCH",c);
X		state = S_BASE;
X		ystop = c * get_pointy(1);
X		page_ystop = ystop;
X		break;
X	case S_BOTTOM:
X		debug_state("S_BOTTOM",c);
X		state = S_BASE;
X		{
X			int temp;
X			temp = page_ystop - c * line_space;
X			if (ystart + line_space < temp)
X				ystop = temp;
X			else
X				invalid("<ESC> N n");
X		}
X		break;
X	case S_TOP:
X		debug_state("S_TOP",c);
X		state = S_BASE;
X		ystart = c * line_space + YSTART ;
X		{
X			int temp;
X			temp = (c-1) * line_space + YSTART ;
X			if (temp + line_space < ystop)
X				ystart = temp;
X			else
X				invalid("<ESC> r n or <ESC> c n");
X		}
X		break;
X	case S_RIGHT:
X		debug_state("S_RIGHT",c);
X		state = S_BASE;
X		{
X			int temp;
X			temp =  c * point_sizex;
X			if (xstart + point_sizex < temp)
X				xstop = temp;
X			else
X				invalid("<ESC> Q n");
X		}
X		break;
X	case S_LEFT:
X		debug_state("S_LEFT",c);
X		state = S_BASE;
X		{
X			int temp;
X			temp = c * point_sizex;
X			if (temp + point_sizex < xstop)
X				xstart = temp;
X			else
X				invalid("<ESC> l n");
X		}
X		cx = xstart;
X		break;
X	case S_ABSOLUTE1:
X		debug_state("S_ABSOLUTE1",c);
X		state = S_ABSOLUTE2;
X		dotposition = c;
X		break;
X	case S_ABSOLUTE2:
X		debug_state("S_ABSOLUTE2",c);
X		state = S_BASE;
X		dotposition = (c*256 + dotposition) * get_pointx(60);
X		if (dotposition < xstop)
X			cx = dotposition;
X		break;
X	case S_RELATIVE1:
X		debug_state("S_RELATIVE1",c);
X		state = S_RELATIVE2;
X		dotposition = c;
X		break;
X	case S_RELATIVE2:
X		debug_state("S_RELATIVE2",c);
X		state = S_BASE;
X		dotposition = c*256 + dotposition;
X		if ((unsigned int)dotposition > (unsigned int)32767) {
X			dotposition = (int)(dotposition - 65536L);
X		}
X		if (lq_mode) {
X			if (nlq_mode)
X				dotposition = dotposition * get_pointx(180);
X			else
X				dotposition = dotposition * get_pointx(120);
X			if (cx + dotposition < xstop)
X				cx += dotposition;
X		}
X		else
X			invalid("<ESC> \\");
X		break;
X	case S_MACRO:
X		debug_state("S_MACRO",c);
X		if (c == 1) {
X			state = S_BASE;
X			for (mindex=0; macro[mindex]!=30; mindex++)
X				dochar((unsigned char)macro[mindex]);
X			break;
X		}
X		else {
X			state = S_SETMACRO;
X			mindex = 0;
X		}
X		/* no break */
X	case S_SETMACRO:
X		debug_state("S_SETMACRO",c);
X		if (mindex<MACROMAX)
X			macro[mindex++] = c;
X		if (c == 30) {
X			macro[mindex] = c;
X			state = S_BASE;
X		}
X		break;
X	case S_IBM_MODE:
X		debug_state("S_IBM_MODE",c);
X		state = S_BASE;
X		if (c == '\0' || c == '0')	ibm_graphic = 0;
X		else if (c == '\1' || c == '1')	ibm_graphic = 1;
X		else invalid("<ESC> t n");
X		break;
X	case S_INTERNATIONAL:
X		debug_state("S_INTERNATIONAL",c);
X		state = S_BASE;
X		if (c > MAX_COUNTRY)
X			invalid("<ESC> R n");
X		else {
X			country_num = c;
X			fprintf(outfile,"%s InternationalSet\n",international[country_num]);
X		}
X		break;
X	case S_LITERAL:
X		debug_state("S_LITERAL",c);
X		state = S_BASE;
X		pchar(c);
X		break;
X	case S_LITERAL1:
X		debug_state("S_LITERAL1",c);
X		state = S_LITERAL2;
X		lcount = c;
X		break;
X	case S_LITERAL2:
X		debug_state("S_LITERAL2",c);
X		state = S_LITERAL_COUNT;
X		lcount = 256 * c + lcount;
X		if (lcount == 0)
X			state = S_BASE;
X		break;
X	case S_LITERAL_COUNT:
X		debug_state("S_LITERAL_COUNT",c);
X		pchar(c);
X		lcount--;
X		if (lcount == 0) {
X			state = S_BASE;
X		}
X		break;
X	case S_SCREENDUMP:
X		debug_state("S_SCREENDUMP",c);
X	        /* recognise only \r and \n */
X	    	switch(c) {
X		case '\n':
X			putline();
X			newline();
X			if (auto_cr)
X				cx = xstart;
X			break;
X		case '\r':
X			putline();
X			cx = xstart;
X			if (auto_lf)
X				newline();
X			break;
X		default:
X			pchar(c);
X			break;
X		}
X		break;
X	case S_GRAPHIC_MODE:
X		debug_state("S_GRAPHIC_MODE",c);
X		state = S_GRAPHIC1;
X		if ( (c <= 6) || (c>=32 && c<=40) )
X			g_mode = c;
X		else
X			invalid("<ESC> *");
X		break;
X	case S_GRAPHIC1:
X		debug_state("S_GRAPHIC1",c);
X		state = S_GRAPHIC2;
X		gcount = c;
X		if (g_mode >= 32) {
X			g_dpi = g_dpi_table[g_mode-32];
X			state = S_GRAPHIC24_2;
X		}
X		else {
X			g_dpi = g_dpi_table[g_mode];
X		}
X		break;
X	case S_GRAPHIC2:
X		debug_state("S_GRAPHIC2",c);
X		state = S_GRAPHIC;
X		gcount = 256 * c + gcount ;
X		if (gcount == 0) {
X			state = S_BASE;
X			break;
X		}
X		gwidth = (int)( (long)get_pointx(1)*gcount/g_dpi);
X		if (lq_mode) {
X		    fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+6*get_pointy(180));
X		    fprintf(outfile,"%d %d scale\n", get_pointy(180)*24, gwidth);
X		}
X		else {
X		    fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+get_pointy(72));
X		    fprintf(outfile,"%d %d scale\n", get_pointy(72)*8, gwidth);
X		}
X		fprintf(outfile,"8 %d true [0 8 %d 0 0 8]", gcount, gcount);
X		fprintf(outfile," {currentfile graphicbuf readhexstring pop} \nimagemask\n");
X		cx += gwidth;
X		break;
X	case S_GRAPHIC:
X		debug_state("S_GRAPHIC",c);
X		hexout(c);
X		gcount--;
X		if ( (gcount & 0x1f) == 0 )
X			(void)fputc('\n',outfile);
X		if (gcount == 0) {
X			fputs("grestore\n",outfile);
X			state = S_BASE;
X		}
X		break;
X	case S_DEF_GRAPHIC:
X		debug_state("S_DEF_GRAPHIC",c);
X		switch(c)
X		{
X		case 'K':
X			state = S_DEF_K;
X			break;
X		case 'L':
X			state = S_DEF_L;
X			break;
X		case 'Y':
X			state = S_DEF_Y;
X			break;
X		case 'Z':
X			state = S_DEF_Z;
X			break;
X		default:
X			state = S_IGNORE1;
X			invalid("ESC ? n0 n1");
X			break;
X		}
X		break;
X	case S_DEF_K:
X		debug_state("S_DEF_K",c);
X		state = S_BASE;
X		if ( (c <= 6) || (c>=32 && c<=40) )
X			g_mode_k = c;
X		else
X			invalid("<ESC> ? K n");
X		break;
X	case S_DEF_L:
X		debug_state("S_DEF_L",c);
X		state = S_BASE;
X		if ( (c <= 6) || (c>=32 && c<=40) )
X			g_mode_l = c;
X		else
X			invalid("<ESC> ? L n");
X		break;
X	case S_DEF_Y:
X		debug_state("S_DEF_Y",c);
X		state = S_BASE;
X		if ( (c <= 6) || (c>=32 && c<=40) )
X			g_mode_y = c;
X		else
X			invalid("<ESC> ? Y n");
X		break;
X	case S_DEF_Z:
X		debug_state("S_DEF_Z",c);
X		state = S_BASE;
X		if ( (c<= 6) || (c>=32 && c<=40) )
X			g_mode_z = c;
X		else
X			invalid("<ESC> ? Z n");
X		break;
X	case S_GRAPHIC9_MODE:
X		debug_state("S_GRAPHIC9_MODE",c);
X		state = S_GRAPHIC9_1;
X		if (c > 6) {
X			invalid("<ESC> ^");
X			g_dpi = g_dpi_table[0];
X		}
X		else {
X			g_dpi = g_dpi_table[c];
X			g_mode = c;
X		}
X		break;
X	case S_GRAPHIC9_1:
X		debug_state("S_GRAPHIC9_1",c);
X		state = S_GRAPHIC9_2;
X		gcount = c;
X		break;
X	case S_GRAPHIC9_2:
X		debug_state("S_GRAPHIC9_2",c);
X		state = S_GRAPHIC9_TOP;
X		gcount = 256 * c + gcount ;
X		if (gcount == 0) {
X			state = S_BASE;
X			break;
X		}
X		gwidth = (int)( (long)get_pointx(1)*gcount/g_dpi);
X		if (lq_mode) {
X		    invalid("<ESC> ^");
X		    fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+9*get_pointy(60));
X		    fprintf(outfile,"%d %d scale\n", get_pointy(60)*16, gwidth);
X		}
X		else {
X		    fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+9*get_pointy(72));
X		    fprintf(outfile,"%d %d scale\n", get_pointy(72)*16, gwidth);
X		}
X		fprintf(outfile,"16 %d true [0 16 %d 0 0 16]", gcount, gcount);
X		fprintf(outfile," {currentfile graphicbuf readhexstring pop} \nimagemask\n");
X		cx += gwidth;
X		break;
X	case S_GRAPHIC9_TOP:
X		debug_state("S_GRAPHIC9_TOP",c);
X		state = S_GRAPHIC9_BOTTOM;
X		hexout(c);
X		break;
X	case S_GRAPHIC9_BOTTOM:
X		debug_state("S_GRAPHIC9_BOTTOM",c);
X		state = S_GRAPHIC9_TOP;
X		c &= 0x80;
X		hexout(c);
X		gcount--;
X		if ( (gcount & 0x0f) == 0 )
X			(void)fputc('\n',outfile);
X		if (gcount == 0) {
X			fputs("grestore\n",outfile);
X			state = S_BASE;
X		}
X		break;
X	case S_GRAPHIC24_2:
X		debug_state("S_GRAPHIC24_2",c);
X		state = S_GRAPHIC24_TOP;
X		gcount = 256 * c + gcount ;
X		if (gcount == 0) {
X			state = S_BASE;
X			break;
X		}
X		gwidth = (int)( (long)get_pointx(1)*gcount/g_dpi);
X		if (lq_mode) {
X		    fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+6*get_pointy(180));
X		    fprintf(outfile,"%d %d scale\n", get_pointy(180)*24, gwidth);
X		}
X		else {
X		    fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+get_pointy(72));
X		    fprintf(outfile,"%d %d scale\n", get_pointy(72)*8, gwidth);
X		}
X		fprintf(outfile,"24 %d true [0 24 %d 0 0 24]", gcount, gcount);
X		fprintf(outfile," {currentfile graphicbuf readhexstring pop} \nimagemask\n");
X		cx += gwidth;
X		break;
X	case S_GRAPHIC24_TOP:
X		debug_state("S_GRAPHIC24_TOP",c);
X		state = S_GRAPHIC24_MIDDLE;
X		hexout(c);
X		break;
X	case S_GRAPHIC24_MIDDLE:
X		debug_state("S_GRAPHIC24_MIDDLE",c);
X		state = S_GRAPHIC24_BOTTOM;
X		hexout(c);
X		break;
X	case S_GRAPHIC24_BOTTOM:
X		debug_state("S_GRAPHIC24_BOTTOM",c);
X		state = S_GRAPHIC24_TOP;
X		hexout(c);
X		gcount--;
X		if ( (gcount & 0x07) == 0 )
X			(void)fputc('\n',outfile);
X		if (gcount == 0) {
X			fputs("grestore\n",outfile);
X			state = S_BASE;
X		}
X		break;
X	case S_ESC:
X		debug_state("S_ESC",c);
X		state = S_BASE;
X		switch (c)
X		{
X		case '\n':	/* reverse line feed - Star NL-10 */
X			cy -= line_space;
X			break;
X		case '\f':	/* reverse form feed - Star NL-10 */
X			cy = ystart;
X			break;
X		case 14:	/* 0x0e - select one line expanded */
X			oneline_doublewidth = 1;
X			set_font();
X			break;
X		case 15:	/* select condensed */
X			condensed = 1;
X			set_font();
X			break;
X		case 25:	/* paper controls */
X			ignore("<ESC> <EM> n");
X			state = S_IGNORE1;
X			break;
X		case '!':	/* master print mode */
X			state = S_MASTER;
X			break;
X		case '#':	/* accept eight bit */
X			eight_bit = 0;
X			break;
X		case '$':	/* absolute dot position - LQ-800 */
X			state = S_ABSOLUTE1;
X			break;
X		case '%':	/* select download character set */
X			ignore("<ESC> % n");
X			state = S_IGNORE1;
X			break;
X		case '*':	/* select graphic mode */
X			state = S_GRAPHIC_MODE;
X			break;
X		case '+':	/* macro - Star NL-10 */
X			state = S_MACRO;
X			break;
X		case '-':
X			state = S_UNDERLINE;
X			break;
X		case '/':	/* select vertical tab channel */
X			state = S_VTABCHANNEL;
X			break;
X		case '0':	/* set line spacing to 1/8 inch */
X			line_space = get_pointy(8);
X			break;
X		case '1':	/* set line spacing to 7/72 inch */
X			line_space = 7 * get_pointy(72);
X			break;
X		case '2':	/* set line spacing to 1/6 inch */
X			line_space = get_pointy(6);
X			break;
X		case '3':	/* set line spacing to n/216 or n/180 inch */
X			state = S_FINE_LINESPACE;
X			break;
X		case '4':
X			italic = 1;
X			set_font();
X			break;
X		case '5':
X			italic = 0;
X			set_font();
X			break;
X		case '6':	/* expand printable area */
X			expand_print = 1;
X			break;
X		case '7':	/* cancels expand printable area */
X			expand_print = 0;
X			break;
X		case '8':	/* disable paper-out detector */
X			ignore("<ESC> 8");
X			break;
X		case '9':	/* enable paper-out detector */
X			ignore("<ESC> 9");
X			break;
X		case ':':	/* copy ROM characters to user defined */
X			state = S_IGNORE3;
X			ignore("<ESC> :");
X			break;
X		case '<':
X			if (lq_mode)
X				cx = 0; /* print head to home */
X			else
X				/* select one line uni-directional printing */
X				ignore("<ESC> <");
X			break;
X		case '=':	/* set eighth bit to 0 */
X			eight_bit = -1;
X			break;
X		case '>':	/* set eighth bit to 1 */
X			eight_bit = 1;
X			break;
X		case '?':
X			state = S_DEF_GRAPHIC;
X			break;
X		case '@':
X			reset_printer();
X			break;
X		case 'A':
X			state = S_LINESPACE;
X			break;
X		case 'B':
X			state = S_SETVTAB1;
X			vsettabchannel = 0;
X			tabindex = 0;
X			break;
X		case 'C':
X			state = S_PAGELENGTH;
X			break;
X		case 'D':
X			state = S_SETTAB;
X			tabindex = 0;
X			break;
X		case 'E':
X			emphasize = 1;
X			set_font();
X			break;
X		case 'F':
X			emphasize = 0;
X			set_font();
X			break;
X		case 'G':
X			highlight = 1;
X			set_font();
X			break;
X		case 'H':
X			highlight = 0;
X			set_font();
X			break;
X		case 'I':  /* allow use of characters 0x80-0x9f - Star NL-10 */
X			state = S_IGNORE1;
X			ignore("<ESC> I n");
X			break;
X		case 'J':
X			state = S_LINEFEED;
X			break;
X		case 'K':
X			state = S_GRAPHIC1;
X			g_mode = g_mode_k;
X			break;
X		case 'L':
X			state = S_GRAPHIC1;
X			g_mode = g_mode_l;
X			break;
X		case 'M':
X			elite = 1;
X			fifteen = 0;
X			set_font();
X			break;
X		case 'N':
X			state = S_BOTTOM;
X			break;
X		case 'O':
X			ystart = YSTART;
X			ystop = page_ystop;
X			break;
X		case 'P':
X			elite = 0;
X			fifteen = 0;
X			set_font();
X			break;
X		case 'Q':
X			state = S_RIGHT;
X			break;
X		case 'R':	/* international character set */
X			state = S_INTERNATIONAL;
X			break;
X		case 'S':
X			state = S_SUBSCRIPT;
X			break;
X		case 'T':
X			subscript = 0;
X			break;
X		case 'U':	/* unidirectional printint */
X			state = S_IGNORE1;
X			ignore("<ESC> U n");
X			break;
X		case 'W':
X			state = S_DOUBLE;
X			break;
X		case 'Y':
X			state = S_GRAPHIC1;
X			g_mode = g_mode_y;
X			break;
X		case 'Z':
X			state = S_GRAPHIC1;
X			g_mode = g_mode_z;
X			break;
X		case '\\':
X			if (lq_mode) 
X				/* relative dot position - LQ-800 */
X				state = S_RELATIVE1;
X			else
X				if (ibm_graphic)
X					state = S_LITERAL1;
X				else
X					state = S_RELATIVE1;
X			break;
X		case '^':
X			if (ibm_graphic)
X				state = S_LITERAL;    /* literal character */
X			else
X				state = S_GRAPHIC9_MODE; /* 9 pin graphics */
X			break;
X		case 'a':	/* justification */
X			state = S_IGNORE1;
X			ignore("<ESC> a n");
X			break;
X		case 'b':
X			state = S_VSETTABCHANNEL;
X			tabindex = 0;
X			break;
X		case 'c':	/* top margin - Star NX-1000 */
X			state = S_TOP;
X			break;
X		case 'e':
X			state = S_TABINC;
X			break;
X		case 'f':
X			state = S_SKIP;
X			break;
X		case 'g':	/* 15-pitch characters - LQ-800 */
X			elite = 0;
X			fifteen = 1;
X			set_font();
X			break;
X		case 'h':	/* enlarge characters - Star NL-10 */
X			state = S_ENLARGE;
X			break;
X		case 'i':	/* immediate print mode - Star NL-10 */
X			state = S_IGNORE1;
X			ignore("<ESC> i n");
X			break;
X		case 'j':	/* reverse line feed - Star NL-10 */
X			state = S_REV_LINEFEED;
X			break;
X		case 'k':	/* select font family */
X			state = S_IGNORE1;
X			ignore("<ESC> k n");
X			break;
X		case 'l':
X			state = S_LEFT;
X			break;
X		case 'm':	/* select special graphics */
X			state = S_IGNORE1;
X			ignore("<ESC> m n");
X			break;
X		case 'p':	/* proportional print - Star NL-10 */
X			state = S_IGNORE1;
X			ignore("<ESC> p n");
X			break;
X		case 'r':	/* top margin - Star NL-10 */
X			state = S_TOP;
X			break;
X		case 's':	/* half speed */
X			state = S_IGNORE1;
X			ignore("<ESC> s n");
X			break;
X		case 't':	/* italic / graphics & international */
X			state = S_IBM_MODE;
X			break;
X		case 'w':	/* double height characters - Star NX-1000 */
X			state = S_DOUBLEHEIGHT;
X			break;
X		case 'x':	/* NLQ mode */
X			state = S_NLQMODE;
X			break;
X		case '~':	/* slash zero - Star NL-10 */
X			state = S_IGNORE1;
X			ignore("<ESC> ~ n");
X			break;
X		default:
X			if (debug)
X			    fprintf(stderr,"Unknown sequence: <ESC> 0x%x\n",c);
X			break;
X		}
X		break;
X	   case S_BASE:
X		if (debug>=3)
X			debug_state("S_BASE",c);
X		if (!expand_print && c>=0x80 && c<=0x9f)
X			c &= 0x7f;
X		switch(c)
X		{
X		case 7:		/* bell (on stderr) */
X			if (debug)
X				(void)fputc((char)c,stderr);
X			break;
X		case '\b':	/* back space */
X			putline();
X			cx -= point_sizex;
X			break;
X		case '\t':
X			{
X				int i,l;
X
X				l = cx / point_sizex + ptr;
X				for (i = 0; i < NUM_TABS && tabs[i] <= l; i++)
X					;
X				if (tabs[i] == -1) break;
X				i = tabs[i] - l;
X				while (i-- > 0) dochar(' ')
X					;
X			}
X			break;
X		case '\n': 
X			putline();
X			newline();
X			if (auto_cr) {
X				cx = xstart;
X				if (oneline_doublewidth) {
X					oneline_doublewidth = 0;
X					set_font();
X				}
X			}
X			break;
X		case 11:	/* vertical tab */
X			putline();
X			if (vtabs[vtabchannel][0] == 0)
X				newline();
X			else {
X				int i,l;
X				l = cy / line_space;
X				for (i = 0; i < NUM_VTABS &&
X					vtabs[vtabchannel][i] <= l; i++) ;
X				if (vtabs[vtabchannel][i] == -1) {
X				    eject_page();
X				}
X				else {
X				    cy = vtabs[vtabchannel][i] * line_space
X						+ YSTART;
X				}
X			}
X			break;
X		case '\f':
X			putline();
X			eject_page();
X			break;
X		case '\r':
X			putline();
X			cx = xstart;
X			if (oneline_doublewidth) {
X				oneline_doublewidth = 0;
X				set_font();
X			}
X			if (auto_lf)
X				newline();
X			break;
X		case 14:	/* 0x0e - select one line expanded */
X			putline();
X			oneline_doublewidth = 1;
X			set_font();
X			break;
X		case 15:	/* 0x0f - select condensed */
X			putline();
X			condensed = 1;
X			set_font();
X			break;
X		case 17:	/* 0x11 - set printer off line */
X			ignore("<DC1>");
X			break;
X		case 18:	/* 0x12 - cancel condensed */
X			putline();
X			condensed = 0;
X			set_font();
X			break;
X		case 19:	/* 0x11 - set printer on line */
X			ignore("<DC3>");
X			break;
X		case 20:	/* 0x14 - cancel one line expanded */
X			putline();
X			oneline_doublewidth = 0;
X			set_font();
X			break;
X		case 24:	/* 0x18 - cancel line */
X			ignore("<CAN>");
X			break;
X		case 26:	/* CTRL-Z */
X			break;
X		case '\033':
X			putline();
X			state = S_ESC;
X			break;
X		case 127:	/* 0x7f - delete char */
X			ignore("<DEL>");
X			break;
X		default:	/* print character */
X			pchar(c);
X			break;
X		}
X		break;
X	}
X}
X
Xvoid
Xinit_printer(void)
X{
Xunsigned int nbytes;
X
X	maxx = page_formats[paper_type].nchars * get_pointx(PICA);
X	maxy = page_formats[paper_type].nlines * get_pointy(FONTHEIGHT);
X	line_space = get_pointy(FONTHEIGHT);
X
X	if (left > page_formats[paper_type].nchars) {
X		fprintf(stderr,"Left margin greater than right margin\n");
X		exit(1);
X	}
X	xstart = left * get_pointx(PICA);
X	xstop = maxx;
X	ystart = YSTART;
X	ystop = maxy;
X	page_ystop = ystop;
X
X	fputs("%!PS-Adobe-2.0\n",outfile);
X	fprintf(outfile,"%%%%BoundingBox: 0 0 %d %d\n",
X		page_formats[paper_type].urx, page_formats[paper_type].ury);
X	fputs("%%Creator: epsonps.c\n",outfile);
X	fputs("%%Pages: (atend)\n",outfile);
X	fputs("%%EndComments\n",outfile);
X	fputs("/saveobj1 save def\n",outfile);
X	if (page_formats[paper_type].rotate) {
X	    fputs("90 rotate\n",outfile);
X	    fprintf(outfile,"%d %d translate\n",page_formats[paper_type].lly,
X	      -page_formats[paper_type].llx);
X	    fprintf(outfile,"%d %d div %d %d div scale\n",
X	      page_formats[paper_type].ury-page_formats[paper_type].lly, maxx,
X	      page_formats[paper_type].llx-page_formats[paper_type].urx, maxy);
X	}
X	else {
X	    fprintf(outfile,"%d %d translate\n",page_formats[paper_type].llx,
X	      page_formats[paper_type].ury);
X	    fprintf(outfile,"%d %d div %d %d div scale\n",
X	      page_formats[paper_type].urx-page_formats[paper_type].llx, maxx,
X	      page_formats[paper_type].lly-page_formats[paper_type].ury, maxy);
X	}
X
X	fprintf(outfile,"/xdpi %d def\n", get_pointx(1));
X	fprintf(outfile,"/ydpi %d def\n", get_pointy(1));
X	fputs("1.5 setlinewidth\nnewpath\n",outfile);
X
X	/* send the header file */
X	fputs("%%BeginProcSet: epsonps.pro\n",outfile);
X	while (!feof(prologfile)) {
X		nbytes = fread(buffer, sizeof(char), EPSONBUFSIZE,
X			prologfile);
X		(void)fwrite(buffer, sizeof(char), nbytes, outfile);
X	}
X	fputs("%%EndProcSet\n",outfile);
X
X	fprintf(outfile,"%s InternationalSet\n",international[country_num]);
X
X	fputs("%%%%EndProlog\n",outfile);
X
X        if (screendump_mode) state = S_SCREENDUMP;
X	init_tabs();	/* initialise tabs */
X	macro[0] = 30;	/* initialise macro */
X
X	page = 0;
X	new_page();
X}
X
Xvoid
Xset_option(option,value)
Xint *option;
Xchar *value;
X{
X	if (*value == '\0')
X		*option = !(*option);
X	else
X		*option = atoi(value);
X}
X
Xvoid
Xusage(str)
Xchar *str;
X{
X	fprintf(stderr,"Usage: %s [-L] [-R] [-c] [-d] [-e] [-lleft_margin]\n",
X		progname);
X	fprintf(stderr,"       [-ooutfile] [-q] [-s] [-tpaper_type] file\n");
X	fprintf(stderr,"%s\n",str);
X	exit(1);
X}
X
Xint
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	int i,j;
X	int ch;
X	infile = (FILE *)NULL;
X	outfile = stdout;
X	progname = argv[0];
X
X	for (i=1; i<argc; i++) {
X	    if (argv[i][0] == '-') {
X		switch( argv[i][1] ) {
X			case 'L':
X				set_option(&auto_lf,&argv[i][2]);
X				break;
X			case 'R':
X				set_option(&auto_cr,&argv[i][2]);
X				break;
X			case 'c':
X				set_option(&condensed,&argv[i][2]);
X				break;
X			case 'd':
X				set_option(&debug,&argv[i][2]);
X				break;
X			case 'e':
X				set_option(&elite,&argv[i][2]);
X				break;
X			case 'l':
X				left = atoi(&argv[i][2]);
X				break;
X			case 'o':
X				if ( argv[i][2] == '\0' )
X				 	usage("Need filename with -o option");
X				else if ( (outfile=fopen(&argv[i][2],"w")) 
X			        	== (FILE *)NULL ) {
X		    		    fprintf(stderr,"Unable to open %s\n",
X					&argv[i][2]);
X				    exit(1);
X				}
X				break;
X			case 'q':
X				set_option(&lq_mode,&argv[i][2]);
X				break;
X			case 's':
X				set_option(&screendump_mode,&argv[i][2]);
X				break;
X			case 't':
X			  for (j=0; page_formats[j].name; j++) {
X			    if (strcmp(&argv[i][2],page_formats[j].name)==0) {
X			      paper_type = j;
X			      break;
X			    }
X			  }
X			  if (page_formats[j].name == (char *)NULL) {
X			      (void)strcpy(outline,"Valid paper types are:");
X			      for (j=0; page_formats[j].name; j++) {
X				(void)strcat(outline," ");
X				(void)strcat(outline,page_formats[j].name);
X			      }
X			      usage(outline);
X			  }
X			  break;
X			default:
X				(void)strcpy(outline,"Unknown option ");
X				(void)strcat(outline,argv[i]);
X				usage(outline);
X				break;
X		}
X	    }
X	    else {
X	        if ((infile = fopen(argv[i],READBIN)) == (FILE *)NULL)  {
X		    fprintf(stderr,"Unable to open %s\n",argv[i]);
X		    exit(1);
X		}
X	    }
X	}
X
X	if (infile == (FILE *)NULL)
X		usage("Need input filename");
X
X	/* open the prolog file */
X	if ((prologfile = fopen(prolog,"r")) == (FILE *)NULL)  {
X		/* try in same directory as epsonps.exe */
X		(void)strcpy(outline,argv[0]);
X		for (i=strlen(outline); i>0; i--) {
X			if (outline[i]=='\\' || outline[i]==':'
X				|| outline[i]=='/' || outline[i]==']') {
X				(void)strcpy(&outline[i+1],prolog);
X		    		prologfile = fopen(outline,"r");
X			break;
X			}
X		}
X		if (prologfile == (FILE *)NULL) {
X			fprintf(stderr,"Unable to open %s\n",prolog);
X			exit(1);
X		}
X        }
X
X	if ( (buffer=(char *)malloc(EPSONBUFSIZE)) == (char *)NULL ) {
X		fprintf(stderr,"%s: Unable to allocate memory\n",progname);
X		exit(1);
X	}
X
X	init_sets();
X	init_printer();
X#ifdef ANSI
X	(void)setvbuf(infile,buffer,_IOFBF,EPSONBUFSIZE);
X#endif
X	while ( (ch=getc(infile)) != EOF)
X		dochar((unsigned char)ch);
X	if (ptr>0)
X		putline();
X	if (cx > xstart || cy > ystart)
X		end_page();
X	else {
X		fputs("saveobj2 restore\n",outfile);
X		page--;
X	}
X	fputs("%%Trailer\n",outfile);
X	fprintf(outfile,"%%%%Pages: %d\n",page);
X	fputs("saveobj1 restore\n",outfile);
X	exit(0);
X	return(0);
X}
X/* end of epsonps.c */
END_OF_epsonps.c
if test 44784 -ne `wc -c <epsonps.c`; then
    echo shar: \"epsonps.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.