Annotation of researchv10no/cmd/post.src/misc/macfont.c, revision 1.1.1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.