|
|
1.1 ! root 1: /* ! 2: * ! 3: * Program that converts IBM font files to a format that works on Unix systems. ! 4: * Essentially all the information needed came from the Adobe paper "Supporting ! 5: * Downloadable PostScript Fonts". To use the program type, ! 6: * ! 7: * ibmfont font.ibm >font.unix ! 8: * ! 9: * where font.ibm is the font file, exactly as it came over from an IBM PC, ! 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: * IBM PC 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: * Everything esle is an input file. No arguments or '-' means stdin. ! 115: * ! 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: int seg; ! 145: long ftell(); ! 146: ! 147: /* ! 148: * ! 149: * Font files on the IBM PC are stored in a compressed binary format. Individual ! 150: * segments in the file are preceeded by a header that looks like, ! 151: * ! 152: * Byte 1: 128 ! 153: * Byte 2: segment type (1=ASCII, 2=TOHEX, or 3=EOF) ! 154: * Bytes 3-6: length of the segment ! 155: * Bytes 7 ... data ! 156: * ! 157: */ ! 158: ! 159: while ( 1 ) { ! 160: seg = ftell(fp_in); ! 161: if ( getc(fp_in) != 128 ) ! 162: error(FATAL, "bad file format"); ! 163: blocktype = getc(fp_in); ! 164: blocksize = getint(fp_in); ! 165: if ( debug == ON ) { ! 166: fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize); ! 167: fprintf(stderr, "start=0%o, end=0%o\n", seg, seg+blocksize+6); ! 168: fprintf(stderr, "start=%d, end=%d\n", seg, seg+blocksize+6); ! 169: } /* End if */ ! 170: switch ( blocktype ) { ! 171: case 1: ! 172: asciitext(blocksize); ! 173: break; ! 174: ! 175: case 2: ! 176: hexdata(blocksize); ! 177: break; ! 178: ! 179: case 3: ! 180: return; ! 181: ! 182: default: ! 183: error(FATAL, "unknown resource type %d", blocktype); ! 184: } /* End switch */ ! 185: } /* End while */ ! 186: ! 187: } /* End of conv */ ! 188: ! 189: /*****************************************************************************/ ! 190: ! 191: asciitext(count) ! 192: ! 193: int count; /* bytes left in the block */ ! 194: ! 195: { ! 196: ! 197: int ch; ! 198: int i = 0; ! 199: ! 200: /* ! 201: * ! 202: * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines ! 203: * is all I've done. ! 204: * ! 205: */ ! 206: ! 207: for ( i = 0; i < count; i++ ) { ! 208: if ( (ch = getc(fp_in)) == '\r' ) ! 209: ch = '\n'; ! 210: putc(ch, fp_out); ! 211: } /* End for */ ! 212: ! 213: } /* End of asciitext */ ! 214: ! 215: /*****************************************************************************/ ! 216: ! 217: hexdata(count) ! 218: ! 219: int count; /* bytes left in the block */ ! 220: ! 221: { ! 222: ! 223: int i; ! 224: int n; ! 225: ! 226: /* ! 227: * ! 228: * Reads the next count bytes and converts each byte to hex. Also starts a new ! 229: * line every 80 hex characters. ! 230: * ! 231: */ ! 232: ! 233: for ( i = 0, n = 0; i < count; i++ ) { ! 234: fprintf(fp_out, "%.2X", getc(fp_in)); ! 235: if ( (++n % 40) == 0 ) ! 236: putc('\n', fp_out); ! 237: } /* End for */ ! 238: ! 239: } /* End of hexdata */ ! 240: ! 241: /*****************************************************************************/ ! 242: ! 243: getint() ! 244: ! 245: { ! 246: ! 247: int val; ! 248: ! 249: /* ! 250: * ! 251: * Reads the next four bytes into an integer and returns the value to the caller. ! 252: * First two bytes are probably always 0. ! 253: * ! 254: */ ! 255: ! 256: val = getc(fp_in); ! 257: val |= (getc(fp_in) << 8); ! 258: val |= (getc(fp_in) << 16); ! 259: val |= (getc(fp_in) << 24); ! 260: ! 261: return(val); ! 262: ! 263: } /* End of getint */ ! 264: ! 265: /*****************************************************************************/ ! 266: ! 267: error(kind, mesg, a1, a2, a3) ! 268: ! 269: int kind; ! 270: char *mesg; ! 271: unsigned a1, a2, a3; ! 272: ! 273: { ! 274: ! 275: /* ! 276: * ! 277: * Print mesg and quit if kind is FATAL. ! 278: * ! 279: */ ! 280: ! 281: if ( mesg != NULL && *mesg != '\0' ) { ! 282: fprintf(stderr, "%s: ", prog_name); ! 283: fprintf(stderr, mesg, a1, a2, a3); ! 284: putc('\n', stderr); ! 285: } /* End if */ ! 286: ! 287: if ( kind == FATAL && ignore == OFF ) ! 288: exit(x_stat | 01); ! 289: ! 290: } /* End of error */ ! 291: ! 292: /*****************************************************************************/ ! 293:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.