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