TeX PK to HP SFP format font conversion (1 of 2)
Chris Lewis
clewis at ecicrl.UUCP
Tue Sep 18 02:17:28 AEST 1990
Since this keeps coming up, and psroff hasn't apparently made it to
comp.sources.unix, here's the utility to convert PK fonts to HP
SFP's that Liam mentions:
Shell archive - cut here -
#!/bin/sh
sed -e 's/^X//' > README <<\!BLOTTO
XThis distribution is that of pk2sfp, which is a subset of
Xthe full psroff 2.0 distribution. Psroff is a complete package
Xto allow you to use CAT (aka "old") troff with HP Laserjet
Xcompatible printers, Postscript and ditroff output drivers.
XPsroff has a complete set of utilities for handling PK and SFP
Xformat fonts. Pk2sfp converts PK and SFP fonts into SFP format,
Xwhich can be useful outside of psroff. Psroff 2.0 is currently
Xsitting in the queue for comp.sources.unix, but since people keep
Xasking for pk2sfp, I've decided to release this subset separately.
XIt also includes pktype, a program for printing the characteristics
Xof PK and SFP fonts. This distribution corresponds to Proff 2.0,
Xpatchlevel 3, though, patches 1 thru 2 did not touch any of this code,
Xand patch 3 was exclusively to make standalone pk2sfp possible.
XPatch 3 to psroff has not been distributed yet.
X
XTo build: modify defs.h as appropriate and type "make".
X
XThe man page for pk2sfp is uneditted from the psroff distribution
Xand refers to some things that aren't in this release:
X
X 1) pk2ditwid (creates ditroff-like width tables)
X 2) pk2ps (converts SFP's and PK's to Postscript fonts)
X 3) "partial" pk2sfp downloading stuff (-p).
X
XIn the interests of saving space, they have been omitted. If
Xyou need them, pick up the full Psroff release (they need tables
Xbuilt by other major parts of psroff). Further, you'll see some
Xstrange things that look like ``%%LJF%%''. If you had the full
Xpsroff release, they'd expand into configuration dependent directory
Xnames, but they're not builtin to any of *this* code.
X
XIf you intend to do any substantial work with PK and SFP fonts,
XI suggest that you get the whole psroff package.
X
XThis distribution is unsupported. However, psroff 2.0 *is*, and patches
Xto psroff may be applicable to this distribution.
X
XPsroff availability (while it's languishing in comp.sources.unix's queue):
X
X - gatekeeper.dec.com (16.1.0.2) as anonymous,
X file /pub/misc/psroff-2.0.tar.Z,
X courtesy Paul Vixie (vixie at wrl.dec.com)
X - cs.toronto.edu as anonymous,
X file pub/psroff.tar.Z,
X pub/psroff.patch[1-2].Z,
X courtesy Mark Moraes (moraes at cs.toronto.edu)
X
XHave fun!
X
XChris Lewis,
X
Xpsroff-request at eci386 or ...!uunet!utai!lsuc!eci386!psroff-request
!BLOTTO
sed -e 's/^X//' > Makefile <<\!BLOTTO
XCFLAGS = -DALONE
X
Xall: pk2sfp pktype
X
Xpk2sfp: pk.o pk2sfp.o debug.o
X $(CC) -o pk2sfp debug.o pk.o pk2sfp.o
X
Xpktype: pk.o pktype.o debug.o
X $(CC) -o pktype debug.o pk.o pktype.o
X
Xpk.o pk2sfp.o debug.o: pk.h defs.h
X
Xclean:
X rm -f *.o pktype pk2sfp
!BLOTTO
sed -e 's/^X//' > defs.h <<\!BLOTTO
X/* Copyright 1988, 1989 11:12:33 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: defs.h 2.5 90/09/17 11:12:33
X Author: Chris Lewis
X Specs: Main header file - contains some customization
X */
X
X/* Official Release and Patch level: */
X#define T2VERSION "@(#)PSROFF Copyright 90/09/17 Chris Lewis - R2 P3"
X
X#ifndef LIBDIR
X/* Don't touch this */
X#define LIBDIR "/usr/lib/troff2"
X#endif
X
X/* Configuration parameters:
X */
X
X#undef BSD /* Define if you are a V7 or BSD machine */
X /* strchr vs. index etc.... */
X
X#define ATT /* Define if you are some sort of SIII or SV system */
X
X#undef BCOPY /* Define if you don't have memcpy and friends - eg:
X oldish BSD systems */
X
X#undef UNSIGNEDCHAR /* Define if chars are unsigned on your machine */
X
X/* The name of a routine that can be called thusly:
X VFPRINTF(stream, format, ap)
X FILE *stream;
X char *format;
X va_list ap;
X (eg: you have varargs.h and you have a routine functionally compatible
X with System V vfprintf. I think BSD has one too)
X
X undef if you don't got, and maybe my fakeout will work.
X */
X
X#define VFPRINTF vfprintf
X
X/* If you have the stand-alone pk2sfp distribution, do not touch
X anything from here on */
X
X/* Font width file configuration:
X
X - If HEADERSIZE defined, use that many bytes as a prefix to the
X compiled font width table. HEADERSIZE 0 is the correct definition
X for Xenix and most System V Troffs. HEADERSIZE=32 works for Ultrix.
X HEADERSIZE=0 works properly for Suns (I think).
X - If COFF is defined instead, use a COFF header on the beginning of
X the file. I personally know of no machine that supports these.
X - If neither are defined, use a BSD/V7 style a.out.h header, this
X is appropriate for V7 and BSD troffs
X
X The headers I write out do not have anything in them, so some
X troff's may blow. Please let me know if they work for you...
X If you do need the headers, and these doesn't work for you, enable
X the COMPILE option in gfnttab. I know of no troff that *needs*
X COMPILE on.
X
X */
X
X#define HEADERSIZE 0 /* size of header in bytes */
X#undef COFF /* systems using COFF headers */
X
X/* What do your CAT codes look like?
X
X If BSDHACK defined, the code to magnify the next lead by 64 replaces the
X codes to set the tilt (tilt used only on 8-font CATs, which most CAT troff
X programs don't support).
X
X Both FONT8 and BSDHACK code are *untested*. FONT8 probably does *not*
X work.
X */
X
X#undef BSDHACK /* Has magnify lead opcode - untested */
X#undef FONT8 /* 8 Font device - untested */
X#define FONT4 /* Normal 4 font device */
X
X /* define a command for decompressing an argument
X file to stdout - allows you to compress SFP's.
X undef if you don't got. The -d option may be
X undocumented, but means decompress. "-dc"
X is equivalent to zcat. -dc appears to be
X in most versions of compress (eg: v3 & v4) */
X#define COMPRESS "/usr/lbin/compress -dc"
X
X/* Some postscript printers don't accept control-D as job termination
X (DEC scriptwriters for instance). In that case, define this
X macro. Alternately, if you have a proper printer manager that
X does this sort of stuff, define it too.
X */
X#undef NOCONTROLD
X
X/* define if you don't want your Postscript printer talking to you */
X#undef NOCHATTER
X
X/* The only advantage to commenting-out one of these is to make the
X binary executable of troff2?? smaller.
X */
X
X/* Basic drivers: */
X#define PS /* Postscript */
X#define LJ /* Laserjet - psroff will not build with this undef'd */
X#define DT /* ditroff */
X
X/* Laserjet driver config: */
X#define PK /* enable PK font downloading (needs LJ) */
X
X#define SFP /* enable SFP incremental font downloading (needs PK).
X You can still use SFP's without this turned on, but
X you won't get incremental downloading */
X
X#define PARTIAL /* partial (not incremental) font downloading */
X
X#define INCR /* enable incremental font downloading (needs PARTIAL) */
X
X#define MDLF 16 /* Max # downloaded fonts permitted by your laserjet
X per *page*. 16 is correct for HPLJ+ and most II's.
X IIP's are 32 I think. Some newer ones have higher
X restrictions (don't put this too high even if
X your printer supports it, you may run out of
X memory) */
X
X#define PRELOAD 0 /* set to number of LJ fonts permanently
X downloaded to printer. The backend will
X make sure that you don't go over the number
X of fonts permitted by the printer */
X
X#define DEBUG /* Do you want the debugger in? If you encounter
X problems and you want help from me, you'll have
X to have this turned on */
X
X#define OPT /* Experimental code */
X
X#define DEFPL 11 /* Default page length (11 inches).
X DO NOT change unless you absolutely HAVE to.
X You should only need to change this if you
X desire your printer to use something different
X as default. If so, you'll HAVE to change
X your macro package to agree on the default - RT
X owners take note! (the man macros are wrong) */
X
X#define DEFOFF 0.5 /* Default page offset. DO NOT change unless you
X absolutely HAVE to. You should only need this
X if: your vendor has buggered your macros to
X have a different default .po offset (Xenix),
X and you aren't using the macro adapter
X libraries that come with psroff (eg: you're
X using troff2ps directly). See README/TROUBLE/
X psroff(1) (-O vs. -rO options) */
X
X#define DEFYOFF 0 /* Default page vertical offset. See README/TROUBLE/
X psroff(1) -Y options too */
X
X/* Edit no more .... */
X
X#define MAXDLFONTS (MDLF - PRELOAD) /* # fonts troff2ps can download */
X
X/* configuration verification */
X
X#if defined(BSDHACK) && defined(FONT8)
X#include "BSDHACK and FONT8 cannot be defined at the same time"
X#endif
X#if defined(FONT4) && defined(FONT8)
X#include "FONT4 and FONT8 cannot be defined at the same time"
X#endif
X
X#if !defined(LJ) && defined(PK)
X#include "Pointless to define PK without LJ"
X#endif
X
X#if !defined(PK) && (defined(INCR) || defined(PARTIAL))
X#include "Pointless to define INCR or PARTIAL without PK"
X#endif
X
X#if defined(INCR) && !defined(PARTIAL)
X#include "Don't support INCR without PARTIAL"
X#endif
X
X#if defined(SFP) && !defined(PK)
X#include "Can't define SFP without PK"
X#endif
X
X#include <stdio.h>
X#include <ctype.h>
X
X#ifdef BSD
X#include <strings.h>
X#define strchr index
X#define strrchr rindex
X#else
X#include <string.h>
X#endif
X
X#ifdef BCOPY
X#define memcpy(to, from, len) bcopy(from, to, len)
X#define clrarray(array, len) bzero(array, len)
X#else
X#define clrarray(array, len) memset(array, '\0', len)
X#endif
X
X#ifdef UNSIGNEDCHAR
X/* Ah heck, and this is probably not ANSI C either... */
X#define SIGNED(x) (((x)&0x80) ? ((x) - 256) : (x))
X#endif
X
X#define ESC 0x80
X#define FLASH 0x00
X#define CONTROL 0x40
X#define LEAD 0x60
X#define SIZE 0x50
X
X#define DOWN 0
X#define UP 1
X#define LOWER 2
X#define UPPER 3
X#define FORWARD 4
X#define BACKWARD 5
X
X#define TROFFRESOLUTION 432
X
X#define SPECIAL /* define if you want to supports special directives */
X#define FORM /* define if you want the forms facility */
X
XFILE *diagFile;
X
X#ifdef DEBUG
X#define DBP(x) if (diagFile) dprintf x
Xextern dprintf();
X#else
X#define DBP(x)
X#endif
X
Xtypedef int(*FUNC)();
X
X#define FNULL (FUNC) NULL
X
Xstruct troff2befont {
X short t2b_font; /* font (troff nomenclature) S=don't change */
X short t2b_xc; /* X-shift */
X short t2b_yc; /* Y-shift */
X short t2b_scale; /* point size scale adjust */
X char *t2b_charseq; /* character sequence - may include PS */
X};
X
Xstruct cattab {
X char *ch_name;
X char ch_set;
X unsigned char ch_catidx;
X unsigned char ch_wididx;
X unsigned char ch_info; /* used by some auxiliary programs */
X char *ch_desc;
X};
X
Xstruct backend {
X char *bename;
X FUNC beprolog,
X beepilog,
X beputchar,
X bepage,
X befontsel, /* special function F */
X beoverlay, /* special function O */
X bepassthru, /* special function P */
X bexlat, /* Xlate function */
X bedraw; /* Ditroff draw emulation routine */
X struct troff2befont
X *bestdfont, /* standard font translate table */
X *besymfont; /* symbol font translate table */
X};
X
X#define MAXFONTS 50
X
Xstruct fonttable {
X char *tab[4];
X long flags;
X#ifdef INCR
X struct downmaps *map;
X#endif
X#ifdef OPT
X char *widthtable;
X#endif
X};
X
X/* Symbolic names for tab entries in fonttable */
X#define troffName tab[0] /* troff name */
X#define fontName tab[1] /* back-end name (if used) */
X#define fontSeq tab[2] /* sequence to emit to shift to it
X lj builtin's mostly */
X
X/* fontFlags is 16 characters that reflect the state of the font
X at a particular pointsize - mainly for lj */
X
X/* Use of flags:
X s: unloaded SFP
X S: loaded SFP
X p: unloaded PK
X P: loaded PK
X n: non-existant
X b: builtin.
X */
X#define fontFlags tab[3]
X
X
X
Xextern struct fonttable fonttable[MAXFONTS+1];
Xextern struct fonttable *xlatetable[8];
X
Xstruct backend *be;
X#define BNULL (struct backend *) NULL
X
Xextern char *skipblanks();
X
X/* Common Back-end definitions */
X
X#define N (unsigned char) (0xff) /* Use standard font */
X#define S (unsigned char) (0xfe) /* Use symbol font */
X#define D (unsigned char) (0xfd) /* Draw macro exists - use string directly */
X#define NTC (unsigned char) (0xfc) /* No font/Special flag */
X
X#define NOC NULL
X
Xextern int currentPage;
Xextern int pageoffset;
Xextern int pageyoffset;
Xextern int pagelength;
Xextern int pagePending;
X
X#ifdef OPT
Xextern char *widthtables;
Xextern char *widthptr;
Xextern int optimize;
X#endif
X
Xextern int lastFont, lastPoints;
Xextern int lastYPos, lastXPos, specXPos, specYPos;
Xextern char *progname, *printer, *device;
Xextern char **prologs;
X
Xint metrics;
X
XFILE *libopen();
X
X/* Encoding format for generating width tables from font files */
X/* Used by pk2ditwid and friends */
Xstruct enctab {
X char *e_name;
X char *e_seq;
X char e_wid;
X};
X
X/* Points in an inch */
X#define POINT 72.27
X
X#define min(a,b) ((a) < (b) ? (a) : (b))
X#define max(a,b) ((a) > (b) ? (a) : (b))
X
X/* debug flags */
X#define D_CAT 1
X#define D_SPEC 2
X#define D_CHAR 4
X#define D_FONT 8
X#define D_BEND 0x10
X#define D_PK 0x20
X#define D_VERB 0x40
X
Xextern int debug;
X
Xextern char username[];
X
Xextern char *mustmalloc();
X
Xextern char *version, *shortversion;
X
X#ifdef ALONE
X#undef PARTIAL
X#undef INCR
X#endif
!BLOTTO
sed -e 's/^X//' > pk.h <<\!BLOTTO
X/* Copyright 1985, 1986, 1987, 1988 16:47:03 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: pk.h
X Author: Chris Lewis
X Specs: PK format font file description
X */
X
X#ifdef PK
X
X#define int8 unsigned char
X#define PK_ID 89
X#define PK_xxx1 240
X#define PK_xxx2 241
X#define PK_xxx3 242
X#define PK_xxx4 243
X#define PK_yyy 244
X#define PK_post 245
X#define PK_no_op 246
X#define PK_pre 247
X
X/* PK header data */
Xstruct pkp {
X#define PK_PK 01
X#define PK_SFP 02
X long pkp_ds; /* design size */
X long pkp_npts; /* pointsize normalized to 300 dpi */
X long pkp_res; /* resolution of this font */
X long pkp_cs; /* checksum */
X long pkp_hppp; /* Horizontal pixel ratio */
X long pkp_vppp; /* Vertical pixel ratio */
X long pkp_bmax; /* baseline max */
X long pkp_dmax; /* descender max */
X long pkp_wmax; /* width max */
X long pkp_xomax; /* left offset max */
X long pkp_kh; /* kern high */
X long pkp_kl; /* kern low */
X struct pkc *pkp_chars; /* pointer to character descriptors */
X struct pkc *pkp_last; /* pointer to last character descriptor */
X struct pkc **pkp_list; /* pointer to sorted list of descriptors */
X long pkp_num; /* number of characters */
X int pkp_symset; /* symbol set */
X char pkp_flags; /* font format */
X char pkp_style; /* style */
X char pkp_sw; /* stroke weight */
X char pkp_typeface; /* typeface */
X};
X
Xstruct pkp *pk_read();
X
Xstruct pkc {
X long pkc_flag; /* flag byte */
X long pkc_dyn_f; /* dynamic packing byte */
X long pkc_pl; /* packet length */
X long pkc_char; /* character code */
X long pkc_tfm; /* TeX font metrics */
X long pkc_dx; /* Horizontal escapement */
X long pkc_dy; /* Vertical escapement */
X long pkc_width; /* character width of BB */
X long pkc_height; /* character height of BB */
X long pkc_x_off; /* horizontal offset from upper left pixel to ref. */
X long pkc_y_off; /* vertical offset from upper left pixel to ref. */
X long turnon; /* used for unravelling bits */
X long pkc_rlen; /* actual raster length */
X int8 *pkc_pkr; /* actual PK raster */
X struct ras *pkc_sfpr; /* SFP raster */
X struct pkc *pkc_next; /* next character */
X};
X
Xstruct ras {
X long ras_width;
X long ras_height;
X long ras_bline;
X long ras_bytes;
X long ras_xcur;
X long ras_ycur;
X int8 *ras_raster;
X};
X
X#define pow2(x) (1L << (x))
X
X#define OUTRES 300
X#endif
!BLOTTO
sed -e 's/^X//' > pk.c <<\!BLOTTO
X/* Copyright 1990 Chris Lewis
X */
X
X
X#include "defs.h"
X
X#ifdef PK
X
X#ifndef lint
Xstatic char SCCSid[] = "@(#)pk.c 2.1 Copyright 90/07/18 16:51:38 Chris Lewis";
X#endif
X
X#define DRAW
X#define OUTRES 300
X
X#include "pk.h"
X
X#if defined(PARTIAL)
X#include "pkc.h"
Xstruct needmaps *needmaps = (struct needmaps *) NULL;
X#endif
X
Xextern char *progname;
X
Xstatic FILE *fin;
Xstatic char *filename; /* name of *current* font being read */
Xextern char *malloc();
X
Xstatic long flag_byte;
Xstatic repeatcount;
Xstatic dyn_f;
X
Xstatic readraster();
X
Xstatic long
Xget1int() { return(getc(fin)); }
X
Xstatic long
Xget2int() {
X register long c;
X c = get1int();
X c = (c<<8) | (0xff & get1int());
X return(c);
X}
X
Xstatic long
Xget4int() {
X register long c;
X c = get2int();
X c = (c << 16) | (0xffff & get2int());
X return(c);
X}
X
Xstatic long
Xget3int() {
X register long c;
X c = get2int();
X c = (c << 8) | (0xff & get1int());
X return(c);
X}
X
X#ifdef VFPRINTF
X#include <varargs.h>
X/* VARARGS */
Xpkmsg(va_alist)
Xva_dcl
X{
X va_list args;
X char *fmt;
X
X va_start(args);
X fmt = (char *) va_arg(args, char *);
X VFPRINTF(stderr, fmt, args);
X va_end(args);
X}
X#else
X/* VARARGS1 ARGSUSED */
Xpkmsg(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
Xchar *fmt;
Xint a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; {
X char buf[BUFSIZ];
X sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
X fprintf(stderr, buf);
X}
X#endif
X
Xstatic
Xskipspecials() {
X register int i,c;
X do {
X flag_byte = getc(fin);
X if (flag_byte >= 240) {
X i = 0;
X switch(flag_byte) {
X case PK_xxx4:
X i = (i << 8) + getc(fin);
X case PK_xxx3:
X i = (i << 8) + getc(fin);
X case PK_xxx2:
X i = (i << 8) + getc(fin);
X case PK_xxx1:
X i = (i << 8) + getc(fin);
X DBP((D_PK, "PK_xxx%d: ", flag_byte - PK_xxx1 + 1));
X while(i--) {
X c = getc(fin);
X DBP((D_PK, "%c", c));
X }
X DBP((D_PK, "\n"));
X break;
X case PK_yyy:
X i = get4int();
X DBP((D_PK, "Num special: %d\n", i));
X break;
X case PK_post:
X DBP((D_PK, "Postamble\n"));
X break;
X case PK_no_op:
X DBP((D_PK, "No-op\n"));
X break;
X default:
X pkmsg("PK file %s: Unexpected %ld\n", filename,
X flag_byte);
X exit(1);
X }
X }
X } while (flag_byte >= 240 && flag_byte != PK_post);
X}
X
Xstatic
Xreadschar(p)
Xstruct pkc *p; {
X p->pkc_pl = get1int() + ((p->pkc_flag&0x3) << 8);
X p->pkc_char = get1int();
X p->pkc_tfm = get3int();
X p->pkc_dx = get1int() * pow2(16);
X p->pkc_dy = 0;
X p->pkc_width = get1int();
X p->pkc_height = get1int();
X p->pkc_x_off = get1int();
X p->pkc_y_off = get1int();
X if (p->pkc_x_off > 127)
X p->pkc_x_off -= 256;
X if (p->pkc_y_off > 127)
X p->pkc_y_off -= 256;
X p->pkc_rlen = p->pkc_pl - 8;
X readraster(p);
X}
X
Xstatic
Xreadeschar(p)
Xstruct pkc *p; {
X p->pkc_pl = get2int() + ((p->pkc_flag&0x3) << 16);
X p->pkc_char = get1int();
X p->pkc_tfm = get3int();
X p->pkc_dx = get2int() * pow2(16);
X p->pkc_dy = 0;
X p->pkc_width = get2int();
X p->pkc_height = get2int();
X p->pkc_x_off = get2int();
X p->pkc_y_off = get2int();
X if (p->pkc_x_off > 32767)
X p->pkc_x_off -= 65536;
X if (p->pkc_y_off > 32767)
X p->pkc_y_off -= 65536;
X p->pkc_rlen = p->pkc_pl - 13;
X readraster(p);
X}
X
Xstatic
Xreadlchar(p)
Xstruct pkc *p; {
X p->pkc_pl = get4int();
X p->pkc_char = get4int();
X p->pkc_tfm = get4int();
X p->pkc_dx = get4int();
X p->pkc_dy = get4int();
X p->pkc_width = get4int();
X p->pkc_height = get4int();
X p->pkc_x_off = get4int();
X p->pkc_y_off = get4int();
X p->pkc_rlen = p->pkc_pl - 28;
X readraster(p);
X}
X
Xstatic
Xreadraster(p)
Xstruct pkc *p; {
X p->pkc_pkr = (int8 *) mustmalloc((int) p->pkc_rlen, filename);
X fread((char *) p->pkc_pkr, 1, (int) p->pkc_rlen, fin);
X}
X
X/* Read a character sequence from a PK file */
Xstatic struct pkc *
Xrpkc() {
X register struct pkc *p = (struct pkc *) mustmalloc(sizeof(struct pkc),
X filename);
X
X p->pkc_pkr = NULL;
X p->pkc_sfpr = NULL;
X p->pkc_flag = flag_byte;
X p->pkc_dyn_f = p->pkc_flag >> 4;
X flag_byte &= 0x7;
X
X if (flag_byte == 7)
X readlchar(p);
X else if (flag_byte > 3)
X readeschar(p);
X else
X readschar(p);
X return(p);
X}
X
X#ifdef SFP
X/* Read a character sequence from an SFP */
Xstatic struct pkc *
Xrsfpc() {
X register struct pkc *p;
X int len;
X
X if ((len = getc(fin)) == EOF || len != '\033') {
X /* HP fonts when loaded often have trailing nulls due to DOS
X file padding. Screech on non-null */
X if (len && len != EOF)
X fprintf(stderr,
X "%s: WARNING: trailing garbage in %s, offset %ld, char 0x%02x\n",
X progname, filename, ftell(fin), len);
X flag_byte = PK_post;
X return((struct pkc *) NULL);
X }
X
X p = (struct pkc *) mustmalloc(sizeof(struct pkc), filename);
X p->pkc_pkr = NULL;
X p->pkc_sfpr = NULL;
X p->pkc_flag = 0;
X p->pkc_dyn_f = 0;
X
X if (fscanf(fin, "*c%ldE", &(p->pkc_char)) != 1) {
X pkmsg("SFP file: %s, bad/missing SET CHAR CODE, offset: %ld\n",
X filename, ftell(fin));
X exit(1);
X }
X
X if (fscanf(fin, "\033(s%dW", &len) != 1 || len < 16) {
X pkmsg("SFP file: %s, bad/missing/tooshort CHAR DOWNLOAD sequence\n",
X filename);
X exit(1);
X }
X
X get4int(); /* skip some garbage */
X get2int(); /* skip more garbage (actually, orientation & dummy */
X
X p->pkc_x_off = get2int();
X if (p->pkc_x_off > 32767)
X p->pkc_x_off -= 65536;
X p->pkc_x_off = -p->pkc_x_off;
X p->pkc_y_off = get2int();
X if (p->pkc_y_off > 32767)
X p->pkc_y_off -= 65536;
X p->pkc_width = get2int();
X p->pkc_height = get2int();
X p->pkc_dx = get2int() * pow2(16) / 4;
X
X p->pkc_sfpr = (struct ras *) mustmalloc(sizeof(struct ras), filename);
X
X p->pkc_sfpr->ras_height = p->pkc_height;
X p->pkc_sfpr->ras_width = p->pkc_width;
X p->pkc_sfpr->ras_bline = (p->pkc_width + 7) / 8;
X p->pkc_sfpr->ras_bytes = p->pkc_sfpr->ras_height * p->pkc_sfpr->ras_bline;
X if (p->pkc_sfpr->ras_bytes) {
X p->pkc_sfpr->ras_raster = (int8 *) mustmalloc((int)
X p->pkc_sfpr->ras_bytes, filename);
X
X fread((char *) p->pkc_sfpr->ras_raster, (int) p->pkc_sfpr->ras_bytes,
X 1, fin);
X } else {
X free((char *) p->pkc_sfpr);
X p->pkc_sfpr = NULL;
X }
X
X return(p);
X}
X#endif
X
Xstatic struct pkc *
Xreadchar(p)
Xstruct pkp *p; {
X if (p->pkp_flags&PK_PK)
X return(rpkc());
X#ifdef SFP
X else if (p->pkp_flags&PK_SFP)
X return(rsfpc());
X#endif
X else
X return((struct pkc *) NULL);
X}
X
Xstatic int
Xpkccomp(a, b)
Xstruct pkc **a, **b; {
X if ((*a)->pkc_char < (*b)->pkc_char)
X return(-1);
X else
X return(1);
X /* can't be equal! */
X}
X
Xstatic
Xrastbit(x,y,r)
Xregister int x, y;
Xregister struct ras *r; {
X register int bi = y * r->ras_bline + (x >> 3);
X
X /* You don't really want to uncomment this.... ;-) */
X /* printf("x,y,bi: %d,%d,%d\n", x, y, bi);*/
X return(r->ras_raster[bi] & (0x80 >> (x&7)));
X}
X
Xstatic int8 *rptr;
Xstatic long bitweight;
X
Xgetnyb() {
X register int8 b;
X if (!bitweight) {
X bitweight = 8;
X rptr++;
X }
X b = *rptr;
X bitweight -= 4;
X#ifdef VDEBUG
X DBP((D_PK, "getnyb byte: %x\n", b));
X DBP((D_PK, "getnyb: %x\n", (b >> bitweight) & 0xf));
X#endif
X return((b >> bitweight)&0xf);
X}
X
X#ifdef NEVER
Xgetbit() {
X register int8 b;
X if (!bitweight) {
X bitweight = 8;
X rptr++;
X }
X b = *rptr;
X bitweight--;
X return((b>>bitweight)&1);
X}
X#endif
X
X/* Dumps an ASCII version of the SFP raster r, to line n.
X Normally only for debugging, but is also used from pktype
X */
X
Xdumpr(r, n)
Xstruct ras *r;
Xint n; {
X int x, y;
X if (!diagFile)
X return;
X fprintf(diagFile, "\n");
X for (y = 0; y < n; y++) {
X fprintf(diagFile, "%3d ", y);
X for (x = 0; x < r->ras_width; x++) {
X if (rastbit(x, y, r))
X putc('*', diagFile);
X else
X putc(' ', diagFile);
X }
X putc('\n', diagFile);
X }
X}
X
Xstatic long
Xpkpack(pc,r)
Xregister struct pkc *pc;
Xregister struct ras *r; {
X long i, j;
X long pkpackret;
X i = getnyb();
X if (i == 0) {
X do {
X j = getnyb();
X i++;
X } while(!j);
X while(i--)
X j = (j << 4) + getnyb();
X pkpackret = (j - 15 + (13 - dyn_f) * 16 + dyn_f);
X } else if (i <= dyn_f)
X pkpackret = (i);
X else if (i < 14)
X pkpackret = ((i - dyn_f - 1)*16 + getnyb() + dyn_f + 1);
X else {
X if (repeatcount) {
X pkmsg("Second repeat count for this row!\n");
X exit(1);
X }
X if (i == 14)
X repeatcount = pkpack(pc,r);
X else
X repeatcount = 1;
X /*sendout(1, repeatcount, pc, r);*/
X pkpackret = (pkpack(pc,r));
X }
X if (pkpackret < 1) {
X pkmsg("pkpack returned < 1! (%s)", filename);
X exit(1);
X }
X return(pkpackret);
X}
X
Xstatic
Xgetpbits(pc, r)
Xregister struct pkc *pc;
Xregister struct ras *r; {
X register int h_bit = pc->pkc_width,
X count,
X turnon;
X turnon = pc->pkc_flag&0x8;
X dyn_f = pc->pkc_dyn_f;
X repeatcount = 0;
X r->ras_xcur = r->ras_ycur = 0;
X while(r->ras_ycur < pc->pkc_height) {
X count = pkpack(pc,r);
X while(count > 0) {
X if (count >= h_bit) {
X count -= h_bit;
X while(h_bit--) {
X if (turnon)
X r->ras_raster[r->ras_ycur*r->ras_bline + (r->ras_xcur>>3)]
X |= (0x80 >> (r->ras_xcur&7));
X r->ras_xcur++;
X }
X r->ras_ycur++;
X r->ras_xcur = 0;
X while(repeatcount --) {
X#ifdef VDEBUG
X DBP((D_PK, "Copy line %d to %d\n", r->ras_ycur,
X r->ras_ycur-1));
X#endif
X memcpy((char*)&(r->ras_raster[r->ras_ycur * r->ras_bline]),
X (char*)&(r->ras_raster[(r->ras_ycur - 1) *
X r->ras_bline]),
X (int) r->ras_bline);
X r->ras_ycur++;
X }
X repeatcount = 0;
X h_bit = pc->pkc_width;
X } else {
X h_bit -= count;
X while(count--) {
X if (turnon)
X r->ras_raster[r->ras_ycur*r->ras_bline +
X (r->ras_xcur>>3)] |= (0x80 >> (r->ras_xcur&7));
X r->ras_xcur++;
X }
X count = 0;
X }
X }
X turnon = !turnon;
X }
X if (r->ras_ycur != pc->pkc_height ||
X h_bit != pc->pkc_width)
X pkmsg("Bad bit somehow (%s)\n", filename);
X}
X
Xstatic
Xgetrbits(pc, r)
Xregister struct pkc *pc;
Xregister struct ras *r; {
X register int x, y;
X register int bit = 0;
X for (y = 0; y < pc->pkc_height; y++) {
X for (x = 0; x < pc->pkc_width; x++) {
X if (pc->pkc_pkr[bit >> 3] & (0x80 >> (bit&7)))
X r->ras_raster[y*r->ras_bline + (x>>3)] |= (0x80 >> (x&7));
X bit++;
X }
X }
X}
X
X/* Convert a PK raster to an unpacked SFP version.
X (If there's already an SFP version, it's returned instead)
X */
Xstruct ras *
Xpkrast(pc)
Xstruct pkc *pc; {
X register struct ras *r;
X if (pc->pkc_sfpr)
X return(pc->pkc_sfpr);
X if (!pc->pkc_rlen)
X return(NULL);
X
X pc->pkc_sfpr = r = (struct ras *) mustmalloc(sizeof(struct ras),
X filename);
X
X r->ras_height = pc->pkc_height;
X r->ras_width = pc->pkc_width;
X r->ras_bline = (pc->pkc_width + 7) / 8;
X r->ras_bytes = r->ras_height * r->ras_bline;
X r->ras_raster = (int8 *) mustmalloc((int) r->ras_bytes, filename);
X
X /* initialize bit unpackers */
X rptr = pc->pkc_pkr;
X bitweight = 8;
X
X /* calculate bits here...*/
X if (pc->pkc_dyn_f == 14)
X getrbits(pc, r);
X else
X getpbits(pc, r);
X return(r);
X}
X
X/* Read a PK font file header */
Xstatic struct pkp *
Xpk_rpk(p)
Xregister struct pkp *p; {
X register int i,c;
X
X if (getc(fin) != 89) {
X pkmsg("PK file %s: Wrong version of packed file!\n", filename);
X exit(1);
X }
X i = getc(fin);
X if (i > 0) {
X DBP((D_PK, "PKVersion: "));
X while (i--) {
X c = getc(fin);
X DBP((D_PK, "%c", c));
X }
X DBP((D_PK, "\n"));
X }
X p->pkp_bmax = 0;
X p->pkp_dmax = 0;
X p->pkp_wmax = 0;
X p->pkp_xomax = 0;
X p->pkp_ds = get4int();
X p->pkp_cs = get4int();
X p->pkp_hppp = get4int();
X p->pkp_vppp = get4int();
X
X if (p->pkp_hppp != p->pkp_vppp)
X pkmsg("PK file %s: Warning aspect ratio not 1:1\n", filename);
X p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
X p->pkp_npts = ((double) p->pkp_ds / pow2(20)) *
X ((double) p->pkp_res / OUTRES) + .5;
X p->pkp_chars = (struct pkc *) NULL;
X p->pkp_last = (struct pkc *) NULL;
X p->pkp_num = 0;
X p->pkp_list = (struct pkc **) NULL;
X
X /* Try to guess symset, style, stroke weight and typeface
X These aren't particularly important, but it assists the LJ
X if it's trying to select one of these via characteristic.
X This will only work if the file name reflects the Troff name,
X according to the following conventions:
X
X filename: {<path>/}troffname.pointsize.[pk|sfp]
X
X All ROMAN8 encodings unless MATH8.
X All 0 strokeweight, unless Bold.
X All upright, unless Italic
X All Roman typeface, unless otherwise specified
X
X R : Normal Roman
X I : Italic
X B : Bold
X S : MATH8 Symbol
X X : Bold italic
X .X : <typeface> Bold italic
X .I : <typeface> Italic
X .B : <typeface> Bold
X .R : <typeface> Normal
X H or H. : Helvetica typeface
X C or C. : Courier typeface
X typefaces should be extended.
X */
X
X {
X register char *fp;
X register int char1, char2, italic, bold, bolditalic, onechar;
X
X fp = strrchr(filename, '/');
X if (!fp)
X fp = filename;
X else
X fp++;
X
X /* Default settings */
X p->pkp_symset = (8 << 5) - 64 + 'U'; /* ROMAN 8 */
X p->pkp_style = 0; /* upright */
X p->pkp_sw = 0; /* stroke 0 */
X p->pkp_typeface = 5; /* typeface Roman */
X
X char1 = *fp++;
X onechar = (*fp == '.');
X
X if (char1 == 'S' && onechar)
X p->pkp_symset = (8 << 5) - 64 + 'M'; /* MATH 8 */
X else {
X
X char2 = *fp;
X
X italic = ((onechar && char1 == 'I') || char2 == 'I');
X bold = ((onechar && char1 == 'B') || char2 == 'B');
X bolditalic = ((onechar && char1 == 'X') || char2 == 'X');
X
X if (bold || bolditalic)
X p->pkp_sw = 3;
X
X if (italic || bolditalic)
X p->pkp_style = 1;
X
X /* This should be extended, but I don't have a good feeling
X for troff typeface -> HPLJ nomenclature */
X switch(char1) {
X case 'H':
X p->pkp_typeface = 4; /* Helvetica */
X break;
X case 'C':
X p->pkp_typeface = 3; /* Courier */
X break;
X /* more? */
X }
X }
X }
X
X return(p);
X}
X
X#ifdef SFP
X
X/* Read an SFP header and convert it into the PK internal structure.
X */
Xstatic struct pkp *
Xpk_rsfp(p)
Xregister struct pkp *p; {
X register int c;
X int len;
X
X if (fscanf(fin, ")s%dW", &len) != 1) {
X pkmsg("SFP file %s: Bad CREATE FONT sequence\n", filename);
X exit(1);
X }
X
X if (len < 26) {
X pkmsg("SFP file %s: CREATE FONT sequence too short (%d)\n",
X filename, len);
X exit(1);
X }
X
X get2int(); /* 26 */
X get1int(); /* 0 */
X get1int(); /* 0 or 1 - forced 1 anyways */
X get2int(); /* dummy */
X
X p->pkp_bmax = get2int(); /* baseline */
X p->pkp_wmax = get2int(); /* cell width */
X p->pkp_dmax = get2int() - p->pkp_bmax; /* cell height */
X
X get1int(); /* 0 port, 1 land - forced 0 */
X get1int(); /* fixed/proportional - forced proportional */
X
X p->pkp_symset = get2int();
X
X get2int(); /* pitch - we calculate this from height */
X c = get2int(); /* retrieved *height* */
X p->pkp_npts = c * POINT / (OUTRES*4) + .5;
X
X get2int(); /* dummy */
X get1int(); /* dummy */
X
X p->pkp_style = get1int();
X p->pkp_sw = get1int();
X p->pkp_typeface = get1int();
X
X p->pkp_xomax = 0;
X
X /* These are simulated so that the PK handlers can figure the font out */
X p->pkp_ds = p->pkp_npts * pow2(20);
X p->pkp_cs = 0;
X p->pkp_hppp = OUTRES * pow2(16) / POINT;
X p->pkp_vppp = OUTRES * pow2(16) / POINT;
X p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
X
X p->pkp_chars = (struct pkc *) NULL;
X p->pkp_last = (struct pkc *) NULL;
X p->pkp_num = 0;
X p->pkp_list = (struct pkc **) NULL;
X
X
X len -= 26;
X while(len--)
X getc(fin);
X return(p);
X}
X#endif
X
Xstatic struct pkp *
Xreadhead() {
X register struct pkp *p = (struct pkp *) mustmalloc(sizeof(struct pkp),
X filename);
X switch(getc(fin)) {
X case PK_pre:
X p->pkp_flags |= PK_PK;
X return(pk_rpk(p));
X#ifdef SFP
X case 0x1b:
X p->pkp_flags |= PK_SFP;
X flag_byte = 0;
X return(pk_rsfp(p));
X#endif
X default:
X fprintf(stderr, "PK file: %s don't know what it is!\n",
X filename);
X exit(1);
X }
X /*NOTREACHED*/
X}
X
Xpk_destroy(p)
Xregister struct pkp *p; {
X register struct pkc *pc, *opc;
X for (pc = p->pkp_chars; pc;) {
X if (pc->pkc_pkr)
X free((char *) pc->pkc_pkr);
X
X if (pc->pkc_sfpr) {
X free((char *) pc->pkc_sfpr->ras_raster);
X free((char *) pc->pkc_sfpr);
X }
X
X opc = pc;
X pc = opc->pkc_next;
X free((char *) opc);
X }
X if (p->pkp_list)
X free((char *) p->pkp_list);
X free((char *) p);
X}
X
Xstruct pkp *
Xpk_read(file, fontcode)
Xchar *file; int fontcode; {
X register struct pkp *p;
X register struct pkc *pc, **pcp;
X#ifdef COMPRESS
X int compressed = 0;
X#endif
X fin = (FILE *) NULL;
X if (access(filename = file, 4) == 0)
X fin = fopen(filename, "r");
X#ifdef COMPRESS
X else {
X char buf[1024];
X strcpy(buf, file);
X strcat(buf, ".Z");
X if (access(buf, 4) == 0) {
X sprintf(buf, "%s %s.Z", COMPRESS, file);
X fin = popen(buf, "r");
X compressed = 1;
X }
X }
X#endif
X if (!fin) {
X pkmsg("Cannot open PK/SFP file %s\n", file);
X exit(1);
X }
X p = readhead();
X if (p->pkp_flags&PK_PK)
X skipspecials();
X
X while ((flag_byte != PK_post) && (pc = readchar(p))) {
X DBP((D_VERB, "type: %s: %d\n", p->pkp_flags&PK_PK? "PK": "SFP",
X pc->pkc_char));
X#ifdef PARTIAL
X if (!needchar(fontcode, pc->pkc_char)) {
X DBP((D_FONT|D_PK, "Dropping char %02x from load\n", pc->pkc_char));
X
X if (pc->pkc_pkr) {
X free((char *) pc->pkc_pkr);
X pc->pkc_pkr = (int8 *) NULL;
X }
X
X if (pc->pkc_sfpr) {
X free((char *) pc->pkc_sfpr->ras_raster);
X free((char *) pc->pkc_sfpr);
X pc->pkc_sfpr = (struct ras *) NULL;
X }
X
X free((char *) pc);
X if (p->pkp_flags&PK_PK)
X skipspecials();
X continue;
X }
X#endif
X DBP((D_FONT|D_PK, "Loading char %02x\n", pc->pkc_char));
X p->pkp_num++;
X pc->pkc_next = (struct pkc *) NULL;
X if (!p->pkp_chars)
X p->pkp_chars = pc;
X if (p->pkp_last)
X p->pkp_last->pkc_next = pc;
X p->pkp_last = pc;
X if (p->pkp_flags&PK_PK) {
X p->pkp_bmax = max(p->pkp_bmax, pc->pkc_y_off);
X p->pkp_dmax = max(p->pkp_dmax, pc->pkc_height - pc->pkc_y_off);
X p->pkp_wmax = max(p->pkp_wmax, pc->pkc_width - pc->pkc_x_off);
X }
X p->pkp_xomax = min(p->pkp_xomax, pc->pkc_x_off);
X if (pc->pkc_char == 'a') {
X p->pkp_kh = pc->pkc_y_off;
X p->pkp_kl = pc->pkc_y_off - pc->pkc_height;
X }
X if (p->pkp_flags&PK_PK)
X skipspecials();
X }
X DBP((D_FONT|D_PK, "End of font\n"));
X#ifdef COMPRESS
X if (compressed) {
X if (pclose(fin)) {
X pkmsg("Decompression of %s failed\n", file);
X exit(1);
X }
X } else
X#endif
X fclose(fin);
X pcp = p->pkp_list = (struct pkc **)
X mustmalloc((int) (p->pkp_num * sizeof(struct pkc *)), filename);
X for (pc = p->pkp_chars; pc; pc = pc->pkc_next)
X *pcp++ = pc;
X qsort(p->pkp_list, (unsigned) p->pkp_num, sizeof(struct pkc *), pkccomp);
X return(p);
X}
X
X/* Emit routines */
X
X/* Emit a font descriptor in SFP format */
Xepk_desc(p, sfp)
Xregister struct pkp *p;
XFILE *sfp; {
X
X fprintf(sfp, "\033)s26W");
X fputshort(26, sfp);
X fputc(0, sfp);
X fputc(1, sfp); /* font type 1 (33-127 && 160-255 printable) */
X fputshort(0, sfp);
X fputshort(p->pkp_bmax, sfp); /* baseline position */
X fputshort(p->pkp_wmax, sfp); /* cell width */
X fputshort(p->pkp_bmax + p->pkp_dmax, sfp); /* cell height */
X fputc(0, sfp); /* portrait */
X fputc(1, sfp); /* proportional */
X
X fputshort((long) p->pkp_symset, sfp);
X
X fputshort((long) (OUTRES * p->pkp_npts * 4) / 120, sfp);
X fputshort((long) (p->pkp_npts * (OUTRES / POINT) * 4), sfp);
X fputshort(0, sfp);
X fputc(0, sfp);
X fputc(p->pkp_style, sfp);
X fputc(p->pkp_sw, sfp);
X fputc(p->pkp_typeface, sfp);
X
X}
X
Xfputshort(val, f)
XFILE *f;
Xlong val; {
X fputc(((int) val >> 8) & 0xff, f);
X fputc((int) val & 0xff, f);
X}
X
X
X/* Emit a character descriptor in SFP format.
X Notes: if this is a PK font, the PK raster is converted
X to SFP format and dumpped. If the font was originally
X SFP format, it's dumpped directly. In either event, epkc_desc
X deletes the SFP raster *and* the PK raster (if the character
X has one), meaning that once this routine has emitted a character,
X you can't emit it again! Which is why pkc's pkflush completely
X destroys the font. Why? Well, SFP's can get rather large, and
X it seems reasonable to get rid of them as quickly as possible.
X
X Returns number of bytes emitted.
X */
Xepkc_desc(pc, sfp)
Xregister struct pkc *pc;
Xregister FILE *sfp; {
X register struct ras *r;
X
X if (!pc->pkc_pkr && !pc->pkc_sfpr) {
X fprintf(stderr, "%s: already downloaded %02x\n", pc->pkc_char);
X return(0);
X }
X
X /* Emit SET CHARACTER sequence */
X fprintf(sfp, "\033*c%dE", pc->pkc_char);
X
X /* Emit DOWNLOAD CHARACTER sequence */
X fprintf(sfp, "\033(s%dW", 16 + ((pc->pkc_width + 7) / 8) *
X pc->pkc_height);
X fputc(4, sfp);
X fputc(0, sfp);
X fputc(14, sfp);
X fputc(1, sfp);
X fputc(0, sfp); /* portrait */
X fputc(0, sfp);
X fputshort(-pc->pkc_x_off, sfp);
X fputshort(pc->pkc_y_off, sfp);
X fputshort(pc->pkc_width, sfp);
X fputshort(pc->pkc_height, sfp);
X fputshort(pc->pkc_dx * 4 / pow2(16), sfp);
X r = pkrast(pc);
X
X if (pc->pkc_pkr)
X free((char *) pc->pkc_pkr);
X pc->pkc_pkr = (int8 *) NULL;
X
X if (r) {
X#ifdef VDEBUG
X dumpr(r, r->ras_ycur);
X#endif
X fwrite((char *) r->ras_raster, 1, (int) ((pc->pkc_width + 7) / 8) *
X (int) pc->pkc_height, sfp);
X free((char *) r->ras_raster);
X free((char *) r);
X }
X pc->pkc_sfpr = (struct ras *) NULL;
X return(((pc->pkc_width + 7) / 8) * pc->pkc_height);
X}
X#endif
!BLOTTO
sed -e 's/^X//' > debug.c <<\!BLOTTO
X#include "defs.h"
X
X#ifndef lint
Xstatic char SCCSid[] =
X "@(#)debug.c: 2.2 Copyright 90/08/08 13:14:09 Chris Lewis";
X#endif
X
X#ifdef DEBUG
X
Xint debug = 0;
X
X#define D_CAT 1
X#define D_SPEC 2
X#define D_CHAR 4
X#define D_FONT 8
X#define D_BEND 0x10
X#define D_PK 0x20
X#define D_VERB 0x40
X#define D_FLSH 0x80
X
Xstruct dbm {
X char req;
X int bit;
X} dbm[] = {
X {'c', D_CAT},
X {'s', D_SPEC},
X {'C', D_CHAR},
X {'f', D_FONT},
X {'F', D_FLSH},
X {'b', D_BEND},
X {'p', D_PK},
X {'v', D_VERB},
X {'A', ~0},
X {0, 0}
X};
X
Xsetdebug(str, df)
Xchar *str, *df; {
X register struct dbm *d;
X for(;*str; str++) {
X for(d = dbm; d->req; d++)
X if (d->req == *str) {
X debug |= d->bit;
X break;
X }
X if (!d->req) {
X fprintf(stderr, "%s: don't understand %c debug flag\n",
X progname, *str);
X exit(1);
X }
X }
X
X if (debug) {
X if (!(diagFile = fopen(df, "w"))) {
X fprintf(stderr, "%s: Cannot open diagnostics file (%s)\n",
X progname, df);
X exit(1);
X }
X fprintf(diagFile, "Debug flags: %x\n", debug);
X }
X}
X
X#ifdef VFPRINTF
X#include <varargs.h>
X/* VARARGS */
Xdprintf(level, va_alist)
Xint level;
Xva_dcl
X{
X va_list args;
X char *fmt;
X
X if (!(debug&level))
X return;
X
X va_start(args);
X fmt = va_arg(args, char *);
X VFPRINTF(diagFile, fmt, args);
X va_end(args);
X if (debug&D_FLSH)
X fflush(diagFile);
X}
X#else
X/* VARARGS1 ARGSUSED */
Xdprintf(level, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
Xint level;
Xchar *fmt;
Xint a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; {
X char buf[BUFSIZ];
X
X if (!(debug&level))
X return;
X
X sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
X fprintf(diagFile, buf);
X if (debug&D_FLSH)
X fflush(diagFile);
X}
X#endif
X#endif
X
Xchar *
Xmustmalloc(n, msg)
Xint n;
Xchar *msg; {
X extern char *malloc();
X register char *p = malloc((unsigned) n);
X if (!p) {
X fprintf(stderr, "%s: Out of space! (requesting %d bytes, key: %s)\n",
X progname, n, msg);
X exit(1);
X }
X clrarray(p, n);
X return(p);
X}
X
X#ifdef BCOPY
X/* "slowish" routines when you don't have memcpy and friends
X */
Xbcopy(from, to, len)
Xregister char *from, *to;
Xregister int n; {
X while(n--)
X *to++ = *from++;
X}
Xbzero(array, len)
Xregister char *array;
Xregister int len; {
X while(n--)
X *array++ = '\0';
X}
X#endif
!BLOTTO
--
Chris Lewis, Phone: (416)-294-9253
UUCP: uunet!utai!lsuc!ecicrl!clewis
Moderator of the Ferret Mailing List (ferret-request at eci386)
Psroff mailing list (psroff-request at eci386)
More information about the Alt.sources
mailing list