Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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