diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/postscript/misc/ibmfont.c | |
download | plan9front-e5888a1ffdae813d7575f5fb02275c6bb07e5199.tar.xz |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/postscript/misc/ibmfont.c')
-rwxr-xr-x | sys/src/cmd/postscript/misc/ibmfont.c | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/sys/src/cmd/postscript/misc/ibmfont.c b/sys/src/cmd/postscript/misc/ibmfont.c new file mode 100755 index 000000000..99e53c346 --- /dev/null +++ b/sys/src/cmd/postscript/misc/ibmfont.c @@ -0,0 +1,293 @@ +/* + * + * Program that converts IBM 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, + * + * ibmfont font.ibm >font.unix + * + * where font.ibm is the font file, exactly as it came over from an IBM PC, + * 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 = stdin; +FILE *fp_out = stdout; + +/*****************************************************************************/ + +main(agc, agv) + + int agc; + char *agv[]; + +{ + +/* + * + * IBM PC to Unix font converter. + * + */ + + argc = agc; + argv = agv; + prog_name = argv[0]; + + 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 esle 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; + int seg; + long ftell(); + +/* + * + * Font files on the IBM PC are stored in a compressed binary format. Individual + * segments in the file are preceeded by a header that looks like, + * + * Byte 1: 128 + * Byte 2: segment type (1=ASCII, 2=TOHEX, or 3=EOF) + * Bytes 3-6: length of the segment + * Bytes 7 ... data + * + */ + + while ( 1 ) { + seg = ftell(fp_in); + if ( getc(fp_in) != 128 ) + error(FATAL, "bad file format"); + blocktype = getc(fp_in); + blocksize = getint(fp_in); + if ( debug == ON ) { + fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize); + fprintf(stderr, "start=0%o, end=0%o\n", seg, seg+blocksize+6); + fprintf(stderr, "start=%d, end=%d\n", seg, seg+blocksize+6); + } /* End if */ + switch ( blocktype ) { + case 1: + asciitext(blocksize); + break; + + case 2: + hexdata(blocksize); + break; + + case 3: + 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; + +/* + * + * Reads the next four bytes into an integer and returns the value to the caller. + * First two bytes are probably always 0. + * + */ + + val = getc(fp_in); + val |= (getc(fp_in) << 8); + val |= (getc(fp_in) << 16); + val |= (getc(fp_in) << 24); + + return(val); + +} /* End of getint */ + +/*****************************************************************************/ + +error(kind, mesg, a1, a2, a3) + + int kind; + char *mesg; + unsigned a1, a2, a3; + +{ + +/* + * + * Print mesg and 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 */ + +/*****************************************************************************/ + |