home *** CD-ROM | disk | FTP | other *** search
- /* t1binary
- *
- * This program takes an Adobe Type-1 font program in ASCII (PFA) format and
- * converts it to binary (PFB) format.
- *
- * Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.
- *
- * Permission is hereby granted to use, modify, and distribute this program
- * for any purpose provided this copyright notice and the one below remain
- * intact.
- *
- * I. Lee Hetherington (ilh@lcs.mit.edu)
- *
- * $Log: t1binary.c,v $
- * Revision 1.1 92/05/22 11:58:17 ilh
- * initial version
- *
- * Ported to Microsoft C/C++ Compiler and MS-DOS operating system by
- * Kai-Uwe Herbing (herbing@netmbx.netmbx.de) on June 12, 1992. Code
- * specific to the MS-DOS version is encapsulated with #ifdef _MSDOS
- * ... #endif, where _MSDOS is an identifier, which is automatically
- * defined, if you compile with the Microsoft C/C++ Compiler.
- *
- */
-
- #ifndef lint
- static char rcsid[] =
- "@(#) $Id: t1binary.c,v 1.1 92/05/22 11:58:17 ilh Exp Locker: ilh $";
- static char copyright[] =
- "@(#) Copyright (c) 1992 by I. Lee Hetherington, all rights reserved.";
- #ifdef _MSDOS
- static char portnotice[] =
- "@(#) Ported to MS-DOS by Kai-Uwe Herbing (herbing@netmbx.netmbx.de).";
- #endif
- #endif
-
- /* Note: this is ANSI C. */
-
- #ifdef _MSDOS
- #include <fcntl.h>
- #include <getopt.h>
- #include <io.h>
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <limits.h>
-
- /* int32 must be at least 32-bit */
- #if INT_MAX >= 0x7FFFFFFFUL
- typedef int int32;
- #else
- typedef long int32;
- #endif
-
- #define LINESIZE 256
-
- #define MAXBLOCKLEN ((1L<<17)-6)
- #define MINBLOCKLEN ((1L<<8)-6)
-
- #define MARKER 128
- #define ASCII 1
- #define BINARY 2
- #define DONE 3
-
- typedef unsigned char byte;
-
- static FILE *ifp = stdin;
- static FILE *ofp = stdout;
- static char line[LINESIZE];
-
- /* for PFB block buffering */
- static byte blockbuf[MAXBLOCKLEN];
- static int32 blocklen = MAXBLOCKLEN;
- static int32 blockpos = -1;
- static int blocktyp = ASCII;
-
- /* This function flushes a buffered PFB block. */
-
- static void output_block()
- {
- int32 i;
-
- /* output four-byte block length */
- fputc((int) (blockpos & 0xff), ofp);
- fputc((int) ((blockpos >> 8) & 0xff), ofp);
- fputc((int) ((blockpos >> 16) & 0xff), ofp);
- fputc((int) ((blockpos >> 24) & 0xff), ofp);
-
- /* output block data */
- for (i = 0; i < blockpos; i++)
- fputc(blockbuf[i], ofp);
-
- /* mark block buffer empty and uninitialized */
- blockpos = -1;
- }
-
- /* This function outputs a single byte. If output is in PFB format then output
- is buffered through blockbuf[]. If output is in PFA format, then output
- will be hexadecimal if in_eexec is set, ASCII otherwise. */
-
- static void output_byte(byte b)
- {
- if (blockpos < 0) {
- fputc(MARKER, ofp);
- fputc(blocktyp, ofp);
- blockpos = 0;
- }
- blockbuf[blockpos++] = b;
- if (blockpos == blocklen)
- output_block();
- }
-
- /* This function outputs a null-terminated string through the PFB buffering. */
-
- static void output_string(char *string)
- {
- while (*string)
- output_byte((byte) *string++);
- }
-
- /* This function returns the value (0-15) of a single hex digit. It returns
- 0 for an invalid hex digit. */
-
- static int hexval(char c)
- {
- if (c >= 'A' && c <= 'F')
- return c - 'A' + 10;
- else if (c >= 'a' && c <= 'f')
- return c - 'a' + 10;
- else if (c >= '0' && c <= '9')
- return c - '0';
- else
- return 0;
- }
-
- /* This function outputs the binary data associated with a string of
- hexadecimal digits. There must be an even number of digits. */
-
- static void output_hex_string(char *string)
- {
- while (string[0] && string[0] != '\n') {
- if (!string[1]) {
- fprintf(stderr, "error: only one hex digit\n");
- exit(1);
- }
- output_byte((byte)((hexval(string[0]) << 4) + hexval(string[1])));
- string += 2;
- }
- }
-
- /* This function returns 1 if the string contains all '0's. */
-
- static int all_zeroes(char *string)
- {
- while (*string == '0')
- string++;
- return *string == '\0' || *string == '\n';
- }
-
- static void usage()
- {
- fprintf(stderr,
- "usage: t1binary [-l block-length] [input [output]]\n");
- fprintf(stderr,
- "The block length applies to the length of blocks in the\n");
- fprintf(stderr,
- "PFB output file; the default is to use the largest possible.\n");
- exit(1);
- }
-
- static void print_banner()
- {
- static char rcs_revision[] = "$Revision: 1.1 $";
- static char revision[20];
-
- if (sscanf(rcs_revision, "$Revision: %19s", revision) != 1)
- revision[0] = '\0';
- fprintf(stderr, "This is t1binary %s.\n", revision);
- }
-
- int main(int argc, char **argv)
- {
- int c;
-
- extern char *optarg;
- extern int optind;
- extern int getopt(int argc, char **argv, char *optstring);
-
- print_banner();
-
- /* interpret command line arguments using getopt */
- while ((c = getopt(argc, argv, "l:")) != -1)
- switch (c) {
- case 'l':
- blocklen = atoi(optarg);
- if (blocklen < MINBLOCKLEN) {
- blocklen = MINBLOCKLEN;
- fprintf(stderr,
- "warning: using minimum block length of %d\n",
- blocklen);
- } else if (blocklen > MAXBLOCKLEN) {
- blocklen = MAXBLOCKLEN;
- fprintf(stderr,
- "warning: using maximum block length of %d\n",
- blocklen);
- }
- break;
- default:
- usage();
- break;
- }
- if (argc - optind > 2)
- usage();
-
- /* possibly open input & output files */
- if (argc - optind >= 1) {
- ifp = fopen(argv[optind], "r");
- if (!ifp) {
- fprintf(stderr, "error: cannot open %s for reading\n",
- argv[optind]);
- exit(1);
- }
- }
- if (argc - optind >= 2) {
- ofp = fopen(argv[optind + 1], "wb");
- if (!ofp) {
- fprintf(stderr, "error: cannot open %s for writing\n",
- argv[optind + 1]);
- exit(1);
- }
- }
-
- #ifdef _MSDOS
- /* As we are processing a PFB (binary) output */
- /* file, we must set its file mode to binary. */
- _setmode(_fileno(ofp), _O_BINARY);
- #endif
-
- /* peek at first byte to see if it is the PFB marker 0x80 */
- c = fgetc(ifp);
- if (c == MARKER) {
- fprintf(stderr,
- "error: input may already be binary (starts with 0x80)\n");
- exit(1);
- }
- ungetc(c, ifp);
-
- /* Finally, we loop until no more input. We need to look for `currentfile
- eexec' to start eexec section (hex to binary conversion) and line of all
- zeros to switch back to ASCII. */
-
- while (fgets(line, LINESIZE, ifp), !feof(ifp) && !ferror(ifp)) {
- if (blocktyp == ASCII && strcmp(line, "currentfile eexec\n") == 0) {
- output_string(line);
- output_block();
- blocktyp = BINARY;
- } else if (blocktyp == BINARY && all_zeroes(line)) {
- output_block();
- blocktyp = ASCII;
- output_string(line);
- } else if (blocktyp == ASCII) {
- output_string(line);
- } else {
- output_hex_string(line);
- }
- }
- output_block();
- fputc(MARKER, ofp);
- fputc(DONE, ofp);
-
- fclose(ifp);
- fclose(ofp);
-
- return 0;
- }