3 * Program that converts IBM font files to a format that works on Unix systems.
4 * Essentially all the information needed came from the Adobe paper "Supporting
5 * Downloadable PostScript Fonts". To use the program type,
7 * ibmfont font.ibm >font.unix
9 * where font.ibm is the font file, exactly as it came over from an IBM PC,
10 * and font.unix is equivalent host resident font file usable on Unix systems.
38 /*****************************************************************************/
49 * IBM PC 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 /*****************************************************************************/
117 * Everything esle 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 /*****************************************************************************/
152 * Font files on the IBM PC are stored in a compressed binary format. Individual
153 * segments in the file are preceeded by a header that looks like,
156 * Byte 2: segment type (1=ASCII, 2=TOHEX, or 3=EOF)
157 * Bytes 3-6: length of the segment
164 if ( getc(fp_in) != 128 )
165 error(FATAL, "bad file format");
166 blocktype = getc(fp_in);
167 blocksize = getint(fp_in);
169 fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
170 fprintf(stderr, "start=0%o, end=0%o\n", seg, seg+blocksize+6);
171 fprintf(stderr, "start=%d, end=%d\n", seg, seg+blocksize+6);
173 switch ( blocktype ) {
175 asciitext(blocksize);
186 error(FATAL, "unknown resource type %d", blocktype);
192 /*****************************************************************************/
196 int count; /* bytes left in the block */
205 * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
210 for ( i = 0; i < count; i++ ) {
211 if ( (ch = getc(fp_in)) == '\r' )
216 } /* End of asciitext */
218 /*****************************************************************************/
222 int count; /* bytes left in the block */
231 * Reads the next count bytes and converts each byte to hex. Also starts a new
232 * line every 80 hex characters.
236 for ( i = 0, n = 0; i < count; i++ ) {
237 fprintf(fp_out, "%.2X", getc(fp_in));
238 if ( (++n % 40) == 0 )
242 } /* End of hexdata */
244 /*****************************************************************************/
254 * Reads the next four bytes into an integer and returns the value to the caller.
255 * First two bytes are probably always 0.
260 val |= (getc(fp_in) << 8);
261 val |= (getc(fp_in) << 16);
262 val |= (getc(fp_in) << 24);
266 } /* End of getint */
268 /*****************************************************************************/
270 error(kind, mesg, a1, a2, a3)
280 * Print mesg and quit if kind is FATAL.
284 if ( mesg != NULL && *mesg != '\0' ) {
285 fprintf(stderr, "%s: ", prog_name);
286 fprintf(stderr, mesg, a1, a2, a3);
290 if ( kind == FATAL && ignore == OFF )
295 /*****************************************************************************/