1: /* 2: * makextdev - make an extended character code table for the ditroff 3: * interpress converter. 4: * 5: * Copyright (c) 1984, 1985 Xerox Corp. 6: * 7: * History: 8: * 24-oct-85 ed flint close fontfiles, ran out of open file 9: * descriptors with large number of fonts 10: * 11: * Some of the characters in the interpress fonts have character codes 12: * greater than 255. Since the ditroff character code table is an array of 13: * char, the codes are too large. This attempts to remedy that situation. 14: * If the character code specified in the normal code table is 0377 (decimal 15: * 255), then the real code can be found in the extended table (which is an 16: * array of short). This program reads the same files that makedev reads and 17: * build the extended code table. 18: * 19: * To specify an extended code in a font table, use a line of the following 20: * form: 21: * 22: * c www kk 0377 xxxxx 23: * 24: * where: c is the one or two letter character code, 25: * www is the character's width, 26: * kk is the kerning information, and 27: * xxxxx is the actual interpress code for the character. 28: * 29: * Basically, this is just like any other line in the font table file, except 30: * that the standard code is set to 0377 and the actual code is placed on the 31: * line as the fifth item. Note that a file with lines like this can still 32: * be run thru makedev successfully -- makedev will just ignore the fifth 33: * item on the line. 34: * 35: * One can make the extended tables for all the loaded fonts by saying 36: * "makextdev DESC" (just as with makedev), but makedev must be run before 37: * doing this, since it will require looking at DESC.out. 38: */ 39: 40: # include "deviceinfo.h" 41: # include <stdio.h> 42: 43: # define Line_length 256 44: 45: # define Max_chars 256 /* maximum # of funny chars */ 46: /* Tab_size includes all ascii characters except control characters */ 47: # define Table_size (Max_chars + 128 - 32) 48: 49: # define white(ch) ((ch) == ' ' || (ch) == '\t' || (ch) == '\n') 50: 51: /* values returned by strcmp */ 52: # define Equal 0 53: 54: char char_name[5 * Max_chars]; 55: short char_index_table[Max_chars]; 56: 57: unsigned char font_index_table[Table_size]; 58: unsigned short extend_table[Table_size]; 59: struct device_entry device_entry; 60: 61: main(argc, argv) 62: 63: int argc; 64: char *argv[]; 65: 66: { 67: int i; 68: int fntcnt; 69: int descfd; 70: register char *ptr; 71: char line[Line_length]; 72: char keyword[80]; 73: char *fname; 74: FILE *descfile; 75: 76: if (argc < 2) 77: { 78: fprintf(stderr, "usage: makextdev font\n"); 79: exit(1); 80: } 81: 82: /* First off, get the DESC.out file -- we need the information */ 83: if ((descfd = open("DESC.out", 0)) == -1) 84: { 85: perror("DESC.out"); 86: fprintf(stderr, "makextdev: please run \"makedev DESC\" first!\n"); 87: exit(1); 88: } 89: 90: /* read struct device_entry off the front */ 91: read(descfd, &device_entry, sizeof(device_entry)); 92: 93: /* skip over the point size table */ 94: lseek(descfd, (device_entry.num_sizes + 1) * sizeof(short), 1); 95: 96: /* read char_index_table and char_name arrays */ 97: read(descfd, char_index_table, device_entry.spec_char_num * sizeof(short)); 98: read(descfd, char_name, device_entry.spec_name_len); 99: for (i=0; i<device_entry.spec_char_num; i++) 100: { 101: fprintf(stderr, "%d ", char_index_table[i]); 102: } 103: fputc('\n', stderr); 104: for (i=0; i<device_entry.spec_char_num; i++) 105: { 106: if (char_name[i] == '\0') 107: { 108: fputc(' ', stderr); 109: } 110: else 111: { 112: fputc(char_name[i], stderr); 113: } 114: } 115: fputc('\n', stderr); 116: 117: /* step thru the arguments */ 118: while (--argc > 0) 119: { 120: fname = *++argv; 121: 122: if (strcmp(fname, "DESC") == Equal) 123: { 124: /* do all the preloaded fonts */ 125: if ((descfile = fopen(fname, "r")) == NULL) 126: { 127: perror(fname); 128: exit(1); 129: } 130: 131: /* scan thru DESC looking for the "fonts" keyword */ 132: do 133: { 134: if (fgets(line, Line_length, descfile) == NULL) 135: { 136: fprintf(stderr, "makextdev: no fonts listed in DESC\n"); 137: exit(1); 138: } 139: sscanf(line, "%s", keyword); 140: } while (strcmp(keyword, "fonts") != Equal); 141: 142: /* found the line -- do each font listed on the line */ 143: /* line looks like this: fonts n X X X X ... */ 144: /* where n is number of fonts and X is a font name */ 145: fclose(descfile); 146: ptr = line + 5; /* 5 == strlen("fonts") */ 147: while (white(*ptr)) 148: { 149: ptr++; /* never trust a macro */ 150: } 151: 152: /* get font count */ 153: fntcnt = atoi(ptr); 154: while (!white(*ptr)) 155: { 156: ptr++; 157: } 158: while (white(*ptr)) 159: { 160: ptr++; 161: } 162: 163: /* process each font on the line */ 164: while (fntcnt-- > 0) 165: { 166: register char *fontname; 167: 168: fontname = ptr; 169: while (!white(*ptr)) 170: { 171: ptr++; 172: } 173: *ptr++ = '\0'; 174: dofont(fontname); 175: while (white(*ptr)) 176: { 177: ptr++; 178: } 179: } 180: } 181: else 182: { 183: dofont(fname); 184: } 185: } 186: } 187: 188: dofont(fontname) 189: 190: char *fontname; 191: 192: { 193: int outfile; 194: int i; 195: int ccode; 196: unsigned int xcode; 197: char outname[20]; 198: char ch[10]; 199: char swid[10]; 200: char skern[10]; 201: char scode[10]; 202: char sauxcode[10]; 203: char line[Line_length]; 204: char keyword[20]; 205: FILE *fontfile; 206: struct font_entry font_entry; 207: 208: /* open the file that describes the font */ 209: if ((fontfile = fopen(fontname, "r")) == NULL) 210: { 211: perror(fontname); 212: exit(1); 213: } 214: 215: /* find the keyword "charset" */ 216: do 217: { 218: if (fgets(line, Line_length, fontfile) == NULL) 219: { 220: fprintf(stderr, "makextdev: font %s has no charset\n", fontname); 221: exit(1); 222: } 223: sscanf(line, "%s", keyword); 224: } while (strcmp(keyword, "charset") != Equal); 225: 226: /* get font info from *.out file */ 227: /* first, open it */ 228: strcpy(outname, fontname); 229: strcat(outname, ".out"); 230: if ((outfile = open(outname, 0)) == -1) 231: { 232: perror(outname); 233: fprintf(stderr, "makextdev: please run \"makedev %s\" first!\n", 234: fontname); 235: exit(1); 236: } 237: 238: /* zero extend_table */ 239: bzero(extend_table, sizeof(extend_table)); 240: 241: /* now read the header and font_index_table */ 242: read(outfile, &font_entry, sizeof(font_entry)); 243: lseek(outfile, (unsigned char)(font_entry.num_char_wid) * 3, 1); /* skip width, kern, and code */ 244: read(outfile, font_index_table, device_entry.spec_char_num + 128 - 32); 245: close(outfile); 246: 247: /* unscramble each line */ 248: while (fgets(line, Line_length, fontfile) != NULL) 249: { 250: i = sscanf(line, "%s %s %s %s %s", ch, swid, skern, scode, sauxcode); 251: 252: if (swid[0] != '"') 253: { 254: /* translate scode and auxcode into actual numerical values */ 255: ccode = convcode(scode); 256: xcode = convcode(sauxcode); 257: } 258: else 259: { 260: /* it's a repeat of the last character */ 261: i = 5; 262: } 263: 264: /* check for extended code */ 265: if (ccode == 0377) 266: { 267: if (i < 5) 268: { 269: fprintf(stderr, "%s: character %s has no extended code\n", 270: fontname, ch); 271: } 272: else 273: { 274: /* find the findex and store the extended code in extend_table */ 275: if (strlen(ch) == 1) 276: { 277: /* fprintf(stderr, "font_index_table[%d] = %d\n", 278: ch[0] - 32, font_index_table[ch[0] - 32]); 279: */ extend_table[font_index_table[ch[0] - 32]] = xcode; 280: } 281: else 282: { 283: /* it's a funny name */ 284: for (i = 0; i < device_entry.spec_char_num; i++) 285: { 286: if (strcmp(&char_name[char_index_table[i]], ch) == Equal) 287: { 288: /* fprintf(stderr, "i = %d, font_index_table[%d] = %d\n", 289: i, i+128-32, font_index_table[i+128-32]); 290: */ 291: extend_table[font_index_table[i + 128-32]] = xcode; 292: break; 293: } 294: } 295: } 296: } 297: } 298: } 299: 300: /* Now, write extend_table in an appropriate file */ 301: /* remember: outname currently looks like "XX.out" */ 302: strcat(outname, ".ext"); 303: if ((outfile = creat(outname, 0666)) == -1) 304: { 305: perror(outname); 306: exit(1); 307: } 308: write(outfile, extend_table, (device_entry.spec_char_num + 128-32) * sizeof(short)); 309: close(outfile); 310: fclose(fontfile); 311: } 312: 313: convcode(str) 314: 315: char *str; 316: 317: { 318: int val; 319: 320: if (str[0] == '0') 321: { 322: sscanf(str, "%o", &val); 323: } 324: else 325: { 326: val = atoi(str); 327: } 328: 329: return(val); 330: }