|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.