|
|
1.1 ! root 1: ! 2: ! 3: /* ! 4: * ! 5: * A few routines used to handle printer resident fonts. They cause us ! 6: * some problems because there's no guaranteed way the post-processor ! 7: * can be sure what fonts are resident on a particular printer. It's ! 8: * certainly possible that two otherwise identical printers could ! 9: * support different resident fonts, and we need to be able to deal ! 10: * with that situation. The way I've decided to handle things is have ! 11: * the post-processor look for special files in *bitdir/RESIDENT as ! 12: * part of the startup procedure. If the file's found and can be ! 13: * read it's used to get all the required resident font data for ! 14: * the printer. If we can't read the control file we'll just assume ! 15: * there aren't any resident fonts. Usually the file we're looking for ! 16: * will have the same name as the target printer, although that can ! 17: * be changed by an option - so we can handle different sets of ! 18: * resident fonts. ! 19: * ! 20: * The control file is ASCII right now and names the resident fonts, ! 21: * the available sizes, family tables, and the member maps. All the ! 22: * required maps are read and immediately written to the output file. ! 23: * Everything else is saved in resdata[] and only used when needed. ! 24: * See the comments at the start of resfonts() for a more complete ! 25: * description of the file. ! 26: * ! 27: * The member maps and family tables come from Imagen, although not ! 28: * directly. I got the info for the lucida fonts by taking one of ! 29: * their programs (mkres) and forcing routine dump_data() to run. ! 30: * The output from mkres was then used to build the control file. ! 31: * You may have to do something similiar if you've got a new set ! 32: * of printer resident fonts. ! 33: * ! 34: * There are other problems, most caused by Imagen's resident fonts. ! 35: * The most annoying is the need to use member maps and family tables. ! 36: * As it turns out the available member codes aren't good enough to ! 37: * access all the required characters in a resident font. That means ! 38: * we can't just use map 0 and the character code available in the ! 39: * font files. Things sure would have been simpler if resident fonts ! 40: * were more logical. Actually I'm not convinced resident fonts are ! 41: * that great an idea. ! 42: * ! 43: */ ! 44: ! 45: ! 46: #include <stdio.h> ! 47: ! 48: #include "gen.h" /* definitions used by everyone */ ! 49: #include "ext.h" /* external variable declarations */ ! 50: #include "init.h" /* just used to get RESDIR */ ! 51: #include "rast.h" /* raster file definitions */ ! 52: #include "impcodes.h" /* Impress 2.0 opcodes */ ! 53: ! 54: ! 55: Resdata resdata[MAXRESIDENT]; /* used to manage resident fonts */ ! 56: int maxres = 0; /* entries so far in resdata[] */ ! 57: ! 58: ! 59: /* ! 60: * ! 61: * We'll want to add size list data for the resident fonts to the ! 62: * sizedata[] structure so mapsize() works properly. ! 63: * ! 64: */ ! 65: ! 66: ! 67: extern Sizedata sizedata[]; /* so we can add resident font sizes */ ! 68: extern int maxrast; ! 69: ! 70: ! 71: /*****************************************************************************/ ! 72: ! 73: ! 74: resfonts(tf) ! 75: ! 76: ! 77: FILE *tf; /* Impress commands go here */ ! 78: ! 79: ! 80: { ! 81: ! 82: ! 83: char name[60]; /* control file pathname */ ! 84: char cmd[20]; /* commands read from *name */ ! 85: int i; /* fill in resdata[i] next */ ! 86: int member; /* starting member for triple */ ! 87: int symbol; /* starting symbol */ ! 88: int count; /* members mapped by this triple */ ! 89: int j, n; /* used for a bunch of things */ ! 90: FILE *fp; ! 91: ! 92: ! 93: /* ! 94: * ! 95: * Resident fonts require some rather special attention. We'll need to ! 96: * keep track of all the resident font names and their associated ! 97: * family tables. In addition we'll need to download all the required ! 98: * member maps. All this stuff is expected to be in file *resfile ! 99: * which is located in *bitdir/RESIDENT. If the file can't be read ! 100: * we'll just assume there aren't any printer resident fonts. ! 101: * ! 102: * For now the control file is ASCII, even though there are more ! 103: * efficient ways of doing things. A decent alternative would be ! 104: * to have all the required Impress commands in the file. That ! 105: * way the file could just be copied directly to the output file. ! 106: * Member maps work nicely that way, but the family tables pose ! 107: * some problems because we've got to add the size to the font ! 108: * name string. Anyway there other choices and most any of them ! 109: * would cause the post-processor to run faster. ! 110: * ! 111: * For now the control file format looks something like, ! 112: * ! 113: * ! 114: * font <name1> ! 115: * sizes <size list> 0 ! 116: * families <n> ! 117: * <map1> <font1> ! 118: * . ! 119: * . ! 120: * . ! 121: * <mapn> <fontn> ! 122: * font <name2> ! 123: * . ! 124: * . ! 125: * . ! 126: * font <namen> ! 127: * map <mapname1> <n> ! 128: * <mem1> <symbol1> <count1> ! 129: * . ! 130: * . ! 131: * . ! 132: * <memn> <symboln> <countn> ! 133: * map <mapname2> <n> ! 134: * ! 135: * . ! 136: * . ! 137: * . ! 138: * ! 139: * map <mapnamen> <n> ! 140: * . ! 141: * . ! 142: * . ! 143: * (EOF) ! 144: * ! 145: * ! 146: * The <size list> data must be given in increasing order and terminated ! 147: * with a 0 entry. Comments can be put in the file, although I don't ! 148: * recommend it. They're lines that have '#' as the first non white ! 149: * space character. ! 150: * ! 151: * The font names and family tables are saved in resdata[], size info ! 152: * is added to sizedata[], and the member maps are immediately downloaded. ! 153: * ! 154: * I'm not responsible for the member maps or family tables. I got the ! 155: * ones for the lucida font by running Imagen's mkres program with the ! 156: * dump_data() routine working (just took a few ifdefs out). The output ! 157: * from that routine was used to build the ASCII control file. ! 158: * ! 159: */ ! 160: ! 161: ! 162: sprintf(name, "%s/%s/%s", bitdir, RESDIR, resfile); ! 163: if ( (fp = fopen(name, "r")) == NULL ) ! 164: return; ! 165: ! 166: i = maxres - 1; /* incremented when "font" is read */ ! 167: ! 168: while ( fscanf(fp, "%s", cmd) != EOF ) { ! 169: if ( strcmp(cmd, "font") == 0 ) ! 170: fscanf(fp, "%10s", resdata[++i].name); ! 171: else if ( strcmp(cmd, "sizes") == 0 ) { ! 172: strncpy(sizedata[maxrast].name, resdata[i].name, L_FNAME); ! 173: j = 0; ! 174: while ( fscanf(fp, "%d", &n) != EOF && n != 0 ) ! 175: sizedata[maxrast].sizes[j++] = n; ! 176: sizedata[maxrast].sizes[j] = 999; ! 177: if ( ++maxrast >= MAXFONTS ) ! 178: error(FATAL, "too many fonts in %s", name); ! 179: } else if ( strcmp(cmd, "families") == 0 ) { ! 180: fscanf(fp, "%d", &resdata[i].count); ! 181: for ( j = 0; j < resdata[i].count; j++ ) ! 182: fscanf(fp, "%d %10s", &resdata[i].table[j].map, resdata[i].table[j].name); ! 183: } else if ( strcmp(cmd, "map") == 0 ) { ! 184: fscanf(fp, "%d %d", &n, &j); ! 185: putc(ACM, tf); ! 186: putc(n, tf); ! 187: putc(j, tf); ! 188: for ( ; j > 0; j-- ) { ! 189: fscanf(fp, "%d %d %d", &member, &symbol, &count); ! 190: putc(member, tf); ! 191: putint(symbol, tf); ! 192: putc(count, tf); ! 193: } /* End for */ ! 194: } else if ( cmd[0] == '#' ) ! 195: while ( (n = getc(fp)) != EOF && n != '\n' ) ; ! 196: else error(FATAL, "bad command %s in file %s", cmd, name); ! 197: } /* End while */ ! 198: ! 199: maxres = i + 1; ! 200: ! 201: fclose(fp); ! 202: ! 203: } /* End of resfonts */ ! 204: ! 205: ! 206: /*****************************************************************************/ ! 207: ! 208: ! 209: isresident(name) ! 210: ! 211: ! 212: char *name; /* is this a printer resident font? */ ! 213: ! 214: ! 215: { ! 216: ! 217: ! 218: int i; /* check res_data[i] next */ ! 219: ! 220: ! 221: /* ! 222: * ! 223: * Returns TRUE if font *name is a resident font and FALSE otherwise. ! 224: * Resident fonts are those listed in resdata[] array, which is set up ! 225: * in routine resfonts() using file *bitdir/RESIDENT/resfile. ! 226: * ! 227: */ ! 228: ! 229: ! 230: for ( i = 0; i < maxres; i++ ) ! 231: if ( strncmp(name, resdata[i].name, L_FNAME) == 0 ) ! 232: return(TRUE); ! 233: ! 234: return(FALSE); ! 235: ! 236: } /* End of isresident */ ! 237: ! 238: ! 239: /*****************************************************************************/ ! 240: ! 241: ! 242: getresdata(f, s, tf) ! 243: ! 244: ! 245: char *f; /* name of the resident font */ ! 246: int s; /* in this point size */ ! 247: FILE *tf; /* job's output file */ ! 248: ! 249: ! 250: { ! 251: ! 252: ! 253: int i; /* loop index for setting famlies */ ! 254: ! 255: ! 256: /* ! 257: * ! 258: * Makes sure data about resident font *f in size s is added to the ! 259: * fam_data[] array. Essentially the same as routine getrastdata() ! 260: * except that the chused bitmap is set to all ones so download() ! 261: * will know the printer already has the glyph. Also don't need the ! 262: * advance stuff saved in fam_data[]. ! 263: * ! 264: */ ! 265: ! 266: ! 267: cur_fam = getfamdata(f, s); /* using this family next */ ! 268: fam = &fam_data[cur_fam]; ! 269: ! 270: if ( cur_fam >= next_fam ) { /* first use */ ! 271: if ( next_fam > MAXFAMILY ) /* can only use 0 to 95 */ ! 272: error(FATAL, "job uses too many font families"); ! 273: ! 274: strncpy(fam->name, f, L_FNAME); /* initialize the fields */ ! 275: fam->name[L_FNAME-1] = '\0'; ! 276: fam->size = s; ! 277: fam->rst = NULL; ! 278: fam->advance = NULL; ! 279: fam->glyphdir = NULL; ! 280: fam->first = 0; ! 281: fam->last = 128; ! 282: ! 283: for ( i = 0; i < 4; i++ ) { ! 284: fam->chused[i] = (unsigned char *) rastalloc((MAXMEMBER+BYTE)/BYTE, TRUE, 0377); ! 285: fam->fam[i] = -1; ! 286: } /* End for */ ! 287: ! 288: famtables(f, s, tf); /* use resdata[] to define families */ ! 289: ! 290: next_fam++; ! 291: } /* End if */ ! 292: ! 293: return(cur_fam); /* probably never used */ ! 294: ! 295: } /* End of getresdata */ ! 296: ! 297: ! 298: /*****************************************************************************/ ! 299: ! 300: ! 301: famtables(f, s, tf) ! 302: ! 303: ! 304: char *f; /* define tables for this font */ ! 305: int s; /* in this size */ ! 306: FILE *tf; /* commands written here */ ! 307: ! 308: ! 309: { ! 310: ! 311: ! 312: int i; /* fonts position in resdata[] */ ! 313: int j; /* next family pair */ ! 314: ! 315: ! 316: /* ! 317: * ! 318: * Defines the family tables for font *f in size s using the data that ! 319: * was read from the ASCII control file and saved in resdata[]. We'll ! 320: * have to look font f up in resdata[] before doing anything. Although ! 321: * that wastes time because it was just done in isresident() it shouldn't ! 322: * be all that expensive because the family tables aren't downloaded ! 323: * that often. There are easy ways to get around it if you want. ! 324: * ! 325: */ ! 326: ! 327: ! 328: for ( i = 0; i < maxres; i++ ) ! 329: if ( strncmp(f, resdata[i].name, L_FNAME) == 0 ) ! 330: break; ! 331: ! 332: if ( i >= maxres ) /* probably can't ever happen */ ! 333: error(FATAL, "can't ffind family data for font %s", f); ! 334: ! 335: putc(ACFT, tf); ! 336: putc(cur_fam, tf); ! 337: putc(resdata[i].count, tf); ! 338: ! 339: for ( j = 0; j < resdata[i].count; j++ ) { ! 340: putc(resdata[i].table[j].map, tf); ! 341: fprintf(tf, "%.10s%d", resdata[i].table[j].name, s); ! 342: putc('\0', tf); ! 343: } /* End for */ ! 344: ! 345: } /* End of famtables */ ! 346: ! 347: ! 348: /*****************************************************************************/ ! 349: ! 350:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.