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,
7 * macfont font.mac >font.unix
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.
38 /*****************************************************************************/
49 * Macintosh to Unix font converter.
66 /*****************************************************************************/
80 * Command line options.
84 while ( (ch = getopt(argc, argv, names)) != EOF ) {
86 case 'D': /* debug flag */
90 case 'I': /* ignore FATAL errors */
94 case '?': /* don't understand the option */
98 default: /* don't know what to do for ch */
99 error(FATAL, "missing case for option %c\n", ch);
107 } /* End of options */
109 /*****************************************************************************/
118 * Everything else is an input file. No arguments or '-' means stdin.
126 if ( strcmp(*argv, "-") == 0 )
128 else if ( (fp_in = fopen(*argv, "r")) == NULL )
129 error(FATAL, "can't open %s", *argv);
131 if ( fp_in != stdin )
137 } /* End of arguments */
139 /*****************************************************************************/
150 * The first four bytes (in a block) are the block size, the fifth is the block
151 * type, and the sixth always appears to be NULL. Type 0 blocks are comments and
152 * are always skipped. Type 1 blocks are ASCII text, type 2 is binary data that
153 * should be converted to hex, while type 5 blocks represent the end of the font
154 * file. Commment block lengths appear to be from the first byte, while other
155 * lengths seem to be measured from block type byte (ie. the fifth byte). Type
156 * four blocks aren't used, while type 3 blocks mean an end of file indication
157 * should be sent to the printer. Haven't done anything with type 3 blocks.
162 blocksize = getint(fp_in);
163 blocktype = getc(fp_in);
166 fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
167 switch ( blocktype ) {
168 case 0: /* comment - skip blockcount bytes */
169 fseek(fp_in, (long) blocksize - 6, 1);
173 asciitext(blocksize - 2);
177 hexdata(blocksize - 2);
182 error(FATAL, "resource type %d not implemented", blocktype);
189 error(FATAL, "unknown resource type %d", blocktype);
195 /*****************************************************************************/
199 int count; /* bytes left in the block */
208 * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
213 for ( i = 0; i < count; i++ ) {
214 if ( (ch = getc(fp_in)) == '\r' )
219 } /* End of asciitext */
221 /*****************************************************************************/
225 int count; /* bytes left in the block */
234 * Reads the next count bytes and converts each byte to hex. Also starts a new
235 * line every 80 hex characters.
239 for ( i = 0, n = 0; i < count; i++ ) {
240 fprintf(fp_out, "%.2X", getc(fp_in));
241 if ( (++n % 40) == 0 )
245 } /* End of hexdata */
247 /*****************************************************************************/
258 * Reads the next four bytes into an integer and returns the value to the caller.
259 * First two bytes are probably always 0.
263 for ( i = 0, val = (getc(fp_in) & 0377); i < 3; i++ )
264 val = (val << 8) | (getc(fp_in) & 0377);
268 } /* End of getint */
270 /*****************************************************************************/
272 error(kind, mesg, a1, a2, a3)
283 * Print *mesg then quit if kind is FATAL.
287 if ( mesg != NULL && *mesg != '\0' ) {
288 fprintf(stderr, "%s: ", prog_name);
289 fprintf(stderr, mesg, a1, a2, a3);
293 if ( kind == FATAL && ignore == OFF )
298 /*****************************************************************************/