3 b855148c 2004-05-16 devnull * Program that converts IBM font files to a format that works on Unix systems.
4 b855148c 2004-05-16 devnull * Essentially all the information needed came from the Adobe paper "Supporting
5 b855148c 2004-05-16 devnull * Downloadable PostScript Fonts". To use the program type,
7 b855148c 2004-05-16 devnull * ibmfont font.ibm >font.unix
9 b855148c 2004-05-16 devnull * where font.ibm is the font file, exactly as it came over from an IBM PC,
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 * IBM PC 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()
117 b855148c 2004-05-16 devnull * Everything esle 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;
147 b855148c 2004-05-16 devnull int seg;
148 b855148c 2004-05-16 devnull long ftell();
152 b855148c 2004-05-16 devnull * Font files on the IBM PC are stored in a compressed binary format. Individual
153 b855148c 2004-05-16 devnull * segments in the file are preceeded by a header that looks like,
155 b855148c 2004-05-16 devnull * Byte 1: 128
156 b855148c 2004-05-16 devnull * Byte 2: segment type (1=ASCII, 2=TOHEX, or 3=EOF)
157 b855148c 2004-05-16 devnull * Bytes 3-6: length of the segment
158 b855148c 2004-05-16 devnull * Bytes 7 ... data
162 b855148c 2004-05-16 devnull while ( 1 ) {
163 b855148c 2004-05-16 devnull seg = ftell(fp_in);
164 b855148c 2004-05-16 devnull if ( getc(fp_in) != 128 )
165 b855148c 2004-05-16 devnull error(FATAL, "bad file format");
166 b855148c 2004-05-16 devnull blocktype = getc(fp_in);
167 b855148c 2004-05-16 devnull blocksize = getint(fp_in);
168 b855148c 2004-05-16 devnull if ( debug == ON ) {
169 b855148c 2004-05-16 devnull fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
170 b855148c 2004-05-16 devnull fprintf(stderr, "start=0%o, end=0%o\n", seg, seg+blocksize+6);
171 b855148c 2004-05-16 devnull fprintf(stderr, "start=%d, end=%d\n", seg, seg+blocksize+6);
172 b855148c 2004-05-16 devnull } /* End if */
173 b855148c 2004-05-16 devnull switch ( blocktype ) {
175 b855148c 2004-05-16 devnull asciitext(blocksize);
179 b855148c 2004-05-16 devnull hexdata(blocksize);
185 b855148c 2004-05-16 devnull default:
186 b855148c 2004-05-16 devnull error(FATAL, "unknown resource type %d", blocktype);
187 b855148c 2004-05-16 devnull } /* End switch */
188 b855148c 2004-05-16 devnull } /* End while */
190 b855148c 2004-05-16 devnull } /* End of conv */
192 b855148c 2004-05-16 devnull /*****************************************************************************/
194 b855148c 2004-05-16 devnull asciitext(count)
196 b855148c 2004-05-16 devnull int count; /* bytes left in the block */
201 b855148c 2004-05-16 devnull int i = 0;
205 b855148c 2004-05-16 devnull * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
206 b855148c 2004-05-16 devnull * is all I've done.
210 b855148c 2004-05-16 devnull for ( i = 0; i < count; i++ ) {
211 b855148c 2004-05-16 devnull if ( (ch = getc(fp_in)) == '\r' )
212 b855148c 2004-05-16 devnull ch = '\n';
213 b855148c 2004-05-16 devnull putc(ch, fp_out);
214 b855148c 2004-05-16 devnull } /* End for */
216 b855148c 2004-05-16 devnull } /* End of asciitext */
218 b855148c 2004-05-16 devnull /*****************************************************************************/
220 b855148c 2004-05-16 devnull hexdata(count)
222 b855148c 2004-05-16 devnull int count; /* bytes left in the block */
231 b855148c 2004-05-16 devnull * Reads the next count bytes and converts each byte to hex. Also starts a new
232 b855148c 2004-05-16 devnull * line every 80 hex characters.
236 b855148c 2004-05-16 devnull for ( i = 0, n = 0; i < count; i++ ) {
237 b855148c 2004-05-16 devnull fprintf(fp_out, "%.2X", getc(fp_in));
238 b855148c 2004-05-16 devnull if ( (++n % 40) == 0 )
239 b855148c 2004-05-16 devnull putc('\n', fp_out);
240 b855148c 2004-05-16 devnull } /* End for */
242 b855148c 2004-05-16 devnull } /* End of hexdata */
244 b855148c 2004-05-16 devnull /*****************************************************************************/
246 b855148c 2004-05-16 devnull getint()
250 b855148c 2004-05-16 devnull int val;
254 b855148c 2004-05-16 devnull * Reads the next four bytes into an integer and returns the value to the caller.
255 b855148c 2004-05-16 devnull * First two bytes are probably always 0.
259 b855148c 2004-05-16 devnull val = getc(fp_in);
260 b855148c 2004-05-16 devnull val |= (getc(fp_in) << 8);
261 b855148c 2004-05-16 devnull val |= (getc(fp_in) << 16);
262 b855148c 2004-05-16 devnull val |= (getc(fp_in) << 24);
264 b855148c 2004-05-16 devnull return(val);
266 fa325e9b 2020-01-10 cross } /* End of getint */
268 b855148c 2004-05-16 devnull /*****************************************************************************/
270 b855148c 2004-05-16 devnull error(kind, mesg, a1, a2, a3)
272 b855148c 2004-05-16 devnull int kind;
273 b855148c 2004-05-16 devnull char *mesg;
274 b855148c 2004-05-16 devnull unsigned a1, a2, a3;
280 b855148c 2004-05-16 devnull * Print mesg and quit if kind is FATAL.
284 b855148c 2004-05-16 devnull if ( mesg != NULL && *mesg != '\0' ) {
285 b855148c 2004-05-16 devnull fprintf(stderr, "%s: ", prog_name);
286 b855148c 2004-05-16 devnull fprintf(stderr, mesg, a1, a2, a3);
287 b855148c 2004-05-16 devnull putc('\n', stderr);
288 b855148c 2004-05-16 devnull } /* End if */
290 b855148c 2004-05-16 devnull if ( kind == FATAL && ignore == OFF )
291 b855148c 2004-05-16 devnull exit(x_stat | 01);
293 b855148c 2004-05-16 devnull } /* End of error */
295 b855148c 2004-05-16 devnull /*****************************************************************************/