/* This program reads a MAC format Adobe Font file and unpacks it so that it can be loaded as a program into a PostScript printer. Note that it does not decrypt the file. I don't beleive that unpacking (as opposed to decrypting) should be a violation of the license agreement, but then again, I am not a lawyer. In short, as far as the legalities go, you are on your own. This program was compiled and tested on an IBM PC/AT with Turbo C Version 2.01. It should build with little trouble using any ANSI C compiler. Modifications for the Amiga: Removed the inclusion of "io.h" and added a MOTOROLA define to select the type of byte ordering. The program requires a MacBinary file of the font to do its magic. */ #include #include #include #define MOTOROLA #define COMMENT_BLOCK 0 #define ASCII_BLOCK 1 #define HEX_BLOCK 2 #define EOF_BLOCK 3 #define PREAMBLE_LENGTH 0x180L #define MAX_LINELEN 78 #define MAX_EVEN_LINELEN MAX_LINELEN & (~1) /* Define error codes */ #define E_IPO 1 #define E_COI 2 /* Can't open input */ #define E_COO 3 /* Can't open output */ #define E_BIF 4 /* Bad input file format */ const char *errmsg[] = { "\nSuccess %s\n", "\nCan't Open Input file %s\n", "\nCan't open Output file %s\n", "\nBad Input Format %s\n", "" }; void EXIT(int code,char *text) { printf(errmsg[code], text ? text : ""); exit(code); } char tohex[] = {"0123456789ABCDEF"}; /* Array to convert to hex */ /* read_block_header() The font block header consists of a Motorola-format long integer consisting of the block length (not including the length of the length field), and a byte (padded to an int) consisting of the block type. */ int read_block_header(FILE *infile, unsigned long *blksiz, int *blktyp) { int i; /* read and convert the Motorola long */ #if MOTOROLA for (i=0; i<4; i++) *((unsigned char *)blksiz+i) = (unsigned char) fgetc(infile); #else for (i=3; i>=0; i--) *((unsigned char *)blksiz+i) = (unsigned char) fgetc(infile); #endif /* get the block type */ *blktyp = fgetc(infile); /* discard the padding */ fgetc(infile); /* adjust the block size to reflect the bytes remaining to read */ *blksiz -=2L; /* flag any problem with the block type */ return (*blktyp < EOF_BLOCK); } void main (int argc, char *argv[]) { int linlen; /* length of current line */ FILE *infile; /* Input file */ FILE *outfile; /* Output file */ unsigned char ch; /* a character */ unsigned long blksiz; /* size of data block */ int blktyp; /* block type */ /* Open the input file and output file */ /* check for proper number of command-line parameters */ if (argc != 3) EXIT(E_IPO, NULL); /* identify and open input file */ if ((infile = fopen(argv[1],"rb")) == NULL) EXIT(E_COI,argv[1]); /* identify and open output file */ if ((outfile = fopen(argv[2],"wb")) == NULL) EXIT(E_COO,argv[2]); /* Macintosh font files have a preamble to discard, so seek past the preamble. */ fseek(infile, PREAMBLE_LENGTH, SEEK_SET); /* Do an initial check on the file to see if it looks like a PostScript font file. Here we check to see if the first block type in ASCII. */ read_block_header(infile, &blksiz, &blktyp); if (blktyp != 1) { printf("PostScript font program not in correct format\n"); EXIT(E_BIF, argv[1]); } /* output the PostScript "magic number" and the text to invoke the server dictionary password */ fputs("%!\n",outfile); fputs("serverdict begin 0 exitserver\n",outfile); /* reseek the start source file */ fseek(infile, PREAMBLE_LENGTH, SEEK_SET); /* while there are blocks in the source file, process them */ while (read_block_header(infile, &blksiz, &blktyp)) { switch (blktyp) { case ASCII_BLOCK: /* read and output the ASCII characters in the ASCII block */ for ( ; blksiz > 0; blksiz--) { ch = fgetc(infile); if (ch != '\015') fputc(ch,outfile); /* if not a carriage return character */ else fputs("\n",outfile); /* otherwise end the string */ } break; case HEX_BLOCK: for (linlen=MAX_EVEN_LINELEN; blksiz > 0; blksiz--, linlen-=2 ) { if (linlen <= 0) { /* force a new line */ fputs("\n",outfile); linlen=MAX_EVEN_LINELEN; } ch = fgetc(infile); fputc(tohex[ch/16], outfile); fputc(tohex[ch%16], outfile); } fputs("\n",outfile); break; default: /* skip comments */ fseek(infile, (long)blksiz, SEEK_CUR); break; } } /* Close the files and return success */ fclose(infile); fclose(outfile); EXIT(0,NULL); }