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: }

Defined functions

AddToCharSet defined in line 385; used 1 times
CheckForSpecialness defined in line 373; used 2 times
InitTroff defined in line 51; used 1 times
PrintCharSet defined in line 408; used 1 times
ProcessEasy defined in line 437; used 1 times
ProcessTroffLigatures defined in line 342; used 1 times
WriteCleanUpFile defined in line 176; used 1 times
  • in line 63
WriteDescFile defined in line 71; used 1 times
  • in line 60
WriteFontMapFile defined in line 113; used 1 times
  • in line 61
WriteInstallFile defined in line 133; used 1 times
  • in line 62

Defined variables

CharSet defined in line 46; used 3 times
DeviceName defined in line 39; used 10 times
FontCount defined in line 49; used 3 times
LibraryDirectory defined in line 40; used 8 times
SetOfPointSizes defined in line 48; used 2 times

Defined struct's

CharElement defined in line 42; used 12 times

Defined macros

FALSE defined in line 21; never used
MAXSPECIALNAMES defined in line 30; never used
TRUE defined in line 20; used 1 times
UNITWIDTH defined in line 27; used 2 times
private defined in line 35; used 11 times
public defined in line 34; used 5 times
Last modified: 1986-01-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2297
Valid CSS Valid XHTML 1.0 Strict