|
|
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.