HP LaserJet driver part 2 of 2.
sources-request at panda.UUCP
sources-request at panda.UUCP
Wed Sep 25 23:53:27 AEST 1985
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 <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <strings.h>
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<pgindex; i += 2)
X printf("%3d %3d\n", pagelist[i], pagelist[i+1]);
X}
X
Xin_olist(n) /* is page n in pagelist? */
Xint n;
X{
X int i;
X
X if (pgindex == 0)
X return(1); /* everything is included */
X for (i = 0; i < pgindex; i += 2)
X if (n >= 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; i++){
X if (finfo[i].f_numb == 6) break;
X }
X if (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
More information about the Mod.sources
mailing list