|
|
1.1 ! root 1: /* ! 2: * fwtable.c ! 3: * 6/7/91 ! 4: * Usage: fwtable [ -cptv ] [ -ssymset ] [ infile [ outfile ] ] ! 5: * Read HP PCL bitmap font, PostScript AFM file, or HP TFM file ! 6: * from infile or stdin, write font width table to outfile or stdout. ! 7: * ! 8: * Requires floating point output, PostScript routines in fwt_PS.c, ! 9: * TFM routines in fwt_TFM.c: ! 10: * cc fwtable.c fwt_PS.c fwt_TFM.c -f ! 11: * ! 12: * Options: ! 13: * -c Write C instead of binary ! 14: * -p Input is PostScript AFM file ! 15: * -ssymset Specify desired symbol set with -t option ! 16: * -t Input is HP TFM file ! 17: * -v Write one-line font description to stderr ! 18: * ! 19: * Understands PCL bitmap fonts, PostScript AFM files, HP TFM files. ! 20: * Does not understand Intellifont scalable fonts. ! 21: * ! 22: * The following had better agree about the binary FWT format: ! 23: * troff/fwtable.c/dump_chartab() writes binary FWT from HP PCL ! 24: * troff/fwt_PS.c/outputPS() writes binary FWT from PostScript AFM ! 25: * troff/fwt_TFM.c/outputTFM() writes binary FWT from HP TFM ! 26: * troff/fonts.c/loadfont() reads binary FWT for troff ! 27: * ! 28: * Modified 12/12/90-12/28/90 by steve from dag's original hptable.c source; ! 29: * the coding could definitely be cleaner. ! 30: */ ! 31: ! 32: #include <stdio.h> ! 33: #include <canon.h> ! 34: #include "fwtable.h" ! 35: ! 36: /* PCL bitmap font descriptor format. Cf. "HP LJ III Tech Ref Man", p. 10-7. */ ! 37: typedef struct fnt_hdr { ! 38: short f_hsize; ! 39: uchar f_desc_format; ! 40: uchar f_font_type; ! 41: uchar f_style_msb; ! 42: uchar f_reserved1; ! 43: short f_baseline; ! 44: short f_cell_width; ! 45: short f_cell_height; ! 46: uchar f_orientation; ! 47: uchar f_spacing; ! 48: short f_symbol_set; ! 49: short f_pitch; ! 50: short f_height; ! 51: short f_xheight; ! 52: uchar f_width_type; ! 53: uchar f_style; ! 54: char f_weight; /* specifically signed! */ ! 55: uchar f_face; ! 56: uchar f_comment[0]; /* remainder in add_info */ ! 57: } font_header; ! 58: ! 59: typedef struct add_info { ! 60: char a_slant; /* Slant information */ ! 61: uchar a_serif; /* Serif style (see serif table) */ ! 62: uchar a_quality; /* Quality level */ ! 63: uchar a_placement; /* Placement */ ! 64: char a_underline; /* Underline position */ ! 65: uchar a_uheight; /* Underline height in dots */ ! 66: short a_lspacing; /* Optimum line spacing in dots * 4 */ ! 67: short a_nwidth; /* Average lower-case char width * 4 */ ! 68: short a_firstc; /* First code */ ! 69: short a_lastc; /* Last code */ ! 70: uchar a_piextend; /* Extend for pitch */ ! 71: uchar a_poextend; /* Extend for height */ ! 72: short a_cap_height; /* Cap height */ ! 73: long a_fontnum; /* Font Number */ ! 74: char a_fontname[16]; /* Font name */ ! 75: } font_extra; ! 76: ! 77: typedef struct chr_hdr { ! 78: uchar c_format; /* Character format (4) */ ! 79: uchar c_continuation; /* Continuation flag */ ! 80: uchar c_size; /* Header size to follow*/ ! 81: uchar c_class; /* Format class 1=raster*/ ! 82: uchar c_orientation; /* Orientation */ ! 83: uchar c_empty2; /* more padding... */ ! 84: short c_left_offset; /* left offset */ ! 85: short c_top_offset; /* top offset */ ! 86: short c_char_width; /* character width */ ! 87: short c_char_height; /* character height */ ! 88: short c_delta_x; /* delta X */ ! 89: uchar c_data[0]; /* character data */ ! 90: } character_header; ! 91: character_header *char_def(); ! 92: ! 93: /* Global arrays. */ ! 94: /* ! 95: * Typefaces. ! 96: * Cf. "HP LJ III Tech Ref Man", pp. 10-27ff. ! 97: * The list given there gives all values 0-84 and some values 87-168. ! 98: * This list is truncated in the name of sanity. ! 99: */ ! 100: char *faces[] = { ! 101: "LinePrinter", /* 0 */ ! 102: "Pica", /* 1 */ ! 103: "Elite", /* 2 */ ! 104: "Courier", /* 3 */ ! 105: "Helvetica", /* 4 */ ! 106: "Times", /* 5 */ ! 107: "LetterGothic", /* 6 */ ! 108: "Script", /* 7 */ ! 109: "Prestige", /* 8 */ ! 110: "Caslon", /* 9 */ ! 111: "Orator", /* 10 */ ! 112: "Presentation", /* 11 */ ! 113: "HelveticaCondensed", /* 12 */ ! 114: "Serifa", /* 13 */ ! 115: "Futura", /* 14 */ ! 116: "Palatino", /* 15 */ ! 117: "ITCSouvenir", /* 16 */ ! 118: "Optima", /* 17 */ ! 119: "ITCGaramond", /* 18 */ ! 120: "CooperBlack", /* 19 */ ! 121: "Coronet", /* 20 */ ! 122: "Broadway", /* 21 */ ! 123: "BauerBodoniBlack", /* 22 */ ! 124: "NewCenturySchlbk", /* 23 */ ! 125: " " /* >23 */ ! 126: }; ! 127: #define NFACES ((sizeof faces / sizeof faces[0]) - 1) ! 128: ! 129: /* f_serif values */ ! 130: char *serif_tab[] = { ! 131: "sans serif square", /* 0 */ ! 132: "sans serif round", /* 1 */ ! 133: "serif line", /* 2 */ ! 134: "serif triangle", /* 3 */ ! 135: "serif swath", /* 4 */ ! 136: "serif block", /* 5 */ ! 137: "serif bracket", /* 6 */ ! 138: "rounded bracket", /* 7 */ ! 139: "flair serif", /* 8 */ ! 140: "script nonconnecting", /* 9 */ ! 141: "script joining", /* 10 */ ! 142: "script calligraphic", /* 11 */ ! 143: "script broken letter", /* 12 */ ! 144: "serif value out-of-range" /* >12 */ ! 145: }; ! 146: #define NSERIFS ((sizeof serif_tab / sizeof serif_tab[0]) - 1) ! 147: ! 148: /* Style posture values. The width and structure info is ignored for now. */ ! 149: char *posture_tab[] = { ! 150: "upright", /* 0 */ ! 151: "italic", /* 1 */ ! 152: "alternate italic", /* 2 */ ! 153: "reserved" /* 3 */ ! 154: }; ! 155: ! 156: /* Orientation. */ ! 157: char *orient_tab[] = { ! 158: "portrait", /* 0 */ ! 159: "landscape", /* 1 */ ! 160: "reverse portrait", /* 2 */ ! 161: "reverse landscape" /* 3 */ ! 162: }; ! 163: ! 164: /* Globals. */ ! 165: char buf[NBUF]; /* String conversion */ ! 166: int cflag; /* Write C not binary */ ! 167: int char_datasize[NWIDTH]; /* Character size */ ! 168: int char_movement[NWIDTH]; /* Character movement */ ! 169: font_header *fhp; /* Font header pointer */ ! 170: FILE *ifp = stdin; /* The input FILE */ ! 171: int ipointsz; /* Integer point size */ ! 172: FILE *ofp = stdout; /* The output FILE */ ! 173: int pflag; /* PostScript input */ ! 174: char *symset; /* Desired symbol set */ ! 175: int tflag; /* TFM input */ ! 176: int this_char; /* Current character */ ! 177: int vflag; /* Verbose */ ! 178: ! 179: main(argc, argv) int argc; char *argv[]; ! 180: { ! 181: register char *s; ! 182: ! 183: /* Process command-line options. */ ! 184: while (argc > 1 && argv[1][0] == '-') { ! 185: for (s = &argv[1][1]; *s; s++) { ! 186: switch(*s) { ! 187: case 'c': ! 188: ++cflag; ! 189: break; ! 190: case 'p': ! 191: ++pflag; ! 192: break; ! 193: case 's': ! 194: symset = ++s; ! 195: while (*s) ! 196: ++s; ! 197: --s; ! 198: break; ! 199: case 't': ! 200: ++tflag; ! 201: break; ! 202: case 'v': ! 203: ++vflag; ! 204: break; ! 205: case 'V': ! 206: fprintf(stderr, "fwtable: V%s\n", VERSION); ! 207: break; ! 208: default: ! 209: usage(); ! 210: } ! 211: } ! 212: --argc; ! 213: ++argv; ! 214: } ! 215: if (pflag && tflag) ! 216: fatal("options -p and -t are mutually exclusive"); ! 217: if (symset != NULL && !tflag) ! 218: fatal("-s option requires -t option"); ! 219: ! 220: /* Set up input and output FILEs. */ ! 221: if (argc > 1 && (ifp = fopen(argv[1], "rb")) == NULL) ! 222: fatal("cannot open input file \"%s\"", argv[1]); ! 223: else if (argc > 2 && (ofp = fopen(argv[2], "w")) == NULL) ! 224: fatal("cannot open output file \"%s\"", argv[2]); ! 225: else if (argc > 3) ! 226: usage(); ! 227: ! 228: /* Do the work. */ ! 229: if (pflag) { ! 230: /* PostScript. */ ! 231: inputPS(); ! 232: outputPS(); ! 233: } else if (tflag) { ! 234: /* TFM. */ ! 235: inputTFM(); ! 236: outputTFM(); ! 237: } else { ! 238: /* PCL. */ ! 239: if (argc > 1 && cflag) ! 240: fprintf(ofp,"/* File %s */\n", argv[1]); ! 241: base(); ! 242: } ! 243: ! 244: /* Close FILEs and exit. */ ! 245: if (ifp != stdin && fclose(ifp) == EOF) ! 246: fatal("cannot close input file \"%s\"", argv[1]); ! 247: else if (ofp != stdout && fclose(ofp) == EOF) ! 248: fatal("cannot close output file \"%s\"", argv[2]); ! 249: exit(0); ! 250: } ! 251: ! 252: /* ! 253: * Allocate size bytes. ! 254: */ ! 255: char * ! 256: alloc(size) register unsigned int size; ! 257: { ! 258: register char *s; ! 259: ! 260: if ((s = malloc(size)) == NULL) ! 261: fatal("out of space"); ! 262: return s; ! 263: } ! 264: ! 265: void ! 266: base() ! 267: { ! 268: register int c; ! 269: ! 270: /* Initialize. */ ! 271: for (c = 0 ; c < NWIDTH; c++) { ! 272: char_movement[c] = -1; ! 273: char_datasize[c] = 0; ! 274: } ! 275: ! 276: /* Read the font description. */ ! 277: while ((c = fgetc(ifp)) != EOF) { ! 278: if (c == '\033') ! 279: escape(); ! 280: else ! 281: if (c) ! 282: nonfatal("unexpected char (0x%02x)", c); ! 283: } ! 284: ! 285: /* Dump character table. */ ! 286: dump_chartab(); ! 287: if (fhp != NULL) ! 288: free(fhp); ! 289: } ! 290: ! 291: int ! 292: char_code(code) int code; ! 293: { ! 294: #ifdef VERBOSE ! 295: if (cflag) ! 296: fprintf(ofp,"Character Code 0x%02x\n", code); ! 297: #endif ! 298: this_char = code; ! 299: return code; ! 300: } ! 301: ! 302: character_header * ! 303: char_def(size) int size; ! 304: { ! 305: register character_header *ch; ! 306: ! 307: ch = alloc(size); ! 308: ch->c_format = getuchar(); ! 309: ch->c_continuation = getuchar(); ! 310: ch->c_size = getuchar(); ! 311: ch->c_class = getuchar(); ! 312: ch->c_orientation = getuchar(); ! 313: ch->c_empty2 = getuchar(); ! 314: ch->c_left_offset = getshort(); ! 315: ch->c_top_offset = getshort(); ! 316: ch->c_char_width = getshort(); ! 317: ch->c_char_height = getshort(); ! 318: ch->c_delta_x = getshort(); ! 319: if (size > 16) ! 320: getextra(ch->c_data, size-16); ! 321: return ch; ! 322: } ! 323: ! 324: /* ! 325: * Dump the character width table. ! 326: */ ! 327: void ! 328: dump_chartab() ! 329: { ! 330: register int c, first, last, max, w; ! 331: register long dsize; ! 332: int mult, div, scale; ! 333: ! 334: /* Find first, last, max values in char_movement[]. */ ! 335: for (c = first = last = max = 0; c < NWIDTH; c++) { ! 336: if (char_movement[c] >= 0) { ! 337: if (first == 0) ! 338: first = c; ! 339: if (max < char_movement[c]) ! 340: max = char_movement[c]; ! 341: last = c; ! 342: } else ! 343: char_movement[c] = 0; ! 344: } ! 345: ! 346: /* ! 347: * Calculate multiplier and divisor to convert entries to troff units. ! 348: * Character deltax is in quarter dots, so movement in troff units is ! 349: * deltax * 720 / 1200. ! 350: * and 720/1200 == 3/5. ! 351: * troff multiplies by pointsize, this predivides accordingly; ! 352: * this simplifies scaling. ! 353: */ ! 354: mult = 3; ! 355: div = ipointsz * 5; ! 356: if (max > 255) { ! 357: /* Max deltax is too big to fit in char, scale accordingly. */ ! 358: scale = (max / 256) + 1; ! 359: mult *= scale; ! 360: for (c = 0; c < NWIDTH; c++) ! 361: if (char_movement[c] > 0) ! 362: char_movement[c] /= scale; ! 363: } ! 364: /* Reduce if possible. */ ! 365: for (w = mult; w > 1; w--) { ! 366: if ((mult % w) == 0 && (div % w) == 0) { ! 367: div /= w; ! 368: mult /= w; ! 369: } ! 370: } ! 371: putshort(mult); /* short f_num */ ! 372: putshort(div); /* short f_den */ ! 373: ! 374: /* Dump the movement table. */ ! 375: if (cflag) { ! 376: fprintf(ofp,"\t\t/* Movement table: first = %d, last = %d */\n", ! 377: first, last); ! 378: fprintf(ofp,"\t\t{\n"); ! 379: } ! 380: dsize = 0L; ! 381: for (w = c = 0; c < NWIDTH; c++) { ! 382: dsize += char_datasize[c]; ! 383: if (cflag) { ! 384: if (w == 0) ! 385: fprintf(ofp,"\t\t\t"); ! 386: fprintf(ofp,"%3d", char_movement[c]); ! 387: fputc((c < NWIDTH-1) ? ',' : ' ', ofp); ! 388: if (++w > 7) { ! 389: w = 0; ! 390: fprintf(ofp,"\t/* 0x%02x-0x%02x */\n", c-7, c); ! 391: } ! 392: } else ! 393: fputc(char_movement[c], ofp); ! 394: } ! 395: if (cflag) { ! 396: fprintf(ofp,"\t\t}\n"); ! 397: fprintf(ofp,"\t/* Size of font data (in bytes): %ld */\n", dsize); ! 398: fprintf(ofp,"\t}\n"); ! 399: } ! 400: } ! 401: ! 402: #ifdef VERBOSE ! 403: #ifdef GLYPH ! 404: void ! 405: dump_glyph(width, height, data) register uchar *data; ! 406: { ! 407: register int c, d, f, g; ! 408: ! 409: width += 7; ! 410: width >>= 3; ! 411: fprintf(ofp,"-----------------------------------\n"); ! 412: for (c=0; c<height; c++) { ! 413: for (d=0; d<width; d++) { ! 414: f = *data++; ! 415: for (g = 0; g < 8; g++) { ! 416: if (f & 0x80) ! 417: fprintf(ofp,"*"); ! 418: else ! 419: fprintf(ofp,"."); ! 420: f <<= 1; ! 421: } ! 422: } ! 423: fprintf(ofp,"\n"); ! 424: } ! 425: fprintf(ofp,"-----------------------------------\n"); ! 426: } ! 427: #endif ! 428: #endif ! 429: ! 430: /* ! 431: * Process an escape sequence. ! 432: * The <Esc> has already been read. ! 433: */ ! 434: void ! 435: escape() ! 436: { ! 437: register int c; ! 438: ! 439: c = getuchar(); ! 440: switch (c) { ! 441: case '*': escape_star(); ! 442: break; ! 443: case '(': escape_oparen(); ! 444: break; ! 445: case ')': escape_cparen(); ! 446: break; ! 447: default: nonfatal("unknown escape sequence (0x1B 0x%02x ...)", c); ! 448: break; ! 449: } ! 450: } ! 451: ! 452: /* ! 453: * Process a font defintition: ! 454: * <Esc> ) s <#> W <font header> ! 455: */ ! 456: void ! 457: escape_cparen() ! 458: { ! 459: register int c, q; ! 460: register font_extra *fe; ! 461: char *cp; ! 462: double pointsz; ! 463: ! 464: if ((c = getuchar()) != 's') { ! 465: nonfatal("unknown sequence \\033)%c", c); ! 466: return; ! 467: } ! 468: q = getparm(); ! 469: if ((c = getuchar()) != 'W') { ! 470: nonfatal("unknown sequence \\033)s%d%c", q, c); ! 471: return; ! 472: } ! 473: read_header(q); ! 474: /* pointsz is height*72/1200, 72/1200 == 3/50 */ ! 475: pointsz = ((double)(3.0*fhp->f_height))/50.0; ! 476: if (cflag) { ! 477: fprintf(ofp, "/*\n * Font Definition:\n"); ! 478: fprintf(ofp, " * Header size: %d\n", fhp->f_hsize); ! 479: fprintf(ofp, " * %s bits\n", ((fhp->f_font_type) ? "Eight" : "Seven")); ! 480: fprintf(ofp, " * Orientation: %s\n", orient_tab[fhp->f_orientation]); ! 481: fprintf(ofp, " * Spacing: %s\n", ((fhp->f_spacing) ? "variable" : "fixed")); ! 482: fprintf(ofp, " * Baseline: %d\n", fhp->f_baseline); ! 483: fprintf(ofp, " * Cell width: %d\n", fhp->f_cell_width); ! 484: fprintf(ofp, " * Cell height: %d\n", fhp->f_cell_height); ! 485: fprintf(ofp, " * Pitch: %d\n", fhp->f_pitch); ! 486: fprintf(ofp, " * Height: %d\n", fhp->f_height); ! 487: fprintf(ofp, " * Weight: %d\n", fhp->f_weight); ! 488: fprintf(ofp, " * Style: %s\n", posture_tab[(fhp->f_style)%4]); ! 489: fprintf(ofp, " * Typeface: %s\n", faces[fhp->f_face]); ! 490: fprintf(ofp, " * Designator: %d%c\n", ! 491: fhp->f_symbol_set / 32, ! 492: fhp->f_symbol_set % 32 + 64); ! 493: } ! 494: if (fhp->f_hsize > 26) { ! 495: fe = fhp->f_comment; ! 496: pointsz += ((double) fe->a_poextend)/4275.0; ! 497: if (fe->a_serif > NSERIFS) ! 498: fe->a_serif = NSERIFS; ! 499: if (cflag) { ! 500: fprintf(ofp, " * Slant: %d\n", fe->a_slant); ! 501: fprintf(ofp, " * %s\n", serif_tab[fe->a_serif]); ! 502: fprintf(ofp, " * Quality: %d\n", fe->a_quality); ! 503: fprintf(ofp, " * First: 0x%02x\n", fe->a_firstc); ! 504: fprintf(ofp, " * Last: 0x%02x\n", fe->a_lastc); ! 505: fprintf(ofp, " * Underline pos: %d\n", fe->a_underline); ! 506: fprintf(ofp, " * Height: %d\n", fe->a_uheight); ! 507: fprintf(ofp, " * Line spacing: %u\n", fe->a_lspacing); ! 508: fprintf(ofp, " * Nominal width: %u\n", fe->a_nwidth); ! 509: fprintf(ofp, " * Pitch extend: %d\n", fe->a_piextend); ! 510: fprintf(ofp, " * Height extend: %d\n", fe->a_poextend); ! 511: fprintf(ofp, " * Font number: %ld\n", fe->a_fontnum); ! 512: fprintf(ofp, " * Font name: %16s\n", fe->a_fontname); ! 513: } ! 514: } ! 515: if (cflag && q > fhp->f_hsize) { ! 516: register uchar *sp, *ep; ! 517: register int c; ! 518: ! 519: c = 0; ! 520: sp = (char *)fhp; ! 521: ep = sp + q; ! 522: sp += fhp->f_hsize; ! 523: while (sp < ep) { ! 524: if (c == 0) ! 525: fprintf(ofp," # "); ! 526: if (*sp >= 0x20 && *sp < 0x7F) ! 527: fprintf(ofp,"%c", *sp++); ! 528: else { ! 529: fprintf(ofp,"\\x%02x", *sp++); ! 530: c += 3; ! 531: } ! 532: if (++c > 72) { ! 533: c = 0; ! 534: fprintf(ofp," #\n"); ! 535: } ! 536: } ! 537: } ! 538: ipointsz = (int)(pointsz*10+.5); /* integer pointsize */ ! 539: if (cflag) ! 540: fprintf(ofp,"\n */\n"); ! 541: ! 542: /* Build a descriptive name. */ ! 543: sprintf(buf, "%s %.2f point ", faces[fhp->f_face], pointsz); ! 544: cp = &buf[strlen(buf)]; ! 545: if (fhp->f_weight == 3) ! 546: strcpy(cp, "bold "); ! 547: else if (fhp->f_weight != 0) ! 548: sprintf(cp, "%d weight ", fhp->f_weight); ! 549: cp = &buf[strlen(buf)]; ! 550: if (fhp->f_style%4 != 0) ! 551: sprintf(cp, "%s ", posture_tab[(fhp->f_style)%4]); ! 552: if (fhp->f_orientation != 0) ! 553: strcat(cp, orient_tab[fhp->f_orientation]); ! 554: if (vflag) ! 555: fprintf(stderr,"\t%s\n", buf); ! 556: if (cflag) ! 557: fprintf(ofp, "\t{\n\t\t\"%s\",\n", buf); ! 558: else ! 559: putstring(buf); /* char *f_descr */ ! 560: ! 561: if (cflag) ! 562: fprintf(ofp, "\t\t\"\",\t/* PostScript name */\n"); ! 563: else ! 564: putstring(""); /* char *f_PSname */ ! 565: ! 566: /* Font parameters. */ ! 567: putshort(FLAG_PCL); /* flags */ ! 568: putshort(fhp->f_font_type); ! 569: putshort(fhp->f_orientation); ! 570: putshort(fhp->f_spacing); ! 571: putshort(fhp->f_symbol_set); ! 572: putshort(fhp->f_pitch); ! 573: putshort(ipointsz); ! 574: putshort(fhp->f_style); ! 575: putshort(fhp->f_weight); ! 576: putshort(fhp->f_face); ! 577: } ! 578: ! 579: /* ! 580: * Process a character definition: ! 581: * <Esc> ( s <#> W <char data> ! 582: */ ! 583: void ! 584: escape_oparen() ! 585: { ! 586: register int c; ! 587: register int q; ! 588: register character_header *ch; ! 589: ! 590: if ((c = getuchar()) != 's') { ! 591: nonfatal("unknown sequence \\033(%c", c); ! 592: return; ! 593: } ! 594: q = getparm(); ! 595: if ((c = getuchar()) != 'W') { ! 596: nonfatal("unknown sequence \\033(s%d%c", q, c); ! 597: return; ! 598: } ! 599: ch = char_def(q); ! 600: ! 601: #ifdef VERBOSE ! 602: fprintf(ofp,"** %s, left off=%d, top off=%d char width=%d, char height=%d\n", ! 603: orient_tab[ch->c_orientation], ! 604: ch->c_left_offset, ch->c_top_offset, ! 605: ch->c_char_width, ch->c_char_height); ! 606: fprintf(ofp,"** movement=%d (%d), data length = %d\n", ! 607: ch->c_delta_x, ch->c_delta_x/4, q-16); ! 608: #ifdef GLYPH ! 609: dump_glyph(ch->c_char_width, ch->c_char_height, ch->c_data); ! 610: #endif ! 611: #endif ! 612: char_movement[this_char] = ch->c_delta_x; ! 613: char_datasize[this_char] = q-16; ! 614: ! 615: free(ch); ! 616: } ! 617: ! 618: /* ! 619: * Process a font id: ! 620: * <Esc> * c <#> D ! 621: * or a character code: ! 622: * <Esc> * c <#> E ! 623: */ ! 624: void ! 625: escape_star() ! 626: { ! 627: register int c, q; ! 628: ! 629: c = getuchar(); ! 630: if (c != 'c') { ! 631: nonfatal("unknown escape sequence (0x1B 0x%02x 0x%02x ...)", ! 632: '*', c); ! 633: return; ! 634: } ! 635: q = getparm(); ! 636: c = getuchar(); ! 637: if (c == 'D') ! 638: nonfatal("Font ID %d", q); ! 639: else if (c == 'E') ! 640: char_code(q); ! 641: else ! 642: nonfatal("unknown sequence \\033*c%d%c", q, c); ! 643: } ! 644: ! 645: /* VARARGS */ ! 646: void ! 647: fatal(args) char *args; ! 648: { ! 649: fprintf(stderr, "fwtable: "); ! 650: if (lineno != 0) ! 651: fprintf(stderr, "%d: ", lineno); ! 652: fprintf(stderr, "%r\n", &args); ! 653: exit(1); ! 654: } ! 655: ! 656: /* ! 657: * Read size bytes into the supplied buffer. ! 658: */ ! 659: void ! 660: getextra(bp, size) register uchar *bp; register int size; ! 661: { ! 662: while (size-- > 0) ! 663: *bp++ = getuchar(); ! 664: } ! 665: ! 666: /* ! 667: * Read a numeric parameter and return it. ! 668: */ ! 669: int ! 670: getparm() ! 671: { ! 672: register int a, c; ! 673: ! 674: for (a = 0; (c = getuchar()) >= '0' && c <= '9'; ) { ! 675: a *= 10; ! 676: a += c - '0'; ! 677: } ! 678: ungetc(c, ifp); ! 679: return a; ! 680: } ! 681: ! 682: /* ! 683: * Read a short and return it. ! 684: * The byte order is the opposite of the in-memory i8086 order. ! 685: */ ! 686: short ! 687: getshort() ! 688: { ! 689: register int s; ! 690: ! 691: s = getuchar() << 8; ! 692: return s | getuchar(); ! 693: } ! 694: ! 695: /* ! 696: * Read an unsigned char and return it. ! 697: */ ! 698: unsigned int ! 699: getuchar() ! 700: { ! 701: register int c; ! 702: ! 703: if ((c = fgetc(ifp)) == EOF) ! 704: fatal("unexpected end of file"); ! 705: return (c & 0xFF); ! 706: } ! 707: ! 708: /* VARARGS */ ! 709: void ! 710: nonfatal(args) char *args; ! 711: { ! 712: fprintf(stderr, "fwtable: %ld: %r\n", ftell(ifp), &args); ! 713: } ! 714: ! 715: /* ! 716: * Write count bytes from buf. ! 717: */ ! 718: void ! 719: ofpwrite(buf, count) register char *buf; register unsigned int count; ! 720: { ! 721: if (fwrite(buf, count, 1, ofp) != 1) ! 722: fatal("write error"); ! 723: } ! 724: ! 725: /* ! 726: * Write a canonical short. ! 727: */ ! 728: void ! 729: putshort(i) int i; ! 730: { ! 731: short s; ! 732: ! 733: if (cflag) ! 734: fprintf(ofp, "\t\t%d,\n", i); ! 735: else { ! 736: s = (short)i; ! 737: canshort(s); ! 738: ofpwrite(&s, sizeof s); ! 739: } ! 740: } ! 741: ! 742: /* ! 743: * Write a NUL-terminated string. ! 744: */ ! 745: void ! 746: putstring(s) register char *s; ! 747: { ! 748: fputs(s, ofp); ! 749: fputc('\0', ofp); ! 750: } ! 751: ! 752: /* ! 753: * Read a PCL font header. ! 754: */ ! 755: void ! 756: read_header(size) register int size; ! 757: { ! 758: register int c; ! 759: ! 760: if (fhp != NULL) ! 761: fatal("multiple font headers"); ! 762: fhp = alloc(size); ! 763: fhp->f_hsize = getshort(); ! 764: fhp->f_desc_format = getuchar(); ! 765: if (fhp->f_desc_format == 10) ! 766: fatal("Intellifont scalable fonts not yet supported"); ! 767: fhp->f_font_type = getuchar(); ! 768: fhp->f_style_msb = getuchar(); ! 769: fhp->f_reserved1 = getuchar(); ! 770: fhp->f_baseline = getshort(); ! 771: fhp->f_cell_width = getshort(); ! 772: fhp->f_cell_height = getshort(); ! 773: fhp->f_orientation = getuchar(); ! 774: fhp->f_spacing = getuchar(); ! 775: fhp->f_symbol_set = getshort(); ! 776: fhp->f_pitch = getshort(); ! 777: fhp->f_height = getshort(); ! 778: fhp->f_xheight = getshort(); ! 779: fhp->f_width_type = getuchar(); ! 780: fhp->f_style = getuchar(); ! 781: fhp->f_weight = getuchar(); ! 782: fhp->f_face = getuchar(); ! 783: if (fhp->f_face > NFACES) { ! 784: /* Use extra entry at end of table. */ ! 785: sprintf(faces[NFACES], "[Typeface %3d]", fhp->f_face); ! 786: fhp->f_face = NFACES; ! 787: } ! 788: if (size > 26) ! 789: getextra(fhp->f_comment, size-26); ! 790: /* ! 791: * Many of the fonts at MWC have a bogus extra ' ' after the font header. ! 792: * Eat the space silently rather than complaining about unexpected char. ! 793: */ ! 794: if ((c = fgetc(ifp)) != ' ') ! 795: ungetc(c, ifp); ! 796: } ! 797: ! 798: void ! 799: usage() ! 800: { ! 801: fprintf(stderr, ! 802: "Usage: fwtable [ -cptv ] [ -ssymset ] [ infile [ outfile ] ]\n" ! 803: "Options:\n" ! 804: "\t-c\t\tWrite C instead of binary\n" ! 805: "\t-p\t\tInput is PostScript AFM file\n" ! 806: "\t-ssymset\tSpecify desired symbol set with -t option\n" ! 807: "\t-t\t\tInput is HP TFM file\n" ! 808: "\t-v\t\tWrite one-line font description to stderr\n" ! 809: ); ! 810: exit(1); ! 811: } ! 812: ! 813: /* end of fwtable.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.