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