Annotation of 43BSDTahoe/new/dipress/src/bin/ipmetrics/troff.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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