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)