home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 Chris Lewis
- All Rights Reserved
-
- See the LICENSE file for a full description of restrictions under which
- this software is provided.
-
- Function: interprets HPLJ sequences.
- */
-
- #ifndef lint
- static char SCCSID[] =
- "@(#)hpinterp.c 2.4 Copyright 91/03/13 22:44:30 Chris Lewis";
- #endif
-
- /* To install:
-
- hpinterp needs to know byte order in shorts. At run time it
- will attempt to figure it out. If you get an abort, or if the
- results are idiotic:
-
- If you are little-endian (eg: 386/pdp-11/vax), define SMALLEND.
- If you are big-endian (eg: pyramid/68000), undef BIGEND.
-
- cc -o hpinterp hpinterp.c
-
- Decide on a directory where you're going to run hpinterp and
- create a directory called "FONTS" (or change the defines for
- BINFILE and DESCFILE to have a better path).
-
- usage:
-
- hpinterp < hpljescapefile > /tmp/output
-
- /tmp/output will contain an englishy *very* verbose listing
- of all of the escape sequences except for the contents of
- font header/download/transfer/raster sequences.
-
- Each font downloaded is caught into a file FONTS/f<fontnumber>
- and a bit of english is saved in FONTS/f<fontnumber>.desc.
- Including some character maps (range restricted by firstchar and
- lastchar). You can turn off the verbose output listing by setting
- verbose to 0. setting "debug" to 1 (if verbose is 1 too), prints
- ESC<string> sequences as well as the english.
-
- (One of these days I'll get it to do all of this stuff by command
- line options....)
- */
- #include <stdio.h>
- #include <ctype.h>
- #undef BIGEND
- #undef SMALLEND
- #define dbprintf(x) if (verbose) printf x
- #define ESCAPE 0x1b
-
- #define uchar unsigned char
- int firstchar = 0;
- int lastchar = 0xff;
-
- typedef int(*FUNC)();
-
- int lastschar;
- int lastfontid;
-
- double curX = 0, curY = 0;
- int emitting = 0;
-
- FILE *out = (FILE *) NULL;
- FILE *txtout = (FILE *) NULL;
- int count = 0;
- int verbose = 0;
- int debug = 0;
- int genps = 0;
- int chars = 0;
- int characteristic = 1;
- int ps_symset = 0;
-
- short canon();
-
- readhex(len)
- int len; {
- while(len--) GETCHAR();
- }
-
- GETCHAR() {
- int c;
- c = getchar();
- #ifdef DEBUG
- if (isprint(c))
- printf("GETCHAR: %c\n", c);
- else
- printf("GETCHAR: %02x\n", c);
- #endif
- return(c);
- }
-
- #define TRANSFER 1
- #define TRANSPARENT 2
- #define FONTHEADER 3
- #define DOWNLOAD 4
- struct fontdesc {
- short f1;
- uchar f2;
- uchar fd_type;
- short f3;
- short fd_base;
- short fd_cellwidth;
- short fd_cellheight;
- uchar fd_orientation;
- uchar fd_fixedprop;
- short fd_symset;
- short fd_pitch;
- short fd_height;
- short f4;
- uchar f5;
- uchar fd_style;
- uchar fd_weight;
- uchar fd_typeface;
- };
-
- struct download {
- uchar f1;
- uchar f2;
- uchar f3;
- uchar f4;
- uchar dl_orientation;
- short dl_leftoffset;
- short dl_topoffset;
- short dl_charwidth;
- short dl_charheight;
- short dl_deltax;
- uchar dl_data[1];
- };
-
- char *fchcont[] = {
- "Delete all fonts",
- "Delete all temporary fonts",
- "Delete last font ID specified",
- "Delete last font ID and char code",
- "Make Temp font",
- "Make Perm font",
- "Copy/Assign",
- NULL};
- char *spcont[] = {
- "Fixed",
- "Proportional",
- NULL};
- char *stcont[] = {
- "Upright",
- "Italic",
- NULL};
- char *tfcont[] = {
- "Line Printer",
- "Pica",
- "Elite",
- "Courier",
- "Helvetica",
- "Times Roman",
- "Gothic",
- "Script",
- "Prestige Elite",
- "Caslon",
- "Orator",
- NULL};
- char *sgcont[] = {
- "Left-most position",
- "Current Cursor",
- NULL};
- char *pscont[] = {
- "Disable",
- "Enable",
- NULL};
-
-
- int movex(),movey(), papinctrl(), movedx(), movedy();
- int spset(), psset(), styset(), strset(), tfset();
-
- struct intlist {
- char *code;
- char *name;
- char **parmnames;
- FUNC exec;
- } intlist[] = {
- {"&lO", "Orientation"},
- {"(sP", "Spacing", spcont, spset},
- {"(sH", "Pitch"},
- {"(sV", "Point Size", NULL, psset},
- {"(sS", "Style", stcont, styset},
- {"(sB", "Stroke", NULL, strset},
- {"(sT", "Typeface", tfcont, tfset},
- {"&lP", "Page Length"},
- {"&lE", "Top Margin"},
- {"&lF", "Text Length"},
- {"&aL", "Left Margin"},
- {"&aM", "Right Margin"},
- {"&lC", "Motion Index"},
- {"&lD", "Lines/Inch"},
- {"*tR", "Resolution"},
- {"*rA", "Start Graphics", sgcont},
- {"*bW", "Transfer"},
- {"*rB", "End Graphics"},
- {"&aR", "Move to Row"},
- {"&aC", "Move to Column"},
- {"&aH", "Move to Column (Decipoints)", NULL, movex},
- {"&aV", "Move to Row (Decipoints)", NULL, movey},
- {"&dD", "Underline on"},
- {"&d@", "Underline off"},
- {"&pX", "Transparent Print"},
- {"&lL", "Perf Skip", pscont},
- {"&kH", "HMI"},
- {"&kS", "Font Pitch"},
- {"&kG", "Line Termination"},
- {"&sC", "Line Wrap"},
- {"&lX", "Number of Copies"},
- {"&lH", "Paper Input Control", NULL, papinctrl},
- {"*pX", "Horizontal cursor (dots)", NULL, movedx},
- {"*pY", "Vertical cursor (dots)", NULL, movedy},
- {"*cD", "Font ID"},
- {"*cE", "Character Code"},
- {"*cF", "Font/Char control", fchcont},
- {")sW", "Create Font Header"},
- {"(sW", "Download Character"},
- {"&fY", "Macro ID"},
- {"&fX", "Macro control"},
- {"&fS", "Push/Pop"},
- {"*cA", "Horizontal Rule/Pattern Size"},
- {"*cH", "Horizontal Rule/Pattern Size"},
- {"*cB", "Vertical Rule/Pattern Size"},
- {"*cV", "Vertical Rule/Pattern Size"},
- {"*cP", "Print Rule/Pattern"},
- {"*cG", "Grey scale/pattern id"},
- {"&lT", "Job offset control"},
- {NULL,NULL}
- };
-
- union {
- struct fontdesc b_fd;
- struct download b_dl;
- char b_buffer[2048];
- } buffer;
-
- interp(prefix, anchor, number, suffix)
- char prefix, anchor, suffix;
- double number; {
- int multi;
- register int i;
- char lookup[4];
-
- if (debug)
- dbprintf(("ESC%c%c%g%c\n", prefix, anchor, number, suffix));
-
- if (islower(suffix))
- suffix = toupper(suffix);
-
- sprintf(lookup, "%c%c%c", prefix, anchor, suffix);
- for (i = 0; intlist[i].code; i++) {
- if (0 == strcmp(intlist[i].code, lookup)) {
- dbprintf(("%s:", intlist[i].name));
- if (intlist[i].parmnames) {
- int j;
- for (j = 0; j < number; j++) {
- if (!intlist[i].parmnames[j])
- break;
- }
- if (intlist[i].parmnames[j]) {
- dbprintf((" %s\n", intlist[i].parmnames[j]));
- } else {
- dbprintf((" %d\n", (int) number));
- }
- } else {
- dbprintf ((" %g\n", number));
- }
- if (intlist[i].exec)
- (*intlist[i].exec)(number);
- break;
- }
- }
-
- multi = 0;
- /* For parsing variable length ones */
- switch(prefix) {
- case '*':
- if (anchor == 'b' && suffix == 'W')
- multi = TRANSFER;
- break;
- case '&':
- if (anchor == 'p' && suffix == 'X')
- multi = TRANSPARENT;
- break;
- case ')':
- if (anchor == 's' && suffix == 'W')
- multi = FONTHEADER;
- break;
- case '(':
- if (anchor == 's' && suffix == 'W')
- multi = DOWNLOAD;
- break;
- }
- if (prefix == '*' && anchor == 'c' && suffix == 'E') {
- lastschar = number;
- }
- if (prefix == '*' && anchor == 'c' && suffix == 'D') {
- lastfontid = number;
- }
- if (multi)
- readdesc(multi, (int) number);
- }
-
- #ifdef SMALLEND
- #define smallend 1
- #endif
- #ifdef BIGEND
- #define smallend 0
- #endif
-
- #if !defined(SMALLEND) && !defined(BIGEND)
- union t {
- char a[2];
- short b;
- };
- int smallend;
- #endif
-
- short
- canon(v)
- short v; {
- if (smallend) {
- return(((v & 0xff) << 8) | ((v&0xff00) >> 8));
- } else
- return(v);
- }
-
- #define BINFILE "FONTS/f%d"
- #define DESCFILE "FONTS/f%d.desc"
-
- readdesc(type, bytecount)
- int type; int bytecount; {
- int points;
- char *typeface;
- char *style;
- char filename[1000];
- switch(type) {
- default:
- readhex(bytecount);
- break;
- case DOWNLOAD:
- fread((char *) &buffer, 1, bytecount, stdin);
- sprintf(filename, BINFILE, lastfontid);
- if (out) fclose(out);
- if ((out = fopen(filename, "a")) == NULL) {
- fprintf(stderr, "Can't open %s\n", filename);
- out = NULL;
- }
- sprintf(filename, DESCFILE, lastfontid);
- if (txtout) fclose(txtout);
- if ((txtout = fopen(filename, "a")) == NULL) {
- fprintf(stderr, "Can't open %s\n", filename);
- txtout = NULL;
- }
- if (lastschar >= firstchar && lastschar <= lastchar) {
- if (txtout) {
- fprintf(txtout, "Character: %c\n", lastschar);
- fprintf(txtout, " orientation: %d\n",
- buffer.b_dl.dl_orientation);
- fprintf(txtout, " leftoffset: %d\n",
- canon(buffer.b_dl.dl_leftoffset));
- fprintf(txtout, " topoffset: %d\n",
- canon(buffer.b_dl.dl_topoffset));
- fprintf(txtout, " charwidth: %d\n",
- canon(buffer.b_dl.dl_charwidth));
- fprintf(txtout, " charheight: %d\n",
- canon(buffer.b_dl.dl_charheight));
- fprintf(txtout, " deltax: %d\n",
- canon(buffer.b_dl.dl_deltax));
- if (chars)
- plotchars(txtout, &buffer.b_dl);
- }
- }
- if (out) {
- fprintf(out, "\033*c%dE", lastschar);
- fprintf(out, "\033(s%dW", bytecount);
- fwrite((char *) &buffer, 1, bytecount, out);
- }
- break;
-
- case FONTHEADER:
- if (txtout) fclose(txtout);
- if (out) fclose(out);
-
- fread((char *) &buffer, 1, bytecount, stdin);
- points = (double) canon(buffer.b_fd.fd_height) * 72 / 4 / 300 + .5;
- switch(buffer.b_fd.fd_typeface) {
- case 0: typeface = "Line Printer"; break;
- case 1: typeface = "Pica"; break;
- case 2: typeface = "Elite"; break;
- case 3: typeface = "Courier"; break;
- case 4: typeface = "Helvetica"; break;
- case 5: typeface = "Times-Roman"; break;
- case 6: typeface = "Gothic"; break;
- case 7: typeface = "Script"; break;
- case 8: typeface = "Prestige"; break;
- case 9: typeface = "Caslon"; break;
- case 10: typeface = "Orator"; break;
- default: typeface = " ";
- sprintf(typeface, "T%d", buffer.b_fd.fd_typeface);
- break;
- }
- switch(buffer.b_fd.fd_style) {
- case 0:
- style = "Upright";
- break;
- case 1:
- style = "Italic";
- break;
- }
- sprintf(filename, BINFILE, lastfontid);
- if ((out = fopen(filename, "w")) == NULL) {
- fprintf(stderr, "Can't open %s\n", filename);
- out = NULL;
- }
- sprintf(filename, DESCFILE, lastfontid);
- if ((txtout = fopen(filename, "w")) == NULL) {
- fprintf(stderr, "Can't open %s\n", filename);
- txtout = NULL;
- }
- /*fprintf(out, "\033*c%dD", lastfontid);*/
- fprintf(out, "\033)s%dW", bytecount);
- fwrite((char *) &buffer, 1, bytecount, out);
- if (txtout) {
- fprintf(txtout, "Height: %d\n", canon(buffer.b_fd.fd_height));
- fprintf(txtout, " Points (rounded): %d\n", points);
- fprintf(txtout, " Points (floating): %.2f\n",
- (double) canon(buffer.b_fd.fd_height) * 72 / 4 / 300);
- fprintf(txtout, "Pitch: %d\n", canon(buffer.b_fd.fd_pitch));
- fprintf(txtout, " Pitch (chars/inch): %d\n",
- 4 * 300 / canon(buffer.b_fd.fd_pitch));
- if (buffer.b_fd.fd_fixedprop)
- fprintf(txtout, "Proportional width font\n");
- else
- fprintf(txtout, "Fixed width font\n");
- fprintf(txtout, "Stroke weight: %d\n", buffer.b_fd.fd_weight);
- fprintf(txtout, "Style: %d; (%s)\n", buffer.b_fd.fd_style,
- style);
- fprintf(txtout, "Typeface: %d; (%s)\n", buffer.b_fd.fd_typeface,
- typeface);
- fprintf(txtout, "Symset: %04x; (%d%c)\n",
- canon(buffer.b_fd.fd_symset),
- canon(buffer.b_fd.fd_symset) >> 5,
- (canon(buffer.b_fd.fd_symset) & 0x1f) + 'A' - 1);
-
- fprintf(txtout, "Type: %x\n", buffer.b_fd.fd_type);
- fprintf(txtout, "Base: %d\n", canon(buffer.b_fd.fd_base));
- fprintf(txtout, "Cellwidth: %d\n", canon(buffer.b_fd.fd_cellwidth));
- fprintf(txtout, "Cellheight: %d\n", canon(buffer.b_fd.fd_cellheight));
- fprintf(txtout, "Orientation: %d\n", buffer.b_fd.fd_orientation);
- fprintf(txtout, "Height: %d\n", canon(buffer.b_fd.fd_height));
- }
- }
- }
-
- plotchars(f, dl)
- struct download *dl;
- FILE *f; {
- short x, y, bx, by, bytes, byteindex, bitindex, bit;
- bytes = (canon(dl->dl_charwidth) + 7) / 8;
- for (y = 0; y < canon(dl->dl_charheight); y++) {
- fprintf(f, " ");
- for (x = 0; x < (canon(dl->dl_charwidth) + canon(dl->dl_leftoffset));
- x++) {
- bx = x - canon(dl->dl_leftoffset);
- by = y;
- if (bx >= 0) {
- byteindex = bytes * by + bx / 8;
- bitindex = (7 - (bx % 8));
- if (dl->dl_data[byteindex] & (1 << bitindex))
- bit = 'X';
- else
- bit = ' ';
- } else
- bit = ' ';
- if (x == 0 && y == canon(dl->dl_topoffset))
- bit = '+';
- if (bit == ' ' && y == canon(dl->dl_topoffset))
- bit = '=';
- fputc(bit, f);
- }
- fputc('\n',f);
- }
- }
-
-
- /* We've got ESC<prefix><anchor>
- * read number/suffix pairs
- */
- multisequence(prefix, anchor)
- char prefix, anchor; {
- int c, neg, seendot;
- double v;
- while(1) {
- v = 0;
- seendot = 0;
- neg = 1;
- while(isdigit(c = GETCHAR()) || (c == '.') || (c == '-') || (c == '+')) {
- if (c == '+') {
- continue;
- }
- if (c == '.') {
- seendot = 10;
- continue;
- }
- if (c == '-') {
- neg *= -1;
- continue;
- }
- if (seendot) {
- v += (double) (c - '0') / seendot;
- seendot *= 10;
- } else
- v = v * 10 + c - '0';
- }
- v *= neg;
- interp(prefix, anchor, v, c);
- if (!islower(c))
- break;
- }
- }
-
- printhex(buf, n)
- char *buf; int n; {
- int i;
- dbprintf(("SEQ:"));
- for (i = 0; i < n; i++) {
- if (isprint(buf[i]))
- putchar(buf[i]);
- else {
- dbprintf(("\\%02x", buf[i]));
- }
- }
- dbprintf(("\n"));
- }
-
- short pts[] = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 28, 36, 4, 4};
- readescape() {
- int c, v, v1, v2, v3;
- c = GETCHAR();
- switch(c) {
- case '9':
- dbprintf(("Clear Margins\n"));
- return;
- case '=':
- dbprintf(("Half linefeed\n"));
- return;
- case 'E':
- dbprintf(("Reset\n"));
- return;
- case 'z':
- dbprintf(("Self test\n"));
- return;
- case 'Y':
- dbprintf(("Display functions on\n"));
- return;
- case 'Z':
- dbprintf(("Display functions off\n"));
- return;
- case ')':
- c = GETCHAR();
- if (isdigit(c)) {
- v = 0;
- while(isdigit(c)) {
- v = v * 10 + c - '0';
- c = GETCHAR();
- }
- switch(c) {
- case 'X':
- dbprintf(("Secondary font %d\n", v));
- break;
- case '@':
- dbprintf(("Secondary font value %d\n", v));
- break;
- default:
- dbprintf(("HUH ESC)%d%c\n", v, c));
- }
- return;
- }
- multisequence(')', c);
- return;
- case '(':
- c = GETCHAR();
- if (isdigit(c)) {
- v = 0;
- while(isdigit(c)) {
- v = v * 10 + c - '0';
- c = GETCHAR();
- }
- switch(c) {
- case 'X':
- dbprintf(("Primary font %d\n", v));
- if (genps) {
- endemit();
- characteristic = 0;
- printf("/f%d findfont %d scalefont setfont\n",
- v, pts[v&0xf]);
- }
- break;
- case '@':
- dbprintf(("Primary font value %d\n", v));
- break;
- default:
- dbprintf(("Symbol set: %d%c\n", v, c));
- ps_symset = c;
- }
- return;
- }
- multisequence('(', c);
- return;
- case '&':
- c = GETCHAR();
- multisequence('&', c);
- return;
- case '*':
- c = GETCHAR();
- multisequence('*', c);
- return;
- default:
- dbprintf(("Huh? %02x\n", c));
- return;
- }
- }
-
- main(argc, argv)
- int argc; char **argv; {
- int c;
- extern char *optarg;
-
- #if !defined(BIGEND) && !defined(SMALLEND)
- union t ta;
- ta.a[0] = 0x01;
- ta.a[1] = 0x02;
- smallend = ((ta.b&0xff) == 0x01);
- #endif
- while((c = getopt(argc, argv, "dpv")) != EOF)
- switch(c) {
- case 'p':
- genps++;
- break;
- case 'v':
- verbose++;
- break;
- case 'd':
- debug++;
- break;
- case '?':
- fprintf(stderr, "usage: hpinterp [-d][-p][-v]< file");
- exit(1);
- }
-
-
- if (genps) {
- printf("/M { moveto } def\n");
- printf("/S { show } def\n");
- }
- while((c = GETCHAR()) != EOF) {
- if (c == ESCAPE) {
- readescape();
- } else {
- if (isprint(c)) {
- dbprintf(("Char: %c\n", c));
- } else {
- dbprintf(("Char: 0x%02x\n", c));
- }
- emitchar(c);
- }
- }
- if (out) fclose(out);
- if (txtout) fclose(txtout);
- endemit();
- }
-
- movex(num)
- double num; {
- curX = num;
- endemit();
- }
-
- movey(num)
- double num; {
- curY = num;
- endemit();
- }
-
- movedx(num)
- double num; {
- curX = num * 720 / 300;
- endemit();
- }
-
- movedy(num)
- double num; {
- curY = num * 720 / 300;
- endemit();
- }
-
- emitchar(c)
- int c; {
- if (!genps)
- return;
-
- if (characteristic)
- selchar();
-
- if (!emitting)
- printf("%g %g M(", curX/10, (72 * 11) - (curY/10));
-
- emitting = 1;
-
- switch(c) {
- case '(': case ')': case '\\':
- printf("\\%c", c);
- break;
- default:
- if (c > ' ' && c < 0x7e)
- printf("%c", c);
- else
- printf("\\%03o", c&0xff);
- break;
- }
- }
-
- endemit() {
- if (emitting)
- printf(")S\n");
- emitting = 0;
- }
-
- papinctrl(num)
- double num; {
- int n = num;
- if (num == 0) {
- endemit();
- if (genps)
- printf("showpage\n");
- }
- }
-
- int ps_pointsize = 10;
- int ps_style = 1;
- int ps_stroke = 0;
- int ps_tface = 5;
- int ps_spacing = 0;
-
- spset(num)
- double num; {
- ps_spacing = num;
- characteristic = 1;
- endemit();
- }
- psset(num)
- double num; {
- characteristic = 1;
- ps_pointsize = num;
- endemit();
- }
- styset(num)
- double num; {
- characteristic = 1;
- ps_style = num;
- endemit();
- }
- strset(num)
- double num; {
- characteristic = 1;
- ps_stroke = num;
- endemit();
- }
- tfset(num)
- double num; {
- characteristic = 1;
- ps_tface = num;
- endemit();
- }
-
- #define TMS "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic"
- #define COUR "Courier", "Courier-Oblique", "Courier-Bold",\
- "Courier-BoldOblique"
- #define HELV "Helvetica", "Helvetica-Oblique", "Helvetica-Bold",\
- "Helvetica-BoldOblique"
-
- #define LAST 7
-
- char *fonts[LAST][4] = {{COUR}, {COUR}, {COUR}, {COUR}, {HELV}, {TMS},
- {COUR}};
-
- selchar() {
- int idx = 0;
- char **font;
- char *p;
- #ifdef NEVER
- printf("ps_pointsize: %d\n", ps_pointsize);
- printf("ps_style: %d\n", ps_style);
- printf("ps_stroke: %d\n", ps_stroke);
- printf("ps_symset: %d\n", ps_symset);
- printf("ps_tface: %d\n", ps_tface);
- printf("ps_spacing: %d\n", ps_spacing);
- #endif
- if (ps_tface == 4101) /* CG Roman on LJ III */
- ps_tface = 5;
- if (ps_tface == 4148) /* CG Univers (Helvetica like) Roman on LJ III */
- ps_tface = 4;
- if (ps_tface >= LAST || ps_tface < 0)
- ps_tface = 3;
- idx = 0;
- if (ps_stroke > 0)
- idx = 2;
- if (ps_style != 0)
- idx++;
- if (ps_symset == 'M')
- p = "Symbol";
- else
- p = fonts[ps_tface][idx];
- printf("/%s findfont %d scalefont setfont\n", p, ps_pointsize);
- characteristic = 0;
- }
-