Annotation of researchv10no/cmd/postscript/dpost/font.c, revision 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.