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