Annotation of researchv10no/cmd/post.src/dpost.utf/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 "rune.h"
                     12: #include "ext.h"
                     13: #include "font.h"
                     14: 
                     15: Font   *mount[MAXFONTS+1];             /* mount table - pointers into fonts[] */
                     16: Font   fonts[MAXFONTS+2];              /* font data - guarantee one empty slot */
                     17: 
                     18: int    fcount;                         /* entries in fonts[] */
                     19: int    mcount;                         /* fonts currently in memory */
                     20: int    mlimit = MAXFONTS+1;            /* and the most we'll allow */
                     21: 
                     22: char   *chnames[SPECIALCHARS];         /* special character hash table */
                     23: int    nchnames;                       /* number of entries in chnames[] */
                     24: 
                     25: extern int     devres;
                     26: extern int     unitwidth;
                     27: extern int     nfonts;
                     28: 
                     29: /*****************************************************************************/
                     30: 
                     31: checkdesc(path)
                     32: 
                     33:     char       *path;
                     34: 
                     35: {
                     36: 
                     37:     char       buf[150];
                     38:     FILE       *fp;
                     39:     int                val = 0;
                     40: 
                     41: /*
                     42:  *
                     43:  * Return non-zero if the typesetter description file path includes,
                     44:  *
                     45:  *     PDL PostScript
                     46:  *
                     47:  * before the charset table.
                     48:  *
                     49:  */
                     50: 
                     51:     if ( (fp = fopen(path, "r")) != NULL ) {
                     52:        while ( fscanf(fp, "%s", buf) != EOF ) {
                     53:            if ( strcmp(buf, "PDL") == 0 ) {
                     54:                fscanf(fp, "%s", buf);
                     55:                val = strcmp(buf, "PostScript") == 0;
                     56:                break;
                     57:            } else if ( strcmp(buf, "charset") == 0 )
                     58:                break;
                     59:            skipline(fp);
                     60:        }   /* End while */
                     61:        fclose(fp);
                     62:     }  /* End if */
                     63: 
                     64:     return(val);
                     65: 
                     66: }   /* End of checkdesc */
                     67: 
                     68: /*****************************************************************************/
                     69: 
                     70: getdesc(path)
                     71: 
                     72:     char       *path;
                     73: 
                     74: {
                     75: 
                     76:     char       buf[150];
                     77:     FILE       *fp;
                     78:     int                n;
                     79: 
                     80:     if ( (fp = fopen(path, "r")) == NULL )
                     81:        return(-1);
                     82: 
                     83:     while ( fscanf(fp, "%s", buf) != EOF ) {
                     84:        if ( strcmp(buf, "res") == 0 )
                     85:            fscanf(fp, "%d", &devres);
                     86:        else if ( strcmp(buf, "unitwidth") == 0 )
                     87:            fscanf(fp, "%d", &unitwidth);
                     88:        else if ( strcmp(buf, "sizes") == 0 )
                     89:            while ( fscanf(fp, "%d", &n) != EOF && n != 0 ) ;
                     90:        else if ( strcmp(buf, "inmemory") == 0 )
                     91:            fscanf(fp, "%d", &mlimit);
                     92:        else if ( strcmp(buf, "Encoding") == 0 ) {
                     93:            fscanf(fp, "%s", buf);
                     94:            fontencoding = strsave(buf);
                     95:        } else if ( strcmp(buf, "fonts") == 0 ) {
                     96:            fscanf(fp, "%d", &nfonts);
                     97:            for ( n = 0; n < nfonts; n++ )
                     98:                fscanf(fp, "%s", buf);
                     99:        } else if ( strcmp(buf, "charset") == 0 ) {
                    100:            while ( fscanf(fp, "%s", buf) != EOF )
                    101:                chadd(buf);
                    102:            break;
                    103:        }   /* End if */
                    104:        skipline(fp);
                    105:     }  /* End while */
                    106: 
                    107:     fclose(fp);
                    108:     return(1);
                    109: 
                    110: }   /* End of getdesc */
                    111: 
                    112: /*****************************************************************************/
                    113: 
                    114: getfont(path, fpos)
                    115: 
                    116:     char       *path;
                    117:     Font       *fpos;
                    118: 
                    119: {
                    120: 
                    121:     FILE       *fin;
                    122:     Chwid      chtemp[LARGESTFONT];
                    123:     int                next;
                    124:     int                i, n, num, wid, code;
                    125:     char       buf[300], ch[100], s1[100], s2[100], s3[100], cmd[100];
                    126: 
                    127: 
                    128: /*
                    129:  *
                    130:  * Read a font width table. Skip unnamed characters, spacewidth, ligatures,
                    131:  * ascender/descender entries, and anything else not recognized. Charset
                    132:  * entries for a new font are first stacked in chtemp[] and later copied
                    133:  * to correct slots in a newly allocated wp array. All calls should come
                    134:  * through mountfont().
                    135:  *
                    136:  */
                    137: 
                    138:     if ( fpos->state == INMEMORY )
                    139:        return(1);
                    140: 
                    141:     if ( (fin = fopen(path, "r")) == NULL )
                    142:        return(-1);
                    143: 
                    144:     if ( fpos->state == NEWFONT ) {
                    145:        if ( ++fcount > MAXFONTS+1 )
                    146:            return(-1);
                    147:        fpos->path = strsave(path);
                    148:     }  /* End if */
                    149: 
                    150:     if ( ++mcount > mlimit && mcount > nfonts+1 )
                    151:        freefonts();
                    152: 
                    153:     while ( fscanf(fin, "%s", cmd) != EOF ) {
                    154:        if ( strcmp(cmd, "name") == 0 ) {
                    155:            release(fpos->name);
                    156:            fscanf(fin, "%s", buf);
                    157:            fpos->name = strsave(buf);
                    158:        } else if ( strcmp(cmd, "fontname") == 0 ) {
                    159:            release(fpos->fontname);
                    160:            fscanf(fin, "%s", buf);
                    161:            fpos->fontname = strsave(buf);
                    162:        } else if ( strcmp(cmd, "special") == 0 )
                    163:            fpos->specfont = 1;
                    164:        else if ( strcmp(cmd, "named") == 0 )   /* in prologue or somewhere else */
                    165:            fpos->flags |= NAMED;
                    166:        else if ( strcmp(cmd, "charset") == 0 ) {
                    167:            skipline(fin);
                    168:            next = 0;
                    169:            fpos->nchars = 0;           /* special characters */
                    170:            fpos->first = LASTCODE;
                    171:            fpos->last = FIRSTCODE;
                    172:            while ( fgets(buf, sizeof(buf), fin) != NULL ) {
                    173:                num = -1;
                    174:                sscanf(buf, "%s %s %s %s", ch, s1, s2, s3);
                    175:                if ( s1[0] != '"' ) {           /* not a synonym */
                    176:                    sscanf(s1, "%d", &wid);
                    177:                    code = strtol(s3, 0, 0);    /* dec/oct/hex */
                    178:                }   /* End if */
                    179:                if ( strlen(ch) == 1 )          /* it's ascii */
                    180:                    num = ch[0];
                    181:                else if ( ch[0] == '\\' && ch[1] == '0' )
                    182:                    num = strtol(ch+1, 0, 0);
                    183:                /*
                    184:                 * Eventually consider something like,
                    185:                 *
                    186:                 * else if ( strlen(ch) == chartorune(&r, ch) )
                    187:                 *      num = r;
                    188:                 */
                    189:                else if ( strcmp(ch, "---") != 0 ) {    /* ignore unnamed chars */
                    190:                    if ( (num = chindex(ch)) == INVALIDCODE )
                    191:                        num = chadd(ch);
                    192:                }   /* End else */
                    193:                if ( ValidChar(num) ) {
                    194:                    if ( next < LARGESTFONT ) {
                    195:                        chtemp[next].num = num;
                    196:                        chtemp[next].wid = wid;
                    197:                        chtemp[next++].code = code;
                    198:                        if ( ValidCode(num) ) {
                    199:                            fpos->first = (num < fpos->first) ? num : fpos->first;
                    200:                            fpos->last = (num > fpos->last) ? num : fpos->last;
                    201:                        } else fpos->nchars++;
                    202:                    } else error(FATAL, "font %s too large", path);
                    203:                } else if ( num != -1 )
                    204:                    error(FATAL, "invalid character in font %s\n", path);
                    205:            }   /* End while */
                    206:            break;
                    207:        }   /* End else */
                    208:        skipline(fin);
                    209:     }  /* End while */
                    210: 
                    211:     fclose(fin);
                    212: 
                    213:     if ( fpos->first > fpos->last )
                    214:        fpos->last = fpos->first - 1;
                    215:     fpos->nchars += fpos->last - fpos->first + 1;
                    216:     fpos->wp = (Chwid *)allocate(fpos->nchars * sizeof(Chwid));
                    217: 
                    218:     for ( i = 0; i < fpos->nchars; i++ )
                    219:        fpos->wp[i].num = INVALIDCODE;
                    220: 
                    221:     for ( i = 0, n = 1; i < next; i++ ) {
                    222:        if ( chtemp[i].num <= fpos->last )
                    223:            fpos->wp[chtemp[i].num - fpos->first] = chtemp[i];
                    224:        else fpos->wp[fpos->last - fpos->first + n++] = chtemp[i];
                    225:     }  /* End for */
                    226: 
                    227:     fpos->state = INMEMORY;
                    228:     return(1);
                    229: 
                    230: }   /* End of getfont */
                    231: 
                    232: /*****************************************************************************/
                    233: 
                    234: mountfont(path, m)
                    235: 
                    236:     char       *path;
                    237:     int                m;
                    238: 
                    239: {
                    240: 
                    241:     Font       *fpos;
                    242: 
                    243:     if ( m < 0 || m > MAXFONTS )
                    244:        return(-1);
                    245: 
                    246:     if ( mount[m] != NULL ) {
                    247:        if ( mount[m]->path != NULL && strcmp(path, mount[m]->path) == 0 ) {
                    248:            if ( mount[m]->state == INMEMORY )
                    249:                return(1);
                    250:        } else {
                    251:            mount[m]->mounted--;
                    252:            mount[m] = NULL;
                    253:        }   /* End else */
                    254:     }  /* End if */
                    255: 
                    256:     mount[m] = fpos = &fonts[findfont(path)];
                    257:     mount[m]->mounted++;
                    258:     return(getfont(path, fpos));
                    259: 
                    260: }   /* End of mountfont */
                    261: 
                    262: /*****************************************************************************/
                    263: 
                    264: freefonts()
                    265: 
                    266: {
                    267: 
                    268:     int                n;
                    269: 
                    270: /*
                    271:  *
                    272:  * Don't release the path without resetting state to NEWFONT - findfont()
                    273:  * assumes path is available.
                    274:  *
                    275:  */
                    276: 
                    277:     for ( n = 0; n < MAXFONTS+2; n++ )
                    278:        if ( fonts[n].state == INMEMORY && fonts[n].mounted == 0 ) {
                    279:            release(fonts[n].wp);
                    280:            fonts[n].wp = NULL;
                    281:            fonts[n].state = RELEASED;
                    282:            mcount--;
                    283:        }   /* End if */
                    284: 
                    285: }   /* End of freefonts */
                    286: 
                    287: /*****************************************************************************/
                    288: 
                    289: findfont(path)
                    290: 
                    291:     char       *path;
                    292: 
                    293: {
                    294: 
                    295:     register   n;
                    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:     return(m >= 0 && m <= MAXFONTS && mount[m] != NULL);
                    313: 
                    314: }   /* End of mounted */
                    315: 
                    316: /*****************************************************************************/
                    317: 
                    318: onfont(c, m)
                    319: 
                    320:     int                c;
                    321:     int                m;
                    322: 
                    323: {
                    324: 
                    325:     Font       *fp;
                    326:     Chwid      *cp, *ep;
                    327: 
                    328: /*
                    329:  *
                    330:  * Returns the position of character c in the font mounted at m, or -1 if the
                    331:  * character is not found.
                    332:  *
                    333:  */
                    334: 
                    335:     if ( mounted(m) ) {
                    336:        fp = mount[m];
                    337:        if ( c >= fp->first && c <= fp->last ) {
                    338:            if ( fp->wp[c-fp->first].num == c )
                    339:                return(c - fp->first);
                    340:            else return(-1);
                    341:        }   /* End if */
                    342: 
                    343:        if ( ValidSpecial(c) ) {
                    344:            cp = &fp->wp[fp->last - fp->first + 1];
                    345:            ep = &fp->wp[fp->nchars];
                    346:            for ( ; cp < ep; cp++ )                     /* search others */
                    347:                if ( cp->num == c )
                    348:                    return(cp - &fp->wp[0]);
                    349:        }   /* End if */
                    350:     }  /* End if */
                    351: 
                    352:     return(-1);
                    353: 
                    354: }   /* End of onfont */
                    355: 
                    356: /*****************************************************************************/
                    357: 
                    358: chindex(s)
                    359: 
                    360:     char       *s;
                    361: 
                    362: {
                    363: 
                    364:     register   i;
                    365: 
                    366: /*
                    367:  *
                    368:  * Return the code assigned to special character s or INVALIDCODE if s
                    369:  * is not currently defined.
                    370:  *
                    371:  */
                    372: 
                    373:     for ( i = hash(s, SPECIALCHARS); chnames[i] != NULL; i = (i+1) % SPECIALCHARS )
                    374:        if ( strcmp(s, chnames[i]) == 0 )
                    375:            return(i+FIRSTSPECIAL);
                    376:     return(INVALIDCODE);
                    377: 
                    378: }   /* End of chindex */
                    379: 
                    380: /*****************************************************************************/
                    381: 
                    382: chadd(s)
                    383: 
                    384:     char       *s;
                    385: 
                    386: {
                    387: 
                    388:     register   i;
                    389: 
                    390:     if ( nchnames >= SPECIALCHARS - 1 )                /* guarantee one empty slot */
                    391:        error(FATAL, "out of table space adding character %s", s);
                    392: 
                    393:     for ( i = hash(s, SPECIALCHARS); chnames[i] != NULL; i = (i+1) % SPECIALCHARS ) ;
                    394: 
                    395:     nchnames++;
                    396:     chnames[i] = strsave(s);
                    397:     return(i+FIRSTSPECIAL);
                    398: 
                    399: }   /* End of chadd */
                    400: 
                    401: /*****************************************************************************/
                    402: 
                    403: char *chname(n)
                    404: 
                    405:     int                n;
                    406: 
                    407: {
                    408: 
                    409:     return(chnames[n-FIRSTSPECIAL]);
                    410: 
                    411: }   /* End of chname */
                    412: 
                    413: /*****************************************************************************/
                    414: 
                    415: hash(s, l)
                    416: 
                    417:     char       *s;
                    418:     int                l;
                    419: 
                    420: {
                    421: 
                    422:     unsigned   i;
                    423: 
                    424:     for ( i = 0; *s; s++ )
                    425:        i = i*10 + *s;
                    426:     return(i % l);
                    427: 
                    428: }   /* End of hash */
                    429: 
                    430: /*****************************************************************************/
                    431: 
                    432: char *strsave(s)
                    433: 
                    434:     char       *s;
                    435: 
                    436: {
                    437: 
                    438:     char       *ptr = NULL;
                    439: 
                    440:     if ( s != NULL ) {
                    441:        ptr = (char *)allocate(strlen(s)+1);
                    442:        strcpy(ptr, s);
                    443:     }  /* End if */
                    444:     return(ptr);
                    445: 
                    446: }   /* End of strsave */
                    447: 
                    448: /*****************************************************************************/
                    449: 
                    450: char *allocate(count)
                    451: 
                    452:     int                count;
                    453: 
                    454: {
                    455: 
                    456:     char       *ptr;
                    457: 
                    458:     if ( (ptr = (char *)malloc(count)) == NULL ) {
                    459:        freefonts();
                    460:        if ( (ptr = (char *)malloc(count)) == NULL )
                    461:            error(FATAL, "no memory");
                    462:     }  /* End if */
                    463:     return(ptr);
                    464: 
                    465: }   /* End of allocate */
                    466: 
                    467: /*****************************************************************************/
                    468: 
                    469: release(ptr)
                    470: 
                    471:     char       *ptr;
                    472: 
                    473: {
                    474: 
                    475:     if ( ptr != NULL )
                    476:        free(ptr);
                    477: 
                    478: }   /* End of release */
                    479: 
                    480: /*****************************************************************************/
                    481: 
                    482: dumpmount(m)
                    483: 
                    484:     int                m;
                    485: 
                    486: {
                    487: 
                    488:     if ( mount[m] != NULL )
                    489:        dumpfont((mount[m] - &fonts[0]));
                    490:     else fprintf(stderr, "no font mounted at %d\n", m);
                    491: 
                    492: }   /* End of dumpmount */
                    493: 
                    494: /*****************************************************************************/
                    495: 
                    496: dumpfont(n)
                    497: 
                    498:     int                n;
                    499: 
                    500: {
                    501: 
                    502:     int                i;
                    503:     Font       *fpos;
                    504:     char       *str;
                    505: 
                    506:     fpos = &fonts[n];
                    507: 
                    508:     if ( fpos->state ) {
                    509:        fprintf(stderr, "path %s\n", fpos->path);
                    510:        fprintf(stderr, "state %d\n", fpos->state);
                    511:        fprintf(stderr, "flags %d\n", fpos->flags);
                    512:        fprintf(stderr, "mounted %d\n", fpos->mounted);
                    513:        fprintf(stderr, "first %d\n", fpos->first);
                    514:        fprintf(stderr, "last %d\n", fpos->last);
                    515:        fprintf(stderr, "nchars %d\n", fpos->nchars);
                    516:        fprintf(stderr, "special %d\n", fpos->specfont);
                    517:        fprintf(stderr, "name %s\n", fpos->name);
                    518:        fprintf(stderr, "fontname %s\n", fpos->fontname);
                    519:        if ( fpos->state == INMEMORY ) {
                    520:            fprintf(stderr, "charset\n");
                    521:            for ( i = 0; i < fpos->nchars; i++ ) {
                    522:                if ( fpos->wp[i].num > 0 ) {
                    523:                    if ( fpos->wp[i].num <= fpos->last )
                    524:                        fprintf(stderr, "%c\t%d\t%d\n", fpos->wp[i].num,
                    525:                                fpos->wp[i].wid, fpos->wp[i].code);
                    526:                    else {
                    527:                        str = chname(fpos->wp[i].num);
                    528:                        if ( *str == '#' && isdigit(*(str+1)) && isdigit(*(str+2)) )
                    529:                            str = "---";
                    530:                        fprintf(stderr, "%s\t%d\t%d\n", str, fpos->wp[i].wid,
                    531:                                fpos->wp[i].code);
                    532:                    }   /* End else */
                    533:                }   /* End if */
                    534:            }   /* End for */
                    535:        } else fprintf(stderr, "charset: not in memory\n");
                    536:     } else fprintf(stderr, "empty font: %d\n", n);
                    537: 
                    538:     putc('\n', stderr);
                    539: 
                    540: }   /* End of dumpfont */
                    541: 
                    542: /*****************************************************************************/
                    543: 

unix.superglobalmegacorp.com

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