1 /* Font description file producer:  David Slattengren
2  * Taken from vfontinfo by Andy Hertzfeld  4/79
3  *
4  *	Use:  mkfnt [-s] [-m] [-p#] [-r#] [-ddirectory] font
5  *
6  *	Mkfnt takes the font named "font" and produces a ditroff description
7  *	file from it.  The -s option tells mkfnt that this is a special font,
8  *	and sould substitute special character names for the normal ones.  The
9  *	-m option switches to the math font character map.  -m and -s together
10  *	will get the math font at the moment.  The
11  *	-p# option tells what point size the DESC file has as it's "unitwidth"
12  *	argument (default: 36).  The -r# option is the resolution of the device
13  *	(default: 240, in units/inch).  The -d option tells where to look for
14  *	fonts (default: /usr/src/local/imagen/fonts/raster).
15  */
16 
17 /*
18  *  Here's an ascii character set, just in case you need it:
19 
20      | 00 nul| 01 soh| 02 stx| 03 etx| 04 eot| 05 enq| 06 ack| 07 bel|
21      | 08 bs | 09 ht | 0a nl | 0b vt | 0c np | 0d cr | 0e so | 0f si |
22      | 10 dle| 11 dc1| 12 dc2| 13 dc3| 14 dc4| 15 nak| 16 syn| 17 etb|
23      | 18 can| 19 em | 1a sub| 1b esc| 1c fs | 1d gs | 1e rs | 1f us |
24      | 20 sp | 21  ! | 22  " | 23  # | 24  $ | 25  % | 26  & | 27  ' |
25      | 28  ( | 29  ) | 2a  * | 2b  + | 2c  , | 2d  - | 2e  . | 2f  / |
26      | 30  0 | 31  1 | 32  2 | 33  3 | 34  4 | 35  5 | 36  6 | 37  7 |
27      | 38  8 | 39  9 | 3a  : | 3b  ; | 3c  < | 3d  = | 3e  > | 3f  ? |
28      | 40  @ | 41  A | 42  B | 43  C | 44  D | 45  E | 46  F | 47  G |
29      | 48  H | 49  I | 4a  J | 4b  K | 4c  L | 4d  M | 4e  N | 4f  O |
30      | 50  P | 51  Q | 52  R | 53  S | 54  T | 55  U | 56  V | 57  W |
31      | 58  X | 59  Y | 5a  Z | 5b  [ | 5c  \ | 5d  ] | 5e  ^ | 5f  _ |
32      | 60  ` | 61  a | 62  b | 63  c | 64  d | 65  e | 66  f | 67  g |
33      | 68  h | 69  i | 6a  j | 6b  k | 6c  l | 6d  m | 6e  n | 6f  o |
34      | 70  p | 71  q | 72  r | 73  s | 74  t | 75  u | 76  v | 77  w |
35      | 78  x | 79  y | 7a  z | 7b  { | 7c  | | 7d  } | 7e  ~ | 7f del|
36 
37  *
38  */
39 
40 #include <stdio.h>
41 #include <ctype.h>
42 #include "rst.h"
43 
44 char 	sccsid[] = "@(#)makeifont.c	1.1	(Berkeley)	08/17/83";
45 
46 #define PCNTUP		62	/* percent of maximum height for an ascender */
47 #define PCNTDOWN	73	/* percent of maximum droop for a descender */
48 #define FONTDIR		"/usr/src/local/imagen/fonts/raster"
49 #define POINTSIZE	40	/* this is the "unitwidth" point size */
50 #define MINSIZE		6	/* the minimum and maximum point size values */
51 #define MAXSIZE		36	/*    acceptible for use as "unitwidth"s */
52 #define MINRES		10	/* check up on resolution input by setting */
53 #define MAXRES		100000	/*    absurdly out-of-range limits on them */
54 
55 
56 unsigned char *idstrings;	/* place for identifying strings */
57 unsigned char *endstring;	/* points to end of id strings */
58 double	fixtowdth;		/* "fix" and magnification conversion factor */
59 glyph_dir g[DIRSIZ];		/* directory of glyph definitions */
60 preamble p;			/* set of variables for preamble */
61 
62 int	res = RES;		/* resolution of the device (units/inch) */
63 int	pointsize = POINTSIZE;	/* point size being used for unitwidth */
64 int	psize;			/* point size of font actually used */
65 int	psizelist[] = { 40, 36, 28, 24, 22, 20, 18, 16,
66 			14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0 };
67 
68 char	*fontdir = FONTDIR;	/* place to look for fonts */
69 char	IName[100];		/* input file name put here */
70 char	*rdchar ();		/* function makes strings for ascii */
71 int	FID = -1;		/* input file number */
72 
73 int	maxdown = 0;		/* size of the most "droopy" character */
74 int	maxup = 0;		/* size of the tallest character */
75 int	type;			/* 1, 2, or 3 for type of ascend/descending */
76 int	mathf = 0;		/* flag "is this a math font?"; */
77 int	specialf = 0;		/* flag "is this a special font?";  used to
78 				   determine which mapping array to look in. */
79 
80 				/* following are the character maps for */
81 				/* ascii code-conversion to printables... */
82 char	**charmap;
83 char *iregular[] = {
84 
85 	"*G", "*D", "*H", "*L", "*C", "*P", "*S", "*U", "*F", "*Q", "*W",
86 	"id", "ij", "ga", "aa", "^", "d^", "hc", "\\-", "..", "~", "->",
87 	"im", "de", "tc", "tl", "hs", "fe", "ae", "oe", "AE", "OE", "/o",
88 	"!", "\"", "fm", "ft", "%", "&", "'", "(", ")", "*", "+", ",", "-",
89 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
90 	"<", "=", ">", "?",
91 	"/O", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
92 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
93 	"b\"", "]", "\\_", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h",
94 	"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
95 	"w", "x", "y", "z", "ff", "fi", "fl", "Fi", "Fl",
96 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
97 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
98 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
99 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
100 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
101 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
102 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
103 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
104 };
105 
106 char *ispecial[] = {
107 
108 	"mi", "m.", "mu", "**", "\\", "de", "+-", "-+", "O+", "O-", "OX", "O/",
109 	"O.", "di", "ht", "bu", "ut", "==", "ib", "ip", "<=", ">=", "(=", ")=",
110 	"ap", "~~", "sb", "sp", "!=", "eq", "((", "))", "<-", "->", "ua", "da",
111 	"<>", "<<", ">>", "~=", "<_", "_>", "Ua", "Da", "><", "uL", "uR", "lR",
112 	"fm", "if", "mo", "!m", "0/", "ru", "al", ")(", "fa", "te", "no", "~N",
113 	"~R", "~T", "cr", "", "sl", "A", "B", "C", "D", "E", "F", "G", "H", "I",
114 	"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
115 	"X", "Y", "Z", "cu", "ca", "c+", "an", "or", "|-", "-|", "lf", "rf",
116 	"lc", "rc", "{", "}", "<", ">", "bv", "||", "[[", "]]", "", "", "sr",
117 	"#", "gr", "is", "ux", "dx", "rx", "dm", "sc", "dg", "dd", "pp", "@",
118 	"co", "", "$",
119 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
120 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
121 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
122 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
123 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
124 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
125 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
126 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
127 };
128 
129 char *imath[] = {
130 
131 	"", "ct", "dd", "aa", "ga", "?1", "?2", "?3", "?4", "?5", "co", "rg",
132 	"tm", "?6", "pp", "fe", "ma", "bu", "bk", "bb", "ci", "sq", "#", "te",
133 	"rh", "lh", "*a", "*b", "*q", "*d", "*e", "*f", "*g", "*y", "*i", "*c",
134 	"*k", "*l", "*m", "*n", "*o", "*p", "*r", "*s", "*t", "*h", "*w", "*x",
135 	"*u", "*z", "*G", "*D", "*F", "*G", "*C", "*L", "*H", "*W", "pl", "mi",
136 	"mu", "eq", "di", "+-", "de", "fm", "*X", "es", "?7", "pt", "ts", "gr",
137 	"pd", ">", "<", ">=", "<=", "or", "sl", "\\\\", "ap", "~=", "~~", "==",
138 	"po", "**", "?8", "{", "}", "br", "sr", "is", "*S", "*P", "sb", "sp",
139 	"ca", "cu", "ib", "ip", "if", "?9", "ru", "?0", "??", "bs", "b4", "b9",
140 	"->", "<-", "ua", "da", "!=", "lf", "rf", "lc", "rc", "ul", "bv", "lt",
141 	"rt", "lb", "rb", "lk", "rk", "no", "fa", "ti",
142 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
143 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
144 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
145 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
146 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
147 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
148 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
149 	"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
150 };
151 
152 
153 
154 main (argc, argv)
155 int argc;
156 char **argv;
157 {
158     register i, j;
159 
160     while (*(*(++argv)) == '-') {		/* do options... */
161 	switch (*(++(*argv))) {
162 
163 	  case 's': specialf = 1;		/* special font */
164 		    break;
165 
166 	  case 'm': mathf = 1;			/* math font */
167 		    break;
168 
169 	  case 'd': fontdir = ++*argv;		/* directory */
170 		    break;
171 
172 	  case 'p': pointsize = atoi(++*argv);	/* point size */
173 		    if (pointsize < MINSIZE || pointsize > MAXSIZE) {
174 			fprintf(stderr, "Illegal point size: %d\n", pointsize);
175 			exit(1);
176 		    }
177 		    break;
178 
179 	  case 'r': res = atoi(++*argv);	/* resolution */
180 		    if (res < MINRES || res > MAXRES) {
181 			fprintf(stderr, "Illegal resolution: %d\n", res);
182 			exit(1);
183 		    }
184 		    break;
185 
186 	   default: fprintf(stderr, "Bad option: %c", **argv);
187 		    exit(1);
188 	}
189     }
190 			/* set character map */
191     charmap = mathf ? imath : specialf ? ispecial : iregular;
192 
193 							/* open font file */
194     for (i = 0; FID < 0 && (psize = psizelist[i]) > 0; i++) {
195 	sprintf (IName, "%s/%s.r%d", fontdir, *argv, psize);
196 	FID = open (IName, 0);
197     }
198     if (FID < 0) {
199 	printf ("Can't find %s\n", *argv);
200 	exit (8);
201     }
202 
203     i = read(FID, &filemark[0], FMARK);
204     if (strncmp(filemark, "Rast", 4) || i != FMARK)
205 	    error("Bad File Mark in Font file.");
206 
207     p.p_size = rd2();
208     p.p_version = rd1();
209     if (p.p_version)
210 	    error("Wrong version of Font file.");
211     p.p_glyph = rd3();
212     p.p_first = rd2();
213     p.p_last = rd2();
214     p.p_mag = rd4();
215     p.p_desiz = rd4();
216     p.p_linesp = rd4();
217     p.p_wordsp = rd4();
218     p.p_rot = rd2();
219     p.p_cadv = rd1();
220     p.p_ladv = rd1();
221     p.p_id = rd4();
222     p.p_res = rd2();
223     if (p.p_res != res)
224 	    error("Wrong resolution in Font file.");
225 
226     i = p.p_glyph - 44;
227     idstrings = (unsigned char *) malloc (i);
228     endstring = idstrings + i;
229     if (read(FID, idstrings, i) != i)
230 	    error("Bad preamble in Font file.");
231 
232     for (i = p.p_first; i <= p.p_last; i++) {
233 	    g[i].g_height = rd2();
234 	    g[i].g_width = rd2();
235 	    g[i].g_up = rd2();
236 	    g[i].g_left = rd2();
237 	    g[i].g_pwidth = rd4();
238 	    g[i].g_bitp = rd3();
239     }
240 
241 
242     if ((fixtowdth = FIXPIX * p.p_mag / 1000.0) == 0.0)
243 	fixtowdth = FIXPIX;
244 
245     printf("# Font %s, size %.2f, ", IName, p.p_desiz * FIX);
246     printf("first %d, last %d, res %d, ", p.p_first, p.p_last, p.p_res);
247     printf("mag %.2f\n", fixtowdth / FIXPIX);
248 
249     printf("spacewidth %d\n", (int) (p.p_wordsp * fixtowdth));
250     printf("name XX\ninternalname #\n");
251     if (specialf || mathf) {
252 	printf ("special\n");
253     } else {
254 	printf ("ligatures ff fl fi ffl ffi 0\n");
255     }
256     printf ("# char	width	u/d	octal\ncharset\n");
257     printf ("\\|	%4d	 0	0\n\\^	%4d	 0	0\n",
258  		(int) (p.p_wordsp * fixtowdth) / 2,
259  		(int) (p.p_wordsp * fixtowdth) / 4);
260     for (j = p.p_first; j <= p.p_last; j++) {
261 	if (g[j].g_bitp != 0) {
262 	    if (g[j].g_up > maxup) maxup = g[j].g_up;
263 	    if ((i = g[j].g_height - (g[j].g_up + 1)) > maxdown) maxdown = i;
264 	}
265     }
266     if (maxdown == 0) maxdown = 1;
267 
268 /*******************************************************************************
269 
270 	`type' is used to determine overhangs (up/down) from percentage of
271 	the maximum heights and dips.  Ascenders are higher than PCNTUP%
272 	of the highest, as descenders are more than PCNTDOWN%.
273 	widths [i = f(width)] are calculated from the definition point
274 	size (pointsize) and the one from this font (psize).
275 
276 *******************************************************************************/
277 
278     for (j=0; j<256; j++) {
279 	if (g[j].g_bitp != 0) {
280 	    type = (int) (((g[j].g_up * 100) / maxup) > PCNTUP) * 2 | (int)
281 	    	((((g[j].g_height - (g[j].g_up+1)) * 100)/maxdown) > PCNTDOWN);
282 	    i = pointsize * g[j].g_pwidth * fixtowdth / psize;
283 	    printf ("%s	%4d	 %d	0%o\n", charmap[j], i, type, j);
284 	}
285     }
286 }
287 
288 error(string)
289 char *string;
290 
291 {
292     printf("\nmakefont: %s\n",string);
293     exit(8);
294 }
295 
296 rd1()
297 {
298     unsigned char i;
299 
300     if(read (FID, &i, 1) != 1) error("File read error");
301     return (int) i;
302 }
303 
304 rd2()
305 {
306     register int i = rd1() << 8;
307 
308     return i + rd1();
309 }
310 
311 rd3()
312 {
313     register int i = rd2() << 8;
314 
315     return i + rd1();
316 }
317 
318 rd4()
319 {
320     register int i = rd2() << 16;
321 
322     return i + rd2();
323 }
324