130594Ssam #ifndef lint 230594Ssam static char Notice[] = "Copyright (c) 1984, 1985 Adobe Systems Incorporated"; 330594Ssam static char *RCSID="$Header: psdit.c,v 2.1 85/11/24 11:50:41 shore Rel $"; 430594Ssam #endif 5*30595Ssam # define XMOD 630594Ssam /* psdit.c 730594Ssam * 830594Ssam * Copyright (c) 1984, 1985 Adobe Systems Incorporated 930594Ssam * 1030594Ssam * ditroff intermediate file to PostScript translator 1130594Ssam * 1230594Ssam * Original Version: Barry Hayes spring/summer 1984 1330594Ssam * Edit History: 1430594Ssam * Andrew Shore: Sat Nov 23 20:05:26 1985 1530594Ssam * End Edit History. 1630594Ssam * 1730594Ssam * RCSLOG: 1830594Ssam * $Log: psdit.c,v $ 1930594Ssam * Revision 2.1 85/11/24 11:50:41 shore 2030594Ssam * Product Release 2.0 2130594Ssam * 2230594Ssam * Revision 1.8 85/11/23 20:09:44 shore 2330594Ssam * test for termination of included PostScript was bad 2430594Ssam * 2530594Ssam * Revision 1.7 85/11/21 14:23:56 shore 2630594Ssam * added envget check for PSLIBDIR 2730594Ssam * 2830594Ssam * Revision 1.6 85/11/20 00:43:43 shore 2930594Ssam * support for included PostScript 3030594Ssam * big rework on FlushShow, word "breaks" 3130594Ssam * removed FlushFont and made them instant 3230594Ssam * Still no Gremlin support yet 3330594Ssam * 3430594Ssam * Revision 1.5 85/10/03 10:48:09 shore 3530594Ssam * added FlushShow to xf fix ! 3630594Ssam * 3730594Ssam * Revision 1.4 85/10/02 16:20:32 shore 3830594Ssam * fixed xf bug 3930594Ssam * mounting a font causes a font switch! 4030594Ssam * 4130594Ssam * Revision 1.3 85/07/09 13:10:20 shore 4230594Ssam * added fclose on map file 4330594Ssam * 4430594Ssam * Revision 1.2 85/05/14 11:24:23 shore 4530594Ssam * added flush to trailer 4630594Ssam * fixed read bug when mounting fonts 4730594Ssam * 4830594Ssam * 4930594Ssam */ 5030594Ssam 5130594Ssam /* 5230594Ssam output language from troff: 5330594Ssam all numbers are character strings 5430594Ssam 5530594Ssam sn size in points 5630594Ssam fn font as number from 1-n 5730594Ssam cx ascii character x 5830594Ssam Cxyz funny char xyz. terminated by white space 5930594Ssam Hn go to absolute horizontal position n 6030594Ssam Vn go to absolute vertical position n (down is positive) 6130594Ssam hn go n units horizontally (relative) 6230594Ssam vn ditto vertically 6330594Ssam nnc move right nn, then print c (exactly 2 digits!) 6430594Ssam (this wart is an optimization that shrinks output file size 6530594Ssam about 35% and run-time about 15% while preserving ascii-ness) 6630594Ssam Dt ...\n draw operation 't': 6730594Ssam Dl x y line from here by x,y 6830594Ssam Dc d circle of diameter d with left side here 6930594Ssam De x y ellipse of axes x,y with left side here 7030594Ssam Da x y r arc counter-clockwise by x,y of radius r 7130594Ssam D~ x y x y ... wiggly line by x,y then x,y ... 7230594Ssam nb a end of line (information only -- no action needed) 7330594Ssam a = space before line, a = after 7430594Ssam w paddable word space -- no action needed 7530594Ssam pn new page begins -- set v to 0 7630594Ssam { push current environment (font info & location) 7730594Ssam } pop a saved environment 7830594Ssam txxxx print string xxxx using natural widths 7930594Ssam #...\n comment 8030594Ssam x ...\n device control functions: 8130594Ssam x i[nit] init 8230594Ssam x T s name of device is s 8330594Ssam x r[es] n h v resolution is n/inch 8430594Ssam h = min horizontal motion, v = min vert 8530594Ssam x p[ause] pause (can restart) 8630594Ssam x s[top] stop -- done for ever 8730594Ssam x t[railer] generate trailer 8830594Ssam x f[font] n s font position n contains font s 8930594Ssam x H[eight] n set character height to n 9030594Ssam x S[slant] n set slant to N 9130594Ssam 9230594Ssam Adobe Extension for included PostScript: 9330594Ssam % 9430594Ssam (raw postscript...) 9530594Ssam .\n 9630594Ssam 9730594Ssam */ 9830594Ssam 9930594Ssam #include <stdio.h> 10030594Ssam #include <ctype.h> 10130594Ssam #include <signal.h> 10230594Ssam #include <pwd.h> 10330594Ssam #ifdef SYSV 10430594Ssam extern struct passwd *getpwuid(); 10530594Ssam #endif 10630594Ssam #include "transcript.h" 10730594Ssam 10830594Ssam #include "dev.h" 10930594Ssam 11030594Ssam char *malloc(); 11130594Ssam 11230594Ssam #define NFONT 10 11330594Ssam 11430594Ssam /* DIT state consists of: */ 11530594Ssam private int hpos; /* current horizontal position */ 11630594Ssam private int vpos; /* current vertical position */ 11730594Ssam private int fontsize; /* current font size */ 11830594Ssam private int fontheight; /* current character height */ 11930594Ssam private int fontslant; /* current font slant */ 12030594Ssam private int font; /* current font */ 12130594Ssam private int resolution; /* device resolution */ 12230594Ssam private int minhoriz; /* minimum horizontal motion */ 12330594Ssam private int minvert; /* minimum vertical motion */ 12430594Ssam 12530594Ssam private int onspecial; 12630594Ssam private int specfont; 12730594Ssam private int prevfont; 12830594Ssam private int pfont; 12930594Ssam 13030594Ssam /* {} push/pop stack */ 13130594Ssam #define DSTACK 10 13230594Ssam private struct ditstack { 13330594Ssam int hpos, vpos, fontsize, fontheight, fontslant, font; 13430594Ssam } ditstack[DSTACK]; 13530594Ssam private int dlevel = 0; 13630594Ssam 13730594Ssam #define ErrorTolerance 48 13830594Ssam #define PSWID 0x00000FFF 13930594Ssam #define ISPSPROC 0x000FF000 14030594Ssam 14130594Ssam 14230594Ssam /* PSscale is equivalent to (x * PSmag / 72000) + 0.5 */ 14330594Ssam #define PSmag 16 14430594Ssam #define PSscale(x) (((x)+2250)/4500) 14530594Ssam 14630594Ssam /* we maintain PS coords with PSmag times the precision */ 14730594Ssam /* current PS state is: */ 14830594Ssam 14930594Ssam private int PSx; /* current horizontal position */ 15030594Ssam private int PSy; /* current vertical position */ 15130594Ssam private int savex, savey; /* position of start of current show string */ 15230594Ssam 15330594Ssam /* ps move types -- note that XMOVE|YMOVE == XYMOVE ! */ 15430594Ssam #define NONE 0 15530594Ssam #define XMOVE 1 15630594Ssam #define YMOVE 2 15730594Ssam #define XYMOVE 3 15830594Ssam 15930594Ssam private int movepending = NONE; 16030594Ssam 16130594Ssam /* buffer string for show -- save up adjacent chars */ 16230594Ssam #define SHOWSIZE 400 16330594Ssam private char showbuf[SHOWSIZE + 3]; /* extras are for quoting */ 16430594Ssam private int showind = 0; /* index into string of next available byte */ 16530594Ssam private int PSshowlen = 0; /* size in big units of buffered string */ 16630594Ssam private int nshow = 0; /* actual number of show chars in showbuf */ 16730594Ssam private int startx; /* troff starting pos of current string */ 16830594Ssam private int thisw; 16930594Ssam 17030594Ssam /* #define NONE 0 */ 17130594Ssam #define HMOT 1 17230594Ssam #define VMOT 2 17330594Ssam #define CPUT 4 17430594Ssam #define BRK 8 17530594Ssam #define FNT 16 17630594Ssam private int lastcmd; 17730594Ssam 17830594Ssam private int output = 0; /* do we do output at all? */ 17930594Ssam private int nolist = 0; /* output page list if > 0 */ 18030594Ssam private int olist[20]; /* pairs of page numbers */ 18130594Ssam private int spage = 9999; /* stop every spage pages */ 18230594Ssam private int scount = 0; 18330594Ssam private int stopped = 0; 18430594Ssam private int pageno = 0; 18530594Ssam private int firstpage = TRUE; 18630594Ssam 18730594Ssam private struct dev dev; 18830594Ssam private struct font *fontbase[NFONT+1]; 18930594Ssam private short *pstab; 19030594Ssam private int dres; /* resolution from DESC */ 19130594Ssam private int nsizes; /* number of point sizes from DESC */ 19230594Ssam private int nfonts; /* number of fonts from DESC */ 19330594Ssam private int smnt; /* index of first special font */ 19430594Ssam private int nchtab; 19530594Ssam private char *chname; 19630594Ssam private short *chtab; 19730594Ssam private char *fitab[NFONT+1]; 19830594Ssam private char *widthtab[NFONT+1]; /* widtab would be a better name */ 19930594Ssam private char *codetab[NFONT+1]; /* device codes */ 20030594Ssam 20130594Ssam private int *pswidths[NFONT+1]; /* ps width tables */ 20230594Ssam private int fontdelta[NFONT+1]; /* nonzero if xf overwrites font i */ 20330594Ssam 20430594Ssam /* font position info: */ 20530594Ssam private struct { 20630594Ssam char *name; 20730594Ssam int number; 20830594Ssam } fontname[NFONT+1]; 20930594Ssam 21030594Ssam #define FATAL 1 21130594Ssam #define BMASK 0377 21230594Ssam 21330594Ssam #ifdef DEBUG 21430594Ssam int dbg = 0; 21530594Ssam int fdbg = 0; 21630594Ssam #define debugp(xxx) {if(dbg != 0){dbg--; printf xxx ; VOIDC fflush(stdout);}} 21730594Ssam #else 21830594Ssam #define debugp(x) 21930594Ssam #endif 22030594Ssam 22130594Ssam private FILE *tf = stdout; /* output file */ 22230594Ssam private char devname[20] = "psc"; 22330594Ssam 22430594Ssam private char *infilename = "stdin"; /* input file name */ 22530594Ssam private char *prologfile = PSDITPRO; 22630594Ssam private char *ditdir = DitDir; 22730594Ssam 22830594Ssam private char *prog; /* argv[0] - program name */ 22930594Ssam 23030594Ssam main(argc, argv) 23130594Ssam int argc; 23230594Ssam char *argv[]; 23330594Ssam { 23430594Ssam FILE *fp; 23530594Ssam VOID done(); 23630594Ssam 23730594Ssam prog = argv[0]; 23830594Ssam while (argc > 1 && argv[1][0] == '-') { 23930594Ssam switch (argv[1][1]) { 24030594Ssam case 'f': 24130594Ssam case 'F': 24230594Ssam if (argv[1][2]) 24330594Ssam ditdir = &argv[1][2]; 24430594Ssam else { 24530594Ssam ditdir = argv[2]; 24630594Ssam argv++; 24730594Ssam argc--; 24830594Ssam } 24930594Ssam break; 25030594Ssam case 'p': 25130594Ssam if (argv[1][2]) 25230594Ssam prologfile = &argv[1][2]; 25330594Ssam break; 25430594Ssam case 'o': 25530594Ssam outlist (&argv[1][2]); 25630594Ssam break; 25730594Ssam case 'd': 25830594Ssam #ifdef DEBUG 25930594Ssam dbg = atoi (&argv[1][2]); 26030594Ssam if (dbg == 0) 26130594Ssam dbg = 1; 26230594Ssam tf = stdout; 26330594Ssam #endif DEBUG 26430594Ssam break; 26530594Ssam case 'b': /* ignore busy */ 26630594Ssam break; 26730594Ssam case 'w': /* ignore wait */ 26830594Ssam break; 26930594Ssam case 's': 27030594Ssam spage = atoi (&argv[1][2]); 27130594Ssam if (spage <= 0) 27230594Ssam spage = 9999; 27330594Ssam break; 27430594Ssam } 27530594Ssam argc--; 27630594Ssam argv++; 27730594Ssam } 27830594Ssam 27930594Ssam if (signal (SIGINT, done) == SIG_IGN) { 28030594Ssam signal (SIGINT, SIG_IGN); 28130594Ssam signal (SIGQUIT, SIG_IGN); 28230594Ssam signal (SIGHUP, SIG_IGN); 28330594Ssam } 28430594Ssam else { 28530594Ssam signal (SIGQUIT, done); 28630594Ssam signal (SIGHUP, done); 28730594Ssam } 28830594Ssam signal (SIGTERM, done); 28930594Ssam 29030594Ssam preface (); 29130594Ssam 29230594Ssam if (argc <= 1) 29330594Ssam conv (stdin); 29430594Ssam else 29530594Ssam while (--argc > 0) { 29630594Ssam if (strcmp (*++argv, "-") == 0) 29730594Ssam fp = stdin; 29830594Ssam else if ((fp = fopen (*argv, "r")) == NULL) { 29930594Ssam fprintf (stderr, "%s: can't open %s\n", prog, *argv); 30030594Ssam pexit(prog,2); 30130594Ssam } 30230594Ssam infilename = *argv; 30330594Ssam conv (fp); 30430594Ssam VOIDC fclose (fp); 30530594Ssam } 30630594Ssam done (); 30730594Ssam } 30830594Ssam 30930594Ssam private outlist(s) /* process list of page numbers to be printed */ 31030594Ssam char *s; 31130594Ssam { 31230594Ssam int n1, n2, i; 31330594Ssam 31430594Ssam nolist = 0; 31530594Ssam while (*s) { 31630594Ssam n1 = 0; 31730594Ssam if (isdigit (*s)) { 31830594Ssam do { 31930594Ssam n1 = 10 * n1 + *s++ - '0'; 32030594Ssam } 32130594Ssam while (isdigit (*s)); 32230594Ssam } 32330594Ssam else { 32430594Ssam n1 = -9999; 32530594Ssam } 32630594Ssam n2 = n1; 32730594Ssam if (*s == '-') { 32830594Ssam s++; 32930594Ssam n2 = 0; 33030594Ssam if (isdigit (*s)) { 33130594Ssam do { 33230594Ssam n2 = 10 * n2 + *s++ - '0'; 33330594Ssam } 33430594Ssam while (isdigit (*s)); 33530594Ssam } 33630594Ssam else { 33730594Ssam n2 = 9999; 33830594Ssam } 33930594Ssam } 34030594Ssam olist[nolist++] = n1; 34130594Ssam olist[nolist++] = n2; 34230594Ssam if (*s != '\0') { 34330594Ssam s++; 34430594Ssam } 34530594Ssam } 34630594Ssam olist[nolist] = 0; 34730594Ssam #ifdef DEBUG 34830594Ssam if (dbg) 34930594Ssam for (i = 0; i < nolist; i += 2) 35030594Ssam printf ("%3d %3d\n", olist[i], olist[i + 1]); 35130594Ssam #endif 35230594Ssam } 35330594Ssam 35430594Ssam private conv(fp) /* convert a file */ 35530594Ssam register FILE *fp; 35630594Ssam { 35730594Ssam register int c, k; 35830594Ssam int m, n, n1, m1; 35930594Ssam char str[100], buf[300]; 36030594Ssam 36130594Ssam while ((c = getc(fp)) != EOF) { 36230594Ssam switch (c) { 36330594Ssam case '\n': case ' ': case '\0': 36430594Ssam break; 36530594Ssam case '{': /* push down current environment */ 36630594Ssam t_push(); 36730594Ssam break; 36830594Ssam case '}': 36930594Ssam t_pop(); 37030594Ssam break; 37130594Ssam case '0': case '1': case '2': case '3': case '4': 37230594Ssam case '5': case '6': case '7': case '8': case '9': 37330594Ssam /* two motion digits plus a character */ 37430594Ssam hmot((c - '0') * 10 + getc (fp) - '0'); 37530594Ssam lastcmd = HMOT; 37630594Ssam put1(getc(fp), (char *) 0); 37730594Ssam lastcmd = CPUT; 37830594Ssam break; 37930594Ssam case 'c': /* single ascii character */ 38030594Ssam put1(getc(fp), (char *) 0); 38130594Ssam lastcmd = CPUT; 38230594Ssam break; 38330594Ssam case 'C': 38430594Ssam fscanf(fp, "%s", str); 38530594Ssam put1s(str); 38630594Ssam lastcmd = CPUT; 38730594Ssam break; 38830594Ssam case 't': /* straight text */ 38930594Ssam fgets(buf, sizeof (buf), fp); 39030594Ssam t_text (buf); 39130594Ssam lastcmd = CPUT; 39230594Ssam break; 39330594Ssam case 'D': /* draw function */ 39430594Ssam fgets(buf, sizeof (buf), fp); 39530594Ssam switch (buf[0]) { 39630594Ssam case 'l': /* draw a line */ 39730594Ssam sscanf (buf + 1, "%d %d", &n, &m); 39830594Ssam drawline (n, m); 39930594Ssam break; 40030594Ssam case 'c': /* circle */ 40130594Ssam sscanf (buf + 1, "%d", &n); 40230594Ssam drawcirc (n); 40330594Ssam break; 40430594Ssam case 'e': /* ellipse */ 40530594Ssam sscanf (buf + 1, "%d %d", &m, &n); 40630594Ssam drawellip (m, n); 40730594Ssam break; 40830594Ssam case 'a': /* arc */ 40930594Ssam sscanf (buf + 1, "%d %d %d %d", &n, &m, &n1, &m1); 41030594Ssam drawarc (n, m, n1, m1); 41130594Ssam break; 41230594Ssam case '~': /* wiggly line */ 41330594Ssam drawwig (buf + 1); 41430594Ssam break; 41530594Ssam default: 41630594Ssam fprintf(stderr,"%s: unknown drawing function %s\n", 41730594Ssam prog,buf); 41830594Ssam exit(2); 41930594Ssam break; 42030594Ssam } 42130594Ssam break; 42230594Ssam case 's': 42330594Ssam fscanf (fp, "%d", &n); 42430594Ssam t_size (n); 42530594Ssam lastcmd = FNT; 42630594Ssam break; 42730594Ssam case 'f': 42830594Ssam fscanf (fp, "%s", str); 42930594Ssam setfont (t_font (str)); 43030594Ssam lastcmd = FNT; 43130594Ssam break; 43230594Ssam case 'H': /* absolute horizontal motion */ 43330594Ssam while ((c = getc (fp)) == ' '); 43430594Ssam k = 0; 43530594Ssam do { 43630594Ssam k = 10 * k + c - '0'; 43730594Ssam } while (isdigit (c = getc (fp))); 43830594Ssam ungetc (c, fp); 43930594Ssam hgoto (k); 44030594Ssam lastcmd = HMOT; 44130594Ssam break; 44230594Ssam case 'h': /* relative horizontal motion */ 44330594Ssam while ((c = getc (fp)) == ' '); 44430594Ssam k = 0; 44530594Ssam do { 44630594Ssam k = 10 * k + c - '0'; 44730594Ssam } while (isdigit (c = getc (fp))); 44830594Ssam ungetc (c, fp); 44930594Ssam hmot (k); 45030594Ssam lastcmd = HMOT; 45130594Ssam break; 45230594Ssam case 'w': 45330594Ssam FlushShow(1); 45430594Ssam lastcmd = BRK; 45530594Ssam break; 45630594Ssam case 'V': 45730594Ssam fscanf (fp, "%d", &n); 45830594Ssam vgoto (n); 45930594Ssam lastcmd = VMOT; 46030594Ssam break; 46130594Ssam case 'v': 46230594Ssam fscanf (fp, "%d", &n); 46330594Ssam vmot (n); 46430594Ssam lastcmd = VMOT; 46530594Ssam break; 46630594Ssam case 'p': /* new page */ 46730594Ssam fscanf (fp, "%d", &n); 46830594Ssam t_page (n); 46930594Ssam lastcmd = NONE; 47030594Ssam break; 47130594Ssam case 'n': /* end of line -- ignore */ 47230594Ssam while (getc (fp) != '\n'); 47330594Ssam FlushShow(1); 47430594Ssam lastcmd = BRK; 47530594Ssam break; 47630594Ssam case '#': /* comment */ 47730594Ssam /* maybe should pass through as a PS comment */ 47830594Ssam while (getc (fp) != '\n'); 47930594Ssam break; 48030594Ssam case 'x': /* device control */ 48130594Ssam devcntrl (fp); 48230594Ssam break; 48330594Ssam case '%': /* imbedded PostScript */ 48430594Ssam /* copy everything up to but NOT including a line */ 48530594Ssam /* with at single "." */ 48630594Ssam FlushShow(0);MoveTo();DoMove(); 48730594Ssam printf("\n%% included PostScript\n"); 48830594Ssam while (fgets(buf, sizeof buf, fp) != NULL) { 48930594Ssam if (strcmp(".\n",buf) == 0) break; 49030594Ssam fputs(buf,stdout); 49130594Ssam } 49230594Ssam break; 49330594Ssam default: 49430594Ssam fprintf(stderr,"%s: bad input char \\%03o (%c)\n",prog,c,c); 49530594Ssam exit(2); 49630594Ssam done (); 49730594Ssam } 49830594Ssam } 49930594Ssam } 50030594Ssam 50130594Ssam 50230594Ssam /* put in PostScript prolog */ 50330594Ssam private preface() 50430594Ssam { 50530594Ssam register FILE *prolog; 50630594Ssam char hostname[256]; 50730594Ssam char tempfile[512]; 50830594Ssam struct passwd *pswd; 50930594Ssam long clock; 51030594Ssam char *libdir; 51130594Ssam 51230594Ssam fprintf (tf, "%%!%s\n", COMMENTVERSION); 51330594Ssam pswd = getpwuid (getuid ()); 51430594Ssam VOIDC gethostname (hostname, sizeof hostname); 51530594Ssam fprintf (tf, "%%%%Creator: %s:%s (%s)\n", hostname, 51630594Ssam pswd->pw_name, pswd->pw_gecos); 51730594Ssam fprintf (tf, "%%%%Title: %s (ditroff)\n", infilename); 51830594Ssam fprintf (tf, "%%%%CreationDate: %s", 51930594Ssam (time (&clock), ctime (&clock))); 52030594Ssam fprintf (tf, "%%%%EndComments\n"); 52130594Ssam 52230594Ssam if ((libdir = envget("PSLIBDIR")) == NULL) libdir = LibDir; 52330594Ssam mstrcat(tempfile, libdir, prologfile, sizeof tempfile); 52430594Ssam if ((copyfile(tempfile, stdout)) != 0) { 52530594Ssam fprintf(stderr,"%s: can't copy prolog file %s\n",prog, tempfile); 52630594Ssam exit(2); 52730594Ssam } 52830594Ssam printf ("ditstart\n"); 52930594Ssam } 53030594Ssam 53130594Ssam private devcntrl(fp) /* interpret device control functions */ 53230594Ssam FILE *fp; 53330594Ssam { 53430594Ssam char str[20], str1[50], buf[50]; 53530594Ssam int c, n, res, minh, minv; 53630594Ssam 53730594Ssam fscanf (fp, "%s", str); 53830594Ssam switch (str[0]) { /* crude for now */ 53930594Ssam case 'i': /* initialize */ 54030594Ssam fileinit (); 54130594Ssam t_init (); 54230594Ssam lastcmd = NONE; 54330594Ssam break; 54430594Ssam case 'T': /* device name */ 54530594Ssam fscanf (fp, "%s", devname); 54630594Ssam if (strcmp (devname, "psc")) { 54730594Ssam fprintf(stderr,"%s: device not psc\n",prog); 54830594Ssam exit(2); 54930594Ssam } 55030594Ssam printf ("(%s)xT\n", devname); 55130594Ssam lastcmd = NONE; 55230594Ssam break; 55330594Ssam case 't': /* trailer */ 55430594Ssam t_trailer (); 55530594Ssam lastcmd = NONE; 55630594Ssam break; 55730594Ssam case 'p': /* pause -- can restart */ 55830594Ssam t_reset ('p'); 55930594Ssam lastcmd = NONE; 56030594Ssam break; 56130594Ssam case 's': /* stop */ 56230594Ssam t_reset ('s'); 56330594Ssam lastcmd = NONE; 56430594Ssam break; 56530594Ssam case 'r': /* resolution assumed when prepared */ 56630594Ssam fscanf (fp, "%d %d %d", &res, &minh, &minv); 56730594Ssam t_res (res, minh, minv); 56830594Ssam lastcmd = NONE; 56930594Ssam break; 57030594Ssam case 'f': /* font used */ 57130594Ssam fscanf (fp, "%d %s", &n, str); 57230594Ssam fgets (buf, sizeof buf, fp);/* in case theres a filename */ 57330594Ssam ungetc ('\n', fp); /* fgets goes too far */ 57430594Ssam str1[0] = 0; /* in case there is nothing to come in */ 57530594Ssam sscanf (buf, "%s", str1); 57630594Ssam loadfont (n, str, str1); 57730594Ssam lastcmd = FNT; 57830594Ssam break; 57930594Ssam case 'H': /* char height */ 58030594Ssam fscanf (fp, "%d", &n); 58130594Ssam t_charht (n); 58230594Ssam lastcmd = FNT; 58330594Ssam break; 58430594Ssam case 'S': /* slant */ 58530594Ssam fscanf (fp, "%d", &n); 58630594Ssam t_slant (n); 58730594Ssam lastcmd = FNT; 58830594Ssam break; 589*30595Ssam #ifdef XMOD 590*30595Ssam case 'X': { /* \X command from ditroff */ 591*30595Ssam int last; 592*30595Ssam char largebuf[128]; 593*30595Ssam fscanf (fp, "%1s", str); 594*30595Ssam switch (str[0]) { 595*30595Ssam case 'p' : 596*30595Ssam FlushShow(0);MoveTo();DoMove(); 597*30595Ssam fgets(largebuf, sizeof(largebuf), fp); 598*30595Ssam last = strlen(largebuf) - 1; 599*30595Ssam if (last >= 0 && largebuf[last] == '\n') { 600*30595Ssam ungetc('\n', fp); 601*30595Ssam largebuf[last] = ' '; 602*30595Ssam } 603*30595Ssam fputs(largebuf, tf); 604*30595Ssam putc('\n', tf); 605*30595Ssam break; 606*30595Ssam case 'f' : 607*30595Ssam FlushShow(0);MoveTo();DoMove(); 608*30595Ssam if (fscanf(fp, "%s", largebuf) == 1) { 609*30595Ssam char *nl = (char *) index(largebuf, '\n'); 610*30595Ssam if (nl) *nl = '\0'; 611*30595Ssam includefile(largebuf); 612*30595Ssam } else 613*30595Ssam fprintf(stderr, "warning - include cmd w/o path.\n"); 614*30595Ssam break; 615*30595Ssam } 616*30595Ssam } 617*30595Ssam break; 618*30595Ssam #endif 61930594Ssam } 62030594Ssam /* skip rest of input line */ 62130594Ssam while ((c = getc (fp)) != '\n') {if (c == EOF) break;}; 62230594Ssam } 62330594Ssam 624*30595Ssam #ifdef XMOD 625*30595Ssam includefile(filenm) 626*30595Ssam char *filenm; { 627*30595Ssam 628*30595Ssam FILE *inf; 629*30595Ssam int ch, c1, c2, firstch = 0; 630*30595Ssam 631*30595Ssam if (!(inf = fopen(filenm, "r"))) { 632*30595Ssam fprintf(stderr, "psdit: fopen(%s): ", filenm); 633*30595Ssam perror(); 634*30595Ssam exit(1); 635*30595Ssam } 636*30595Ssam c1 = fgetc(inf); c2 = fgetc(inf); 637*30595Ssam if (c1 != '%' || c2 != '!') 638*30595Ssam fprintf(stderr, "psdit: %s not a postscript file.\n", filenm), 639*30595Ssam exit(1); 640*30595Ssam 641*30595Ssam fputs("%!", tf); 642*30595Ssam while ((ch = fgetc(inf)) != EOF) { 643*30595Ssam fputc(ch, tf); 644*30595Ssam if (firstch && ch == '%') { 645*30595Ssam /* we have to double leading '%'s */ 646*30595Ssam fputc('%', tf); 647*30595Ssam } 648*30595Ssam firstch = (ch == '\n'); 649*30595Ssam } 650*30595Ssam fclose(inf); 651*30595Ssam } 652*30595Ssam #endif 65330594Ssam private fileinit() /* read in font and code files, etc. */ 65430594Ssam { 65530594Ssam int i, fin, nw; 65630594Ssam char *filebase, *p; 65730594Ssam char temp[60]; 65830594Ssam unsigned msize; 65930594Ssam 66030594Ssam /* open table for device, 66130594Ssam * read in resolution, size info, font info, etc. and set params */ 66230594Ssam 66330594Ssam sprintf (temp, "%s/dev%s/DESC.out", ditdir, devname); 66430594Ssam if ((fin = open (temp, 0)) < 0) { 66530594Ssam fprintf (stderr, "%s: can't open %s - %s\n", prog, devname, temp); 66630594Ssam pexit(prog,2); 66730594Ssam } 66830594Ssam if (read(fin,(char *)&dev, (int) sizeof(struct dev)) != sizeof(struct dev)) { 66930594Ssam fprintf (stderr, "%s: can't read %s\n", prog, temp); 67030594Ssam pexit(prog,2); 67130594Ssam } 67230594Ssam dres = dev.res; 67330594Ssam nfonts = dev.nfonts; 67430594Ssam nsizes = dev.nsizes; 67530594Ssam nchtab = dev.nchtab; 67630594Ssam /* enough room for whole file */ 67730594Ssam filebase = malloc ((unsigned) dev.filesize); 67830594Ssam if (read (fin, filebase, dev.filesize) != dev.filesize) { 67930594Ssam fprintf (stderr, "%s: trouble reading %s\n", prog, temp); 68030594Ssam pexit(prog,2); 68130594Ssam } 68230594Ssam pstab = (short *) filebase; /* point size table */ 68330594Ssam chtab = pstab + nsizes + 1; /* char index table */ 68430594Ssam chname = (char *) (chtab + dev.nchtab); /* char name table */ 68530594Ssam p = chname + dev.lchname; /* end of char name table */ 68630594Ssam /* parse the preloaded font tables */ 68730594Ssam for (i = 1; i <= nfonts; i++) { 68830594Ssam fontdelta[i] = 0; 68930594Ssam fontbase[i] = (struct font *) p; 69030594Ssam nw = *p & BMASK; /* number of width entries */ 69130594Ssam if ((smnt == 0) && (fontbase[i]->specfont == 1)) 69230594Ssam smnt = i; /* first special font */ 69330594Ssam p += sizeof (struct font); /* skip header */ 69430594Ssam widthtab[i] = p; /* width table */ 69530594Ssam /* kern table is next */ 69630594Ssam codetab[i] = p + 2 * nw; /* device codes */ 69730594Ssam fitab[i] = p + 3 * nw; /* font index table */ 69830594Ssam 69930594Ssam p += 3 * nw + dev.nchtab + (128 - 32); /* next font */ 70030594Ssam t_fp (i, fontbase[i]->namefont, fontbase[i]->intname); 70130594Ssam loadpswidths (i, fontbase[i]->namefont); 70230594Ssam sayload (i, fontbase[i]->namefont, (char *) 0); 70330594Ssam #ifdef DEBUG 70430594Ssam if (fdbg > 1) 70530594Ssam fontprint (i); 70630594Ssam #endif 70730594Ssam } 70830594Ssam fontdelta[0] = 0; 70930594Ssam msize = 3*255 + dev.nchtab + (128-32) + sizeof (struct font); 71030594Ssam fontbase[0] = (struct font *) malloc(msize); 71130594Ssam widthtab[0] = (char *) fontbase[0] + sizeof (struct font); 71230594Ssam fontbase[0]->nwfont = 255; 71330594Ssam close (fin); 71430594Ssam } 71530594Ssam 71630594Ssam private loadpswidths(i,name) 71730594Ssam int i; 71830594Ssam char *name; 71930594Ssam { 72030594Ssam char temp[60]; 72130594Ssam register FILE *auxin; 72230594Ssam register int j; 72330594Ssam int cc, wid, funny; 72430594Ssam 72530594Ssam sprintf(temp, "%s/dev%s/%s.aux", ditdir, devname, name); 72630594Ssam auxin = fopen(temp, "r"); 72730594Ssam /* allocate table */ 72830594Ssam if (pswidths[i] == NULL) { 72930594Ssam pswidths[i] = (int *) malloc(256 * (sizeof (int))); 73030594Ssam } 73130594Ssam /* initialize to not-there */ 73230594Ssam for (j = 0; j <= 255; pswidths[i][j++] = -1); 73330594Ssam /* read them in */ 73430594Ssam while (fscanf(auxin, "%d %d %d", &cc, &wid, &funny) != EOF) { 73530594Ssam pswidths[i][cc] = wid | (funny << 12); 73630594Ssam } 73730594Ssam VOIDC fclose(auxin); 73830594Ssam } 73930594Ssam 74030594Ssam #ifdef DEBUG 74130594Ssam private fontprint(i) /* debugging print of font i (0,...) */ 74230594Ssam int i; 74330594Ssam { 74430594Ssam int j, n; 74530594Ssam char *p; 74630594Ssam 74730594Ssam printf ("font %d:\n", i); 74830594Ssam p = (char *) fontbase[i]; 74930594Ssam n = fontbase[i]->nwfont & BMASK; 75030594Ssam printf ("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n", 75130594Ssam p, n, fontbase[i]->specfont, 75230594Ssam fontbase[i]->namefont, widthtab[i], fitab[i]); 75330594Ssam printf ("widths:\n"); 75430594Ssam for (j = 0; j <= n; j++) { 75530594Ssam printf (" %2d", widthtab[i][j] & BMASK); 75630594Ssam if (j % 20 == 19) 75730594Ssam printf ("\n"); 75830594Ssam } 75930594Ssam printf ("\ncodetab:\n"); 76030594Ssam for (j = 0; j <= n; j++) { 76130594Ssam printf (" %2d", codetab[i][j] & BMASK); 76230594Ssam if (j % 20 == 19) 76330594Ssam printf ("\n"); 76430594Ssam } 76530594Ssam printf ("\nfitab:\n"); 76630594Ssam for (j = 0; j <= dev.nchtab + 128 - 32; j++) { 76730594Ssam printf (" %2d", fitab[i][j] & BMASK); 76830594Ssam if (j % 20 == 19) 76930594Ssam printf ("\n"); 77030594Ssam } 77130594Ssam printf ("\n"); 77230594Ssam } 77330594Ssam #endif 77430594Ssam 77530594Ssam private loadfont(n, s, s1) /* load font info for font s on position n */ 77630594Ssam int n; 77730594Ssam char *s, *s1; 77830594Ssam { 77930594Ssam char temp[60]; 78030594Ssam int fin, nw, norig; 78130594Ssam int bcount; 78230594Ssam 78330594Ssam if (n < 0 || n > NFONT) { 78430594Ssam fprintf(stderr,"%s: illegal fp command %d %s\n", prog, n, s); 78530594Ssam exit(2); 78630594Ssam } 78730594Ssam if (strcmp(s, fontbase[n]->namefont) == 0) return; 78830594Ssam if (fontbase[n]->namefont != 0) { 78930594Ssam fontdelta[n] = 1; 79030594Ssam } 79130594Ssam if (s1 == NULL || s1[0] == '\0') { 79230594Ssam sprintf (temp, "%s/dev%s/%s.out", ditdir, devname, s); 79330594Ssam } 79430594Ssam else { 79530594Ssam sprintf (temp, "%s/%s.out", s1, s); 79630594Ssam } 79730594Ssam if ((fin = open (temp, 0)) < 0) { 79830594Ssam fprintf(stderr,"%s: can't open font table %s\n", prog, temp); 79930594Ssam pexit(prog,2); 80030594Ssam } 80130594Ssam norig = fontbase[n]->nwfont & BMASK; 80230594Ssam bcount = 3 * norig + nchtab + 128 - 32 + sizeof (struct font); 80330594Ssam VOIDC read (fin, (char *)fontbase[n], bcount); 80430594Ssam if ((fontbase[n]->nwfont & BMASK) > norig) { 80530594Ssam fprintf(stderr,"%s: Font %s too big for position %d\n", prog, s, n); 80630594Ssam exit(2); 80730594Ssam } 80830594Ssam close (fin); 80930594Ssam nw = fontbase[n]->nwfont & BMASK; 81030594Ssam widthtab[n] = (char *) fontbase[n] + sizeof (struct font); 81130594Ssam codetab[n] = (char *) widthtab[n] + 2 * nw; 81230594Ssam fitab[n] = (char *) widthtab[n] + 3 * nw; 81330594Ssam t_fp (n, fontbase[n]->namefont, fontbase[n]->intname); 81430594Ssam loadpswidths (n, fontbase[n]->namefont); 81530594Ssam sayload (n, s, s1); 81630594Ssam fontbase[n]->nwfont = norig; /* so can later use full original size */ 81730594Ssam #ifdef DEBUG 81830594Ssam if (fdbg > 1) 81930594Ssam fontprint (n); 82030594Ssam #endif 82130594Ssam } 82230594Ssam 82330594Ssam private sayload(n, s, s1) /* position n contains font s (internal s1) */ 82430594Ssam int n; 82530594Ssam char *s, *s1; 82630594Ssam { 82730594Ssam char pass[60]; 82830594Ssam FILE *ptrfile; 82930594Ssam char Adobefont[60]; 83030594Ssam 83130594Ssam if (s1 == NULL || s1[0] == '\0') { 83230594Ssam sprintf (pass, "%s/dev%s/%s.map", ditdir, devname, s); 83330594Ssam } 83430594Ssam else { 83530594Ssam sprintf (pass, "%s/%s.map", s1, s); 83630594Ssam } 83730594Ssam 83830594Ssam if ((ptrfile = fopen (pass, "r")) == NULL) { 83930594Ssam fprintf(stderr,"%s: can't open font map file %s\n", prog, pass); 84030594Ssam pexit(prog,2); 84130594Ssam } 84230594Ssam 84330594Ssam fscanf (ptrfile, "%s", Adobefont); 84430594Ssam FlushShow(0); 84530594Ssam printf ("%d(%s)xf %d f\n", n, Adobefont, n); 84630594Ssam font = n; 84730594Ssam VOIDC fclose(ptrfile); 84830594Ssam } 84930594Ssam 85030594Ssam private VOID done() 85130594Ssam { 85230594Ssam if (tf == NULL) 85330594Ssam exit (1); 85430594Ssam t_reset ('s'); 85530594Ssam exit (0); 85630594Ssam } 85730594Ssam 85830594Ssam private t_init() /* "x i" - initialize device */ 85930594Ssam { 86030594Ssam movepending = NONE; 86130594Ssam savex = savey = 0; 86230594Ssam 86330594Ssam t_size (10); /* start somewhere */ 86430594Ssam t_slant (0); 86530594Ssam setfont (1); /* set font */ 86630594Ssam printf("xi\n"); 86730594Ssam printf("%%%%EndProlog\n"); 86830594Ssam } 86930594Ssam 87030594Ssam private t_push() /* begin a new block */ 87130594Ssam { 87230594Ssam FlushShow(1);MoveTo();DoMove(); 87330594Ssam if (dlevel == DSTACK) { 87430594Ssam fprintf(stderr,"%s: ditroff push/pop overflow!\n",prog); 87530594Ssam exit(2); 87630594Ssam } 87730594Ssam ditstack[dlevel].hpos = hpos; 87830594Ssam ditstack[dlevel].vpos = vpos; 87930594Ssam ditstack[dlevel].fontsize = fontsize; 88030594Ssam ditstack[dlevel].fontheight = fontheight; 88130594Ssam ditstack[dlevel].fontslant = fontslant; 88230594Ssam ditstack[dlevel].font = font; 88330594Ssam dlevel++; 88430594Ssam printf ("\nditpush\n"); 88530594Ssam } 88630594Ssam 88730594Ssam private t_pop() /* pop to previous state */ 88830594Ssam { 88930594Ssam FlushShow(1);MoveTo();DoMove(); 89030594Ssam if (dlevel == 0) { 89130594Ssam fprintf(stderr,"%s: ditroff push/pop underflow!\n",prog); 89230594Ssam exit(2); 89330594Ssam } 89430594Ssam dlevel--; 89530594Ssam hpos = ditstack[dlevel].hpos; 89630594Ssam vpos = ditstack[dlevel].vpos; 89730594Ssam fontsize = ditstack[dlevel].fontsize; 89830594Ssam fontheight = ditstack[dlevel].fontheight; 89930594Ssam fontslant = ditstack[dlevel].fontslant; 90030594Ssam font = ditstack[dlevel].font; 90130594Ssam printf ("%d s %d xH %d xS %d f\n",fontsize,fontheight,fontslant,font); 90230594Ssam startx = savex = hpos; 90330594Ssam savey = vpos; 90430594Ssam PSx = hpos * PSmag; 90530594Ssam PSy = vpos * PSmag; 90630594Ssam printf("%d %d MXY\n",savex,savey); 90730594Ssam movepending = NONE; 90830594Ssam printf("\nditpop\n"); 90930594Ssam } 91030594Ssam 91130594Ssam private t_page(n) /* do whatever new page functions */ 91230594Ssam { 91330594Ssam int i; 91430594Ssam 91530594Ssam if (output) { 91630594Ssam if (++scount >= spage) { 91730594Ssam t_reset ('p'); 91830594Ssam scount = 0; 91930594Ssam } 92030594Ssam } 92130594Ssam output = 1; 92230594Ssam FlushShow(0); 92330594Ssam if (!firstpage) { 92430594Ssam printf("\n%d p",n); 92530594Ssam } 92630594Ssam firstpage = FALSE; 92730594Ssam printf ("\n%%%%Page: %d %d\n", n, ++pageno, n); 92830594Ssam for (i = 0; i <= nfonts; i++) { 92930594Ssam if (fontdelta[i] != 0) { 93030594Ssam sayload (i, fontname[i].name, (char *) 0); 93130594Ssam } 93230594Ssam } 93330594Ssam vpos = 0; 93430594Ssam PSy = 0; 93530594Ssam printf ("%d s %d xH %d xS %d f\n",fontsize,fontheight,fontslant,font); 93630594Ssam if (nolist == 0) 93730594Ssam return; 93830594Ssam output = 0; 93930594Ssam for (i = 0; i < nolist; i += 2) 94030594Ssam if (n >= olist[i] && n <= olist[i + 1]) { 94130594Ssam output = 1; 94230594Ssam break; 94330594Ssam } 94430594Ssam } 94530594Ssam 94630594Ssam private t_size(n) /* convert integer to internal size number*/ 94730594Ssam int n; 94830594Ssam { 94930594Ssam FlushShow(1); 95030594Ssam if (fontsize != n) { 95130594Ssam fontsize = n; 952*30595Ssam #ifdef XMOD 953*30595Ssam fontheight = n; 954*30595Ssam #endif 95530594Ssam printf("%d s\n",fontsize); 95630594Ssam } 95730594Ssam } 95830594Ssam 95930594Ssam private t_charht(n) /* set character height to n */ 96030594Ssam int n; 96130594Ssam { 96230594Ssam FlushShow(1); 96330594Ssam if (fontheight != n) { 96430594Ssam fontheight = n; 96530594Ssam printf("%d xH\n",fontheight); 96630594Ssam } 96730594Ssam } 96830594Ssam 96930594Ssam private t_slant(n) /* set slant to n */ 97030594Ssam int n; 97130594Ssam { 97230594Ssam FlushShow(1); 97330594Ssam if (fontslant != n) { 97430594Ssam fontslant = n; 97530594Ssam printf("%d xS\n",fontslant); 97630594Ssam } 97730594Ssam } 97830594Ssam 97930594Ssam private t_font(s) /* convert string to internal font number */ 98030594Ssam char *s; 98130594Ssam { 98230594Ssam int n; 98330594Ssam 98430594Ssam n = atoi (s); 98530594Ssam if (n < 0 || n > nfonts) n = 1; 98630594Ssam return (n); 98730594Ssam } 98830594Ssam 98930594Ssam private t_text(s) /* print string s as text??? */ 99030594Ssam char *s; 99130594Ssam { 99230594Ssam fprintf(stderr,"%s: ditroff t <%s> unimplemented!\n",prog,s); 99330594Ssam } 99430594Ssam 99530594Ssam private t_reset(c) 99630594Ssam { 99730594Ssam output = 1; /* by God */ 99830594Ssam if (c == 'p') { 99930594Ssam printf ("\nxp\n"); 100030594Ssam } 100130594Ssam else { 100230594Ssam if (!stopped) 100330594Ssam printf ("\nxs\n"); 100430594Ssam stopped = 1; 100530594Ssam } 100630594Ssam fflush (tf); 100730594Ssam } 100830594Ssam 100930594Ssam private t_res(res, minh, minv) 101030594Ssam int res, minh, minv; 101130594Ssam { 101230594Ssam resolution = res; 101330594Ssam minhoriz = minh; 101430594Ssam minvert = minv; 101530594Ssam printf ("%d %d %d xr\n", res, minh, minv); 101630594Ssam } 101730594Ssam 101830594Ssam private t_trailer() 101930594Ssam { 102030594Ssam FlushShow(0); 102130594Ssam printf("\n%d p",pageno); 102230594Ssam printf("\n%%%%Trailer\n"); 102330594Ssam printf("xt\n"); 102430594Ssam } 102530594Ssam 102630594Ssam private put1s(s) /* s is a funny char name */ 102730594Ssam char *s; 102830594Ssam { 102930594Ssam int i; 103030594Ssam 103130594Ssam if (!output) return; 103230594Ssam debugp(("%s ", s)); 103330594Ssam 103430594Ssam /* search for s in the funny char name table */ 103530594Ssam for (i = 0; i < nchtab; i++) { 103630594Ssam if (strcmp(&chname[chtab[i]], s) == 0) break; 103730594Ssam } 103830594Ssam 103930594Ssam if (i < nchtab) { 104030594Ssam put1(i + 128, s); 104130594Ssam } 104230594Ssam else { 104330594Ssam debugp(("not found ")); 104430594Ssam putnf (0, s); 104530594Ssam } 104630594Ssam } 104730594Ssam 104830594Ssam #define needsescape(c) ((c=='\\') || (c=='(') || (c==')')) 104930594Ssam 105030594Ssam private put1(c, s) /* output char c */ 105130594Ssam int c; 105230594Ssam char *s; 105330594Ssam { 105430594Ssam char *pw; 105530594Ssam register char *p; 105630594Ssam register int i, k; 105730594Ssam register int cc; 105830594Ssam int ofont, code; 105930594Ssam int psinfo, pswid, tw; 106030594Ssam 106130594Ssam if (!output) return; 106230594Ssam if (c == 32) { 106330594Ssam thisw = 0; 106430594Ssam FlushShow(0); 106530594Ssam return; 106630594Ssam } 106730594Ssam if (c < 32) { 106830594Ssam debugp(("non-exist 0%o\n",c)); 106930594Ssam return; 107030594Ssam } 107130594Ssam 107230594Ssam c -= 32; /* offset char code */ 107330594Ssam k = ofont = pfont = font; 107430594Ssam if (onspecial) pfont = prevfont; 107530594Ssam 107630594Ssam if ((i = (fitab[pfont][c] & BMASK)) != 0) {/* char on this font */ 107730594Ssam p = codetab[pfont]; 107830594Ssam pw = widthtab[pfont]; 107930594Ssam if (onspecial) { 108030594Ssam setfont(prevfont); 108130594Ssam thisw = 0; 108230594Ssam onspecial = 0; 108330594Ssam } 108430594Ssam } 108530594Ssam else if (smnt > 0) { /* on special (we hope) */ 108630594Ssam for (k = smnt; k <= nfonts; k += 1) 108730594Ssam if ((i = (fitab[k][c] & BMASK)) != 0) { 108830594Ssam p = codetab[k]; 108930594Ssam pw = widthtab[k]; 109030594Ssam prevfont = pfont; 109130594Ssam if (onspecial && (k == specfont)) break; 109230594Ssam setfont (k); 109330594Ssam thisw = 0; 109430594Ssam onspecial = 1; 109530594Ssam specfont = k; 109630594Ssam break; 109730594Ssam } 109830594Ssam } 109930594Ssam if ((i == 0) || (k > nfonts) || ((code = p[i] & BMASK) == 0)) { 110030594Ssam debugp(("not found 0%o\n", c+32)); 110130594Ssam putnf (c + 32, s); 110230594Ssam return; 110330594Ssam } 110430594Ssam /* when we get here, 110530594Ssam * c == biased character code 110630594Ssam * k == font number 110730594Ssam * i == index into codetab and widthtab for this character 110830594Ssam * p == codetab for this font 110930594Ssam * pw == width tab for this font 111030594Ssam * code == character code for this char 111130594Ssam */ 111230594Ssam 111330594Ssam cc = c + 32; 111430594Ssam debugp(((isascii(cc) && isprint(cc)) ? "%c %d\n":"%03o %d\n", 111530594Ssam cc, code)); 111630594Ssam psinfo = pswidths[font][code]; /* PS specific char info */ 111730594Ssam pswid = psinfo & PSWID; /* PS character width */ 111830594Ssam thisw = pw[i] & BMASK; /* troff char width */ 111930594Ssam tw = thisw = (thisw * fontsize + dev.unitwidth/2) / dev.unitwidth; 112030594Ssam 112130594Ssam if ((psinfo & ISPSPROC) && (psinfo != -1)) { 112230594Ssam /* character is implemented by a PostScript proc */ 112330594Ssam showspecial(s, code, pswid); 112430594Ssam if (pswid > 0) { 112530594Ssam PSx += PSscale(pswid * fontsize * dres); 112630594Ssam } 112730594Ssam thisw = 0; 112830594Ssam } 112930594Ssam else { 113030594Ssam showchar(code); 113130594Ssam if (pswid > 0) { 113230594Ssam PSshowlen += PSscale(pswid * fontsize * dres); 113330594Ssam } 113430594Ssam } 113530594Ssam 113630594Ssam /* 113730594Ssam if (font != ofont) { 113830594Ssam setfont(ofont); 113930594Ssam startx = hpos + tw; 114030594Ssam thisw = 0; 114130594Ssam lastcmd = FNT; 114230594Ssam } 114330594Ssam */ 114430594Ssam debugp(("...width (%d)\n", pw[i]&BMASK)); 114530594Ssam } 114630594Ssam 114730594Ssam 114830594Ssam private putnf(c, s) /* note that a character wasnt found */ 114930594Ssam int c; 115030594Ssam char *s; 115130594Ssam { 115230594Ssam 115330594Ssam FlushShow(0); 115430594Ssam thisw = 0; 115530594Ssam if ((s == NULL) || (*s == '\0')) printf("(\%3o)cb\n", c); 115630594Ssam else if ((strcmp(s, "\\|") == 0) || (strcmp(s, "\\^") == 0) 115730594Ssam || (strcmp (s, "\\&") == 0)) 115830594Ssam return; 115930594Ssam else 116030594Ssam printf("(%s)cb\n", s); 116130594Ssam } 116230594Ssam 116330594Ssam 116430594Ssam private t_fp(n, s, si) /* font position n now contains font s, intname si */ 116530594Ssam int n; /* position */ 116630594Ssam char *s; /* font (ditname) */ 116730594Ssam char *si; /* font (intname = number) */ 116830594Ssam { 116930594Ssam fontname[n].name = s; 117030594Ssam fontname[n].number = atoi (si); 117130594Ssam } 117230594Ssam 117330594Ssam private setfont(n) /* set font to n */ 117430594Ssam int n; 117530594Ssam { 117630594Ssam FlushShow(1); 117730594Ssam 117830594Ssam if (n < 0 || n > NFONT) { 117930594Ssam fprintf(stderr,"%s: illegal font %d\n", prog,n); 118030594Ssam } 118130594Ssam if (font != n) { 118230594Ssam font = n; 118330594Ssam printf("%d f\n",font); 118430594Ssam } 118530594Ssam onspecial = 0; 118630594Ssam } 118730594Ssam 118830594Ssam private drawline(dx, dy) /* draw line from here to dx, dy */ 118930594Ssam int dx, dy; 119030594Ssam { 119130594Ssam FlushShow(0); MoveTo(); DoMove(); 119230594Ssam printf("%d %d Dl\n", dx, dy); 119330594Ssam hpos += dx; 119430594Ssam PSx = hpos * PSmag; 119530594Ssam vpos += dy; 119630594Ssam PSy = vpos * PSmag; 119730594Ssam } 119830594Ssam 119930594Ssam private drawwig(s) /* draw wiggly line */ 120030594Ssam char *s; 120130594Ssam { 120230594Ssam FlushShow(0); MoveTo(); DoMove(); 120330594Ssam printf("D~ %s D~~\n",s); 120430594Ssam } 120530594Ssam 120630594Ssam private drawcirc(d) 120730594Ssam int d; 120830594Ssam { 120930594Ssam FlushShow(0); MoveTo(); DoMove(); 121030594Ssam printf("%d Dc\n",d); 121130594Ssam } 121230594Ssam 121330594Ssam private drawarc(dx1, dy1, dx2, dy2) 121430594Ssam int dx1, dy1, dx2, dy2; 121530594Ssam { 121630594Ssam FlushShow(0); MoveTo(); DoMove(); 121730594Ssam printf("%d %d %d %d Da\n", dx1, dy1, dx2, dy2); 121830594Ssam hpos += dx1 + dx2; 121930594Ssam PSx = hpos * PSmag; 122030594Ssam vpos += dy1 + dy2; 122130594Ssam PSy = vpos * PSmag; 122230594Ssam } 122330594Ssam 122430594Ssam private drawellip(a, b) 122530594Ssam int a, b; 122630594Ssam { 122730594Ssam FlushShow(0);MoveTo();DoMove(); 122830594Ssam printf("%d %d De\n",a,b); 122930594Ssam } 123030594Ssam 123130594Ssam private hmot(a) /* relative horizontal motion */ 123230594Ssam int a; 123330594Ssam { 123430594Ssam register int aa; 123530594Ssam aa = abs(a); 123630594Ssam if ((aa < 8) || (aa > (10 * thisw)) || (a >= 100) 123730594Ssam || ((thisw != 0) && (abs(thisw - a) > 4))) { 123830594Ssam FlushShow(1); 123930594Ssam } 124030594Ssam hpos += a; 124130594Ssam if (lastcmd != CPUT) startx = hpos; 124230594Ssam } 124330594Ssam 124430594Ssam private hgoto(a) /* absolute horizontal motion */ 124530594Ssam int a; 124630594Ssam { 124730594Ssam FlushShow(1); 124830594Ssam startx = hpos = a; 124930594Ssam thisw = 0; 125030594Ssam } 125130594Ssam 125230594Ssam private vmot(a) /* relative vertical motion */ 125330594Ssam int a; 125430594Ssam { 125530594Ssam FlushShow(1); 125630594Ssam vpos += a; 125730594Ssam thisw = 0; 125830594Ssam } 125930594Ssam 126030594Ssam private vgoto(a) /* absolute vertical motion */ 126130594Ssam int a; 126230594Ssam { 126330594Ssam FlushShow(1); 126430594Ssam vpos = a; 126530594Ssam thisw = 0; 126630594Ssam } 126730594Ssam 126830594Ssam private showspecial(s,cc,wid) 126930594Ssam char *s; 127030594Ssam int cc; 127130594Ssam int wid; 127230594Ssam { 127330594Ssam char *sp; 127430594Ssam 127530594Ssam FlushShow(0); 127630594Ssam MoveTo(); 127730594Ssam DoMove(); 127830594Ssam putchar('('); 127930594Ssam for (sp = s; *sp != '\0'; sp++) { 128030594Ssam if (needsescape(*sp)) { 128130594Ssam putchar('\\'); 128230594Ssam } 128330594Ssam putchar(*sp); 128430594Ssam } 128530594Ssam printf(")%d %d oc\n",cc,wid); 128630594Ssam } 128730594Ssam 128830594Ssam private showchar(c) 128930594Ssam int c; 129030594Ssam { 129130594Ssam if (showind == 0) {MoveTo();} 129230594Ssam else if ((vpos * PSmag) != PSy) { 129330594Ssam FlushShow(0); 129430594Ssam MoveTo(); 129530594Ssam } 129630594Ssam if (showind >= SHOWSIZE) FlushShow(0); 129730594Ssam if (isascii(c) && isprint(c)) { 129830594Ssam switch (c) { 129930594Ssam case '\\': case '(': case ')': 130030594Ssam showbuf[showind++] = '\\'; 130130594Ssam /* fall through */ 130230594Ssam 130330594Ssam default: 130430594Ssam showbuf[showind++] = c; 130530594Ssam } 130630594Ssam } 130730594Ssam else { 130830594Ssam showbuf[showind++] = '\\'; 130930594Ssam showbuf[showind++] = ((c>>6)&03) + '0'; 131030594Ssam showbuf[showind++] = ((c>>3)&07) + '0'; 131130594Ssam showbuf[showind++] = (c&07) + '0'; 131230594Ssam } 131330594Ssam showbuf[showind] = '\0'; 131430594Ssam nshow++; 131530594Ssam } 131630594Ssam 131730594Ssam private MoveTo() { 131830594Ssam int x, y; 131930594Ssam x = hpos * PSmag; 132030594Ssam y = vpos * PSmag; 132130594Ssam 132230594Ssam if (x != PSx) { 132330594Ssam startx = savex = hpos; 132430594Ssam PSx = x; 132530594Ssam movepending |= XMOVE; 132630594Ssam } 132730594Ssam if (y != PSy) { 132830594Ssam savey = vpos; 132930594Ssam PSy = y; 133030594Ssam movepending |= YMOVE; 133130594Ssam } 133230594Ssam } 133330594Ssam 133430594Ssam private FlushMove() { 133530594Ssam switch (movepending) { 133630594Ssam case NONE: 133730594Ssam break; 133830594Ssam case XMOVE: 133930594Ssam printf("%d",savex); 134030594Ssam break; 134130594Ssam case YMOVE: 134230594Ssam printf("%d",savey); 134330594Ssam break; 134430594Ssam case XYMOVE: 134530594Ssam printf("%d %d",savex,savey); 134630594Ssam break; 134730594Ssam default: 134830594Ssam fprintf(stderr,"%s: invalid move code %d\n",prog, movepending); 134930594Ssam exit(2); 135030594Ssam } 135130594Ssam } 135230594Ssam 135330594Ssam private char *movecmds[] = { 135430594Ssam "MX","MY","MXY" 135530594Ssam }; 135630594Ssam 135730594Ssam private DoMove() { 135830594Ssam FlushMove(); 135930594Ssam if (movepending != NONE) { 136030594Ssam printf(" %s\n",movecmds[movepending-1]); 136130594Ssam movepending = NONE; 136230594Ssam } 136330594Ssam } 136430594Ssam 136530594Ssam private char showops[] = "SXYN"; 136630594Ssam 136730594Ssam private FlushShow(t) int t; { 136830594Ssam long err, tlen; 136930594Ssam float cerror; 137030594Ssam 137130594Ssam if (showind == 0) {thisw = 0; return;} 137230594Ssam if (movepending != NONE) { 137330594Ssam FlushMove(); 137430594Ssam } 137530594Ssam tlen = hpos - startx; 137630594Ssam if (lastcmd == CPUT) tlen += thisw; 137730594Ssam err = tlen * PSmag - PSshowlen; 137830594Ssam if ((nshow != 1) && (abs(err) > ErrorTolerance)) { 137930594Ssam cerror = ((float) err) / ((nshow - 1) * PSmag); 138030594Ssam #ifdef DEBUG 138130594Ssam fprintf(stderr,"F%d lc %d thisw %d ",t,lastcmd,thisw); 138230594Ssam fprintf(stderr,"x %ld h %ld tn %ld %ld ", 138330594Ssam startx, hpos, tlen*PSmag,PSshowlen); 138430594Ssam fprintf(stderr,"error %d %.4f %s\n",nshow,cerror,showbuf); 138530594Ssam fflush(stderr); 138630594Ssam #endif 138730594Ssam printf(" %.4f(%s)A%c\n", cerror, showbuf, showops[movepending]); 138830594Ssam } 138930594Ssam else { 139030594Ssam printf("(%s)%c\n", showbuf, showops[movepending]); 139130594Ssam } 139230594Ssam 139330594Ssam showind = 0; 139430594Ssam nshow = 0; 139530594Ssam showbuf[showind] = '\0'; 139630594Ssam PSx += PSshowlen; 139730594Ssam PSshowlen = 0; 139830594Ssam startx = hpos; 139930594Ssam if (lastcmd == CPUT) startx += thisw; 140030594Ssam thisw = 0; 140130594Ssam movepending = NONE; 140230594Ssam } 1403