1*19928Sslatteng /*	makevfont.c	(Berkeley)	85/05/03	1.6
217910Sslatteng  *
317910Sslatteng  * Font description file producer for versatec fonts:  David Slattengren
414681Sslatteng  * Taken from vfontinfo by Andy Hertzfeld  4/79
514681Sslatteng  *
616097Sslatteng  *	Use:  makevfont [ -nNAME ]  [ -s -a -o -l -c -p# -r# -f# -ddir ]
715057Sslatteng  *		[ "-xs1,s2[;s1,s2...]" ]  [ "-ys1,s2[;s1,s2...]" ]  font
814681Sslatteng  *
9*19928Sslatteng  *	Makefont takes the font named "font" (with or without pointsize
10*19928Sslatteng  *	extension on the filename) and produces a ditroff description file
11*19928Sslatteng  *	from it.  The -n option takes the 1 or 2 letter troff name to put
1215057Sslatteng  *	the description (default = XX).  The -f option takes an integer per-
1316097Sslatteng  *	centage factor to multiply widths by.  The -s, -o and -a options select
1415057Sslatteng  *	a different character mapping than for a "roman" font.  s = special;
1516097Sslatteng  *	o = otimespecal; a = ascii.  The -l option indicates it has ligatures.
1616097Sslatteng  *	The -c option tells makevfont that the font is constant width and
1716097Sslatteng  *	will set parameters appropriately.
1815057Sslatteng  *
1916097Sslatteng  *	Both -x and -y options allow character name mapping.  A colon separated
2016097Sslatteng  *	list of comma-separated character-name pairs follows the x or y.
2116097Sslatteng  *	Notice that there are no spaces in the -x or -y command.  A -x pair
2216097Sslatteng  *	REPLACES the definition for s1 by s2.  A -y pair creates a synonym for
2316097Sslatteng  *	s1 and calls it s2.  -x and -y MUST be sent after -s, -m, -i, or -a
2416097Sslatteng  *	if one of them is used.  Some synonyms are defaulted.  To remove a
2516097Sslatteng  *	synonym or character, leave out s2.
2615057Sslatteng  *
2716097Sslatteng  *	The -p# option tells what point size the DESC file has as it's
2816097Sslatteng  *	"unitwidth" argument (default: 36).  The -r# option is the resolution
2916097Sslatteng  *	of the device (default: 200, in units/inch).  The -d option tells
3016097Sslatteng  *	where to find fonts (default: /usr/lib/vfont).
3114681Sslatteng  */
3214681Sslatteng 
3314681Sslatteng /*
3414681Sslatteng  *  Here's an ascii character set, just in case you need it:
3514681Sslatteng 
3614681Sslatteng      | 00 nul| 01 soh| 02 stx| 03 etx| 04 eot| 05 enq| 06 ack| 07 bel|
3714681Sslatteng      | 08 bs | 09 ht | 0a nl | 0b vt | 0c np | 0d cr | 0e so | 0f si |
3814681Sslatteng      | 10 dle| 11 dc1| 12 dc2| 13 dc3| 14 dc4| 15 nak| 16 syn| 17 etb|
3914681Sslatteng      | 18 can| 19 em | 1a sub| 1b esc| 1c fs | 1d gs | 1e rs | 1f us |
4014681Sslatteng      | 20 sp | 21  ! | 22  " | 23  # | 24  $ | 25  % | 26  & | 27  ' |
4114681Sslatteng      | 28  ( | 29  ) | 2a  * | 2b  + | 2c  , | 2d  - | 2e  . | 2f  / |
4214681Sslatteng      | 30  0 | 31  1 | 32  2 | 33  3 | 34  4 | 35  5 | 36  6 | 37  7 |
4314681Sslatteng      | 38  8 | 39  9 | 3a  : | 3b  ; | 3c  < | 3d  = | 3e  > | 3f  ? |
4414681Sslatteng      | 40  @ | 41  A | 42  B | 43  C | 44  D | 45  E | 46  F | 47  G |
4514681Sslatteng      | 48  H | 49  I | 4a  J | 4b  K | 4c  L | 4d  M | 4e  N | 4f  O |
4614681Sslatteng      | 50  P | 51  Q | 52  R | 53  S | 54  T | 55  U | 56  V | 57  W |
4714681Sslatteng      | 58  X | 59  Y | 5a  Z | 5b  [ | 5c  \ | 5d  ] | 5e  ^ | 5f  _ |
4814681Sslatteng      | 60  ` | 61  a | 62  b | 63  c | 64  d | 65  e | 66  f | 67  g |
4914681Sslatteng      | 68  h | 69  i | 6a  j | 6b  k | 6c  l | 6d  m | 6e  n | 6f  o |
5014681Sslatteng      | 70  p | 71  q | 72  r | 73  s | 74  t | 75  u | 76  v | 77  w |
5114681Sslatteng      | 78  x | 79  y | 7a  z | 7b  { | 7c  | | 7d  } | 7e  ~ | 7f del|
5214681Sslatteng 
5314681Sslatteng  *
5414681Sslatteng  */
5514681Sslatteng 
5614681Sslatteng #include <stdio.h>
5714681Sslatteng #include <ctype.h>
5814681Sslatteng #include <vfont.h>
59*19928Sslatteng #include <strings.h>
6014681Sslatteng 
61*19928Sslatteng char 	sccsid[] = "@(#)makevfont.c	1.6	(Berkeley)	05/03/85";
6214681Sslatteng 
6314681Sslatteng #define MAGICN		0436	/* font file magic number */
6414681Sslatteng #define PCNTUP		62	/* percent of maximum height for an ascender */
6514681Sslatteng #define PCNTDOWN	73	/* percent of maximum droop for a descender */
6618124Sslatteng #ifndef BITDIR
6716097Sslatteng #define BITDIR		"/usr/lib/vfont"
6818124Sslatteng #endif
6914681Sslatteng #define POINTSIZE	36	/* this is the "unitwidth" point size */
7014681Sslatteng #define MINSIZE		6	/* the minimum and maximum point size values */
7114681Sslatteng #define MAXSIZE		36	/*    acceptible for use as "unitwidth"s */
7214681Sslatteng #define RESOLUTION	200	/* resolution of versatec (dots/inch) */
7314681Sslatteng #define MINRES		10	/* check up on resolution input by setting */
7414681Sslatteng #define MAXRES		100000	/*    absurdly out-of-range limits on them */
7514681Sslatteng #define APOINT		72	/* 1/APOINT inches = 1 point */
7615057Sslatteng #define SYNON		100	/* 2 * pairs allowed in synonym table */
7714681Sslatteng 
7815057Sslatteng 
7914681Sslatteng struct header	FontHeader;
8014681Sslatteng struct dispatch	disptable[256];
8114681Sslatteng 
8214681Sslatteng int	res = RESOLUTION;	/* resolution of the device (units/inch) */
8314681Sslatteng int	pointsize = POINTSIZE;	/* point size being used for unitwidth */
8415057Sslatteng int	factor = 100;		/* percent for magnifying (shrinking) widths */
8514681Sslatteng int	psize;			/* point size of font actually used */
8615057Sslatteng int	psizelist[] = { 36,24,22,20,18,16,14,28,12,11,10,9,8,7,6,0 };
8714681Sslatteng 
8815057Sslatteng char	*fontname = "XX";	/* troff font name - set on command line */
8916097Sslatteng char	*fontdir = BITDIR;	/* place to look for fonts */
9014681Sslatteng char	IName[100];		/* input file name put here */
9114681Sslatteng char	*rdchar ();		/* function makes strings for ascii */
9214681Sslatteng int	FID = -1;		/* input file number */
9314681Sslatteng 
9414681Sslatteng int	maxdown = 0;		/* size of the most "droopy" character */
9514681Sslatteng int	maxup = 0;		/* size of the tallest character */
9614681Sslatteng int	type;			/* 1, 2, or 3 for type of ascend/descending */
9716097Sslatteng int	nullchar = -1;		/* finds non-existant character in the font */
9815057Sslatteng int	ligsf = 0;		/* flag "does this font have ligatures?" */
9916097Sslatteng int	constant = 0;		/* flag constant width font (spacewidth, etc.)*/
10014681Sslatteng 
10114681Sslatteng 				/* following are the character maps for */
10214681Sslatteng 				/* ascii code-conversion to printables... */
10314681Sslatteng char	**charmap;
10415057Sslatteng char	**synonyms;
10515057Sslatteng int	numsyn;
10615057Sslatteng 
10714681Sslatteng char *vregular[] = {
10814681Sslatteng 
10915057Sslatteng 	"??", "fi", "fl", "ff", "\\-", "ru", "em", "bu", "sq", "Fi", "Fl", "de",
11014681Sslatteng 	"dg", "fm", "co", "rg", "ct", "14", "12", "34", "^T", "^U", "^V", "^W",
11115057Sslatteng 	"^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_", "", "!", "\"", "#",
11214681Sslatteng 	"$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1",
11314681Sslatteng 	"2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
11414681Sslatteng 	"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
11514681Sslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
11614681Sslatteng 	"\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
11714681Sslatteng 	"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
11815057Sslatteng 	"x", "y", "z", "{", "|", "}", "~", "^?",
11915057Sslatteng 	(char *) 0
12015057Sslatteng };
12115057Sslatteng int nregular = 2;
12215057Sslatteng char *sregular[SYNON] = {
12315057Sslatteng 	"-", "hy",	"_", "\\_"
12415057Sslatteng };
12514681Sslatteng 
12614681Sslatteng char *vspecial[] = {
12714681Sslatteng 
12815057Sslatteng 	"??", "if", "ip", "pt", "rh", "cu", "rn", "bs", "+-", "<=", ">=", "sr",
12914681Sslatteng 	"ts", "is", "sl", "bv", "lf", "rf", "lc", "rc", "lt", "lb", "rt", "rb",
13015057Sslatteng 	"lk", "rk", "sb", "sp", "ca", "no", "lh", "mo", "", "!", "\"", "#",
13114681Sslatteng 	"$", "%", "&", "aa", "gr", ")", "mu", "pl", ",", "mi", ".", "di", "==",
13214681Sslatteng 	"~=", "ap", "!=", "<-", "->", "ua", "da", "sc", "**", ":", ";", "<",
13314681Sslatteng 	"eq", ">", "?", "@", "*A", "*B", "*G", "*D", "*E", "*Z", "*Y", "*H",
13414681Sslatteng 	"*I", "*K", "*L", "*M", "*N", "*C", "*O", "*P", "*R", "*S", "*T", "*U",
13514681Sslatteng 	"*F", "*X", "*Q", "*W", "dd", "br", "ib", "\\", "ci", "^", "ul", "ga",
13614681Sslatteng 	"*a", "*b", "*g", "*d", "*e", "*z", "*y", "*h", "*i", "*k", "*l", "*m",
13714681Sslatteng 	"*n", "*c", "*o", "*p", "*r", "*s", "*t", "*u", "es", "*x", "*q", "*w",
13815057Sslatteng 	"pd", "*f", "{", "|", "}", "~", "^?",
13915057Sslatteng 	(char *) 0
14014681Sslatteng };
14115057Sslatteng int nspecial = 0;
14215057Sslatteng char *sspecial[SYNON] = {
14315057Sslatteng 	"",""
14415057Sslatteng };
14514681Sslatteng 
14615057Sslatteng char *vtimes[] = {
14714681Sslatteng 
14815057Sslatteng 	"??", "if", "ip", "pt", "rh", "cu", "rn", "bs", "+-", "<=", ">=", "mi",
14915057Sslatteng 	"**", "pl", "eq", "gr", "lt", "lk", "lb", "rt", "rk", "rb", "ap", "mo",
15015057Sslatteng 	"br", "rk", "sb", "sp", "ca", "no", "~=", "mo", "", "da", "no", "ua",
15115057Sslatteng 	"sc", "dd", "if", "pd", "sb", "sp", "mu", "+-", "ca", "cu", "<-", "di",
15215057Sslatteng 	"->",
15315057Sslatteng 	"!=", "sr", "<=", ">=", "==", "or", "is", "bv", "lc", "rc", "lf", "rf",
15415057Sslatteng 	"~=", "_", "ib", "ul", "rn", "ip", "*G", "*D", "*E", "*F", "*G", "*H",
15515057Sslatteng 	"*I", "??", "*L", "*L", "*N", "*C", "*O", "*P", "*H", "*S", "*S", "*U",
15615057Sslatteng 	"*U", "*X", "*W", "*C", "*Q", "br", "ib", "ga", "aa", "^", "ul", "ga",
15715057Sslatteng 	"*a", "*b", "*g", "*d", "*e", "*z", "*y", "*h", "*i", "*k", "*l", "*m",
15815057Sslatteng 	"*n", "*c", "*o", "*p", "*r", "*s", "*t", "*u", "es", "*x", "*q", "*w",
15915057Sslatteng 	"pd", "*f", "{", "|", "}", "~", "^?",
16015057Sslatteng 	(char *) 0
16115057Sslatteng };
16215057Sslatteng int ntimes = 0;
16315057Sslatteng char *stimes[SYNON] = {
16415057Sslatteng 	"",""
16515057Sslatteng };
16615057Sslatteng 
16715057Sslatteng 
16815057Sslatteng char *vascii[] = {
16916097Sslatteng 	"", "da", "*a", "*b", "an", "no", "mo", "*p", "*l", "*g", "*d",
17015057Sslatteng 	"ua", "+-", "O+", "if", "pd", "sb", "sp", "ca", "cu", "fa", "te",
17115057Sslatteng 	"OX", "<>", "<-", "->", "!=", "ap", "<=", ">=", "==", "or", "",
17215057Sslatteng 	"!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
17315057Sslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
17415057Sslatteng 	"<", "=", ">", "?",
17515057Sslatteng 	"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
17615057Sslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
17715057Sslatteng 	"\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
17815057Sslatteng 	"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
17916097Sslatteng 	"x", "y", "z", "{", "|", "}", "~", "??",
18015057Sslatteng 	(char *)0
18115057Sslatteng };
18215057Sslatteng int	nascii = 3;
18315057Sslatteng char *sascii[SYNON] = {
18415057Sslatteng 	"-", "hy",	"-", "\\-",	"_", "\\_"
18515057Sslatteng };
18615057Sslatteng 
18715057Sslatteng 
main(argc,argv)18814681Sslatteng main (argc, argv)
18914681Sslatteng int argc;
19014681Sslatteng char **argv;
19114681Sslatteng {
19215057Sslatteng     register int i;		/* two indexes */
19315057Sslatteng     register int j;
19415057Sslatteng     register char *ptr;		/* string traveler */
19515057Sslatteng     register char delimit;	/* place for delimiters on command line */
19616097Sslatteng     char *replacelist = NULL;	/* string of character name replacements */
19716097Sslatteng     char *synonymlist = NULL;	/* string of synonym entries */
19815057Sslatteng     char tostring();		/* function makes a string */
19915057Sslatteng     char *nextstring();		/* moves to next string on list */
20016097Sslatteng     char *operand();
20114681Sslatteng 
20215057Sslatteng 
20315057Sslatteng     charmap = vregular;			/* default character map */
20415057Sslatteng     synonyms = sregular;
20515057Sslatteng     numsyn = nregular;
20616097Sslatteng     while (--argc > 0 && *(*(++argv)) == '-') {		/* do options... */
20716097Sslatteng 	switch ((*argv)[1]) {
20814681Sslatteng 
20915057Sslatteng 	  case 's': charmap = vspecial;		/* special font */
21015057Sslatteng 		    synonyms = sspecial;
21115057Sslatteng 		    numsyn = nspecial;
21214681Sslatteng 		    break;
21315057Sslatteng 
21416097Sslatteng 	  case 'o': charmap = vtimes;		/* times special font */
21515057Sslatteng 		    synonyms = stimes;
21615057Sslatteng 		    numsyn = ntimes;
21715057Sslatteng 		    break;
21815057Sslatteng 
21915057Sslatteng 	  case 'a': charmap = vascii;		/* ascii font */
22015057Sslatteng 		    synonyms = sascii;
22115057Sslatteng 		    numsyn = nascii;
22215057Sslatteng 		    break;
22315057Sslatteng 
22416097Sslatteng 	  case 'c': constant = 1;		/* constant width font */
22516097Sslatteng 		    break;
22616097Sslatteng 
22715057Sslatteng 	  case 'l': ligsf = 1;			/* ascii font */
22815057Sslatteng 		    break;
22915057Sslatteng 
23016097Sslatteng 	  case 'n': fontname = operand(&argc, &argv);	/* troff font name */
23115057Sslatteng 		    break;
23215057Sslatteng 
23316097Sslatteng 	  case 'x': replacelist = operand(&argc, &argv);   /* replacements */
23415057Sslatteng 		    break;
23515057Sslatteng 
23616097Sslatteng 	  case 'y': synonymlist = operand(&argc, &argv);	/* synonyms */
23715057Sslatteng 		    break;
23815057Sslatteng 
23916097Sslatteng 	  case 'd': fontdir = operand(&argc, &argv);	/* directory */
24014681Sslatteng 		    break;
24114681Sslatteng 
24216097Sslatteng 	  case 'p': pointsize = atoi(operand(&argc, &argv));	/* point size */
24316097Sslatteng 		    if (pointsize < MINSIZE || pointsize > MAXSIZE)
24416097Sslatteng 			error("Illegal point size: %d", pointsize);
24514681Sslatteng 		    break;
24614681Sslatteng 
24716097Sslatteng 	  case 'f': factor = atoi(operand(&argc, &argv));    /*  % reduction */
24816097Sslatteng 		    if (factor < 1 || factor > 1000)
24916097Sslatteng 			error("Illegal factor: %d", factor);
25015057Sslatteng 		    break;
25115057Sslatteng 
25216097Sslatteng 	  case 'r': res = atoi(operand(&argc, &argv));	/* resolution */
25316097Sslatteng 		    if (res < MINRES || res > MAXRES)
25416097Sslatteng 			error("Illegal resolution: %d", res);
25514681Sslatteng 		    break;
25614681Sslatteng 
25716097Sslatteng 	   default: error("Bad option: %c", **argv);
25814681Sslatteng 	}
25914681Sslatteng     }
26016097Sslatteng 				/* do character name replacements */
26116097Sslatteng     if (replacelist != NULL) {
26216097Sslatteng 	ptr = replacelist;
26316097Sslatteng 	while (delimit = tostring(ptr, ',')) {		/* get s1 */
26416097Sslatteng 	    for (i = 0; charmap[i] != 0; i++)		/* search for match */
26516097Sslatteng 		if (strcmp (charmap[i], ptr) == 0)
26616097Sslatteng 		    break;
26716097Sslatteng 	    if (!charmap[i]) error("-x option: no match");
26816097Sslatteng 	    charmap[i] = ptr = nextstring(ptr);		/* replace s1 */
26916097Sslatteng 	    delimit = tostring(ptr, ':');		/* with string s2 */
27016097Sslatteng 	    if (delimit) ptr = nextstring(ptr);
27116097Sslatteng 	}
27216097Sslatteng     }
27316097Sslatteng 				/* do the synonym list */
27416097Sslatteng     if (synonymlist != NULL) {
27516097Sslatteng 	ptr = synonymlist;
27616097Sslatteng 	while (delimit = tostring(ptr, ',')) {	/* get s1 */
27716097Sslatteng 	    synonyms[2 * numsyn] = ptr;		/* set on end of list */
27816097Sslatteng 	    ptr = nextstring(ptr);		/* get string s2 */
27916097Sslatteng 	    delimit = tostring(ptr, ':');
28016097Sslatteng 	    if (*ptr) {				 /* if something there */
28116097Sslatteng 		synonyms[2 * numsyn++ + 1] = ptr;	/* add to list */
28216097Sslatteng 	    } else {				   /* otherwise remove */
28316097Sslatteng 		for (i = 0; i < numsyn; i++) {		  /* from list */
28416097Sslatteng 		    if (!strcmp(synonyms[2*i],synonyms[2*numsyn])) {
28516097Sslatteng 			numsyn--;
28616097Sslatteng 			for (j = i--; j < numsyn; j++) {
28716097Sslatteng 			    synonyms[2 * j] = synonyms[2 * (j+1)];
28816097Sslatteng 			    synonyms[2*j + 1] = synonyms[2*j + 3];
28916097Sslatteng 			}
29016097Sslatteng 		    }
29116097Sslatteng 		}
29216097Sslatteng 	    }
29316097Sslatteng 	    if (delimit) ptr = nextstring(ptr);
29416097Sslatteng 	    if (numsyn > SYNON) error("out of synonym space");
29516097Sslatteng 	}
29616097Sslatteng     }
29714681Sslatteng 
29816097Sslatteng     if (argc != 1)					/* open font file */
29916097Sslatteng 	error("A vfont filename must be the last operand.");
300*19928Sslatteng     if (ptr = rindex(*argv, '.')) ptr++;
301*19928Sslatteng     if (ptr && *ptr <= '9' && *ptr >= '0') {
302*19928Sslatteng 	psize = atoi(ptr);
303*19928Sslatteng 	if (psize < MINSIZE || psize > MAXSIZE)
304*19928Sslatteng 	    error("point size of file \"%s\" out of range", *argv);
305*19928Sslatteng 	sprintf (IName, "%s/%s", fontdir, *argv);
30614681Sslatteng 	FID = open (IName, 0);
307*19928Sslatteng     } else {
308*19928Sslatteng 	for (i = 0; FID < 0 && (psize = psizelist[i]) > 0; i++) {
309*19928Sslatteng 	    sprintf (IName, "%s/%s.%d", fontdir, *argv, psize);
310*19928Sslatteng 	    FID = open (IName, 0);
311*19928Sslatteng 	}
31214681Sslatteng     }
313*19928Sslatteng     if (FID < 0)
314*19928Sslatteng 	error ("Can't open %s", *argv);
31514681Sslatteng 
31616097Sslatteng 						/* read font width table */
31714681Sslatteng     if (read (FID, &FontHeader, sizeof FontHeader) != sizeof FontHeader)
31816097Sslatteng 	error("Bad header in Font file.");
31914681Sslatteng     if (read (FID, &disptable[0], sizeof disptable) != sizeof disptable)
32016097Sslatteng 	error("Bad dispatch table in Font file");
32114681Sslatteng     if (FontHeader.magic != MAGICN)
32214681Sslatteng 	printf ("Magic number %o wrong\n", FontHeader.magic);
32314681Sslatteng 
32414681Sslatteng 
32514681Sslatteng     printf ("# Font %s, ", IName);			/* head off the file */
32614681Sslatteng     printf ("max width %d, max height %d\n",
32714681Sslatteng 		FontHeader.maxx, FontHeader.maxy);
32815057Sslatteng     printf ("name %s\n", fontname);
32915057Sslatteng     if (ligsf)
33014681Sslatteng 	printf ("ligatures ff fl fi ffl ffi 0\n");
33114681Sslatteng 
33215057Sslatteng 				/* pass 1 - set up maximums for ups and downs */
33316097Sslatteng     for (j=0; j<256; j++) {	/* and find out constant width if requested */
33414681Sslatteng 	if (disptable[j].nbytes != 0) {
33514681Sslatteng 	    if (disptable[j].up > maxup) maxup = disptable[j].up;
33614681Sslatteng 	    if (disptable[j].down > maxdown) maxdown = disptable[j].down;
33716097Sslatteng 	    if (constant && disptable[j].width) constant = disptable[j].width;
33816097Sslatteng 	} else			/* find a non-existant character to put \| in */
33916097Sslatteng 	    if (nullchar < 0) nullchar = j;
34014681Sslatteng     }
34114681Sslatteng     if (maxdown == 0) maxdown = 1;
34214681Sslatteng 
34316097Sslatteng     if (constant) {
34416097Sslatteng 	constant = (factor * (pointsize * constant + psize/2) / psize) / 100;
34516097Sslatteng 	printf ("spacewidth %d\n", constant);
34616097Sslatteng     }
34716097Sslatteng     printf ("# char	width	u/d	octal\ncharset\n");
34816097Sslatteng     if (nullchar >= 0) {
34916097Sslatteng 	printf ("\\|	%4d	 0	0%o\n\\^	%4d	 0	0%o\n",
35016097Sslatteng 		constant ? constant : (res*pointsize / APOINT + 4)/6, nullchar,
35116097Sslatteng 		constant ? 0 : (res * pointsize / APOINT + 7) / 12, nullchar);
35216097Sslatteng     }
35316097Sslatteng 
35414681Sslatteng /*******************************************************************************
35514681Sslatteng 
35614681Sslatteng 	`type' is used to determine overhangs (up/down) from percentage of
35714681Sslatteng 	the maximum heights and dips.  Ascenders are higher than PCNTUP%
35814681Sslatteng 	of the highest, as descenders are more than PCNTDOWN%.
35914681Sslatteng 	widths [i = f(width)] are calculated from the definition point
36014681Sslatteng 	size (pointsize) and the one from this font (psize).
36114681Sslatteng 
36214681Sslatteng *******************************************************************************/
36314681Sslatteng 
36414681Sslatteng     for (j=0; j<256; j++) {
36514681Sslatteng 	if (disptable[j].nbytes != 0) {
36614681Sslatteng 	    type = (int) (((disptable[j].up * 100) / maxup) > PCNTUP) * 2 |
36714681Sslatteng 		    (int) (((disptable[j].down * 100) / maxdown) > PCNTDOWN);
36815057Sslatteng 	    if (*(ptr = charmap[j])) {
36915057Sslatteng 		printf ("%s	%4d	 %d	0%o\n", ptr, (factor *
37015057Sslatteng 			(pointsize * disptable[j].width + psize/2) / psize)/100,
37115057Sslatteng 			type, j);
37215057Sslatteng 		for (i = 0; i < numsyn; i++)
37315057Sslatteng 		    if (strcmp (ptr, synonyms[2 * i]) == 0)
37415057Sslatteng 			printf ("%s	\"\n", synonyms[2 * i + 1]);
37515057Sslatteng 	    }
37614681Sslatteng 	}
37717910Sslatteng     } /* for j */
37817910Sslatteng     exit(0);
37914681Sslatteng }
38014681Sslatteng 
38115057Sslatteng 
38215057Sslatteng /*----------------------------------------------------------------------------*
38316097Sslatteng  | Routine:	char  * operand (& argc,  & argv)
38416097Sslatteng  |
38516097Sslatteng  | Results:	returns address of the operand given with a command-line
38616097Sslatteng  |		option.  It uses either "-Xoperand" or "-X operand", whichever
38716097Sslatteng  |		is present.  The program is terminated if no option is present.
38816097Sslatteng  |
38916097Sslatteng  | Side Efct:	argc and argv are updated as necessary.
39016097Sslatteng  *----------------------------------------------------------------------------*/
39116097Sslatteng 
operand(argcp,argvp)39216097Sslatteng char *operand(argcp, argvp)
39316097Sslatteng int * argcp;
39416097Sslatteng char ***argvp;
39516097Sslatteng {
39616097Sslatteng 	if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
39716097Sslatteng 	if ((--*argcp) <= 0)			/* no operand */
39816097Sslatteng 	    error("command-line option operand missing.");
39916097Sslatteng 	return(*(++(*argvp)));			/* operand next word */
40016097Sslatteng }
40116097Sslatteng 
40216097Sslatteng 
40316097Sslatteng /*----------------------------------------------------------------------------*
40415057Sslatteng  | Routine:	char  tostring (pointer, delimitter)
40515057Sslatteng  |
40615057Sslatteng  | Results:	checks string pointed to by pointer and turns it into a
40715057Sslatteng  |		string at 'delimitter' by replacing it with '\0'.  If the
40815057Sslatteng  |		end of the string is found first, '\0' is returned; otherwise
40915057Sslatteng  |		the delimitter found there is returned.
41015057Sslatteng  |
41115057Sslatteng  *----------------------------------------------------------------------------*/
41215057Sslatteng 
tostring(p,d)41315057Sslatteng char tostring(p, d)
41415057Sslatteng register char *p;
41515057Sslatteng register char d;
41615057Sslatteng {
41715057Sslatteng     while (*p && *p != d) p++;
41815057Sslatteng     d = *p;
41915057Sslatteng     *p = '\0';
42015057Sslatteng     return d;
42115057Sslatteng }
42215057Sslatteng 
42315057Sslatteng 
42415057Sslatteng /*----------------------------------------------------------------------------*
42515057Sslatteng  | Routine:	char  * nextstring (pointer)
42615057Sslatteng  |
42715057Sslatteng  | Results:	returns address of next string after one pointed to by
42815057Sslatteng  |		pointer.  The next string is after the '\0' byte.
42915057Sslatteng  |
43015057Sslatteng  *----------------------------------------------------------------------------*/
43115057Sslatteng 
nextstring(p)43215057Sslatteng char *nextstring(p)
43315057Sslatteng register char *p;
43415057Sslatteng {
43515057Sslatteng     while (*(p++));
43615057Sslatteng     return p;
43715057Sslatteng }
43815057Sslatteng 
43915057Sslatteng 
error(s,a1,a2,a3,a4,a5)44016097Sslatteng error(s, a1, a2, a3, a4, a5)
44116097Sslatteng char *s;
44214681Sslatteng {
44316097Sslatteng     fprintf(stderr, "makefont: ");
44416097Sslatteng     fprintf(stderr, s, a1, a2, a3, a4);
44516097Sslatteng     fprintf(stderr, "\n");
44614681Sslatteng     exit(8);
44714681Sslatteng }
448