Annotation of researchv10no/cmd/postscript/dpost/font.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *
                      3:  * Typesetter font tables routines - for postprocessors.
                      4:  *
                      5:  */
                      6: 
                      7: #include <stdio.h>
                      8: #include <ctype.h>
                      9: 
                     10: #include "gen.h"
                     11: #include "ext.h"
                     12: #include "font.h"
                     13: 
                     14: Font   *mount[MAXFONTS+1];             /* mount table - pointers into fonts[] */
                     15: Font   fonts[MAXFONTS+2];              /* font data - guarantee one empty slot */
                     16: 
                     17: int    fcount;                         /* entries in fonts[] */
                     18: int    mcount;                         /* fonts currently in memory */
                     19: int    mlimit = MAXFONTS+1;            /* and the most we'll allow */
                     20: 
                     21: char   *chnames[MAXCH];                /* special character hash table */
                     22: int    nchnames;                       /* number of entries in chnames[] */
                     23: 
                     24: extern int     devres;
                     25: extern int     unitwidth;
                     26: extern int     nfonts;
                     27: 
                     28: /*****************************************************************************/
                     29: 
                     30: checkdesc(path)
                     31: 
                     32:     char       *path;
                     33: 
                     34: {
                     35: 
                     36:     char       buf[150];
                     37:     FILE       *fp;
                     38:     int                val = 0;
                     39: 
                     40: /*
                     41:  *
                     42:  * Return non-zero if the typesetter description file path includes,
                     43:  *
                     44:  *     PDL PostScript
                     45:  *
                     46:  * before the charset table.
                     47:  *
                     48:  */
                     49: 
                     50:     if ( (fp = fopen(path, "r")) != NULL ) {
                     51:        while ( fscanf(fp, "%s", buf) != EOF ) {
                     52:            if ( strcmp(buf, "PDL") == 0 ) {
                     53:                fscanf(fp, "%s", buf);
                     54:                val = strcmp(buf, "PostScript") == 0;
                     55:                break;
                     56:            } else if ( strcmp(buf, "charset") == 0 )
                     57:                break;
                     58:            skipline(fp);
                     59:        }   /* End while */
                     60:        fclose(fp);
                     61:     }  /* End if */
                     62: 
                     63:     return(val);
                     64: 
                     65: }   /* End of checkdesc */
                     66: 
                     67: /*****************************************************************************/
                     68: 
                     69: getdesc(path)
                     70: 
                     71:     char       *path;
                     72: 
                     73: {
                     74: 
                     75:     char       buf[150];
                     76:     FILE       *fp;
                     77:     int                n;
                     78: 
                     79: /*
                     80:  *
                     81:  * Read a typesetter description file. Font and size lists are discarded. Only
                     82:  * used to get to the start of the next command.
                     83:  *
                     84:  */
                     85: 
                     86:     if ( (fp = fopen(path, "r")) == NULL )
                     87:        return(-1);
                     88: 
                     89:     while ( fscanf(fp, "%s", buf) != EOF ) {
                     90:        if ( strcmp(buf, "res") == 0 )
                     91:            fscanf(fp, "%d", &devres);
                     92:        else if ( strcmp(buf, "unitwidth") == 0 )
                     93:            fscanf(fp, "%d", &unitwidth);
                     94:        else if ( strcmp(buf, "sizes") == 0 )
                     95:            while ( fscanf(fp, "%d", &n) != EOF && n != 0 ) ;
                     96:        else if ( strcmp(buf, "inmemory") == 0 )
                     97:            fscanf(fp, "%d", &mlimit);
                     98:        else if ( strcmp(buf, "Encoding") == 0 ) {
                     99:            fscanf(fp, "%s", buf);
                    100:            fontencoding = strsave(buf);
                    101:        } else if ( strcmp(buf, "fonts") == 0 ) {
                    102:            fscanf(fp, "%d", &nfonts);
                    103:            for ( n = 0; n < nfonts; n++ )
                    104:                fscanf(fp, "%s", buf);
                    105:        } else if ( strcmp(buf, "charset") == 0 ) {
                    106:            while ( fscanf(fp, "%s", buf) != EOF )
                    107:                chadd(buf);
                    108:            break;
                    109:        }   /* End if */
                    110:        skipline(fp);
                    111:     }  /* End while */
                    112: 
                    113:     fclose(fp);
                    114:     return(1);
                    115: 
                    116: }   /* End of getdesc */
                    117: 
                    118: /*****************************************************************************/
                    119: 
                    120: getfont(path, fpos)
                    121: 
                    122:     char       *path;
                    123:     Font       *fpos;
                    124: 
                    125: {
                    126: 
                    127:     FILE       *fin;
                    128:     Chwid      chtemp[MAXCH];
                    129:     static     Chwid chinit;
                    130:     int                i, nw, n, wid, code;
                    131:     char       buf[300], ch[100], s1[100], s2[100], s3[100], cmd[100];
                    132: 
                    133: 
                    134: /*
                    135:  *
                    136:  * Read a width table from path into *fpos. Skip unnamed characters, spacewidth,
                    137:  * ligatures, ascender/descender entries, and anything else not recognized. All
                    138:  * calls should come through mountfont().
                    139:  *
                    140:  */
                    141: 
                    142:     if ( fpos->state == INMEMORY )
                    143:        return(1);
                    144: 
                    145:     if ( (fin = fopen(path, "r")) == NULL )
                    146:        return(-1);
                    147: 
                    148:     if ( fpos->state == NEWFONT ) {
                    149:        if ( ++fcount > MAXFONTS+1 )
                    150:            return(-1);
                    151:        fpos->path = strsave(path);
                    152:     }  /* End if */
                    153: 
                    154:     if ( ++mcount > mlimit && mcount > nfonts+1 )
                    155:        freefonts();
                    156: 
                    157:     for ( i = 0; i < ALPHABET-32; i++ )
                    158:        chtemp[i] = chinit;
                    159: 
                    160:     while ( fscanf(fin, "%s", cmd) != EOF ) {
                    161:        if ( strcmp(cmd, "name") == 0 ) {
                    162:            release(fpos->name);
                    163:            fscanf(fin, "%s", buf);
                    164:            fpos->name = strsave(buf);
                    165:        } else if ( strcmp(cmd, "fontname") == 0 ) {
                    166:            release(fpos->fontname);
                    167:            fscanf(fin, "%s", buf);
                    168:            fpos->fontname = strsave(buf);
                    169:        } else if ( strcmp(cmd, "special") == 0 )
                    170:            fpos->specfont = 1;
                    171:        else if ( strcmp(cmd, "named") == 0 )   /* in prologue or somewhere else */
                    172:            fpos->flags |= NAMED;
                    173:        else if ( strcmp(cmd, "charset") == 0 ) {
                    174:            skipline(fin);
                    175:            nw = ALPHABET-32;
                    176:            while ( fgets(buf, sizeof(buf), fin) != NULL ) {
                    177:                sscanf(buf, "%s %s %s %s", ch, s1, s2, s3);
                    178:                if ( s1[0] != '"' ) {           /* not a synonym */
                    179:                    sscanf(s1, "%d", &wid);
                    180:                    code = strtol(s3, 0, 0);    /* dec/oct/hex */
                    181:                }   /* End if */
                    182:                if ( strlen(ch) == 1 ) {        /* it's ascii */
                    183:                    n = ch[0] - 32;             /* origin omits non-graphics */
                    184:                    chtemp[n].num = ch[0];
                    185:                    chtemp[n].wid = wid;
                    186:                    chtemp[n].code = code;
                    187:                } else if ( ch[0] == '\\' && ch[1] == '0' ) {
                    188:                    n = strtol(ch+1, 0, 0) - 32;        /* check against ALPHABET? */
                    189:                    chtemp[n].num = n + 32;
                    190:                    chtemp[n].wid = wid;
                    191:                    chtemp[n].code = code;
                    192:                } else if ( strcmp(ch, "---") != 0 ) {  /* ignore unnamed chars */
                    193:                    if ( (n = chindex(ch)) == -1 )      /* global? */
                    194:                        n = chadd(ch);
                    195:                    chtemp[nw].num = n;
                    196:                    chtemp[nw].wid = wid;
                    197:                    chtemp[nw].code = code;
                    198:                    nw++;
                    199:                }   /* End else */
                    200:            }   /* End while */
                    201:            break;
                    202:        }   /* End else */
                    203:        skipline(fin);
                    204:     }  /* End while */
                    205: 
                    206:     fclose(fin);
                    207: 
                    208:     fpos->wp = (Chwid *)allocate(nw * sizeof(Chwid));
                    209:     for ( i = 0; i < nw; i++ )
                    210:        fpos->wp[i] = chtemp[i];
                    211: 
                    212:     fpos->nchars = nw;
                    213:     fpos->state = INMEMORY;
                    214: 
                    215:     return(1);
                    216: 
                    217: }   /* End of getfont */
                    218: 
                    219: /*****************************************************************************/
                    220: 
                    221: mountfont(path, m)
                    222: 
                    223:     char       *path;
                    224:     int                m;
                    225: 
                    226: {
                    227: 
                    228:     Font       *fpos;
                    229: 
                    230: /*
                    231:  *
                    232:  * Mount font table from file path at position m. Mounted fonts are guaranteed
                    233:  * to be in memory.
                    234:  *
                    235:  */
                    236: 
                    237:     if ( m < 0 || m > MAXFONTS )
                    238:        return(-1);
                    239: 
                    240:     if ( mount[m] != NULL ) {
                    241:        if ( strcmp(path, mount[m]->path) == 0 ) {
                    242:            if ( mount[m]->state == INMEMORY )
                    243:                return(1);
                    244:        } else {
                    245:            mount[m]->mounted--;
                    246:            mount[m] = NULL;
                    247:        }   /* End else */
                    248:     }  /* End if */
                    249: 
                    250:     mount[m] = fpos = &fonts[findfont(path)];
                    251:     mount[m]->mounted++;
                    252:     return(getfont(path, fpos));
                    253: 
                    254: }   /* End of mountfont */
                    255: 
                    256: /*****************************************************************************/
                    257: 
                    258: freefonts()
                    259: 
                    260: {
                    261: 
                    262:     int                n;
                    263: 
                    264: /*
                    265:  *
                    266:  * Release memory used by all unmounted fonts - except for the path string.
                    267:  *
                    268:  */
                    269: 
                    270:     for ( n = 0; n < MAXFONTS+2; n++ )
                    271:        if ( fonts[n].state == INMEMORY && fonts[n].mounted == 0 ) {
                    272:            release(fonts[n].wp);
                    273:            fonts[n].wp = NULL;
                    274:            fonts[n].state = RELEASED;
                    275:            mcount--;
                    276:        }   /* End if */
                    277: 
                    278: }   /* End of freefonts */
                    279: 
                    280: /*****************************************************************************/
                    281: 
                    282: findfont(path)
                    283: 
                    284:     char       *path;
                    285: 
                    286: {
                    287: 
                    288:     register   n;
                    289: 
                    290: /*
                    291:  *
                    292:  * Look for path in the fonts table. Returns the index where it was found or can
                    293:  * be inserted (if not found).
                    294:  *
                    295:  */
                    296: 
                    297:     for ( n = hash(path, MAXFONTS+2); fonts[n].state != NEWFONT; n = (n+1) % (MAXFONTS+2) )
                    298:        if ( strcmp(path, fonts[n].path) == 0 )
                    299:            break;
                    300:     return(n);
                    301: 
                    302: }   /* End of findfont */
                    303: 
                    304: /*****************************************************************************/
                    305: 
                    306: mounted(m)
                    307: 
                    308:     int                m;
                    309: 
                    310: {
                    311: 
                    312: /*
                    313:  *
                    314:  * Return 1 if a font is mounted at position m.
                    315:  *
                    316:  */
                    317: 
                    318:     return((m >= 0 && m <= MAXFONTS && mount[m] != NULL) ? 1 : 0);
                    319: 
                    320: }   /* End of mounted */
                    321: 
                    322: /*****************************************************************************/
                    323: 
                    324: onfont(c, m)
                    325: 
                    326:     int                c;
                    327:     int                m;
                    328: 
                    329: {
                    330: 
                    331:     register Font      *fp;
                    332:     register Chwid     *cp, *ep;
                    333: 
                    334: /*
                    335:  *
                    336:  * Returns the position of character c in the font mounted at m, or -1 if the
                    337:  * character is not found.
                    338:  *
                    339:  */
                    340: 
                    341:     if ( mounted(m) ) {
                    342:        fp = mount[m];
                    343:        if ( c < ALPHABET ) {
                    344:            if ( fp->wp[c-32].num == c )        /* ascii at front */
                    345:                return c - 32;
                    346:            else return -1;
                    347:        }   /* End if */
                    348: 
                    349:        cp = &fp->wp[ALPHABET-32];
                    350:        ep = &fp->wp[fp->nchars];
                    351:        for ( ; cp < ep; cp++ )                 /* search others */
                    352:            if ( cp->num == c )
                    353:                return cp - &fp->wp[0];
                    354:     }  /* End if */
                    355: 
                    356:     return -1;
                    357: 
                    358: }   /* End of onfont */
                    359: 
                    360: /*****************************************************************************/
                    361: 
                    362: chwidth(n, m)
                    363: 
                    364:     int                n;
                    365:     int                m;
                    366: 
                    367: {
                    368: 
                    369: /*
                    370:  *
                    371:  * Return width of the character at position n in the font mounted at m. Skip
                    372:  * bounds checks - assume it's already been done.
                    373:  *
                    374:  */
                    375: 
                    376:     return(mount[m]->wp[n].wid);
                    377: 
                    378: }   /* End of chwidth */
                    379: 
                    380: /*****************************************************************************/
                    381: 
                    382: chcode(n, m)
                    383: 
                    384:     int                n;
                    385:     int                m;
                    386: 
                    387: {
                    388: 
                    389: /*
                    390:  *
                    391:  * Return typesetter code for the character at position n in the font mounted
                    392:  * at m. Skip bounds checks - assume it's already been done. 
                    393:  *
                    394:  */
                    395: 
                    396:     return(mount[m]->wp[n].code);
                    397: 
                    398: }   /* End of chcode */
                    399: 
                    400: /*****************************************************************************/
                    401: 
                    402: chindex(s)
                    403: 
                    404:     char       *s;
                    405: 
                    406: {
                    407: 
                    408:     register   i;
                    409: 
                    410: /*
                    411:  *
                    412:  * Look for s in global character name table. Hash table is guaranteed to have
                    413:  * at least one empty slot (by chadd()) so the loop terminate.
                    414:  *
                    415:  */
                    416: 
                    417:     for ( i = hash(s, MAXCH); chnames[i] != NULL; i = (i+1) % MAXCH )
                    418:        if ( strcmp(s, chnames[i]) == 0 )
                    419:            return(i+ALPHABET);
                    420:     return(-1);
                    421: 
                    422: }   /* End of chindex */
                    423: 
                    424: /*****************************************************************************/
                    425: 
                    426: chadd(s)
                    427: 
                    428:     char       *s;
                    429: 
                    430: {
                    431: 
                    432:     register   i;
                    433: 
                    434: /*
                    435:  *
                    436:  * Add s to the global character name table. Leave one empty slot so loops
                    437:  * terminate.
                    438:  *
                    439:  */
                    440: 
                    441:     if ( nchnames >= MAXCH - 1 )
                    442:        error(FATAL, "out of table space adding character %s", s);
                    443: 
                    444:     for ( i = hash(s, MAXCH); chnames[i] != NULL; i = (i+1) % MAXCH ) ;
                    445: 
                    446:     nchnames++;
                    447:     chnames[i] = strsave(s);
                    448: 
                    449:     return(i+ALPHABET);
                    450: 
                    451: }   /* End of chadd */
                    452: 
                    453: /*****************************************************************************/
                    454: 
                    455: char *chname(n)
                    456: 
                    457:     int                n;
                    458: 
                    459: {
                    460: 
                    461: /*
                    462:  *
                    463:  * Returns string for the character with index n.
                    464:  *
                    465:  */
                    466: 
                    467:     return(chnames[n-ALPHABET]);
                    468: 
                    469: }   /* End of chname */
                    470: 
                    471: /*****************************************************************************/
                    472: 
                    473: hash(s, l)
                    474: 
                    475:     char       *s;
                    476:     int                l;
                    477: 
                    478: {
                    479: 
                    480:     register   i;
                    481: 
                    482: /*
                    483:  *
                    484:  * Return the hash index for string s in a table of length l. Probably should
                    485:  * make i unsigned and mod once at the end.
                    486:  *
                    487:  */
                    488: 
                    489:     for ( i = 0; *s != '\0'; s++ )
                    490:        i = (i * 10 + *s) % l;
                    491:     return(i);
                    492: 
                    493: }   /* End of hash */
                    494: 
                    495: /*****************************************************************************/
                    496: 
                    497: char *strsave(s)
                    498: 
                    499:     char       *s;
                    500: 
                    501: {
                    502: 
                    503:     char       *ptr = NULL;
                    504: 
                    505: /*
                    506:  *
                    507:  * Make a permanent copy of string s.
                    508:  *
                    509:  */
                    510: 
                    511:     if ( s != NULL ) {
                    512:        ptr = (char *)allocate(strlen(s)+1);
                    513:        strcpy(ptr, s);
                    514:     }  /* End if */
                    515:     return(ptr);
                    516: 
                    517: }   /* End of strsave */
                    518: 
                    519: /*****************************************************************************/
                    520: 
                    521: char *allocate(count)
                    522: 
                    523:     int                count;
                    524: 
                    525: {
                    526: 
                    527:     char       *ptr;
                    528: 
                    529: /*
                    530:  *
                    531:  * Allocates count bytes. Free unmounted fonts if the first attempt fails. To
                    532:  * be absolutely correct all memory allocation should be done by this routine.
                    533:  *
                    534:  */
                    535: 
                    536:     if ( (ptr = (char *)malloc(count)) == NULL ) {
                    537:        freefonts();
                    538:        if ( (ptr = (char *)malloc(count)) == NULL )
                    539:            error(FATAL, "no memory");
                    540:     }  /* End if */
                    541:     return(ptr);
                    542: 
                    543: }   /* End of allocate */
                    544: 
                    545: /*****************************************************************************/
                    546: 
                    547: release(ptr)
                    548: 
                    549:     char       *ptr;
                    550: 
                    551: {
                    552: 
                    553: /*
                    554:  *
                    555:  * Free memory provided ptr isn't NULL.
                    556:  *
                    557:  */
                    558: 
                    559:     if ( ptr != NULL )
                    560:        free(ptr);
                    561: 
                    562: }   /* End of release */
                    563: 
                    564: /*****************************************************************************/
                    565: 
                    566: dumpmount(m)
                    567: 
                    568:     int                m;
                    569: 
                    570: {
                    571: 
                    572: /*
                    573:  *
                    574:  * Dumps the font mounted at position n.
                    575:  *
                    576:  */
                    577: 
                    578:     if ( mount[m] != NULL )
                    579:        dumpfont((mount[m] - &fonts[0]));
                    580:     else fprintf(stderr, "no font mounted at %d\n", m);
                    581: 
                    582: }   /* End of dumpmount */
                    583: 
                    584: /*****************************************************************************/
                    585: 
                    586: dumpfont(n)
                    587: 
                    588:     int                n;
                    589: 
                    590: {
                    591: 
                    592:     int                i;
                    593:     Font       *fpos;
                    594:     char       *str;
                    595: 
                    596: /*
                    597:  *
                    598:  * Dump of everything known about the font saved at fonts[n].
                    599:  *
                    600:  */
                    601: 
                    602:     fpos = &fonts[n];
                    603: 
                    604:     if ( fpos->state ) {
                    605:        fprintf(stderr, "path %s\n", fpos->path);
                    606:        fprintf(stderr, "state %d\n", fpos->state);
                    607:        fprintf(stderr, "flags %d\n", fpos->flags);
                    608:        fprintf(stderr, "mounted %d\n", fpos->mounted);
                    609:        fprintf(stderr, "nchars %d\n", fpos->nchars);
                    610:        fprintf(stderr, "special %d\n", fpos->specfont);
                    611:        fprintf(stderr, "name %s\n", fpos->name);
                    612:        fprintf(stderr, "fontname %s\n", fpos->fontname);
                    613:        if ( fpos->state == INMEMORY ) {
                    614:            fprintf(stderr, "charset\n");
                    615:            for ( i = 0; i < fpos->nchars; i++ ) {
                    616:                if ( fpos->wp[i].num > 0 ) {
                    617:                    if ( fpos->wp[i].num < ALPHABET )
                    618:                        fprintf(stderr, "%c\t%d\t%d\n", fpos->wp[i].num,
                    619:                                fpos->wp[i].wid, fpos->wp[i].code);
                    620:                    else {
                    621:                        str = chname(fpos->wp[i].num);
                    622:                        if ( *str == '#' && isdigit(*(str+1)) && isdigit(*(str+2)) )
                    623:                            str = "---";
                    624:                        fprintf(stderr, "%s\t%d\t%d\n", str, fpos->wp[i].wid,
                    625:                                fpos->wp[i].code);
                    626:                    }   /* End else */
                    627:                }   /* End if */
                    628:            }   /* End for */
                    629:        } else fprintf(stderr, "charset: not in memory\n");
                    630:     } else fprintf(stderr, "empty font: %d\n", n);
                    631: 
                    632:     putc('\n', stderr);
                    633: 
                    634: }   /* End of dumpfont */
                    635: 
                    636: /*****************************************************************************/
                    637: 

unix.superglobalmegacorp.com

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