Annotation of 43BSDTahoe/new/dipress/src/bin/ipmetrics/troff.c, revision 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.