curtj@pogo.WV.TEK.COM (Curt Jutzi) (09/13/89)
In article <124162@sun.Eng.Sun.COM> henry%angel@Sun.COM (Henry McGilton -- Software Products) writes: > > >Unfortunately, the relevant font information -- the stuff >that comes after the eexec operator, is in some kind of >compressed eight-bit binary, that I have been unable to >determine how to uncompress. Basically, the Mac font files contain: > > some Mac specific stuff > some font file heading stuff (PostScript) > a currentfile eexec > a lot of binary stuff (1) > a bunch of zeros > a cleartomark operator > some more Mac specific stuff. > >It's section (1) that's causing problems, because it's binary. > >The question is, how do I get the stuff after the >eexec operator into seven-bit ASCII readable hex? Is >it possible to do this at all with the Mac fonts? Well .. Adobe puts out a document called Supporting Downloadable PostScript Fonts.. In it is described the way to do it.. Following is the code I wrote to unpack it.. -------------------------- cut here ---------------------------- /* Unpack: unpack an Adobe font in preparation for downloading to a PostScript device. The format for the packed font is described in "Supporting Downloadable PostScript Fonts", August 14, '87, by Glenn Reid, Adobe Systems, Inc. */ #include <stdio.h> #define FALSE 0 #define TRUE 1 /* global jive */ #define Header_Size 6 int header [Header_Size]; /* define the block types */ #define ASCII_Block 1 #define Binary_Block 2 #define End_of_File 3 int mygetc(c) FILE *c; { static loc = 0; static arr[32]; int i,j; i = getc(c); return (i); printf("%x ",i = getc(c)); arr[loc] = i; if (loc++ >= 32) { loc = 0; for (j=0;j<32;j++) printf("%c",arr[j]); printf("\n"); } return (i); } main (argc, argv, envp) int argc; char **argv; char **envp; { /* main program */ char **infilename; char **outfilename; FILE *infile; FILE *outfile; /* display the argument count */ argc--; /* check argument count */ if (argc <= 0) { printf (" Usage: unpack <infile> <outfile>\n"); exit (0); } else if (argc > 2) { printf (" Excessive arguments specified.\n"); exit (0); }; /* get pointers to file names */ infilename = ++argv; outfilename = ++argv; if ((infile = fopen (*infilename, "rb")) == NULL) { /* couldn't open the input file */ printf (" %s not found.\n", *infilename); exit (0); }; if (strcmp(*outfilename,"stdout") == 0) outfile = stdout; else if ((outfile = fopen (*outfilename, "wb")) == NULL) { /* couldn't open the output file */ printf (" %s not found.\n", *outfilename); exit (0); }; /* unpack the file. */ unpack (infile, outfile); /* close the files. */ fclose (infile); fclose (outfile); /* terminate */ exit (0); } /* end main program */ unpack (infile, outfile) /* unpack the adobe file. */ FILE *infile; FILE *outfile; { int done; unsigned char next_byte; int block_type; int ASCII_block; unsigned long int block_length; long int index; unsigned int length[100]; int ccount; /* prepare to unpack the file */ done = FALSE; /* Enter the unpacking loop */ do { /* try to read the header for another block */ if ((next_byte = mygetc (infile)) == EOF) { /* unexpected eof */ printf (" End-of-file at start of header.\n"); exit (0); } /* Is this the expected byte? */ if (next_byte != 128) { /* the expected header was absent. */ printf (" Header ID byte expected.\n"); exit (0); } /* read the block type byte. */ block_type = mygetc (infile); /* Is this a legal block type byte? */ /* if ((block_type < ASCII_block) | (block_type > End_of_File)) { printf (" Invalid block type: %03o.\n", block_type); exit (0); } */ /* This is a valid block type. Is this an end of file? */ if ((int) block_type == End_of_File) { /* yes. exit the loop */ break; } /* read the header length */ for (index = 0; index < 4; ++index) { if ((length [index] = mygetc (infile)) == EOF) { printf (" End-of-file in length bytes.\n"); exit (0); } } /* convert the length */ block_length = 0; for (index = 4; index >= 0; --index) { /* add the next bytes length */ block_length = 256 * block_length + length [index]; } /* process according to block type */ if (block_type == ASCII_Block) { /* copy ASCII characters */ for (index = 0; index < block_length; ++index) { /* read the next byte */ if ((next_byte = mygetc (infile)) == EOF) { /* end of file in mid-block */ printf (" End-of-file in ASCII block.\n"); exit (0); } /* write the byte */ if (next_byte == '\r') fprintf (outfile, "\n"); else fprintf (outfile, "%c", next_byte); } } else if (block_type == Binary_Block) { /* process a binary data block start the hex string */ /* copy the block of characters */ for (ccount = 0,index = 0; index < block_length; ++index) { /* read the next character */ next_byte = mygetc (infile); /* write as a pair of hex digits */ fprintf (outfile, "%02x", next_byte); ccount += 2; if (ccount > 76) { fprintf(outfile, "\n"); ccount = 0; } } fprintf(outfile, "\n"); } else if (block_type == End_of_File) { printf("EOF\n"); exit(0); } else { printf("SHIT\n"); exit(0); } } while (!done); }; /* end unpack */ Newsgroups: poster Subject: Re: Downloadable Fonts Summary: Expires: References: <124162@sun.Eng.Sun.COM> Sender: Reply-To: curtj@pogo.WV.TEK.COM (Curt Jutzi) Followup-To: Distribution: usa Organization: Tektronix, Inc., Wilsonville, OR. Keywords: Download, compressed, fonts, Macintosh In article <124162@sun.Eng.Sun.COM> henry%angel@Sun.COM (Henry McGilton -- Software Products) writes: > > >Unfortunately, the relevant font information -- the stuff >that comes after the eexec operator, is in some kind of >compressed eight-bit binary, that I have been unable to >determine how to uncompress. Basically, the Mac font files contain: > > some Mac specific stuff > some font file heading stuff (PostScript) > a currentfile eexec > a lot of binary stuff (1) > a bunch of zeros > a cleartomark operator > some more Mac specific stuff. > >It's section (1) that's causing problems, because it's binary. > >The question is, how do I get the stuff after the >eexec operator into seven-bit ASCII readable hex? Is >it possible to do this at all with the Mac fonts? Well .. Adobe puts out a document called Supporting Downloadable PostScript Fonts.. In it is described the way to do it.. Following is the code I wrote to unpack it.. -------------------------- cut here ---------------------------- /* Unpack: unpack an Adobe font in preparation for downloading to a PostScript device. The format for the packed font is described in "Supporting Downloadable PostScript Fonts", August 14, '87, by Glenn Reid, Adobe Systems, Inc. */ #include <stdio.h> #define FALSE 0 #define TRUE 1 /* global jive */ #define Header_Size 6 int header [Header_Size]; /* define the block types */ #define ASCII_Block 1 #define Binary_Block 2 #define End_of_File 3 int mygetc(c) FILE *c; { static loc = 0; static arr[32]; int i,j; i = getc(c); return (i); printf("%x ",i = getc(c)); arr[loc] = i; if (loc++ >= 32) { loc = 0; for (j=0;j<32;j++) printf("%c",arr[j]); printf("\n"); } return (i); } main (argc, argv, envp) int argc; char **argv; char **envp; { /* main program */ char **infilename; char **outfilename; FILE *infile; FILE *outfile; /* display the argument count */ argc--; /* check argument count */ if (argc <= 0) { printf (" Usage: unpack <infile> <outfile>\n"); exit (0); } else if (argc > 2) { printf (" Excessive arguments specified.\n"); exit (0); }; /* get pointers to file names */ infilename = ++argv; outfilename = ++argv; if ((infile = fopen (*infilename, "rb")) == NULL) { /* couldn't open the input file */ printf (" %s not found.\n", *infilename); exit (0); }; if (strcmp(*outfilename,"stdout") == 0) outfile = stdout; else if ((outfile = fopen (*outfilename, "wb")) == NULL) { /* couldn't open the output file */ printf (" %s not found.\n", *outfilename); exit (0); }; /* unpack the file. */ unpack (infile, outfile); /* close the files. */ fclose (infile); fclose (outfile); /* terminate */ exit (0); } /* end main program */ unpack (infile, outfile) /* unpack the adobe file. */ FILE *infile; FILE *outfile; { int done; unsigned char next_byte; int block_type; int ASCII_block; unsigned long int block_length; long int index; unsigned int length[100]; int ccount; /* prepare to unpack the file */ done = FALSE; /* Enter the unpacking loop */ do { /* try to read the header for another block */ if ((next_byte = mygetc (infile)) == EOF) { /* unexpected eof */ printf (" End-of-file at start of header.\n"); exit (0); } /* Is this the expected byte? */ if (next_byte != 128) { /* the expected header was absent. */ printf (" Header ID byte expected.\n"); exit (0); } /* read the block type byte. */ block_type = mygetc (infile); /* Is this a legal block type byte? */ /* if ((block_type < ASCII_block) | (block_type > End_of_File)) { printf (" Invalid block type: %03o.\n", block_type); exit (0); } */ /* This is a valid block type. Is this an end of file? */ if ((int) block_type == End_of_File) { /* yes. exit the loop */ break; } /* read the header length */ for (index = 0; index < 4; ++index) { if ((length [index] = mygetc (infile)) == EOF) { printf (" End-of-file in length bytes.\n"); exit (0); } } /* convert the length */ block_length = 0; for (index = 4; index >= 0; --index) { /* add the next bytes length */ block_length = 256 * block_length + length [index]; } /* process according to block type */ if (block_type == ASCII_Block) { /* copy ASCII characters */ for (index = 0; index < block_length; ++index) { /* read the next byte */ if ((next_byte = mygetc (infile)) == EOF) { /* end of file in mid-block */ printf (" End-of-file in ASCII block.\n"); exit (0); } /* write the byte */ if (next_byte == '\r') fprintf (outfile, "\n"); else fprintf (outfile, "%c", next_byte); } } else if (block_type == Binary_Block) { /* process a binary data block start the hex string */ /* copy the block of characters */ for (ccount = 0,index = 0; index < block_length; ++index) { /* read the next character */ next_byte = mygetc (infile); /* write as a pair of hex digits */ fprintf (outfile, "%02x", next_byte); ccount += 2; if (ccount > 76) { fprintf(outfile, "\n"); ccount = 0; } } fprintf(outfile, "\n"); } else if (block_type == End_of_File) { printf("EOF\n"); exit(0); } else { printf("SHIT\n"); exit(0); } } while (!done); }; /* end unpack */