Annotation of coherent/b/bin/troff/fwt_PS.c, revision 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.