Annotation of researchv10dc/cmd/picasso/font.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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