jos@bull.nl (Jos Vos) (04/26/91)
As response to various questions in this newsgroup, here's a program to convert PFB files to a PostScript program that downloads the font. It was not written by me: see the NOTICE at the beginning of the program. In order to load the font permanently, insert the following line in the beginning of the output from the program: 0 serverdict begin exitserver Here's the program: ------------------CUT HERE /* * NOTICE * * Copyright 1988, 1989 by h-three Systems Corporation. * * Permission is hereby granted for this software's free reproduction * and modification for non-commercial purposes, provided that this * notice is retained. Commercial enterprises may give away copies * as part of their products provided that they do so without charge, * that they retain this notice, and that they acknowledge the source * of the software. * * PostScript is a registered trademark of Adobe Systems Incorporated. * IBM is a registered trademark of International Business Machines * Corporation. * * h-three Systems Corporation * 100 Park Drive Suite 204/ P.O. Box 12557 * Research Triangle Park, NC 27709 * * CHANGE HISTORY * * - A small change was made by Jos Vos <jos@bull.nl> to generate * a PostScript program with a '\n' ('\012') as line separator * i.s.o. a '\r' ('\015'). */ #ifdef NOWHAT static char *sccsid = "%W% - %E%"; #endif /* * unfont.c * * usage: unfont [ -v ] [ files ] * -v Prints execution information on the standard error. * * Unpacks IBM PC-format PostScript fonts into a downloadable form. * */ char *USAGE = "\ usage: unfont [ -? ] [ -v ] [files ]\n\ -? Prints this message.\n\ -v Prints execution information on the standard error.\n\ "; #include <stdio.h> #include <fcntl.h> #include <ctype.h> #include <varargs.h> #define OK 0 #define FAILURE (-1) #define Failed(x) ((x) == FAILURE) #define TRUE 1 #define FALSE 0 typedef char bool; #define STREQ(a,b) (strcmp(a,b) == 0) FILE *fp; /* * used to convert nibbles (n0 is least sig) to ascii-hex */ #define N0(c) hexbyt[((c) & 0x000f)] #define N1(c) N0((c) >> 4) char hexbyt[] = "0123456789ABCDEF"; /* * vars controlled by command line options */ bool verbose = FALSE; /* be verbose */ extern char *optarg; /* getopt(3) control vars */ extern int optind; extern int errno; char *infile; char *progname; /* for error() */ char *strchr(), *strrchr(); long stol(), getparm(); int mygetc(); void dounfont(); long getcount(); void bintohex(); main(argc, argv) int argc; char **argv; { register int c; bool showusage = FALSE; /* usage error? */ /* * figure out invocation leaf-name */ if ((progname = strrchr(argv[0], '/')) == (char *) NULL) progname = argv[0]; else progname++; argv[0] = progname; /* for getopt err reporting */ /* * Check options and arguments. */ progname = argv[0]; while ((c = getopt(argc, argv, "v")) != EOF) switch (c) { case 'v': /* toggle verbose */ verbose = ! verbose; break; case '?': showusage = TRUE; } if (showusage) { (void) fprintf(stderr, "%s", USAGE); exit(1); } /* unfont stuff */ if (argv[optind]) { for ( ; argv[optind]; optind++) { if (!(fp = fopen(argv[optind], "r"))) { error(0, "can't open input file '%s'", argv[optind]); continue; } infile = argv[optind]; dounfont(); close(fp); } } else { infile = "<stdin>"; fp = stdin; dounfont(); } exit(0); } long getcount(); void dounfont() { register int c; register int ch; long count; register int i; for (;;) { if ((c = mygetc()) != 0x80) { error(0, "not a proper font data segment '%s'", infile); error(0, "foobar char is 0x%x", c); exit(1); } c = mygetc(); switch (c) { case 1: /* get count, output count bytes to stdout */ count = getcount(); if (verbose) fprintf(stderr, "case1 count is %ld\n", count); for (i=0; i<count; i++) { c = mygetc(); putchar(c == '\r' ? '\n' : c); } break; case 2: /* get count, convert count bytes to hex, output */ /* to stdout */ count = getcount(); if (verbose) fprintf(stderr, "case2 count is %ld\n", count); bintohex(count); break; case 3: /* reached EOF; next file, please */ if (verbose) fprintf(stderr, "logical eof encountered\n"); return; default: error(0, "not a valid segment type '%s'", infile); return; } } } /* * getc for error-checking */ int mygetc() { int ch; if ((ch = getc(fp)) == -1) { error(-1, "unexpected eof on input in '%s'", infile); exit(1); } return(ch); } /* * get count of bytes from segment header */ long getcount() { int i; long count = 0; for (i=0; i<4; i++) count += ((long) mygetc()) << (i * 8); return(count); } /* * convert binary to ASCII hex and write it to stdout */ void bintohex(count) long count; { int ch; long i; for (i=0; i<count; i++) { if ((i % 30) == 0) putchar('\n'); ch = mygetc(); putchar(N1(ch)); putchar(N0(ch)); } } /* end of unfont stuff /* * error(errn, arglist) * report an error to stderr using printf(3) conventions. * Any output is preceded by '<progname>: ' * If 'errn' is non-zero, it is assumed to be an 'errno' and its * associated error message is appended to the output. */ /*VARARGS*/ error(errn, va_alist) int errn; va_dcl { va_list arglist; register char *format; extern char *sys_errlist[]; extern int sys_nerr; extern int errno; if (errn == -1) /* use errno if -1 */ errn = errno; va_start(arglist); format = va_arg(arglist, char *); (void) fprintf(stderr, "%s: ", progname); (void) vfprintf(stderr, format, arglist); va_end(arglist); if (errn) if ((errn > 0) && (errn <= sys_nerr)) (void) fprintf(stderr, " (%s)\n", sys_errlist[errn]); else (void) fprintf(stderr, " (unknown errno=%d)\n", errn); else (void) fprintf(stderr, "\n"); } ------------------CUT HERE -- -- Jos Vos <jos@bull.nl> (UUCP: ...!{uunet,mcsun,hp4nl}!nlbull!jos) -- Bull Nederland NV, Product Support Unix, Amsterdam, The Netherlands