xref: /titanic_50/usr/src/cmd/troff/troff.d/makedev.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	  All Rights Reserved  	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
32 
33 /*
34  * University Copyright- Copyright (c) 1982, 1986, 1988
35  * The Regents of the University of California
36  * All Rights Reserved
37  *
38  * University Acknowledgment- Portions of this document are derived from
39  * software developed by the University of California, Berkeley, and its
40  * contributors.
41  */
42 
43 /* Note added 9/25/83
44 	Setting the parameter biggestfont in the DESC file
45 	to be at least as big as the number of characters
46 	in the largest font for a particular device
47 	eliminates the "font X too big for position Y"
48 	message from troff.
49 	Thanks to Dave Stephens, WECo.
50 */
51 /*
52   makedev:
53 	read text info about a particular device
54 	(e.g., cat, 202, aps5) from file, convert
55 	it into internal (binary) form suitable for
56 	fast reading by troff initialization (ptinit()).
57 
58 	Usage:
59 
60 	makedev DESC [ F ... ]
61 		uses DESC to create a description file
62 		using the information therein.
63 		It creates the file DESC.out.
64 
65 	makedev F ...
66 		makes the font tables for fonts F only,
67 		creates files F.out.
68 
69 	DESC.out contains:
70 	dev structure with fundamental sizes
71 	list of sizes (nsizes+1) terminated by 0, as short's
72 	indices of char names (nchtab * sizeof(short))
73 	char names as hy\0em\0... (lchname)
74 	nfonts occurrences of
75 		widths (nwidth)
76 		kerning (nwidth) [ascender+descender only so far]
77 		codes (nwidth) to drive actual typesetter
78 		fitab (nchtab+128-32)
79 	each of these is an array of char.
80 
81 	dev.filesize contains the number of bytes
82 	in the file, excluding the dev part itself.
83 
84 	F.out contains the font header, width, kern, codes, and fitab.
85 	Width, kern and codes are parallel arrays.
86 	(Which suggests that they ought to be together?)
87 	Later, we might allow for codes which are actually
88 	sequences of formatting info so characters can be drawn.
89 */
90 
91 #include	"stdio.h"
92 #include	"dev.h"
93 
94 #define	BYTEMASK	0377
95 #define	skipline(f)	while(getc(f) != '\n')
96 
97 struct	dev	dev;
98 struct	Font	font;
99 
100 #define	NSIZE	100	/* maximum number of sizes */
101 short	size[NSIZE];
102 #define	NCH	256	/* max number of characters with funny names */
103 char	chname[5*NCH];	/* character names, including \0 for each */
104 short	chtab[NCH];	/* index of character in chname */
105 
106 #define	NFITAB	(NCH + 128-32)	/* includes ascii chars, but not non-graphics */
107 char	fitab[NFITAB];	/* font index table: position of char i on this font. */
108 			/* zero if not there */
109 
110 #define	FSIZE	256	/* size of a physical font (e.g., 102 for cat) */
111 char	width[FSIZE];	/* width table for a physical font */
112 char	kern[FSIZE];	/* ascender+descender info */
113 char	code[FSIZE];	/* actual device codes for a physical font */
114 
115 #define	NFONT	60	/* max number of default fonts */
116 char	fname[NFONT][10];	/* temp space to hold default font names */
117 
118 int	fflag	= 0;	/* on if font table to be written */
119 int	fdout;	/* output file descriptor */
120 char	*fout	= "DESC.out";
121 
122 int main(int argc, char *argv[])
123 {
124 	FILE *fin;
125 	char cmd[100], *p;
126 	int i, totfont, v;
127 
128     if (argc < 2) {
129         fprintf(stderr, "Usage:  makedev [DESC] [fonts]\n");
130         exit(1);
131     }
132 
133 	if ((fin = fopen("DESC", "r")) == NULL) {
134 		fprintf(stderr, "makedev: can't open %s\n", argv[1]);
135 		exit(1);
136 	}
137 	while (fscanf(fin, "%s", cmd) != EOF) {
138 		if (cmd[0] == '#')	/* comment */
139 			skipline(fin);
140 		else if (strcmp(cmd, "res") == 0) {
141 			fscanf(fin, "%hd", &dev.res);
142 		} else if (strcmp(cmd, "hor") == 0) {
143 			fscanf(fin, "%hd", &dev.hor);
144 		} else if (strcmp(cmd, "vert") == 0) {
145 			fscanf(fin, "%hd", &dev.vert);
146 		} else if (strcmp(cmd, "unitwidth") == 0) {
147 			fscanf(fin, "%hd", &dev.unitwidth);
148 		} else if (strcmp(cmd, "sizescale") == 0) {
149 			fscanf(fin, "%hd", &dev.sizescale);
150 		} else if (strcmp(cmd, "paperwidth") == 0) {
151 			fscanf(fin, "%hd", &dev.paperwidth);
152 		} else if (strcmp(cmd, "paperlength") == 0) {
153 			fscanf(fin, "%hd", &dev.paperlength);
154 		} else if (strcmp(cmd, "biggestfont") == 0) {
155 			fscanf(fin, "%hd", &dev.biggestfont);
156 		} else if (strcmp(cmd, "spare2") == 0) {
157 			fscanf(fin, "%hd", &dev.spare2);
158 		} else if (strcmp(cmd, "sizes") == 0) {
159 			dev.nsizes = 0;
160 			while (fscanf(fin, "%d", &v) != EOF && v != 0)
161 				size[dev.nsizes++] = v;
162 			size[dev.nsizes] = 0;	/* need an extra 0 at the end */
163 		} else if (strcmp(cmd, "fonts") == 0) {
164 			fscanf(fin, "%hd", &dev.nfonts);
165 			for (i = 0; i < dev.nfonts; i++)
166 				fscanf(fin, "%s", fname[i]);
167 		} else if (strcmp(cmd, "charset") == 0) {
168 			p = chname;
169 			dev.nchtab = 0;
170 			while (fscanf(fin, "%s", p) != EOF) {
171 				chtab[dev.nchtab++] = p - chname;
172 				while (*p++)	/* skip to end of name */
173 					;
174 			}
175 			dev.lchname = p - chname;
176 			chtab[dev.nchtab++] = 0;	/* terminate properly */
177 		} else
178 			fprintf(stderr, "makedev: unknown command %s\n", cmd);
179 	}
180 	if (argc > 0 && strcmp(argv[1], "DESC") == 0) {
181 		fdout = creat(fout, 0666);
182 		if (fdout < 0) {
183 			fprintf(stderr, "makedev: can't open %s\n", fout);
184 			exit(1);
185 		}
186 		write(fdout, &dev, sizeof(struct dev));
187 		write(fdout, size, (dev.nsizes+1) * sizeof(size[0]));	/* we need a 0 on the end */
188 		write(fdout, chtab, dev.nchtab * sizeof(chtab[0]));
189 		write(fdout, chname, dev.lchname);
190 		totfont = 0;
191 		for (i = 0; i < dev.nfonts; i++) {
192 			totfont += dofont(fname[i]);
193 			write(fdout, &font, sizeof(struct Font));
194 			write(fdout, width, font.nwfont & BYTEMASK);
195 			write(fdout, kern, font.nwfont & BYTEMASK);
196 			write(fdout, code, font.nwfont & BYTEMASK);
197 			write(fdout, fitab, dev.nchtab+128-32);
198 		}
199 		lseek(fdout, 0L, 0);	/* back to beginning to install proper size */
200 		dev.filesize =		/* excluding dev struct itself */
201 			(dev.nsizes+1) * sizeof(size[0])
202 			+ dev.nchtab * sizeof(chtab[0])
203 			+ dev.lchname * sizeof(char)
204 			+ totfont * sizeof(char);
205 		write(fdout, &dev, sizeof(struct dev));
206 		close(fdout);
207 		argc--;
208 		argv++;
209 	}
210 	for (i = 1; i < argc; i++)
211 		dofont(argv[i]);
212 	exit(0);
213 }
214 
215 dofont(name)	/* create fitab and width tab for font */
216 char *name;
217 {
218 	FILE *fin;
219 	int fdout;
220 	int i, nw, spacewidth, n, v;
221 	char buf[100], ch[10], s1[10], s2[10], s3[10], cmd[30];
222 
223 	if ((fin = fopen(name, "r")) == NULL) {
224 		fprintf(stderr, "makedev: can't open font %s\n", name);
225 		exit(2);
226 	}
227 	sprintf(cmd, "%s.out", name);
228 	fdout = creat(cmd, 0666);
229 	for (i = 0; i < NFITAB; i++)
230 		fitab[i] = 0;
231 	for (i = 0; i < FSIZE; i++)
232 		width[i] = kern[i] = code[i] = 0;
233 	font.specfont = font.ligfont = spacewidth = 0;
234 	while (fscanf(fin, "%s", cmd) != EOF) {
235 		if (cmd[0] == '#')
236 			skipline(fin);
237 		else if (strcmp(cmd, "name") == 0)
238 			fscanf(fin, "%s", font.namefont);
239 		else if (strcmp(cmd, "internalname") == 0)
240 			fscanf(fin, "%s", font.intname);
241 		else if (strcmp(cmd, "special") == 0)
242 			font.specfont = 1;
243 		else if (strcmp(cmd, "spare1") == 0)
244 			fscanf(fin, "%1s", &font.spare1);
245 		else if (strcmp(cmd, "ligatures") == 0) {
246 			font.ligfont = getlig(fin);
247 		} else if (strcmp(cmd, "spacewidth") == 0) {
248 			fscanf(fin, "%d", &spacewidth);
249 			width[0] = spacewidth;	/* width of space on this font */
250 		} else if (strcmp(cmd, "charset") == 0) {
251 			skipline(fin);
252 			nw = 0;
253 			/* widths are origin 1 so fitab==0 can mean "not there" */
254 			while (fgets(buf, 100, fin) != NULL) {
255 				sscanf(buf, "%s %s %s %s", ch, s1, s2, s3);
256 				if (s1[0] != '"') {	/* it's a genuine new character */
257 					nw++;
258 					width[nw] = atoi(s1);
259 					kern[nw] = atoi(s2);
260 					/* temporarily, pick up one byte as code */
261 					if (s3[0] == '0')
262 						sscanf(s3, "%o", &i);
263 					else
264 						sscanf(s3, "%d", &i);
265 					code[nw] = i;
266 				}
267 				/* otherwise it's a synonym for previous character,
268 				/* so leave previous values intact
269 				*/
270 				if (strlen(ch) == 1)	/* it's ascii */
271 					fitab[ch[0] - 32] = nw;	/* fitab origin omits non-graphics */
272 				else {		/* it has a funny name */
273 					for (i = 0; i < dev.nchtab; i++)
274 						if (strcmp(&chname[chtab[i]], ch) == 0) {
275 							fitab[i + 128-32] = nw;	/* starts after the ascii */
276 							break;
277 						}
278 					if (i >= dev.nchtab)
279 						fprintf(stderr, "makedev: font %s: %s not in charset\n", name, ch);
280 				}
281 			}
282 			nw++;
283 			if (dev.biggestfont >= nw)
284 				n = dev.biggestfont;
285 			else {
286 				if (dev.biggestfont > 0)
287 					fprintf(stderr, "font %s too big\n", name);
288 				n = nw;
289 			}
290 			font.nwfont = n;
291 		}
292 	}
293 	if (spacewidth == 0)
294 		width[0] = dev.res * dev.unitwidth / 72 / 3;
295 	fclose(fin);
296 
297 	write(fdout, &font, sizeof(struct Font));
298 	write(fdout, width, font.nwfont & BYTEMASK);
299 	write(fdout, kern, font.nwfont & BYTEMASK);
300 	write(fdout, code, font.nwfont & BYTEMASK);
301 	write(fdout, fitab, dev.nchtab+128-32);
302 	close(fdout);
303 	v = sizeof(struct Font) + 3 * n + dev.nchtab + 128-32;
304 	fprintf(stderr, "%3s: %3d chars, width %3d, size %3d\n",
305 		font.namefont, nw, width[0], v);
306 	return v;
307 }
308 
309 getlig(fin)	/* pick up ligature list */
310 	FILE *fin;
311 {
312 	int lig;
313 	char temp[100];
314 
315 	lig = 0;
316 	while (fscanf(fin, "%s", temp) != EOF && strcmp(temp, "0") != 0) {
317 		if (strcmp(temp, "fi") == 0)
318 			lig |= LFI;
319 		else if (strcmp(temp, "fl") == 0)
320 			lig |= LFL;
321 		else if (strcmp(temp, "ff") == 0)
322 			lig |= LFF;
323 		else if (strcmp(temp, "ffi") == 0)
324 			lig |= LFFI;
325 		else if (strcmp(temp, "ffl") == 0)
326 			lig |= LFFL;
327 		else
328 			fprintf(stderr, "illegal ligature %s\n", temp);
329 	}
330 	skipline(fin);
331 	return lig;
332 }
333