Annotation of coherent/d/bin/nroff/fwtable.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.