1 /*	rst2ch.c	(Berkeley)	1.2	86/03/04
2  *
3  * Font translation for Imagen-style fonts (RST format) to character format.
4  *
5  *	Use:  rst2ch fontfile  [ character_list ]
6  *
7  *		Reads "fontfile" from current directory (or if not found,
8  *	from BITDIR defined below) and converts it to a character font format
9  *	editable by real people, and convertable BACK to rst format by the
10  *	ch2rst program.  Output goes to stdout.
11  */
12 
13 #include <stdio.h>
14 #include "rst.h"
15 
16 #define  BITDIR		"/usr/src/local/imagen/fonts/raster"
17 
18 char *	rdchar();
19 char *	malloc();
20 
21 char	defascii[DIRSIZ];	/* list of ascii characters - in order */
22 char	*charswanted = defascii;/* list of characters to print info for */
23 glyph_dir g[DIRSIZ];		/* directory of glyph definitions */
24 preamble p;			/* set of variables for preamble */
25 double	fixtowdth;		/* "fix" and magnification conversion factor */
26 
27 char	*fontdir = BITDIR;	/* place to look for fonts */
28 char	IName[100];		/* input file name put here */
29 FILE *	FID;			/* input file number */
30 
31 char	charbits[10000];	/* place to store bits for a glyph */
32 int	gbase;			/* base address of glyphs in RST file */
33 			/* variables used to print character */
34 int	H, W, WB, base, lbound, rbound;
35 
36 
37 main(argc,argv)
38 int argc;
39 char **argv;
40 {
41 	register int i;
42 	register int j;
43 	register int k;
44 	register int l;
45 
46 
47 	if (argc < 2 || argc > 3)
48 		error("usage: %s filename [ charlist ]", argv[0]);
49 
50 	for (i = 0; i < DIRSIZ; i++)
51 		defascii[i] = i;
52 	if (argc >= 3)
53 		charswanted = argv[2];
54 
55 	sprintf(IName, "%s/%s", fontdir, argv[1]);
56 	if ((FID = fopen(argv[1], "r")) == NULL)
57 		if ((FID = fopen(IName, "r")) == NULL)
58 			error("can't find %s", argv[1]);
59 
60 	for (i = 0; i < FMARK; i++) filemark[i] = getc(FID);
61 	if (strncmp(filemark, "Rast", 4))
62 	    error("bad File Mark in Font file.");
63 
64 	p.p_size = rd2();
65 	p.p_version = rd1();
66 	if (p.p_version)
67 	    error("wrong version (%d) of Font file.", p.p_version);
68 	p.p_glyph = rd3();
69 	p.p_first = rd2();
70 	if ((p.p_last = rd2()) >= DIRSIZ)
71 	    error("too many glyphs (%d) in font.", p.p_last);
72 	p.p_mag = rd4();
73 
74 	p.p_desiz = rd4();
75 	p.p_linesp = rd4();
76 	p.p_wordsp = rd4();
77 	p.p_rot = rd2();
78 	p.p_cadv = rd1();
79 	p.p_ladv = rd1();
80 	p.p_id = rd4();
81 	p.p_res = rd2();
82 
83 	if ((fixtowdth = FIXIN * p.p_res * p.p_mag / 1000.0) == 0.0)
84 	    fixtowdth = FIXIN * p.p_res;
85 	i = p.p_glyph - 44;
86 	while (i--) if (getc(FID) == EOF)
87 	    error("bad preamble in Font file.");
88 
89 	for (i = p.p_first; i <= p.p_last; i++) {
90 	    g[i].g_height = rd2();
91 	    g[i].g_width = rd2();
92 	    g[i].g_up = rd2();
93 	    g[i].g_left = rd2();
94 	    g[i].g_pwidth = rd4();
95 	    g[i].g_bitp = rd3();
96 	}
97 
98 	printf("fontheader\nsize %d\nversion %d\n", p.p_size, p.p_version);
99 	printf("mag %d\ndesiz %.2f\n", p.p_mag, p.p_desiz * FIX);
100 	printf("linesp %.2f\n", p.p_linesp * fixtowdth);
101 	printf("wordsp %.2f\n", p.p_wordsp * fixtowdth);
102 	printf("rot %d\ncadv %d\nladv %d\n", p.p_rot, p.p_cadv, p.p_ladv);
103 	printf("id %d\nres %d\n", p.p_id, p.p_res);
104 
105 
106 	for (l = p.p_first; l <= p.p_last; l++) {
107 	    j = charswanted[l];
108 	    if (l>0 && j==0) break;
109 	    if ((gbase = g[j].g_bitp) != 0) {
110 		printf(":%d, width = %.2f\n", j, g[j].g_pwidth * fixtowdth);
111 		H = g[j].g_height;
112 		W = g[j].g_width;
113 		if (H <= 0 || W <= 0) {
114 		    g[j].g_up = 0;
115 		    g[j].g_left = 0;
116 		}
117 		lseek(fileno(FID), (long) gbase, 0);
118 		read(fileno(FID), charbits, (WB = (W+7)/8) * H);
119 		base = g[j].g_up;
120 		if ((lbound = g[j].g_left) > 0) lbound = 0;
121 		if ((rbound = g[j].g_left + 1) < W) rbound = W;
122 		for (k = g[j].g_up; k < 0; k++) {
123 		    for (i = lbound; i < rbound; i++)
124 			printf("%c", k==g[j].g_up && i==g[j].g_left ? 'x':'.');
125 		    putchar ('\n');
126 		}
127 		for (k = 0; k < H; k++) {
128 		    for (i = g[j].g_left; i < 0; i++)
129 			printf("%c", k==g[j].g_up && i==g[j].g_left ? 'x':'.');
130 		    for (i = 0; i < W; i++)
131 			printf("%c", k==g[j].g_up && i==g[j].g_left ?
132 				(biton(k,i) ? 'X':'x') : biton(k,i) ? '@':'.');
133 		    while (i < rbound) {
134 			printf("%c", k==g[j].g_up && i==g[j].g_left ? 'x':'.');
135 			i++;
136 		    }
137 		    putchar ('\n');
138 		}
139 		while (k <= g[j].g_up) {
140 		    for (i = lbound; i < rbound; i++)
141 			printf("%c", k==g[j].g_up && i==g[j].g_left ? 'x':'.');
142 		    putchar ('\n');
143 		    k++;
144 		}
145 		putchar ('\n');
146 	    }
147 	}
148 	exit(0);
149 }
150 
151 
152 /*----------------------------------------------------------------------------*
153  | Routine:	error (format_string, argument1, argument2.... )
154  |
155  | Results:	fprints a message to standard error, then exits with error
156  |		code 1.
157  |
158  | Side Efct:	This routine does NOT return
159  *----------------------------------------------------------------------------*/
160 
161 /*VARARGS1*/
162 error(string, a1, a2, a3, a4)
163 char *string;
164 {
165 	fprintf(stderr, "rst2ch: ");
166 	fprintf(stderr, string, a1, a2, a3, a4);
167 	fprintf(stderr, "\n");
168 	exit (1);
169 }
170 
171 
172 /*----------------------------------------------------------------------------*
173  | Routine:	biton (row, column)
174  |
175  | Results:	returns true (non-0) or false (0) for whether the bit at
176  |		(row, col) in the character bit-map is "on".
177  *----------------------------------------------------------------------------*/
178 
179 biton(row, col)
180 int row, col;
181 {
182 	return ((charbits[row * WB + (col >> 3)] & 0xff) & (0x80 >> (col & 7)));
183 }
184 
185 
186 /*----------------------------------------------------------------------------*
187  | Routines:	rd1, rd2, rd3, rd4
188  |
189  | Results:	returns 1, 2, 3 or 4 bytes from the font file.  Used to read
190  |		2-, 3- and 4- byte integers in the proper byte order.
191  *----------------------------------------------------------------------------*/
192 
193 rd1()
194 {
195     int i;
196 
197     if((i = getc(FID)) == EOF) error("file read error");
198     return i;
199 }
200 
201 rd2()
202 {
203     register int i = rd1() << 8;
204 
205     return i + rd1();
206 }
207 
208 rd3()
209 {
210     register int i = rd2() << 8;
211 
212     return i + rd1();
213 }
214 
215 rd4()
216 {
217     register int i = rd2() << 16;
218 
219     return i + rd2();
220 }
221