home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / pfb2ps / unfont.c < prev    next >
C/C++ Source or Header  |  1991-04-10  |  5KB  |  289 lines

  1. /*
  2.  * NOTICE
  3.  *
  4.  * Copyright 1988, 1989 by h-three Systems Corporation.
  5.  *
  6.  * Permission is hereby granted for this software's free reproduction
  7.  * and modification for non-commercial purposes, provided that this
  8.  * notice is retained. Commercial enterprises may give away copies
  9.  * as part of their products provided that they do so without charge,
  10.  * that they retain this notice, and that they acknowledge the source
  11.  * of the software.
  12.  *
  13.  *    PostScript is a registered trademark of Adobe Systems Incorporated.
  14.  *    IBM is a registered trademark of International Business Machines
  15.  *      Corporation.
  16.  *
  17.  *    h-three Systems Corporation
  18.  *    100 Park Drive Suite 204/ P.O. Box 12557
  19.  *    Research Triangle Park, NC  27709
  20.  */
  21.  
  22. #ifdef NOWHAT
  23. static char *sccsid = "%W% - %E%";
  24. #endif
  25.  
  26. /*
  27.  * unfont.c
  28.  *
  29.  * usage: unfont [ -v ] [ files ]
  30.  *    -v     Prints execution information on the standard error.
  31.  *
  32.  * Unpacks IBM PC-format PostScript fonts into a downloadable form.
  33.  *
  34.  */
  35.  
  36. char *USAGE = "\
  37. usage: unfont [ -? ] [ -v ]  [files ]\n\
  38.     -?    Prints this message.\n\
  39.     -v     Prints execution information on the standard error.\n\
  40. ";
  41.  
  42. #include <stdio.h>
  43. #include <fcntl.h>
  44. #include <ctype.h>
  45. #include <varargs.h>
  46.  
  47. #define OK    0
  48. #define FAILURE (-1)
  49. #define Failed(x)    ((x) == FAILURE)
  50. #define TRUE    1
  51. #define FALSE    0
  52. typedef char bool;
  53. #define STREQ(a,b)    (strcmp(a,b) == 0)
  54.  
  55. FILE *fp;
  56.  
  57. /*
  58.  * used to convert nibbles (n0 is least sig) to ascii-hex
  59.  */
  60.  
  61. #define N0(c)        hexbyt[((c) & 0x000f)]
  62. #define N1(c)        N0((c) >> 4)
  63.  
  64. char hexbyt[] = "0123456789ABCDEF";
  65.  
  66. /*
  67.  * vars controlled by command line options
  68.  */
  69.  
  70. bool verbose = FALSE;            /* be verbose */
  71.  
  72. extern char *optarg;            /* getopt(3) control vars */
  73. extern int optind;
  74. extern int errno;
  75.  
  76. char *infile;
  77.  
  78. char *progname;                /* for error() */
  79.  
  80. char *strchr(), *strrchr();
  81. long stol(), getparm();
  82.  
  83. int mygetc();
  84. void dounfont();
  85. long getcount();
  86. void bintohex();
  87.  
  88. main(argc, argv)
  89. int argc;
  90. char **argv;
  91. {
  92.     register int c;
  93.     bool showusage = FALSE;            /* usage error? */
  94.  
  95.     /*
  96.      * figure out invocation leaf-name
  97.      */
  98.  
  99.     if ((progname = strrchr(argv[0], '/')) == (char *) NULL)
  100.     progname = argv[0];
  101.     else
  102.     progname++;
  103.  
  104.     argv[0] = progname;                /* for getopt err reporting */
  105.  
  106.     /*
  107.      *    Check options and arguments.
  108.      */
  109.  
  110.     progname = argv[0];
  111.     while ((c = getopt(argc, argv, "v")) != EOF)
  112.     switch (c)
  113.     {
  114.         case 'v':                /* toggle verbose */
  115.         verbose = ! verbose;
  116.         break;
  117.  
  118.         case '?':
  119.         showusage = TRUE;
  120.     }
  121.  
  122.     if (showusage)
  123.     {
  124.     (void) fprintf(stderr, "%s", USAGE);
  125.     exit(1);
  126.     }
  127.  
  128. /* unfont stuff        */
  129.  
  130.     if (argv[optind])
  131.     {
  132.         for ( ; argv[optind]; optind++)
  133.     {
  134.         if (!(fp = fopen(argv[optind], "r"))) {
  135.         error(0, "can't open input file '%s'", argv[optind]);    
  136.         continue;
  137.         }
  138.  
  139.         infile = argv[optind];
  140.         dounfont();
  141.         close(fp);
  142.     }
  143.     }
  144.     else
  145.     {
  146.     infile = "<stdin>";
  147.     fp = stdin;
  148.         dounfont();
  149.     }
  150.     exit(0);
  151. }
  152.  
  153. long getcount();
  154.  
  155. void 
  156. dounfont()
  157. {
  158.     register int c; 
  159.     register int ch;
  160.              long count;
  161.     register int i;
  162.  
  163.     for (;;)
  164.     {
  165.     if ((c = mygetc()) != 0x80) {
  166.         error(0, "not a proper font data segment '%s'", infile);
  167.         error(0, "foobar char is 0x%x", c);
  168.         exit(1);
  169.     }
  170.     c = mygetc();
  171.     switch (c) {
  172.     case 1:        
  173.         /* get count, output count bytes to stdout    */
  174.         count = getcount();
  175.         if (verbose)
  176.             fprintf(stderr, "case1 count is %ld\n", count);
  177.         for (i=0; i<count; i++)
  178.                 putchar(mygetc());
  179.         break;
  180.     case 2:        
  181.         /* get count, convert count bytes to hex, output    */
  182.         /* to stdout                        */
  183.         count = getcount();
  184.         if (verbose)
  185.             fprintf(stderr, "case2 count is %ld\n", count);
  186.         bintohex(count);
  187.         break;
  188.     case 3:        
  189.         /* reached EOF; next file, please             */
  190.         if (verbose)
  191.             fprintf(stderr, "logical eof encountered\n");
  192.         return;
  193.  
  194.     default:
  195.         error(0, "not a valid segment type '%s'", infile);    
  196.         return;
  197.     }
  198.     }
  199. }
  200.  
  201. /* 
  202.  * getc for error-checking    
  203.  */
  204.  
  205. int
  206. mygetc()
  207. {
  208.     int ch;
  209.         if ((ch = getc(fp)) == -1) {
  210.         error(-1, "unexpected eof on input in '%s'", infile);
  211.         exit(1);
  212.     }
  213.         return(ch);
  214. }
  215.  
  216. /*
  217.  * get count of bytes from segment header
  218.  */
  219.  
  220. long
  221. getcount()
  222. {
  223.     int i;
  224.     long count = 0;
  225.  
  226.         for (i=0; i<4; i++)
  227.                count += ((long) mygetc()) << (i * 8);
  228.     return(count);
  229. }
  230.  
  231. /* 
  232.  * convert binary to ASCII hex and write it to stdout
  233.  */
  234.  
  235. void
  236. bintohex(count)
  237. long count;
  238. {
  239.     int ch;
  240.     long i;
  241.  
  242.     for (i=0; i<count; i++) {
  243.             if ((i % 30) == 0)
  244.             putchar('\n');
  245.            ch = mygetc();
  246.             putchar(N1(ch));
  247.             putchar(N0(ch));
  248.     }
  249. }
  250.  
  251. /* end of unfont stuff
  252.  
  253. /*
  254.  * error(errn, arglist)
  255.  *    report an error to stderr using printf(3) conventions.
  256.  *    Any output is preceded by '<progname>: '
  257.  *    If 'errn' is non-zero, it is assumed to be an 'errno' and its
  258.  *    associated error message is appended to the output.
  259.  */
  260.  
  261. /*VARARGS*/
  262. error(errn, va_alist)
  263. int errn;
  264. va_dcl
  265. {
  266.     va_list arglist;
  267.     register char *format;
  268.     extern char *sys_errlist[];
  269.     extern int sys_nerr;
  270.     extern int errno;
  271.  
  272.     if (errn == -1)                /* use errno if -1 */
  273.     errn = errno;
  274.  
  275.     va_start(arglist);
  276.     format = va_arg(arglist, char *);
  277.     (void) fprintf(stderr, "%s: ", progname);
  278.     (void) vfprintf(stderr, format, arglist);
  279.     va_end(arglist);
  280.  
  281.     if (errn)
  282.     if ((errn > 0) && (errn <= sys_nerr))
  283.         (void) fprintf(stderr, " (%s)\n", sys_errlist[errn]);
  284.     else
  285.         (void) fprintf(stderr, " (unknown errno=%d)\n", errn);
  286.     else
  287.     (void) fprintf(stderr, "\n");
  288. }
  289.