[comp.fonts] Download Fonts

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 */