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
96 struct dev dev;
97 struct Font font;
98
99 #define NSIZE 100 /* maximum number of sizes */
100 short size[NSIZE];
101 #define NCH 256 /* max number of characters with funny names */
102 char chname[5*NCH]; /* character names, including \0 for each */
103 short chtab[NCH]; /* index of character in chname */
104
105 #define NFITAB (NCH + 128-32) /* includes ascii chars, but not non-graphics */
106 char 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) */
110 char width[FSIZE]; /* width table for a physical font */
111 char kern[FSIZE]; /* ascender+descender info */
112 char code[FSIZE]; /* actual device codes for a physical font */
113
114 #define NFONT 60 /* max number of default fonts */
115 char fname[NFONT][10]; /* temp space to hold default font names */
116
117 int fflag = 0; /* on if font table to be written */
118 int fdout; /* output file descriptor */
119 char *fout = "DESC.out";
120
main(int argc,char * argv[])121 int 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
216 int
dofont(name)217 dofont(name) /* create fitab and width tab for font */
218 char *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
312 int
getlig(fin)313 getlig(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