home *** CD-ROM | disk | FTP | other *** search
- /* vi:se ts=4 sw=4 wm=0: */
- static char *RCSid =
- "$Header: hp.c,v 1.1.1.9 85/08/17 15:53:35 ron Exp $";
-
- /*
- * hp.c - Copyright (c) 1985 by Ron Saad (ron1!ron)
- * All Rights Reserved.
- *
- * This code maybe freely distributed in source
- * for non commercial purposes.
- * Please keep this notice intact.
- */
-
- /*
- * $Log: hp.c,v $
- * Revision 1.1.1.9 85/08/17 15:53:35 ron
- * As usual, just 'one more thing ..' - moved the
- * size cheating code to where it belongs - just before
- * the file gets read in.
- * still to do:
- * make vgoto adjust the height to scale for not having a full
- * 11 inches, otherwise get bogus page feeds.
- *
- * Revision 1.1.1.8 85/08/15 14:50:29 ron
- * this seems to be the version going out to mod.sources
- * (if they'll take it).
- *
- * Revision 1.1.1.7 85/08/07 23:13:06 ron
- * this is probably a usable version of the laserjet driver. it loads
- * bit maps for special fonts and for sizes that are not on the cartridge,
- * and has the basis for enhancement - it still needs a LOT of work:
- * CLEANING UP!
- * recognition of vfont/rasti10 by f_magic - add field to FINFO
- * and use to decide on height/width of character, positioning, etc.
- * add code tables for rasti10 bit maps.
- * etc
- *
- * Revision 1.1.1.6 85/08/04 12:38:56 ron
- * added font info table, changed font reads to a fseek followed
- * by charater data reads. still need to add code tables for rasti10
- * and distinguish between rasti10 and vfont. add field to finfo based
- * on the f_magic and enforce f_magic. find out why vfont produces
- * poorly placed characters.
- * has not yet been tested.
- *
- * Revision 1.1.1.5 85/08/02 14:08:40 ron
- * adding a font info table so that we can use more than
- * one bit-map at a time without constantly loading/unloading
- * files. may also change the loading to an fseek followed by a read to
- * minimize file access since most of the bit-map stuff are done
- * for only a few characters.
- * therefore keep this "pre-change" version b4 i destroy it ...
- *
- * Revision 1.1.1.4 85/07/28 15:07:33 ron
- * works. is confined to one size - next step is size changes. rule
- * is done wrong - comes out too low - should use bit map.
- * knows about differences between vfont and rasti10 - i.e. adding
- * 1 bit and 1 row when needed.
- *
- * Revision 1.1.1.3 85/07/21 16:28:51 ron
- * first attempt at adding the special font as a raster
- * map and dump'n out bit maps when appropriate.
- *
- * Revision 1.1.1.2 85/07/19 12:24:15 ron
- * took out the 'optimization'. it does work, i.e. cuts file size,
- * imaging time etc, but the spacing of the laserjet is much larger
- * than what troff thinks it is.
- *
- * Revision 1.1.1.1 85/07/10 10:26:06 ron
- * gave up on eliminating hpos for now. may try again
- * later.
- *
- * Revision 1.1.0.2 85/07/10 08:38:59 ron
- * ok, put in a fudge to do hflush() only if it's not
- * a sequence of characters.
- *
- * Revision 1.1.0.1 85/07/10 08:30:23 ron
- * the numbering in rcs is ridiculous. anyway, this is the 'starting'
- * file for this 'branch'. goal is to eliminate as many horiz position
- * as possible, since this takes forever on the laserjet. next try
- * is to let the printer do the spacing in every case where
- * we have just printed a sequence of 2hor-mot-digits+char and
- * have another one immediately following.
- *
- *
- */
-
-
- #include <stdio.h>
- #include <signal.h>
- #include <ctype.h>
- #include <strings.h>
-
- #include "glyph.h"
- #include "asctab.h"
- #include "spectab.h"
-
- int output = 0; /* do we do output at all? */
- int pgindex = 0; /* output page list if > 0 */
- int pagelist[20]; /* pairs of page numbers */
-
-
-
- #define FATAL 1
- int dbg = 0;
-
- #define dprintf if (dbg) fprintf
- #define dinfoprint if (dbg) finfoprint
-
- int res = 720;
- /* input assumed computed according */
- /* to this resolution (actually 723) */
- /* initial value to avoid 0 divide */
-
- char *dfltdir = "/usr/lib/vfont";
-
- char *fontdir = "/usr/lib/font";
- char *vfontdir = "/usr/lib/vfont";
- char *rfontdir = "/usr/src/cmd/text/troff.d/devi10/rasti10";
-
- extern char devname[];
-
- int want_siz = 10; /* convenient defaults */
- int crnt_siz = 10;
-
- int c_fnt_indx = 0;
- int cartridge = 1;
-
- #define NUMFONTS 8
-
- /*
- * the purpose for this array is to have more than one size
- * of a font available at a time. this is not handled properly now,
- * the entry is just replaced, causing some unnecessary i/o to
- * take place. when it's done correctly, the character info structures
- * will only need to be read once and this thing will work faster.
- * (it will never be fast - the laserjet is too slow in processing
- * the positioning commands/bit maps to be REALLY useful).
- * Also, presently, the c_fnt_indx always corresponds to the font
- * position used. The inclusion of f_numb field is to make this
- * unnecessary, to enable switching font files without abandoning
- * their entries/info.
- */
- struct FINFO {
- int f_numb;
- /*
- * 0 means not currently used, otherwise
- * this is the position 'loaded' on
- */
- char f_name[30]; /* name.size */
- struct c_param * f_chp;
- /* really points to the first element in
- * a 256 array of structs, so we can have
- * the character info for all members of
- * this font without re-reading the file
- */
- FILE * f_ptr;
- } finfo[NUMFONTS] = {
- 1, "R.10", NULL, NULL,
- 2, "B.10", NULL, NULL,
- 3, "I.10", NULL, NULL,
- 4, "", NULL, NULL,
- 5, "", NULL, NULL,
- 6, "", NULL, NULL,
- 7, "", NULL, NULL,
- 8, "", NULL, NULL
- };
-
- FILE *fp = stdin; /* input file pointer */
-
-
- main(argc, argv)
- char *argv[];
- {
- char buf[BUFSIZ];
- int done();
-
- setbuf(stdout, buf);
- while (argc > 1 && argv[1][0] == '-') {
- switch (argv[1][1]) {
- case 'o':
- outlist(&argv[1][2]);
- break;
- case 'd':
- dbg = atoi(&argv[1][2]);
- if (dbg == 0) dbg = 1;
- break;
- }
- argc--;
- argv++;
- }
-
- if (argc <= 1)
- dofile(stdin);
- else
- while (--argc > 0) {
- if (strcmp(*++argv, "-") == 0)
- fp = stdin;
- else if ((fp = fopen(*argv, "r")) == NULL)
- error(FATAL, "can't open %s", *argv);
- dofile(fp);
- fclose(fp);
- }
- done();
- }
-
- outlist(s) /* process list of page numbers to be printed */
- char *s;
- {
- int start, finish, i;
-
- pgindex = 0;
- while (*s) {
- for (start = 0; isdigit(*s); start = start * 10 +*s++ - '0');
- finish = start;
- if (*s == '-'){
- s++;
- for (finish = 0; isdigit(*s); finish = finish * 10 +*s++ - '0');
- }
- if (finish==0) finish = 9999;
-
- pagelist[pgindex++] = start;
- pagelist[pgindex++] = finish;
- if (*s != '\0')
- s++;
- }
- pagelist[pgindex] = 0;
- if (dbg)
- for (i=0; i<pgindex; i += 2)
- printf("%3d %3d\n", pagelist[i], pagelist[i+1]);
- }
-
- in_olist(n) /* is page n in pagelist? */
- int n;
- {
- int i;
-
- if (pgindex == 0)
- return(1); /* everything is included */
- for (i = 0; i < pgindex; i += 2)
- if (n >= pagelist[i] && n <= pagelist[i+1])
- return(1);
- return(0);
- }
-
-
- dofile(fp)
- register FILE *fp;
- {
- register int c, k;
- int m, n, n1, m1;
- char str[100], buf[300];
-
- while ((c = getc(fp)) != EOF) {
- switch (c) {
- case '\n': /* when input is text */
- case ' ':
- case 0: /* occasional noise creeps in */
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* two motion digits plus a character */
- hmot((c-'0')*10 + getc(fp)-'0');
- put1(getc(fp));
- break;
- case 'c': /* single ascii character */
- put1(getc(fp));
- break;
- case 'C': /* 'funny' character */
- fscanf(fp, "%s", str);
- #ifdef DEBUG
- dprintf(stderr, "%s", str);
- #endif
- put1s(str);
- break;
- case 't': /* straight text */
- fgets(buf, sizeof(buf), fp);
- t_text(buf);
- break;
- case 'D': /* draw function - not done yet */
- fgets(buf, sizeof(buf), fp);
- switch (buf[0]) {
- case 'l': /* draw a line */
- sscanf(buf+1, "%d %d", &n, &m);
- drawline(n, m, ".");
- break;
- case 'c': /* circle */
- sscanf(buf+1, "%d", &n);
- drawcirc(n);
- break;
- case 'e': /* ellipse */
- sscanf(buf+1, "%d %d", &m, &n);
- drawellip(m, n);
- break;
- case 'a': /* arc */
- sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
- drawarc(n, m, n1, m1);
- break;
- case '~': /* wiggly line */
- drawwig(buf+1);
- break;
- default:
- error(FATAL, "unknown drawing function %s", buf);
- break;
- }
- break;
- case 's':
- fscanf(fp, "%d", &n); /* ignore fractional sizes */
- #ifdef DEBUG
- dprintf(stderr, "%d", n);
- #endif
- setsize(t_size(n));
- break;
- case 'f':
- fscanf(fp, "%s", str);
- #ifdef DEBUG
- dprintf(stderr, "%s", str);
- #endif
- setfont(t_font(str));
- break;
- case 'H': /* absolute horizontal motion */
- while ((c = getc(fp)) == ' ')
- ;
- for (k = c-'0'; isdigit(c = getc(fp)); k = 10*k+c-'0');
- ungetc(c, fp);
- hgoto(k);
- break;
- case 'h': /* relative horizontal motion */
- while ((c = getc(fp)) == ' ')
- ;
- for (k = c-'0'; isdigit(c = getc(fp)); k = 10*k+c-'0');
- ungetc(c, fp);
- hmot(k);
- break;
- case 'w': /* word space */
- /* should either ignore this or space over
- the right character width, not just space */
- putc(' ', stdout);
- break;
- case 'V':
- while ((c = getc(fp)) == ' ')
- ;
- for (n = c-'0'; isdigit(c = getc(fp)); n = 10*n+c-'0');
- ungetc(c, fp);
- #ifdef DEBUG
- dprintf(stderr, "%d", n);
- #endif
- vgoto(n);
- break;
- case 'v':
- while ((c = getc(fp)) == ' ')
- ;
- for (n = c-'0'; isdigit(c = getc(fp)); n = 10*n+c-'0');
- ungetc(c, fp);
- #ifdef DEBUG
- dprintf(stderr, "%d", n);
- #endif
- vmot(n);
- break;
- case 'p': /* new page */
- fscanf(fp, "%d", &n);
- #ifdef DEBUG
- dprintf(stderr, "%d", n);
- #endif
- t_page(n);
- break;
- case 'n': /* end of line */
- while (getc(fp) != '\n')
- ;
- t_newline();
- break;
- case '#': /* comment */
- while (getc(fp) != '\n')
- ;
- break;
- case 'x': /* device control */
- device(fp);
- break;
- default:
- error(!FATAL, "unknown input character %o %c", c, c);
- done();
- }
- }
- }
-
- device(fp) /* interpret device control functions */
- FILE *fp;
- {
- char str[20];
- int n;
-
- fscanf(fp, "%s", str);
- #ifdef DEBUG
- dprintf(stderr, "%s", str);
- #endif
- switch (str[0]) {
- case 'i': /* initialize */
- fileinit();
- t_init(0);
- break;
- case 'T': /* device name */
- fscanf(fp, "%s", devname);
- #ifdef DEBUG
- dprintf(stderr, "%s", devname);
- #endif
- /* gets ignored anyway */
- break;
- case 't': /* trailer */
- t_trailer();
- break;
- case 'p': /* pause -- can restart */
- t_reset('p');
- break;
- case 's': /* stop */
- t_reset('s');
- break;
- case 'r': /* resolution assumed when prepared */
- fscanf(fp, "%d", &res);
- #ifdef DEBUG
- dprintf(stderr, "%d", res);
- #endif
- break;
- case 'f': /* font used */
- fscanf(fp, "%d %s", &n, str);
- #ifdef DEBUG
- dprintf(stderr, "%d %s", n, str);
- #endif
- loadfont(n, str);
- break;
- }
- while (getc(fp) != '\n') /* skip rest of input line */
- ;
- }
-
-
- fileinit() /* read in font and code files, etc. */
- {
- /*
- * don't do anything here since the first commands
- * in any output from troff are font load commands and
- * we'll do them there anyway
- */
- }
-
- fontprint(i) /* debugging print of font i (1,...NUMFONTS) */
- {
- /*
- * I'm too lazy - add this if you want - it's just
- * a simple loop, e.g for (i=0; i<256; call raster)
- */
- }
-
- loadcode(n, nw)
- /* load codetab on position n (0...NUMFONTS); #chars is nw */
- /* someday will get added when i discover where the tables */
- /* are, or if i create them from my font dumps. */
- int n, nw;
- {
- /*
- * do we know how the code tables are organized?
- * the code positions are different (of course ...) for vfont
- * and for the AT&T DWB fonts (the imagen rasters).
- * we need a way to distinguish between the raster files
- * not based on their names, and f_magic, as far as i remember,
- * is not consistent. either find a 'smart' way to do this, or
- * go over ALL the font files and force f_magic to 0436 for vfont
- * and to something else for rasti10. then we can have independent
- * code tables and add them to the FINFO structures, so that we
- * can find find a character FAST.
- * P.S. - i think the maxx, maxy, and xtend fields are ALWAYS 0 on
- * the rasti10 stuff, and ALWAYS initialized to something normal in
- * vfont, so that may be a solution.
- */
- }
-
- cheat_size(n)
- int n;
- {
- register int * siz;
- static int av_siz [] = {
- 6, 7, 8, 9, 10, 11, 12,
- 14, 16, 18, 20, 22, 24,
- 28, 36, 0
- };
-
- n = (int)(n*1.33);
- /*
- * is vfont for 200 dpi?
- * this seems to give a good size ratio
- * but can change to fit your mood ...
- * it's not exact anyway cause of cheatsize().
- */
-
- for (siz=av_siz; (*siz != 0) && (n > *siz); siz++)
- ;
- return ((*siz == 0) ? *--siz : *siz);
- }
-
- loadfont(pos, s)
- /* load font info for font s on position n (1...NUMFONTS) */
- int pos;
- char *s;
- {
- /*
- * read in a font here from the library - just the header
- * and the c_param structures. we'll do an fseek and read
- * for the characters separately.
- * call t_fp to update the table of fonts and see if we
- * already have the info we need, and check if not on cartridge.
- *
- * there should be
- * space for more than one font since troff seems to enjoy
- * changing point sizes on the fly ..
- */
-
- char filename[100];
- struct f_header fh;
- register int i;
- char tmpname[30];
- struct c_param * chpalloc();
-
- #ifdef DEBUG
- dinfoprint("loadfont entered");
- #endif
- sprintf(tmpname, "%s.%d", s, want_siz);
- i = t_fp(pos, tmpname);
- if ((strcmp(tmpname,"R.10")==0)
- || (strcmp(tmpname,"I.10")==0)
- || (strcmp(tmpname,"B.10")==0)) {
- cartridge = 1;
- c_fnt_indx = i;
- crnt_siz = want_siz;
- #ifdef DEBUG
- dinfoprint("loadfont");
- #endif
- return;
- }
- sprintf(tmpname, "%s.%d", s, cheat_size(want_siz));
- /*
- * cheat with the size here. maybe should use
- * (int)(want_siz/0.8) or (int)(want_siz/0.67)
- * to compensate - check
- * availability of these sizes b4 u try it
- */
- /* this is the font we want */
- if (finfo[i].f_ptr != NULL){
- /* found it, and the file has already been read */
- cartridge = 0;
- c_fnt_indx = i;
- crnt_siz = want_siz;
- #ifdef DEBUG
- dinfoprint("loadfont");
- #endif
- return;
- }
- /*
- * found an entry, but it hasn't been read yet - alloc
- * mem if needed, file gets read at end of else clause.
- */
- cartridge = 0;
- c_fnt_indx = i;
- crnt_siz = want_siz;
- if (finfo[c_fnt_indx].f_chp == NULL)
- if ((finfo[c_fnt_indx].f_chp = chpalloc()) == NULL)
- error(FATAL,"couldn't allocate memory");
- /* does not return */
- /*
- * we now have a spot in finfo[c_fnt_indx]
- * either because we found an entry that hasn't
- * been read in,
- * or because we replaced an old entry. so now
- * we read in the information from the font file.
- */
-
-
- sprintf(filename, "%s/%s", dfltdir, tmpname);
- finfo[c_fnt_indx].f_ptr = fopen (filename, "r");
- if (finfo[c_fnt_indx].f_ptr == NULL) {
- error (!FATAL, "font file - can't open %s", filename);
- finfo[c_fnt_indx].f_name[0] = '\0';
- c_fnt_indx = 0;
- #ifdef DEBUG
- dinfoprint("loadfont");
- #endif
- return;
- }
- #ifdef DEBUG
- dprintf (stderr, "font file %s\n", filename);
- #endif
-
- fread (&fh, sizeof (struct f_header), 1, finfo[c_fnt_indx].f_ptr);
- /*
- * not used at the time. may need it later on since we have
- * to distinguish between berkeley vfont and dwb rasti10
- * files, so might stuff a different magic number and stick
- * an indicator into the finfo structure.
- */
- fread (finfo[c_fnt_indx].f_chp,
- sizeof (struct c_param), 256, finfo[c_fnt_indx].f_ptr);
- crnt_siz = want_siz;
- #ifdef DEBUG
- dinfoprint("loadfont");
- #endif
- }
-
-
-
-
- char devname[20] = "hp2686A";
- /* (Laserjet) - not used anywhere */
- int hpos, vpos;
-
- t_init(reinit) /* initialize device */
- int reinit;
- {
-
- fflush(stdout);
- hpos = vpos = 0;
- }
-
- t_page(n) /* do whatever new page functions */
- {
- hpos = vpos = 0;
- if (output == 0) {
- output = in_olist(n);
- t_init(1);
- return;
- }
- putpage();
- fflush(stdout);
- }
-
- putpage()
- {
- putchar('\f');
- }
-
- t_newline() /* do whatever for the end of a line */
- {
- putchar('\n');
- /*
- * not really needed, but good for breaking up
- * output file (debugging, modifying).
- */
- hpos = 0;
- }
-
- t_size(n)
- int n;
- {
- return(n);
- }
-
- t_font(s) /* convert string to internal font number */
- char *s;
- {
- /* will have to choose which font to read
- into the tables so be careful here */
- return(atoi(s));
- }
-
- t_text(s) /* print string s as text */
- char *s;
- {
- int c, wspc;
- char str[100];
-
- if (!output)
- return;
- while ((c = *s++) != '\n') {
- if (c == '\\') {
- switch (c = *s++) {
- case '\\':
- case 'e':
- put1('\\');
- break;
- case '(':
- str[0] = *s++;
- str[1] = *s++;
- str[2] = '\0';
- put1s(str);
- break;
- }
- } else {
- put1(c);
- }
- wspc = crnt_siz*300./72.; /* an 'em's worth? */
- hmot(wspc);
- }
- }
-
- t_reset(c)
- {
-
- output = 1;
- if (c == 's'){
- printf("\033E");
- t_page(9999);
- }
- fflush(stdout);
- }
-
- t_trailer()
- {
- }
-
- hgoto(n)
- {
- hpos = n; /* this is where we want to be */
- /* before printing a character, */
- /* have to make sure it's true */
- }
-
- hmot(n) /* generate n units of horizontal motion */
- int n;
- {
- hpos += n;
- }
-
- hflush() /* actual horizontal output occurs here */
- {
- printf("\033&a%dH",hpos);
- }
-
- vgoto(n)
- {
- static int oldvpos = 0;
-
- vpos = n;
- if (vpos != oldvpos){
- printf("\033&a%dV",vpos);
- oldvpos = vpos;
- }
- }
-
- vmot(n) /* generate n units of vertical motion */
- int n;
- {
- vgoto(vpos + n); /* ignores rounding */
- }
-
- put1s(s) /* s is a funny char name */
- char *s;
- {
- register int i, j;
- register char *p;
- extern char *asctab[];
- /* is only good for the fonts on the cartridge
- * need a codetable for the raster dumps.
- */
- extern char *spectab[];
- /* names of chars on S font- index of name = index of
- * c_param so easy to find raster map
- */
- static char prev[10] = "";
- static int previ;
- static char prevs[10] = "";
- static int prevsi;
- char tmpname[30];
- int o_fnt_indx;
- int o_cartridge;
-
- if (!output)
- return;
-
- #ifdef DEBUG
- dinfoprint("put1s entered");
- #endif
- if (strcmp(s, prev) != 0) {
- previ = -1;
- for (i = 0; asctab[i] != 0; i += 2)
- if (strcmp(asctab[i], s) == 0) {
- strcpy(prev, s);
- previ = i;
- break;
- }
- }
- if (previ >= 0) {
- hflush(); vgoto(vpos);
- /*
- * should only use this for the cartridge fonts, but since
- * don't have a codetable yet for the rasters, use this
- * anyway - it will come out in the wrong font and size
- * but it's at least viewable.
- */
- for (p = asctab[previ+1]; *p; p++)
- putc(*p, stdout);
-
- #ifdef DEBUG
- dprintf(stderr,"ascii character %s, font is %s\n",
- asctab[previ], finfo[c_fnt_indx].f_name);
-
- dinfoprint("put1s");
- #endif
- return;
- } else
- prev[0] = 0;
-
-
- if (strcmp(s, prevs) != 0) {
- prevsi = -1;
- for (i = 0; i<128; i++)
- if (strcmp(spectab[i], s) == 0) {
- strcpy(prevs, s);
- prevsi = i;
- break;
- }
- }
- if (prevsi >= 0) {
- for (i=0; i<NUMFONTS; i++){
- if (finfo[i].f_numb == 6) break;
- }
- if (i >= NUMFONTS) error(FATAL,"nothing mounted on position 6");
- /* may add a s_fnt_indx to get around this */
-
- #ifdef DEBUG
- dprintf(stderr,"special character %s, font on position 6 is %s\n",
- spectab[prevsi], finfo[i].f_name);
- #endif
-
- o_fnt_indx = c_fnt_indx;
- o_cartridge = cartridge;
-
- if ((p = index(finfo[i].f_name,'.'))==0)
- error(FATAL,"finfo entry screwed up");
-
- /* size check - may need new file */
-
- if (atoi(++p)!=want_siz) {
- for (j=0; (tmpname[j]=finfo[i].f_name[j])!='.' ;j++);
- tmpname[j]='\0';
- /* copy the font name up to the '.' into tmpname */
-
- loadfont(finfo[i].f_numb, tmpname);
- /* do a new load on position 6 for new size */
- /* this will change c_fnt_indx and */
- /* cartridge indicator, so need to restore. */
- i = c_fnt_indx;
-
- #ifdef DEBUG
- dprintf(stderr,
- "put1s - needed size change, current font pos %d has %s\n",
- finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
- #endif
- }
- else {
- /*
- * we didn't call loadfont since size was ok,
- * but raster looks at c_fnt_indx to get a file
- * pointer, so change it here and reset later.
- * dirty, lousy code - redo this whole section
- */
- c_fnt_indx = i;
- }
-
- #ifdef DEBUG
- dinfoprint("put1s");
- #endif
- raster(finfo[i].f_chp+prevsi);
-
- cartridge = o_cartridge;
- c_fnt_indx = o_fnt_indx;
-
- #ifdef DEBUG
- dprintf(stderr,
- "put1s - restored old font, position %d has %s\n",
- finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
-
- dinfoprint("put1s");
- #endif
- return;
- } else
- prevs[0] = 0;
- #ifdef DEBUG
- dinfoprint("put1s");
- #endif
- }
-
-
- put1(c) /* output char c */
- int c;
- {
- register char * pt; /* finds the size of the current font */
-
- if (!output)
- return;
- vgoto(vpos);
- /*
- horiz position gets flushed if it's not a
- 'nnc' sequence, in which case we try to let
- the laserjet handle the spacing
- */
- /*
- Cancel the above - the laserjet's spacing is too
- wide for troff. it doesn't look as nice either. while
- this cuts file size & xmission time, we need a better
- solution, i.e. width tables, etc.
- */
- hflush();
-
- /*
- * the following is SLOW and messy. find a better
- * way of knowing what the size is. yuck.
- */
-
- #ifdef DEBUG
- dinfoprint("put1 entered");
- #endif
-
- if ((pt = index(finfo[c_fnt_indx].f_name,'.'))==0)
- error(FATAL,"finfo entry screwed up");
-
- if (atoi(++pt)!=want_siz) {
- /* copy the font name up to the '.' into tmpname */
- setfont(finfo[c_fnt_indx].f_numb);
- /* do a new load since we lost our size */
-
- #ifdef DEBUG
- dprintf(stderr,
- "put1 - needed size change, current font pos %d has %s\n",
- finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
- #endif
- }
-
- #ifdef DEBUG
- dinfoprint("put1");
- #endif
- if (cartridge) putc(c, stdout);
- else {
- raster(finfo[c_fnt_indx].f_chp+c);
- /* only good for vfont, dwb needs a code table */
- }
- #ifdef DEBUG
- dinfoprint("put1");
- #endif
- }
-
- setsize(n) /* set point size to n (internal) */
- int n;
- {
- #ifdef DEBUG
- dprintf(stderr,"going to point size %d\n",n);
- #endif
- want_siz = n;
- }
-
- t_fp(n, s) /* font position n now contains font s */
- int n;
- char *s; /* s is a name.size combination */
- {
- register int ind;
-
- #ifdef DEBUG
- dinfoprint("t_fp entered");
- #endif
- for (ind = 0; ind < NUMFONTS; ind++){
- if (finfo[ind].f_numb == n){
- if (strcmp(finfo[ind].f_name, s)==0){
- #ifdef DEBUG
- dinfoprint("t_fp");
- #endif
- return(ind); /* already there */
- }
- else {
- strcpy(finfo[ind].f_name, s);
- if (finfo[ind].f_ptr != NULL)
- fclose(finfo[ind].f_ptr);
- finfo[ind].f_ptr = NULL;
- #ifdef DEBUG
- dinfoprint("t_fp");
- #endif
- return(ind);
- }
- }
- }
- #ifdef DEBUG
- dinfoprint("t_fp");
- #endif
- error(FATAL, "can't mount %s, pos %d doesn't exist", s, n);
- /* NOTREACHED */
- }
-
- setfont(n) /* set font to n */
- int n;
- {
- register int ind;
- register char * pt;
- char tmpname[30]; /* just a convenience */
-
- #ifdef DEBUG
- dinfoprint("setfont entered");
- dprintf(stderr,"request for font on position %d\n",n);
- #endif
-
- for (ind = 0; ind < NUMFONTS; ind++){
- if (finfo[ind].f_numb == n) break;
- }
- if (ind >= NUMFONTS)
- error(FATAL, "nothing mounted on position %d", n);
-
- c_fnt_indx = ind;
- crnt_siz = want_siz;
-
- cartridge = 0;
-
- /*
- * check the size of the mounted font and make
- * sure its what we want, otherwise call loadfont
- */
- if ((pt = index(finfo[c_fnt_indx].f_name,'.'))==0)
- error(FATAL,"finfo entry screwed up");
-
- if (atoi(++pt)!=want_siz) {
- for (ind=0;
- (tmpname[ind]=finfo[c_fnt_indx].f_name[ind])!='.' ;ind++);
- tmpname[ind]='\0';
- /* copy the font name up to the '.' into tmpname */
- loadfont(finfo[c_fnt_indx].f_numb, tmpname);
- /* do a new load since we lost our size */
-
- #ifdef DEBUG
- dprintf(stderr,
- "setfont - needed size change, current font pos %d has %s\n",
- finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
- #endif
- }
-
- strcpy(tmpname, finfo[c_fnt_indx].f_name);
- if (strcmp(tmpname,"R.10")==0){
- printf("\033&l0O\033(0U\033(s1p10v0s0b5T");
- /* Times Roman medium upright (portrait) */
- cartridge = 1;
- #ifdef DEBUG
- dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
- dinfoprint("setfont");
- #endif
- return;
- }
- if (strcmp(tmpname,"I.10")==0){
- printf("\033&l0O\033(0U\033(s1p10v1s0b5T");
- /* Times Roman medium italic (portrait) */
- cartridge = 1;
- #ifdef DEBUG
- dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
- dinfoprint("setfont");
- #endif
- return;
- }
- if (strcmp(tmpname,"B.10")==0) {
- printf("\033&l0O\033(0U\033(s1p10v0s1b5T");
- /* Times Roman bold upright (portrait) */
- cartridge = 1;
- #ifdef DEBUG
- dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
- dinfoprint("setfont");
- #endif
- return;
- }
-
- if (finfo[c_fnt_indx].f_ptr==NULL) {
- for (ind=0;
- (tmpname[ind]=finfo[c_fnt_indx].f_name[ind])!='.' ;ind++);
- tmpname[ind]='\0';
- /* copy the font name up to the '.' into tmpname */
- loadfont(finfo[c_fnt_indx].f_numb, tmpname);
- /* do a new load since we lost our size */
-
- #ifdef DEBUG
- dprintf(stderr,
- "setfont - got a NULL fptr, current font pos %d has %s\n",
- finfo[c_fnt_indx].f_numb, finfo[c_fnt_indx].f_name);
- #endif
- }
-
- #ifdef DEBUG
- dprintf(stderr,"set font to %s\n", finfo[c_fnt_indx].f_name);
- dinfoprint("setfont");
- #endif
- }
-
- done()
- {
- output = 1;
- putpage();
- fflush(stdout);
- exit(0);
- }
-
- raster (chp)
- struct c_param * chp;
- {
- int height, width, bytewidth;
- int lsrres = 300;
- int i, j;
- long p;
- FILE * fp; /* just a convenience */
-
- if ((fp = finfo[c_fnt_indx].f_ptr)==NULL){
- /* fseek dumps core on a NULL file pointer */
- error(!FATAL,"raster: called with a NULL file pointer, %s",
- "ignoring request");
- return;
- }
-
- height = (int) ckint (chp->c_up) + (int) ckint (chp->c_down);
- width = (int) ckint (chp->c_left) + (int) ckint (chp->c_right);
- bytewidth = (width+7)/8;
-
- if ((height*bytewidth)!=chp->c_size){
- /*
- * brain damage - system V and /usr/lib/vfont don't
- * agree on whether size is left+right or 1 bit bigger.
- * same for height (# of rows in bit map).
- *
- * change this thing to use f_magic somehow. (or the
- * presence/absence of normal numbers in maxx, maxy, etc
- */
- fprintf(stderr,
- "width & height don't match, trying rasti10 format ... ");
- width += 1;
- height += 1;
- bytewidth = (width+7)/8;
- if ((height*bytewidth)!=chp->c_size)
- fprintf(stderr, "FAILED - BAD FONT FILE\n");
- else
- fprintf(stderr, "ok\n");
- }
- #ifdef DEBUG
- else dprintf(stderr, "width & height match\n");
- #endif
-
- p = F_OFFSET + chp->c_addr;
- if (fseek(fp, p, 0) == -1)
- error(FATAL, "seek failed on file %s offset %d",
- finfo[c_fnt_indx].f_name, p);
- /* does not return */
-
- #define CNV(x) ((int)((723./lsrres)*(x)))
-
- vgoto (vpos - CNV(chp->c_up));
- hgoto (hpos + 24 - CNV(chp->c_left)); hflush();
- /*
- * the 24 is because the laserjet's letters are not
- * placed where troff thinks they are. they seem to be
- * in the lower left corner of the character cell instead of
- * at the baseline - probably need to adjust
- * the height too, but do that later.
- * Why 24? why not? got a better number?
- */
- printf ("\033*t%dR",lsrres);
- printf ("\033*r1A");
-
- for (i = 0; i < height; i++) {
- if (p >= F_OFFSET + chp->c_addr + chp->c_size){
- error(!FATAL, "ran out of bit map data");
- /* does return, but don't fail in the middle
- * of an esc seqence - spit it out first, then
- * complain.
- */
- break;
- }
- printf ("\033*b%dW", (int) ((width + 7) / 8));
- for (j = 0; j < width; j += 8) {
- putchar (getc(fp));
- ++p;
- }
- }
- printf ("\033*rB");
- vgoto (vpos + CNV(chp->c_up));
- hgoto (hpos -24 + CNV(chp->c_left)); hflush();
- }
- int ckint (n)
- char n;
- {
- #ifdef u3b
- int i;
- if ((int) n > 0177) {
- i = (int) n;
- i = (256 - i) * -1;
- }
- else {
- i = (int) n;
- }
- return (i);
- #else
- return ((int) n);
- #endif
- }
-
- drawline(n, m, s) int n,m; char * s; {}
- drawcirc(n) int n; {}
- drawellip(m, n) int n,m; {}
- drawarc(n, m, n1, m1) int n,m,n1,m1; {}
- drawwig(buf) char * buf; {}
-
- get1c(fp)
- FILE * fp;
- {
- register int c;
- c = getc(fp);
- fputc(c, stderr);
- return(c);
- }
- struct c_param *
- chpalloc()
- {
- char * calloc();
- register int i;
- register struct c_param * tmptr;
-
- /* give it 3 shots, otherwise die */
- for (i=0; i<3; i++){
- if ((tmptr=(struct c_param *)
- calloc(256, sizeof(struct c_param)))!=NULL)
- return(tmptr);
- }
- return (tmptr); /* NULL cast into right pointer */
- }
-
- error(f, s, a1, a2, a3, a4, a5, a6, a7) {
- fprintf(stderr, "hp: ");
- fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
- fprintf(stderr, "\n");
- if (f)
- exit(1);
- }
-
- finfoprint(m)
- char * m;
- {
- register struct FINFO * i;
-
- fprintf(stderr, "%s: crnt_siz %d want_siz %d cartridge %d\n",
- m, crnt_siz, want_siz, cartridge);
- for (i=finfo; i < finfo + NUMFONTS; i++)
- fprintf(stderr, "pos %d name %30s chp %s fptr %s\n",
- i->f_numb, i->f_name, (i->f_chp ? "alloc" : "null"),
- (i->f_ptr ? "open" : "null"));
- }
-