3 b855148c 2004-05-16 devnull * Program that converts Macintosh font files to a format that works on Unix
4 b855148c 2004-05-16 devnull * systems. Essentially all the information needed came from the Adobe paper
5 b855148c 2004-05-16 devnull * "Supporting Downloadable PostScript Fonts". To use the program type,
7 b855148c 2004-05-16 devnull * macfont font.mac >font.unix
9 b855148c 2004-05-16 devnull * where font.mac is the font file, exactly as it came over from a Macintosh,
10 b855148c 2004-05-16 devnull * and font.unix is equivalent host resident font file usable on Unix systems.
14 b855148c 2004-05-16 devnull #include <stdio.h>
15 b855148c 2004-05-16 devnull #include <signal.h>
17 b855148c 2004-05-16 devnull #define OFF 0
18 b855148c 2004-05-16 devnull #define ON 1
20 b855148c 2004-05-16 devnull #define NON_FATAL 0
21 b855148c 2004-05-16 devnull #define FATAL 1
23 b855148c 2004-05-16 devnull #define FALSE 0
24 b855148c 2004-05-16 devnull #define TRUE 1
26 b855148c 2004-05-16 devnull char **argv;
27 b855148c 2004-05-16 devnull int argc;
29 b855148c 2004-05-16 devnull char *prog_name;
31 b855148c 2004-05-16 devnull int x_stat;
32 b855148c 2004-05-16 devnull int debug = OFF;
33 b855148c 2004-05-16 devnull int ignore = OFF;
35 b855148c 2004-05-16 devnull FILE *fp_in;
36 b855148c 2004-05-16 devnull FILE *fp_out;
38 b855148c 2004-05-16 devnull /*****************************************************************************/
40 b855148c 2004-05-16 devnull main(agc, agv)
43 b855148c 2004-05-16 devnull char *agv[];
49 b855148c 2004-05-16 devnull * Macintosh to Unix font converter.
53 b855148c 2004-05-16 devnull argc = agc;
54 b855148c 2004-05-16 devnull argv = agv;
55 b855148c 2004-05-16 devnull prog_name = argv[0];
57 b855148c 2004-05-16 devnull fp_in = stdin;
58 b855148c 2004-05-16 devnull fp_out = stdout;
60 b855148c 2004-05-16 devnull options();
61 b855148c 2004-05-16 devnull arguments();
62 b855148c 2004-05-16 devnull exit(x_stat);
64 b855148c 2004-05-16 devnull } /* End of main */
66 b855148c 2004-05-16 devnull /*****************************************************************************/
68 b855148c 2004-05-16 devnull options()
73 b855148c 2004-05-16 devnull char *names = "DI";
75 b855148c 2004-05-16 devnull extern char *optarg;
76 b855148c 2004-05-16 devnull extern int optind;
80 b855148c 2004-05-16 devnull * Command line options.
84 b855148c 2004-05-16 devnull while ( (ch = getopt(argc, argv, names)) != EOF ) {
85 b855148c 2004-05-16 devnull switch ( ch ) {
86 b855148c 2004-05-16 devnull case 'D': /* debug flag */
87 b855148c 2004-05-16 devnull debug = ON;
90 b855148c 2004-05-16 devnull case 'I': /* ignore FATAL errors */
91 b855148c 2004-05-16 devnull ignore = ON;
94 b855148c 2004-05-16 devnull case '?': /* don't understand the option */
95 b855148c 2004-05-16 devnull error(FATAL, "");
98 b855148c 2004-05-16 devnull default: /* don't know what to do for ch */
99 b855148c 2004-05-16 devnull error(FATAL, "missing case for option %c\n", ch);
101 b855148c 2004-05-16 devnull } /* End switch */
102 b855148c 2004-05-16 devnull } /* End while */
104 b855148c 2004-05-16 devnull argc -= optind;
105 b855148c 2004-05-16 devnull argv += optind;
107 b855148c 2004-05-16 devnull } /* End of options */
109 b855148c 2004-05-16 devnull /*****************************************************************************/
111 b855148c 2004-05-16 devnull arguments()
118 b855148c 2004-05-16 devnull * Everything else is an input file. No arguments or '-' means stdin.
122 b855148c 2004-05-16 devnull if ( argc < 1 )
125 b855148c 2004-05-16 devnull while ( argc > 0 ) {
126 b855148c 2004-05-16 devnull if ( strcmp(*argv, "-") == 0 )
127 b855148c 2004-05-16 devnull fp_in = stdin;
128 b855148c 2004-05-16 devnull else if ( (fp_in = fopen(*argv, "r")) == NULL )
129 b855148c 2004-05-16 devnull error(FATAL, "can't open %s", *argv);
131 b855148c 2004-05-16 devnull if ( fp_in != stdin )
132 b855148c 2004-05-16 devnull fclose(fp_in);
135 b855148c 2004-05-16 devnull } /* End while */
137 b855148c 2004-05-16 devnull } /* End of arguments */
139 b855148c 2004-05-16 devnull /*****************************************************************************/
145 b855148c 2004-05-16 devnull int blocksize;
146 b855148c 2004-05-16 devnull int blocktype;
150 b855148c 2004-05-16 devnull * The first four bytes (in a block) are the block size, the fifth is the block
151 b855148c 2004-05-16 devnull * type, and the sixth always appears to be NULL. Type 0 blocks are comments and
152 b855148c 2004-05-16 devnull * are always skipped. Type 1 blocks are ASCII text, type 2 is binary data that
153 b855148c 2004-05-16 devnull * should be converted to hex, while type 5 blocks represent the end of the font
154 b855148c 2004-05-16 devnull * file. Commment block lengths appear to be from the first byte, while other
155 b855148c 2004-05-16 devnull * lengths seem to be measured from block type byte (ie. the fifth byte). Type
156 b855148c 2004-05-16 devnull * four blocks aren't used, while type 3 blocks mean an end of file indication
157 b855148c 2004-05-16 devnull * should be sent to the printer. Haven't done anything with type 3 blocks.
161 b855148c 2004-05-16 devnull while ( 1 ) {
162 b855148c 2004-05-16 devnull blocksize = getint(fp_in);
163 b855148c 2004-05-16 devnull blocktype = getc(fp_in);
164 b855148c 2004-05-16 devnull getc(fp_in);
165 b855148c 2004-05-16 devnull if ( debug == ON )
166 b855148c 2004-05-16 devnull fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
167 b855148c 2004-05-16 devnull switch ( blocktype ) {
168 b855148c 2004-05-16 devnull case 0: /* comment - skip blockcount bytes */
169 b855148c 2004-05-16 devnull fseek(fp_in, (long) blocksize - 6, 1);
173 b855148c 2004-05-16 devnull asciitext(blocksize - 2);
177 b855148c 2004-05-16 devnull hexdata(blocksize - 2);
182 b855148c 2004-05-16 devnull error(FATAL, "resource type %d not implemented", blocktype);
188 b855148c 2004-05-16 devnull default:
189 b855148c 2004-05-16 devnull error(FATAL, "unknown resource type %d", blocktype);
190 b855148c 2004-05-16 devnull } /* End switch */
191 b855148c 2004-05-16 devnull } /* End while */
193 b855148c 2004-05-16 devnull } /* End of conv */
195 b855148c 2004-05-16 devnull /*****************************************************************************/
197 b855148c 2004-05-16 devnull asciitext(count)
199 b855148c 2004-05-16 devnull int count; /* bytes left in the block */
204 b855148c 2004-05-16 devnull int i = 0;
208 b855148c 2004-05-16 devnull * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
209 b855148c 2004-05-16 devnull * is all I've done.
213 b855148c 2004-05-16 devnull for ( i = 0; i < count; i++ ) {
214 b855148c 2004-05-16 devnull if ( (ch = getc(fp_in)) == '\r' )
215 b855148c 2004-05-16 devnull ch = '\n';
216 b855148c 2004-05-16 devnull putc(ch, fp_out);
217 b855148c 2004-05-16 devnull } /* End for */
219 b855148c 2004-05-16 devnull } /* End of asciitext */
221 b855148c 2004-05-16 devnull /*****************************************************************************/
223 b855148c 2004-05-16 devnull hexdata(count)
225 b855148c 2004-05-16 devnull int count; /* bytes left in the block */
234 b855148c 2004-05-16 devnull * Reads the next count bytes and converts each byte to hex. Also starts a new
235 b855148c 2004-05-16 devnull * line every 80 hex characters.
239 b855148c 2004-05-16 devnull for ( i = 0, n = 0; i < count; i++ ) {
240 b855148c 2004-05-16 devnull fprintf(fp_out, "%.2X", getc(fp_in));
241 b855148c 2004-05-16 devnull if ( (++n % 40) == 0 )
242 b855148c 2004-05-16 devnull putc('\n', fp_out);
243 b855148c 2004-05-16 devnull } /* End for */
245 b855148c 2004-05-16 devnull } /* End of hexdata */
247 b855148c 2004-05-16 devnull /*****************************************************************************/
249 b855148c 2004-05-16 devnull getint()
253 b855148c 2004-05-16 devnull int val;
258 b855148c 2004-05-16 devnull * Reads the next four bytes into an integer and returns the value to the caller.
259 b855148c 2004-05-16 devnull * First two bytes are probably always 0.
263 b855148c 2004-05-16 devnull for ( i = 0, val = (getc(fp_in) & 0377); i < 3; i++ )
264 b855148c 2004-05-16 devnull val = (val << 8) | (getc(fp_in) & 0377);
266 b855148c 2004-05-16 devnull return(val);
268 fa325e9b 2020-01-10 cross } /* End of getint */
270 b855148c 2004-05-16 devnull /*****************************************************************************/
272 b855148c 2004-05-16 devnull error(kind, mesg, a1, a2, a3)
275 b855148c 2004-05-16 devnull int kind;
276 b855148c 2004-05-16 devnull char *mesg;
277 b855148c 2004-05-16 devnull unsigned a1, a2, a3;
283 b855148c 2004-05-16 devnull * Print *mesg then quit if kind is FATAL.
287 b855148c 2004-05-16 devnull if ( mesg != NULL && *mesg != '\0' ) {
288 b855148c 2004-05-16 devnull fprintf(stderr, "%s: ", prog_name);
289 b855148c 2004-05-16 devnull fprintf(stderr, mesg, a1, a2, a3);
290 b855148c 2004-05-16 devnull putc('\n', stderr);
291 b855148c 2004-05-16 devnull } /* End if */
293 b855148c 2004-05-16 devnull if ( kind == FATAL && ignore == OFF )
294 b855148c 2004-05-16 devnull exit(x_stat | 01);
296 b855148c 2004-05-16 devnull } /* End of error */
298 b855148c 2004-05-16 devnull /*****************************************************************************/