|
|
1.1 root 1: /*
2: *
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,
6: *
7: * ibmfont font.ibm >font.unix
8: *
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.
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: * IBM PC 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: * Everything esle is an input file. No arguments or '-' means stdin.
115: *
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: int seg;
145: long ftell();
146:
147: /*
148: *
149: * Font files on the IBM PC are stored in a compressed binary format. Individual
150: * segments in the file are preceeded by a header that looks like,
151: *
152: * Byte 1: 128
153: * Byte 2: segment type (1=ASCII, 2=TOHEX, or 3=EOF)
154: * Bytes 3-6: length of the segment
155: * Bytes 7 ... data
156: *
157: */
158:
159: while ( 1 ) {
160: seg = ftell(fp_in);
161: if ( getc(fp_in) != 128 )
162: error(FATAL, "bad file format");
163: blocktype = getc(fp_in);
164: blocksize = getint(fp_in);
165: if ( debug == ON ) {
166: fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
167: fprintf(stderr, "start=0%o, end=0%o\n", seg, seg+blocksize+6);
168: fprintf(stderr, "start=%d, end=%d\n", seg, seg+blocksize+6);
169: } /* End if */
170: switch ( blocktype ) {
171: case 1:
172: asciitext(blocksize);
173: break;
174:
175: case 2:
176: hexdata(blocksize);
177: break;
178:
179: case 3:
180: return;
181:
182: default:
183: error(FATAL, "unknown resource type %d", blocktype);
184: } /* End switch */
185: } /* End while */
186:
187: } /* End of conv */
188:
189: /*****************************************************************************/
190:
191: asciitext(count)
192:
193: int count; /* bytes left in the block */
194:
195: {
196:
197: int ch;
198: int i = 0;
199:
200: /*
201: *
202: * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
203: * is all I've done.
204: *
205: */
206:
207: for ( i = 0; i < count; i++ ) {
208: if ( (ch = getc(fp_in)) == '\r' )
209: ch = '\n';
210: putc(ch, fp_out);
211: } /* End for */
212:
213: } /* End of asciitext */
214:
215: /*****************************************************************************/
216:
217: hexdata(count)
218:
219: int count; /* bytes left in the block */
220:
221: {
222:
223: int i;
224: int n;
225:
226: /*
227: *
228: * Reads the next count bytes and converts each byte to hex. Also starts a new
229: * line every 80 hex characters.
230: *
231: */
232:
233: for ( i = 0, n = 0; i < count; i++ ) {
234: fprintf(fp_out, "%.2X", getc(fp_in));
235: if ( (++n % 40) == 0 )
236: putc('\n', fp_out);
237: } /* End for */
238:
239: } /* End of hexdata */
240:
241: /*****************************************************************************/
242:
243: getint()
244:
245: {
246:
247: int val;
248:
249: /*
250: *
251: * Reads the next four bytes into an integer and returns the value to the caller.
252: * First two bytes are probably always 0.
253: *
254: */
255:
256: val = getc(fp_in);
257: val |= (getc(fp_in) << 8);
258: val |= (getc(fp_in) << 16);
259: val |= (getc(fp_in) << 24);
260:
261: return(val);
262:
263: } /* End of getint */
264:
265: /*****************************************************************************/
266:
267: error(kind, mesg, a1, a2, a3)
268:
269: int kind;
270: char *mesg;
271: unsigned a1, a2, a3;
272:
273: {
274:
275: /*
276: *
277: * Print mesg and quit if kind is FATAL.
278: *
279: */
280:
281: if ( mesg != NULL && *mesg != '\0' ) {
282: fprintf(stderr, "%s: ", prog_name);
283: fprintf(stderr, mesg, a1, a2, a3);
284: putc('\n', stderr);
285: } /* End if */
286:
287: if ( kind == FATAL && ignore == OFF )
288: exit(x_stat | 01);
289:
290: } /* End of error */
291:
292: /*****************************************************************************/
293:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.