|
|
1.1 ! root 1: /* ! 2: * ! 3: * Program that converts Macintosh font files to a format that works on Unix ! 4: * systems. Essentially all the information needed came from the Adobe paper ! 5: * "Supporting Downloadable PostScript Fonts". To use the program type, ! 6: * ! 7: * macfont font.mac >font.unix ! 8: * ! 9: * where font.mac is the font file, exactly as it came over from a Macintosh, ! 10: * and font.unix is equivalent host resident font file usable on Unix systems. ! 11: * ! 12: */ ! 13: ! 14: #include <stdio.h> ! 15: #include <signal.h> ! 16: ! 17: #define OFF 0 ! 18: #define ON 1 ! 19: ! 20: #define NON_FATAL 0 ! 21: #define FATAL 1 ! 22: ! 23: #define FALSE 0 ! 24: #define TRUE 1 ! 25: ! 26: char **argv; ! 27: int argc; ! 28: ! 29: char *prog_name; ! 30: ! 31: int x_stat; ! 32: int debug = OFF; ! 33: int ignore = OFF; ! 34: ! 35: FILE *fp_in = stdin; ! 36: FILE *fp_out = stdout; ! 37: ! 38: /*****************************************************************************/ ! 39: ! 40: main(agc, agv) ! 41: ! 42: int agc; ! 43: char *agv[]; ! 44: ! 45: { ! 46: ! 47: /* ! 48: * ! 49: * Macintosh to Unix font converter. ! 50: * ! 51: */ ! 52: ! 53: argc = agc; ! 54: argv = agv; ! 55: prog_name = argv[0]; ! 56: ! 57: options(); ! 58: arguments(); ! 59: exit(x_stat); ! 60: ! 61: } /* End of main */ ! 62: ! 63: /*****************************************************************************/ ! 64: ! 65: options() ! 66: ! 67: { ! 68: ! 69: int ch; ! 70: char *names = "DI"; ! 71: ! 72: extern char *optarg; ! 73: extern int optind; ! 74: ! 75: /* ! 76: * ! 77: * Command line options. ! 78: * ! 79: */ ! 80: ! 81: while ( (ch = getopt(argc, argv, names)) != EOF ) { ! 82: switch ( ch ) { ! 83: case 'D': /* debug flag */ ! 84: debug = ON; ! 85: break; ! 86: ! 87: case 'I': /* ignore FATAL errors */ ! 88: ignore = ON; ! 89: break; ! 90: ! 91: case '?': /* don't understand the option */ ! 92: error(FATAL, ""); ! 93: break; ! 94: ! 95: default: /* don't know what to do for ch */ ! 96: error(FATAL, "missing case for option %c\n", ch); ! 97: break; ! 98: } /* End switch */ ! 99: } /* End while */ ! 100: ! 101: argc -= optind; ! 102: argv += optind; ! 103: ! 104: } /* End of options */ ! 105: ! 106: /*****************************************************************************/ ! 107: ! 108: arguments() ! 109: ! 110: { ! 111: ! 112: ! 113: /* ! 114: * ! 115: * Everything else is an input file. No arguments or '-' means stdin. ! 116: * ! 117: */ ! 118: ! 119: if ( argc < 1 ) ! 120: conv(); ! 121: else ! 122: while ( argc > 0 ) { ! 123: if ( strcmp(*argv, "-") == 0 ) ! 124: fp_in = stdin; ! 125: else if ( (fp_in = fopen(*argv, "r")) == NULL ) ! 126: error(FATAL, "can't open %s", *argv); ! 127: conv(); ! 128: if ( fp_in != stdin ) ! 129: fclose(fp_in); ! 130: argc--; ! 131: argv++; ! 132: } /* End while */ ! 133: ! 134: } /* End of arguments */ ! 135: ! 136: /*****************************************************************************/ ! 137: ! 138: conv() ! 139: ! 140: { ! 141: ! 142: int blocksize; ! 143: int blocktype; ! 144: ! 145: /* ! 146: * ! 147: * The first four bytes (in a block) are the block size, the fifth is the block ! 148: * type, and the sixth always appears to be NULL. Type 0 blocks are comments and ! 149: * are always skipped. Type 1 blocks are ASCII text, type 2 is binary data that ! 150: * should be converted to hex, while type 5 blocks represent the end of the font ! 151: * file. Commment block lengths appear to be from the first byte, while other ! 152: * lengths seem to be measured from block type byte (ie. the fifth byte). Type ! 153: * four blocks aren't used, while type 3 blocks mean an end of file indication ! 154: * should be sent to the printer. Haven't done anything with type 3 blocks. ! 155: * ! 156: */ ! 157: ! 158: while ( 1 ) { ! 159: blocksize = getint(fp_in); ! 160: blocktype = getc(fp_in); ! 161: getc(fp_in); ! 162: if ( debug == ON ) ! 163: fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize); ! 164: switch ( blocktype ) { ! 165: case 0: /* comment - skip blockcount bytes */ ! 166: fseek(fp_in, (long) blocksize - 6, 1); ! 167: break; ! 168: ! 169: case 1: ! 170: asciitext(blocksize - 2); ! 171: break; ! 172: ! 173: case 2: ! 174: hexdata(blocksize - 2); ! 175: break; ! 176: ! 177: case 3: ! 178: case 4: ! 179: error(FATAL, "resource type %d not implemented", blocktype); ! 180: break; ! 181: ! 182: case 5: ! 183: return; ! 184: ! 185: default: ! 186: error(FATAL, "unknown resource type %d", blocktype); ! 187: } /* End switch */ ! 188: } /* End while */ ! 189: ! 190: } /* End of conv */ ! 191: ! 192: /*****************************************************************************/ ! 193: ! 194: asciitext(count) ! 195: ! 196: int count; /* bytes left in the block */ ! 197: ! 198: { ! 199: ! 200: int ch; ! 201: int i = 0; ! 202: ! 203: /* ! 204: * ! 205: * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines ! 206: * is all I've done. ! 207: * ! 208: */ ! 209: ! 210: for ( i = 0; i < count; i++ ) { ! 211: if ( (ch = getc(fp_in)) == '\r' ) ! 212: ch = '\n'; ! 213: putc(ch, fp_out); ! 214: } /* End for */ ! 215: ! 216: } /* End of asciitext */ ! 217: ! 218: /*****************************************************************************/ ! 219: ! 220: hexdata(count) ! 221: ! 222: int count; /* bytes left in the block */ ! 223: ! 224: { ! 225: ! 226: int i; ! 227: int n; ! 228: ! 229: /* ! 230: * ! 231: * Reads the next count bytes and converts each byte to hex. Also starts a new ! 232: * line every 80 hex characters. ! 233: * ! 234: */ ! 235: ! 236: for ( i = 0, n = 0; i < count; i++ ) { ! 237: fprintf(fp_out, "%.2X", getc(fp_in)); ! 238: if ( (++n % 40) == 0 ) ! 239: putc('\n', fp_out); ! 240: } /* End for */ ! 241: ! 242: } /* End of hexdata */ ! 243: ! 244: /*****************************************************************************/ ! 245: ! 246: getint() ! 247: ! 248: { ! 249: ! 250: int val; ! 251: int i; ! 252: ! 253: /* ! 254: * ! 255: * Reads the next four bytes into an integer and returns the value to the caller. ! 256: * First two bytes are probably always 0. ! 257: * ! 258: */ ! 259: ! 260: for ( i = 0, val = (getc(fp_in) & 0377); i < 3; i++ ) ! 261: val = (val << 8) | (getc(fp_in) & 0377); ! 262: ! 263: return(val); ! 264: ! 265: } /* End of getint */ ! 266: ! 267: /*****************************************************************************/ ! 268: ! 269: error(kind, mesg, a1, a2, a3) ! 270: ! 271: ! 272: int kind; ! 273: char *mesg; ! 274: unsigned a1, a2, a3; ! 275: ! 276: { ! 277: ! 278: /* ! 279: * ! 280: * Print *mesg then quit if kind is FATAL. ! 281: * ! 282: */ ! 283: ! 284: if ( mesg != NULL && *mesg != '\0' ) { ! 285: fprintf(stderr, "%s: ", prog_name); ! 286: fprintf(stderr, mesg, a1, a2, a3); ! 287: putc('\n', stderr); ! 288: } /* End if */ ! 289: ! 290: if ( kind == FATAL && ignore == OFF ) ! 291: exit(x_stat | 01); ! 292: ! 293: } /* End of error */ ! 294: ! 295: /*****************************************************************************/ ! 296:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.