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