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