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