change -t option to -o
[unix-history] / usr / src / local / ditroff / ditroff.old.okeeffe / driver / makevfont.c
CommitLineData
ae72ba14 1/* Font description file producer for versatec fonts: David Slattengren
ebac57d3
DS
2 * Taken from vfontinfo by Andy Hertzfeld 4/79
3 *
ae72ba14
DS
4 * Use: mvfnt [ -nNAME ] [ -s -a -t -l -p# -r# -f# -ddir ]
5 * [ "-xs1,s2[;s1,s2...]" ] [ "-ys1,s2[;s1,s2...]" ] font
ebac57d3
DS
6 *
7 * Mkfnt takes the font named "font" and produces a ditroff description
ae72ba14
DS
8 * file from it. The -n option takes the 1 or 2 letter troff name to put
9 * the description (default = XX). The -f option takes an integer per-
10 * centage factor to multiply widths by. The -s, -t and -a options select
11 * a different character mapping than for a "roman" font. s = special;
12 * t = otimespec; a = ascii. The -l option says the font has ligatures.
13 *
14 * Both -x and -y options allow character name mapping. A semi-colon
15 * separated list of comma-separated character-name pairs follows the
16 * x or y. Notice that there are no spaces in the -x or -y command. It
17 * is also IMPORTANT to enclose these arguments in single quotes to stop
18 * the cshell from interpretting the contents. A -x pair REPLACES the
19 * definition for s1 by s2. A -y pair creates a synonym for s1 and calls
20 * it s2. -x and -y MUST be sent after -s, -m, -i, or -a if one of them
21 * is used. Some synonyms are defaulted. To remove a synonym or char-
22 * acter, leave out s2.
23 *
24 * The -p# option tells what point size the DESC file has
25 * as it's "unitwidth" argument (default: 36). The -r# option is the
26 * resolution of the device (default: 200, in units/inch). The -d option
27 * tells where to find fonts (default: /usr/lib/vfont).
ebac57d3
DS
28 */
29
30/*
31 * Here's an ascii character set, just in case you need it:
32
33 | 00 nul| 01 soh| 02 stx| 03 etx| 04 eot| 05 enq| 06 ack| 07 bel|
34 | 08 bs | 09 ht | 0a nl | 0b vt | 0c np | 0d cr | 0e so | 0f si |
35 | 10 dle| 11 dc1| 12 dc2| 13 dc3| 14 dc4| 15 nak| 16 syn| 17 etb|
36 | 18 can| 19 em | 1a sub| 1b esc| 1c fs | 1d gs | 1e rs | 1f us |
37 | 20 sp | 21 ! | 22 " | 23 # | 24 $ | 25 % | 26 & | 27 ' |
38 | 28 ( | 29 ) | 2a * | 2b + | 2c , | 2d - | 2e . | 2f / |
39 | 30 0 | 31 1 | 32 2 | 33 3 | 34 4 | 35 5 | 36 6 | 37 7 |
40 | 38 8 | 39 9 | 3a : | 3b ; | 3c < | 3d = | 3e > | 3f ? |
41 | 40 @ | 41 A | 42 B | 43 C | 44 D | 45 E | 46 F | 47 G |
42 | 48 H | 49 I | 4a J | 4b K | 4c L | 4d M | 4e N | 4f O |
43 | 50 P | 51 Q | 52 R | 53 S | 54 T | 55 U | 56 V | 57 W |
44 | 58 X | 59 Y | 5a Z | 5b [ | 5c \ | 5d ] | 5e ^ | 5f _ |
45 | 60 ` | 61 a | 62 b | 63 c | 64 d | 65 e | 66 f | 67 g |
46 | 68 h | 69 i | 6a j | 6b k | 6c l | 6d m | 6e n | 6f o |
47 | 70 p | 71 q | 72 r | 73 s | 74 t | 75 u | 76 v | 77 w |
48 | 78 x | 79 y | 7a z | 7b { | 7c | | 7d } | 7e ~ | 7f del|
49
50 *
51 */
52
53#include <stdio.h>
54#include <ctype.h>
55#include <vfont.h>
56
d4c56fb4 57char sccsid[] = "@(#)makevfont.c 1.3 (Berkeley) %G%";
ebac57d3
DS
58
59#define MAGICN 0436 /* font file magic number */
60#define PCNTUP 62 /* percent of maximum height for an ascender */
61#define PCNTDOWN 73 /* percent of maximum droop for a descender */
62#define FONTDIR "/usr/lib/vfont"
ebac57d3
DS
63#define POINTSIZE 36 /* this is the "unitwidth" point size */
64#define MINSIZE 6 /* the minimum and maximum point size values */
65#define MAXSIZE 36 /* acceptible for use as "unitwidth"s */
66#define RESOLUTION 200 /* resolution of versatec (dots/inch) */
67#define MINRES 10 /* check up on resolution input by setting */
68#define MAXRES 100000 /* absurdly out-of-range limits on them */
69#define APOINT 72 /* 1/APOINT inches = 1 point */
ae72ba14
DS
70#define SYNON 100 /* 2 * pairs allowed in synonym table */
71
ebac57d3
DS
72
73struct header FontHeader;
74struct dispatch disptable[256];
75
76int res = RESOLUTION; /* resolution of the device (units/inch) */
77int pointsize = POINTSIZE; /* point size being used for unitwidth */
ae72ba14 78int factor = 100; /* percent for magnifying (shrinking) widths */
ebac57d3 79int psize; /* point size of font actually used */
ae72ba14 80int psizelist[] = { 36,24,22,20,18,16,14,28,12,11,10,9,8,7,6,0 };
ebac57d3 81
ae72ba14 82char *fontname = "XX"; /* troff font name - set on command line */
ebac57d3
DS
83char *fontdir = FONTDIR; /* place to look for fonts */
84char IName[100]; /* input file name put here */
85char *rdchar (); /* function makes strings for ascii */
86int FID = -1; /* input file number */
87
88int maxdown = 0; /* size of the most "droopy" character */
89int maxup = 0; /* size of the tallest character */
90int type; /* 1, 2, or 3 for type of ascend/descending */
ae72ba14 91int ligsf = 0; /* flag "does this font have ligatures?" */
ebac57d3
DS
92
93 /* following are the character maps for */
94 /* ascii code-conversion to printables... */
95char **charmap;
ae72ba14
DS
96char **synonyms;
97int numsyn;
98
ebac57d3
DS
99char *vregular[] = {
100
ae72ba14 101 "??", "fi", "fl", "ff", "\\-", "ru", "em", "bu", "sq", "Fi", "Fl", "de",
ebac57d3 102 "dg", "fm", "co", "rg", "ct", "14", "12", "34", "^T", "^U", "^V", "^W",
ae72ba14 103 "^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_", "", "!", "\"", "#",
ebac57d3
DS
104 "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1",
105 "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
106 "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
107 "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
108 "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
109 "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
ae72ba14
DS
110 "x", "y", "z", "{", "|", "}", "~", "^?",
111 (char *) 0
112};
113int nregular = 2;
114char *sregular[SYNON] = {
115 "-", "hy", "_", "\\_"
ebac57d3 116};
ae72ba14 117
ebac57d3
DS
118char *vspecial[] = {
119
ae72ba14 120 "??", "if", "ip", "pt", "rh", "cu", "rn", "bs", "+-", "<=", ">=", "sr",
ebac57d3 121 "ts", "is", "sl", "bv", "lf", "rf", "lc", "rc", "lt", "lb", "rt", "rb",
ae72ba14 122 "lk", "rk", "sb", "sp", "ca", "no", "lh", "mo", "", "!", "\"", "#",
ebac57d3
DS
123 "$", "%", "&", "aa", "gr", ")", "mu", "pl", ",", "mi", ".", "di", "==",
124 "~=", "ap", "!=", "<-", "->", "ua", "da", "sc", "**", ":", ";", "<",
125 "eq", ">", "?", "@", "*A", "*B", "*G", "*D", "*E", "*Z", "*Y", "*H",
126 "*I", "*K", "*L", "*M", "*N", "*C", "*O", "*P", "*R", "*S", "*T", "*U",
127 "*F", "*X", "*Q", "*W", "dd", "br", "ib", "\\", "ci", "^", "ul", "ga",
128 "*a", "*b", "*g", "*d", "*e", "*z", "*y", "*h", "*i", "*k", "*l", "*m",
129 "*n", "*c", "*o", "*p", "*r", "*s", "*t", "*u", "es", "*x", "*q", "*w",
ae72ba14
DS
130 "pd", "*f", "{", "|", "}", "~", "^?",
131 (char *) 0
132};
133int nspecial = 0;
134char *sspecial[SYNON] = {
135 "",""
136};
137
138char *vtimes[] = {
139
140 "??", "if", "ip", "pt", "rh", "cu", "rn", "bs", "+-", "<=", ">=", "mi",
141 "**", "pl", "eq", "gr", "lt", "lk", "lb", "rt", "rk", "rb", "ap", "mo",
142 "br", "rk", "sb", "sp", "ca", "no", "~=", "mo", "", "da", "no", "ua",
143 "sc", "dd", "if", "pd", "sb", "sp", "mu", "+-", "ca", "cu", "<-", "di",
144 "->",
145 "!=", "sr", "<=", ">=", "==", "or", "is", "bv", "lc", "rc", "lf", "rf",
146 "~=", "_", "ib", "ul", "rn", "ip", "*G", "*D", "*E", "*F", "*G", "*H",
147 "*I", "??", "*L", "*L", "*N", "*C", "*O", "*P", "*H", "*S", "*S", "*U",
148 "*U", "*X", "*W", "*C", "*Q", "br", "ib", "ga", "aa", "^", "ul", "ga",
149 "*a", "*b", "*g", "*d", "*e", "*z", "*y", "*h", "*i", "*k", "*l", "*m",
150 "*n", "*c", "*o", "*p", "*r", "*s", "*t", "*u", "es", "*x", "*q", "*w",
151 "pd", "*f", "{", "|", "}", "~", "^?",
152 (char *) 0
153};
154int ntimes = 0;
155char *stimes[SYNON] = {
156 "",""
157};
158
159
160char *vascii[] = {
161 "bx", "da", "*a", "*b", "an", "no", "mo", "*p", "*l", "*g", "*d",
162 "ua", "+-", "O+", "if", "pd", "sb", "sp", "ca", "cu", "fa", "te",
163 "OX", "<>", "<-", "->", "!=", "ap", "<=", ">=", "==", "or", "",
164 "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
165 ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
166 "<", "=", ">", "?",
167 "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
168 "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
169 "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
170 "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
171 "x", "y", "z", "{", "|", "}", "~", "^?",
172 (char *)0
173};
174int nascii = 3;
175char *sascii[SYNON] = {
176 "-", "hy", "-", "\\-", "_", "\\_"
ebac57d3
DS
177};
178
179
180main (argc, argv)
181int argc;
182char **argv;
183{
ae72ba14
DS
184 register int i; /* two indexes */
185 register int j;
186 register char *ptr; /* string traveler */
187 register char delimit; /* place for delimiters on command line */
188 char tostring(); /* function makes a string */
189 char *nextstring(); /* moves to next string on list */
ebac57d3 190
ae72ba14
DS
191
192 charmap = vregular; /* default character map */
193 synonyms = sregular;
194 numsyn = nregular;
ebac57d3
DS
195 while (*(*(++argv)) == '-') { /* do options... */
196 switch (*(++(*argv))) {
197
ae72ba14
DS
198 case 's': charmap = vspecial; /* special font */
199 synonyms = sspecial;
200 numsyn = nspecial;
201 break;
202
203 case 't': charmap = vtimes; /* times special font */
204 synonyms = stimes;
205 numsyn = ntimes;
ebac57d3 206 break;
ae72ba14
DS
207
208 case 'a': charmap = vascii; /* ascii font */
209 synonyms = sascii;
210 numsyn = nascii;
211 break;
212
213 case 'l': ligsf = 1; /* ascii font */
214 break;
215
216 case 'n': fontname = ++*argv; /* troff font name */
217 break;
218
219 case 'x': ptr = ++*argv; /* replacements */
220 while (delimit = tostring(ptr, ',')) { /* get s1 */
221 for (i = 0; charmap[i] != 0; i++) /* search for match */
222 if (strcmp (charmap[i], ptr) == 0)
223 break;
224 if (!charmap[i]) error ("-x option: no match");
225 charmap[i] = ptr = nextstring(ptr); /* replace s1 */
226 delimit = tostring(ptr, ';'); /* with string s2 */
227 if (delimit) ptr = nextstring(ptr);
228 }
229 break;
230
231 case 'y': ptr = ++*argv; /* synonyms */
232 while (delimit = tostring(ptr, ',')) { /* get s1 */
233 synonyms[2 * numsyn] = ptr; /* set on end of list */
234 ptr = nextstring(ptr); /* get string s2 */
235 delimit = tostring(ptr, ';');
236 if (*ptr) { /* if something there */
237 synonyms[2 * numsyn++ + 1] = ptr; /* add to list */
238 } else { /* otherwise remove */
239 for (i = 0; i < numsyn; i++) /* from list */
240 if (strcmp (synonyms[2 * i], ptr) == 0)
241 *synonyms[2 * i] = '\0';
242 }
243 if (delimit) ptr = nextstring(ptr);
244 if (numsyn > SYNON) error ("out of synonym space");
245 }
246 break;
247
ebac57d3
DS
248 case 'd': fontdir = ++*argv; /* directory */
249 break;
250
251 case 'p': pointsize = atoi(++*argv); /* point size */
252 if (pointsize < MINSIZE || pointsize > MAXSIZE) {
253 fprintf(stderr, "Illegal point size: %d\n", pointsize);
254 exit(1);
255 }
256 break;
257
ae72ba14
DS
258 case 'f': if ((factor = atoi(++*argv)) < 1 || factor > 1000) {
259 fprintf(stderr, "Illegal factor: %d\n", factor);
260 exit(1);
261 }
262 break;
263
ebac57d3
DS
264 case 'r': res = atoi(++*argv); /* resolution */
265 if (res < MINRES || res > MAXRES) {
266 fprintf(stderr, "Illegal resolution: %d\n", res);
267 exit(1);
268 }
269 break;
270
271 default: fprintf(stderr, "Bad option: %c", **argv);
272 exit(1);
273 }
274 }
ebac57d3
DS
275
276 /* open font file */
277 for (i = 0; FID < 0 && (psize = psizelist[i]) > 0; i++) {
278 sprintf (IName, "%s/%s.%d", fontdir, *argv, psize);
279 FID = open (IName, 0);
280 }
281 if (FID < 0) {
282 printf ("Can't find %s\n", *argv);
283 exit (8);
284 }
285
286
287 if (read (FID, &FontHeader, sizeof FontHeader) != sizeof FontHeader)
288 error ("Bad header in Font file.");
289 if (read (FID, &disptable[0], sizeof disptable) != sizeof disptable)
290 error ("Bad dispatch table in Font file");
291 if (FontHeader.magic != MAGICN)
292 printf ("Magic number %o wrong\n", FontHeader.magic);
293
294
295 printf ("# Font %s, ", IName); /* head off the file */
296 printf ("max width %d, max height %d\n",
297 FontHeader.maxx, FontHeader.maxy);
ae72ba14
DS
298 printf ("name %s\n", fontname);
299 if (ligsf)
ebac57d3 300 printf ("ligatures ff fl fi ffl ffi 0\n");
ebac57d3
DS
301 printf ("# char width u/d octal\ncharset\n");
302 printf ("\\| %4d 0 0\n\\^ %4d 0 0\n",
303 (res * pointsize / APOINT + 4) / 6,
304 (res * pointsize / APOINT + 7) / 12);
305
ae72ba14 306 /* pass 1 - set up maximums for ups and downs */
ebac57d3
DS
307 for (j=0; j<256; j++) {
308 if (disptable[j].nbytes != 0) {
309 if (disptable[j].up > maxup) maxup = disptable[j].up;
310 if (disptable[j].down > maxdown) maxdown = disptable[j].down;
311 }
312 }
313 if (maxdown == 0) maxdown = 1;
314
315/*******************************************************************************
316
317 `type' is used to determine overhangs (up/down) from percentage of
318 the maximum heights and dips. Ascenders are higher than PCNTUP%
319 of the highest, as descenders are more than PCNTDOWN%.
320 widths [i = f(width)] are calculated from the definition point
321 size (pointsize) and the one from this font (psize).
322
323*******************************************************************************/
324
325 for (j=0; j<256; j++) {
326 if (disptable[j].nbytes != 0) {
327 type = (int) (((disptable[j].up * 100) / maxup) > PCNTUP) * 2 |
328 (int) (((disptable[j].down * 100) / maxdown) > PCNTDOWN);
ae72ba14
DS
329 if (*(ptr = charmap[j])) {
330 printf ("%s %4d %d 0%o\n", ptr, (factor *
331 (pointsize * disptable[j].width + psize/2) / psize)/100,
332 type, j);
333 for (i = 0; i < numsyn; i++)
334 if (strcmp (ptr, synonyms[2 * i]) == 0)
335 printf ("%s \"\n", synonyms[2 * i + 1]);
336 }
ebac57d3
DS
337 }
338 }
339}
340
ae72ba14
DS
341
342/*----------------------------------------------------------------------------*
343 | Routine: char tostring (pointer, delimitter)
344 |
345 | Results: checks string pointed to by pointer and turns it into a
346 | string at 'delimitter' by replacing it with '\0'. If the
347 | end of the string is found first, '\0' is returned; otherwise
348 | the delimitter found there is returned.
349 |
350 *----------------------------------------------------------------------------*/
351
352char tostring(p, d)
353register char *p;
354register char d;
355{
356 while (*p && *p != d) p++;
357 d = *p;
358 *p = '\0';
359 return d;
360}
361
362
363/*----------------------------------------------------------------------------*
364 | Routine: char * nextstring (pointer)
365 |
366 | Results: returns address of next string after one pointed to by
367 | pointer. The next string is after the '\0' byte.
368 |
369 *----------------------------------------------------------------------------*/
370
371char *nextstring(p)
372register char *p;
373{
374 while (*(p++));
375 return p;
376}
377
378
ebac57d3
DS
379error(string)
380char *string;
381
382{
383 printf("\nmakefont: %s\n",string);
384 exit(8);
385}