|
|
1.1 root 1: /*
2: *
3: * Program that converts Macintosh font files to a format that works on Unix
4: * systems. Essentially all the information needed came from the Adobe paper
5: * "Supporting Downloadable PostScript Fonts". To use the program type,
6: *
7: * macfont font.mac >font.unix
8: *
9: * where font.mac is the font file, exactly as it came over from a Macintosh,
10: * and font.unix is equivalent host resident font file usable on Unix systems.
11: *
12: */
13:
14: #include <stdio.h>
15: #include <signal.h>
16:
17: #define OFF 0
18: #define ON 1
19:
20: #define NON_FATAL 0
21: #define FATAL 1
22:
23: #define FALSE 0
24: #define TRUE 1
25:
26: char **argv;
27: int argc;
28:
29: char *prog_name;
30:
31: int x_stat;
32: int debug = OFF;
33: int ignore = OFF;
34:
35: FILE *fp_in = stdin;
36: FILE *fp_out = stdout;
37:
38: /*****************************************************************************/
39:
40: main(agc, agv)
41:
42: int agc;
43: char *agv[];
44:
45: {
46:
47: /*
48: *
49: * Macintosh to Unix font converter.
50: *
51: */
52:
53: argc = agc;
54: argv = agv;
55: prog_name = argv[0];
56:
57: options();
58: arguments();
59: exit(x_stat);
60:
61: } /* End of main */
62:
63: /*****************************************************************************/
64:
65: options()
66:
67: {
68:
69: int ch;
70: char *names = "DI";
71:
72: extern char *optarg;
73: extern int optind;
74:
75: /*
76: *
77: * Command line options.
78: *
79: */
80:
81: while ( (ch = getopt(argc, argv, names)) != EOF ) {
82: switch ( ch ) {
83: case 'D': /* debug flag */
84: debug = ON;
85: break;
86:
87: case 'I': /* ignore FATAL errors */
88: ignore = ON;
89: break;
90:
91: case '?': /* don't understand the option */
92: error(FATAL, "");
93: break;
94:
95: default: /* don't know what to do for ch */
96: error(FATAL, "missing case for option %c\n", ch);
97: break;
98: } /* End switch */
99: } /* End while */
100:
101: argc -= optind;
102: argv += optind;
103:
104: } /* End of options */
105:
106: /*****************************************************************************/
107:
108: arguments()
109:
110: {
111:
112:
113: /*
114: *
115: * Everything else is an input file. No arguments or '-' means stdin.
116: *
117: */
118:
119: if ( argc < 1 )
120: conv();
121: else
122: while ( argc > 0 ) {
123: if ( strcmp(*argv, "-") == 0 )
124: fp_in = stdin;
125: else if ( (fp_in = fopen(*argv, "r")) == NULL )
126: error(FATAL, "can't open %s", *argv);
127: conv();
128: if ( fp_in != stdin )
129: fclose(fp_in);
130: argc--;
131: argv++;
132: } /* End while */
133:
134: } /* End of arguments */
135:
136: /*****************************************************************************/
137:
138: conv()
139:
140: {
141:
142: int blocksize;
143: int blocktype;
144:
145: /*
146: *
147: * The first four bytes (in a block) are the block size, the fifth is the block
148: * type, and the sixth always appears to be NULL. Type 0 blocks are comments and
149: * are always skipped. Type 1 blocks are ASCII text, type 2 is binary data that
150: * should be converted to hex, while type 5 blocks represent the end of the font
151: * file. Commment block lengths appear to be from the first byte, while other
152: * lengths seem to be measured from block type byte (ie. the fifth byte). Type
153: * four blocks aren't used, while type 3 blocks mean an end of file indication
154: * should be sent to the printer. Haven't done anything with type 3 blocks.
155: *
156: */
157:
158: while ( 1 ) {
159: blocksize = getint(fp_in);
160: blocktype = getc(fp_in);
161: getc(fp_in);
162: if ( debug == ON )
163: fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
164: switch ( blocktype ) {
165: case 0: /* comment - skip blockcount bytes */
166: fseek(fp_in, (long) blocksize - 6, 1);
167: break;
168:
169: case 1:
170: asciitext(blocksize - 2);
171: break;
172:
173: case 2:
174: hexdata(blocksize - 2);
175: break;
176:
177: case 3:
178: case 4:
179: error(FATAL, "resource type %d not implemented", blocktype);
180: break;
181:
182: case 5:
183: return;
184:
185: default:
186: error(FATAL, "unknown resource type %d", blocktype);
187: } /* End switch */
188: } /* End while */
189:
190: } /* End of conv */
191:
192: /*****************************************************************************/
193:
194: asciitext(count)
195:
196: int count; /* bytes left in the block */
197:
198: {
199:
200: int ch;
201: int i = 0;
202:
203: /*
204: *
205: * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
206: * is all I've done.
207: *
208: */
209:
210: for ( i = 0; i < count; i++ ) {
211: if ( (ch = getc(fp_in)) == '\r' )
212: ch = '\n';
213: putc(ch, fp_out);
214: } /* End for */
215:
216: } /* End of asciitext */
217:
218: /*****************************************************************************/
219:
220: hexdata(count)
221:
222: int count; /* bytes left in the block */
223:
224: {
225:
226: int i;
227: int n;
228:
229: /*
230: *
231: * Reads the next count bytes and converts each byte to hex. Also starts a new
232: * line every 80 hex characters.
233: *
234: */
235:
236: for ( i = 0, n = 0; i < count; i++ ) {
237: fprintf(fp_out, "%.2X", getc(fp_in));
238: if ( (++n % 40) == 0 )
239: putc('\n', fp_out);
240: } /* End for */
241:
242: } /* End of hexdata */
243:
244: /*****************************************************************************/
245:
246: getint()
247:
248: {
249:
250: int val;
251: int i;
252:
253: /*
254: *
255: * Reads the next four bytes into an integer and returns the value to the caller.
256: * First two bytes are probably always 0.
257: *
258: */
259:
260: for ( i = 0, val = (getc(fp_in) & 0377); i < 3; i++ )
261: val = (val << 8) | (getc(fp_in) & 0377);
262:
263: return(val);
264:
265: } /* End of getint */
266:
267: /*****************************************************************************/
268:
269: error(kind, mesg, a1, a2, a3)
270:
271:
272: int kind;
273: char *mesg;
274: unsigned a1, a2, a3;
275:
276: {
277:
278: /*
279: *
280: * Print *mesg then quit if kind is FATAL.
281: *
282: */
283:
284: if ( mesg != NULL && *mesg != '\0' ) {
285: fprintf(stderr, "%s: ", prog_name);
286: fprintf(stderr, mesg, a1, a2, a3);
287: putc('\n', stderr);
288: } /* End if */
289:
290: if ( kind == FATAL && ignore == OFF )
291: exit(x_stat | 01);
292:
293: } /* End of error */
294:
295: /*****************************************************************************/
296:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.