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