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