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