Annotation of coherent/b/bin/troff/fwt_PS.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * fwt_PS.c
                      3:  * 6/7/91
                      4:  * Build troff font width table from PostScript AFM file.
                      5:  * Reference: "Adobe Font Metric Files Specification Version 3.0", 3/8/90.
                      6:  */
                      7: 
                      8: #include <stdio.h>
                      9: #include <canon.h>
                     10: #include <ctype.h>
                     11: #include <stdlib.h>
                     12: #include <string.h>
                     13: #include "fwtable.h"
                     14: 
                     15: /*
                     16:  * Recognized keywords.
                     17:  * Most of the AFM file is ignored, recognized keys are listed here.
                     18:  */
                     19: #define        OTHER           0               /* anything other than listed below */
                     20: #define        COMMENT         1
                     21: #define        ENDCHAR         2
                     22: #define        ENDFONT         3
                     23: #define        FONTNAME        4
                     24: #define        FULLNAME        5
                     25: #define        STARTCHAR       6
                     26: #define        STARTFONT       7
                     27: #define        WEIGHT          8
                     28: typedef        struct  key {
                     29:        char    *key_name;
                     30:        int     key_val;
                     31:        size_t  key_len;
                     32: } KEY;
                     33: KEY    keys[] = {
                     34:        "Comment",              COMMENT,         7,
                     35:        "EndCharMetrics",       ENDCHAR,        14,
                     36:        "EndFontMetrics",       ENDFONT,        14,
                     37:        "FontName",             FONTNAME,        8,
                     38:        "FullName",             FULLNAME,        8,
                     39:        "StartCharMetrics",     STARTCHAR,      16,
                     40:        "StartFontMetrics",     STARTFONT,      16,
                     41:        "Weight",               WEIGHT,          6
                     42: };
                     43: #define        NKEYS   (sizeof keys/sizeof (struct key))
                     44: 
                     45: /* Globals. */
                     46: char   *bufp;                          /* buffer pointer               */
                     47: int    chartab[NWIDTH];                /* character movement table     */
                     48: char   *FontName;                      /* AFM FontName                 */
                     49: char   *FullName;                      /* AFM FullName                 */
                     50: int    lineno;                         /* input line number            */
                     51: int    maxwidth;                       /* maximum character movement   */
                     52: char   *Weight;                        /* AFM Weight                   */
                     53: 
                     54: /*
                     55:  * Process an AFM file character metric line
                     56:  * and store the character width in the width table.
                     57:  * Very ad hoc.
                     58:  * Understands only "C", "CH", "W", "WX"; everything else is ignored.
                     59:  * Should probably understand "WX0" as well.
                     60:  */
                     61: void
                     62: character()
                     63: {
                     64:        register char *s, *next;
                     65:        int code, width, base;
                     66: 
                     67:        code = -2;                      /* -1 to 255 are legal */
                     68:        width = -1;
                     69:        for (s = buf; s != NULL; s = next) {
                     70:                if ((next = strchr(s, ';')) != NULL)
                     71:                        *next++ = '\0';
                     72:                while(isspace(*s))
                     73:                        s++;
                     74:                if (*s == 'C') {
                     75:                        ++s;
                     76:                        if (*s == 'H') {
                     77:                                ++s;
                     78:                                base = 16;
                     79:                        } else
                     80:                                base = 10;
                     81:                        code = (int)strtol(s, NULL, base);
                     82:                        if (code < -1 || code >= NWIDTH)
                     83:                                fatal("illegal character code %d\n", code);
                     84:                } else if (*s == 'W' && isspace(*(s+1)))
                     85:                        width = atoi(s+2);
                     86:                else if (*s == 'W' && *(s+1) == 'X')
                     87:                        width = atoi(s+2);
                     88:        }
                     89:        if (code == -2)
                     90:                fatal("missing character code");
                     91:        if (width == -1)
                     92:                fatal("missing character width");
                     93:        if (code != -1) {
                     94:                chartab[code] = width;
                     95:                if (width > maxwidth)
                     96:                        maxwidth = width;
                     97:        }
                     98: }
                     99: 
                    100: /*
                    101:  * Process the AFM file character metrics section.
                    102:  */
                    103: void
                    104: charmetrics()
                    105: {
                    106:        register int cmsize, nchars;
                    107: 
                    108:        cmsize = atoi(bufp);            /* number of chars to expect */
                    109:        nchars = 0;                     /* number of chars seen so far */
                    110:        while (fgets(buf, sizeof buf, ifp) != NULL) {
                    111:                ++lineno;
                    112:                switch(lookup()) {
                    113:                case COMMENT:
                    114:                        continue;
                    115:                case ENDCHAR:
                    116:                        if (nchars != cmsize)
                    117:                                nonfatal("warning: %d chars in character metrics section, expected %d\n",
                    118:                                        nchars, cmsize);
                    119:                                return;
                    120:                default:
                    121:                        ++nchars;
                    122:                        character();
                    123:                        break;
                    124:                }
                    125:        }
                    126:        fatal("missing EndCharMetrics");
                    127: }
                    128: 
                    129: /*
                    130:  * Process AFM input file.
                    131:  * Most of the specifications are ignored.
                    132:  */
                    133: void
                    134: inputPS()
                    135: {
                    136:        register int n, flag;
                    137: 
                    138:        for (flag = 1; fgets(buf, sizeof buf, ifp) != NULL; ) {
                    139:                ++lineno;
                    140:                if ((n = lookup()) == COMMENT)
                    141:                        continue;
                    142:                else if (flag) {
                    143:                        if (n != STARTFONT)
                    144:                                fatal("not an AFM file (no StartFontMetrics)");
                    145:                        flag = 0;
                    146:                        continue;
                    147:                }
                    148:                switch(n = lookup()) {
                    149:                case OTHER:     /* ignored... */                        break;
                    150:                case ENDCHAR:   fatal("unexpected EndCharMetrics");     break;
                    151:                case ENDFONT:   return;
                    152:                case FONTNAME:  FontName = newstring(bufp);             break;
                    153:                case FULLNAME:  FullName = newstring(bufp);             break;
                    154:                case STARTCHAR: charmetrics();                          break;
                    155:                case STARTFONT: fatal("unexpected StartFontMetrics");   break;
                    156:                case WEIGHT:    Weight = newstring(bufp);               break;
                    157:                default:        fatal("lookup botch %d", n);            break;
                    158:                }
                    159:        }
                    160: }
                    161: 
                    162: /*
                    163:  * See if the line in buf[] starts with a recognized keyword.
                    164:  * If so, set bufp to point past it and return its key_val.
                    165:  * If not, return OTHER.
                    166:  * This does not skip leading whitespace in the line,
                    167:  * if whitespace is legal then it should.
                    168:  */
                    169: int
                    170: lookup()
                    171: {
                    172:        register KEY *kp;
                    173:        register size_t n;
                    174:        char *s;
                    175: 
                    176:        if ((s = strrchr(buf, '\n')) != NULL)
                    177:                *s = '\0';                      /* zap trailing newline */
                    178:        for (kp = keys; kp < &keys[NKEYS]; kp++) {
                    179:                n = kp->key_len;
                    180:                if (strncmp(buf, kp->key_name, n) == 0) {
                    181:                        bufp = buf + n;
                    182:                        if (*bufp != '\0') {
                    183:                                if (!isspace(*bufp))
                    184:                                        continue;       /* no match */
                    185:                                while (isspace(*bufp))
                    186:                                        bufp++;         /* skip trailing whitespace */
                    187:                        }
                    188:                        return kp->key_val;
                    189:                }
                    190:        }
                    191:        return OTHER;
                    192: }
                    193: 
                    194: /*
                    195:  * Return pointer to allocated copy of string s.
                    196:  */
                    197: char *
                    198: newstring(s) register char *s;
                    199: {
                    200:        return strcpy(alloc(strlen(s) + 1), s);
                    201: }
                    202: 
                    203: /*
                    204:  * Write a font width table for troff.
                    205:  * Most of the fields in the binary FWT are for PCL and are zeroed here.
                    206:  */
                    207: void
                    208: outputPS()
                    209: {
                    210:        register int i, mul;
                    211:        char *fullname;
                    212:        int spacing, width;
                    213: 
                    214:        if (FontName == NULL)
                    215:                fatal("no FontName specified");
                    216:        fullname = (FullName == NULL) ? FontName : FullName;
                    217: 
                    218:        /* Verbose output. */
                    219:        if (vflag) {
                    220:                if (FullName != NULL)
                    221:                        fprintf(stderr, "FullName = %s\n", FullName);
                    222:                fprintf(stderr, "FontName = %s\n", FontName);
                    223:                if (Weight != NULL)
                    224:                        fprintf(stderr, "Weight = %s\n", Weight);
                    225:        }
                    226: 
                    227:        /* Descriptive name. */
                    228:        if (cflag) {
                    229:                fprintf(ofp, "{\n\t\"%s", fullname);
                    230:                fprintf(ofp, "\",\n");
                    231:        } else {
                    232:                fputs(fullname, ofp);
                    233:                fputc(0, ofp);
                    234:        }
                    235: 
                    236:        /* Font name. */
                    237:        if (cflag)
                    238:                fprintf(ofp, "\t\"%s\",\n", FontName);
                    239:        else {
                    240:                fputs(FontName, ofp);
                    241:                fputc(0, ofp);
                    242:        }
                    243: 
                    244:        /* Determine if fixed or variable spacing. */
                    245:        width = spacing = 0;                            /* assume fixed spacing */
                    246:        for (i = 0; i < NWIDTH; i++) {
                    247:                if (chartab[i] == 0)
                    248:                        continue;
                    249:                else if (width == 0)
                    250:                        width = chartab[i];             /* first nonzero width */
                    251:                else if (width != chartab[i]) {
                    252:                        spacing = 1;                    /* variable spacing */
                    253:                        break;
                    254:                }
                    255:        }
                    256: 
                    257:        /*
                    258:         * Write FWTAB fields.
                    259:         * All but spacing, pitch, ptsize, num, den are zeroed.
                    260:         * This uses a nominal point size of 10, for no particular reason.
                    261:         */
                    262:        putshort(FLAG_PS);
                    263:        putshort(0);
                    264:        putshort(0);
                    265:        putshort(spacing);              /* spacing */
                    266:        putshort(0);
                    267:        putshort(44);                   /* pitch */
                    268:        putshort(100);                  /* 10 * ptsize */
                    269:        putshort(0);                    /* style */
                    270:        putshort(0);                    /* weight */
                    271:        putshort(0);                    /* face */
                    272:        mul = (maxwidth / 256) + 1;     /* scale factor */
                    273:        putshort(mul);                  /* mul */
                    274:        putshort(1000);                 /* div */
                    275: 
                    276:        /* Write width table. */
                    277:        if (cflag) {
                    278:                fprintf(ofp, "\t{");
                    279:                for (i = 0; i < NWIDTH; i++) {
                    280:                        if (i % 8 == 0)
                    281:                                fprintf(ofp, "\n\t\t");
                    282:                        fprintf(ofp, "%3d, ", chartab[i]/mul);
                    283:                }
                    284:                fprintf(ofp, "\n\t}\n}\n");
                    285:        } else {
                    286:                for (i = 0; i < NWIDTH; i++)
                    287:                        fputc(chartab[i]/mul, ofp);
                    288:        }
                    289: }
                    290: 
                    291: /* end of fwt_PS.c */

unix.superglobalmegacorp.com

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