Annotation of 43BSD/contrib/dipress/src/bin/ipmetrics/troff.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1984, 1985 Xerox Corp.
                      3:  * Handle troff here
                      4:  *
                      5:  * note that Troff uses "fat points" of which there are exactly 72 per inch.
                      6:  *
                      7:  *  HISTORY
                      8:  *     Nov, 1985       Lee Moore, Xerox Webster Research Center
                      9:  *             Created.
                     10:  */
                     11: 
                     12: #include <stdio.h>
                     13: #include <math.h>
                     14: #include "stack.h"
                     15: #include "token.h"
                     16: #include "config.h"
                     17: #include "ipmetrics.h"
                     18: #include "troff.h"
                     19: 
                     20: #define TRUE   1
                     21: #define FALSE  0
                     22: 
                     23: 
                     24: /* the following value should be choosen so that none of the widths
                     25:  * is greater than 256
                     26:  */
                     27: #define UNITWIDTH      5       /* was 10 */
                     28: 
                     29: 
                     30: #define MAXSPECIALNAMES        221     /* maximum number of special characters.
                     31:                                 * this constant is fixed in Troff
                     32:                                 */
                     33: 
                     34: #define public
                     35: #define private        static
                     36: 
                     37: public char *malloc();
                     38: 
                     39: public char *DeviceName,
                     40:            *LibraryDirectory;
                     41: 
                     42: struct CharElement {
                     43:        struct CharElement *Next;
                     44:        char CharName[3]; };
                     45: 
                     46: private struct CharElement *CharSet = NULL;
                     47: 
                     48: private int SetOfPointSizes[MAXPOINTSIZE],
                     49:            FontCount = 0;
                     50: 
                     51: public
                     52: InitTroff() {
                     53: }
                     54: 
                     55: public
                     56: CleanUpTroff(configChain)
                     57:     struct FontConfig *configChain; {
                     58:        struct FontConfig *p;
                     59: 
                     60:        WriteDescFile(configChain);
                     61:        WriteFontMapFile(configChain);
                     62:        WriteInstallFile(configChain);
                     63:        WriteCleanUpFile(configChain);
                     64: 
                     65:        for( p = configChain; p != NULL; p = p->Next )
                     66:                if( !p->SeenFlag )
                     67:                        printf("couldn't find: %s/%s/%s\n",
                     68:                                p->FontPt1, p->FontPt2, p->FontPt3);
                     69: }
                     70: 
                     71: private
                     72: WriteDescFile(configChain)
                     73:     struct FontConfig *configChain; {
                     74:        int i;
                     75:        FILE *deviceFile;
                     76:        struct FontConfig *p;
                     77: 
                     78:        if( (deviceFile = fopen("DESC", "w")) == NULL ) {
                     79:            printf("can't open 'DESC' for writing\n");
                     80:            exit(1); }
                     81: 
                     82:        /* output boiler plate */
                     83:        fprintf(deviceFile, "# describe the '%s' interpress device\n", DeviceName);
                     84:        fprintf(deviceFile, "res %d\n", MICAS_PER_INCH);
                     85:        fprintf(deviceFile, "hor 1\n");
                     86:        fprintf(deviceFile, "vert 1\n");
                     87:        fprintf(deviceFile, "unitwidth %d\n", UNITWIDTH);
                     88:        fprintf(deviceFile, "paperwidth %d\n", PAGE_WIDTH_IN_MICAS);
                     89:        fprintf(deviceFile, "paperlength %d\n", PAGE_HEIGHT_IN_MICAS);
                     90: 
                     91:        /* output sizes */
                     92:        fprintf(deviceFile, "sizes ");
                     93: 
                     94:        for( i = 1; i < MAXPOINTSIZE; i++ )
                     95:            if( SetOfPointSizes[i] )
                     96:                fprintf(deviceFile," %d", i);
                     97: 
                     98:        fprintf(deviceFile, " 0\n");
                     99: 
                    100:        /* output fonts */
                    101:        fprintf(deviceFile, "fonts %d ", FontCount);
                    102: 
                    103:        for( p = configChain; p != NULL; p = p->Next )
                    104:                if( p->SeenFlag )
                    105:                        fprintf(deviceFile, "%s ", p->TroffName);
                    106: 
                    107:        fprintf(deviceFile, "\n");
                    108:        PrintCharSet(deviceFile);
                    109:        fclose(deviceFile); }
                    110: 
                    111: 
                    112: 
                    113: private
                    114: WriteFontMapFile(configChain)
                    115:     struct FontConfig *configChain; {
                    116:        int i;
                    117:        FILE *fontMapFile;
                    118:        struct FontConfig *p;
                    119: 
                    120:        if( (fontMapFile = fopen(FONTMAPFILENAME, "w")) == NULL ) {
                    121:            fprintf(stderr, "can't open the file '%s' for writing\n", FONTMAPFILENAME);
                    122:            return; }
                    123: 
                    124:        for( p = configChain; p != NULL; p = p->Next )
                    125:                if( p->SeenFlag )
                    126:                        fprintf(fontMapFile, "%s %s/%s/%s\n", p->TroffName,
                    127:                                p->FontPt1, p->FontPt2, p->FontPt3);
                    128: 
                    129:        fclose(fontMapFile);
                    130:        chmod(FONTMAPFILENAME, 0755); }
                    131: 
                    132: 
                    133: private
                    134: WriteInstallFile(configChain)
                    135:     struct FontConfig *configChain; {
                    136:        int i;
                    137:        FILE *installFile;
                    138:        struct FontConfig *p;
                    139: 
                    140:        if( (installFile = fopen(INSTALLNAME, "w")) == NULL ) {
                    141:            fprintf(stderr, "can't open the file 'install' for writing\n");
                    142:            return; }
                    143: 
                    144:        fprintf(installFile, "#! /bin/sh\n");
                    145:        fprintf(installFile, "if test ! -d %s/fonts/%s\n", LibraryDirectory, DeviceName);
                    146:        fprintf(installFile, "  then\n");
                    147:        fprintf(installFile, "    mkdir %s/fonts/%s\n", LibraryDirectory, DeviceName);
                    148:        fprintf(installFile, "  fi\n");
                    149:        fprintf(installFile, "if test ! -d %s/fonts/%s/devipress\n", LibraryDirectory, DeviceName);
                    150:        fprintf(installFile, "  then\n");
                    151:        fprintf(installFile, "    mkdir %s/fonts/%s/devipress\n", LibraryDirectory, DeviceName);
                    152:        fprintf(installFile, "  fi\n");
                    153: 
                    154: 
                    155:        for( p = configChain; p != NULL; p = p->Next )
                    156:                if( p->SeenFlag )
                    157:                        fprintf(installFile, "cp %s %s/fonts/%s/devipress\n",
                    158:                                p->TroffName, LibraryDirectory, DeviceName);
                    159: 
                    160:        fprintf(installFile, "cp DESC %s/fonts/%s/devipress\n", LibraryDirectory,
                    161:                        DeviceName);
                    162:        fprintf(installFile, "cp %s %s/fonts/%s/devipress\n", FONTMAPFILENAME,
                    163:                        LibraryDirectory, DeviceName);
                    164:        fprintf(installFile, "cd %s/fonts/%s/devipress\n", LibraryDirectory,
                    165:                        DeviceName);
                    166:        fprintf(installFile, "makedev DESC\n");
                    167:        fprintf(installFile, "makextdev DESC\n");
                    168:        fclose(installFile);
                    169:        chmod(INSTALLNAME, 0755); }
                    170: 
                    171: 
                    172: /*
                    173:  * write a file that rm's all the files created by this program
                    174:  */
                    175: 
                    176: private
                    177: WriteCleanUpFile(configChain)
                    178:     struct FontConfig *configChain; {
                    179:        int i;
                    180:        FILE *cleanupFile;
                    181:        struct FontConfig *p;
                    182: 
                    183:        if( (cleanupFile = fopen(CLEANUPNAME, "w")) == NULL ) {
                    184:            fprintf(stderr, "can't open the file 'cleanup' for writing\n");
                    185:            return; }
                    186: 
                    187:        fprintf(cleanupFile, "#! /bin/sh\n");
                    188: 
                    189:        for( p = configChain; p != NULL; p = p->Next )
                    190:                if( p->SeenFlag )
                    191:                        fprintf(cleanupFile, "rm %s\n", p->TroffName);
                    192: 
                    193:        fprintf(cleanupFile, "rm DESC\n");
                    194:        fprintf(cleanupFile, "rm %s\n", INSTALLNAME);
                    195:        fprintf(cleanupFile, "rm %s\n", FONTMAPFILENAME);
                    196:        fprintf(cleanupFile, "rm %s\n", CLEANUPNAME);
                    197:        fclose(cleanupFile);
                    198:        chmod(CLEANUPNAME, 0755); }
                    199: 
                    200: /*
                    201:  * called once per font on the stack
                    202:  */
                    203: 
                    204: public
                    205: PerTroffFont(configChain, fontDescVec)
                    206:     struct FontConfig *configChain;
                    207:     unsigned char *fontDescVec; {
                    208:        unsigned char *charMetricsProperty,
                    209:                      *metricsProperty,
                    210:                      *width,
                    211:                      *charMetric;
                    212:        char iSender[MAXTOKENSIZE],
                    213:             iCharName[MAXTOKENSIZE],
                    214:             fileType[MAXTOKENSIZE],
                    215:            *fontName[3],
                    216:             iCharSet[MAXTOKENSIZE],
                    217:             iCharCode[MAXTOKENSIZE];
                    218:        FILE *descFile,
                    219:             *modelFile;
                    220:        struct FontConfig *p;
                    221:        struct TokenState *ts;
                    222:        int charSet,
                    223:            charNumber,
                    224:            charIndex,
                    225:            xWidth;
                    226: 
                    227:        if( !GetFontNameProperty(fontDescVec, fontName) ) {
                    228:                fprintf(stderr, "ipmetrics: can't get font name\n");
                    229:                return;
                    230:        }
                    231: 
                    232:        if( (charMetricsProperty = GetStringProp("characterMetrics", fontDescVec))
                    233:                        == NULL ) {
                    234:                printf("ipmetrics: can't find 'characterMetrics' property\n");
                    235:                return; }
                    236: 
                    237:        for( p = configChain; p != NULL; p = p->Next ) {
                    238:                if( !(strcmp(p->FontPt1,  fontName[0]) == 0 &&
                    239:                            strcmp(p->FontPt2,  fontName[1]) == 0 &&
                    240:                            strcmp(p->FontPt3,  fontName[2]) == 0) )
                    241:                        continue;
                    242: 
                    243:                if( (descFile = fopen(p->TroffName , "w")) == NULL ) {
                    244:                        printf("ipmetrics: can't open %s for writing\n", p->TroffName);
                    245:                        return;}
                    246:        
                    247:                if( (modelFile = fopen(p->MapFile, "r")) == NULL ) {
                    248:                        printf("ipmetrics: can't open %s for reading\n", p->MapFile);
                    249:                        return;}
                    250: 
                    251:                p->SeenFlag = TRUE;
                    252: /*             (void) strcpy(malloc((unsigned) 3), p->TroffName);      */
                    253:                FontCount++;
                    254:        
                    255:                ts = InitTokenStream(modelFile);
                    256:        
                    257:                fprintf(descFile, "#\n");
                    258:                fprintf(descFile, "# %s/%s/%s for Interpress device %s\n", p->FontPt1, p->FontPt2, p->FontPt3, DeviceName);
                    259:                fprintf(descFile, "name %s\n", p->TroffName);
                    260:                fprintf(descFile, "internalname %d\n", FontCount);
                    261:        
                    262:                GetToken(ts, fileType, MAXTOKENSIZE);
                    263:        
                    264:                if( strcmp(fileType, "special") == 0 )
                    265:                        fprintf(descFile, "special\n");
                    266:                else
                    267:                        ProcessTroffLigatures(charMetricsProperty, descFile);
                    268:        
                    269:                fprintf(descFile, "charset\n");
                    270:        
                    271:                while( !EndOfFile(ts) ) {
                    272:                        GetToken(ts, iCharSet, MAXTOKENSIZE);
                    273:                        sscanf(iCharSet, "%o", &charSet);
                    274:                        GetToken(ts, iCharCode, MAXTOKENSIZE);
                    275:                        sscanf(iCharCode, "%o", &charNumber);
                    276:                        GetToken(ts, iSender, MAXTOKENSIZE);
                    277:                        GetToken(ts, iCharName, MAXTOKENSIZE);
                    278:                        charIndex = Make16BitChar(charSet, charNumber);
                    279:        
                    280:                        /* skip the rest of this loop if it's not in this font */
                    281:                        if( (charMetric =
                    282:                            GetIntegerProp(charIndex, charMetricsProperty)) == NULL )
                    283:                                continue;
                    284:        
                    285:                        if( (width = GetStringProp("widthX", charMetric)) == NULL ){
                    286:                                printf("ipmetrics: can't find widthX property of %d\n",
                    287:                                        charIndex);
                    288:                                continue;}
                    289:        
                    290:                        if( gettype(width) != type_number ) {
                    291:                                printf("ipmetrics: width not of type number for %d\n",
                    292:                                        charIndex);
                    293:                                continue;}
                    294:        
                    295:                        if( getsubtype(width) != subtype_rational ) {
                    296:                                printf("ipmetrics: width not of subtype number for %d\n",
                    297:                                        charIndex);
                    298:                                continue;}
                    299:        
                    300:                        xWidth = (getnumerator(width)*UNITWIDTH*MICAS_PER_INCH +
                    301:                                 (getdenominator(width) * POINTS_PER_INCH)/2)/
                    302:                                 (getdenominator(width) * POINTS_PER_INCH);
                    303:        
                    304:                        if( xWidth >= 256 )
                    305:                                printf("ipmetrics: warning width >= 256\n");
                    306:        
                    307:                        fprintf(descFile, "%s\t%d\t%s\t", iCharName, xWidth,
                    308:                                iSender);
                    309:        
                    310:                        if( charIndex < 0377 )
                    311:                                fprintf(descFile, "%d\n", charIndex);
                    312:                        else
                    313:                                fprintf(descFile, "0377\t0%o\n", charIndex);
                    314:        
                    315:                        CheckForSpecialness(iCharName);
                    316:        
                    317:                        while( !EndOfLine(ts) ) {
                    318:                                GetToken(ts, iCharName, MAXTOKENSIZE);
                    319:                                fprintf(descFile, "%s\t\"\n", iCharName);
                    320:                                CheckForSpecialness(iCharName);}}
                    321:        
                    322:                CloseTokenStream(ts);
                    323:                fclose(descFile);
                    324:                fclose(modelFile);
                    325:        }
                    326: 
                    327:        if( (metricsProperty = GetStringProp("metrics", fontDescVec))
                    328:                        != NULL ) {
                    329:                unsigned char *easyProperty;
                    330: 
                    331:                if( (easyProperty = GetStringProp("easy", metricsProperty))
                    332:                                != NULL ) 
                    333:                        ProcessEasy(easyProperty);
                    334:        }
                    335: }
                    336: 
                    337: /*
                    338:  * assume that the font is in XC1-1-1 standard and find the ligatures
                    339:  * that troff wants
                    340:  */
                    341: 
                    342: private
                    343: ProcessTroffLigatures(charMetricsVec, descFile)
                    344:     unsigned char *charMetricsVec;
                    345:     FILE *descFile; {
                    346:        char ligatureNames[21];
                    347: 
                    348:        (void) strcpy(ligatureNames, "");
                    349: 
                    350:        if( GetIntegerProp(Make16BitChar(0360, 044), charMetricsVec) != NULL )
                    351:            (void) strcat(ligatureNames, " fi");
                    352: 
                    353:        if( GetIntegerProp(Make16BitChar(0360, 045), charMetricsVec) != NULL )
                    354:            (void) strcat(ligatureNames, " fl");
                    355: 
                    356:        if( GetIntegerProp(Make16BitChar(0360, 041), charMetricsVec) != NULL )
                    357:            (void) strcat(ligatureNames, " ff");
                    358: 
                    359:        if( GetIntegerProp(Make16BitChar(0360, 042), charMetricsVec) != NULL )
                    360:            (void) strcat(ligatureNames, " ffi");
                    361: 
                    362:        if( GetIntegerProp(Make16BitChar(0360, 043), charMetricsVec) != NULL )
                    363:            (void) strcat(ligatureNames, " ffl");
                    364: 
                    365:        if( strcmp(ligatureNames, "") != 0 )
                    366:                fprintf(descFile, "ligatures %s 0\n", ligatureNames);}
                    367: 
                    368: /*
                    369:  * Check to see if a character is special and add it to the "charset"
                    370:  * in the DESC file if it is.
                    371:  */
                    372: 
                    373: private
                    374: CheckForSpecialness(s)
                    375:     char *s; {
                    376:        /* right now, if it two characters long, then it must be special */
                    377:        if( strlen(s) == 2 )
                    378:            AddToCharSet(s); }
                    379: 
                    380: /*
                    381:  * add a special character to the set of special characters.  The set
                    382:  * is implemented as a linked list.
                    383:  */
                    384: 
                    385: private
                    386: AddToCharSet(s)
                    387:     char *s; {
                    388:        struct CharElement **p,
                    389:                            *q;
                    390: 
                    391:        p = &CharSet;
                    392: 
                    393:        while( *p != NULL ) {
                    394:            if( strcmp(s, (*p)->CharName) == 0 )
                    395:                return;
                    396: 
                    397:            p = &(*p)->Next; }
                    398: 
                    399:        q = (struct CharElement *) malloc((unsigned) sizeof(struct CharElement));
                    400:        (void) strcpy(q->CharName, s);
                    401:        q->Next = NULL;
                    402:        *p = q; }
                    403: 
                    404: /*
                    405:  * print out the list of special characters to the DESC file
                    406:  */
                    407:        
                    408: private
                    409: PrintCharSet(file)
                    410:     FILE *file; {
                    411:        int itemsPerLine;
                    412:        struct CharElement *p;
                    413: 
                    414:        /* test to see if there is a char. set.  ditroff requires this!
                    415:          * you just can't have a null charset! */
                    416:        if( CharSet == NULL )
                    417:            return;
                    418: 
                    419:        fprintf(file, "charset\n");
                    420:        itemsPerLine = 0;
                    421: 
                    422:        for( p = CharSet; p != NULL; p = p->Next ) {
                    423:            fprintf(file, " %s", p->CharName);
                    424: 
                    425:            if( itemsPerLine++ > 20 ) {
                    426:                fputc('\n', file);
                    427:                itemsPerLine = 0; } }
                    428: 
                    429:        if( itemsPerLine != 0 )
                    430:            fputc('\n', file); }
                    431: 
                    432: /*
                    433:  * Process the "easy" property of the "metrics" property.  This
                    434:  * will tell us what (viewing) sizes the font is available in.
                    435:  */
                    436: 
                    437: private
                    438: ProcessEasy(easyProperty)
                    439: unsigned char *easyProperty; {
                    440:        int     depth,
                    441:                i;
                    442:        unsigned char **array;
                    443:        
                    444:        if( gettype(easyProperty) != type_vector  ||
                    445:            getsubtype(easyProperty) != subtype_general ) {
                    446:                printf("ipmetrics: wrong vector type in 'easy'\n");
                    447:                return; }
                    448: 
                    449:        depth = getdepth(easyProperty);
                    450:        array = getvector(easyProperty);
                    451: 
                    452:        for( i = 0; i < depth; i++ ) {
                    453:                double *transform,
                    454:                        fPointSize;
                    455:                int iPointSize;
                    456: 
                    457:                if( gettype(array[i]) != type_transformation ) {
                    458:                        printf("ipmetrics: transforms not found in 'easy'\n");
                    459:                        return; }
                    460: 
                    461:                transform = gettransformation(array[i]);
                    462: 
                    463:                if( transform[0] != transform[4] ) {
                    464:                        printf("ipmetrics: only square transforms in 'easy'\n");
                    465:                        return; }
                    466: 
                    467:                if( transform[1] != 0  ||  transform[2] != 0  ||
                    468:                    transform[3] != 0  ||  transform[5] != 0  ) {
                    469:                        printf("ipmetrics: troff doesn't support rotations\n");
                    470:                        return; }
                    471: 
                    472:                fPointSize = transform[0]*72*100000/2540;
                    473:                iPointSize = fPointSize + 0.5;
                    474: 
                    475:                if( fabs(fPointSize - iPointSize) > .25 ) {
                    476:                        printf("ipmetrics: troff doesn't support fractional points: %f6.2\n", fPointSize);
                    477:                        return; }
                    478: 
                    479:                SetOfPointSizes[iPointSize] = 1;
                    480:                free((char *) transform);
                    481:        }
                    482: 
                    483:        free((char *) array);
                    484: }

unix.superglobalmegacorp.com

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