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 2005 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 254 /* 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 #define BIGGESTFONT FSIZE /* biggest font if no size in DESC */
114 /* MUST be < 256 */
115
116 #define NFONT 50 /* max number of default fonts */
117 char fname[NFONT][10]; /* temp space to hold default font names */
118
119 int fflag = 0; /* on if font table to be written */
120 int fdout; /* output file descriptor */
121 char *fout = "DESC.out";
122
123 static int dofont(char *);
124 static int getlig(FILE *);
125
126 int
main(int argc,char * argv[])127 main(int argc, char *argv[])
128 {
129 FILE *fin;
130 char cmd[100], *p;
131 int i, totfont, v;
132
133 if (argc < 2) {
134 fprintf(stderr, "Usage: makedev [DESC] [fonts]\n");
135 exit(1);
136 }
137 if ((fin = fopen("DESC", "r")) == NULL) {
138 fprintf(stderr, "makedev: can't open DESC file\n");
139 exit(1);
140 }
141 while (fscanf(fin, "%s", cmd) != EOF) {
142 if (cmd[0] == '#') /* comment */
143 skipline(fin);
144 else if (strcmp(cmd, "res") == 0) {
145 fscanf(fin, "%hd", &dev.res);
146 } else if (strcmp(cmd, "hor") == 0) {
147 fscanf(fin, "%hd", &dev.hor);
148 } else if (strcmp(cmd, "vert") == 0) {
149 fscanf(fin, "%hd", &dev.vert);
150 } else if (strcmp(cmd, "unitwidth") == 0) {
151 fscanf(fin, "%hd", &dev.unitwidth);
152 } else if (strcmp(cmd, "sizescale") == 0) {
153 fscanf(fin, "%hd", &dev.sizescale);
154 } else if (strcmp(cmd, "paperwidth") == 0) {
155 fscanf(fin, "%hd", &dev.paperwidth);
156 } else if (strcmp(cmd, "paperlength") == 0) {
157 fscanf(fin, "%hd", &dev.paperlength);
158 } else if (strcmp(cmd, "biggestfont") == 0) {
159 fscanf(fin, "%hd", &dev.biggestfont);
160 } else if (strcmp(cmd, "spare2") == 0) {
161 fscanf(fin, "%hd", &dev.spare2);
162 } else if (strcmp(cmd, "sizes") == 0) {
163 dev.nsizes = 0;
164 while (fscanf(fin, "%d", &v) != EOF && v != 0)
165 size[dev.nsizes++] = v;
166 size[dev.nsizes] = 0; /* need an extra 0 at the end */
167 } else if (strcmp(cmd, "fonts") == 0) {
168 fscanf(fin, "%hd", &dev.nfonts);
169 for (i = 0; i < dev.nfonts; i++)
170 fscanf(fin, "%s", fname[i]);
171 } else if (strcmp(cmd, "charset") == 0) {
172 short pchname;
173
174 p = chname;
175 pchname = 0;
176 dev.nchtab = 0;
177 while (fscanf(fin, "%s", p) != EOF) {
178 chtab[dev.nchtab++] = pchname;
179 while (*p++) /* skip to end of name */
180 pchname++;
181 pchname++;
182 }
183 dev.lchname = pchname;
184 chtab[dev.nchtab++] = 0; /* terminate properly */
185 } else
186 fprintf(stderr, "makedev: unknown command %s\n", cmd);
187 }
188 if (argc > 1 && strcmp(argv[1], "DESC") == 0) {
189 fdout = creat(fout, 0666);
190 if (fdout < 0) {
191 fprintf(stderr, "makedev: can't open %s\n", fout);
192 exit(1);
193 }
194 write(fdout, &dev, sizeof(struct dev));
195 write(fdout, size, (dev.nsizes+1) * sizeof(size[0])); /* we need a 0 on the end */
196 write(fdout, chtab, dev.nchtab * sizeof(chtab[0]));
197 write(fdout, chname, dev.lchname);
198 totfont = 0;
199 for (i = 0; i < dev.nfonts; i++) {
200 totfont += dofont(fname[i]);
201 write(fdout, &font, sizeof(struct Font));
202 write(fdout, width, font.nwfont & BYTEMASK);
203 write(fdout, kern, font.nwfont & BYTEMASK);
204 write(fdout, code, font.nwfont & BYTEMASK);
205 write(fdout, fitab, dev.nchtab+128-32);
206 }
207 lseek(fdout, 0L, 0); /* back to beginning to install proper size */
208 dev.filesize = /* excluding dev struct itself */
209 (dev.nsizes+1) * sizeof(size[0])
210 + dev.nchtab * sizeof(chtab[0])
211 + dev.lchname * sizeof(char)
212 + totfont * sizeof(char);
213 write(fdout, &dev, sizeof(struct dev));
214 close(fdout);
215 argc--;
216 argv++;
217 }
218 for (i = 1; i < argc; i++)
219 dofont(argv[i]);
220 return (0);
221 }
222
223 static int
dofont(char * name)224 dofont(char *name) /* create fitab and width tab for font */
225 {
226 FILE *fin;
227 int fdout;
228 int i, nw, spacewidth, n, v;
229 char buf[100], ch[10], s1[10], s2[10], s3[10], cmd[30];
230
231 if ((fin = fopen(name, "r")) == NULL) {
232 fprintf(stderr, "makedev: can't open font %s\n", name);
233 exit(2);
234 }
235 sprintf(cmd, "%s.out", name);
236 fdout = creat(cmd, 0666);
237 if (fdout < 0) {
238 fprintf(stderr, "makedev: can't open %s\n", fout);
239 exit(1);
240 }
241 for (i = 0; i < NFITAB; i++)
242 fitab[i] = 0;
243 for (i = 0; i < FSIZE; i++)
244 width[i] = kern[i] = code[i] = 0;
245 font.specfont = font.ligfont = spacewidth = 0;
246 while (fscanf(fin, "%s", cmd) != EOF) {
247 if (cmd[0] == '#')
248 skipline(fin);
249 else if (strcmp(cmd, "name") == 0)
250 fscanf(fin, "%s", font.namefont);
251 else if (strcmp(cmd, "internalname") == 0)
252 fscanf(fin, "%s", font.intname);
253 else if (strcmp(cmd, "special") == 0)
254 font.specfont = 1;
255 else if (strcmp(cmd, "spare1") == 0)
256 fscanf(fin, "%1s", &font.spare1);
257 else if (strcmp(cmd, "ligatures") == 0) {
258 font.ligfont = getlig(fin);
259 } else if (strcmp(cmd, "spacewidth") == 0) {
260 fscanf(fin, "%d", &spacewidth);
261 width[0] = spacewidth; /* width of space on this font */
262 } else if (strcmp(cmd, "charset") == 0) {
263 skipline(fin);
264 nw = 0;
265 /* widths are origin 1 so fitab==0 can mean "not there" */
266 while (fgets(buf, 100, fin) != NULL) {
267 sscanf(buf, "%s %s %s %s", ch, s1, s2, s3);
268 if (s1[0] != '"') { /* it's a genuine new character */
269 nw++;
270 width[nw] = atoi(s1);
271 kern[nw] = atoi(s2);
272 /* temporarily, pick up one byte as code */
273 if (s3[0] == '0')
274 sscanf(s3, "%o", &i);
275 else
276 sscanf(s3, "%d", &i);
277 code[nw] = i;
278 }
279 /* otherwise it's a synonym for previous character,
280 * so leave previous values intact
281 */
282 if (strlen(ch) == 1) /* it's ascii */
283 fitab[ch[0] - 32] = nw; /* fitab origin omits non-graphics */
284 else if (strcmp(ch, "---") != 0) { /* it has a 2-char name */
285 for (i = 0; i < dev.nchtab; i++)
286 if (strcmp(&chname[chtab[i]], ch) == 0) {
287 fitab[i + 128-32] = nw; /* starts after the ascii */
288 break;
289 }
290 if (i >= dev.nchtab)
291 fprintf(stderr, "makedev: font %s: %s not in charset\n", name, ch);
292 }
293 }
294 nw++;
295 if (dev.biggestfont > 0)
296 n = dev.biggestfont + 1;
297 else
298 n = BIGGESTFONT;
299 /*
300 * Make files at least as big as biggestfont. Larger fonts
301 * may only fit in postion 0.
302 */
303 if ( nw > n ) {
304 n = nw;
305 fprintf(stderr, "makedev: warning font %s may only fit in position 0\n", font.namefont);
306 }
307 if (n >= NCH) {
308 fprintf(stderr, "makedev: font has %d characters, too big\n", n);
309 exit(2);
310 }
311 font.nwfont = n;
312 }
313 }
314 if (spacewidth == 0)
315 width[0] = dev.res * dev.unitwidth / 72 / 3; /* should be rounded */
316 fclose(fin);
317
318 write(fdout, &font, sizeof(struct Font));
319 write(fdout, width, font.nwfont & BYTEMASK);
320 write(fdout, kern, font.nwfont & BYTEMASK);
321 write(fdout, code, font.nwfont & BYTEMASK);
322 write(fdout, fitab, dev.nchtab+128-32);
323 close(fdout);
324 v = sizeof(struct Font) + 3 * n + dev.nchtab + 128-32;
325 fprintf(stderr, "%3s: %3d chars, width %3d, size %3d\n",
326 font.namefont, nw, width[0], v);
327 return (v);
328 }
329
330 static int
getlig(FILE * fin)331 getlig(FILE *fin) /* pick up ligature list */
332 {
333 int lig;
334 char temp[100];
335
336 lig = 0;
337 while (fscanf(fin, "%s", temp) != EOF && strcmp(temp, "0") != 0) {
338 if (strcmp(temp, "fi") == 0)
339 lig |= LFI;
340 else if (strcmp(temp, "fl") == 0)
341 lig |= LFL;
342 else if (strcmp(temp, "ff") == 0)
343 lig |= LFF;
344 else if (strcmp(temp, "ffi") == 0)
345 lig |= LFFI;
346 else if (strcmp(temp, "ffl") == 0)
347 lig |= LFFL;
348 else
349 fprintf(stderr, "illegal ligature %s\n", temp);
350 }
351 skipline(fin);
352 return (lig);
353 }
354