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