[comp.fonts] TEX PK to HP SFP font conversion

clewis@ecicrl.UUCP (Chris Lewis) (09/17/90)

Shell archive - cut here -
#!/bin/sh
sed -e 's/^X//' > pk2sfp.c <<\!BLOTTO
X/*	Copyright 1985, 1986, 1987, 1988 90/09/17 Chris Lewis
X		All Rights Reserved
X
X    Permission to copy and further distribute is freely given provided
X    this copyright notice remains intact and that this software is not
X    sold for profit.
X
X	Project:	Generic Troff drivers
X	Module:		pk2sfp.c
X	Author: 	Chris Lewis
X	Specs:		Generates SFP's from PK's.
X */
X
X#ifndef	lint
Xstatic char SCCSID[] =
X    "@(#)pk2sfp.c 2.2 Copyright 90/09/17 10:50:03 Chris Lewis";
X#endif
X
X#include "defs.h"
X#include "pk.h"
X
X#define	MAXMAP 256
X
Xstruct fontmap {
X    short from;
X    short to;
X} fontmap[MAXMAP], *flast = fontmap, *fp;
X
Xchar emittedyet[256];
X
X#define	NOTSET	32767
X
Xint symset = NOTSET;
Xint style = NOTSET;
Xint strokeweight = NOTSET;
Xint typeface = NOTSET;
Xint fontid = NOTSET;
Xint verbose = 0;
Xint merge = 0;
Xint symbol = 0;
Xint partial = 0;
Xint permanent = 0;
X
Xchar *progname;
X
X#ifdef	PARTIAL
Xextern struct enctab encNormal[], encSymbol[];
X
Xneedchar(font, character)
Xint font;
Xlong character; {
X    register struct enctab *tab;
X    register char *p;
X
X    if (!partial)
X	return(1);
X
X    if (symbol)
X	tab = encSymbol;
X    else
X	tab = encNormal;
X
X    for(; tab->e_name; tab++) {
X	for (p = tab->e_seq; *p; p++)
X	    if (((*p) & 0xff) == character)
X		return(1);
X    }
X
X    return(0);
X}
X#else
Xneedchar(font, character)
Xint font;
Xlong character; {
X    return(1);
X}
X#endif
X
Xmain(argc, argv)
Xint argc;
Xchar **argv; {
X    char buf[512];
X    extern int optind;
X    long totalbytes, numbytes;
X    int totalcodes, numcodes;
X
X    extern char *optarg;
X    int i;
X    int c;
X
X    progname = argv[0];
X
X    while((c = getopt(argc, argv, "D:s:t:w:f:i:vmSpP")) != EOF) {
X	switch(c) {
X	    case 'D':
X#ifdef	DEBUG
X		setdebug(optarg, "diagnostics");
X		break;
X#else
X		fprintf(stderr, "%s: DEBUG disabled, recompile\n", progname);
X		exit(1);
X#endif
X	    case 'P':
X		permanent = 1;
X		break;
X	    case 'S':
X		symbol = 1;
X		break;
X	    case 'p':
X		partial = 1;
X		break;
X	    case 's':
X		symset = ((optarg[0] - '0') << 5) + optarg[1] - 64;
X		break;
X	    case 't':
X		style = atoi(optarg);
X		break;
X	    case 'w':
X		strokeweight = atoi(optarg);
X		break;
X	    case 'f':
X		typeface = atoi(optarg);
X		break;
X	    case 'i':
X		fontid = atoi(optarg);
X		break;
X	    case 'v':
X		verbose = 1;
X		break;
X	    case 'm':
X		merge = 1;
X		break;
X
X	    default:
X		fprintf(stderr, "usage: pk2sfp [-Dopts] [<options>] file...\n");
X		fprintf(stderr, "or   : pk2sfp -m [-Dopts] [<options>]");
X		fprintf(stderr, " map file map file ....\n");
X
X		fprintf(stderr, "\t-sna: symset, eg: -s8U\n");
X		fprintf(stderr, "\t-t0|1: style: 0 upright, 1 italic\n");
X		fprintf(stderr, "\t-wn: stroke weight (-7..7)\n");
X		fprintf(stderr, "\t-fn: typeface, eg: 5 is Times Roman\n");
X		fprintf(stderr, "\t-in: prepend fontid n, auto increments\n");
X		fprintf(stderr, "\t-v: verbose - emit actions to stderr\n");
X		fprintf(stderr, "\t-p: only download chars psroff needs\n");
X		fprintf(stderr, "\t-S: font is used for psroff Symbol font\n");
X		fprintf(stderr, "\t-P: mark font as permanent (needs -in)\n");
X		exit(1);
X	}
X    }
X    if (merge)
X	fprintf(stderr, "MERGING fonts\n");
X
X    numbytes = 0;
X
X    for(;argv[optind];optind++) {
X	register struct pkp *pk;
X	register struct pkc *pc;
X
X	numcodes = 0;
X	numbytes = 0;
X
X	strcpy(buf, argv[optind]);
X
X	if (merge && readmerge(buf))
X	    continue;
X
X	/* Read the PK file in-core */
X	pk = pk_read(buf);
X
X	/* Overrides */
X	if (symset != NOTSET)
X	    pk->pkp_symset = symset;
X	if (style != NOTSET)
X	    pk->pkp_style = style;
X	if (strokeweight != NOTSET)
X	    pk->pkp_sw = strokeweight;
X	if (typeface != NOTSET)
X	    pk->pkp_typeface = typeface;
X
X	if (verbose)
X	    if (merge > 1)
X		fprintf(stderr, "Appending %s: ", buf);
X	    else
X		fprintf(stderr, "Emitting %s: ", buf);
X
X	/* you want a font ID select? */
X	if (merge <= 1 && fontid != NOTSET) {
X	    if (verbose)
X		fprintf(stderr, "fontid %d\n", fontid);
X	    printf("\033*c%dD", fontid);
X	} else
X	    if (verbose)
X		fprintf(stderr, "no fontid\n");
X
X	if (merge <= 1 && verbose) {
X	    fprintf(stderr, "\tsymset: %d%c\n", pk->pkp_symset >> 5,
X		(pk->pkp_symset & 0x1f) + 64);
X	    fprintf(stderr, "\ttype: %s\n", pk->pkp_style?"italic":"upright");
X	    fprintf(stderr, "\tstroke weight: %d\n", pk->pkp_sw);
X	    fprintf(stderr, "\ttypeface: %d\n", pk->pkp_typeface);
X	}
X
X	if (merge <= 1) {
X	    /* Emit the SFP header */
X	    epk_desc(pk, stdout);
X	    numbytes += 2048;
X	    numcodes = 0;
X	    if (merge == 1)
X		merge++;
X	}
X
X	/* Emit each character */
X	for (i = 0; i < pk->pkp_num; i++) {
X	    pc = pk->pkp_list[i];
X	    if (merge) {
X		for (fp = fontmap; fp < flast; fp++)
X		    if (pc->pkc_char == fp->from) {
X			pc->pkc_char = fp->to;
X			if (emittedyet[(fp->to)&0xff]) {
X			    if (verbose)
X				fprintf(stderr,
X				"Skipping %02x (%c) as %02x (%c) from %s\n",
X				fp->from, pchr(fp->from),
X				fp->to, pchr(fp->to), buf);
X			    break;
X			}
X			if (verbose)
X			    fprintf(stderr,
X				"Emitting %02x (%c) as %02x (%c) from %s\n",
X				fp->from, pchr(fp->from),
X				fp->to, pchr(fp->to), buf);
X			emittedyet[(fp->to)&0xff] = 1;
X			fp->to = 0x00;
X			numbytes += epkc_desc(pc, stdout);
X			numcodes++;
X			break;
X		    }
X	    } else {
X		DBP((D_FONT,"Downloading char %02x (%c)\n", pc->pkc_char,
X		    pchr(pc->pkc_char)));
X		numbytes += epkc_desc(pc, stdout);
X		numcodes++;
X	    }
X	}
X				/* added to make fonts permanent */
X				/* ron@mlfarm 6.1.90 */
X
X	if (fontid != NOTSET && permanent)
X	    printf("\033*c%dd5F", fontid);
X
X	if (fontid != NOTSET)
X	    fontid++;
X
X	/* Clobber in-core PK */
X	pk_destroy(pk);
X
X	totalbytes += numbytes;
X	totalcodes += numcodes;
X	if (verbose)
X	    fprintf(stderr, "%s: %d bytes %d codes\n", buf, numbytes, numcodes);
X
X    }
X    if (merge)
X	checkmissing((char *) NULL);
X    if (verbose)
X	fprintf(stderr, "total: %d bytes %d codes\n", totalbytes, totalcodes);
X    exit(0);
X}
X
X/*	similar to strtol */
Xshort
Xcvt(p)
Xregister char *p; {
X    register short ret = 0;
X    int base = 10;
X
X    if (!isdigit(*p) && !*(p+1))
X	return(*p);
X
X    if (*p == '0')
X	if (*(p+1) == 'x' || *(p+1) == 'X') {
X	    base = 16;
X	    p += 2;
X	} else
X	    base = 8;
X    while(*p)
X	ret = ret * base + ccvt(*p++);
X    return(ret);
X}
X
Xccvt(c)
Xint c; {
X    if (isdigit(c))
X	return(c - '0');
X    else if (isupper(c))
X	return(c - 'A' + 10);
X    else if (islower(c))
X	return(c - 'a' + 10);
X    else {
X	fprintf(stderr, "%s: bad digit %c in map file\n", progname, c);
X	exit(1);
X    }
X}
Xpchr(x)
Xint x; {
X    if (isascii(x) && isprint(x))
X	return(x);
X    else
X	return('?');
X}
X
X/*	Reads merge descriptor.  Returns non-zero if not a merge */
Xreadmerge(name)
Xchar *name; {
X    char from[20], to[20];
X    FILE *f = fopen(name, "r");
X    char buffer[512];
X    register char *p;
X    if (!f) {
X	fprintf(stderr, "%s: Can't open %s\n", progname, name);
X	exit(1);
X    }
X    if (!fgets(buffer, sizeof(buffer), f)) {
X	fprintf(stderr, "%s: Nothing in this file? (%s)\n", progname, name);
X	fclose(f);
X	return(0);
X    }
X    if (buffer[0] == '\033' || (buffer[0] & 0xff) == PK_pre) {
X	fclose(f);
X	return(0);
X    }
X    checkmissing(name);
X    flast = fontmap;
X    do {
X	for(p = buffer; *p && isspace(*p); p++);
X	if (!*p || *p == '\n' || *p == '#')
X	    continue;
X	switch(sscanf(p, "%s %s", from, to)) {
X	    case 0:
X		continue;
X	    case 1:
X		strcpy(to, from);
X		break;
X	    case 2:
X		if (strcmp(to, "\"") == 0)
X		    strcpy(to, from);
X		break;
X	}
X	if (flast - fontmap >= MAXMAP) {
X	    fprintf(stderr, "%s: too many map sequences in %s\n", progname,
X		name);
X	    exit(1);
X	}
X
X	flast->from = cvt(from);
X	flast->to = cvt(to);
X	flast++;
X    } while (fgets(buffer, sizeof(buffer), f));
X    fclose(f);
X
X#ifdef	DEBUG
X    if (debug&D_FONT) {
X	DBP((D_FONT, "Map from %s map file\n", name));
X	for (fp = fontmap; fp < flast; fp++)
X	    DBP((D_FONT, "  %02x (%c) -> %02x (%c)\n",
X		fp->from, pchr(fp->from),
X		fp->to, pchr(fp->to)));
X    }
X#endif
X    return(1);
X}
X
Xcheckmissing(name)
Xregister char *name; {
X    static char lastmap[512];
X    if (!verbose || flast == fontmap)
X	return;
X    for (fp = fontmap; fp < flast; fp++)
X	if (fp->to)
X	    fprintf(stderr, "Didn't remap 0x%02x:0%o:%d (%c) in map file %s\n",
X		fp->from, fp->from, fp->from, pchr(fp->from), lastmap);
X    if (name)
X	strcpy(lastmap, name);
X}
!BLOTTO
sed -e 's/^X//' > pktype.c <<\!BLOTTO
X/*	Copyright 1985, 1986, 1987, 1988 16:49:49 Chris Lewis
X		All Rights Reserved
X
X    Permission to copy and further distribute is freely given provided
X    this copyright notice remains intact and that this software is not
X    sold for profit.
X
X	Project:	Generic Troff drivers
X	Module:		pk2sfp.c
X	Author: 	Chris Lewis
X	Specs:		prints header info from PK's and SFP's
X */
X
X#ifndef	lint
Xstatic char SCCSID[] =
X    "@(#)pk2sfp.c 2.1 Copyright 90/07/18 16:49:49 Chris Lewis";
X#endif
X#include "defs.h"
X#include "pk.h"
X
Xint firstchar = 0, lastchar = 0xff;
Xint verbose = 0;
Xchar *progname;
Xextern char *mustmalloc();
Xlong pks_malloc;
X
X/*	Dummied out for pk.c */
Xneedchar(a, b)
Xint a, b; {
X    return(1);
X}
X
Xmain(argc, argv)
Xint argc;
Xchar **argv; {
X    int c;
X    extern int optind, getopt();
X    extern char *optarg;
X    register struct pkp *p;
X    struct pkp *pk_read();
X
X    progname = argv[0];
X    while((c = getopt(argc, argv, "D:vf:l:")) != EOF)
X	switch(c) {
X	    case 'D':
X#ifdef	DEBUG
X		setdebug(optarg, "diagnostics");
X		break;
X#else
X		fprintf(stderr, "%s: debug not supported recompile with DEBUG\n",
X		    progname);
X		exit(1);
X#endif
X	    case 'v':
X		verbose = 1;
X		break;
X	    case 'f':
X		firstchar = *optarg;
X		break;
X	    case 'l':
X		lastchar = *optarg;
X		break;
X	    default:
X		fprintf(stderr, "Usage: %s [-f<ch>] [-l<ch>] pk_files\n", progname);
X		exit(1);
X	}
X#ifdef	DEBUG2
X    {
X	struct pkc p;
X	static int8 raster[] = {
X	    0xd9, 0xe2, 0x97, 0x2b, 0x1e, 0x22,
X	    0x93, 0x24, 0xe3, 0x97, 0x4e, 0x22,
X	    0x93, 0x2c, 0x5e, 0x22, 0x97, 0xd9};
X
X	struct ras *r;
X
X	p.pkc_flag = 0x88;
X	p.pkc_dyn_f = 8;
X	p.pkc_pl = 0x1a;
X	p.pkc_char = 4;
X	p.pkc_tfm = 0x09c61c;
X	p.pkc_dx = 0x19;
X	p.pkc_dy = 0;
X	p.pkc_x_off = 0xFE;
X	p.pkc_y_off = 0;
X	p.pkc_height = 0x1d;
X	p.pkc_width = 0x14;
X	p.pkc_pkr = raster;
X	p.pkc_rlen = sizeof(raster);
X	r = pkrast(&p);
X	dumpr(r, p.pkc_height);
X    }
X#endif
X    for (; optind < argc; optind++) {
X	char *filebuf = mustmalloc(strlen(argv[optind]) + 10);
X	register char *cp;
X
X	cp = strrchr(argv[optind], '/');
X
X	if (cp)
X	    strcpy(filebuf, cp+1);
X	else
X	    strcpy(filebuf, argv[optind]);
X
X	strcat(filebuf, ".D");
X
X	if (diagFile)
X	    fclose(diagFile);
X
X	if (!(diagFile = fopen(filebuf, "w"))) {
X	    fprintf(stderr, "%s: cannot open filebuf\n");
X	    exit(1);
X	}
X	p = pk_read(argv[optind]);
X	pk_dump(p, argv[optind]);
X	pk_destroy(p);
X	free(filebuf);
X    }
X    exit(0);
X}
X
Xpk_dump(p, file)
Xstruct pkp *p;
Xchar *file; {
X    struct pkc *pc;
X
X    fprintf(diagFile, "**********************************************\n");
X    fprintf(diagFile, "File %s:\n", file);
X    fprintf(diagFile, "  Font file type: %s\n",
X	p->pkp_flags&1 ? "PK" : "SFP");
X    fprintf(diagFile, "  Number of characters: %d\n", p->pkp_num);
X    fprintf(diagFile, "  Approximately %d bytes used\n", pks_malloc);
X    fprintf(diagFile, "  Design size: %ld, Native point size: %ld\n",
X	p->pkp_ds, p->pkp_ds / pow2(20));
X    fprintf(diagFile, "  Pointsize normalized to %d DPI: %ld\n",
X	OUTRES, p->pkp_npts);
X    fprintf(diagFile, "  Checksum: %ld\n", p->pkp_cs);
X    fprintf(diagFile, "  hppp: %ld, vppp: %ld\n", p->pkp_hppp, p->pkp_vppp);
X    fprintf(diagFile, "  hor. pixels/point: %f, ver. pixels/point: %f\n",
X	(double) p->pkp_hppp / pow2(16), (double) p->pkp_vppp / pow2(16));
X    fprintf(diagFile,
X	"  Hor. font resolution: %ld, Ver. font resolution: %ld\n",
X	p->pkp_res, (long) ((p->pkp_vppp * POINT / pow2(16)) + .5));
X    fprintf(diagFile,
X	"  Max y offset: %ld, Max descender: %ld, ", p->pkp_bmax, p->pkp_dmax);
X    fprintf(diagFile, "Max width: %ld, Max X offset: %ld\n",
X	p->pkp_wmax, p->pkp_xomax);
X    fprintf(diagFile,
X	"  Kern high: %ld, Kern low: %ld\n", p->pkp_kh, p->pkp_kl);
X    fprintf(diagFile,
X	"  SFP Info: symset: %d%c, style: %d, stroke: %d, typeface: %d\n",
X	(p->pkp_symset & 0x01e0) >> 5, (p->pkp_symset & 0x1f) + '@',
X	p->pkp_style, p->pkp_sw, p->pkp_typeface);
X
X    for (pc = p->pkp_chars; pc; pc = pc->pkc_next) {
X	register int i;
X	if (pc->pkc_char < firstchar || pc->pkc_char > lastchar)
X	    continue;
X	fprintf(diagFile, "\nCharacter: %lx (%c), (0%03o), Packet length: %d\n",
X	    pc->pkc_char, (char) (isprint(pc->pkc_char) ? pc->pkc_char : '?'),
X	    pc->pkc_char, pc->pkc_pl);
X	fprintf(diagFile, "  Flag byte: %d\n", pc->pkc_flag);
X	fprintf(diagFile, "  Dynamic packing variable: %d\n", pc->pkc_dyn_f);
X	fprintf(diagFile, "  TFM width: %d, dx: %d", pc->pkc_tfm, pc->pkc_dx);
X	if (pc->pkc_dy)
X	    fprintf(diagFile, " dy: %d\n", pc->pkc_dy);
X	else
X	    putc('\n', diagFile);
X	fprintf(diagFile,
X	    "  Height: %d, Width: %d, X-offset: %d, Y-offset: %d\n",
X	    pc->pkc_height, pc->pkc_width, pc->pkc_x_off, pc->pkc_y_off);
X	if (pc->pkc_rlen) {
X	    fprintf(diagFile,
X		"  Raster length: %d, width in pixels: %ld\n", pc->pkc_rlen,
X		pc->pkc_dx / pow2(16));
X	    fprintf(diagFile, "  ");
X	    for (i = 0; i < 32; i++)
X		if (i >= pc->pkc_rlen)
X		    break;
X		else
X		    fprintf(diagFile, "%02x", 0xff & pc->pkc_pkr[i]);
X	    putc('\n', diagFile);
X	}
X
X	if (pc->pkc_sfpr)
X	    fprintf(diagFile, "  SFP length: %d\n", pc->pkc_sfpr->ras_bytes);
X	if (p->pkp_flags&PK_PK) {
X	    if (pc->pkc_dyn_f == 14)
X		fprintf(diagFile, "  Bit map character, ");
X	    else
X		fprintf(diagFile, "  Packed character, ");
X	    switch(pc->pkc_flag & 0x7) {
X		case 7:
X		    fprintf(diagFile, "Long form\n");
X		    break;
X		case 4: case 5: case 6:
X		    fprintf(diagFile, "Extended short form\n");
X		    break;
X		default:
X		    fprintf(diagFile, "Short form\n");
X	    }
X	}
X	if (verbose)
X	    rasterdump(pc);
X    }
X}
X
Xrasterdump(pc)
Xstruct pkc *pc; {
X    struct ras *r;
X    register int x, y;
X    extern struct ras *pkrast();
X    r = pkrast(pc);
X    if (r) {
X	fprintf(diagFile, "Character image:\n");
X	dumpr(r, r->ras_height);
X	free(r->ras_raster);
X	free(r);
X    } else
X	fprintf(diagFile, "NULL character image\n");
X}
!BLOTTO
sed -e 's/^X//' > pk2sfp.1 <<\!BLOTTO
X.\"Copyright 1988 by Chris Lewis 90/07/18
X.TH PK2SFP 1 local
X.SH NAME
Xpk2sfp,pk2ditwid,pktype,pk2ps \- PK/SFP format font file handling utilities
X.SH SYNOPSIS
X.B pk2sfp
X.BI "[-D" opts "]"
X.BI "[" options "]"
Xfonts ...
X.br
X.B pk2sfp
X.B -m
X.BI "[-D" opts "]"
X.BI "[" options "]"
Xmap font map font ...
X.br
X.B pk2ditwid
X.BI "[-D" opts "]"
X.B "[-S]"
X.B "[-s]"
Xfiles...
X.br
X.B pktype
X.BI "[-v]"
X.BI "[-f" char "]"
X.BI "[-l" char "]"
X.BI "[-D" opts "]"
Xfiles...
X.br
X.B pk2ps
X.B "[-f]"
X.B "[-v]"
X.BI "[-D" opts "]"
Xfiles...
X.SH DESCRIPTION
XThese programs allow you to manipulate PK and SFP format font files,
Xwhich
X.B psroff
Xcan use with Hewlett Packard Laserjet (or compatible) printers.
XThese programs are usually found in %%LIBDIR%%.
X.SH "Converting SFP and PK files: pk2sfp"
X.P
X.B pk2sfp
Xreads each of its argument files, and converts them into HPLJ format
Xfonts (HP SFP format), and outputs them to standard output sorted
Xin ascending order of character code.
XThe output does not normally contain "SET FONT ID" sequences.
XThis is how HP distributes their fonts on floppies.
X.P
X.B pk2sfp
Xconcatenates all the conversions of the input files together on standard
Xoutput.
X.P
X.B pk2sfp
Xwith the
X.B "-m"
Xoption allows you to merge font files, at the same time changing the
Xencoding.
XMost of the options for simple font conversions apply to
X.B pk2sfp
Xwith the
X.B "-m"
Xoption, but merging is covered more completely in "Merging SFP and PK
Xfonts" below.
X.P
X.B pk2sfp
Xcan read both PK and SFP format files (the latter effectively being a
X``no-op'' conversion - which can be useful for checking format validity
Xand changing header characteristics, see below).
X.P
X.B pk2sfp
Xattempts to infer certain header characteristics by the basename
Xof the input font file name if the input font is PK format.
XThe
X.B psroff
Xnaming convention is:
X.BR path / troffname . pointsize . "[pk|sfp]"
X.sp
X.in +.5i
X.nf
XAll ROMAN8 encodings unless MATH8.
XAll 0 strokeweight, unless Bold.
XAll upright, unless Italic
XAll Roman typeface, unless otherwise specified
X
XR	: Normal Roman
XI	: Italic
XB	: Bold
XS	: MATH8 Symbol
XX	: Bold italic
X\&.X	: <typeface> Bold italic
X\&.I	: <typeface> Italic
X\&.B	: <typeface> Bold
X\&.R	: <typeface> Normal
XH or H.	: Helvetica typeface
XC or C.	: Courier typeface
X          typefaces should be extended.
X.fi
X.in -.5i
X.P
X.B pk2sfp
Xwill pass through SFP characteristics unchanged, unless you change them
Xexplicitly (see below).
X.P
X.SH "Additional options for pk2sfp"
X.P
XThe
X.BI "-s" na
Xoption will set the symbol set.
XEg:
X.B "-s8U"
Xsets the symbol set to "ROMAN8".
X.P
X.BI "-t" "0|1"
Xsets the orientation to ``upright'' (0) or ``italic'' (1).
X.P
X.BI "-w" n
Xsets the stroke weight, 0 is normal, -7 is very light and 7 is very
Xbold.
X-3 and 3 are traditional values.
X.P
X.BI "-f" n
Xsets the typeface to ``n''.
XFor example, Times Roman is ``5''.
X.P
X.BI "-i" n
Xcauses
X.B pk2sfp
Xto emit fontid sequences in front of each downloaded
Xfont, incrementing the id by one for each font, starting with number
X.IR n .
XFor compatibility with
X.B psroff
Xit is suggested that ``n'' be at least 1000.
X.P
XSpecifying
X.B "-v"
Xrequests pk2sfp to tell you what it's doing on stderr.
X.P
XThe
X.B "-S"
Xtells
X.B pk2sfp
Xthat it's dealing with a font intended for
X.BR psroff "'s"
XS font.
XThis has no effect unless
X.B "-p"
Xis specified.
X.P
XThe
X.B "-p"
X("partial downloading") feature indicates to
X.B pk2sfp
Xthat the fonts are intended for use with
X.B psroff
Xand that characters that aren't used by
X.B psroff
X(eg: half of a ROMAN8 font isn't used) will be dropped from the
Xoutput font.
XThe font being read are assumed to be ROMAN8 fonts and the list of
Xvalid characters will correspond to the characters that
X.B psroff
Xneeds from ROMAN8 sets.
XSpecify
X.B "-S"
Xtoo if you want to do this to MATH8 fonts which are intended for
Xthe characters that
X.B psroff
Xneeds from the MATH8 set.
X.P
XThe
X.B "-P"
Xoption tells pk2sfp to mark the fonts it downloads as permanent,
Xwhich means they are not cleared by a software reset, only explicit
Xdeletions or printer power-offs.
XThis option does not do anything unless
X.BI "-i" n
Xspecified as well.
X.P
XPlease note: the tables used to control
X.B "-p"
Xare compiled into
X.BR pk2sfp .
XIf you change the character translations in lj.c or lj.fonts, you
Xwill have to rebuild
X.BR pk2sfp .
XThe partial option should not be used for auxiliary fonts (fonts
Xwhich supply characters not in ROMAN8 or MATH8).
XUse the
X.B "-m"
X(merge) options for creating specialized reduced size font sets for
Xsuch fonts.
X.P
XThe following example shows how you could preload your laserjet
Xwith fonts (in sizes 8, 9, 10, 11 and 12).
XThis demonstrates the use of
Xthe
X.BR -p "," -P ","
Xand
X.B -S
Xoptions to use up as little Laserjet memory as possible.
X(These fonts should be marked ``b'' (builtin) in
X.IR lj.fonts ")."
X.sp
X.in +.25i
X.nf
X F=%%LJF%%
X pk2sfp -pP -i1000 $F/R.[89].pk $F/R.1[0-2].pk | lp
X pk2sfp -SpP -i1006 $F/S.[89].pk $F/S.1[0-2].pk | lp
X.fi
X.in .-25i
X.sp
X.P
XAll of the preceding options take place on all of the fonts specified in
Xthe command line.
XMost of the options perform no sanity checks on their arguments.
XThe reader is cautioned to read the HP manuals before attempting anything
Xfancy with options that affect header descriptors.
X.SH "Merging PK and SFP fonts: pk2sfp -m"
X.P
XThere are a wealth of fonts and font formats in the world.
XPerforming simple conversions between one format and the other would
Xlead to you having a considerably bigger repertoire of fonts.
XRight?
X.P
XWell, not always.
XNot only to the formats change from one font format to another, but
X.B encodings
Xdo too.
XIf you simply converted Knuth's fonts in PK format to SFP and used them
Xon your Laserjet you're bound to be disappointed, because a character in
XKnuth's font isn't necessarily in the same place in standard SFP fonts.
XEg: If you used the hex code 0x7B to print a left brace-bracket (that's
Xwhat it is in ASCII and ROMAN8 fonts right?), you'd find that in Knuth's
XCMR font you'll get a "ff" ligature instead.
XWorse, other ASCII/ROMAN8 characters don't exist in CMR at all.
X.P
XSo, font conversion often needs more than simple format translation
Xto work out the way you want.
X.P
XThe
X.B "-m"
Xoption to
X.B pk2sfp
Xis intended to do just that: take characters from a combination of
Xfonts, change encodings as necessary, and create one output font.
X.BR Psroff "'s"
XHP Laserjet S font is created in this way from four separate PK fonts.
X.P
XThe
X.B "-m"
Xoption to
X.B pk2sfp
Xindicates that preceding each font file specified a map file will be
Xgiven.
XEach font file will be appended together (with only one SFP header)
Xwith the translations specified by the map files and copied to
Xstandard output.
XAny character not mentioned in a map file is not copied.
XThe map file applies to the font files following until overridden
Xby the next map file.
XThe map file specifies the translations with lines of the following format:
X.sp
X.in +.5i
X.nf
Xfrom  to  description
X.fi
X.in -.5i
X.sp
X.P
X.I From
Xspecifies the character in the font file to be selected.
XAny character that doesn't match a ``from'' line will not be
Xcopied to the output.
X.I To
Xspecifies what character number the ``from'' character should be
Xchanged to.
XIf ``to'' is omitted, it is assumed to be the same as ``from''.
XThe description is free form text and is ignored.
XFrom, to and description are separated by white space.
XEmpty lines or lines beginning with "#" are comments.
X.P
X``From'' and ``to'' can be specified in any of the following formats:
Xa single non-numeric character other than ``#'',
Xa decimal number starting with a non-zero digit,
Xan octal number consisting of a zero digit followed by numeric digits,
Xor hexadecimal consisting of a zero digit, followed by 'x' or 'X', followed
Xby digits and upper or lower case 'a' through 'f'.
XIf the ``to'' string is a single double quote ("), it is duplicated
Xfrom the ``from'' string.
XThe error checking isn't very exhaustive, so it is recommended that you
Xuse the
X.B -v
Xoption to check things.
XThe
X.B -v
Xoption will also give you a very verbose description of what characters
Xits translating and what characters it couldn't find.
X.P
XThere are some examples of this in the source tree for
X.B psroff ,
Xthat generate a ROMAN8 and MATH8 SFP in 10 points.
XLook in utils/Makefile for ``testmerge'', utils/maps contains some
Xuseful translation maps, and utils/fonts contains a few PK files for
Xyour experimentation.
X.B Psroff
Xis shipped with PK format font files that were created by use of this
Xutility.
X.SH "Creating width tables: pk2ditwid"
X.P
X.B pk2ditwid
Xis used to generate a ditroff format width table file (used by
X.B psroff
Xwidth table installation via
X.B gfnttab
Xand
X.BR dit2catwid )
Xfrom PK or SFP font files.
XThe output files are generated in the current directory with the
Xsame name as the basename of the input files, with a ".WID"
Xsuffix.
X.P
XThe
X.B -S
Xoption indicates to
X.B pk2ditwid
Xthat the font file is a
XPK or SFP used for the symbol font, otherwise
X.B pk2ditwid
Xassumes that it is a normal font.
X.P
XThe
X.B -s
Xoption tells
X.B pk2ditwid
Xto shut up and do the best it can.
XOrdinarily
X.B pk2ditwid
Xis extremely chatty about which characters it could find etc.,
Xwhich is rarely of major interest to the user.
XWhich is why
X.BR psroff "'s"
Xinstallation script puts
X.BR pk2ditwid "'s"
Xoutput in log files and makes no attempt to show them to the user.
X.P
X.BR pk2ditwid "'s"
Xexact operation is somewhat bizarre, the following is a simplified
Xdescription:
X.P
XNormally,
X.B psroff
Xworks with pure ROMAN8 and MATH8
Xencoded fonts for normal and symbol font sets respectively.
X(ROMAN8 and MATH8 are two of HP's standard "char-to-glyph" mapping tables).
XHowever,
XThe MATH8 and ROMAN8 encodings do not exactly reflect CAT
X.BI troff 's
Xdivisions of characters.
XIn
X.BR troff2ps 's
Xbackend drivers, there are tables that correspond to CAT normal and symbol,
Xwhich are indexed by CAT code to select which HP font and character sequence
Xshould be emitted by the backend to print a specific CAT character.
X.P
XMost CAT codes are single HP characters, but a few are done by concatenation
X(for example \e(34 may be) or overstrike
X(\e(co may be).
X.P
X.B pk2ditwid
Xuses the backend tables and reads each of the font files given as arguments.
XIt then generates a ditroff-like width table that contains width information
Xfor each sequence of HP characters needed to generate a CAT character.
XThe width tables are fairly simple, and contain three fields of principle
Xinterest:
X.P
XColumn one is the CAT
X.B troff
Xcharacter name.
XSingle characters are themselves, dual characters are prefixed by "\e("
Xin
X.BR troff .
X.P
XThe second column indicates the width of that character in 1/300th's of an
Xinch when the character is printed at 10 points.
X(Which are the default
X.BR gfnttab / dit2catwid
Xsettings)
X.P
XThe third column is the kerning information, and is a number formed
Xby or'ing a 1 and/or 2 together.
XA ``1'' denotes an descender (eg: ``g''),
Xand a ``2'' denotes a character with an ascender (eg: ``k'').
X.P
XPlease note this is only ditroff-\f3like\fP \(em the output is not
Xintended to go through real
X.B makedev
Xwhich will probably complain about multiple-character emit sequences and
Xmissing directives.
X.P
XThe wierdness comes from the fact that it's possible to override the
XCAT character to HP sequence translation by adding directives to the
X.I lj.fonts
Xfile but the sequences are built-in (so I'm lazy...) to
X.BR pk2ditwid .
XIf you choose to add in translation overrides to
X.IR lj.fonts ,
Xyou will have to recompile
X.B pk2ditwid
Xand rerun the width table build and install procedures
Xto recompute and install the new width tables.
XThe Makefile uses the
X.B troff2ps
Xbinary to generate a compileable table of translation sequences, using
Xboth the built-in backend map plus the
X.I lj.fonts
Xoverride you've specified,
Xplus the mkenctab shell script to generate the pk2ditwid tables.
XThis is so durn complicated, that I simply automated it all:
Xin the
X.B psroff
Xsource directory area, change
X.B lib/lj.fonts
Xto reflect the translations you need,
Xand rebuild and reinstall
X.BR psroff .
X.P
XIf you're just adding new fonts to
X.BR psroff 's
Xrepertoire, this isn't all necessary, just install the fonts into
X%%LJF%% (using the proper naming convention),
Xupdate
X.IR lj.fonts ,
Xand go into the widths source directory and type ``make ljwidths widths''
Xthen su to root and ``make installwidths''.
X.P
X.B pk2ditwid
Xneed only be run on one font in each family, and by default, the build
Xprocedure runs
X.B pk2ditwid
Xonce each font (in the size closest to 10) that it finds in the
X%%LJF%% directory.
X.SH "Examining PK and SFP font files: pktype"
X.P
X.B pktype
Xreads PK and SFP format files and generates files suffixed with ".D"
Xwhich contain a description of the font and each character.
XIf the
X.B "-v"
Xoption is specified, an approximation of the character image is displayed
Xtoo.
XThe
X.BI "-f" char
Xand
X.BI "-l" char
Xoptions allow you to specify a range of characters to print, where
Xthe
X.B -f
Xspecifies the first character, and
X.B -l
Xspecifies the last character.
X.SH "Displaying PK and SFP font files: pk2ps"
X.P
X.B pk2ps
Xtakes each of the specified files and generates bitmap Postscript
Xfonts and appends to each commands to draw a table.
XThe table contains each character in the font, and below it are
Xdecimal, hexidecimal and octal numbers representing the character code.
XThe output of
X.B pk2ps
Xis on standard output.
X.P
XThe
X.B -f
Xoption causes
X.B pk2ps
Xto omit the table printing commands and some of the extra Postscript, leaving
Xonly the Postscript font definition.
XThe resultant output can then be used as a Postscript font (via inclusion
Xin ps.lib etc.).
XThe font is named for the basename of the filename.
X``<path>/cmr10.358pk'' will be called ``cmr10''.
XThe font is supposedly properly scaled, so Postscript ``scalefont'' will
Xwork normally and generate the size font you expect.
XWarning: this uses bitmapped fonts: displaying these characters at
Xconsiderably
Xlarger sizes or at odd multiples of the ``true'' size (the size of the
Xexample is actually 10 * 358 / 300) may lead to some objectionable
Xjaggies.
X.P
XIn all four utilities, the
X.BI "-D" opts
Xoption allows you to turn on debugging.
XSee
X.BR troff2ps (1)
Xfor further information.
XNote: if DEBUG compiled out, this will not be available.
X.SH FILES
X.if t .ta 2.5i
X.if n .ta 3.5i
X%%LJF%%	troff2ps LJ font directory.
X.br
X%%LIBDIR%%/lib/lj.fonts	LJ font definitions and translation overrides.
X	not read by pk2sfp/pktype/pk2ditwid
X.SH "BUGS"
X.B pk2sfp
Xshould really have multiple output files when requested by an option.
X.B pk2ditwid
Xand
X.B pk2sfp
Xshould be able to read the
X.I lj.fonts
Xfile instead of being recompiled.
X.B pk2ditwid
Xonly understands backspace or character concatenation sequences
X(eg: "a\010b" or "ab"),
Xany translation that contains any other escape sequence will not be
Xparsed properly and may generate bizarre widths, though it will
Xbe moderately sane if all of the characters in the escape sequence
Xare nonprintable (or not in the font file).
XSuch escape sequences may also affect operation of
X.B pk2sfp "'s"
Xpartial downloading feature (by including characters that you don't
Xreally need - which is harmless).
X.SH "SEE ALSO"
Xtroff2ps(1L), \fIlj.fonts\fP,
XHewlett Packard's HP Laserjet Reference Manuals.
X.SH AUTHOR
XWritten by Chris Lewis
!BLOTTO
-- 
Chris Lewis, Phone: (416)-294-9253
UUCP: uunet!utai!lsuc!ecicrl!clewis
Moderator of the Ferret Mailing List (ferret-request@eci386)
Psroff mailing list (psroff-request@eci386)