home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / printer / epsonps / epsonps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  45.7 KB  |  1,998 lines

  1. /*
  2.  *  epsonps.c
  3.  *  version 1.00   19910507
  4.  *
  5.  *  IBM Graphics printer to postscript translator.
  6.  *
  7.  *    Copyright (c) 1988, Jonathan Greenblatt,
  8.  *        <jonnyg@rover.umd.edu> (128.8.2.73)
  9.  *        <jonnyg@umd5.umd.edu> (128.8.10.5)
  10.  *        <pcproj@gymble.umd.edu> (128.8.128.16)
  11.  *      This program may be redistributed in source form,
  12.  *      provided no fee is charged and this copyright notice is preserved.
  13.  *
  14.  *  DESCRIPTION:
  15.  *    This program converts epson printer codes from an input file to
  16.  *    PostScript on standard output.  Unknown, ignored or invalid epson
  17.  *    codes are output to standard error output.
  18.  *    This program is an excellent ASCII listing printer.
  19.  *
  20.  *    Usage:
  21.  *      epsonps [-L] -[R] [-c] [-d] [-e] [-lleft_margin] [-ooutfile] [-q] 
  22.  *                [-s] [-tpaper_type] file
  23.  *
  24.  *  FILES:
  25.  *    epsonps.c    This file.
  26.  *    epsonps.pro    PostScript prolog.
  27.  *    epsonps.1    Manual page.
  28.  *    Makefile    Makefile for Unix
  29.  *      README        
  30.  *
  31.  *  SUPPORTS:
  32.  *    All Epson LX-800 and Star NL-10 codes except
  33.  *         1: Download characters <ESC> %, <ESC> &
  34.  *        2: Alignment <ESC> a
  35.  *        3: Proportional printing <ESC> p
  36.  *    Most Epson LQ-800 printer codes.
  37.  *
  38.  *  CONTRIBUTIONS:
  39.  *
  40.  *    The Following was contributed by:
  41.  *         Mark Alexander <uunet!amdahl!drivax!alexande@umd5.UMD.EDU>
  42.  *
  43.  *  - Added 1/72 line-spacing support (ESC-A).  This required changing
  44.  *    the scaling in the Y dimension to 792, so that we have 72 points
  45.  *    per inch in Y, instead of 36.
  46.  *  - Changed the BNDY definition to compute page breaks correctly
  47.  *    when we're right at the page break.
  48.  *  - If variable line spacing is being used to slew past the end
  49.  *    of page, don't reset cy to the top of page; instead, set it
  50.  *    to top of page + n, where n is the position it would have
  51.  *    been on continuous paper in an Epson.
  52.  *  - Allowed spaces to be underlined.
  53.  *  - Added support for emphasized mode.  It's treated exactly
  54.  *    the same way as doublestrike.
  55.  *  - Added support for italics.  Italics-bold hasn't been tested, though.
  56.  *  - Print unknown ESC codes on standard error.
  57.  *  - Allow an optional input filename to specified on the command line.
  58.  *  - Changed the indentation to make it more readable to me; you
  59.  *    may not like my style at all (sorry).
  60.  *
  61.  *
  62.  *  BUGS:
  63.  *    1: Seems to timeout the apple laserwriter when I send large prinouts
  64.  *       through the tty line using no special line control.
  65.  *    2: Underlining works, but the lines chop right through the descenders
  66.  *       on some lower case characters.  I haven't tried to fix this.
  67.  *
  68.  *  CONTRIBUTIONS:
  69.  *
  70.  *    The Following was contributed by:
  71.  *        Russell Lang <rjl@monu1.cc.monash.edu.au>
  72.  *        Graham Holmes <eln127v@monu1.cc.monash.edu.au>
  73.  *        19910507
  74.  *  - Compiles with Turbo C 2.0, Turbo C++ 1.01, MSC 5.10, cc.
  75.  *  - Conforms with PostScript document structuring conventions.
  76.  *  - Input file is now binary, input filename is now required.
  77.  *  - Added output file.
  78.  *  - Added many many "Ignoring ..." warnings.
  79.  *  - Added paper type selection - default is A4  (80 chars * 70 lines).
  80.  *    11" paper type not tested - all laserprinters here are A4!
  81.  *  - Revised font selection.  Most font combinations are valid.
  82.  *  - Corrected horizontal tab spacings.
  83.  *  - Added graphic escapes.
  84.  *  - Added margins, vertical tabs, macro, reset printer.
  85.  *  - Added elite, condensed and enlarged modes.
  86.  *  - Added input options 
  87.  *  - Added 1/216" line spacing (and others).
  88.  *  - Escape codes are a combination of Epson LX-800, Epson LQ-800, 
  89.  *    Star NL-10 and Star NX-1000.  There are probably some incompatiblities.
  90.  *  - Changed to single module source - set.c, set.h included in epsonps.c
  91.  *  - Added IBM extended characters and international character sets.
  92.  *  - Added Epson LQ-800 codes.
  93.  *  - Added literal codes.
  94.  *  - Added IBM screen dump mode.
  95.  */
  96.  
  97. #include    <stdio.h>
  98.  
  99. int debug = 1;        /* Print bad things to stderr */
  100. int auto_lf = 0;    /* add line feed after carriage return */
  101. int auto_cr = 0;    /* add carriage return after line feed */
  102. int paper_type = 0;    /* default paper type a4 = 0, 11" = 4 */
  103. int country_num = 0;    /* International character set */
  104. int expand_print = 1;    /* print characters in range 0x80-0x9f */
  105. int ibm_graphic = 1;    /* print IBM graphic characters in range 0x80-0xff */
  106. int lq_mode = 0;    /* 0 = epson lx mode, 1 = epson lq mode */
  107. int screendump_mode = 0;/* IBM screen dump mode */
  108. char prolog[] = "epsonps.pro";    /* prolog filename */
  109.  
  110. #define READBIN "rb"    /* binary read mode for fopen() */
  111.  
  112. #define INTS_IN_SET    16
  113. typedef unsigned int char_set[INTS_IN_SET];
  114.  
  115. #ifdef __TURBOC__
  116. #define ANSI
  117. #endif
  118.  
  119. /* prototypes */
  120. #ifdef ANSI
  121. #include <string.h>
  122. #include <stdlib.h>
  123. int main(int, char*[]);
  124. void new_page(void);
  125. void end_page(void);
  126. void set_font(void);
  127. void eject_page(void);
  128. void check_page(void);
  129. void clear_set(char_set);
  130. int in_set(char_set, unsigned char);
  131. void str_add_set(char_set, char*);
  132. void init_sets(void);
  133. int get_pointx(int);
  134. int get_pointy(int);
  135. void init_tabs(void);
  136. void reset_printer(void);
  137. void pchar(unsigned char);
  138. void putline(void);
  139. void newline(void);
  140. void ignore(char*);
  141. void invalid(char*);
  142. void hexout(unsigned char);
  143. void debug_state(char*, unsigned char);
  144. void dochar(unsigned char);
  145. void init_printer(void);
  146. void set_option(int*, char*);
  147. void usage(char *);
  148. #else
  149. int strlen();        /* from <string.h> */
  150. int strcmp();        /* from <string.h> */
  151. char *strcat();        /* from <string.h> */
  152. char *strcpy();        /* from <string.h> */
  153. int atoi();        /* from <stdlib.h> */
  154. int exit();        /* from <stdlib.h> */
  155. char *malloc();        /* from <stdlib.h> */
  156. void new_page();
  157. void end_page();
  158. void set_font();
  159. void eject_page();
  160. void check_page();
  161. void clear_set();
  162. int in_set();
  163. void str_add_set();
  164. void init_sets();
  165. int get_pointx();
  166. int get_pointy();
  167. void init_tabs();
  168. void reset_printer();
  169. void pchar();
  170. void putline();
  171. void newline();
  172. void ignore();
  173. void invalid();
  174. void hexout();
  175. void debug_state();
  176. void dochar();
  177. void init_printer();
  178. void set_option();
  179. void usage();
  180. #endif
  181.  
  182.  
  183. /* Bounding Boxes */
  184. #define A4_LLX 22
  185. #define A4_LLY 16
  186. #define A4_URX 574
  187. #define A4_URY 826
  188.  
  189. /* Letter (11"*8.5") bounding box NOT TESTED 19901123 */
  190. #define LTR_LLX 22
  191. #define LTR_LLY 16
  192. #define LTR_URX 590
  193. #define LTR_URY 784
  194.  
  195. struct page_format {
  196.     char *name;
  197.     int llx,lly,urx,ury;    /* bounding box */
  198.     int nlines;        /* lines per page */
  199.     int nchars;        /* number of PICA characers across page */
  200.     int rotate;        /* rotate output ? */
  201. };
  202.  
  203. struct page_format page_formats[] = {
  204.   {"a4",    A4_LLX,A4_LLY,A4_URX,A4_URY,70,80,0},   /* 297mm x 210mm */
  205.   {"a4-15w",A4_LLX,A4_LLY,A4_URX,A4_URY,66,132,1},  /* 11"*15" -> a4 rotated */
  206.   {"a4-12", A4_LLX,A4_LLY,A4_URX,A4_URY,72,80,0},   /* 12"*8.5" -> a4 */
  207.   {"a4-11", A4_LLX,A4_LLY,A4_URX,A4_URY,66,80,0},   /* 11"*8.5" -> a4 */
  208.   {"11", LTR_LLX,LTR_LLY,LTR_URX,LTR_URY,66,80,0},    /* 11"*8.5" */
  209.   {"11-15w",LTR_LLX,LTR_LLY,LTR_URX,LTR_URY,66,80,1}, /* 11"*15" -> 8.5"*11" */
  210.   {(char *)NULL,0,0,0,0,0,0,0}
  211. };
  212.  
  213. FILE *infile;
  214. FILE *outfile;
  215. FILE *prologfile;
  216. #define EPSONBUFSIZE 20000
  217. char *buffer;
  218. char *progname;
  219.  
  220. int left = 0;        /* left margin (in PICA characters) */
  221. int maxx, maxy;
  222. int xstart, xstop, ystart, ystop, page_ystop;
  223. #define YSTART line_space;
  224.  
  225. int cx, cy;
  226. int point_sizex, point_sizey, line_space;
  227. int dotposition;
  228. int page;
  229. int eight_bit = 0;
  230. int lcount;
  231.  
  232. #define    BNDX    (cx > (xstop - point_sizex))
  233. #define    BNDY    (cy > ystop)
  234.  
  235. #define    NUM_TABS    28
  236. int tabs[NUM_TABS+1];
  237. int tabindex;
  238. #define    NUM_VTABS    16
  239. #define NUM_VCHANNELS    8
  240. int vtabs[NUM_VCHANNELS][NUM_VTABS+1];
  241. int vtabchannel = 0;
  242. int vsettabchannel = 0;
  243.  
  244. #define MACROMAX 32
  245. char macro[MACROMAX+1];
  246. int mindex;
  247.  
  248. /* character sets */
  249. char_set printable_set; /* set of printable chararacters in normal font */
  250. char_set needesc_set;    /* set of characters that need to be \ quoted */
  251. char_set ibmgraph_set;    /* set of IBM graphic characters in ibmgraphfont */
  252. char_set ibmextend_set; /* set of IBM extended characters in normal font */
  253. char *printables =
  254. " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`,./\\[]=-!@#$%^&*()_+|{}:\"<>?~;'";
  255. char *needesc = "()\\";
  256. char *ibmextend1 =
  257.     "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217";
  258. char *ibmextend2 =
  259.     "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\237";
  260. char *ibmextend3 =
  261.     "\240\241\242\243\244\245\246\247\250\255\256\257";
  262. char *ibmgraph1 =
  263.     "\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017";
  264. char *ibmgraph2 =
  265.     "\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037";
  266. char *ibmgraph3 =
  267.     "\177\236\251\252\253\254";
  268. char *ibmgraph4 =
  269.     "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277";
  270. char *ibmgraph5 =
  271.     "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317";
  272. char *ibmgraph6 =
  273.     "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337";
  274. char *ibmgraph7 = 
  275.     "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357";
  276. char *ibmgraph8 = 
  277.     "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377";
  278.  
  279. char *font_name[] = {
  280.     "normalfont","boldfont","italicfont","bolditalicfont","ibmgraphfont"};
  281. int font_type = 0;
  282. typedef enum {NORMAL, IBMGRAPH, ITALIC} extend_modes;
  283. extend_modes extend_mode = NORMAL;
  284.  
  285. #define MAX_COUNTRY 12
  286. char *international[] = { 
  287.     "USA","France","Germany","UnitedKingdom","DenmarkI","Sweden", 
  288.     "Italy","SpainI","Japan","Norway","DenmarkII","SpainII",
  289.     "LatinAmerica"};
  290.  
  291. /* width of fonts in characters per inch */
  292. #define PICA 10
  293. #define ELITE 12
  294. #define FIFTEEN 15
  295. /* height of font in characters per inch */
  296. #define FONTHEIGHT 6
  297.  
  298. /* font variations */
  299. int underline = 0;
  300. int subscript =  0;
  301. int doublewidth = 0;
  302. int oneline_doublewidth = 0;
  303. int highlight = 0;
  304. int emphasize = 0;
  305. int italic = 0;
  306. int elite = 0;
  307. int fifteen = 0;
  308. int condensed = 0;
  309. int doubleheight = 0;
  310. int quadheight = 0;
  311. int nlq_mode = 0;
  312.  
  313. /* graphics */
  314. int gcount;
  315. int g_dpi;
  316. int g_dpi_table[] = {60,120,120,240,80,72,90,180,360};
  317. int g_mode;
  318. int g_mode_k = 0;
  319. int g_mode_l = 1;
  320. int g_mode_y = 2;
  321. int g_mode_z = 3;
  322. int gwidth;
  323.  
  324.  
  325. void
  326. new_page(void)
  327. {
  328.     page++;
  329.     cx = xstart;
  330.     cy = ystart;
  331.     fprintf(outfile,"%%%%Page: %d %d\n",page,page);
  332.     fputs("/saveobj2 save def\n",outfile);
  333.     set_font();
  334. }
  335.  
  336. void
  337. end_page(void)
  338. {
  339.     fputs("showpage\nsaveobj2 restore\n",outfile);
  340. }
  341.  
  342. void
  343. set_font(void)
  344. {
  345.     int    boldface;
  346.  
  347.     boldface = highlight || emphasize;
  348.  
  349.     font_type = 0;
  350.     if (italic)
  351.         font_type |= 2;
  352.     if (boldface)
  353.         font_type |= 1;
  354.     if (extend_mode == ITALIC)
  355.         font_type |= 2;
  356.     if (extend_mode == IBMGRAPH)
  357.         font_type = 4;
  358.  
  359.     point_sizey = get_pointy(FONTHEIGHT);
  360.  
  361.     if (elite) {
  362.         point_sizex = get_pointx(ELITE);
  363.         fputs("elite ",outfile);
  364.     }
  365.     else if (fifteen) {
  366.         point_sizex = get_pointx(FIFTEEN);
  367.         fputs("fifteen ",outfile);
  368.     }
  369.     else {
  370.         point_sizex = get_pointx(PICA);
  371.         fputs("pica ",outfile);
  372.     }
  373.     if (condensed) {
  374.         point_sizex = point_sizex * 3 / 5;
  375.         fputs("condensed ",outfile);
  376.     }
  377.     if (doublewidth || oneline_doublewidth) {
  378.         point_sizex = point_sizex * 2;
  379.         fputs("doublewidth ",outfile);
  380.     }
  381.     else if (doubleheight) {
  382.         fputs("doubleheight ",outfile);
  383.         point_sizex = point_sizex * 2;
  384.         point_sizey = point_sizey * 2;
  385.     }
  386.     else if (quadheight) {
  387.         fputs("quadheight ",outfile);
  388.         point_sizex = point_sizex * 4;
  389.         point_sizey = point_sizey * 4;
  390.     }
  391.  
  392.     fprintf(outfile,"%s\n",font_name[font_type]);
  393. }
  394.  
  395. void
  396. eject_page(void)
  397. {
  398.     end_page();
  399.     new_page();
  400. }
  401.  
  402. /* Check if cy has gone past a page boundary, and skip to a new
  403.  * page if necessary.  Set the new y-position not to the top of
  404.  * page, but the point it would have been had this been a real
  405.  * Epson printer with continuous forms.
  406.  */
  407. void
  408. check_page(void)
  409. {
  410.     int oldcy;
  411.  
  412.     if (BNDY) {
  413.         oldcy = cy;
  414.         eject_page();
  415.         cy = oldcy - ystop + ystart - YSTART;
  416.     }
  417. }
  418.  
  419. void
  420. clear_set(set)
  421. char_set set;
  422. {
  423.     int i;
  424.     for (i = 0; i < INTS_IN_SET; i++) set[i] = 0;
  425. }
  426.  
  427. int
  428. in_set(set,c)
  429. char_set set;
  430. unsigned char c;
  431. {
  432.     c &= 0xff;
  433.     return ((set[c >> 4] & (1 << (c & 15))) != 0);
  434. }
  435.  
  436. void
  437. str_add_set(set,s)
  438. char_set set;
  439. char *s;
  440. {
  441.     unsigned char c;
  442.     while (*s) {
  443.         c = (unsigned char)*s++;
  444.         c &= 0xff;
  445.         set[c >> 4] |= 1 << (c & 15);
  446.     }
  447. }
  448.  
  449. void
  450. init_sets(void)
  451. {
  452.     clear_set(printable_set);
  453.     clear_set(needesc_set);
  454.     clear_set(ibmextend_set);
  455.     clear_set(ibmgraph_set);
  456.     str_add_set(printable_set,printables);
  457.     str_add_set(needesc_set,needesc);
  458.     str_add_set(ibmextend_set,ibmextend1);
  459.     str_add_set(ibmextend_set,ibmextend2);
  460.     str_add_set(ibmextend_set,ibmextend3);
  461.     str_add_set(ibmgraph_set,ibmgraph1);
  462.     str_add_set(ibmgraph_set,ibmgraph2);
  463.     str_add_set(ibmgraph_set,ibmgraph3);
  464.     str_add_set(ibmgraph_set,ibmgraph4);
  465.     str_add_set(ibmgraph_set,ibmgraph5);
  466.     str_add_set(ibmgraph_set,ibmgraph6);
  467.     str_add_set(ibmgraph_set,ibmgraph7);
  468.     str_add_set(ibmgraph_set,ibmgraph8);
  469. }
  470.  
  471. int
  472. get_pointx(char_per_inch)
  473. {
  474.     if (lq_mode)
  475.         return(360/char_per_inch);
  476.     return(240/char_per_inch);
  477. }
  478.  
  479. int
  480. get_pointy(char_per_inch)
  481. {
  482.     if (lq_mode)
  483.         return(360/char_per_inch);
  484.     return(216/char_per_inch);
  485. }
  486.  
  487. void
  488. init_tabs(void)
  489. {
  490. int i;
  491.     for (i=0; i<NUM_TABS; i++)
  492.         tabs[i] = (i+1) * 8;
  493.     tabs[NUM_TABS] = -1;
  494.     for (vtabchannel=0; vtabchannel<NUM_VCHANNELS; vtabchannel++)
  495.         for (i=0; i<=NUM_VTABS; i++)
  496.             vtabs[vtabchannel][i] = 0;
  497.     vtabchannel = 0;
  498. }
  499.  
  500. void
  501. reset_printer(void)
  502. {
  503.     end_page();
  504.  
  505.     /* margins */
  506.     left = 0;
  507.     xstart = left * get_pointx(PICA);
  508.     xstop = maxx;
  509.     ystart = YSTART;
  510.     ystop = maxy;
  511.     page_ystop = ystop;
  512.  
  513.     /* line spacing */
  514.     line_space = get_pointy(FONTHEIGHT);
  515.  
  516.     /* current position */
  517.     cx = xstart;
  518.     cy = ystart;
  519.  
  520.     /* fonts */
  521.     font_type = 0;
  522.     underline = 0;
  523.     subscript =  0;
  524.     doublewidth = 0;
  525.     oneline_doublewidth = 0;
  526.     highlight = 0;
  527.     emphasize = 0;
  528.     italic = 0;
  529.     elite = 0;
  530.     fifteen = 0;
  531.     condensed = 0;
  532.     doubleheight = 0;
  533.     quadheight = 0;
  534.  
  535.     /* graphics */
  536.     g_mode_k = 0;
  537.     g_mode_l = 1;
  538.     g_mode_y = 2;
  539.     g_mode_z = 3;
  540.  
  541.     /* tabs */
  542.     init_tabs();
  543.  
  544.     /* other */
  545.     eight_bit = 0;
  546.     ibm_graphic = 1;
  547.     expand_print = 1;
  548.     country_num = 0;
  549.  
  550.     new_page();
  551.     fprintf(outfile,"%s InternationalSet\n",international[country_num]);
  552. }
  553.  
  554. #define    LINE_SIZE    256
  555. unsigned char pline[LINE_SIZE];
  556. int ptr = 0;
  557.  
  558. char outline[LINE_SIZE+5];    /* used in putline() and main() */
  559.  
  560. void
  561. pchar(c)
  562. unsigned char c;
  563. {
  564.     if (eight_bit) {
  565.         if (eight_bit == 1)
  566.             c |= 0x80;
  567.         else
  568.             c &= 0x7f;
  569.     }
  570.     if (in_set(printable_set,c)) {
  571.         if (extend_mode != NORMAL) {
  572.             putline();
  573.             extend_mode = NORMAL;
  574.             set_font();
  575.         }
  576.         pline[ptr++] = c;
  577.     }
  578.     else if (ibm_graphic && in_set(ibmextend_set,c)) {
  579.         if (extend_mode != NORMAL) {
  580.             putline();
  581.             extend_mode = NORMAL;
  582.             set_font();
  583.         }
  584.         pline[ptr++] = c;
  585.     }
  586.     else if (ibm_graphic && in_set(ibmgraph_set,c)) {
  587.         if (extend_mode != IBMGRAPH) {
  588.             putline();
  589.             extend_mode = IBMGRAPH;
  590.             set_font();
  591.         }
  592.         pline[ptr++] = c;
  593.     }
  594.     else if (!ibm_graphic && in_set(printable_set,c&0x7f)) {
  595.         if (extend_mode != ITALIC) {
  596.             putline();
  597.             extend_mode = ITALIC;
  598.             set_font();
  599.         }
  600.         pline[ptr++] = c&0x7f;
  601.     }
  602.     else {
  603.         if (debug)
  604.             fprintf(stderr,
  605.               "Character 0x%02x is not printable\n",((int)c)&0xff);
  606.         if (extend_mode != NORMAL) {
  607.             putline();
  608.             extend_mode = NORMAL;
  609.             set_font();
  610.         }
  611.         pline[ptr++] = ' ';
  612.     }
  613. }
  614.  
  615. void
  616. putline(void)
  617. {
  618.     unsigned char *s = pline;
  619.     int p;
  620.     int lx;
  621.  
  622.     check_page();
  623.  
  624.     /* Skip over leading spaces, unless underlining is enabled
  625.      * (we want to underline spaces)
  626.      */
  627.     if (underline == 0) {
  628.         while (*s == ' ' && ptr > 0) {
  629.         s++;
  630.         ptr--;
  631.         if (BNDX) {
  632.             cx = xstart;
  633.             newline();
  634.         }
  635.         cx += point_sizex;
  636.         }
  637.     }
  638.  
  639.     while (ptr > 0) {
  640.         p = 0;
  641.         check_page();
  642.         if (BNDX) {
  643.         cx = xstart;
  644.         newline();
  645.         }
  646.         lx = cx;
  647.         while ((lx+point_sizex-1) < xstop && ptr > 0 && p < LINE_SIZE) {
  648.         if (*s>0x7f || *s<0x20) {
  649.             outline[p++] = '\\';
  650.             (void)sprintf(&outline[p],"%03o",*s++);
  651.             p+=3;
  652.         }
  653.         else {
  654.             if (in_set(needesc_set,*s))
  655.                 outline[p++] = '\\';
  656.                 outline[p++] = *s++;
  657.         }
  658.         ptr--;
  659.         lx += point_sizex;
  660.         }
  661.         outline[p] = 0;
  662.         if (p > 0) {
  663.         int i = strlen(outline);
  664.         /* Forward slash won't work at the end of a string */
  665.         if (outline[i-1] == '/') {
  666.             outline[i] = ' ';
  667.             outline[i+1] = '\0';
  668.         }
  669.         if (subscript) {
  670.           if (subscript == 1) /* Subscript */
  671.             fprintf(outfile,"%d %d M gsave 1 .5 scale (%s) S grestore\n"
  672.             ,cx,cy,outline);
  673.           else   /* Superscript */
  674.             fprintf(outfile,"%d %d M gsave 1 .5 scale (%s) S grestore\n"
  675.             ,cx,(cy-(point_sizey>>1)),outline);
  676.         }
  677.         else /* Normal printing */
  678.             fprintf(outfile,"%d %d M (%s) S\n",cx,cy,outline);
  679.         if (underline)
  680.             fprintf(outfile,"%d %d M %d %d L stroke\n",
  681.             cx,cy+3,lx-1,cy+3);
  682.         }
  683.         cx = lx;
  684.     }
  685. }
  686.  
  687. void
  688. newline(void)
  689. {
  690.     cy += line_space;
  691.     if (doubleheight)
  692.         cy += get_pointy(FONTHEIGHT) * 2 / 3;
  693.     else if (quadheight)
  694.         cy += get_pointy(FONTHEIGHT) * 2;
  695.     check_page();
  696. }
  697.  
  698. void
  699. ignore(str)
  700. char *str;
  701. {
  702.     if (debug)
  703.         fprintf(stderr,"Ignoring %s sequence\n",str);
  704. }
  705.  
  706. void
  707. invalid(str)
  708. char *str;
  709. {
  710.     if (debug)
  711.         fprintf(stderr,"Invalid %s sequence\n",str);
  712. }
  713.  
  714. char hextable[] = {'0','1','2','3','4','5','6','7','8','9',
  715.         'A','B','C','D','E','F'};
  716.  
  717. void
  718. hexout(c)
  719. unsigned char c;
  720. {
  721.     (void)fputc(hextable[ ((int)c>>4) & 0x0f ],outfile);
  722.     (void)fputc(hextable[ (int)c & 0x0f ],outfile);
  723. }
  724.  
  725. void
  726. debug_state(str,c)
  727. char *str;
  728. unsigned char c;
  729. {
  730.     if (debug>=2)
  731.         fprintf(stderr,"%s: 0x%02x %c\n", str, c,
  732. #ifdef __TURBOC__
  733.             (c>=32 && c<127) || (c>=128) ? c : ' ');
  734. #else
  735.             (c>=32 && c<127) ? c : ' ');
  736. #endif
  737. }
  738.  
  739. typedef enum {S_BASE,S_ESC,S_UNDERLINE,S_SUBSCRIPT,S_DOUBLE,S_NLQMODE,
  740.     S_LINESPACE,S_FINE_LINESPACE,S_LINEFEED,S_REV_LINEFEED,
  741.     S_IGNORE1,S_IGNORE2,S_IGNORE3,S_MASTER,S_ENLARGE,S_DOUBLEHEIGHT,
  742.     S_SETTAB,S_SETVTAB1,S_SETVTAB2,S_VTABCHANNEL,S_VSETTABCHANNEL,
  743.     S_TABINC,S_HTABINC,S_VTABINC,S_SKIP,S_HSKIP,S_VSKIP,
  744.     S_PAGELENGTH,S_PAGEINCH,S_BOTTOM,S_TOP,S_RIGHT,S_LEFT,
  745.     S_ABSOLUTE1,S_ABSOLUTE2,S_RELATIVE1,S_RELATIVE2,
  746.     S_MACRO,S_SETMACRO,S_IBM_MODE,S_INTERNATIONAL,
  747.     S_LITERAL,S_LITERAL1,S_LITERAL2,S_LITERAL_COUNT,S_SCREENDUMP,
  748.     S_GRAPHIC_MODE,S_GRAPHIC1,S_GRAPHIC2,S_GRAPHIC,
  749.     S_DEF_GRAPHIC,S_DEF_K,S_DEF_L,S_DEF_Y,S_DEF_Z,
  750.     S_GRAPHIC9_MODE,S_GRAPHIC9_1,S_GRAPHIC9_2,
  751.     S_GRAPHIC9_TOP,S_GRAPHIC9_BOTTOM,S_GRAPHIC24_2, 
  752.     S_GRAPHIC24_TOP,S_GRAPHIC24_MIDDLE,S_GRAPHIC24_BOTTOM} states;
  753.  
  754. states state = S_BASE;
  755.  
  756. void
  757. dochar(c)
  758. unsigned char c;
  759. {
  760.     c &= 0xff;
  761.     if (ptr >= LINE_SIZE) putline();
  762.     switch (state)
  763.     {
  764.     case S_UNDERLINE:
  765.         debug_state("S_UNDERLINE",c);
  766.         state = S_BASE;
  767.         if (c == '\0' || c == '0')    underline = 0;
  768.         else if (c == '\1' || c == '1')    underline = 1;
  769.         break;
  770.     case S_DOUBLE:
  771.         debug_state("S_DOUBLE",c);
  772.         state = S_BASE;
  773.         if (c == '\0' || c == '0')    doublewidth = 0;
  774.         else if (c == '\1' || c == '1')    doublewidth = 1;
  775.         set_font();
  776.         break;
  777.     case S_SUBSCRIPT:
  778.         debug_state("S_SUBSCRIPT",c);
  779.         state = S_BASE;
  780.         if (c == '\0' || c == '0')    subscript = 2;
  781.         else if (c == '\1' || c == '1')    subscript = 1;
  782.         break;
  783.     case S_NLQMODE:
  784.         debug_state("S_NLQMODE",c);
  785.         state = S_BASE;
  786.         if (c == '\0' || c == '0')    nlq_mode = 0;
  787.         else if (c == '\1' || c == '1')    nlq_mode = 1;
  788.         break;
  789.     case S_LINESPACE:
  790.         debug_state("S_LINESPACE",c);
  791.         state = S_BASE;
  792.         if (lq_mode)
  793.             line_space = c * get_pointy(60); /* c/60 " */
  794.         else
  795.             line_space = 3 * c;         /* c/72 " */
  796.         break;
  797.     case S_FINE_LINESPACE:
  798.         debug_state("S_FINE_LINESPACE",c);
  799.         state = S_BASE;
  800.         if (lq_mode)
  801.             line_space = c * get_pointy(180); /* c/180 " */
  802.         else
  803.             line_space = c;             /* c/216 " */
  804.         break;
  805.     case S_LINEFEED:
  806.         debug_state("S_LINEFEED",c);
  807.         state = S_BASE;
  808.         if (lq_mode)
  809.             cy += c * get_pointy(180);
  810.         else
  811.             cy += c;
  812.         break;
  813.     case S_REV_LINEFEED:
  814.         debug_state("S_REV_LINEFEED",c);
  815.         state = S_BASE;
  816.         if (lq_mode)
  817.             cy -= c * get_pointy(180);
  818.         else
  819.             cy -= c;
  820.         break;
  821.     case S_IGNORE1:
  822.         debug_state("S_IGNORE1",c);
  823.         state = S_BASE;
  824.         break;
  825.     case S_IGNORE2:
  826.         debug_state("S_IGNORE2",c);
  827.         state = S_IGNORE1;
  828.         break;
  829.     case S_IGNORE3:
  830.         debug_state("S_IGNORE3",c);
  831.         state = S_IGNORE2;
  832.         break;
  833.     case S_MASTER:
  834.         debug_state("S_MASTER",c);
  835.         state = S_BASE;
  836.         elite = c & 0x01;
  837.         /* ignore proportional c & 0x02 */
  838.         condensed = c & 0x04;
  839.         emphasize = c & 0x08;
  840.         highlight = c & 0x10;
  841.         doublewidth = c & 0x20;
  842.         italic = c & 0x40;
  843.         underline = c & 0x80;
  844.         set_font();
  845.         break;
  846.     case S_ENLARGE:
  847.         debug_state("S_ENLARGE",c);
  848.         state = S_BASE;
  849.         switch(c) {
  850.             case 0:
  851.                 doubleheight = 0;
  852.                 quadheight = 0;
  853.                 set_font();
  854.                 break;
  855.             case 1:
  856.                 doubleheight = 1;
  857.                 quadheight = 0;
  858.                 cy += get_pointy(FONTHEIGHT) * 2 / 3;
  859.                 set_font();
  860.                 break;
  861.             case 2:
  862.                 doubleheight = 0;
  863.                 quadheight = 1;
  864.                 cy += get_pointy(FONTHEIGHT) * 2;
  865.                 set_font();
  866.                 break;
  867.             default:
  868.                 ignore("<ESC> h n");
  869.                 break;
  870.         }
  871.         break;
  872.     case S_DOUBLEHEIGHT:
  873.         debug_state("S_DOUBLEHEIGHT",c);
  874.         state = S_BASE;
  875.         if (c == '\0' || c == '0')    doubleheight = 0;
  876.         else if (c == '\1' || c == '1')    doubleheight = 1;
  877.         set_font();
  878.         break;
  879.     case S_SETTAB:
  880.         debug_state("S_SETTAB",c);
  881.         if (c == 0) {
  882.             state = S_BASE;
  883.             for (; tabindex <= NUM_TABS; tabindex++)
  884.                 tabs[tabindex] = -1;
  885.         }
  886.         else {
  887.             if ( tabindex < NUM_TABS )
  888.                 tabs[tabindex++] = c;
  889.         }
  890.         break;
  891.     case S_VSETTABCHANNEL:
  892.         debug_state("S_VSETTABCHANNEL",c);
  893.         state = S_SETVTAB1;
  894.         if (c > 7) {
  895.             invalid("<ESC> b n");
  896.             vsettabchannel = 0;
  897.         }
  898.         else
  899.             vsettabchannel = c;
  900.         break;
  901.     case S_SETVTAB1:
  902.         debug_state("S_SETVTAB1",c);
  903.         if (c == 0) { /* no vtabs */
  904.             state = S_BASE;
  905.             vtabs[vsettabchannel][tabindex] = 0;
  906.         }
  907.         else {
  908.             state = S_SETVTAB2;
  909.             vtabs[vsettabchannel][tabindex++] = c;
  910.         }
  911.         break;
  912.     case S_SETVTAB2:
  913.         debug_state("S_SETVTAB2",c);
  914.         if (c == 0) {
  915.             state = S_BASE;
  916.             for (; tabindex <= NUM_VTABS; tabindex++)
  917.                 vtabs[vsettabchannel][tabindex] = -1;
  918.         }
  919.         else {
  920.             if ( tabindex < NUM_VTABS )
  921.                 vtabs[vsettabchannel][tabindex++] = c;
  922.         }
  923.         break;
  924.     case S_VTABCHANNEL:
  925.         debug_state("S_VTABCHANNEL",c);
  926.         state = S_BASE;
  927.         if (c > 7)
  928.             invalid("<ESC> / n");
  929.         else
  930.             vtabchannel = c;
  931.         break;
  932.     case S_TABINC:
  933.         debug_state("S_TABINC",c);
  934.         if (c == '\0' || c == '0')
  935.             state = S_HTABINC;
  936.         else if (c == '\1' || c == '1')    
  937.             state = S_VTABINC;
  938.         else {
  939.             state = S_IGNORE1;
  940.             invalid("<ESC> e n");
  941.         }
  942.     case S_HTABINC:
  943.         debug_state("S_HTABINC",c);
  944.         state = S_BASE;
  945.         {
  946.         int i;
  947.         for (i=0; i<NUM_TABS; i++)
  948.             tabs[i] = (i+1) * c;
  949.         tabs[NUM_TABS] = -1;
  950.         }
  951.         break;
  952.     case S_VTABINC:
  953.         debug_state("S_VTABINC",c);
  954.         state = S_BASE;
  955.         {
  956.         int i;
  957.         for (i=0; i<NUM_VTABS; i++)
  958.             vtabs[vtabchannel][i] = (i+1) * c;
  959.         vtabs[vtabchannel][NUM_VTABS] = -1;
  960.         }
  961.         break;
  962.     case S_SKIP:
  963.         debug_state("S_SKIP",c);
  964.         if (c == '\0' || c == '0')
  965.             state = S_HSKIP;
  966.         else if (c == '\1' || c == '1')    
  967.             state = S_VSKIP;
  968.         else {
  969.             state = S_IGNORE1;
  970.             invalid("<ESC> f n");
  971.         }
  972.     case S_HSKIP:
  973.         debug_state("S_HSKIP",c);
  974.         state = S_BASE;
  975.         {
  976.         int i;
  977.         for (i=0; i<c; i++)
  978.             dochar(' ');
  979.         }
  980.         break;
  981.     case S_VSKIP:
  982.         debug_state("S_VSKIP",c);
  983.         state = S_BASE;
  984.         {
  985.         int i;
  986.         for (i=0; i<c; i++)
  987.             newline();
  988.         }
  989.         break;
  990.     case S_PAGELENGTH:
  991.         debug_state("S_PAGELENGTH",c);
  992.         if (c !=0) {
  993.             state = S_BASE;
  994.             ystop = c * line_space;
  995.             page_ystop = ystop;
  996.         }
  997.         else {
  998.             state = S_PAGEINCH;
  999.         }
  1000.         break;
  1001.     case S_PAGEINCH:
  1002.         debug_state("S_PAGEINCH",c);
  1003.         state = S_BASE;
  1004.         ystop = c * get_pointy(1);
  1005.         page_ystop = ystop;
  1006.         break;
  1007.     case S_BOTTOM:
  1008.         debug_state("S_BOTTOM",c);
  1009.         state = S_BASE;
  1010.         {
  1011.             int temp;
  1012.             temp = page_ystop - c * line_space;
  1013.             if (ystart + line_space < temp)
  1014.                 ystop = temp;
  1015.             else
  1016.                 invalid("<ESC> N n");
  1017.         }
  1018.         break;
  1019.     case S_TOP:
  1020.         debug_state("S_TOP",c);
  1021.         state = S_BASE;
  1022.         ystart = c * line_space + YSTART ;
  1023.         {
  1024.             int temp;
  1025.             temp = (c-1) * line_space + YSTART ;
  1026.             if (temp + line_space < ystop)
  1027.                 ystart = temp;
  1028.             else
  1029.                 invalid("<ESC> r n or <ESC> c n");
  1030.         }
  1031.         break;
  1032.     case S_RIGHT:
  1033.         debug_state("S_RIGHT",c);
  1034.         state = S_BASE;
  1035.         {
  1036.             int temp;
  1037.             temp =  c * point_sizex;
  1038.             if (xstart + point_sizex < temp)
  1039.                 xstop = temp;
  1040.             else
  1041.                 invalid("<ESC> Q n");
  1042.         }
  1043.         break;
  1044.     case S_LEFT:
  1045.         debug_state("S_LEFT",c);
  1046.         state = S_BASE;
  1047.         {
  1048.             int temp;
  1049.             temp = c * point_sizex;
  1050.             if (temp + point_sizex < xstop)
  1051.                 xstart = temp;
  1052.             else
  1053.                 invalid("<ESC> l n");
  1054.         }
  1055.         cx = xstart;
  1056.         break;
  1057.     case S_ABSOLUTE1:
  1058.         debug_state("S_ABSOLUTE1",c);
  1059.         state = S_ABSOLUTE2;
  1060.         dotposition = c;
  1061.         break;
  1062.     case S_ABSOLUTE2:
  1063.         debug_state("S_ABSOLUTE2",c);
  1064.         state = S_BASE;
  1065.         dotposition = (c*256 + dotposition) * get_pointx(60);
  1066.         if (dotposition < xstop)
  1067.             cx = dotposition;
  1068.         break;
  1069.     case S_RELATIVE1:
  1070.         debug_state("S_RELATIVE1",c);
  1071.         state = S_RELATIVE2;
  1072.         dotposition = c;
  1073.         break;
  1074.     case S_RELATIVE2:
  1075.         debug_state("S_RELATIVE2",c);
  1076.         state = S_BASE;
  1077.         dotposition = c*256 + dotposition;
  1078.         if ((unsigned int)dotposition > (unsigned int)32767) {
  1079.             dotposition = (int)(dotposition - 65536L);
  1080.         }
  1081.         if (lq_mode) {
  1082.             if (nlq_mode)
  1083.                 dotposition = dotposition * get_pointx(180);
  1084.             else
  1085.                 dotposition = dotposition * get_pointx(120);
  1086.             if (cx + dotposition < xstop)
  1087.                 cx += dotposition;
  1088.         }
  1089.         else
  1090.             invalid("<ESC> \\");
  1091.         break;
  1092.     case S_MACRO:
  1093.         debug_state("S_MACRO",c);
  1094.         if (c == 1) {
  1095.             state = S_BASE;
  1096.             for (mindex=0; macro[mindex]!=30; mindex++)
  1097.                 dochar((unsigned char)macro[mindex]);
  1098.             break;
  1099.         }
  1100.         else {
  1101.             state = S_SETMACRO;
  1102.             mindex = 0;
  1103.         }
  1104.         /* no break */
  1105.     case S_SETMACRO:
  1106.         debug_state("S_SETMACRO",c);
  1107.         if (mindex<MACROMAX)
  1108.             macro[mindex++] = c;
  1109.         if (c == 30) {
  1110.             macro[mindex] = c;
  1111.             state = S_BASE;
  1112.         }
  1113.         break;
  1114.     case S_IBM_MODE:
  1115.         debug_state("S_IBM_MODE",c);
  1116.         state = S_BASE;
  1117.         if (c == '\0' || c == '0')    ibm_graphic = 0;
  1118.         else if (c == '\1' || c == '1')    ibm_graphic = 1;
  1119.         else invalid("<ESC> t n");
  1120.         break;
  1121.     case S_INTERNATIONAL:
  1122.         debug_state("S_INTERNATIONAL",c);
  1123.         state = S_BASE;
  1124.         if (c > MAX_COUNTRY)
  1125.             invalid("<ESC> R n");
  1126.         else {
  1127.             country_num = c;
  1128.             fprintf(outfile,"%s InternationalSet\n",international[country_num]);
  1129.         }
  1130.         break;
  1131.     case S_LITERAL:
  1132.         debug_state("S_LITERAL",c);
  1133.         state = S_BASE;
  1134.         pchar(c);
  1135.         break;
  1136.     case S_LITERAL1:
  1137.         debug_state("S_LITERAL1",c);
  1138.         state = S_LITERAL2;
  1139.         lcount = c;
  1140.         break;
  1141.     case S_LITERAL2:
  1142.         debug_state("S_LITERAL2",c);
  1143.         state = S_LITERAL_COUNT;
  1144.         lcount = 256 * c + lcount;
  1145.         if (lcount == 0)
  1146.             state = S_BASE;
  1147.         break;
  1148.     case S_LITERAL_COUNT:
  1149.         debug_state("S_LITERAL_COUNT",c);
  1150.         pchar(c);
  1151.         lcount--;
  1152.         if (lcount == 0) {
  1153.             state = S_BASE;
  1154.         }
  1155.         break;
  1156.     case S_SCREENDUMP:
  1157.         debug_state("S_SCREENDUMP",c);
  1158.             /* recognise only \r and \n */
  1159.             switch(c) {
  1160.         case '\n':
  1161.             putline();
  1162.             newline();
  1163.             if (auto_cr)
  1164.                 cx = xstart;
  1165.             break;
  1166.         case '\r':
  1167.             putline();
  1168.             cx = xstart;
  1169.             if (auto_lf)
  1170.                 newline();
  1171.             break;
  1172.         default:
  1173.             pchar(c);
  1174.             break;
  1175.         }
  1176.         break;
  1177.     case S_GRAPHIC_MODE:
  1178.         debug_state("S_GRAPHIC_MODE",c);
  1179.         state = S_GRAPHIC1;
  1180.         if ( (c <= 6) || (c>=32 && c<=40) )
  1181.             g_mode = c;
  1182.         else
  1183.             invalid("<ESC> *");
  1184.         break;
  1185.     case S_GRAPHIC1:
  1186.         debug_state("S_GRAPHIC1",c);
  1187.         state = S_GRAPHIC2;
  1188.         gcount = c;
  1189.         if (g_mode >= 32) {
  1190.             g_dpi = g_dpi_table[g_mode-32];
  1191.             state = S_GRAPHIC24_2;
  1192.         }
  1193.         else {
  1194.             g_dpi = g_dpi_table[g_mode];
  1195.         }
  1196.         break;
  1197.     case S_GRAPHIC2:
  1198.         debug_state("S_GRAPHIC2",c);
  1199.         state = S_GRAPHIC;
  1200.         gcount = 256 * c + gcount ;
  1201.         if (gcount == 0) {
  1202.             state = S_BASE;
  1203.             break;
  1204.         }
  1205.         gwidth = (int)( (long)get_pointx(1)*gcount/g_dpi);
  1206.         if (lq_mode) {
  1207.             fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+6*get_pointy(180));
  1208.             fprintf(outfile,"%d %d scale\n", get_pointy(180)*24, gwidth);
  1209.         }
  1210.         else {
  1211.             fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+get_pointy(72));
  1212.             fprintf(outfile,"%d %d scale\n", get_pointy(72)*8, gwidth);
  1213.         }
  1214.         fprintf(outfile,"8 %d true [0 8 %d 0 0 8]", gcount, gcount);
  1215.         fprintf(outfile," {currentfile graphicbuf readhexstring pop} \nimagemask\n");
  1216.         cx += gwidth;
  1217.         break;
  1218.     case S_GRAPHIC:
  1219.         debug_state("S_GRAPHIC",c);
  1220.         hexout(c);
  1221.         gcount--;
  1222.         if ( (gcount & 0x1f) == 0 )
  1223.             (void)fputc('\n',outfile);
  1224.         if (gcount == 0) {
  1225.             fputs("grestore\n",outfile);
  1226.             state = S_BASE;
  1227.         }
  1228.         break;
  1229.     case S_DEF_GRAPHIC:
  1230.         debug_state("S_DEF_GRAPHIC",c);
  1231.         switch(c)
  1232.         {
  1233.         case 'K':
  1234.             state = S_DEF_K;
  1235.             break;
  1236.         case 'L':
  1237.             state = S_DEF_L;
  1238.             break;
  1239.         case 'Y':
  1240.             state = S_DEF_Y;
  1241.             break;
  1242.         case 'Z':
  1243.             state = S_DEF_Z;
  1244.             break;
  1245.         default:
  1246.             state = S_IGNORE1;
  1247.             invalid("ESC ? n0 n1");
  1248.             break;
  1249.         }
  1250.         break;
  1251.     case S_DEF_K:
  1252.         debug_state("S_DEF_K",c);
  1253.         state = S_BASE;
  1254.         if ( (c <= 6) || (c>=32 && c<=40) )
  1255.             g_mode_k = c;
  1256.         else
  1257.             invalid("<ESC> ? K n");
  1258.         break;
  1259.     case S_DEF_L:
  1260.         debug_state("S_DEF_L",c);
  1261.         state = S_BASE;
  1262.         if ( (c <= 6) || (c>=32 && c<=40) )
  1263.             g_mode_l = c;
  1264.         else
  1265.             invalid("<ESC> ? L n");
  1266.         break;
  1267.     case S_DEF_Y:
  1268.         debug_state("S_DEF_Y",c);
  1269.         state = S_BASE;
  1270.         if ( (c <= 6) || (c>=32 && c<=40) )
  1271.             g_mode_y = c;
  1272.         else
  1273.             invalid("<ESC> ? Y n");
  1274.         break;
  1275.     case S_DEF_Z:
  1276.         debug_state("S_DEF_Z",c);
  1277.         state = S_BASE;
  1278.         if ( (c<= 6) || (c>=32 && c<=40) )
  1279.             g_mode_z = c;
  1280.         else
  1281.             invalid("<ESC> ? Z n");
  1282.         break;
  1283.     case S_GRAPHIC9_MODE:
  1284.         debug_state("S_GRAPHIC9_MODE",c);
  1285.         state = S_GRAPHIC9_1;
  1286.         if (c > 6) {
  1287.             invalid("<ESC> ^");
  1288.             g_dpi = g_dpi_table[0];
  1289.         }
  1290.         else {
  1291.             g_dpi = g_dpi_table[c];
  1292.             g_mode = c;
  1293.         }
  1294.         break;
  1295.     case S_GRAPHIC9_1:
  1296.         debug_state("S_GRAPHIC9_1",c);
  1297.         state = S_GRAPHIC9_2;
  1298.         gcount = c;
  1299.         break;
  1300.     case S_GRAPHIC9_2:
  1301.         debug_state("S_GRAPHIC9_2",c);
  1302.         state = S_GRAPHIC9_TOP;
  1303.         gcount = 256 * c + gcount ;
  1304.         if (gcount == 0) {
  1305.             state = S_BASE;
  1306.             break;
  1307.         }
  1308.         gwidth = (int)( (long)get_pointx(1)*gcount/g_dpi);
  1309.         if (lq_mode) {
  1310.             invalid("<ESC> ^");
  1311.             fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+9*get_pointy(60));
  1312.             fprintf(outfile,"%d %d scale\n", get_pointy(60)*16, gwidth);
  1313.         }
  1314.         else {
  1315.             fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+9*get_pointy(72));
  1316.             fprintf(outfile,"%d %d scale\n", get_pointy(72)*16, gwidth);
  1317.         }
  1318.         fprintf(outfile,"16 %d true [0 16 %d 0 0 16]", gcount, gcount);
  1319.         fprintf(outfile," {currentfile graphicbuf readhexstring pop} \nimagemask\n");
  1320.         cx += gwidth;
  1321.         break;
  1322.     case S_GRAPHIC9_TOP:
  1323.         debug_state("S_GRAPHIC9_TOP",c);
  1324.         state = S_GRAPHIC9_BOTTOM;
  1325.         hexout(c);
  1326.         break;
  1327.     case S_GRAPHIC9_BOTTOM:
  1328.         debug_state("S_GRAPHIC9_BOTTOM",c);
  1329.         state = S_GRAPHIC9_TOP;
  1330.         c &= 0x80;
  1331.         hexout(c);
  1332.         gcount--;
  1333.         if ( (gcount & 0x0f) == 0 )
  1334.             (void)fputc('\n',outfile);
  1335.         if (gcount == 0) {
  1336.             fputs("grestore\n",outfile);
  1337.             state = S_BASE;
  1338.         }
  1339.         break;
  1340.     case S_GRAPHIC24_2:
  1341.         debug_state("S_GRAPHIC24_2",c);
  1342.         state = S_GRAPHIC24_TOP;
  1343.         gcount = 256 * c + gcount ;
  1344.         if (gcount == 0) {
  1345.             state = S_BASE;
  1346.             break;
  1347.         }
  1348.         gwidth = (int)( (long)get_pointx(1)*gcount/g_dpi);
  1349.         if (lq_mode) {
  1350.             fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+6*get_pointy(180));
  1351.             fprintf(outfile,"%d %d scale\n", get_pointy(180)*24, gwidth);
  1352.         }
  1353.         else {
  1354.             fprintf(outfile,"gsave\n%d %d translate\n",cx,cy+get_pointy(72));
  1355.             fprintf(outfile,"%d %d scale\n", get_pointy(72)*8, gwidth);
  1356.         }
  1357.         fprintf(outfile,"24 %d true [0 24 %d 0 0 24]", gcount, gcount);
  1358.         fprintf(outfile," {currentfile graphicbuf readhexstring pop} \nimagemask\n");
  1359.         cx += gwidth;
  1360.         break;
  1361.     case S_GRAPHIC24_TOP:
  1362.         debug_state("S_GRAPHIC24_TOP",c);
  1363.         state = S_GRAPHIC24_MIDDLE;
  1364.         hexout(c);
  1365.         break;
  1366.     case S_GRAPHIC24_MIDDLE:
  1367.         debug_state("S_GRAPHIC24_MIDDLE",c);
  1368.         state = S_GRAPHIC24_BOTTOM;
  1369.         hexout(c);
  1370.         break;
  1371.     case S_GRAPHIC24_BOTTOM:
  1372.         debug_state("S_GRAPHIC24_BOTTOM",c);
  1373.         state = S_GRAPHIC24_TOP;
  1374.         hexout(c);
  1375.         gcount--;
  1376.         if ( (gcount & 0x07) == 0 )
  1377.             (void)fputc('\n',outfile);
  1378.         if (gcount == 0) {
  1379.             fputs("grestore\n",outfile);
  1380.             state = S_BASE;
  1381.         }
  1382.         break;
  1383.     case S_ESC:
  1384.         debug_state("S_ESC",c);
  1385.         state = S_BASE;
  1386.         switch (c)
  1387.         {
  1388.         case '\n':    /* reverse line feed - Star NL-10 */
  1389.             cy -= line_space;
  1390.             break;
  1391.         case '\f':    /* reverse form feed - Star NL-10 */
  1392.             cy = ystart;
  1393.             break;
  1394.         case 14:    /* 0x0e - select one line expanded */
  1395.             oneline_doublewidth = 1;
  1396.             set_font();
  1397.             break;
  1398.         case 15:    /* select condensed */
  1399.             condensed = 1;
  1400.             set_font();
  1401.             break;
  1402.         case 25:    /* paper controls */
  1403.             ignore("<ESC> <EM> n");
  1404.             state = S_IGNORE1;
  1405.             break;
  1406.         case '!':    /* master print mode */
  1407.             state = S_MASTER;
  1408.             break;
  1409.         case '#':    /* accept eight bit */
  1410.             eight_bit = 0;
  1411.             break;
  1412.         case '$':    /* absolute dot position - LQ-800 */
  1413.             state = S_ABSOLUTE1;
  1414.             break;
  1415.         case '%':    /* select download character set */
  1416.             ignore("<ESC> % n");
  1417.             state = S_IGNORE1;
  1418.             break;
  1419.         case '*':    /* select graphic mode */
  1420.             state = S_GRAPHIC_MODE;
  1421.             break;
  1422.         case '+':    /* macro - Star NL-10 */
  1423.             state = S_MACRO;
  1424.             break;
  1425.         case '-':
  1426.             state = S_UNDERLINE;
  1427.             break;
  1428.         case '/':    /* select vertical tab channel */
  1429.             state = S_VTABCHANNEL;
  1430.             break;
  1431.         case '0':    /* set line spacing to 1/8 inch */
  1432.             line_space = get_pointy(8);
  1433.             break;
  1434.         case '1':    /* set line spacing to 7/72 inch */
  1435.             line_space = 7 * get_pointy(72);
  1436.             break;
  1437.         case '2':    /* set line spacing to 1/6 inch */
  1438.             line_space = get_pointy(6);
  1439.             break;
  1440.         case '3':    /* set line spacing to n/216 or n/180 inch */
  1441.             state = S_FINE_LINESPACE;
  1442.             break;
  1443.         case '4':
  1444.             italic = 1;
  1445.             set_font();
  1446.             break;
  1447.         case '5':
  1448.             italic = 0;
  1449.             set_font();
  1450.             break;
  1451.         case '6':    /* expand printable area */
  1452.             expand_print = 1;
  1453.             break;
  1454.         case '7':    /* cancels expand printable area */
  1455.             expand_print = 0;
  1456.             break;
  1457.         case '8':    /* disable paper-out detector */
  1458.             ignore("<ESC> 8");
  1459.             break;
  1460.         case '9':    /* enable paper-out detector */
  1461.             ignore("<ESC> 9");
  1462.             break;
  1463.         case ':':    /* copy ROM characters to user defined */
  1464.             state = S_IGNORE3;
  1465.             ignore("<ESC> :");
  1466.             break;
  1467.         case '<':
  1468.             if (lq_mode)
  1469.                 cx = 0; /* print head to home */
  1470.             else
  1471.                 /* select one line uni-directional printing */
  1472.                 ignore("<ESC> <");
  1473.             break;
  1474.         case '=':    /* set eighth bit to 0 */
  1475.             eight_bit = -1;
  1476.             break;
  1477.         case '>':    /* set eighth bit to 1 */
  1478.             eight_bit = 1;
  1479.             break;
  1480.         case '?':
  1481.             state = S_DEF_GRAPHIC;
  1482.             break;
  1483.         case '@':
  1484.             reset_printer();
  1485.             break;
  1486.         case 'A':
  1487.             state = S_LINESPACE;
  1488.             break;
  1489.         case 'B':
  1490.             state = S_SETVTAB1;
  1491.             vsettabchannel = 0;
  1492.             tabindex = 0;
  1493.             break;
  1494.         case 'C':
  1495.             state = S_PAGELENGTH;
  1496.             break;
  1497.         case 'D':
  1498.             state = S_SETTAB;
  1499.             tabindex = 0;
  1500.             break;
  1501.         case 'E':
  1502.             emphasize = 1;
  1503.             set_font();
  1504.             break;
  1505.         case 'F':
  1506.             emphasize = 0;
  1507.             set_font();
  1508.             break;
  1509.         case 'G':
  1510.             highlight = 1;
  1511.             set_font();
  1512.             break;
  1513.         case 'H':
  1514.             highlight = 0;
  1515.             set_font();
  1516.             break;
  1517.         case 'I':  /* allow use of characters 0x80-0x9f - Star NL-10 */
  1518.             state = S_IGNORE1;
  1519.             ignore("<ESC> I n");
  1520.             break;
  1521.         case 'J':
  1522.             state = S_LINEFEED;
  1523.             break;
  1524.         case 'K':
  1525.             state = S_GRAPHIC1;
  1526.             g_mode = g_mode_k;
  1527.             break;
  1528.         case 'L':
  1529.             state = S_GRAPHIC1;
  1530.             g_mode = g_mode_l;
  1531.             break;
  1532.         case 'M':
  1533.             elite = 1;
  1534.             fifteen = 0;
  1535.             set_font();
  1536.             break;
  1537.         case 'N':
  1538.             state = S_BOTTOM;
  1539.             break;
  1540.         case 'O':
  1541.             ystart = YSTART;
  1542.             ystop = page_ystop;
  1543.             break;
  1544.         case 'P':
  1545.             elite = 0;
  1546.             fifteen = 0;
  1547.             set_font();
  1548.             break;
  1549.         case 'Q':
  1550.             state = S_RIGHT;
  1551.             break;
  1552.         case 'R':    /* international character set */
  1553.             state = S_INTERNATIONAL;
  1554.             break;
  1555.         case 'S':
  1556.             state = S_SUBSCRIPT;
  1557.             break;
  1558.         case 'T':
  1559.             subscript = 0;
  1560.             break;
  1561.         case 'U':    /* unidirectional printint */
  1562.             state = S_IGNORE1;
  1563.             ignore("<ESC> U n");
  1564.             break;
  1565.         case 'W':
  1566.             state = S_DOUBLE;
  1567.             break;
  1568.         case 'Y':
  1569.             state = S_GRAPHIC1;
  1570.             g_mode = g_mode_y;
  1571.             break;
  1572.         case 'Z':
  1573.             state = S_GRAPHIC1;
  1574.             g_mode = g_mode_z;
  1575.             break;
  1576.         case '\\':
  1577.             if (lq_mode) 
  1578.                 /* relative dot position - LQ-800 */
  1579.                 state = S_RELATIVE1;
  1580.             else
  1581.                 if (ibm_graphic)
  1582.                     state = S_LITERAL1;
  1583.                 else
  1584.                     state = S_RELATIVE1;
  1585.             break;
  1586.         case '^':
  1587.             if (ibm_graphic)
  1588.                 state = S_LITERAL;    /* literal character */
  1589.             else
  1590.                 state = S_GRAPHIC9_MODE; /* 9 pin graphics */
  1591.             break;
  1592.         case 'a':    /* justification */
  1593.             state = S_IGNORE1;
  1594.             ignore("<ESC> a n");
  1595.             break;
  1596.         case 'b':
  1597.             state = S_VSETTABCHANNEL;
  1598.             tabindex = 0;
  1599.             break;
  1600.         case 'c':    /* top margin - Star NX-1000 */
  1601.             state = S_TOP;
  1602.             break;
  1603.         case 'e':
  1604.             state = S_TABINC;
  1605.             break;
  1606.         case 'f':
  1607.             state = S_SKIP;
  1608.             break;
  1609.         case 'g':    /* 15-pitch characters - LQ-800 */
  1610.             elite = 0;
  1611.             fifteen = 1;
  1612.             set_font();
  1613.             break;
  1614.         case 'h':    /* enlarge characters - Star NL-10 */
  1615.             state = S_ENLARGE;
  1616.             break;
  1617.         case 'i':    /* immediate print mode - Star NL-10 */
  1618.             state = S_IGNORE1;
  1619.             ignore("<ESC> i n");
  1620.             break;
  1621.         case 'j':    /* reverse line feed - Star NL-10 */
  1622.             state = S_REV_LINEFEED;
  1623.             break;
  1624.         case 'k':    /* select font family */
  1625.             state = S_IGNORE1;
  1626.             ignore("<ESC> k n");
  1627.             break;
  1628.         case 'l':
  1629.             state = S_LEFT;
  1630.             break;
  1631.         case 'm':    /* select special graphics */
  1632.             state = S_IGNORE1;
  1633.             ignore("<ESC> m n");
  1634.             break;
  1635.         case 'p':    /* proportional print - Star NL-10 */
  1636.             state = S_IGNORE1;
  1637.             ignore("<ESC> p n");
  1638.             break;
  1639.         case 'r':    /* top margin - Star NL-10 */
  1640.             state = S_TOP;
  1641.             break;
  1642.         case 's':    /* half speed */
  1643.             state = S_IGNORE1;
  1644.             ignore("<ESC> s n");
  1645.             break;
  1646.         case 't':    /* italic / graphics & international */
  1647.             state = S_IBM_MODE;
  1648.             break;
  1649.         case 'w':    /* double height characters - Star NX-1000 */
  1650.             state = S_DOUBLEHEIGHT;
  1651.             break;
  1652.         case 'x':    /* NLQ mode */
  1653.             state = S_NLQMODE;
  1654.             break;
  1655.         case '~':    /* slash zero - Star NL-10 */
  1656.             state = S_IGNORE1;
  1657.             ignore("<ESC> ~ n");
  1658.             break;
  1659.         default:
  1660.             if (debug)
  1661.                 fprintf(stderr,"Unknown sequence: <ESC> 0x%x\n",c);
  1662.             break;
  1663.         }
  1664.         break;
  1665.        case S_BASE:
  1666.         if (debug>=3)
  1667.             debug_state("S_BASE",c);
  1668.         if (!expand_print && c>=0x80 && c<=0x9f)
  1669.             c &= 0x7f;
  1670.         switch(c)
  1671.         {
  1672.         case 7:        /* bell (on stderr) */
  1673.             if (debug)
  1674.                 (void)fputc((char)c,stderr);
  1675.             break;
  1676.         case '\b':    /* back space */
  1677.             putline();
  1678.             cx -= point_sizex;
  1679.             break;
  1680.         case '\t':
  1681.             {
  1682.                 int i,l;
  1683.  
  1684.                 l = cx / point_sizex + ptr;
  1685.                 for (i = 0; i < NUM_TABS && tabs[i] <= l; i++)
  1686.                     ;
  1687.                 if (tabs[i] == -1) break;
  1688.                 i = tabs[i] - l;
  1689.                 while (i-- > 0) dochar(' ')
  1690.                     ;
  1691.             }
  1692.             break;
  1693.         case '\n': 
  1694.             putline();
  1695.             newline();
  1696.             if (auto_cr) {
  1697.                 cx = xstart;
  1698.                 if (oneline_doublewidth) {
  1699.                     oneline_doublewidth = 0;
  1700.                     set_font();
  1701.                 }
  1702.             }
  1703.             break;
  1704.         case 11:    /* vertical tab */
  1705.             putline();
  1706.             if (vtabs[vtabchannel][0] == 0)
  1707.                 newline();
  1708.             else {
  1709.                 int i,l;
  1710.                 l = cy / line_space;
  1711.                 for (i = 0; i < NUM_VTABS &&
  1712.                     vtabs[vtabchannel][i] <= l; i++) ;
  1713.                 if (vtabs[vtabchannel][i] == -1) {
  1714.                     eject_page();
  1715.                 }
  1716.                 else {
  1717.                     cy = vtabs[vtabchannel][i] * line_space
  1718.                         + YSTART;
  1719.                 }
  1720.             }
  1721.             break;
  1722.         case '\f':
  1723.             putline();
  1724.             eject_page();
  1725.             break;
  1726.         case '\r':
  1727.             putline();
  1728.             cx = xstart;
  1729.             if (oneline_doublewidth) {
  1730.                 oneline_doublewidth = 0;
  1731.                 set_font();
  1732.             }
  1733.             if (auto_lf)
  1734.                 newline();
  1735.             break;
  1736.         case 14:    /* 0x0e - select one line expanded */
  1737.             putline();
  1738.             oneline_doublewidth = 1;
  1739.             set_font();
  1740.             break;
  1741.         case 15:    /* 0x0f - select condensed */
  1742.             putline();
  1743.             condensed = 1;
  1744.             set_font();
  1745.             break;
  1746.         case 17:    /* 0x11 - set printer off line */
  1747.             ignore("<DC1>");
  1748.             break;
  1749.         case 18:    /* 0x12 - cancel condensed */
  1750.             putline();
  1751.             condensed = 0;
  1752.             set_font();
  1753.             break;
  1754.         case 19:    /* 0x11 - set printer on line */
  1755.             ignore("<DC3>");
  1756.             break;
  1757.         case 20:    /* 0x14 - cancel one line expanded */
  1758.             putline();
  1759.             oneline_doublewidth = 0;
  1760.             set_font();
  1761.             break;
  1762.         case 24:    /* 0x18 - cancel line */
  1763.             ignore("<CAN>");
  1764.             break;
  1765.         case 26:    /* CTRL-Z */
  1766.             break;
  1767.         case '\033':
  1768.             putline();
  1769.             state = S_ESC;
  1770.             break;
  1771.         case 127:    /* 0x7f - delete char */
  1772.             ignore("<DEL>");
  1773.             break;
  1774.         default:    /* print character */
  1775.             pchar(c);
  1776.             break;
  1777.         }
  1778.         break;
  1779.     }
  1780. }
  1781.  
  1782. void
  1783. init_printer(void)
  1784. {
  1785. unsigned int nbytes;
  1786.  
  1787.     maxx = page_formats[paper_type].nchars * get_pointx(PICA);
  1788.     maxy = page_formats[paper_type].nlines * get_pointy(FONTHEIGHT);
  1789.     line_space = get_pointy(FONTHEIGHT);
  1790.  
  1791.     if (left > page_formats[paper_type].nchars) {
  1792.         fprintf(stderr,"Left margin greater than right margin\n");
  1793.         exit(1);
  1794.     }
  1795.     xstart = left * get_pointx(PICA);
  1796.     xstop = maxx;
  1797.     ystart = YSTART;
  1798.     ystop = maxy;
  1799.     page_ystop = ystop;
  1800.  
  1801.     fputs("%!PS-Adobe-2.0\n",outfile);
  1802.     fprintf(outfile,"%%%%BoundingBox: 0 0 %d %d\n",
  1803.         page_formats[paper_type].urx, page_formats[paper_type].ury);
  1804.     fputs("%%Creator: epsonps.c\n",outfile);
  1805.     fputs("%%Pages: (atend)\n",outfile);
  1806.     fputs("%%EndComments\n",outfile);
  1807.     fputs("/saveobj1 save def\n",outfile);
  1808.     if (page_formats[paper_type].rotate) {
  1809.         fputs("90 rotate\n",outfile);
  1810.         fprintf(outfile,"%d %d translate\n",page_formats[paper_type].lly,
  1811.           -page_formats[paper_type].llx);
  1812.         fprintf(outfile,"%d %d div %d %d div scale\n",
  1813.           page_formats[paper_type].ury-page_formats[paper_type].lly, maxx,
  1814.           page_formats[paper_type].llx-page_formats[paper_type].urx, maxy);
  1815.     }
  1816.     else {
  1817.         fprintf(outfile,"%d %d translate\n",page_formats[paper_type].llx,
  1818.           page_formats[paper_type].ury);
  1819.         fprintf(outfile,"%d %d div %d %d div scale\n",
  1820.           page_formats[paper_type].urx-page_formats[paper_type].llx, maxx,
  1821.           page_formats[paper_type].lly-page_formats[paper_type].ury, maxy);
  1822.     }
  1823.  
  1824.     fprintf(outfile,"/xdpi %d def\n", get_pointx(1));
  1825.     fprintf(outfile,"/ydpi %d def\n", get_pointy(1));
  1826.     fputs("1.5 setlinewidth\nnewpath\n",outfile);
  1827.  
  1828.     /* send the header file */
  1829.     fputs("%%BeginProcSet: epsonps.pro\n",outfile);
  1830.     while (!feof(prologfile)) {
  1831.         nbytes = fread(buffer, sizeof(char), EPSONBUFSIZE,
  1832.             prologfile);
  1833.         (void)fwrite(buffer, sizeof(char), nbytes, outfile);
  1834.     }
  1835.     fputs("%%EndProcSet\n",outfile);
  1836.  
  1837.     fprintf(outfile,"%s InternationalSet\n",international[country_num]);
  1838.  
  1839.     fputs("%%%%EndProlog\n",outfile);
  1840.  
  1841.         if (screendump_mode) state = S_SCREENDUMP;
  1842.     init_tabs();    /* initialise tabs */
  1843.     macro[0] = 30;    /* initialise macro */
  1844.  
  1845.     page = 0;
  1846.     new_page();
  1847. }
  1848.  
  1849. void
  1850. set_option(option,value)
  1851. int *option;
  1852. char *value;
  1853. {
  1854.     if (*value == '\0')
  1855.         *option = !(*option);
  1856.     else
  1857.         *option = atoi(value);
  1858. }
  1859.  
  1860. void
  1861. usage(str)
  1862. char *str;
  1863. {
  1864.     fprintf(stderr,"Usage: %s [-L] [-R] [-c] [-d] [-e] [-lleft_margin]\n",
  1865.         progname);
  1866.     fprintf(stderr,"       [-ooutfile] [-q] [-s] [-tpaper_type] file\n");
  1867.     fprintf(stderr,"%s\n",str);
  1868.     exit(1);
  1869. }
  1870.  
  1871. int
  1872. main(argc,argv)
  1873. int argc;
  1874. char *argv[];
  1875. {
  1876.     int i,j;
  1877.     int ch;
  1878.     infile = (FILE *)NULL;
  1879.     outfile = stdout;
  1880.     progname = argv[0];
  1881.  
  1882.     for (i=1; i<argc; i++) {
  1883.         if (argv[i][0] == '-') {
  1884.         switch( argv[i][1] ) {
  1885.             case 'L':
  1886.                 set_option(&auto_lf,&argv[i][2]);
  1887.                 break;
  1888.             case 'R':
  1889.                 set_option(&auto_cr,&argv[i][2]);
  1890.                 break;
  1891.             case 'c':
  1892.                 set_option(&condensed,&argv[i][2]);
  1893.                 break;
  1894.             case 'd':
  1895.                 set_option(&debug,&argv[i][2]);
  1896.                 break;
  1897.             case 'e':
  1898.                 set_option(&elite,&argv[i][2]);
  1899.                 break;
  1900.             case 'l':
  1901.                 left = atoi(&argv[i][2]);
  1902.                 break;
  1903.             case 'o':
  1904.                 if ( argv[i][2] == '\0' )
  1905.                      usage("Need filename with -o option");
  1906.                 else if ( (outfile=fopen(&argv[i][2],"w")) 
  1907.                         == (FILE *)NULL ) {
  1908.                         fprintf(stderr,"Unable to open %s\n",
  1909.                     &argv[i][2]);
  1910.                     exit(1);
  1911.                 }
  1912.                 break;
  1913.             case 'q':
  1914.                 set_option(&lq_mode,&argv[i][2]);
  1915.                 break;
  1916.             case 's':
  1917.                 set_option(&screendump_mode,&argv[i][2]);
  1918.                 break;
  1919.             case 't':
  1920.               for (j=0; page_formats[j].name; j++) {
  1921.                 if (strcmp(&argv[i][2],page_formats[j].name)==0) {
  1922.                   paper_type = j;
  1923.                   break;
  1924.                 }
  1925.               }
  1926.               if (page_formats[j].name == (char *)NULL) {
  1927.                   (void)strcpy(outline,"Valid paper types are:");
  1928.                   for (j=0; page_formats[j].name; j++) {
  1929.                 (void)strcat(outline," ");
  1930.                 (void)strcat(outline,page_formats[j].name);
  1931.                   }
  1932.                   usage(outline);
  1933.               }
  1934.               break;
  1935.             default:
  1936.                 (void)strcpy(outline,"Unknown option ");
  1937.                 (void)strcat(outline,argv[i]);
  1938.                 usage(outline);
  1939.                 break;
  1940.         }
  1941.         }
  1942.         else {
  1943.             if ((infile = fopen(argv[i],READBIN)) == (FILE *)NULL)  {
  1944.             fprintf(stderr,"Unable to open %s\n",argv[i]);
  1945.             exit(1);
  1946.         }
  1947.         }
  1948.     }
  1949.  
  1950.     if (infile == (FILE *)NULL)
  1951.         usage("Need input filename");
  1952.  
  1953.     /* open the prolog file */
  1954.     if ((prologfile = fopen(prolog,"r")) == (FILE *)NULL)  {
  1955.         /* try in same directory as epsonps.exe */
  1956.         (void)strcpy(outline,argv[0]);
  1957.         for (i=strlen(outline); i>0; i--) {
  1958.             if (outline[i]=='\\' || outline[i]==':'
  1959.                 || outline[i]=='/' || outline[i]==']') {
  1960.                 (void)strcpy(&outline[i+1],prolog);
  1961.                     prologfile = fopen(outline,"r");
  1962.             break;
  1963.             }
  1964.         }
  1965.         if (prologfile == (FILE *)NULL) {
  1966.             fprintf(stderr,"Unable to open %s\n",prolog);
  1967.             exit(1);
  1968.         }
  1969.         }
  1970.  
  1971.     if ( (buffer=(char *)malloc(EPSONBUFSIZE)) == (char *)NULL ) {
  1972.         fprintf(stderr,"%s: Unable to allocate memory\n",progname);
  1973.         exit(1);
  1974.     }
  1975.  
  1976.     init_sets();
  1977.     init_printer();
  1978. #ifdef ANSI
  1979.     (void)setvbuf(infile,buffer,_IOFBF,EPSONBUFSIZE);
  1980. #endif
  1981.     while ( (ch=getc(infile)) != EOF)
  1982.         dochar((unsigned char)ch);
  1983.     if (ptr>0)
  1984.         putline();
  1985.     if (cx > xstart || cy > ystart)
  1986.         end_page();
  1987.     else {
  1988.         fputs("saveobj2 restore\n",outfile);
  1989.         page--;
  1990.     }
  1991.     fputs("%%Trailer\n",outfile);
  1992.     fprintf(outfile,"%%%%Pages: %d\n",page);
  1993.     fputs("saveobj1 restore\n",outfile);
  1994.     exit(0);
  1995.     return(0);
  1996. }
  1997. /* end of epsonps.c */
  1998.