1*26451Sslatteng /*	makeifont.c	(Berkeley)	1.8	86/03/04
217909Sslatteng  *
317909Sslatteng  * Font description file producer for imagen fonts:  David Slattengren
414680Sslatteng  * Taken from vfontinfo by Andy Hertzfeld  4/79
514680Sslatteng  *
616096Sslatteng  *  Use:  makeifont [ -nNAME ]  [ -i -s -a -o -l -c ]  [ "-xs1,s2[;s1,s2...]" ]
714983Sslatteng  *		[ "-ys1,s2[;s1,s2...]" ]  [ -p# ]  [ -r# ]  [ -ddir ]  font
814680Sslatteng  *
914680Sslatteng  *	Mkfnt takes the font named "font" and produces a ditroff description
1014983Sslatteng  *	file from it.  The -n option takes the 1 or 2 letter troff name to put
1116096Sslatteng  *	the description (default = XX).  The -s, -o, -i, -a options select a
1214983Sslatteng  *	different character mapping than for a "roman" font.  s = special;
1316096Sslatteng  *	o = math;  i = italics;  a = ascii.  The -l option tells if the font
1416096Sslatteng  *	has ligatures.  The -c option tells makeifont that the font is a
1516096Sslatteng  *	constant width one and sets parameters appropriately.
1614983Sslatteng  *
1714983Sslatteng  *	Both -x and -y options allow character name mapping.  A semi-colon
1814983Sslatteng  *	separated list of comma-separated character-name pairs follows the
1914983Sslatteng  *	x or y.  Notice that there are no spaces in the -x or -y command.  It
2015058Sslatteng  *	is also IMPORTANT to enclose these arguments in single quotes to stop
2114983Sslatteng  *	the cshell from interpretting the contents.  A -x pair REPLACES the
2214983Sslatteng  *	definition for s1 by s2.  A -y pair creates a synonym for s1 and calls
2314983Sslatteng  *	it s2.  -x and -y MUST be sent after -s, -m, -i, or -a  if one of them
2414983Sslatteng  *	is used.  Some synonyms are defaulted.  To remove a synonym or char-
2514983Sslatteng  *	acter, leave out s2.
2614983Sslatteng  *
2714983Sslatteng  *	The -p# option tells what point size the DESC file has
2815058Sslatteng  *	as it's "unitwidth" argument (default: 40).  The -r# option is the
2914983Sslatteng  *	resolution of the device (default: 240, in units/inch).  The -d option
3014983Sslatteng  *	tells where to find fonts (default: /usr/src/local/imagen/fonts/raster).
3114680Sslatteng  */
3214680Sslatteng 
3314680Sslatteng /*
3414680Sslatteng  *  Here's an ascii character set, just in case you need it:
3514680Sslatteng 
3614680Sslatteng      | 00 nul| 01 soh| 02 stx| 03 etx| 04 eot| 05 enq| 06 ack| 07 bel|
3714680Sslatteng      | 08 bs | 09 ht | 0a nl | 0b vt | 0c np | 0d cr | 0e so | 0f si |
3814680Sslatteng      | 10 dle| 11 dc1| 12 dc2| 13 dc3| 14 dc4| 15 nak| 16 syn| 17 etb|
3914680Sslatteng      | 18 can| 19 em | 1a sub| 1b esc| 1c fs | 1d gs | 1e rs | 1f us |
4014680Sslatteng      | 20 sp | 21  ! | 22  " | 23  # | 24  $ | 25  % | 26  & | 27  ' |
4114680Sslatteng      | 28  ( | 29  ) | 2a  * | 2b  + | 2c  , | 2d  - | 2e  . | 2f  / |
4214680Sslatteng      | 30  0 | 31  1 | 32  2 | 33  3 | 34  4 | 35  5 | 36  6 | 37  7 |
4314680Sslatteng      | 38  8 | 39  9 | 3a  : | 3b  ; | 3c  < | 3d  = | 3e  > | 3f  ? |
4414680Sslatteng      | 40  @ | 41  A | 42  B | 43  C | 44  D | 45  E | 46  F | 47  G |
4514680Sslatteng      | 48  H | 49  I | 4a  J | 4b  K | 4c  L | 4d  M | 4e  N | 4f  O |
4614680Sslatteng      | 50  P | 51  Q | 52  R | 53  S | 54  T | 55  U | 56  V | 57  W |
4714680Sslatteng      | 58  X | 59  Y | 5a  Z | 5b  [ | 5c  \ | 5d  ] | 5e  ^ | 5f  _ |
4814680Sslatteng      | 60  ` | 61  a | 62  b | 63  c | 64  d | 65  e | 66  f | 67  g |
4914680Sslatteng      | 68  h | 69  i | 6a  j | 6b  k | 6c  l | 6d  m | 6e  n | 6f  o |
5014680Sslatteng      | 70  p | 71  q | 72  r | 73  s | 74  t | 75  u | 76  v | 77  w |
5114680Sslatteng      | 78  x | 79  y | 7a  z | 7b  { | 7c  | | 7d  } | 7e  ~ | 7f del|
5214680Sslatteng 
5314680Sslatteng  *
5414680Sslatteng  */
5514680Sslatteng 
5614680Sslatteng #include <stdio.h>
5714680Sslatteng #include <ctype.h>
5814680Sslatteng #include "rst.h"
5914680Sslatteng 
60*26451Sslatteng char 	sccsid[] = "@(#)makeifont.c	1.8	(Berkeley)	03/04/86";
6114680Sslatteng 
6214680Sslatteng #define PCNTUP		62	/* percent of maximum height for an ascender */
6314680Sslatteng #define PCNTDOWN	73	/* percent of maximum droop for a descender */
6418123Sslatteng #ifndef BITDIR
6516096Sslatteng #define BITDIR		"/usr/src/local/imagen/fonts/raster"
6618123Sslatteng #endif
6714680Sslatteng #define POINTSIZE	40	/* this is the "unitwidth" point size */
6814680Sslatteng #define MINSIZE		6	/* the minimum and maximum point size values */
6914680Sslatteng #define MAXSIZE		36	/*    acceptible for use as "unitwidth"s */
7014680Sslatteng #define MINRES		10	/* check up on resolution input by setting */
7114680Sslatteng #define MAXRES		100000	/*    absurdly out-of-range limits on them */
7214983Sslatteng #define MAXLAST		127	/* highest character code allowed */
7314983Sslatteng #define SYNON		100	/* number of entries in a synonym table. */
7414983Sslatteng 				/*    equals twice the number of pairs. */
7514680Sslatteng 
7614680Sslatteng 
7714680Sslatteng unsigned char *idstrings;	/* place for identifying strings */
7814680Sslatteng unsigned char *endstring;	/* points to end of id strings */
7914680Sslatteng double	fixtowdth;		/* "fix" and magnification conversion factor */
8014680Sslatteng glyph_dir g[DIRSIZ];		/* directory of glyph definitions */
8114680Sslatteng preamble p;			/* set of variables for preamble */
8214680Sslatteng 
8314680Sslatteng int	res = RES;		/* resolution of the device (units/inch) */
84*26451Sslatteng double	fixpix = FIXPIX;	/* conversion factor "fix"es to pixels */
8514680Sslatteng int	pointsize = POINTSIZE;	/* point size being used for unitwidth */
8614680Sslatteng int	psize;			/* point size of font actually used */
8714680Sslatteng int	psizelist[] = { 40, 36, 28, 24, 22, 20, 18, 16,
8814680Sslatteng 			14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0 };
8914680Sslatteng 
9014983Sslatteng char	*fontname = "XX";	/* troff name of font - set on command line */
9116096Sslatteng char	*fontdir = BITDIR;	/* place to look for fonts */
9214680Sslatteng char	IName[100];		/* input file name put here */
9314680Sslatteng char	*rdchar ();		/* function makes strings for ascii */
9415280Sslatteng FILE *	FID = NULL;		/* input file number */
9514680Sslatteng 
9614680Sslatteng int	maxdown = 0;		/* size of the most "droopy" character */
9714680Sslatteng int	maxup = 0;		/* size of the tallest character */
9814680Sslatteng int	type;			/* 1, 2, or 3 for type of ascend/descending */
9914983Sslatteng int	ligsf = 0;		/* flag "does this font have ligatures?" */
10016096Sslatteng int	constant = 0;		/* flag constant width font (spacewidth, etc.)*/
10114680Sslatteng 
10214680Sslatteng 				/* following are the character maps for */
10314680Sslatteng 				/* ascii code-conversion to printables... */
10414680Sslatteng char	**charmap;
10514983Sslatteng char	**synonyms;
10614983Sslatteng int	numsyn;
10714983Sslatteng 
10814680Sslatteng char *iregular[] = {
10914680Sslatteng 	"*G", "*D", "*H", "*L", "*C", "*P", "*S", "*U", "*F", "*Q", "*W",
11014983Sslatteng 	"id", "ij", "ga", "aa", "^", "d^", "hc", "rn", "..", "~", "ve",
11114983Sslatteng 	"im", "de", "ce", "tl", "ar", "fb", "ae", "oe", "AE", "OE", "o/",
11214983Sslatteng 	"!", "\"", "fm", "ft", "%", "&", "'", "(", ")", "*", "+", ",", "hy",
11314680Sslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
11414680Sslatteng 	"<", "=", ">", "?",
11514983Sslatteng 	"es", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
11614680Sslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
11714983Sslatteng 	"b\"", "]", "\\-", "em", "`", "a", "b", "c", "d", "e", "f", "g", "h",
11814680Sslatteng 	"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
11914983Sslatteng 	"w", "x", "y", "z", "ff", "fi", "fl", "Fi", "Fl"
12014680Sslatteng };
12114983Sslatteng int	nregular = 14;
12214983Sslatteng char *sregular[SYNON] = {
12314983Sslatteng 	"A", "*A",	"B", "*B",	"E", "*E",	"H", "*Y",
12414983Sslatteng 	"I", "*I",	"K", "*K",	"M", "*M",	"N", "*N",
12514983Sslatteng 	"O", "*O",	"P", "*R",	"T", "*T",	"X", "*X",
12614983Sslatteng 	"Z", "*Z",	"hy", "-"
12714983Sslatteng };
12814680Sslatteng 
12914983Sslatteng char *iascii[] = {
13014983Sslatteng 	"m.", "da", "*a", "*b", "an", "no", "mo", "*p", "*l", "*g", "*d",
13114983Sslatteng 	"is", "+-", "O+", "if", "pd", "sb", "sp", "ca", "cu", "fa", "te",
13214983Sslatteng 	"OX", "<>", "<-", "->", "ap", "!=", "<=", ">=", "==", "or", "",
13314983Sslatteng 	"!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
13414983Sslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
13514983Sslatteng 	"<", "=", ">", "?",
13614983Sslatteng 	"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
13714983Sslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
13815058Sslatteng 	"\\", "]", "^", "em", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
13914983Sslatteng 	"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
14014983Sslatteng 	"x", "y", "z", "{", "|", "}", "~", "dm"
14114983Sslatteng };
14214983Sslatteng int	nascii = 2;
14314983Sslatteng char *sascii[SYNON] = {
14414983Sslatteng 	"-", "hy",	"-", "\\-"
14514983Sslatteng };
14614983Sslatteng 
14714680Sslatteng char *ispecial[] = {
14814983Sslatteng 	"mi", "m.", "mu", "**", "\\", "ci", "+-", "-+", "O+", "O-", "OX", "O/",
14914983Sslatteng 	"O.", "di", "ht", "bu", "pe", "==", "ib", "ip", "<=", ">=", "(=", ")=",
15014983Sslatteng 	"ap", "pt", "sb", "sp", "!=", ".=", "((", "))", "<-", "->", "ua", "da",
15114983Sslatteng 	"<>", "<<", ">>", "~=", "lh", "rh", "Ua", "Da", "><", "uL", "uR", "lR",
15214983Sslatteng 	"fm", "if", "mo", "!m", "0/", "ul", "al", ")(", "fa", "te", "no", "?0",
15314983Sslatteng 	"?1", "?2", "cr", "", "/", "A", "B", "C", "D", "E", "F", "G", "H", "I",
15414680Sslatteng 	"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
15514680Sslatteng 	"X", "Y", "Z", "cu", "ca", "c+", "an", "or", "|-", "-|", "lf", "rf",
15615280Sslatteng 	"lc", "rc", "{", "}", "<", ">", "br", "||", "[[", "]]", "", "", "sr",
15714680Sslatteng 	"#", "gr", "is", "ux", "dx", "rx", "dm", "sc", "dg", "dd", "pp", "@",
15814983Sslatteng 	"co", "", "$"
15914680Sslatteng };
16015280Sslatteng int	nspecial = 2;
16114983Sslatteng char *sspecial[SYNON] = {
16215280Sslatteng 	"lh", "La",	"rh", "Ra"
16314983Sslatteng };
16414680Sslatteng 
16514680Sslatteng char *imath[] = {
16615280Sslatteng 	"Bl", "Br", "LT", "RT", "LB", "RB", "rt", "rk", "rb", "lt", "lk", "lb",
16716096Sslatteng 	"rc", "lc", "rf", "lf", "bv", "ci", "^R", "^S", "^T", "^U", "^V", "^W",
16816096Sslatteng 	"^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_",
16916096Sslatteng 	" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
17016096Sslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
17116096Sslatteng 	"<", "=", ">", "?",
17216096Sslatteng 	"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
17316096Sslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
17416096Sslatteng 	"\\", "]", "^", "em", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
17516096Sslatteng 	"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
17616096Sslatteng 	"x", "y", "z", "{", "|", "}", "~", "dm"
17714983Sslatteng };
17814983Sslatteng int	nmath = 0;
17914983Sslatteng char *smath[SYNON] = {
18014983Sslatteng 	"",""
18114983Sslatteng };
18214680Sslatteng 
18314983Sslatteng char *iitalics[] = {
18414983Sslatteng 	"*G", "*D", "*H", "*L", "*C", "*P", "*S", "*U", "*F", "*Q", "*W",
18514983Sslatteng 	"*a", "*b", "*g", "*d", "*e", "*z", "*y", "*h", "*i", "*k", "*l",
18614983Sslatteng 	"*m", "*n", "*c", "*p", "*r", "*s", "*t", "*u", "*f", "*x", "id",
18715280Sslatteng 	"!", "\"", "el", "Fi", "pd", "&", "'", "(", ")", "*", "+", ",", "hy",
18814983Sslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
18914983Sslatteng 	"<", "=", ">", "?",
19014983Sslatteng 	"id", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
19114983Sslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
19215280Sslatteng 	"ff", "]", "fi", "fl", "`", "a", "b", "c", "d", "e", "f", "g", "h",
19314983Sslatteng 	"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
19415280Sslatteng 	"w", "x", "y", "z", "*q", "*w", "?2", "?1", "Fl"
19514680Sslatteng };
19614983Sslatteng int	nitalics = 15;
19714983Sslatteng char *sitalics[SYNON] = {
19814983Sslatteng 	"A", "*A",	"B", "*B",	"E", "*E",	"H", "*Y",
19914983Sslatteng 	"I", "*I",	"K", "*K",	"M", "*M",	"N", "*N",
20014983Sslatteng 	"O", "*O",	"P", "*R",	"T", "*T",	"X", "*X",
20114983Sslatteng 	"Z", "*Z",	"o", "*o",	"hy", "-"
20214983Sslatteng };
20314680Sslatteng 
20414680Sslatteng 
20514680Sslatteng 
main(argc,argv)20614680Sslatteng main (argc, argv)
20714680Sslatteng int argc;
20814680Sslatteng char **argv;
20914680Sslatteng {
21014983Sslatteng     register int i;		/* two indexes */
21114983Sslatteng     register int j;
21214983Sslatteng     register char *ptr;		/* string traveller */
21314983Sslatteng     register char delimit;	/* place for delemiters on command-line */
21416096Sslatteng     char *replacelist = NULL;	/* list of character-name replacements */
21516096Sslatteng     char *synonymlist = NULL;	/* list of synonym entries */
21614983Sslatteng     char tostring();		/* function makes string */
21714983Sslatteng     char *nextstring();		/* moves to next string on list */
21816096Sslatteng     char *operand();		/* reads operands from commandline */
21914680Sslatteng 
22014983Sslatteng     charmap = iregular;			/* default character map */
22114983Sslatteng     synonyms = sregular;
22214983Sslatteng     numsyn = nregular;
22316096Sslatteng     while (--argc > 0 && *(*(++argv)) == '-') {	/* do options... */
22416096Sslatteng 	switch ((*argv)[1]) {
22514680Sslatteng 
22614983Sslatteng 	  case 's': charmap = ispecial;		/* special font */
22714983Sslatteng 		    synonyms = sspecial;
22814983Sslatteng 		    numsyn = nspecial;
22914680Sslatteng 		    break;
23014680Sslatteng 
23116096Sslatteng 	  case 'o': charmap = imath;		/* math font */
23214983Sslatteng 		    synonyms = smath;
23314983Sslatteng 		    numsyn = nmath;
23414680Sslatteng 		    break;
23514680Sslatteng 
23614983Sslatteng 	  case 'i': charmap = iitalics;		/* italics font */
23714983Sslatteng 		    synonyms = sitalics;
23814983Sslatteng 		    numsyn = nitalics;
23914983Sslatteng 		    break;
24014983Sslatteng 
24114983Sslatteng 	  case 'a': charmap = iascii;		/* ascii font */
24214983Sslatteng 		    synonyms = sascii;
24314983Sslatteng 		    numsyn = nascii;
24414983Sslatteng 		    break;
24514983Sslatteng 
24616096Sslatteng 	  case 'c': constant = 1;		/* constant width font */
24716096Sslatteng 		    break;
24816096Sslatteng 
24914983Sslatteng 	  case 'l': ligsf = 1;			/* ascii font */
25014983Sslatteng 		    break;
25114983Sslatteng 
25216096Sslatteng 	  case 'n': fontname = operand(&argc, &argv);	/* troff font name */
25314983Sslatteng 		    break;
25414983Sslatteng 
25516096Sslatteng 	  case 'x': replacelist = operand(&argc, &argv);   /* replacements */
25614983Sslatteng 		    break;
25714983Sslatteng 
25816096Sslatteng 	  case 'y': synonymlist = operand(&argc, &argv);	/* synonyms */
25914983Sslatteng 		    break;
26014983Sslatteng 
26116096Sslatteng 	  case 'd': fontdir = operand(&argc, &argv);		/* directory */
26214680Sslatteng 		    break;
26314680Sslatteng 
26416096Sslatteng 	  case 'p': pointsize = atoi(operand(&argc, &argv));	/* point size */
26515280Sslatteng 		    if (pointsize < MINSIZE || pointsize > MAXSIZE)
26615280Sslatteng 			error("illegal point size: %d", pointsize);
26714680Sslatteng 		    break;
26814680Sslatteng 
26916096Sslatteng 	  case 'r': res = atoi(operand(&argc, &argv));	/* resolution */
27015280Sslatteng 		    if (res < MINRES || res > MAXRES)
27115280Sslatteng 			error("illegal resolution: %d", res);
272*26451Sslatteng 		    fixpix = (FIXIN * res);		/* pixels per fix */
27314680Sslatteng 		    break;
27414680Sslatteng 
27515280Sslatteng 	   default: error("bad option: %c", **argv);
27614680Sslatteng 	}
27714680Sslatteng     }
27814680Sslatteng 
27916096Sslatteng     if (replacelist != NULL) {
28016096Sslatteng 	ptr = replacelist;
28116096Sslatteng 	while (delimit = tostring(ptr, ',')) {		/* get s1 */
28216096Sslatteng 	    for (i = 0; i <= MAXLAST; i++)		/* search for match */
28316096Sslatteng 		if (strcmp (charmap[i], ptr) == 0)
28416096Sslatteng 		    break;
28516096Sslatteng 	    if (i > MAXLAST) error("-x option: no match");
28616096Sslatteng 	    charmap[i] = ptr = nextstring(ptr);		/* replace s1 */
28716096Sslatteng 	    delimit = tostring(ptr, ':');		/* with string s2 */
28816096Sslatteng 	    if (delimit) ptr = nextstring(ptr);
28916096Sslatteng 	}
29016096Sslatteng     }
29116096Sslatteng 
29216096Sslatteng     if (synonymlist != NULL) {
29316096Sslatteng 	ptr = synonymlist;
29416096Sslatteng 	while (delimit = tostring(ptr, ',')) {	/* get s1 */
29516096Sslatteng 	    synonyms[2 * numsyn] = ptr;		/* set on end of list */
29616096Sslatteng 	    ptr = nextstring(ptr);		/* get string s2 */
29716096Sslatteng 	    delimit = tostring(ptr, ':');
29816096Sslatteng 	    if (*ptr) {				/* if something there */
29916096Sslatteng 		synonyms[2 * numsyn++ + 1] = ptr;	/* add to list */
30016096Sslatteng 	    } else {				/* otherwise */
30116096Sslatteng 		for (i = 0; i < numsyn; i++) {		/* remove from list */
30216096Sslatteng 		    if (!strcmp(synonyms[2*i],synonyms[2*numsyn])) {
30316096Sslatteng 			numsyn--;
30416096Sslatteng 			for (j = i--; j < numsyn; j++) {
30516096Sslatteng 			    synonyms[2 * j] = synonyms[2 * (j+1)];
30616096Sslatteng 			    synonyms[2*j + 1] = synonyms[2*j + 3];
30716096Sslatteng 			}
30816096Sslatteng 		    }
30916096Sslatteng 		}
31016096Sslatteng 	    }
31116096Sslatteng 	    if (delimit) ptr = nextstring(ptr);
31216096Sslatteng 	    if (numsyn > SYNON) error("out of synonym space");
31316096Sslatteng 	}
31416096Sslatteng     }
31516096Sslatteng 
31616096Sslatteng     if (argc != 1)					/* open font file */
31716096Sslatteng 	error("An RST font filename must be the last option");
31815280Sslatteng     for (i = 0; FID == NULL && (psize = psizelist[i]) > 0; i++) {
31914680Sslatteng 	sprintf (IName, "%s/%s.r%d", fontdir, *argv, psize);
32015280Sslatteng 	FID = fopen (IName, "r");
32114680Sslatteng     }
32215280Sslatteng     if (FID == NULL)
32315280Sslatteng 	error("can't find %s", *argv);
32414680Sslatteng 
32515280Sslatteng     for (i = 0; i < FMARK; filemark[i++] = getc(FID));
32615280Sslatteng     if (strncmp(filemark, "Rast", 4))
32715280Sslatteng 	    error("bad File Mark in Font file.");
32814680Sslatteng 
32914680Sslatteng     p.p_size = rd2();
33014680Sslatteng     p.p_version = rd1();
33114680Sslatteng     if (p.p_version)
33215280Sslatteng 	error("wrong version of Font file.");
33314680Sslatteng     p.p_glyph = rd3();
33414680Sslatteng     p.p_first = rd2();
33514680Sslatteng     p.p_last = rd2();
33614983Sslatteng     if (p.p_last > MAXLAST) {
33714983Sslatteng 	fprintf(stderr, "truncating from %d to %d\n", p.p_last, MAXLAST);
33814983Sslatteng 	p.p_last = MAXLAST;
33914983Sslatteng     }
34014680Sslatteng     p.p_mag = rd4();
34114680Sslatteng     p.p_desiz = rd4();
34214680Sslatteng     p.p_linesp = rd4();
34314680Sslatteng     p.p_wordsp = rd4();
34414680Sslatteng     p.p_rot = rd2();
34514680Sslatteng     p.p_cadv = rd1();
34614680Sslatteng     p.p_ladv = rd1();
34714680Sslatteng     p.p_id = rd4();
34814680Sslatteng     p.p_res = rd2();
34914680Sslatteng     if (p.p_res != res)
35015280Sslatteng 	    error("wrong resolution in Font file.");
35114680Sslatteng 
35214680Sslatteng     i = p.p_glyph - 44;
35314680Sslatteng     idstrings = (unsigned char *) malloc (i);
35414680Sslatteng     endstring = idstrings + i;
35515280Sslatteng     while (i--) if (getc(FID) == EOF)
35615280Sslatteng 	    error("bad preamble in Font file.");
35714680Sslatteng 
35814680Sslatteng     for (i = p.p_first; i <= p.p_last; i++) {
35914680Sslatteng 	    g[i].g_height = rd2();
36014680Sslatteng 	    g[i].g_width = rd2();
36114680Sslatteng 	    g[i].g_up = rd2();
36214680Sslatteng 	    g[i].g_left = rd2();
36314680Sslatteng 	    g[i].g_pwidth = rd4();
36414680Sslatteng 	    g[i].g_bitp = rd3();
36514680Sslatteng     }
36614680Sslatteng 
36714680Sslatteng 
368*26451Sslatteng     if ((fixtowdth = fixpix * p.p_mag / 1000.0) == 0.0)
369*26451Sslatteng 	fixtowdth = fixpix;
37014680Sslatteng 
37114983Sslatteng     printf("# Font %s\n# size %.2f, ", IName, p.p_desiz * FIX);
37214680Sslatteng     printf("first %d, last %d, res %d, ", p.p_first, p.p_last, p.p_res);
373*26451Sslatteng     printf("mag %.2f\n", fixtowdth / fixpix);
37414680Sslatteng 
37514983Sslatteng     printf("name %s\n", fontname);
37614983Sslatteng     if (ligsf)
37714680Sslatteng 	printf ("ligatures ff fl fi ffl ffi 0\n");
37814983Sslatteng     if ((i = (pointsize * p.p_wordsp * fixtowdth) / psize) > 127) i = 127;
37914983Sslatteng     printf("spacewidth %d\n", i);
38014680Sslatteng     printf ("# char	width	u/d	octal\ncharset\n");
38114983Sslatteng 			/* the octal values for the following characters are */
38216096Sslatteng 			/* purposefully OUT of the range of characters (128) */
38315280Sslatteng     printf ("\\|	%4d	 0	0%o\n\\^	%4d	 0	0%o\n",
38416096Sslatteng 		(constant ? i : i/3), DIRSIZ, (constant ? 0 : i/6), DIRSIZ);
38514983Sslatteng 
38614680Sslatteng     for (j = p.p_first; j <= p.p_last; j++) {
38714680Sslatteng 	if (g[j].g_bitp != 0) {
38814680Sslatteng 	    if (g[j].g_up > maxup) maxup = g[j].g_up;
38914680Sslatteng 	    if ((i = g[j].g_height - (g[j].g_up + 1)) > maxdown) maxdown = i;
39014680Sslatteng 	}
39114680Sslatteng     }
39214680Sslatteng     if (maxdown == 0) maxdown = 1;
39314680Sslatteng 
39414680Sslatteng /*******************************************************************************
39514680Sslatteng 
39614680Sslatteng 	`type' is used to determine overhangs (up/down) from percentage of
39714680Sslatteng 	the maximum heights and dips.  Ascenders are higher than PCNTUP%
39814680Sslatteng 	of the highest, as descenders are more than PCNTDOWN%.
39914680Sslatteng 	widths [i = f(width)] are calculated from the definition point
40014680Sslatteng 	size (pointsize) and the one from this font (psize).
40114680Sslatteng 
40214680Sslatteng *******************************************************************************/
40314680Sslatteng 
40415280Sslatteng     for (j=0; j<DIRSIZ; j++) {
40514680Sslatteng 	if (g[j].g_bitp != 0) {
40614680Sslatteng 	    type = (int) (((g[j].g_up * 100) / maxup) > PCNTUP) * 2 | (int)
40714680Sslatteng 	    	((((g[j].g_height - (g[j].g_up+1)) * 100)/maxdown) > PCNTDOWN);
40814983Sslatteng 	    if (*(ptr = charmap[j])) {
40914983Sslatteng 		printf ("%s	%4d	 %d	0%o\n", ptr, (int) (pointsize
41014983Sslatteng 			* g[j].g_pwidth * fixtowdth / psize), type, j);
41114983Sslatteng 		for (i = 0; i < numsyn; i++)
41214983Sslatteng 		    if (strcmp (ptr, synonyms[2 * i]) == 0)
41314983Sslatteng 			printf ("%s	\"\n", synonyms[2 * i + 1]);
41414983Sslatteng 	    }
41514680Sslatteng 	}
41617909Sslatteng     } /* for j */
41717909Sslatteng     exit(0);
41814680Sslatteng }
41914680Sslatteng 
42014983Sslatteng 
42114983Sslatteng /*----------------------------------------------------------------------------*
42216096Sslatteng  | Routine:	char  * operand (& argc,  & argv)
42316096Sslatteng  |
42416096Sslatteng  | Results:	returns address of the operand given with a command-line
42516096Sslatteng  |		option.  It uses either "-Xoperand" or "-X operand", whichever
42616096Sslatteng  |		is present.  The program is terminated if no option is present.
42716096Sslatteng  |
42816096Sslatteng  | Side Efct:	argc and argv are updated as necessary.
42916096Sslatteng  *----------------------------------------------------------------------------*/
43016096Sslatteng 
operand(argcp,argvp)43116096Sslatteng char *operand(argcp, argvp)
43216096Sslatteng int * argcp;
43316096Sslatteng char ***argvp;
43416096Sslatteng {
43516096Sslatteng 	if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
43616096Sslatteng 	if ((--*argcp) <= 0)			/* no operand */
43716096Sslatteng 	    error("command-line option operand missing.");
43816096Sslatteng 	return(*(++(*argvp)));			/* operand operand */
43916096Sslatteng }
44016096Sslatteng 
44116096Sslatteng 
44216096Sslatteng /*----------------------------------------------------------------------------*
44314983Sslatteng  | Routine:	char  tostring (pointer, delimitter)
44414983Sslatteng  |
44514983Sslatteng  | Results:	checks string pointed to by pointer and turns it into a
44614983Sslatteng  |		string at 'delimitter' by replacing it with '\0'.  If the
44714983Sslatteng  |		end of the string is found first, '\0' is returned; otherwise
44814983Sslatteng  |		the delimitter found there is returned.
44914983Sslatteng  |
45014983Sslatteng  *----------------------------------------------------------------------------*/
45114983Sslatteng 
tostring(p,d)45214983Sslatteng char tostring(p, d)
45314983Sslatteng register char *p;
45414983Sslatteng register char d;
45514983Sslatteng {
45614983Sslatteng     while (*p && *p != d) p++;
45714983Sslatteng     d = *p;
45814983Sslatteng     *p = '\0';
45914983Sslatteng     return d;
46014983Sslatteng }
46114983Sslatteng 
46214983Sslatteng 
46314983Sslatteng /*----------------------------------------------------------------------------*
46414983Sslatteng  | Routine:	char  * nextstring (pointer)
46514983Sslatteng  |
46614983Sslatteng  | Results:	returns address of next string after one pointed to by
46714983Sslatteng  |		pointer.  The next string is after the '\0' byte.
46814983Sslatteng  |
46914983Sslatteng  *----------------------------------------------------------------------------*/
47014983Sslatteng 
nextstring(p)47114983Sslatteng char *nextstring(p)
47214983Sslatteng register char *p;
47314983Sslatteng {
47414983Sslatteng     while (*(p++));
47514983Sslatteng     return p;
47614983Sslatteng }
47714983Sslatteng 
47814983Sslatteng 
47915280Sslatteng /*VARARGS1*/
error(string,a1,a2,a3,a4)48015280Sslatteng error(string, a1, a2, a3, a4)
48114680Sslatteng char *string;
48214680Sslatteng {
48315280Sslatteng     fprintf(stderr, "makefont: ");
48415280Sslatteng     fprintf(stderr, string, a1, a2, a3, a4);
48515280Sslatteng     fprintf(stderr, "\n");
48614680Sslatteng     exit(8);
48714680Sslatteng }
48814680Sslatteng 
rd1()48914680Sslatteng rd1()
49014680Sslatteng {
49115280Sslatteng     int i;
49214680Sslatteng 
49315280Sslatteng     if((i = getc(FID)) == EOF) error("file read error");
49415280Sslatteng     return i;
49514680Sslatteng }
49614680Sslatteng 
rd2()49714680Sslatteng rd2()
49814680Sslatteng {
49914680Sslatteng     register int i = rd1() << 8;
50014680Sslatteng 
50114680Sslatteng     return i + rd1();
50214680Sslatteng }
50314680Sslatteng 
rd3()50414680Sslatteng rd3()
50514680Sslatteng {
50614680Sslatteng     register int i = rd2() << 8;
50714680Sslatteng 
50814680Sslatteng     return i + rd1();
50914680Sslatteng }
51014680Sslatteng 
rd4()51114680Sslatteng rd4()
51214680Sslatteng {
51314680Sslatteng     register int i = rd2() << 16;
51414680Sslatteng 
51514680Sslatteng     return i + rd2();
51614680Sslatteng }
517