Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!philabs!cmcl2!seismo!lll-crg!lll-lcc!ucdavis!ucbvax!cad!faustus From: faustus@cad.UUCP (Wayne A. Christopher) Newsgroups: net.text Subject: Re: Looking for nroff tables for HP LaserJet Message-ID: <65@cad.UUCP> Date: Mon, 24-Feb-86 13:29:27 EST Article-I.D.: cad.65 Posted: Mon Feb 24 13:29:27 1986 Date-Received: Wed, 26-Feb-86 20:13:49 EST References: <1361@wucec2.UUCP> Organization: U. C. Berkeley CAD Group Lines: 1477 Keywords: term(5) HP-LaserJet nroff tabhp.c I have ditroff width tables for the Times Roman cartridge -- I hope you can make use of them. I measured the characters by hand, so I don't have anything for the other cartidges (it's a lot of trouble). I'm also including a simple-minded ditroff filter for the laserjet, and other things that should be all you need to set up a laserjet, software-wise... This stuff is full of bugs which I don't have time to fix, so I would be happy to get any bug fixes. The diff file is for /usr/src/usr.lib/lpr/filters/lpf.c. Wayne -- # The rest of this file is a shell script which will extract: # Makefile ljf.c.diff ljfd.c width.c pagereverse.c DESC R I B echo x - Makefile cat >Makefile <<'!Funky!Stuff!' # Makefile for ljfd and ljf CC = cc CFLAGS = -g CFILES = ljfd.c ljf.c width.c pagereverse.c OFILES = ljfd.o ljf.o width.o pagereverse.o HFILES = all: ljf ljfd desc/DESC.out pagereverse ljfd: ljfd.o width.o $(CC) $(CFLAGS) ljfd.o width.o -o ljfd ljf: ljf.o $(CC) $(CFLAGS) ljf.o -o ljf pagereverse: pagereverse.o $(CC) $(CFLAGS) pagereverse.o -o pagereverse desc/DESC.out: desc/DESC desc/I desc/R desc/B (cd desc; ./devconfig DESC; cd ..) ctags: ctags $(CFILES) $(HFILES) !Funky!Stuff! echo x - ljf.c.diff cat >ljf.c.diff <<'!Funky!Stuff!' 18,20d17 < * < * >>> This version is modified for the HP laserjet, and does tab < * >>> expansion and page reversal. 29,32d25 < #define PAGEREVERSE "/usr/local/pagereverse" < < #define NLINES 66 /* This is bad, but that's life. */ < 49,50c42 < register FILE *p = stdin, *o = stdout, *tf; < FILE *fopen(); --- > register FILE *p = stdin, *o = stdout; 55d46 < char *mktemp(), *tempf = "/tmp/ljXXXXXX"; 91,96d81 < tempf = mktemp(tempf); < if (!(tf = fopen(tempf, "w"))) { < /* Well, let's not die horribly... */ < tf = stdout; < } < initlj(); 172,176c157 < if (*cp == '\n') { < putc('\r', tf); < putc('\n', tf); < } else < putc(*cp, tf); --- > putc(*cp, o); 179,185c160,163 < if (i < maxrep) { < putc('\r', tf); < } else if (ch == '\n') { < putc('\r', tf); < putc('\n', tf); < } else < putc(ch, tf); --- > if (i < maxrep) > putc('\r', o); > else > putc(ch, o); 187c165 < fflush(tf); --- > fflush(o); 194,200c172,174 < < /* Now take the temp file and run it through pagereverse. */ < if (tf != stdout) { < fclose(tf); < sprintf(buf, "%s < %s", PAGEREVERSE, tempf); < system(buf); < unlink(tempf); --- > if (lineno) { /* be sure to end on a page boundary */ > putchar('\f'); > npages++; 202d175 < 209,226d181 < < /* Initialize the laserjet -- make sure that the lpr font is current. */ < < initlj() < { < /* Get the right font. */ < printf("\033E\033&l0O\033(8U\033(s0p10h12v0s0b3T"); < < /* Set page length -- see page 4-28 of the lj manual. */ < printf("\033&l14c1e7.64c66F"); < < /* Set the left margin. */ < printf("\033&a2L"); < < fflush(stdout); < return; < } < !Funky!Stuff! echo x - ljfd.c cat >ljfd.c <<'!Funky!Stuff!' /* RCS Info: $Revision: 1.1 $ on $Date: 85/10/29 14:44:27 $ * $Source: /cad4/faustus/src/laserjet/RCS/ljfd.c,v $ * Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * Permission is granted to do anything with this code except sell it * or remove this message. * * Ditroff driver for the hp laserjet. Much of this is generic, and for * many printers only a few lines in each routine need be changed to * get something that works... */ #include #include extern char *tmalloc(), *copy(); #define eq(a,b) (!strcmp((a), (b))) #define prefix(p, s) (!strncmp((p), (s), strlen(p))) #define alloc(strname) ((struct strname *) tmalloc(sizeof(struct strname))) int pagereverse = 0; struct command { char *c_line; /* NULL terminated, no newline. */ struct command *c_next; struct command *c_prev; struct command *c_nextpage; /* If this is a 'p' line... */ struct command *c_prevpage; } ; /* Stuff to describe the state of the page. */ int hpos, vpos; int hmax, vmax; int curfont, cursize; int maxfont, maxsize; int curpage; int debug = 0; int wordspace = 0; main(ac, av) char **av; { char buf[BUFSIZ]; struct command *coms, *cc, *tr = NULL, *lp = NULL, *readcoms(); if (eq(av[1], "-d")) debug = 1; else if (eq(av[1], "-D")) debug = 2; startup(); /* Gather up all the commands first. */ coms = readcoms(stdin); /* if (debug) printcoms((int) coms); */ /* Do commands until we get to a 'p' line... */ for (cc = coms; cc && (*cc->c_line != 'p'); cc = cc->c_next) doline(cc->c_line); /* Now print the pages out in the proper order. */ if (pagereverse) { while (cc->c_nextpage) cc = cc->c_nextpage; do { doline(cc->c_line); lp = cc; cc = cc->c_next; while (cc && (*cc->c_line != 'p') && !prefix("x trailer", cc->c_line)) { doline(cc->c_line); cc = cc->c_next; } if (prefix("x trailer", cc->c_line)) tr = cc; cc = lp; if (cc) cc = cc->c_prevpage; else break; } while (cc); if (tr) while (tr) { doline(tr->c_line); tr = tr->c_next; } else fprintf(stderr, "Warning: no x trailer!\n"); } else { while (cc) { doline(cc->c_line); cc = cc->c_next; } } cleanup(); exit(0); } /* Read in commands, filtering out comments and breaking up multiple * commands on one line. This is really bad -- ditroff should be more * nice to us. */ struct command * readcoms(fp) FILE *fp; { struct command *comm = NULL, *last = NULL, *prevpage = NULL; char *s, *getcom(); while (s = getcom(fp)) { if (comm) { last->c_next = alloc(command); last->c_next->c_prev = last; last = last->c_next; } else { last = comm = alloc(command); } last->c_line = s; if (*s == 'p') { /* Link this one and prevpage together. */ if (prevpage) { prevpage->c_nextpage = last; last->c_prevpage = prevpage; } prevpage = last; } } return (comm); } char * getcom(fp) FILE *fp; { static char buf[BUFSIZ] = ""; char wbuf[BUFSIZ]; static int i = 0; register char *s, *t; register int j = 0; new: while (!buf[i] || (buf[0] == '#')) { if (!fgets(buf, BUFSIZ, fp)) return (NULL); i = 0; } while (isspace(buf[i])) i++; if (!buf[i]) goto new; switch (buf[i]) { case 's': case 'f': case 'H': case 'V': case 'h': case 'v': case 'p': /* Grab the next number. */ wbuf[j++] = buf[i++]; while (isdigit(buf[i])) wbuf[j++] = buf[i++]; wbuf[j] = '\0'; break; case 'w': wbuf[0] = buf[i++]; wbuf[1] = '\0'; break; case 'c': wbuf[0] = buf[i++]; wbuf[1] = buf[i++]; wbuf[2] = '\0'; break; case 'C': while (buf[i] && !isspace(buf[i])) wbuf[j++] = buf[i++]; wbuf[j] = '\0'; break; case 'n': while (!isspace(buf[i])) wbuf[j++] = buf[i++]; while (buf[i] && isspace(buf[i])) wbuf[j++] = buf[i++]; while (!isspace(buf[i])) wbuf[j++] = buf[i++]; wbuf[j] = '\0'; break; default: if (isdigit(buf[i])) { wbuf[0] = buf[i++]; wbuf[1] = buf[i++]; wbuf[2] = buf[i++]; wbuf[3] = '\0'; } else { while (buf[i] && (buf[i] != '\n')) wbuf[j++] = buf[i++]; wbuf[j] = '\0'; } ; } return (copy(wbuf)); } /* Execute one ditroff command, not necessarily a whole line. */ doline(line) char *line; { if (debug == 2) { fprintf(stderr, "> %s\n", line); return; } switch (*line) { case 's': /* Set point size to num. */ setsize(atoi(line + 1)); break; case 'f': /* Set font to num. */ setfont(atoi(line + 1)); break; case 'c': /* Write one character. */ writechar(line[1]); break; case 'C': /* Write a special character. */ writespec(line + 1); break; case 'H': /* Go to hpos num. */ hgoto(atoi(line + 1)); break; case 'V': /* Go to vpos num. */ vgoto(atoi(line + 1)); break; case 'h': /* Move relative num horiz. */ hmove(atoi(line + 1)); break; case 'v': /* Move relative num vert. */ vmove(atoi(line + 1)); break; case 'n': /* End of line. */ break; case 'w': /* Paddable word space. */ wordspace = 1; break; case 'p': /* New page. */ newpage(atoi(line + 1)); break; case 'x': /* Device control... */ devcontrol(line); break; case 'D': /* Drawing function. */ drawfunc(line); break; default: /* NNc. */ if (!isdigit(line[0]) || !isdigit(line[1])) { fprintf(stderr, "Error: bad line %s\n", line); return; } hmove((line[0] - '0') * 10 + (line[1] - '0')); writechar(line[2]); } return; } /* Parse an 'x' control line. */ devcontrol(l) char *l; { char *line = l + 1; char *getword(), *command; char *s; int i; command = getword(&line); switch (*command) { case 'i': /* Initialize printer. */ initprinter(); break; case 'T': /* The name of the typesetter... */ break; /* Who cares? */ case 'r': /* Resolution... We know this... */ break; case 'p': /* Pause... */ /*** What do we do? */ break; case 's': /* Quit. */ cleanup(); exit(0); case 't': /* Trailer? */ break; case 'f': /* Make font n be s. */ s = getword(&line); if (!*s) { fprintf(stderr, "Error: bad line %s\n", l); return; } i = atoi(s); s = getword(&line); loadfont(i, s); break; case 'H': /* Set character height. */ s = getword(&line); if (!*s) { fprintf(stderr, "Error: bad line %s\n", l); return; } i = atoi(s); setheight(i); break; case 'S': /* Set character slant. */ s = getword(&line); if (!*s) { fprintf(stderr, "Error: bad line %s\n", l); return; } i = atoi(s); setslant(i); break; default: fprintf(stderr, "Error: bad device control line %s\n", l); return; } return; } drawfunc(line) char *line; { /* This remains to be implemented... */ return; } /* This returns static data... */ char * getword(s) char **s; { static char buf[BUFSIZ]; int i = 0; while (isspace(**s)) (*s)++; while (**s && !isspace(**s)) buf[i++] = *(*s)++; buf[i] = '\0'; return (buf); } /* Create a copy of a string. */ char * copy(str) char *str; { char *p, *tmalloc(); p = tmalloc(strlen(str) + 1); strcpy(p, str); return(p); } /* Malloc num bytes and initialize to zero. Fatal error if the space can't * be malloc'd. */ char * tmalloc(num) register int num; { register char *s; char *malloc(); if (!(s = malloc((unsigned) num))) { fprintf(stderr, "malloc: can't allocate %d bytes.\n", num); exit(1); } bzero(s, num); return(s); } /* Diagnostic... */ printcoms(i) int i; { struct command *c = (struct command *) i; while (c) { if (*c->c_line == 'p') printf("%s [%0x%x, pp = 0x%x, np = 0x%x]\n", c->c_line, (int) c, c->c_prevpage, c->c_nextpage); else printf("%s\n", c->c_line); c = c->c_next; } return; } /* Everything above this point is completely generic stuff, so lazy people * can just change things in the following routines. * ====================================================================== */ startup() { /* The laserjet spits out pages in reverse order. */ pagereverse = 1; hmax = 2500; vmax = 3000; cursize = 10; maxfont = 4; return; } cleanup() { /* Reset the font, etc on the laserjet. lpd should do this really. */ printf("\033E\033&l0O\033(8U\033(s0p10h12v0s0b3T"); /* Font. */ #ifdef notdef printf("\033&l14c1e7.64c66F"); /* Page length. */ printf("\033&a2L"); /* Left margin. */ #endif return; } writechar(c) char c; { char *curfontname(); putchar(c); hmove(- askwidth(c, curfontname())); return; } /* Here is the table of special charactrs that can be made with other * characters. Acknowledgements to Ron Saad for some of the codes. * The widths are for 10 point Tms Rmn. */ struct asctab { char *a_name; char *a_seq; int a_width; } asctab[] = { { "\\|", "\033&a+3H", 6 } , { "\\^", "\033&a+2H", 2 } , { "em", "-", 23 } , { "hy", "-", 23 } , { "\\-", "-", 23 } , { "dg", "|\033&a-30H-", 23 } , { "aa", "'", 16 } , { "ga", "`", 12 } , { "en", "-", 23 } , { "l.", ".", 12 } , { "br", "|", 8 } , { "vr", "|", 8 } , { "fm", "'", 16 } , { "or", "|", 8 } , /* { "fi", "f\033&a-25Hi", 30 } , { "ff", "f\033&a-25Hf", 30 } , { "fl", "f\033&a-25Hl", 30 } , { "Fi", "f\033&a-30Hf\033&a-25Hi", 30 } , { "Fl", "f\033&a-30Hf\033&a-25Hl", 30 } , { "ce", "\277", 30 } , */ { "ci", "O", 33 } , { "ul", "_", 35 } , { "ru", "_", 35 } } ; writespec(s) char *s; { int i, nascs = sizeof (asctab) / sizeof (struct asctab); for (i = 0; i < nascs; i++) if (eq(s, asctab[i].a_name)) break; if (i == nascs) { fprintf(stderr, "Error: can't print character '%s'...\n", s); return; } fputs(asctab[i].a_seq, stdout); hmove( - asctab[i].a_width); return; } /* The laserjet uses decipoints, with one decipoint = 720 / 300 pixels. */ #define pixtodec(num) (((num) * 720) / 300) hgoto(num) { if ((num < 0) || (num > hmax)) { fprintf(stderr, "Error: can't hgoto %d\n", num); return; } hpos = num; printf("\033&a%dH", pixtodec(num)); return; } /* This is strange -- ditroff seems to send vgoto's beyond the end of the * page when it wants to go to the end of the page. */ vgoto(num) { if ((num < 0) || (num > vmax)) { /* fprintf(stderr, "Error: can't vgoto %d\n", num); */ /* return; */ num = vmax - 25; /* Fudge... */ } vpos = num; printf("\033&a%dV", pixtodec(num)); return; } hmove(num) { if ((hpos + num < 0) || (hpos + num > hmax)) { fprintf(stderr, "Error: can't hmove %d\n", num); return; } hpos += num; printf("\033&a%c%dH", (num > 0) ? '+' : '-', pixtodec(abs(num))); return; } vmove(num) { if ((vpos + num < 0) || (vpos + num > vmax)) { fprintf(stderr, "Error: can't vmove %d\n", num); return; } vpos += num; printf("\033&a%c%dV", (num > 0) ? '+' : '-', pixtodec(abs(num))); return; } newpage(num) { curpage = num; printf("\n\f"); return; } initprinter() { /* Nothing to do. */ return; } /* Here we assume that the 'B' TMS font cartridge is loaded. */ #define OR_LAND 1 #define OR_PORT 2 #define SY_ROMAN 1 #define SY_KANA 2 #define SY_USASCII 3 #define SY_LINE 4 #define SY_MATH 5 #define SP_FIXED 1 #define SP_PROP 2 #define ST_UPRIGHT 1 #define ST_ITALIC 2 #define SK_LIGHT 1 #define SK_MEDIUM 2 #define SK_BOLD 3 /* Don't change these -- see page 4-22 of the laserjet manual. */ #define TF_LINEPR 0 #define TF_PICA 1 #define TF_ELITE 2 #define TF_COURIER 3 #define TF_HELV 4 #define TF_TMSRMN 5 #define TF_GOTHIC 6 #define TF_SCRIPT 7 #define TF_PRESTIGE 8 struct hpfontinfo { char *fi_name; /* What ditroff calls it. */ int fi_cartridge; /* The one-character cartridge name, 0 = res. */ int fi_orientation; /* OR_LAND or OR_PORT. */ int fi_symbolset; /* SY_ROMAN or SY_USASCII. */ int fi_spacing; /* SP_FIXED or SP_PROP. */ float fi_pitch; float fi_point; int fi_style; /* ST_UPRIGHT or ST_ITALIC. */ int fi_stroke; /* SK_LIGHT, SK_MEDIUM, or SK_BOLD. */ int fi_typeface; /* TF_*. */ int fi_number; /* The number given in 'f' commands. */ } carttab[] = { { "", 0, OR_PORT, SY_ROMAN, SP_FIXED, 10.0, 12.0, ST_UPRIGHT, SK_MEDIUM, TF_COURIER, 0 } , { "", 'B', OR_PORT, SY_USASCII, SP_PROP, 0.0, 14.4, ST_UPRIGHT, SK_BOLD, TF_HELV , 0} , { "R", 'B', OR_PORT, SY_USASCII, SP_PROP, 0.0, 10.0, ST_UPRIGHT, SK_MEDIUM, TF_TMSRMN, 0 } , { "B", 'B', OR_PORT, SY_USASCII, SP_PROP, 0.0, 10.0, ST_UPRIGHT, SK_BOLD, TF_TMSRMN, 0 } , { "I", 'B', OR_PORT, SY_USASCII, SP_PROP, 0.0, 10.0, ST_ITALIC, SK_MEDIUM, TF_TMSRMN, 0 } , { "", 'B', OR_PORT, SY_USASCII, SP_PROP, 0.0, 8.0, ST_UPRIGHT, SK_LIGHT, TF_TMSRMN, 0 } , { "", 'B', OR_LAND, SY_ROMAN, SP_FIXED, 16.66, 8.5, ST_UPRIGHT, SK_LIGHT, TF_LINEPR, 0 } , { "", 0, OR_LAND, SY_ROMAN, SP_FIXED, 10.0, 12.0, ST_UPRIGHT, SK_MEDIUM, TF_COURIER, 0 } } ; loadfont(num, name) char *name; { int i, nfonts = sizeof (carttab) / sizeof (struct hpfontinfo); for (i = 0; i < nfonts; i++) if (eq(name, carttab[i].fi_name)) break; if (i == nfonts) { fprintf(stderr, "Error: no such font as '%s'...\n", name); return; } carttab[i].fi_number = num; return; } setfont(num) { int i, nfonts = sizeof (carttab) / sizeof (struct hpfontinfo); for (i = 0; i < nfonts; i++) if (carttab[i].fi_number == num) break; if (i == nfonts) { fprintf(stderr, "Error: no such font numbered %d...\n", num); return; } curfont = num; /* Now set all the characteristics of this font. */ switch (carttab[i].fi_orientation) { case OR_LAND: fputs("\033&l1O", stdout); break; case OR_PORT: fputs("\033&l0O", stdout); break; default: fprintf(stderr, "Error: bad orientation %d\n...", carttab[i].fi_orientation); return; } switch (carttab[i].fi_symbolset) { case SY_ROMAN: fputs("\033(8U", stdout); break; case SY_KANA: fputs("\033(8K", stdout); break; case SY_USASCII: fputs("\033(0U", stdout); break; case SY_LINE: fputs("\033(0B", stdout); break; case SY_MATH: fputs("\033(0A", stdout); break; default: fprintf(stderr, "Error: bad symbol set %d\n...", carttab[i].fi_symbolset); return; } switch (carttab[i].fi_spacing) { case SP_PROP: fputs("\033(s1P", stdout); break; case SP_FIXED: fputs("\033(s0P", stdout); break; default: fprintf(stderr, "Error: bad spacing %d\n...", carttab[i].fi_spacing); return; } if (carttab[i].fi_pitch > 0.0) printf("\033(s%.2fH", carttab[i].fi_pitch); if (carttab[i].fi_point > 0.0) printf("\033(s%.2fV", carttab[i].fi_point); switch (carttab[i].fi_style) { case ST_ITALIC: fputs("\033(s1S", stdout); break; case ST_UPRIGHT: fputs("\033(s0S", stdout); break; default: fprintf(stderr, "Error: bad style %d\n...", carttab[i].fi_style); return; } switch (carttab[i].fi_stroke) { case SK_LIGHT: fputs("\033(s-3B", stdout); break; case SK_MEDIUM: fputs("\033(s0B", stdout); break; case SK_BOLD: fputs("\033(s3B", stdout); break; default: fprintf(stderr, "Error: bad stroke weight %d\n...", carttab[i].fi_stroke); return; } printf("\033(s%dT", carttab[i].fi_typeface); return; } char * curfontname() { int i, nfonts = sizeof (carttab) / sizeof (struct hpfontinfo); for (i = 0; i < nfonts; i++) if (carttab[i].fi_number == curfont) break; if (i == nfonts) return (NULL); else return (carttab[i].fi_name); } setheight(num) { /* Can't do this apart from setting font... */ fprintf(stderr, "Error: can't set height...\n"); return; } setslant(num) { /* Can't do this apart from setting font... */ fprintf(stderr, "Error: can't set slant...\n"); return; } setsize(num) { /* Can't do this apart from setting font... */ if (num != cursize) fprintf(stderr, "Error: can't set size...\n"); return; } !Funky!Stuff! echo x - width.c cat >width.c <<'!Funky!Stuff!' /* RCS Info: $Revision: $ on $Date: $ * $Source: $ * Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * Permission is granted to do anything with this code except sell it * or remove this message. * * This is a hack to make up for the fact that the laserjet is strange... */ int R_width[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 15, 29, 23, 35, 35, 16, 15, 16, 21, 23, 14, 23, 12, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 10, 12, 24, 25, 24, 21, 38, 35, 29, 31, 34, 30, 28, 36, 35, 16, 20, 37, 30, 42, 35, 33, 26, 33, 34, 22, 30, 37, 34, 38, 36, 33, 31, 13, 21, 14, 24, 35, 12, 21, 25, 21, 25, 21, 19, 23, 25, 14, 17, 25, 13, 36, 25, 22, 25, 24, 17, 17, 15, 25, 24, 34, 24, 24, 20, 16, 8, 17, 25 } ; int B_width[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 18, 28, 24, 38, 34, 12, 17, 19, 17, 24, 13, 23, 13, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 11, 11, 25, 26, 25, 21, 41, 32, 31, 31, 32, 29, 27, 35, 37, 18, 24, 33, 29, 41, 33, 34, 28, 34, 32, 26, 30, 35, 33, 41, 32, 31, 32, 13, 22, 14, 26, 33, 12, 22, 24, 21, 24, 21, 19, 23, 27, 14, 17, 26, 14, 36, 25, 22, 24, 24, 18, 18, 16, 24, 20, 32, 24, 23, 20, 16, 8, 17, 30 } ; int I_width[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 27, 23, 31, 31, 20, 20, 20, 21, 21, 11, 22, 11, 31, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 17, 17, 30, 25, 31, 21, 50, 29, 29, 30, 33, 29, 29, 29, 35, 19, 24, 30, 29, 40, 33, 33, 28, 33, 32, 28, 30, 33, 31, 35, 34, 29, 33, 24, 12, 24, 22, 33, 9, 22, 24, 22, 25, 20, 21, 25, 23, 14, 21, 24, 14, 36, 25, 21, 24, 21, 17, 18, 14, 21, 19, 31, 25, 23, 23, 21, 7, 21, 25 } ; /* This routine returns the width of the character in the given font. It * should really read the device description file... */ askwidth(ch, ft) char *ft; { if (!strcmp(ft, "R")) return (R_width[ch]); else if (!strcmp(ft, "B")) return (B_width[ch]); else if (!strcmp(ft, "I")) return (I_width[ch]); } !Funky!Stuff! echo x - pagereverse.c cat >pagereverse.c <<'!Funky!Stuff!' /* RCS Info: $Revision: 1.1 $ on $Date: 85/10/29 14:44:13 $ * $Source: /cad4/faustus/src/laserjet/RCS/pagereverse.c,v $ * Copyright (c) 1985 Wayne A. Christopher, U. C. Berkeley CAD Group * Permission is granted to do anything with this code except sell it * or remove this message. * * Reverse the pages in a file. Usage is pagereverse [pagelength]. */ #include #define MAXPAGES 10000 main(ac, av) char **av; { register plen = 66, pnum = 0, line = 0, i = 0; long pages[MAXPAGES]; /* The beginning of each page. */ char buf[BUFSIZ]; char *mktemp(), *tempf = "/tmp/prXXXXXX"; FILE *fopen(), *fp; if (ac == 2) { plen = atoi(av[1]); if ((plen <= 0) || (plen > 1000)) { fprintf(stderr, "Usage: %s [pagelen]\n"); exit(1); } } else if (ac > 2) { fprintf(stderr, "Usage: %s [pagelen]\n"); exit(1); } tempf = mktemp(tempf); if (!(fp = fopen(tempf, "w+"))) { perror(tempf); exit(1); } pages[0] = 0; /* Copy all the lines and figure out the page boundaries. */ while (fgets(buf, BUFSIZ, stdin)) { if (line++ == plen - (pnum ? 1 : 0)) { pages[++pnum] = i; line = 0; } if (*buf == '\f') { /* Now we have to expand this as newlines. */ while (line++ <= plen) { putc('\n', fp); } pages[++pnum] = ftell(fp); line = 0; } else { fputs(buf, fp); } i = ftell(fp); } fflush(fp); /* Now go back and output them in reversed order. */ while (pnum >= 0) { fseek(fp, pages[pnum], 0); for (i = 0; i < plen; i++) { if (!fgets(buf, BUFSIZ, fp)) { /* Fill the last page with blank lines... */ while (i++ < plen) putchar('\n'); break; } fputs(buf, stdout); } pnum--; } fclose(fp); unlink(tempf); exit(0); } !Funky!Stuff! echo x - DESC cat >DESC <<'!Funky!Stuff!' # Laserjet Ditroff Description file fonts 3 R I B sizes 10 0 unitwidth 10 # This should be res 300, but ditroff is so screwed up... res 290 hor 2 vert 2 # This is evil -- ditroff ignores these two values completely. paperwidth 2500 paperlength 2500 # I have yet to add the MSB-set characters that the lj accepts -- these # are all simulated with ascii. charset Fi Fl \- \^ \| aa br ce ci dg em en ff fi fl fm ga hy l. or ru ul vr !Funky!Stuff! echo x - R cat >R <<'!Funky!Stuff!' # Tms Rmn name R ligatures 0 # char width u/d octal charset ! 12 2 41 " 15 2 42 # 29 3 43 $ 23 2 44 % 35 2 45 & 35 2 46 ' 16 2 47 ( 15 3 50 ) 16 3 51 * 21 2 52 + 23 2 53 , 14 0 54 - 23 0 55 . 12 0 56 / 21 2 57 0 23 2 60 1 23 2 61 2 23 2 62 3 23 2 63 4 23 2 64 5 23 2 65 6 23 2 66 7 23 2 67 8 23 2 70 9 23 2 71 : 10 0 72 ; 12 0 73 < 24 2 74 = 25 0 75 > 24 2 76 ? 21 2 77 @ 38 2 100 A 35 2 101 B 29 2 102 C 31 2 103 D 34 2 104 E 30 2 105 F 28 2 106 G 36 2 107 H 35 2 110 I 16 2 111 J 20 2 112 K 37 2 113 L 30 2 114 M 42 2 115 N 35 2 116 O 33 2 117 P 26 2 120 Q 33 2 121 R 34 2 122 S 22 2 123 T 30 2 124 U 37 2 125 V 34 2 126 W 38 2 127 X 36 2 130 Y 33 2 131 Z 31 2 132 [ 13 3 133 \ 21 2 134 ] 14 3 135 ^ 24 0 136 _ 35 0 137 ` 12 2 140 a 21 0 141 b 25 2 142 c 21 0 143 d 25 2 144 e 21 0 145 f 19 2 146 g 23 1 147 h 25 2 150 i 14 2 151 j 17 3 152 k 25 2 153 l 13 2 154 m 36 0 155 n 25 0 156 o 22 0 157 p 25 1 160 q 24 1 161 r 17 0 162 s 17 0 163 t 15 2 164 u 25 0 165 v 24 0 166 w 34 0 167 x 24 0 170 y 24 1 171 z 20 0 172 { 16 3 173 | 8 3 174 } 17 3 175 ~ 25 0 176 \| 6 0 0 \^ 2 0 0 em 23 0 0 hy 23 0 0 \- 0 0 0 xxx ce 0 0 0 xxx dg 0 0 0 xxx aa 16 0 0 ga 12 0 0 en 23 0 0 l. 12 0 0 br 8 0 0 vr 8 0 0 fm 16 0 0 or 8 0 0 fi 30 0 0 xxx ff 30 0 0 xxx fl 30 0 0 xxx Fi 30 0 0 xxx Fl 30 0 0 xxx ci 33 0 0 ul 35 0 0 ru 35 0 0 !Funky!Stuff! echo x - I cat >I <<'!Funky!Stuff!' # Tms Rmn Italic name I ligatures 0 # char width u/d octal charset ! 17 2 41 " 17 2 42 # 27 3 43 $ 23 2 44 % 31 2 45 & 31 2 46 ' 20 2 47 ( 20 3 50 ) 20 3 51 * 21 2 52 + 21 2 53 , 11 0 54 - 22 0 55 . 11 0 56 / 31 2 57 0 22 2 60 1 22 2 61 2 22 2 62 3 22 2 63 4 22 2 64 5 22 2 65 6 22 2 66 7 22 2 67 8 22 2 70 9 22 2 71 : 17 0 72 ; 17 0 73 < 30 2 74 = 25 0 75 > 31 2 76 ? 21 2 77 @ 50 2 100 A 29 2 101 B 29 2 102 C 30 2 103 D 33 2 104 E 29 2 105 F 29 2 106 Fi 30 0 0 xxx Fl 30 0 0 xxx G 29 2 107 H 35 2 110 I 19 2 111 J 24 2 112 K 30 2 113 L 29 2 114 M 40 2 115 N 33 2 116 O 33 2 117 P 28 2 120 Q 33 3 121 R 32 2 122 S 28 2 123 T 30 2 124 U 33 2 125 V 31 2 126 W 35 2 127 X 34 2 130 Y 29 2 131 Z 33 2 132 [ 24 3 133 \ 12 2 134 \- 0 0 0 xxx \^ 2 0 0 \| 6 0 0 ] 24 3 135 ^ 22 0 136 _ 33 0 137 ` 9 2 140 a 22 0 141 aa 16 0 0 b 24 2 142 br 8 0 0 c 22 0 143 ce 0 0 0 xxx ci 33 0 0 d 25 2 144 dg 0 0 0 xxx e 20 0 145 em 23 0 0 en 23 0 0 f 21 3 146 ff 30 0 0 xxx fi 30 0 0 xxx fl 30 0 0 xxx fm 16 0 0 g 25 1 147 ga 12 0 0 h 23 2 150 hy 23 0 0 i 14 2 151 j 21 3 152 k 24 2 153 l 14 2 154 l. 12 0 0 m 36 0 155 n 25 0 156 o 21 0 157 or 8 0 0 p 24 1 160 q 21 1 161 r 17 0 162 ru 35 0 0 s 18 0 163 t 14 2 164 u 21 0 165 ul 35 0 0 v 19 0 166 vr 8 0 0 w 31 0 167 x 25 0 170 y 23 1 171 z 23 0 172 { 21 3 173 | 7 3 174 } 21 3 175 ~ 25 0 176 !Funky!Stuff! echo x - B cat >B <<'!Funky!Stuff!' # Tms Rmn Bold name B ligatures 0 # char width u/d octal charset ! 13 2 41 " 18 2 42 # 28 3 43 $ 24 2 44 % 38 2 45 & 34 2 46 ' 12 2 47 ( 17 3 50 ) 19 3 51 * 17 2 52 + 24 2 53 , 13 0 54 - 23 0 55 . 13 0 56 / 22 2 57 0 24 2 60 1 24 2 61 2 24 2 62 3 24 2 63 4 24 2 64 5 24 2 65 6 24 2 66 7 24 2 67 8 24 2 70 9 24 2 71 : 11 0 72 ; 11 0 73 < 25 2 74 = 26 0 75 > 25 2 76 ? 21 2 77 @ 41 2 100 A 32 2 101 B 31 2 102 C 31 2 103 D 32 2 104 E 29 2 105 F 27 2 106 Fi 30 0 0 xxx Fl 30 0 0 xxx G 35 2 107 H 37 2 110 I 18 2 111 J 24 2 112 K 33 2 113 L 29 2 114 M 41 2 115 N 33 2 116 O 34 2 117 P 28 2 120 Q 34 2 121 R 32 2 122 S 26 2 123 T 30 2 124 U 35 2 125 V 33 2 126 W 41 2 127 X 32 2 130 Y 31 2 131 Z 32 2 132 [ 13 3 133 \ 22 2 134 \- 0 0 0 xxx \^ 2 0 0 \| 6 0 0 ] 14 3 135 ^ 26 0 136 _ 33 0 137 ` 12 2 140 a 22 0 141 aa 16 0 0 b 24 2 142 br 8 0 0 c 21 0 143 ce 0 0 0 xxx ci 33 0 0 d 24 2 144 dg 0 0 0 xxx e 21 0 145 em 23 0 0 en 23 0 0 f 19 2 146 ff 30 0 0 xxx fi 30 0 0 xxx fl 30 0 0 xxx fm 16 0 0 g 23 1 147 ga 12 0 0 h 27 2 150 hy 23 0 0 i 14 2 151 j 17 3 152 k 26 2 153 l 14 2 154 l. 12 0 0 m 36 0 155 n 25 0 156 o 22 0 157 or 8 0 0 p 24 1 160 q 24 1 161 r 18 0 162 ru 35 0 0 s 18 0 163 t 16 2 164 u 24 0 165 ul 35 0 0 v 20 0 166 vr 8 0 0 w 32 0 167 x 24 0 170 y 23 1 171 z 20 0 172 { 16 3 173 | 8 3 174 } 17 3 175 ~ 30 0 176 !Funky!Stuff!