|
|
1.1 root 1: /*
2: * PSfont.c
3: * 5/17/93
4: * Usage: PSfont [ -q ] [ -s ] [ infile [ outfile ] ]
5: * Options:
6: * -q Quiet: suppress warning messages.
7: * -s Suppress "exitserver" header line.
8: * Expand PostScript font from infile (default: stdin)
9: * in IBM PC compressed binary format (PostScript binary format, .pfb)
10: * to outfile (default: stdout) in downloadable ASCII PostScript (.ps).
11: * Use "-s" when embedding outfile in a PS document,
12: * do not use "-s" when downloading a font permanently.
13: * Reference: "Supporting Downloadable PostScript Language Fonts",
14: * Adobe Technical Note #5040, 3/31/92, section 3.3.
15: */
16:
17: #if __STDC__
18: #define __(args) args
19: #else
20: #define __(args) ()
21: #endif
22:
23: #define VERSION "1.2"
24:
25: #include <stdio.h>
26:
27: /* Manifest constants. */
28: #define NBUF 32 /* offset message buffer size */
29: #define NDATA 32 /* output line binary data items (64 in Adobe PCSEND.EXE) */
30: #define HDRCMT "%! Adobe PostScript follows...\n"
31: #define HDRSRV "%%BeginExitServer: 0\n"\
32: "serverdict begin 0 exitserver\n"\
33: "%%EndExitServer\n"
34:
35: /* Definitions for binary segment header byte and type bytes. */
36: #define HDRBYTE 128
37: #define ISASCII 1
38: #define ISBDATA 2
39: #define ISEOF 3
40:
41: /* Forward. */
42: extern int main __((int argc, char *argv[] ));
43: extern void fatal __((char *fmt, ... ));
44: extern long getlong __((void ));
45: extern void process __((void ));
46: extern void usage __((void ));
47: extern void warning __((char *fmt, ... ));
48: extern int xgetc __((void ));
49: extern FILE *xopen __((char *name, char *mode ));
50:
51: /* Global. */
52: FILE *ifp = stdin; /* input FILE */
53: FILE *ofp = stdout; /* output FILE */
54: int qflag; /* no warnings */
55: int sflag; /* no exitserver line */
56:
57: int
58: main(argc, argv) int argc; char *argv[];
59: {
60: register char *s;
61:
62: while (argc > 1 && argv[1][0] == '-') {
63: for (s = &argv[1][1]; *s != '\0'; ++s) {
64: switch(*s) {
65: case 'q': ++qflag; break;
66: case 's': ++sflag; break;
67: case 'V':
68: fprintf(stderr, "PSfont: V" VERSION "\n");
69: break;
70: default:
71: usage();
72: break;
73: }
74: }
75: --argc;
76: ++argv;
77: }
78: if (argc > 3)
79: usage();
80: if (argc > 2)
81: ofp = xopen(argv[2], "w");
82: if (argc > 1)
83: ifp = xopen(argv[1], "rb");
84: process();
85: if (ifp != stdin)
86: fclose(ifp);
87: if (ofp != stdout)
88: fclose(ofp);
89: exit(0);
90: }
91:
92: /* Print a fatal error message and die. */
93: /* VARARGS */
94: void
95: fatal(fmt) char *fmt;
96: {
97: fprintf(stderr, "PSfont: %r\n", &fmt);
98: exit(1);
99: }
100:
101: /* Read a four-byte long in Intel byte order. */
102: long
103: getlong()
104: {
105: register long l;
106:
107: l = xgetc();
108: l |= (xgetc() << 8);
109: l |= (xgetc() << 16);
110: l |= (xgetc() << 24);
111: return l;
112: }
113:
114: /*
115: * Process a compressed binary font file.
116: * The input file is a series of records, each starting with HDRBYTE (0x80).
117: * The next byte of each record is either ISASCII, ISBDATA or ISEOF.
118: * ISASCII records have a 4-byte length followed by length ASCII bytes.
119: * ISBDATA records have a 4-byte length followed by length binary bytes.
120: * ISEOF indicates the end of the input data, it should be followed
121: * by EOF but in practice there are sometimes extraneous trailing bytes.
122: * The output file contains a header comment,
123: * an "exitserver" line if not -s,
124: * and the input data, with binary converted to hex ASCII.
125: * ASCII CR gets translated to NL for the benefit of other programs
126: * which may want to edit the PS output.
127: */
128: void
129: process()
130: {
131: register long length;
132: register int c, i, type, count;
133: char buf[NBUF];
134:
135: fputs(HDRCMT, ofp); /* write header comment */
136: if (!sflag)
137: fputs(HDRSRV, ofp); /* cf. Red Book, 2nd Ed., 3.7.7, pp. 70 ff. */
138: for (;;) {
139: if ((c = xgetc()) != HDRBYTE) {
140: if (ifp != stdin)
141: sprintf(buf, "offset %ld: ", ftell(ifp));
142: else
143: buf[0] = '\0';
144: fatal("%sbad header byte, expected 0x%X, read 0x%X",
145: buf, HDRBYTE, c);
146: }
147: if ((type = xgetc()) == ISEOF)
148: break;
149: else if (type != ISASCII && type != ISBDATA)
150: fatal("unexpected type byte 0x%X", type);
151: length = getlong();
152: if (type == ISASCII) {
153: /* Copy ASCII data. Convert CR to NL. */
154: while (length--) {
155: if ((c = xgetc()) == '\r')
156: c = '\n';
157: putc(c, ofp);
158: }
159: } else {
160: /* Expand binary data. */
161: for (; length > 0; length -= count) {
162: count = (length > NDATA) ? NDATA : length;
163: for (i = 0; i < count; i++)
164: fprintf(ofp, "%02X", xgetc());
165: putc('\n', ofp);
166: }
167: }
168: }
169: putc('\n', ofp);
170: if (getc(ifp) != EOF)
171: warning("extra data after input file EOF indicator ignored");
172: }
173:
174: /* Print a fatal usage message and die. */
175: void
176: usage()
177: {
178: fprintf(stderr,
179: "Usage: PSfont [ -q ] [ -s ] [ infile [ outfile ] ]\n"
180: "Options:\n"
181: "\t-q\tQuiet: suppress warning messages.\n"
182: "\t-s\tSuppress \"serverdict ... exitserver\" line in header\n"
183: );
184: exit(1);
185: }
186:
187: /* Print a nonfatal warning message. */
188: /* VARARGS */
189: void
190: warning(fmt) char *fmt;
191: {
192: if (!qflag)
193: fprintf(stderr, "PSfont: warning: %r\n", &fmt);
194: }
195:
196: /* Read a character and return it, die on EOF. */
197: int
198: xgetc()
199: {
200: register int c;
201:
202: if ((c = getc(ifp)) == EOF)
203: fatal("unexpected EOF");
204: return c & 0xFF;
205: }
206:
207: /* Open a file, die on failure. */
208: FILE *
209: xopen(name, mode) register char *name, *mode;
210: {
211: register FILE *fp;
212:
213: if ((fp = fopen(name, mode)) == NULL)
214: fatal("cannot open file \"%s\"", name);
215: return fp;
216: }
217:
218: /* end of PSfont.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.