1*5be69f91Sslatteng /*	makeifont.c	(Berkeley)	1.8	86/03/04
29e6f77caSslatteng  *
39e6f77caSslatteng  * Font description file producer for imagen fonts:  David Slattengren
459cd0d0fSslatteng  * Taken from vfontinfo by Andy Hertzfeld  4/79
559cd0d0fSslatteng  *
6acbb7b62Sslatteng  *  Use:  makeifont [ -nNAME ]  [ -i -s -a -o -l -c ]  [ "-xs1,s2[;s1,s2...]" ]
7c34ef83dSslatteng  *		[ "-ys1,s2[;s1,s2...]" ]  [ -p# ]  [ -r# ]  [ -ddir ]  font
859cd0d0fSslatteng  *
959cd0d0fSslatteng  *	Mkfnt takes the font named "font" and produces a ditroff description
10c34ef83dSslatteng  *	file from it.  The -n option takes the 1 or 2 letter troff name to put
11acbb7b62Sslatteng  *	the description (default = XX).  The -s, -o, -i, -a options select a
12c34ef83dSslatteng  *	different character mapping than for a "roman" font.  s = special;
13acbb7b62Sslatteng  *	o = math;  i = italics;  a = ascii.  The -l option tells if the font
14acbb7b62Sslatteng  *	has ligatures.  The -c option tells makeifont that the font is a
15acbb7b62Sslatteng  *	constant width one and sets parameters appropriately.
16c34ef83dSslatteng  *
17c34ef83dSslatteng  *	Both -x and -y options allow character name mapping.  A semi-colon
18c34ef83dSslatteng  *	separated list of comma-separated character-name pairs follows the
19c34ef83dSslatteng  *	x or y.  Notice that there are no spaces in the -x or -y command.  It
200c2c9c1bSslatteng  *	is also IMPORTANT to enclose these arguments in single quotes to stop
21c34ef83dSslatteng  *	the cshell from interpretting the contents.  A -x pair REPLACES the
22c34ef83dSslatteng  *	definition for s1 by s2.  A -y pair creates a synonym for s1 and calls
23c34ef83dSslatteng  *	it s2.  -x and -y MUST be sent after -s, -m, -i, or -a  if one of them
24c34ef83dSslatteng  *	is used.  Some synonyms are defaulted.  To remove a synonym or char-
25c34ef83dSslatteng  *	acter, leave out s2.
26c34ef83dSslatteng  *
27c34ef83dSslatteng  *	The -p# option tells what point size the DESC file has
280c2c9c1bSslatteng  *	as it's "unitwidth" argument (default: 40).  The -r# option is the
29c34ef83dSslatteng  *	resolution of the device (default: 240, in units/inch).  The -d option
30c34ef83dSslatteng  *	tells where to find fonts (default: /usr/src/local/imagen/fonts/raster).
3159cd0d0fSslatteng  */
3259cd0d0fSslatteng 
3359cd0d0fSslatteng /*
3459cd0d0fSslatteng  *  Here's an ascii character set, just in case you need it:
3559cd0d0fSslatteng 
3659cd0d0fSslatteng      | 00 nul| 01 soh| 02 stx| 03 etx| 04 eot| 05 enq| 06 ack| 07 bel|
3759cd0d0fSslatteng      | 08 bs | 09 ht | 0a nl | 0b vt | 0c np | 0d cr | 0e so | 0f si |
3859cd0d0fSslatteng      | 10 dle| 11 dc1| 12 dc2| 13 dc3| 14 dc4| 15 nak| 16 syn| 17 etb|
3959cd0d0fSslatteng      | 18 can| 19 em | 1a sub| 1b esc| 1c fs | 1d gs | 1e rs | 1f us |
4059cd0d0fSslatteng      | 20 sp | 21  ! | 22  " | 23  # | 24  $ | 25  % | 26  & | 27  ' |
4159cd0d0fSslatteng      | 28  ( | 29  ) | 2a  * | 2b  + | 2c  , | 2d  - | 2e  . | 2f  / |
4259cd0d0fSslatteng      | 30  0 | 31  1 | 32  2 | 33  3 | 34  4 | 35  5 | 36  6 | 37  7 |
4359cd0d0fSslatteng      | 38  8 | 39  9 | 3a  : | 3b  ; | 3c  < | 3d  = | 3e  > | 3f  ? |
4459cd0d0fSslatteng      | 40  @ | 41  A | 42  B | 43  C | 44  D | 45  E | 46  F | 47  G |
4559cd0d0fSslatteng      | 48  H | 49  I | 4a  J | 4b  K | 4c  L | 4d  M | 4e  N | 4f  O |
4659cd0d0fSslatteng      | 50  P | 51  Q | 52  R | 53  S | 54  T | 55  U | 56  V | 57  W |
4759cd0d0fSslatteng      | 58  X | 59  Y | 5a  Z | 5b  [ | 5c  \ | 5d  ] | 5e  ^ | 5f  _ |
4859cd0d0fSslatteng      | 60  ` | 61  a | 62  b | 63  c | 64  d | 65  e | 66  f | 67  g |
4959cd0d0fSslatteng      | 68  h | 69  i | 6a  j | 6b  k | 6c  l | 6d  m | 6e  n | 6f  o |
5059cd0d0fSslatteng      | 70  p | 71  q | 72  r | 73  s | 74  t | 75  u | 76  v | 77  w |
5159cd0d0fSslatteng      | 78  x | 79  y | 7a  z | 7b  { | 7c  | | 7d  } | 7e  ~ | 7f del|
5259cd0d0fSslatteng 
5359cd0d0fSslatteng  *
5459cd0d0fSslatteng  */
5559cd0d0fSslatteng 
5659cd0d0fSslatteng #include <stdio.h>
5759cd0d0fSslatteng #include <ctype.h>
5859cd0d0fSslatteng #include "rst.h"
5959cd0d0fSslatteng 
60*5be69f91Sslatteng char 	sccsid[] = "@(#)makeifont.c	1.8	(Berkeley)	03/04/86";
6159cd0d0fSslatteng 
6259cd0d0fSslatteng #define PCNTUP		62	/* percent of maximum height for an ascender */
6359cd0d0fSslatteng #define PCNTDOWN	73	/* percent of maximum droop for a descender */
64b655654cSslatteng #ifndef BITDIR
65acbb7b62Sslatteng #define BITDIR		"/usr/src/local/imagen/fonts/raster"
66b655654cSslatteng #endif
6759cd0d0fSslatteng #define POINTSIZE	40	/* this is the "unitwidth" point size */
6859cd0d0fSslatteng #define MINSIZE		6	/* the minimum and maximum point size values */
6959cd0d0fSslatteng #define MAXSIZE		36	/*    acceptible for use as "unitwidth"s */
7059cd0d0fSslatteng #define MINRES		10	/* check up on resolution input by setting */
7159cd0d0fSslatteng #define MAXRES		100000	/*    absurdly out-of-range limits on them */
72c34ef83dSslatteng #define MAXLAST		127	/* highest character code allowed */
73c34ef83dSslatteng #define SYNON		100	/* number of entries in a synonym table. */
74c34ef83dSslatteng 				/*    equals twice the number of pairs. */
7559cd0d0fSslatteng 
7659cd0d0fSslatteng 
7759cd0d0fSslatteng unsigned char *idstrings;	/* place for identifying strings */
7859cd0d0fSslatteng unsigned char *endstring;	/* points to end of id strings */
7959cd0d0fSslatteng double	fixtowdth;		/* "fix" and magnification conversion factor */
8059cd0d0fSslatteng glyph_dir g[DIRSIZ];		/* directory of glyph definitions */
8159cd0d0fSslatteng preamble p;			/* set of variables for preamble */
8259cd0d0fSslatteng 
8359cd0d0fSslatteng int	res = RES;		/* resolution of the device (units/inch) */
84*5be69f91Sslatteng double	fixpix = FIXPIX;	/* conversion factor "fix"es to pixels */
8559cd0d0fSslatteng int	pointsize = POINTSIZE;	/* point size being used for unitwidth */
8659cd0d0fSslatteng int	psize;			/* point size of font actually used */
8759cd0d0fSslatteng int	psizelist[] = { 40, 36, 28, 24, 22, 20, 18, 16,
8859cd0d0fSslatteng 			14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0 };
8959cd0d0fSslatteng 
90c34ef83dSslatteng char	*fontname = "XX";	/* troff name of font - set on command line */
91acbb7b62Sslatteng char	*fontdir = BITDIR;	/* place to look for fonts */
9259cd0d0fSslatteng char	IName[100];		/* input file name put here */
9359cd0d0fSslatteng char	*rdchar ();		/* function makes strings for ascii */
948fdbe243Sslatteng FILE *	FID = NULL;		/* input file number */
9559cd0d0fSslatteng 
9659cd0d0fSslatteng int	maxdown = 0;		/* size of the most "droopy" character */
9759cd0d0fSslatteng int	maxup = 0;		/* size of the tallest character */
9859cd0d0fSslatteng int	type;			/* 1, 2, or 3 for type of ascend/descending */
99c34ef83dSslatteng int	ligsf = 0;		/* flag "does this font have ligatures?" */
100acbb7b62Sslatteng int	constant = 0;		/* flag constant width font (spacewidth, etc.)*/
10159cd0d0fSslatteng 
10259cd0d0fSslatteng 				/* following are the character maps for */
10359cd0d0fSslatteng 				/* ascii code-conversion to printables... */
10459cd0d0fSslatteng char	**charmap;
105c34ef83dSslatteng char	**synonyms;
106c34ef83dSslatteng int	numsyn;
10759cd0d0fSslatteng 
108c34ef83dSslatteng char *iregular[] = {
10959cd0d0fSslatteng 	"*G", "*D", "*H", "*L", "*C", "*P", "*S", "*U", "*F", "*Q", "*W",
110c34ef83dSslatteng 	"id", "ij", "ga", "aa", "^", "d^", "hc", "rn", "..", "~", "ve",
111c34ef83dSslatteng 	"im", "de", "ce", "tl", "ar", "fb", "ae", "oe", "AE", "OE", "o/",
112c34ef83dSslatteng 	"!", "\"", "fm", "ft", "%", "&", "'", "(", ")", "*", "+", ",", "hy",
11359cd0d0fSslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
11459cd0d0fSslatteng 	"<", "=", ">", "?",
115c34ef83dSslatteng 	"es", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
11659cd0d0fSslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
117c34ef83dSslatteng 	"b\"", "]", "\\-", "em", "`", "a", "b", "c", "d", "e", "f", "g", "h",
11859cd0d0fSslatteng 	"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
119c34ef83dSslatteng 	"w", "x", "y", "z", "ff", "fi", "fl", "Fi", "Fl"
120c34ef83dSslatteng };
121c34ef83dSslatteng int	nregular = 14;
122c34ef83dSslatteng char *sregular[SYNON] = {
123c34ef83dSslatteng 	"A", "*A",	"B", "*B",	"E", "*E",	"H", "*Y",
124c34ef83dSslatteng 	"I", "*I",	"K", "*K",	"M", "*M",	"N", "*N",
125c34ef83dSslatteng 	"O", "*O",	"P", "*R",	"T", "*T",	"X", "*X",
126c34ef83dSslatteng 	"Z", "*Z",	"hy", "-"
127c34ef83dSslatteng };
128c34ef83dSslatteng 
129c34ef83dSslatteng char *iascii[] = {
130c34ef83dSslatteng 	"m.", "da", "*a", "*b", "an", "no", "mo", "*p", "*l", "*g", "*d",
131c34ef83dSslatteng 	"is", "+-", "O+", "if", "pd", "sb", "sp", "ca", "cu", "fa", "te",
132c34ef83dSslatteng 	"OX", "<>", "<-", "->", "ap", "!=", "<=", ">=", "==", "or", "",
133c34ef83dSslatteng 	"!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
134c34ef83dSslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
135c34ef83dSslatteng 	"<", "=", ">", "?",
136c34ef83dSslatteng 	"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
137c34ef83dSslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
1380c2c9c1bSslatteng 	"\\", "]", "^", "em", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
139c34ef83dSslatteng 	"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
140c34ef83dSslatteng 	"x", "y", "z", "{", "|", "}", "~", "dm"
141c34ef83dSslatteng };
142c34ef83dSslatteng int	nascii = 2;
143c34ef83dSslatteng char *sascii[SYNON] = {
144c34ef83dSslatteng 	"-", "hy",	"-", "\\-"
14559cd0d0fSslatteng };
14659cd0d0fSslatteng 
14759cd0d0fSslatteng char *ispecial[] = {
148c34ef83dSslatteng 	"mi", "m.", "mu", "**", "\\", "ci", "+-", "-+", "O+", "O-", "OX", "O/",
149c34ef83dSslatteng 	"O.", "di", "ht", "bu", "pe", "==", "ib", "ip", "<=", ">=", "(=", ")=",
150c34ef83dSslatteng 	"ap", "pt", "sb", "sp", "!=", ".=", "((", "))", "<-", "->", "ua", "da",
151c34ef83dSslatteng 	"<>", "<<", ">>", "~=", "lh", "rh", "Ua", "Da", "><", "uL", "uR", "lR",
152c34ef83dSslatteng 	"fm", "if", "mo", "!m", "0/", "ul", "al", ")(", "fa", "te", "no", "?0",
153c34ef83dSslatteng 	"?1", "?2", "cr", "", "/", "A", "B", "C", "D", "E", "F", "G", "H", "I",
15459cd0d0fSslatteng 	"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
15559cd0d0fSslatteng 	"X", "Y", "Z", "cu", "ca", "c+", "an", "or", "|-", "-|", "lf", "rf",
1568fdbe243Sslatteng 	"lc", "rc", "{", "}", "<", ">", "br", "||", "[[", "]]", "", "", "sr",
15759cd0d0fSslatteng 	"#", "gr", "is", "ux", "dx", "rx", "dm", "sc", "dg", "dd", "pp", "@",
158c34ef83dSslatteng 	"co", "", "$"
159c34ef83dSslatteng };
1608fdbe243Sslatteng int	nspecial = 2;
161c34ef83dSslatteng char *sspecial[SYNON] = {
1628fdbe243Sslatteng 	"lh", "La",	"rh", "Ra"
16359cd0d0fSslatteng };
16459cd0d0fSslatteng 
16559cd0d0fSslatteng char *imath[] = {
1668fdbe243Sslatteng 	"Bl", "Br", "LT", "RT", "LB", "RB", "rt", "rk", "rb", "lt", "lk", "lb",
167acbb7b62Sslatteng 	"rc", "lc", "rf", "lf", "bv", "ci", "^R", "^S", "^T", "^U", "^V", "^W",
168acbb7b62Sslatteng 	"^X", "^Y", "^Z", "^[", "^\\", "^]", "^^", "^_",
169acbb7b62Sslatteng 	" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
170acbb7b62Sslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
171acbb7b62Sslatteng 	"<", "=", ">", "?",
172acbb7b62Sslatteng 	"@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
173acbb7b62Sslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
174acbb7b62Sslatteng 	"\\", "]", "^", "em", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i",
175acbb7b62Sslatteng 	"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w",
176acbb7b62Sslatteng 	"x", "y", "z", "{", "|", "}", "~", "dm"
177c34ef83dSslatteng };
178c34ef83dSslatteng int	nmath = 0;
179c34ef83dSslatteng char *smath[SYNON] = {
180c34ef83dSslatteng 	"",""
181c34ef83dSslatteng };
18259cd0d0fSslatteng 
183c34ef83dSslatteng char *iitalics[] = {
184c34ef83dSslatteng 	"*G", "*D", "*H", "*L", "*C", "*P", "*S", "*U", "*F", "*Q", "*W",
185c34ef83dSslatteng 	"*a", "*b", "*g", "*d", "*e", "*z", "*y", "*h", "*i", "*k", "*l",
186c34ef83dSslatteng 	"*m", "*n", "*c", "*p", "*r", "*s", "*t", "*u", "*f", "*x", "id",
1878fdbe243Sslatteng 	"!", "\"", "el", "Fi", "pd", "&", "'", "(", ")", "*", "+", ",", "hy",
188c34ef83dSslatteng 	".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
189c34ef83dSslatteng 	"<", "=", ">", "?",
190c34ef83dSslatteng 	"id", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
191c34ef83dSslatteng 	"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[",
1928fdbe243Sslatteng 	"ff", "]", "fi", "fl", "`", "a", "b", "c", "d", "e", "f", "g", "h",
193c34ef83dSslatteng 	"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
1948fdbe243Sslatteng 	"w", "x", "y", "z", "*q", "*w", "?2", "?1", "Fl"
195c34ef83dSslatteng };
196c34ef83dSslatteng int	nitalics = 15;
197c34ef83dSslatteng char *sitalics[SYNON] = {
198c34ef83dSslatteng 	"A", "*A",	"B", "*B",	"E", "*E",	"H", "*Y",
199c34ef83dSslatteng 	"I", "*I",	"K", "*K",	"M", "*M",	"N", "*N",
200c34ef83dSslatteng 	"O", "*O",	"P", "*R",	"T", "*T",	"X", "*X",
201c34ef83dSslatteng 	"Z", "*Z",	"o", "*o",	"hy", "-"
20259cd0d0fSslatteng };
20359cd0d0fSslatteng 
20459cd0d0fSslatteng 
20559cd0d0fSslatteng 
main(argc,argv)20659cd0d0fSslatteng main (argc, argv)
20759cd0d0fSslatteng int argc;
20859cd0d0fSslatteng char **argv;
20959cd0d0fSslatteng {
210c34ef83dSslatteng     register int i;		/* two indexes */
211c34ef83dSslatteng     register int j;
212c34ef83dSslatteng     register char *ptr;		/* string traveller */
213c34ef83dSslatteng     register char delimit;	/* place for delemiters on command-line */
214acbb7b62Sslatteng     char *replacelist = NULL;	/* list of character-name replacements */
215acbb7b62Sslatteng     char *synonymlist = NULL;	/* list of synonym entries */
216c34ef83dSslatteng     char tostring();		/* function makes string */
217c34ef83dSslatteng     char *nextstring();		/* moves to next string on list */
218acbb7b62Sslatteng     char *operand();		/* reads operands from commandline */
21959cd0d0fSslatteng 
220c34ef83dSslatteng     charmap = iregular;			/* default character map */
221c34ef83dSslatteng     synonyms = sregular;
222c34ef83dSslatteng     numsyn = nregular;
223acbb7b62Sslatteng     while (--argc > 0 && *(*(++argv)) == '-') {	/* do options... */
224acbb7b62Sslatteng 	switch ((*argv)[1]) {
22559cd0d0fSslatteng 
226c34ef83dSslatteng 	  case 's': charmap = ispecial;		/* special font */
227c34ef83dSslatteng 		    synonyms = sspecial;
228c34ef83dSslatteng 		    numsyn = nspecial;
22959cd0d0fSslatteng 		    break;
23059cd0d0fSslatteng 
231acbb7b62Sslatteng 	  case 'o': charmap = imath;		/* math font */
232c34ef83dSslatteng 		    synonyms = smath;
233c34ef83dSslatteng 		    numsyn = nmath;
234c34ef83dSslatteng 		    break;
235c34ef83dSslatteng 
236c34ef83dSslatteng 	  case 'i': charmap = iitalics;		/* italics font */
237c34ef83dSslatteng 		    synonyms = sitalics;
238c34ef83dSslatteng 		    numsyn = nitalics;
239c34ef83dSslatteng 		    break;
240c34ef83dSslatteng 
241c34ef83dSslatteng 	  case 'a': charmap = iascii;		/* ascii font */
242c34ef83dSslatteng 		    synonyms = sascii;
243c34ef83dSslatteng 		    numsyn = nascii;
244c34ef83dSslatteng 		    break;
245c34ef83dSslatteng 
246acbb7b62Sslatteng 	  case 'c': constant = 1;		/* constant width font */
247acbb7b62Sslatteng 		    break;
248acbb7b62Sslatteng 
249c34ef83dSslatteng 	  case 'l': ligsf = 1;			/* ascii font */
250c34ef83dSslatteng 		    break;
251c34ef83dSslatteng 
252acbb7b62Sslatteng 	  case 'n': fontname = operand(&argc, &argv);	/* troff font name */
253c34ef83dSslatteng 		    break;
254c34ef83dSslatteng 
255acbb7b62Sslatteng 	  case 'x': replacelist = operand(&argc, &argv);   /* replacements */
256c34ef83dSslatteng 		    break;
257c34ef83dSslatteng 
258acbb7b62Sslatteng 	  case 'y': synonymlist = operand(&argc, &argv);	/* synonyms */
25959cd0d0fSslatteng 		    break;
26059cd0d0fSslatteng 
261acbb7b62Sslatteng 	  case 'd': fontdir = operand(&argc, &argv);		/* directory */
26259cd0d0fSslatteng 		    break;
26359cd0d0fSslatteng 
264acbb7b62Sslatteng 	  case 'p': pointsize = atoi(operand(&argc, &argv));	/* point size */
2658fdbe243Sslatteng 		    if (pointsize < MINSIZE || pointsize > MAXSIZE)
2668fdbe243Sslatteng 			error("illegal point size: %d", pointsize);
26759cd0d0fSslatteng 		    break;
26859cd0d0fSslatteng 
269acbb7b62Sslatteng 	  case 'r': res = atoi(operand(&argc, &argv));	/* resolution */
2708fdbe243Sslatteng 		    if (res < MINRES || res > MAXRES)
2718fdbe243Sslatteng 			error("illegal resolution: %d", res);
272*5be69f91Sslatteng 		    fixpix = (FIXIN * res);		/* pixels per fix */
27359cd0d0fSslatteng 		    break;
27459cd0d0fSslatteng 
2758fdbe243Sslatteng 	   default: error("bad option: %c", **argv);
27659cd0d0fSslatteng 	}
27759cd0d0fSslatteng     }
27859cd0d0fSslatteng 
279acbb7b62Sslatteng     if (replacelist != NULL) {
280acbb7b62Sslatteng 	ptr = replacelist;
281acbb7b62Sslatteng 	while (delimit = tostring(ptr, ',')) {		/* get s1 */
282acbb7b62Sslatteng 	    for (i = 0; i <= MAXLAST; i++)		/* search for match */
283acbb7b62Sslatteng 		if (strcmp (charmap[i], ptr) == 0)
284acbb7b62Sslatteng 		    break;
285acbb7b62Sslatteng 	    if (i > MAXLAST) error("-x option: no match");
286acbb7b62Sslatteng 	    charmap[i] = ptr = nextstring(ptr);		/* replace s1 */
287acbb7b62Sslatteng 	    delimit = tostring(ptr, ':');		/* with string s2 */
288acbb7b62Sslatteng 	    if (delimit) ptr = nextstring(ptr);
289acbb7b62Sslatteng 	}
290acbb7b62Sslatteng     }
291acbb7b62Sslatteng 
292acbb7b62Sslatteng     if (synonymlist != NULL) {
293acbb7b62Sslatteng 	ptr = synonymlist;
294acbb7b62Sslatteng 	while (delimit = tostring(ptr, ',')) {	/* get s1 */
295acbb7b62Sslatteng 	    synonyms[2 * numsyn] = ptr;		/* set on end of list */
296acbb7b62Sslatteng 	    ptr = nextstring(ptr);		/* get string s2 */
297acbb7b62Sslatteng 	    delimit = tostring(ptr, ':');
298acbb7b62Sslatteng 	    if (*ptr) {				/* if something there */
299acbb7b62Sslatteng 		synonyms[2 * numsyn++ + 1] = ptr;	/* add to list */
300acbb7b62Sslatteng 	    } else {				/* otherwise */
301acbb7b62Sslatteng 		for (i = 0; i < numsyn; i++) {		/* remove from list */
302acbb7b62Sslatteng 		    if (!strcmp(synonyms[2*i],synonyms[2*numsyn])) {
303acbb7b62Sslatteng 			numsyn--;
304acbb7b62Sslatteng 			for (j = i--; j < numsyn; j++) {
305acbb7b62Sslatteng 			    synonyms[2 * j] = synonyms[2 * (j+1)];
306acbb7b62Sslatteng 			    synonyms[2*j + 1] = synonyms[2*j + 3];
307acbb7b62Sslatteng 			}
308acbb7b62Sslatteng 		    }
309acbb7b62Sslatteng 		}
310acbb7b62Sslatteng 	    }
311acbb7b62Sslatteng 	    if (delimit) ptr = nextstring(ptr);
312acbb7b62Sslatteng 	    if (numsyn > SYNON) error("out of synonym space");
313acbb7b62Sslatteng 	}
314acbb7b62Sslatteng     }
315acbb7b62Sslatteng 
316acbb7b62Sslatteng     if (argc != 1)					/* open font file */
317acbb7b62Sslatteng 	error("An RST font filename must be the last option");
3188fdbe243Sslatteng     for (i = 0; FID == NULL && (psize = psizelist[i]) > 0; i++) {
31959cd0d0fSslatteng 	sprintf (IName, "%s/%s.r%d", fontdir, *argv, psize);
3208fdbe243Sslatteng 	FID = fopen (IName, "r");
32159cd0d0fSslatteng     }
3228fdbe243Sslatteng     if (FID == NULL)
3238fdbe243Sslatteng 	error("can't find %s", *argv);
32459cd0d0fSslatteng 
3258fdbe243Sslatteng     for (i = 0; i < FMARK; filemark[i++] = getc(FID));
3268fdbe243Sslatteng     if (strncmp(filemark, "Rast", 4))
3278fdbe243Sslatteng 	    error("bad File Mark in Font file.");
32859cd0d0fSslatteng 
32959cd0d0fSslatteng     p.p_size = rd2();
33059cd0d0fSslatteng     p.p_version = rd1();
33159cd0d0fSslatteng     if (p.p_version)
3328fdbe243Sslatteng 	error("wrong version of Font file.");
33359cd0d0fSslatteng     p.p_glyph = rd3();
33459cd0d0fSslatteng     p.p_first = rd2();
33559cd0d0fSslatteng     p.p_last = rd2();
336c34ef83dSslatteng     if (p.p_last > MAXLAST) {
337c34ef83dSslatteng 	fprintf(stderr, "truncating from %d to %d\n", p.p_last, MAXLAST);
338c34ef83dSslatteng 	p.p_last = MAXLAST;
339c34ef83dSslatteng     }
34059cd0d0fSslatteng     p.p_mag = rd4();
34159cd0d0fSslatteng     p.p_desiz = rd4();
34259cd0d0fSslatteng     p.p_linesp = rd4();
34359cd0d0fSslatteng     p.p_wordsp = rd4();
34459cd0d0fSslatteng     p.p_rot = rd2();
34559cd0d0fSslatteng     p.p_cadv = rd1();
34659cd0d0fSslatteng     p.p_ladv = rd1();
34759cd0d0fSslatteng     p.p_id = rd4();
34859cd0d0fSslatteng     p.p_res = rd2();
34959cd0d0fSslatteng     if (p.p_res != res)
3508fdbe243Sslatteng 	    error("wrong resolution in Font file.");
35159cd0d0fSslatteng 
35259cd0d0fSslatteng     i = p.p_glyph - 44;
35359cd0d0fSslatteng     idstrings = (unsigned char *) malloc (i);
35459cd0d0fSslatteng     endstring = idstrings + i;
3558fdbe243Sslatteng     while (i--) if (getc(FID) == EOF)
3568fdbe243Sslatteng 	    error("bad preamble in Font file.");
35759cd0d0fSslatteng 
35859cd0d0fSslatteng     for (i = p.p_first; i <= p.p_last; i++) {
35959cd0d0fSslatteng 	    g[i].g_height = rd2();
36059cd0d0fSslatteng 	    g[i].g_width = rd2();
36159cd0d0fSslatteng 	    g[i].g_up = rd2();
36259cd0d0fSslatteng 	    g[i].g_left = rd2();
36359cd0d0fSslatteng 	    g[i].g_pwidth = rd4();
36459cd0d0fSslatteng 	    g[i].g_bitp = rd3();
36559cd0d0fSslatteng     }
36659cd0d0fSslatteng 
36759cd0d0fSslatteng 
368*5be69f91Sslatteng     if ((fixtowdth = fixpix * p.p_mag / 1000.0) == 0.0)
369*5be69f91Sslatteng 	fixtowdth = fixpix;
37059cd0d0fSslatteng 
371c34ef83dSslatteng     printf("# Font %s\n# size %.2f, ", IName, p.p_desiz * FIX);
37259cd0d0fSslatteng     printf("first %d, last %d, res %d, ", p.p_first, p.p_last, p.p_res);
373*5be69f91Sslatteng     printf("mag %.2f\n", fixtowdth / fixpix);
37459cd0d0fSslatteng 
375c34ef83dSslatteng     printf("name %s\n", fontname);
376c34ef83dSslatteng     if (ligsf)
37759cd0d0fSslatteng 	printf ("ligatures ff fl fi ffl ffi 0\n");
378c34ef83dSslatteng     if ((i = (pointsize * p.p_wordsp * fixtowdth) / psize) > 127) i = 127;
379c34ef83dSslatteng     printf("spacewidth %d\n", i);
38059cd0d0fSslatteng     printf ("# char	width	u/d	octal\ncharset\n");
381c34ef83dSslatteng 			/* the octal values for the following characters are */
382acbb7b62Sslatteng 			/* purposefully OUT of the range of characters (128) */
3838fdbe243Sslatteng     printf ("\\|	%4d	 0	0%o\n\\^	%4d	 0	0%o\n",
384acbb7b62Sslatteng 		(constant ? i : i/3), DIRSIZ, (constant ? 0 : i/6), DIRSIZ);
385c34ef83dSslatteng 
38659cd0d0fSslatteng     for (j = p.p_first; j <= p.p_last; j++) {
38759cd0d0fSslatteng 	if (g[j].g_bitp != 0) {
38859cd0d0fSslatteng 	    if (g[j].g_up > maxup) maxup = g[j].g_up;
38959cd0d0fSslatteng 	    if ((i = g[j].g_height - (g[j].g_up + 1)) > maxdown) maxdown = i;
39059cd0d0fSslatteng 	}
39159cd0d0fSslatteng     }
39259cd0d0fSslatteng     if (maxdown == 0) maxdown = 1;
39359cd0d0fSslatteng 
39459cd0d0fSslatteng /*******************************************************************************
39559cd0d0fSslatteng 
39659cd0d0fSslatteng 	`type' is used to determine overhangs (up/down) from percentage of
39759cd0d0fSslatteng 	the maximum heights and dips.  Ascenders are higher than PCNTUP%
39859cd0d0fSslatteng 	of the highest, as descenders are more than PCNTDOWN%.
39959cd0d0fSslatteng 	widths [i = f(width)] are calculated from the definition point
40059cd0d0fSslatteng 	size (pointsize) and the one from this font (psize).
40159cd0d0fSslatteng 
40259cd0d0fSslatteng *******************************************************************************/
40359cd0d0fSslatteng 
4048fdbe243Sslatteng     for (j=0; j<DIRSIZ; j++) {
40559cd0d0fSslatteng 	if (g[j].g_bitp != 0) {
40659cd0d0fSslatteng 	    type = (int) (((g[j].g_up * 100) / maxup) > PCNTUP) * 2 | (int)
40759cd0d0fSslatteng 	    	((((g[j].g_height - (g[j].g_up+1)) * 100)/maxdown) > PCNTDOWN);
408c34ef83dSslatteng 	    if (*(ptr = charmap[j])) {
409c34ef83dSslatteng 		printf ("%s	%4d	 %d	0%o\n", ptr, (int) (pointsize
410c34ef83dSslatteng 			* g[j].g_pwidth * fixtowdth / psize), type, j);
411c34ef83dSslatteng 		for (i = 0; i < numsyn; i++)
412c34ef83dSslatteng 		    if (strcmp (ptr, synonyms[2 * i]) == 0)
413c34ef83dSslatteng 			printf ("%s	\"\n", synonyms[2 * i + 1]);
41459cd0d0fSslatteng 	    }
41559cd0d0fSslatteng 	}
4169e6f77caSslatteng     } /* for j */
4179e6f77caSslatteng     exit(0);
418c34ef83dSslatteng }
419c34ef83dSslatteng 
420c34ef83dSslatteng 
421c34ef83dSslatteng /*----------------------------------------------------------------------------*
422acbb7b62Sslatteng  | Routine:	char  * operand (& argc,  & argv)
423acbb7b62Sslatteng  |
424acbb7b62Sslatteng  | Results:	returns address of the operand given with a command-line
425acbb7b62Sslatteng  |		option.  It uses either "-Xoperand" or "-X operand", whichever
426acbb7b62Sslatteng  |		is present.  The program is terminated if no option is present.
427acbb7b62Sslatteng  |
428acbb7b62Sslatteng  | Side Efct:	argc and argv are updated as necessary.
429acbb7b62Sslatteng  *----------------------------------------------------------------------------*/
430acbb7b62Sslatteng 
operand(argcp,argvp)431acbb7b62Sslatteng char *operand(argcp, argvp)
432acbb7b62Sslatteng int * argcp;
433acbb7b62Sslatteng char ***argvp;
434acbb7b62Sslatteng {
435acbb7b62Sslatteng 	if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
436acbb7b62Sslatteng 	if ((--*argcp) <= 0)			/* no operand */
437acbb7b62Sslatteng 	    error("command-line option operand missing.");
438acbb7b62Sslatteng 	return(*(++(*argvp)));			/* operand operand */
439acbb7b62Sslatteng }
440acbb7b62Sslatteng 
441acbb7b62Sslatteng 
442acbb7b62Sslatteng /*----------------------------------------------------------------------------*
443c34ef83dSslatteng  | Routine:	char  tostring (pointer, delimitter)
444c34ef83dSslatteng  |
445c34ef83dSslatteng  | Results:	checks string pointed to by pointer and turns it into a
446c34ef83dSslatteng  |		string at 'delimitter' by replacing it with '\0'.  If the
447c34ef83dSslatteng  |		end of the string is found first, '\0' is returned; otherwise
448c34ef83dSslatteng  |		the delimitter found there is returned.
449c34ef83dSslatteng  |
450c34ef83dSslatteng  *----------------------------------------------------------------------------*/
451c34ef83dSslatteng 
tostring(p,d)452c34ef83dSslatteng char tostring(p, d)
453c34ef83dSslatteng register char *p;
454c34ef83dSslatteng register char d;
455c34ef83dSslatteng {
456c34ef83dSslatteng     while (*p && *p != d) p++;
457c34ef83dSslatteng     d = *p;
458c34ef83dSslatteng     *p = '\0';
459c34ef83dSslatteng     return d;
460c34ef83dSslatteng }
461c34ef83dSslatteng 
462c34ef83dSslatteng 
463c34ef83dSslatteng /*----------------------------------------------------------------------------*
464c34ef83dSslatteng  | Routine:	char  * nextstring (pointer)
465c34ef83dSslatteng  |
466c34ef83dSslatteng  | Results:	returns address of next string after one pointed to by
467c34ef83dSslatteng  |		pointer.  The next string is after the '\0' byte.
468c34ef83dSslatteng  |
469c34ef83dSslatteng  *----------------------------------------------------------------------------*/
470c34ef83dSslatteng 
nextstring(p)471c34ef83dSslatteng char *nextstring(p)
472c34ef83dSslatteng register char *p;
473c34ef83dSslatteng {
474c34ef83dSslatteng     while (*(p++));
475c34ef83dSslatteng     return p;
476c34ef83dSslatteng }
477c34ef83dSslatteng 
47859cd0d0fSslatteng 
4798fdbe243Sslatteng /*VARARGS1*/
error(string,a1,a2,a3,a4)4808fdbe243Sslatteng error(string, a1, a2, a3, a4)
48159cd0d0fSslatteng char *string;
48259cd0d0fSslatteng {
4838fdbe243Sslatteng     fprintf(stderr, "makefont: ");
4848fdbe243Sslatteng     fprintf(stderr, string, a1, a2, a3, a4);
4858fdbe243Sslatteng     fprintf(stderr, "\n");
48659cd0d0fSslatteng     exit(8);
48759cd0d0fSslatteng }
48859cd0d0fSslatteng 
rd1()48959cd0d0fSslatteng rd1()
49059cd0d0fSslatteng {
4918fdbe243Sslatteng     int i;
49259cd0d0fSslatteng 
4938fdbe243Sslatteng     if((i = getc(FID)) == EOF) error("file read error");
4948fdbe243Sslatteng     return i;
49559cd0d0fSslatteng }
49659cd0d0fSslatteng 
rd2()49759cd0d0fSslatteng rd2()
49859cd0d0fSslatteng {
49959cd0d0fSslatteng     register int i = rd1() << 8;
50059cd0d0fSslatteng 
50159cd0d0fSslatteng     return i + rd1();
50259cd0d0fSslatteng }
50359cd0d0fSslatteng 
rd3()50459cd0d0fSslatteng rd3()
50559cd0d0fSslatteng {
50659cd0d0fSslatteng     register int i = rd2() << 8;
50759cd0d0fSslatteng 
50859cd0d0fSslatteng     return i + rd1();
50959cd0d0fSslatteng }
51059cd0d0fSslatteng 
rd4()51159cd0d0fSslatteng rd4()
51259cd0d0fSslatteng {
51359cd0d0fSslatteng     register int i = rd2() << 16;
51459cd0d0fSslatteng 
51559cd0d0fSslatteng     return i + rd2();
51659cd0d0fSslatteng }
517