|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 13638 (0x3546) Types: TextFile Names: »psdvi.c«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦this⟧ »./DVIware/laser-setters/dvi2adobe_fonts/psdvi.c« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/laser-setters/dvi2adobe_fonts/psdvi.c«
#ifndef LINT static char *rcs_header = "$Header: psdvi.c,v 1.5 87/11/27 16:39:25 elwell Exp $"; #endif /* * psdvi -- convert TeX DVI files to PostScript * * Written by Clayton M. Elwell, The Ohio State University * * Edit History: * * $Log: psdvi.c,v $ * Revision 1.5 87/11/27 16:39:25 elwell * Split out PostScript prologue into separate file * * Revision 1.4 87/09/17 22:13:53 elwell * Cleaned up PostScript prologue * * Revision 1.3 87/07/30 12:21:43 elwell * Fixed bug in font scaling (TeX points vs. PostScript points) * * Revision 1.2 87/07/29 11:23:02 elwell * Added support for oblique (slanted) fonts. The PostScript * macro that implements this was written by L.A. Carr (as far * as I can tell). * * Revision 1.1 87/07/14 19:11:07 elwell * Initial revision * * */ #include <stdio.h> char *malloc(); #ifdef BSD #include <pwd.h> #include <strings.h> #endif char profile[80] = "/usr/local/lib/ps/psdvi.pro"; #define SETC_000 0 #define SETC_127 127 #define SET1 128 #define SET2 129 #define SET3 130 #define SET4 131 #define SET_RULE 132 #define PUT1 133 #define PUT2 134 #define PUT3 135 #define PUT4 136 #define PUT_RULE 137 #define NOP 138 #define BOP 139 #define EOP 140 #define PUSH 141 #define POP 142 #define RIGHT1 143 #define RIGHT2 144 #define RIGHT3 145 #define RIGHT4 146 #define W0 147 #define W1 148 #define W2 149 #define W3 150 #define W4 151 #define X0 152 #define X1 153 #define X2 154 #define X3 155 #define X4 156 #define DOWN1 157 #define DOWN2 158 #define DOWN3 159 #define DOWN4 160 #define Y0 161 #define Y1 162 #define Y2 163 #define Y3 164 #define Y4 165 #define Z0 166 #define Z1 167 #define Z2 168 #define Z3 169 #define Z4 170 #define FONT_00 171 #define FONT_63 234 #define FNT1 235 #define FNT2 236 #define FNT3 237 #define FNT4 238 #define XXX1 239 #define XXX2 240 #define XXX3 241 #define XXX4 242 #define FNT_DEF1 243 #define FNT_DEF2 244 #define FNT_DEF3 245 #define FNT_DEF4 246 #define PRE 247 #define POST 248 #define POST_POST 249 char *program_name; FILE *dvi_file; open_dvi_file(s) char *s; { dvi_file = fopen(s, "r"); if (!dvi_file) error("Unable to open DVI file %s", s); } #define set_dvi_file_pos(i) fseek(dvi_file, (long) (i), 0) #define get_dvi_file_pos() ftell(dvi_file) get_byte() /* get a byte from the DVI file, unsigned */ { register int i; if ((i = getc(dvi_file)) == EOF) error("unexpected end of file on DVI file"); return i & 255; } signed_byte() { register int i; i = get_byte(); if (i > 127) i -= 256; return i; } get_two_bytes() { register int c1, c2; c1 = get_byte(); c2 = get_byte(); return c1 * 256 + c2; } signed_pair() { register int c1, c2; c1 = signed_byte(); c2 = get_byte(); return c1 * 256 + c2; } get_three_bytes() { register int c1, c2 ,c3; c1 = get_byte(); c2 = get_byte(); c3 = get_byte(); return (c1 * 256 + c2) * 256 + c3; } get_signed_trio() { register int c1, c2, c3; c1 = signed_byte(); c2 = get_byte(); c3 = get_byte(); return (c1 * 256 + c2) * 256 + c3; } signed_quad() { int i; register int c1, c2, c3, c4; c1 = signed_byte(); c2 = get_byte(); c3 = get_byte(); c4 = get_byte(); i = ((c1*256+c2)*256+c3)*256+c4; return i; } get_dvi_str(l, s) int l; char *s; { int i; for (i = 0; i < l; i++) s[i] = get_byte(); s[i] = 0; } include_file(s) char *s; { FILE *fp; int c; if (!(fp = fopen(s, "r"))) return -1; while ((c = getc(fp)) != EOF) putchar(c); fclose(fp); return 0; } double mag; write_preamble_comment() { register int byte1, byte2; #ifdef BSD struct passwd *pw; char h[80]; #endif byte1 = get_byte(); byte2 = get_byte(); if (byte1 != PRE || byte2 != 2) error ("input file is not a DVI file"); set_dvi_file_pos(14); printf("%%%%Creator: "); byte1 = get_byte(); while (byte1--) putchar(get_byte()); putchar('\n'); #ifdef BSD pw = getpwuid(getuid()); gethostname(h, 80); if (index(pw->pw_gecos, ',')) *(index(pw->pw_gecos, ',')) = 0; printf("%%%%For: %s@%s (%s)\n", pw->pw_name, h, pw->pw_gecos); #endif } scmp(s1, s2) char **s1; char **s2; { return strcmp(*s1, *s2); } int last_bop_pointer; double conv, true_conv, mag; load_postamble_and_fonts() { int pos, op, dvi_mag, numerator, denominator, max_v, max_h, max_s, total_pages, p; int scaled, design; int waste, length; char str[200]; char *ftab[500]; int nfonts, i; /* find postamble */ fseek(dvi_file, -5L, 2); /* find end of file - 5 */ pos = get_dvi_file_pos(); for (op = get_byte(); op == 223;) { pos--; set_dvi_file_pos(pos); op = get_byte(); } set_dvi_file_pos(pos - 4); pos = signed_quad(); /* load postamble proper */ set_dvi_file_pos(pos + 1); /* just past the POST command */ last_bop_pointer = signed_quad(); numerator = signed_quad(); denominator = signed_quad(); dvi_mag = signed_quad(); mag = ((double) dvi_mag) / 1000.0; conv = (((double) numerator)/254000.0)*(72.0/((double) denominator)); true_conv = conv; conv = true_conv * mag; max_v = signed_quad(); max_h = signed_quad(); max_s = get_two_bytes(); total_pages = get_two_bytes(); pos = get_dvi_file_pos(); printf("%%%%DocumentFonts:"); nfonts = 0; for (op = get_byte(); op != POST_POST; op = get_byte()) { if (op >= FNT_DEF1 && op <= FNT_DEF4) { p = first_par(op); signed_quad(); scaled = signed_quad(); design = signed_quad(); waste = get_byte(); length = get_byte() + waste; get_dvi_str(length, str); for (i = 0; i < nfonts; i++) if (!strcmp(str, ftab[i])) break; if (i == nfonts) { ftab[i] = malloc(strlen(str)+1); strcpy(ftab[i], str); nfonts++; } } } qsort(ftab, nfonts, sizeof(char *), scmp); puts(ftab[0]); for (i = 1; i < nfonts; i++) { printf("%%%%+%s\n", ftab[i]); free(ftab[i]); } set_dvi_file_pos(pos); printf("%%%%Pages: %d\n%%%%EndComments\n", total_pages); include_file(profile); for (op = get_byte(); op != POST_POST; op = get_byte()) { if (op >= FNT_DEF1 && op <= FNT_DEF4) { p = first_par(op); signed_quad(); scaled = signed_quad(); design = signed_quad(); waste = get_byte(); length = get_byte() + waste; get_dvi_str(length, str); /* notice correction factor between TeX and PostScript points */ printf("/f%d { %g /%s tf } def\n", p, (((double)scaled)/((double)design))*mag*0.996264010, str); } } puts("%%EndProlog"); } first_par(o) int o; { if (o >= SETC_000 && o <= SETC_127) return (o - SETC_000); if (o >= FONT_00 && o <= FONT_63) return (o - FONT_00); switch (o) { case SET1: case PUT1: case FNT1: case XXX1: case FNT_DEF1: return get_byte(); case SET2: case PUT2: case FNT2: case XXX2: case FNT_DEF2: return get_two_bytes(); case SET3: case PUT3: case FNT3: case XXX3: case FNT_DEF3: return get_three_bytes(); case RIGHT1: case W1: case X1: case DOWN1: case Y1: case Z1: return signed_byte(); case RIGHT2: case W2: case X2: case DOWN2: case Y2: case Z2: return signed_pair(); case RIGHT3: case W3: case X3: case DOWN3: case Y3: case Z3: return get_signed_trio(); case SET4: case SET_RULE: case PUT4: case PUT_RULE: case RIGHT4: case W4: case X4: case DOWN4: case Y4: case Z4: case FNT4: case XXX4: case FNT_DEF4: return signed_quad(); case W0: return 0; case X0: return 0; case Y0: return 0; case Z0: return 0; case NOP: case BOP: case EOP: case PUSH: case POP: case PRE: case POST: case POST_POST: default: return 0; } } char cur_name[200]; int first_bop_pointer; find_starting_page() { int p, found, counts_match, i; found = 0; for (p = last_bop_pointer; p >= 0; p = signed_quad()) { set_dvi_file_pos(p + 1); /* move to byte after BOP */ /* match counts against starting page spec -- ignore for now */ for (i = 0; i < 10; i++) signed_quad(); first_bop_pointer = p; found = 1; } if (!found) error ("Starting page number could not be found"); } int cur_font; process_pages() { char waste_string[200]; /* string shaped waste basket */ int waste; /* integer shaped waste basket */ int beginning_of_page, pages_processed, fonts_on_page, op, p; int k, f, width, pxl_height, pxl_width; int length; int scaled_size, design_size; set_dvi_file_pos(first_bop_pointer); pages_processed = 0; for (op = get_byte(); op != POST; op = get_byte()) { switch (op) { case BOP: printf("%%%%Page: %d %d\nbop ", signed_quad(), pages_processed+1); /* process one page */ /* toss out extra counts and the back pointer */ for (k = 0; k < 10; k++) signed_quad(); for (op = get_byte(); op != EOP; op = get_byte()) { /* interpret one command */ nxtcmd: if (op >= SETC_000 && op <= SETC_127) { putchar('('); while (op <= 128) { if (op == 128) { p = get_byte(); printf("\\%c%c%c", p/0100 + '0', ((p/010) & 7) + '0', (p & 7)+'0'); } else if (op != '\\' && op != '(' && op != ')') putchar(op); else { putchar('\\'); putchar(op); } op = get_byte(); switch (op) { case W0: putchar(' '); op = get_byte(); break; } } puts(")s"); goto nxtcmd; } else if ((op >= FONT_00 && op <= FONT_63) || (op >= FNT1 && op <= FNT4)) { p = first_par(op); printf("f%d ", p); } else { p = first_par(op); /* get first parameter */ switch (op) { case SET1: case SET2: case SET3: case SET4: printf("(\\%c%c%c)s ", p/0100 + '0', ((p/010) & 7) + '0', (p & 7)+'0'); break; case PUT1: case PUT2: case PUT3: case PUT4: printf("(\\%c%c%c)p ", p/0100 + '0', ((p/010) & 7) + '0', (p & 7)+'0'); break; case SET_RULE: /* output rule and move, height in p */ width = signed_quad(); printf("%g %g rl\n", conv*(double)width, conv*(double)p); break; case PUT_RULE: /* output rule, height in p */ width = signed_quad(); printf("%g %g pr\n", conv*(double)width, conv*(double)p); break; case NOP: break; case PUSH: printf("S "); break; case POP: printf("R "); break; case X0: printf("x0 "); break; case X1: case X2: case X3: case X4: printf("%g xs ", conv*(double)p); break; case W0: printf("w0 "); break; case W1: case W2: case W3: case W4: printf("%g ws ", conv*(double)p); break; case RIGHT1: case RIGHT2: case RIGHT3: case RIGHT4: printf("%g r ", conv*(double)p); break; case Z0: printf("z0 "); break; case Z1: case Z2: case Z3: case Z4: printf("%g zs ", conv*(double)p); break; case Y0: printf("y0 "); break; case Y1: case Y2: case Y3: case Y4: printf("%g ys ", conv*(double)p); break; case DOWN1: case DOWN2: case DOWN3: case DOWN4: printf("%g d ", conv*(double)p); break; case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4: signed_quad(); scaled_size = signed_quad(); design_size = signed_quad(); waste = get_byte(); length = get_byte()+waste; get_dvi_str(length, waste_string); /* printf("/f%d { %g /%s tf } def\n", p, ((double)scaled_size)/ ((double)design_size), waste_string); */ break; case XXX1: case XXX2: case XXX3: case XXX4: get_dvi_str(p, waste_string); do_special(waste_string); break; default: error("Unknown or misplaced DVI command: %d", op); break; } } } puts("eop"); /* page separator */ pages_processed++; break; case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4: p = first_par(op); /* skip external font no. */ signed_quad(); scaled_size = signed_quad(); design_size = signed_quad(); waste = get_byte(); length = get_byte()+waste; get_dvi_str(length, waste_string); /* printf("/f%d { %g /%s tf } def\n", p, ((double)scaled_size)/ ((double)design_size), waste_string); */ break; } } puts("%%Trailer"); } main(argc, argv) int argc; char **argv; { int i; program_name = argv[0]; if (argc != 2) { fprintf(stderr, "usage: %s dvi-file\n", argv[0]); exit(-1); } printf("%%!PS-Adobe-1.0\n%%%%Title: %s\n", argv[1]); open_dvi_file(argv[1]); write_preamble_comment(); load_postamble_and_fonts(); find_starting_page(); process_pages(); } error(s, a1, a2, a3, a4, a5, a6, a7, a8, a9) char *s; int a1, a2, a3, a4, a5, a6, a7, a8, a9; { fprintf(stderr, "%s: ", program_name); fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7, a8, a9); putc('\n', stderr); exit(-1); } do_special(s) char *s; { FILE *fp; int c; if (s[0] != '!') { puts(s); return; } if (!strncmp(s, "!include", 8)) { if (include_file(s+9)) { fprintf(stderr, "%s: WARNING: cannot include file %s\n", program_name, s+9); return; } } else puts(s); }