Annotation of researchv10dc/cmd/picasso/font.c, revision 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.