|
|
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:
46: #define SLANT_BIT 1 /* slant flag is bit 0 */
47: #define FONT_BIT 2 /* font flag is bit 1 */
48: #define RANGE_BIT 4 /* range flag is bit 2 */
49:
50: #define SLANT_VAL 3 /* slant angle starts in bit 3 */
51: #define RANGE_VAL 5 /* max range starts in bit 5 */
52:
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 200 /* 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: char alt_code[FSIZE]; /* code for alternate font */
73: int alt_font[FSIZE]; /* alternate font to use */
74:
75: int dbg = 0; /* debug flag */
76:
77:
78: #define NFONT 10 /* max number of default fonts */
79: char fname[NFONT][10]; /* temp space to hold default font names */
80:
81: int fflag = 0; /* on if font table to be written */
82: int fdout; /* output file descriptor */
83: char *fout = "DESC.out";
84:
85: main(argc, argv)
86: char *argv[];
87: {
88: FILE *fin;
89: char cmd[100], *p;
90: int i, totfont, v;
91:
92: if ((fin = fopen("DESC", "r")) == NULL) {
93: fprintf(stderr, "makedev: can't open %s\n", argv[1]);
94: exit(1);
95: }
96: while (fscanf(fin, "%s", cmd) != EOF) {
97: if (cmd[0] == '#') /* comment */
98: skipline(fin);
99: else if (strcmp(cmd, "debug") == 0)
100: dbg++;
101: else if (strcmp(cmd, "res") == 0) {
102: fscanf(fin, "%hd", &dev.res);
103: } else if (strcmp(cmd, "hor") == 0) {
104: fscanf(fin, "%hd", &dev.hor);
105: } else if (strcmp(cmd, "vert") == 0) {
106: fscanf(fin, "%hd", &dev.vert);
107: } else if (strcmp(cmd, "unitwidth") == 0) {
108: fscanf(fin, "%hd", &dev.unitwidth);
109: } else if (strcmp(cmd, "sizescale") == 0) {
110: fscanf(fin, "%hd", &dev.sizescale);
111: } else if (strcmp(cmd, "paperwidth") == 0) {
112: fscanf(fin, "%hd", &dev.paperwidth);
113: } else if (strcmp(cmd, "paperlength") == 0) {
114: fscanf(fin, "%hd", &dev.paperlength);
115: } else if (strcmp(cmd, "spare1") == 0) {
116: fscanf(fin, "%hd", &dev.spare1);
117: } else if (strcmp(cmd, "spare2") == 0) {
118: fscanf(fin, "%hd", &dev.spare2);
119: } else if (strcmp(cmd, "sizes") == 0) {
120: dev.nsizes = 0;
121: while (fscanf(fin, "%d", &v) != EOF && v != 0)
122: size[dev.nsizes++] = v;
123: size[dev.nsizes] = 0; /* need an extra 0 at the end */
124: } else if (strcmp(cmd, "fonts") == 0) {
125: fscanf(fin, "%hd", &dev.nfonts);
126: for (i = 0; i < dev.nfonts; i++)
127: fscanf(fin, "%s", fname[i]);
128: } else if (strcmp(cmd, "charset") == 0) {
129: p = chname;
130: dev.nchtab = 0;
131: while (fscanf(fin, "%s", p) != EOF) {
132: chtab[dev.nchtab++] = p - chname;
133: while (*p++) /* skip to end of name */
134: ;
135: }
136: dev.lchname = p - chname;
137: chtab[dev.nchtab++] = 0; /* terminate properly */
138: } else
139: fprintf(stderr, "makedev: unknown command %s\n", cmd);
140: }
141: if (argc > 0 && strcmp(argv[1], "DESC") == 0) {
142: fdout = creat(fout, 0666);
143: if (fdout < 0) {
144: fprintf(stderr, "makedev: can't open %s\n", fout);
145: exit(1);
146: }
147: write(fdout, &dev, sizeof(struct dev));
148: write(fdout, size, (dev.nsizes+1) * sizeof(size[0])); /* we need a 0 on the end */
149: write(fdout, chtab, dev.nchtab * sizeof(chtab[0]));
150: write(fdout, chname, dev.lchname);
151: totfont = 0;
152: for (i = 0; i < dev.nfonts; i++) {
153: totfont += dofont(fname[i]);
154: write(fdout, &font, sizeof(struct font));
155: write(fdout, width, font.nwfont & BMASK);
156: write(fdout, kern, font.nwfont & BMASK);
157: write(fdout, code, font.nwfont & BMASK);
158: write(fdout, fitab, dev.nchtab+128-32);
159: }
160: lseek(fdout, 0L, 0); /* back to beginning to install proper size */
161: dev.filesize = /* excluding dev struct itself */
162: (dev.nsizes+1) * sizeof(size[0])
163: + dev.nchtab * sizeof(chtab[0])
164: + dev.lchname * sizeof(char)
165: + totfont * sizeof(char);
166: write(fdout, &dev, sizeof(struct dev));
167: close(fdout);
168: argc--;
169: argv++;
170: }
171: for (i = 1; i < argc; i++)
172: dofont(argv[i]);
173: exit(0);
174: }
175:
176:
177: /*****************************************************************************/
178:
179:
180: dofont(name)
181:
182:
183: char *name; /* string containing name of font */
184:
185:
186: {
187:
188:
189: FILE *fin; /* input file descriptor */
190: int fdout; /* output file descriptor */
191: int i, nw, spacewidth, n, v;
192: char buf[100], ch[10], s1[10], s2[10], s3[10], cmd[30];
193: char s4[10]; /* used to check for extra info */
194: int count; /* value returned from sscanf() */
195: int dflt_range; /* default maximum range for font */
196: int dflt_slant; /* default slant for this font */
197:
198:
199:
200: /********************************************************************
201: * *
202: * This routine is responsible for making the '.out' file for *
203: * the font specified by the parameter name. It also sets up some *
204: * of the data structures needed to make the DESC.out file in the *
205: * main routine. In addition I have changed this routine so that *
206: * we can add some typesetter dependent parameters to the font *
207: * files and have this information dumped out to a 'add' file *
208: * for this font, which can be read as needed by the aps driver. *
209: * *
210: ********************************************************************/
211:
212:
213:
214: if ((fin = fopen(name, "r")) == NULL) {
215: fprintf(stderr, "makedev: can't open font %s\n", name);
216: exit(2);
217: } /* End if */
218:
219: sprintf(cmd, "%s.out", name); /* output file is name.out */
220: fdout = creat(cmd, 0666); /* create the '.out' font file */
221:
222: font.specfont = 0; /* by default it isn't special font */
223: font.ligfont = 0; /* it also has no ligatures either */
224: font.spare1 = 0; /* all the flags are initially off */
225: spacewidth = 0; /* tables may specify a spacewidth */
226: dflt_range = 3; /* max range available on the APS-5 */
227: dflt_slant = 0; /* no slant for this font yet */
228:
229: for (i = 0; i < NFITAB; i++) /* initialize font index table */
230: fitab[i] = 0;
231:
232: for (i = 0; i < FSIZE; i++) { /* initialize character tables */
233: width[i] = kern[i] = code[i] = 0;
234: alt_font[i] = 0;
235: alt_code[i] = 0;
236: } /* End for */
237:
238: while (fscanf(fin, "%s", cmd) != EOF) { /* read the font file */
239:
240: if (strcmp(cmd, "name") == 0)
241: fscanf(fin, "%s", font.namefont);
242: else if (strcmp(cmd, "internalname") == 0)
243: fscanf(fin, "%s", font.intname);
244: else if (strcmp(cmd, "special") == 0)
245: font.specfont = 1;
246: else if (strcmp(cmd, "ligatures") == 0) {
247: skipline(fin); /* skip over any names for now */
248: font.ligfont = 1;
249: } else if (strcmp(cmd, "spacewidth") == 0) {
250: fscanf(fin, "%d", &spacewidth);
251: width[0] = spacewidth; /* width of space on this font */
252: } else if (strcmp(cmd, "charset") == 0) {
253: skipline(fin);
254: nw = 0;
255:
256: /* widths are origin 1 so fitab==0 can mean "not there" */
257:
258: while (fgets(buf, 100, fin) != NULL) { /* read next line */
259:
260: count = sscanf(buf, "%s %s %s %s %s", ch, s1, s2, s3, s4);
261:
262: if (s1[0] != '"') { /* it's a genuine new character */
263:
264: nw++;
265: width[nw] = atoi(s1);
266: kern[nw] = atoi(s2);
267:
268: /* temporarily, pick up one byte as code */
269:
270: if ( s3[0] == '0' ) /* code is in octal */
271: sscanf(s3, "%o", &i);
272: else
273: sscanf(s3, "%d", &i); /* otherwise it is decimal */
274: code[nw] = i;
275:
276: if ( count > 4 && font.spare1 ) /* process the rest */
277: finish_line(buf, nw);
278:
279: } /* End if */
280:
281: /* otherwise it's a synonym for previous character,
282: /* so leave previous values intact
283: */
284:
285: if (strlen(ch) == 1) /* it's ascii */
286: fitab[ch[0] - 32] = nw; /* fitab origin omits non-graphics */
287: else { /* it has a funny name */
288: for (i = 0; i < dev.nchtab; i++)
289: if (strcmp(&chname[chtab[i]], ch) == 0) {
290: fitab[i + 128-32] = nw; /* starts after the ascii */
291: break;
292: } /* End if */
293:
294: if (i >= dev.nchtab)
295: fprintf(stderr, "makedev: font %s: %s not in charset\n", name, ch);
296: } /* End else */
297:
298: } /* End while */
299: nw++;
300: font.nwfont = n = nw;
301: } else if ( strcmp(cmd, "alternate_font") == 0 )
302: font.spare1 |= FONT_BIT; /* set alternate font bit */
303: else if ( strcmp(cmd, "default_slant") == 0 ) {
304: font.spare1 &= ~(3 << SLANT_VAL); /* clear two slant val bits */
305: font.spare1 |= SLANT_BIT; /* set font slant bit */
306: fscanf(fin, "%d", &dflt_slant); /* read the default slant value */
307: if ( dflt_slant > 0 ) /* encode it as 01 */
308: font.spare1 |= (1 << SLANT_VAL);
309: else if ( dflt_slant < 0 ) /* encode it as 10 */
310: font.spare1 |= (1 << (SLANT_VAL + 1));
311: } else if ( strcmp(cmd, "max_range") == 0 ) {
312: font.spare1 |= RANGE_BIT; /* set range bit in spare1 */
313: fscanf(fin, "%d", &dflt_range); /* read default font slant */
314: if ( dflt_range < 1 || dflt_range > 4 ) {
315: fprintf(stderr, "makedev: illegal default range %d\n",dflt_range);
316: exit(1);
317: } /* End if */
318: font.spare1 |= (dflt_range << RANGE_VAL);
319: } else if ( strcmp(cmd, "debug") == 0 )
320: dbg++;
321:
322: } /* End while */
323:
324: if (spacewidth == 0)
325: width[0] = dev.res * dev.unitwidth / 72 / 3;
326: fclose(fin);
327:
328: write(fdout, &font, sizeof(struct font));
329: write(fdout, width, font.nwfont & BMASK);
330: write(fdout, kern, font.nwfont & BMASK);
331: write(fdout, code, font.nwfont & BMASK);
332: write(fdout, fitab, dev.nchtab+128-32);
333: close(fdout);
334:
335: if ( font.spare1 ) add_font(name);
336:
337: if ( dbg ) dump_font();
338:
339: v = sizeof(struct font) + 3 * n + dev.nchtab + 128-32;
340: fprintf(stderr, "%3s: %3d chars, width %3d, size %3d\n",
341: font.namefont, nw, width[0], v);
342: return v;
343:
344: } /* End of dofont */
345:
346:
347: /*****************************************************************************/
348:
349:
350: finish_line(buf, nw)
351:
352:
353: char *buf; /* contains current input line */
354: int nw; /* current index in char tables */
355:
356:
357: {
358:
359:
360: char s[3][20]; /* used for special char commands */
361: char v[3][20]; /* used to hold values */
362: int count; /* number of vals read in sscanf() */
363: int range; /* value of max range for character */
364: int angle; /* value of slant angle for char */
365: int i; /* for loop index */
366:
367:
368:
369: /********************************************************************
370: * *
371: * This routine is called from dofont() to finish scanning an *
372: * input line which has additional character information on it. *
373: * The line was read in dofont() and put in the buffer buf, while *
374: * the current index that we are using for the character tables is *
375: * the value of the parameter nw. The format of the additional *
376: * information that may appear in a line in the character set part *
377: * of a font file is shown below, *
378: * *
379: * slant l max_range m font n *
380: * *
381: * where l, m, and n are integers. Any or all of these commands *
382: * may appear on a given line after the normal code entry for the *
383: * current character. *
384: * *
385: ********************************************************************/
386:
387:
388:
389: count = sscanf(buf,"%*s %*s %*s %*s %s %s %s %s %s %s",s[0],v[0],s[1],v[1],s[2],v[2]);
390:
391: if ( (count % 2 != 0) || (count == 0) ) {
392: fprintf(stderr, "makedev: format error in charset table\n");
393: exit(1);
394: } /* End if */
395:
396: alt_code[nw] = code[nw]; /* store real code in alt_code array */
397: code[nw] = 128; /* turn bit 7 on */
398:
399: for ( i = 0; i < count/2; i++ ) { /* process the strings */
400:
401: if ( strcmp(s[i], "font") == 0 ) { /* have an alternate font */
402: code[nw] |= FONT_BIT; /* turn font bit on */
403: alt_font[nw] = atoi(v[i]); /* save this font number */
404: } else if ( strcmp(s[i], "max_range") == 0 ) {
405: code[nw] &= ~(3 << RANGE_VAL);
406: code[nw] |= RANGE_BIT;
407: range = atoi(v[i]);
408: if ( range < 1 || range > 4 ) {
409: fprintf(stderr, "makedev: illegal range\n");
410: exit(1);
411: } /* End if */
412: code[nw] |= (range << RANGE_VAL);
413: } else if ( strcmp(s[i], "slant" ) == 0 ) {
414: code[nw] &= ~(3 << SLANT_VAL);
415: code[nw] |= SLANT_BIT;
416: angle = atoi(v[i]);
417: if ( angle > 0 ) /* set angle bits to 01 */
418: code[nw] |= (1 << SLANT_VAL);
419: else if ( angle < 0 ) /* set angle bits to 10 */
420: code[nw] |= (1 << (SLANT_VAL + 1));
421: } else { /* illegal command - abort */
422: fprintf(stderr, "makedev: illegal command\n");
423: exit(1);
424: } /* End else */
425:
426: } /* End for */
427: if ( code[nw] & BMASK == 128 ) {
428: fprintf(stderr, "makedev: char code %d less than 129\n", code[nw]);
429: exit(1);
430: } /* End if */
431:
432: } /* End of finish_line */
433:
434:
435: /*****************************************************************************/
436:
437:
438: add_font(name)
439:
440:
441: char *name; /* name of currnent font */
442:
443:
444: {
445:
446:
447: int fdout; /* output file descriptor */
448: int k; /* number of width entries */
449: char cmd[30]; /* used to create output file */
450:
451:
452:
453: /********************************************************************
454: * *
455: * This routine is called from dofont() to write out the *
456: * additional information that was specified in the input font *
457: * file. As currently implemented the alternate code table and *
458: * the alternate font tables are always written to the output *
459: * file. *
460: * *
461: ********************************************************************/
462:
463:
464:
465: sprintf(cmd, "%s.add", name); /* file will be 'name'.add */
466: fdout = creat(cmd, 0666); /* create the '.add' file */
467:
468: k = font.nwfont & BMASK;
469:
470: write(fdout, alt_font, FSIZE * sizeof(alt_font[0]));
471: write(fdout, alt_code, FSIZE);
472:
473: close(fdout);
474:
475: } /* End of add_font */
476:
477:
478: /*****************************************************************************/
479:
480:
481: dump_font()
482:
483:
484: {
485:
486:
487: int pos; /* position in character tables */
488: int j; /* for loop index */
489: int code_val; /* number in code table */
490:
491:
492:
493: /********************************************************************
494: * *
495: * This routine is called to dump the information that we have *
496: * read from the current font file. *
497: * *
498: ********************************************************************/
499:
500:
501:
502: printf("DATA FOR FONT %s:\n\n", font.namefont);
503:
504: printf(" font structure data:\n");
505: printf("\t\tfont.nwfont = %d\n", font.nwfont & BMASK);
506: printf("\t\tfont.specfont = %d\n", font.specfont & BMASK);
507: printf("\t\tfont.ligfont = %d\n", font.ligfont & BMASK);
508: printf("\t\tfont.spare1 = 0%o\n", font.spare1 & BMASK);
509: printf("\t\tfont.intname = %s\n\n", font.intname);
510:
511: printf(" CHAR WIDTH KERN CODE INDEX\n");
512:
513: for ( j = 0; j < dev.nchtab + 128 - 32; j++ ) {
514:
515: if ( (pos = fitab[j] & BMASK) != 0 ) {
516: if ( j >= 96 )
517: printf("%5s", &chname[chtab[j-96]]);
518: else printf("%5c", (j + 32) & BMASK);
519: printf("%10d", width[pos] & BMASK);
520: printf("%10d", kern[pos] & BMASK);
521: code_val = code[pos] & BMASK;
522: printf("%10d", code_val & BMASK);
523: printf("%10d", j);
524:
525: if ( code_val > 128 ) {
526: printf("%5d", alt_code[pos] & BMASK);
527: if ( code_val & SLANT_BIT )
528: printf(" slant %d", (code_val >> SLANT_VAL) & 03);
529: if ( code_val & FONT_BIT )
530: printf(" font %d", alt_font[pos]);
531: if ( code_val & RANGE_BIT )
532: printf(" range %d", (code_val >> RANGE_VAL) & 03);
533: } /* End if */
534:
535: printf("\n");
536: } /* End if */
537:
538: } /* End for */
539:
540: printf("\n\n");
541:
542: } /* End of dump_font */
543:
544:
545: /*****************************************************************************/
546:
547:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.