aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/postscript/misc/macfont.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/postscript/misc/macfont.c')
-rw-r--r--src/cmd/postscript/misc/macfont.c299
1 files changed, 299 insertions, 0 deletions
diff --git a/src/cmd/postscript/misc/macfont.c b/src/cmd/postscript/misc/macfont.c
new file mode 100644
index 00000000..59244a19
--- /dev/null
+++ b/src/cmd/postscript/misc/macfont.c
@@ -0,0 +1,299 @@
+/*
+ *
+ * Program that converts Macintosh font files to a format that works on Unix
+ * systems. Essentially all the information needed came from the Adobe paper
+ * "Supporting Downloadable PostScript Fonts". To use the program type,
+ *
+ * macfont font.mac >font.unix
+ *
+ * where font.mac is the font file, exactly as it came over from a Macintosh,
+ * and font.unix is equivalent host resident font file usable on Unix systems.
+ *
+ */
+
+#include <stdio.h>
+#include <signal.h>
+
+#define OFF 0
+#define ON 1
+
+#define NON_FATAL 0
+#define FATAL 1
+
+#define FALSE 0
+#define TRUE 1
+
+char **argv;
+int argc;
+
+char *prog_name;
+
+int x_stat;
+int debug = OFF;
+int ignore = OFF;
+
+FILE *fp_in;
+FILE *fp_out;
+
+/*****************************************************************************/
+
+main(agc, agv)
+
+ int agc;
+ char *agv[];
+
+{
+
+/*
+ *
+ * Macintosh to Unix font converter.
+ *
+ */
+
+ argc = agc;
+ argv = agv;
+ prog_name = argv[0];
+
+ fp_in = stdin;
+ fp_out = stdout;
+
+ options();
+ arguments();
+ exit(x_stat);
+
+} /* End of main */
+
+/*****************************************************************************/
+
+options()
+
+{
+
+ int ch;
+ char *names = "DI";
+
+ extern char *optarg;
+ extern int optind;
+
+/*
+ *
+ * Command line options.
+ *
+ */
+
+ while ( (ch = getopt(argc, argv, names)) != EOF ) {
+ switch ( ch ) {
+ case 'D': /* debug flag */
+ debug = ON;
+ break;
+
+ case 'I': /* ignore FATAL errors */
+ ignore = ON;
+ break;
+
+ case '?': /* don't understand the option */
+ error(FATAL, "");
+ break;
+
+ default: /* don't know what to do for ch */
+ error(FATAL, "missing case for option %c\n", ch);
+ break;
+ } /* End switch */
+ } /* End while */
+
+ argc -= optind;
+ argv += optind;
+
+} /* End of options */
+
+/*****************************************************************************/
+
+arguments()
+
+{
+
+
+/*
+ *
+ * Everything else is an input file. No arguments or '-' means stdin.
+ *
+ */
+
+ if ( argc < 1 )
+ conv();
+ else
+ while ( argc > 0 ) {
+ if ( strcmp(*argv, "-") == 0 )
+ fp_in = stdin;
+ else if ( (fp_in = fopen(*argv, "r")) == NULL )
+ error(FATAL, "can't open %s", *argv);
+ conv();
+ if ( fp_in != stdin )
+ fclose(fp_in);
+ argc--;
+ argv++;
+ } /* End while */
+
+} /* End of arguments */
+
+/*****************************************************************************/
+
+conv()
+
+{
+
+ int blocksize;
+ int blocktype;
+
+/*
+ *
+ * The first four bytes (in a block) are the block size, the fifth is the block
+ * type, and the sixth always appears to be NULL. Type 0 blocks are comments and
+ * are always skipped. Type 1 blocks are ASCII text, type 2 is binary data that
+ * should be converted to hex, while type 5 blocks represent the end of the font
+ * file. Commment block lengths appear to be from the first byte, while other
+ * lengths seem to be measured from block type byte (ie. the fifth byte). Type
+ * four blocks aren't used, while type 3 blocks mean an end of file indication
+ * should be sent to the printer. Haven't done anything with type 3 blocks.
+ *
+ */
+
+ while ( 1 ) {
+ blocksize = getint(fp_in);
+ blocktype = getc(fp_in);
+ getc(fp_in);
+ if ( debug == ON )
+ fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
+ switch ( blocktype ) {
+ case 0: /* comment - skip blockcount bytes */
+ fseek(fp_in, (long) blocksize - 6, 1);
+ break;
+
+ case 1:
+ asciitext(blocksize - 2);
+ break;
+
+ case 2:
+ hexdata(blocksize - 2);
+ break;
+
+ case 3:
+ case 4:
+ error(FATAL, "resource type %d not implemented", blocktype);
+ break;
+
+ case 5:
+ return;
+
+ default:
+ error(FATAL, "unknown resource type %d", blocktype);
+ } /* End switch */
+ } /* End while */
+
+} /* End of conv */
+
+/*****************************************************************************/
+
+asciitext(count)
+
+ int count; /* bytes left in the block */
+
+{
+
+ int ch;
+ int i = 0;
+
+/*
+ *
+ * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
+ * is all I've done.
+ *
+ */
+
+ for ( i = 0; i < count; i++ ) {
+ if ( (ch = getc(fp_in)) == '\r' )
+ ch = '\n';
+ putc(ch, fp_out);
+ } /* End for */
+
+} /* End of asciitext */
+
+/*****************************************************************************/
+
+hexdata(count)
+
+ int count; /* bytes left in the block */
+
+{
+
+ int i;
+ int n;
+
+/*
+ *
+ * Reads the next count bytes and converts each byte to hex. Also starts a new
+ * line every 80 hex characters.
+ *
+ */
+
+ for ( i = 0, n = 0; i < count; i++ ) {
+ fprintf(fp_out, "%.2X", getc(fp_in));
+ if ( (++n % 40) == 0 )
+ putc('\n', fp_out);
+ } /* End for */
+
+} /* End of hexdata */
+
+/*****************************************************************************/
+
+getint()
+
+{
+
+ int val;
+ int i;
+
+/*
+ *
+ * Reads the next four bytes into an integer and returns the value to the caller.
+ * First two bytes are probably always 0.
+ *
+ */
+
+ for ( i = 0, val = (getc(fp_in) & 0377); i < 3; i++ )
+ val = (val << 8) | (getc(fp_in) & 0377);
+
+ return(val);
+
+} /* End of getint */
+
+/*****************************************************************************/
+
+error(kind, mesg, a1, a2, a3)
+
+
+ int kind;
+ char *mesg;
+ unsigned a1, a2, a3;
+
+{
+
+/*
+ *
+ * Print *mesg then quit if kind is FATAL.
+ *
+ */
+
+ if ( mesg != NULL && *mesg != '\0' ) {
+ fprintf(stderr, "%s: ", prog_name);
+ fprintf(stderr, mesg, a1, a2, a3);
+ putc('\n', stderr);
+ } /* End if */
+
+ if ( kind == FATAL && ignore == OFF )
+ exit(x_stat | 01);
+
+} /* End of error */
+
+/*****************************************************************************/
+