v19i066: dvi - C++ DVI filter for HP LaserJets, Part03/03
Parag Patel
parag at hpsdeb.sde.hp.com
Wed May 15 04:23:26 AEST 1991
Submitted-by: Parag Patel <parag at hpsdeb.sde.hp.com>
Posting-number: Volume 19, Issue 66
Archive-name: dvi/part03
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 03 of dvi
# ============= pkfont.C ==============
if test -f 'pkfont.C' -a X"$1" != X"-c"; then
echo 'x - skipping pkfont.C (File already exists)'
else
echo 'x - extracting pkfont.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'pkfont.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: pkfont.C,v 1.21 91/02/22 15:58:17 hmgr Exp $";
X
// read font data from the METAFONT PK (packed font) files
//
// by Parag Patel
X
#include "defs.h"
X
X
// these are for "drawing" an image of a character in a font
const int WHITE = FALSE;
const int BLACK = TRUE;
X
X
// return a string containing the magnification sub-directory for the
// requested magnification
//
char *pkmagdir(Dirlist &dirlist, long mag)
{
X // look for the closest resolution value to the one desired
X int ent = -1;
X long diff = MAXLONG;
X
X for (int i = 0; i < dirlist.size(); i++)
X {
X long magval = dirlist[i].val;
X if (strchr(dirlist[i].name, '.') == NULL)
X {
X magval *= 1000;
X magval /= RESOLUTION;
X }
X
X long d = mag - magval;
X long newdiff = d < 0 ? -d : d; // absolute value
X if (newdiff < diff)
X {
X diff = newdiff;
X ent = i;
X }
X }
X debug(7, "PK dir ent=%s diff=%ld mag=%ld",
X ent < 0 ? "" : dirlist[ent].name, diff, mag);
X
X // we should be within 1/32 (~3%) of the desired mag value
X if (ent < 0 || diff > (mag >> 5))
X return "";
X
X // return the new value as a string, if there was one
X return dirlist[ent].name;
}
X
X
// setup a PK font file in memory
//
void setuppkfont(font &f, FILE *fp)
{
X // skip the comment
X int len = (unsigned)getuval(1, fp);
X while (len-- > 0)
X (void)getuval(1, fp);
X
X // get and verify that the design size is ok - the PK file stores
X // this value as a "fix_word" value while the DVI file keeps it as
X // a "scaled-point" value - also note that the "basename" pointer
X // is NULL only for the "dumpfont" main program
X
X long dsize = getsval(4, fp);
X debug(4, "PK designsize=%ld", dsize);
X if (f.basename != NULL && dsize >> 4 != f.designsize)
X if (dochecksum && dsize != 0 && f.designsize != 0)
X quit("Designsize in DVI and PK file %s does not match", f.path);
X else
X warn("Designsize in DVI and PK file %s does not match", f.path);
X
X // check the checksum
X long check = getuval(4, fp);
X debug(5, "PK checksum=%ld", check);
X if (f.basename != NULL && check != f.checksum)
X if (dochecksum && check != 0 && f.checksum != 0)
X quit("Checksums in DVI and PK file %s do not match", f.path);
X else
X warn("Checksums in DVI and PK file %s do not match", f.path);
X
X // get the horizontal and vertical pixels per point values
X f.hppp = getuval(4, fp);
X f.vppp = getuval(4, fp);
X
X debug(3, "mag=%ld hppp=%ld vppp=%ld", f.mag, f.hppp, f.vppp);
X
X f.minm = MAXLONG;
X f.maxm = -MAXLONG;
X f.minn = MAXLONG;
X f.maxn = -MAXLONG;
X
X // now initialize the info for each character in this font
X int op;
X while ((op = (int)getuval(1, fp)) != PKPOST)
X {
X switch (op)
X {
X // special opcodes - just ignore for now
X case PKXXX1:
X skipbytes(getuval(1, fp), fp);
X continue;
X case PKXXX2:
X skipbytes(getuval(2, fp), fp);
X continue;
X case PKXXX3:
X skipbytes(getuval(3, fp), fp);
X continue;
X case PKXXX4:
X skipbytes(getuval(4, fp), fp);
X continue;
X
X // special numeric opcode - also ignored
X case PKYYY:
X (void)getuval(4, fp);
X continue;
X
X case PKNOOP:
X continue;
X default:
X ;
X }
X
X // save the location of this character in the file
X long floc = ftell(fp) - 1;
X
X if (op > PKCHAR)
X quit("Illegal opcode %d in PK file %s", op, f.path);
X
X int flag = op;
X int size = (flag & 0x04) ? 2 : 1;
X int addtolen = flag & 0x03;
X if ((flag & 0x07) == 0x07)
X size = 4;
X
X long packetlen, charcode;
X
X switch (size)
X {
X Case 1:
X packetlen = getuval(1, fp) + (addtolen << 8);
X charcode = getuval(1, fp);
X
X Case 2:
X packetlen = getuval(2, fp) + (addtolen << 16);
X charcode = getuval(1, fp);
X
X Case 4:
X packetlen = getuval(4, fp);
X charcode = getuval(4, fp);
X
X Default:
X quit("?!?Eh? Internal error - size must be 1, 2, or 4.");
X }
X
X if (charcode >= MAXCHARS)
X quit("Char %ld too big in PF file %s", charcode, f.path);
X fontchar & g = f.chr[charcode];
X
X // save the location of the character data in the file
X g.floc = floc;
X
X double tfmwidth;
X long width, height, hoff, voff;
X
X switch (size)
X {
X Case 1:
X tfmwidth = Getuval(3, fp);
X g.dx = getuval(1, fp) << 16;
X g.dy = 0;
X width = getuval(1, fp);
X height = getuval(1, fp);
X hoff = getsval(1, fp);
X voff = getsval(1, fp);
X packetlen -= 8;
X
X Case 2:
X tfmwidth = Getuval(3, fp);
X g.dx = getuval(2, fp) << 16;
X g.dy = 0;
X width = getuval(2, fp);
X height = getuval(2, fp);
X hoff = getsval(2, fp);
X voff = getsval(2, fp);
X packetlen -= 13;
X
X Case 4:
X tfmwidth = Getsval(4, fp);
X g.dx = getuval(4, fp);
X g.dy = getuval(4, fp);
X width = getuval(4, fp);
X height = getuval(4, fp);
X hoff = getsval(4, fp);
X voff = getsval(4, fp);
X packetlen -= 28;
X
X Default:
X quit("?!?Eh? Internal error - size must be 1, 2, or 4.");
X }
X
X // calculate character min/max boundaries
X g.minm = -hoff;
X g.maxm = width - hoff;
X g.minn = voff - height + 1;
X g.maxn = voff;
X
X // set the size limits of the characters in this font
X if (g.minm < f.minm)
X f.minm = g.minm;
X if (g.maxm > f.maxm)
X f.maxm = g.maxm;
X if (g.minn < f.minn)
X f.minn = g.minn;
X if (g.maxn > f.maxn)
X f.maxn = g.maxn;
X
X // calculate the scaled points width from the pixel width
X g.width = (double)tfmwidth / (double)16 * (double)f.designsize /
X (double)65536L * (double)f.mag / 1000.0;
X
X // skip the character data and go to the next char
X if (fseek(fp, packetlen, SEEK_CUR) < 0)
X quit("Cannot seek past character data in %s", f.path);
X }
}
X
X
static long packetlen = 0;
X
X
// return a nybble (4-bit value) from a file - reset ourselves
// if we are called with a NULL file - return the upper nybble
// of a byte first and then the lower - as a side-effect, we decrement
// the packetlen count for every byte read from the file
//
static int getnyb(FILE *fp)
{
X static boolean nybsave = FALSE;
X static int nybdata = 0;
X
X packetlen--;
X if (fp == NULL || nybsave)
X {
X nybsave = FALSE;
X return nybdata & 0x0F;
X }
X nybsave = TRUE;
X nybdata = (unsigned)getuval(1, fp);
X return nybdata >> 4;
}
X
X
X
static int dynf = 0;
static int repeat = 0;
X
X
// get a packed run-count value from a file using getnyb() above -
// assumes that dynf above is initialized to a reasonable value
//
static int getpacked(FILE *fp)
{
X int i = getnyb(fp);
X if (i == 0)
X {
X if (packetlen <= 0)
X return 0;
X int j;
X do
X {
X j = getnyb(fp);
X i++;
X } while (j == 0);
X while (i-- > 0)
X j = (j << 4) + getnyb(fp);
X return j - 15 + ((13 - dynf) << 4) + dynf;
X }
X if (i <= dynf)
X return i;
X if (i < 14)
X return ((i - dynf - 1) << 4) + getnyb(fp) + dynf + 1;
X if (i == 14)
X repeat = getpacked(fp);
X else
X repeat = 1;
X return getpacked(fp);
}
X
X
X
// load the specified character "ch" from the PK file - we read this
// character's PK commands to build a bitmap of the character in memory
//
void getpkchar(font &f, fontchar &g, int ch)
{
X // go to the file where this character is defined
X if (fseek(f.fp, g.floc, SEEK_SET) < 0)
X quit("Cannot fseek to start of font in %s", f.path);
X FILE *fp = f.fp;
X
X // reset our get-nybble function
X (void)getnyb(NULL);
X
X int flag = (unsigned)getuval(1, fp);
X if (flag > PKCHAR)
X quit("Illegal flag value %d in PK file %s", flag, f.path);
X
X // set up globals for getpacked() above
X dynf = flag >> 4;
X
X int size = (flag & 0x04) ? 2 : 1;
X long addtolen = flag & 0x03;
X if ((flag & 0x07) == 0x07)
X size = 4;
X
X long charcode;
X
X switch (size)
X {
X Case 1:
X packetlen = getuval(1, fp) + (addtolen << 8);
X charcode = getuval(1, fp);
X
X Case 2:
X packetlen = getuval(2, fp) + (addtolen << 16);
X charcode = getuval(1, fp);
X
X Case 4:
X packetlen = getuval(4, fp);
X charcode = getuval(4, fp);
X
X Default:
X quit("?!?Eh? Internal error - size must be 1, 2, or 4");
X }
X
X if (charcode != ch)
X quit("?!?Eh? Internal error - expected charcode for %d here", ch);
X
X long dx, dy, tfmwidth, width, height, hoff, voff;
X
X switch (size)
X {
X Case 1:
X tfmwidth = getuval(3, fp);
X dx = getuval(1, fp) << 16;
X dy = 0;
X width = getuval(1, fp);
X height = getuval(1, fp);
X hoff = getsval(1, fp);
X voff = getsval(1, fp);
X packetlen -= 8;
X
X Case 2:
X tfmwidth = getuval(3, fp);
X dx = getuval(2, fp) << 16;
X dy = 0;
X width = getuval(2, fp);
X height = getuval(2, fp);
X hoff = getsval(2, fp);
X voff = getsval(2, fp);
X packetlen -= 13;
X
X Case 4:
X tfmwidth = getuval(4, fp);
X dx = getuval(4, fp);
X dy = getuval(4, fp);
X width = getuval(4, fp);
X height = getuval(4, fp);
X hoff = getsval(4, fp);
X voff = getsval(4, fp);
X packetlen -= 28;
X
X Default:
X quit("?!?Eh? Internal error - size must be 1, 2, or 4.");
X }
X {
X int len;
X const char *x = dev_char2dev(ch, len);
X debug(5, "char=%d(%s) minm=%ld maxm=%ld minn=%ld maxn=%ld",
X ch, x, g.minm, g.maxm, g.minn, g.maxn);
X debug(5, " dx=%ld dy=%ld dx/=%ld dy/=%ld width=%ld/%f height=%ld",
X dx, dy, dx >> 16, dy >> 16, width, g.width, height);
X debug(5, " hoff=%ld voff=%ld len=%ld flag=%d dyn_f=%d",
X hoff, voff, packetlen, flag, dynf);
X }
X
X if (dynf < 0 || dynf > 14)
X quit("?!?Eh? dyn_f value must be 0-14 inclusive - not %d", dynf);
X
X // initialize the character painting variables
X register long m = 0;
X register long n = height - 1;
X int p = (flag & 0x08) ? BLACK : WHITE;
X
X // clear the global fontbits for the bitmap
X for (long d = n; d >= 0; d--)
X fontbits[d]->clear();
X
X // paint the fontbits to build this character
X if (dynf < 14)
X {
X // packed data
X repeat = 0;
X packetlen <<= 1;
X while (packetlen > 0)
X {
X int count = getpacked(fp);
X while (count-- > 0)
X {
X if (p)
X *fontbits[n] += m;
X if (++m >= width)
X {
X long r = n--;
X n -= repeat;
X m = 0;
X for (; repeat > 0; repeat--)
X *fontbits[r - repeat] = *fontbits[r];
X repeat = 0;
X }
X }
X p = !p;
X }
X for (; repeat > 0; repeat--)
X *fontbits[n - repeat] = *fontbits[n];
X }
X else
X {
X // straight bit-map
X while (packetlen-- > 0)
X {
X int byte = (unsigned)getuval(1, fp);
X for (int mask = 0x0080; mask != 0; mask >>= 1)
X {
X if (byte & mask)
X *fontbits[n] += m;
X if (++m >= width)
X {
X n--;
X m = 0;
X }
X }
X }
X }
}
SHAR_EOF
chmod 0444 pkfont.C ||
echo 'restore of pkfont.C failed'
Wc_c="`wc -c < 'pkfont.C'`"
test 10380 -eq "$Wc_c" ||
echo 'pkfont.C: original size 10380, current size' "$Wc_c"
fi
# ============= bitvec.C ==============
if test -f 'bitvec.C' -a X"$1" != X"-c"; then
echo 'x - skipping bitvec.C (File already exists)'
else
echo 'x - extracting bitvec.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'bitvec.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: bitvec.C,v 1.5 91/02/22 15:58:31 hmgr Exp $";
X
// An array of bits
//
// By Parag Patel
X
#include <stdio.h>
#include "bitvec.h"
X
X
// the following are machine-dependant - change them if necessary
// sizeof long == 32 bits == 2**5 --> 5, therefore ...
const int NUM = 32;
const int SHIFT = 5;
const int MASK = 0x1F;
const unsigned long EMPTY = 0L;
X
X
// generic minimum function
inline long MIN(long i1, long i2)
{
X return i1 < i2 ? i1 : i2;
}
X
// this determines which particular "long" in the array has this element
inline long ELT(long e)
{
X return e >> SHIFT;
}
X
// this gets the bit position in a "long" for this vec element
inline unsigned long BIT(long e)
{
X return ((unsigned long)(1L << (e & MASK)));
}
X
// this adds an element to an array of longs
inline void ADD(unsigned long *elts, long e)
{
X elts[ELT(e)] |= BIT(e);
}
X
X
// return a new vec of elts - clear it
static unsigned long *newelts(long largest)
{
X register unsigned long *elts = new unsigned long[ELT(largest) + 1];
X
X for (register long i = ELT(largest); i >= 0; i--)
X elts[i] = EMPTY;
X return elts;
}
X
// bump the size of a vec
void Bitvec::bumpsize(long largest)
{
X if (largest <= num)
X return;
X
X // only re-allocate our array if we are out of ELTs
X if (ELT(largest) != ELT(num))
X {
X register unsigned long *ne = newelts(largest);
X for (register long i = ELT(num); i >= 0; i--)
X ne[i] = elts[i];
X delete elts;
X elts = ne;
X }
X num = largest;
}
X
// various constructors:
X
// make a new vec of the specified size
Bitvec::Bitvec(long size)
{
X if (size <= 1)
X size = 1;
X elts = newelts(num = size - 1);
}
X
// dup a vec
Bitvec::Bitvec(const Bitvec &s)
{
X elts = newelts(num = s.num);
X for (register long i = ELT(s.num); i >= 0; i--)
X elts[i] = s.elts[i];
}
X
// assign a vec to a vec - also a dup
Bitvec &Bitvec::operator=(const Bitvec &s)
{
X register long i, t;
X
X BUMPSIZE(s.num);
X for (i = t = ELT(s.num); i >= 0; i--)
X elts[i] = s.elts[i];
X for (i = ELT(num); i > t; i--)
X elts[i] = EMPTY;
X return *this;
}
X
X
// add an element to a vec
Bitvec &Bitvec::add(long elt)
{
X if (elt < 0)
X return *this;
X BUMPSIZE(elt);
X elts[ELT(elt)] |= BIT(elt);
X return *this;
}
X
// delete an element from a vec
Bitvec &Bitvec::remove(long elt)
{
X if (elt < 0)
X return *this;
X elts[ELT(elt)] &= ~BIT(elt);
X return *this;
}
X
// is vec same as s?
boolean Bitvec::operator==(const Bitvec &s) const
{
X register long i = MIN(num, s.num);
X
X for (i = ELT(i); i >= 0; i--)
X if (elts[i] != s.elts[i])
X return FALSE;
X if (num == s.num)
X return TRUE;
X
X register long t;
X if (num < s.num)
X {
X for (t = ELT(num), i = ELT(s.num); i > t; i--)
X if (s.elts[i])
X return FALSE;
X }
X else
X {
X for (t = ELT(s.num), i = ELT(num); i > t; i--)
X if (elts[i])
X return FALSE;
X }
X return TRUE;
}
X
X
// return the number of elements in the vec (cardinality)
long Bitvec::size() const
{
X register long n = 0;
X
X for (register long i = ELT(num); i >= 0; i--)
X for (register unsigned long m = 1; m; m <<= 1)
X if (elts[i] & m)
X n++;
X return n;
}
X
// clear the vec of all elements
void Bitvec::clear()
{
X for (register long i = ELT(num); i >= 0; i--)
X elts[i] = EMPTY;
}
SHAR_EOF
chmod 0444 bitvec.C ||
echo 'restore of bitvec.C failed'
Wc_c="`wc -c < 'bitvec.C'`"
test 3331 -eq "$Wc_c" ||
echo 'bitvec.C: original size 3331, current size' "$Wc_c"
fi
# ============= hp2684.h ==============
if test -f 'hp2684.h' -a X"$1" != X"-c"; then
echo 'x - skipping hp2684.h (File already exists)'
else
echo 'x - extracting hp2684.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hp2684.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: hp2684.h,v 1.10 91/02/22 15:58:37 hmgr Exp $
X
// HP2684 LaserJet 2000 device-specific definitions.
// The LaserJet 2000 Reference Manual should be consulted for more
// information on the various constants.
//
// by Parag Patel
X
X
class HP2684 : public HP33447
{
protected:
X HP2684(int maxf, int maxc, int maxpg, int maxld, int res,
X int ho, int vo, int fhmn, int fhmx, int fvmn,
X int fvmx, int fwd, int fhg, char *deffp) :
X HP33447(maxf, maxc, maxpg, maxld, res, ho, vo,
X fhmn, fhmx, fvmn, fvmx, fwd, fhg, deffp) { }
public:
X HP2684();
};
SHAR_EOF
chmod 0444 hp2684.h ||
echo 'restore of hp2684.h failed'
Wc_c="`wc -c < 'hp2684.h'`"
test 632 -eq "$Wc_c" ||
echo 'hp2684.h: original size 632, current size' "$Wc_c"
fi
# ============= hp33440.h ==============
if test -f 'hp33440.h' -a X"$1" != X"-c"; then
echo 'x - skipping hp33440.h (File already exists)'
else
echo 'x - extracting hp33440.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hp33440.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: hp33440.h,v 1.8 91/02/22 15:58:41 hmgr Exp $
X
// LaserJetII series device-specific definitions.
// The LaserJetII Reference Manual should be consulted for more
// information on the various constants.
//
// by Parag Patel
X
X
// LaserJetII
//
class HP33440 : public HP2686
{
protected:
X HP33440(int maxf, int maxc, int maxpg, int maxld, int res,
X int ho, int vo, int fhmn, int fhmx, int fvmn, int fvmx,
X int fwd, int fhg, char *deffp) :
X HP2686(maxf, maxc, maxpg, maxld, res, ho, vo,
X fhmn, fhmx, fvmn, fvmx, fwd, fhg, deffp) { }
public:
X HP33440();
};
X
X
// LaserJetIID - does double-sided but is otherwise identical to the II
//
class HP33447 : public HP33440
{
protected:
X HP33447(int maxf, int maxc, int maxpg, int maxld, int res,
X int ho, int vo, int fhmn, int fhmx, int fvmn,
X int fvmx, int fwd, int fhg, char *deffp);
public:
X HP33447();
X ~HP33447();
X void newpage(boolean odd, boolean first);
};
SHAR_EOF
chmod 0444 hp33440.h ||
echo 'restore of hp33440.h failed'
Wc_c="`wc -c < 'hp33440.h'`"
test 1015 -eq "$Wc_c" ||
echo 'hp33440.h: original size 1015, current size' "$Wc_c"
fi
# ============= hp2686.h ==============
if test -f 'hp2686.h' -a X"$1" != X"-c"; then
echo 'x - skipping hp2686.h (File already exists)'
else
echo 'x - extracting hp2686.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'hp2686.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: hp2686.h,v 1.13 91/02/22 15:58:47 hmgr Exp $
X
// HP2686 LaserJet+ device-specific definitions.
// The LaserJet+ Reference Manual should be consulted for more
// information on the various constants.
//
// by Parag Patel
X
X
class HP2686 : public Device
{
protected:
X HP2686(int maxf, int maxc, int maxpg, int maxld, int res,
X int ho, int vo, int fhmn, int fhmx, int fvmn, int fvmx,
X int fwd, int fhg, char *deffp);
X void downljchar(font &f, fontchar &g, int ch);
public:
X HP2686();
X ~HP2686();
X
X const char *char2dev(int ch, int &len);
X long sp2dev(double sp);
X double dev2sp(long pix);
X
X void newpage(boolean odd, boolean first);
X void downchar(font &f, fontchar &g, int ch);
X void bigchar(font &f, fontchar &g, int ch);
X void movehv(long h, long v);
X void moveh(long);
X void movev(long);
X void push();
X void pop();
X void delfont(font &);
X void newfont(font &);
X void usefont(font &);
X void rule(double v, double h);
};
X
#define HP2686_FPATH "/usr/lib/tex/fontbits/laser:/usr/lib/tex/fnt:/usr/local/tex/fontbits/laser"
X
// about 1 inch from both margins - tweaked until TeX test comes out right
// when printed to a LaserJet - lots of fun with unprintable regions!
#define HP2686_HOFFSET 245
#define HP2686_VOFFSET 300
SHAR_EOF
chmod 0444 hp2686.h ||
echo 'restore of hp2686.h failed'
Wc_c="`wc -c < 'hp2686.h'`"
test 1357 -eq "$Wc_c" ||
echo 'hp2686.h: original size 1357, current size' "$Wc_c"
fi
# ============= defs.h ==============
if test -f 'defs.h' -a X"$1" != X"-c"; then
echo 'x - skipping defs.h (File already exists)'
else
echo 'x - extracting defs.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'defs.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: defs.h,v 1.22 91/02/22 15:58:55 hmgr Exp $
X
// Header file for a C++ TeX DVI filter.
// Strangely enough, this file should be device-INdependent.
//
// by Parag Patel
X
X
// This program takes as input the DVI file generated by TeX or LaTeX
// and converts it to a device-specific format that is used to actually
// typeset (print) the document. The device-specific info should be in
// the files "dev.h" and "dev.c". The HP2686 LaserJet+ is currently
// supported, but others should be fairly easy to add, unless the code
// isn't as device-indenpendent as it was intended to be.
//
// The DVI file format is described in the book "TeX: The Program" by
// Donald E. Knuth (of course) pp. 234-243. This program also uses the
// GF (Generic Font) format files to determine what to download to the
// device/printer. This format is described in the book
// "METAFONT: The Program" by Donald E. Knuth pp. 484-489. Both these
// books should be used to determine exactly what the code is supposed
// to be doing. The various number formats are also described in
// these books.
X
X
// some standard include files
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#ifndef __ZTC__
# include <sys/param.h>
# include <unistd.h>
#endif
#if !defined(BSD) && !defined(__ZTC__)
# include <values.h>
#endif
X
#ifdef __ZTC__
X extern "C" int getopt(int, const char**, const char*);
# define NUMOPENFILES 7
#endif
X
#ifdef MSDOS
# define PATHSEP ';'
# define F_READ "rb"
#endif
#ifndef PATHSEP
# define PATHSEP ':'
#endif
X
#ifndef NUMOPENFILES
# define NUMOPENFILES 5
#endif
#ifndef MAXLONG
# define MAXLONG 0x7FFFFFFFL
#endif
#ifndef MAXPATHLEN
# define MAXPATHLEN 64
#endif
#ifndef SEEK_SET
# define SEEK_SET 0
# define SEEK_CUR 1
# define SEEK_END 2
#endif
#ifndef _NFILE
# define _NFILE 20
#endif
#ifndef F_READ
// for fopen(), because of POS-ICKS adding "rb" instead of "rt"
# define F_READ "r"
#endif
X
// handy macros for large switch statements
#define Case break;case
#define Default break;default
X
X
// DVI-file specific id and tail filler bytes
const int ID = 2;
const int FILLER = 223;
X
// DVI file opcodes - thoroughly described in "TeX: The Program"
enum opcodes
{
X SET0 = 0, // typeset range of characters
X SET127 = 127,
X
X SET1 = 128, // typeset char and move cursor
X SET2 = 129,
X SET3 = 130,
X SET4 = 131,
X SETRULE = 132, // typeset a rule & move cursor
X
X PUT1 = 133, // just typeset a character
X PUT2 = 134,
X PUT3 = 135,
X PUT4 = 136,
X PUTRULE = 137, // typeset rule
X
X NOOP = 138,
X
X BOP = 139, // Beginning Of Page
X EOP = 140, // End Of Page
X PUSH = 141, // push internal DVI stack
X POP = 142, // pop DVI stack
X
X RIGHT1 = 143, // move cursor right/left
X RIGHT2 = 144,
X RIGHT3 = 145,
X RIGHT4 = 146,
X
X W0 = 147, // move right/left using W DVI var
X W1 = 148,
X W2 = 149,
X W3 = 150,
X W4 = 151,
X
X X0 = 152, // move right/left using X var
X X1 = 153,
X X2 = 154,
X X3 = 155,
X X4 = 156,
X
X DOWN1 = 157, // move cursor down/up
X DOWN2 = 158,
X DOWN3 = 159,
X DOWN4 = 160,
X
X Y0 = 161, // move down/up using Y var
X Y1 = 162,
X Y2 = 163,
X Y3 = 164,
X Y4 = 165,
X
X Z0 = 166, // move down/up using Z var
X Z1 = 167,
X Z2 = 168,
X Z3 = 169,
X Z4 = 170,
X
X FONT0 = 171, // use a new font - range version
X FONT63 = 234,
X
X FNT1 = 235, // use a new font
X FNT2 = 236,
X FNT3 = 237,
X FNT4 = 238,
X
X XXX1 = 239, // special - user defined
X XXX2 = 240,
X XXX3 = 241,
X XXX4 = 242,
X
X FNTDEF1 = 243, // define a font
X FNTDEF2 = 244,
X FNTDEF3 = 245,
X FNTDEF4 = 246,
X
X PRE = 247, // preamble
X POST = 248, // start of postamble
X POSTPOST = 249, // end of postamble
};
X
X
// this describes which pages exist in the DVI file
struct pageinfo
{
X long page;
X long section;
X long loc;
};
X
// this describes which pages (or page ranges) that we wish to print
struct pagespec
{
X long page, endpage;
X long section, endsection;
};
X
X
// other include files for this program
#include "boolean.h"
#include "bitvec.h"
#include "darray.h"
#include "dev.h"
#include "font.h"
#include "dirs.h"
X
// all other misc externs are here to keep 'em together
#include "extern.h"
SHAR_EOF
chmod 0444 defs.h ||
echo 'restore of defs.h failed'
Wc_c="`wc -c < 'defs.h'`"
test 4214 -eq "$Wc_c" ||
echo 'defs.h: original size 4214, current size' "$Wc_c"
fi
# ============= extern.h ==============
if test -f 'extern.h' -a X"$1" != X"-c"; then
echo 'x - skipping extern.h (File already exists)'
else
echo 'x - extracting extern.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'extern.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: extern.h,v 1.24 91/02/22 15:59:02 hmgr Exp $
X
// externs for various LaserJet+ DVI filter functions
//
// by Parag Patel
X
// misc. dynamic array types
declare_array(Pageinfo, pageinfo);
declare_array(Pagespec, pagespec);
X
class fontptr
{
public:
X font *ptr;
X fontptr() { ptr = NULL; }
X operator font*() { return ptr; }
X font *operator->() { return ptr; }
X font *operator=(font *p) { return ptr = p; }
};
declare_array(Fontlist, fontptr);
X
// globals.C
extern char *fontpath;
extern char *dviinput;
extern int debuglevel;
extern boolean verbose;
extern boolean dochecksum;
extern char *devname;
extern boolean reverse;
extern boolean landscape;
extern boolean duplexv;
extern boolean duplexh;
extern boolean duparg;
extern long usermag;
extern font *currfont;
extern Fontlist fontlist;
extern Bitvec **fontbits;
extern double H, V, W, X, Y, Z;
extern void init_globals();
extern void fini_globals();
X
// util.C
extern void debug(int, char *, ...);
extern void mesg(char *, ...);
extern void warn(char *, ...);
extern void error(char *, ...);
extern void quit(char *, ...);
extern long getuval(int, FILE *);
extern long getsval(int, FILE *);
extern void skipbytes(long num, FILE *fp);
extern FILE *fopenp(char *path, char *file, char *type);
X
// stack.C
extern void pushdvi();
extern void popdvi();
extern void cleardvi();
X
// fonts.C
extern void clearfonts();
extern void definefont(FILE*, long, long);
extern void newfont(long);
extern void makecurrent(boolean force = FALSE);
extern void special(FILE*, long);
extern void typeset(long, boolean, double);
extern void typerule(FILE*, boolean, double);
X
// dirs.C
extern Pathlist pathlist;
extern void setupdirs(char *path);
X
// readfont.C
extern void setupfont(font &);
extern void downchar(int ch, boolean toomany);
extern void dumpbits(int);
X
// gffont.C
extern void setupgffont(font &f, FILE *fp);
extern void getgfchar(font &f, fontchar &g, int);
extern char *gfmagdir(Dirlist &, long mag);
X
// pkfont.C
extern void setuppkfont(font &f, FILE *fp);
extern void getpkchar(font &f, fontchar &g, int);
extern char *pkmagdir(Dirlist &, long mag);
X
// dvi.C
extern void dodvi(FILE *, Pagespec&);
X
X
// convienient inlines - these would otherwise would have to go elsewhere
X
inline char *strnew(size_t len) { return (char*)malloc(len + 1); }
inline void strfree(char *s) { if (s != NULL) free((void *)s); }
inline char *strdup(const char *s)
X { return s != NULL ? strcpy((char*)malloc(strlen(s) + 1), s) : NULL; }
inline boolean streq(const char *s1, const char *s2)
X { return (strcmp(s1, s2) == 0) ? TRUE: FALSE; }
X
inline double Getsval(int n, FILE *fp)
{
X return double(getsval(n, fp));
}
X
inline double Getuval(int n, FILE *fp)
{
X return double(getuval(n, fp));
}
X
inline void movedown(double m)
{
X V += m;
}
X
inline void moveright(double m)
{
X H += m;
}
SHAR_EOF
chmod 0444 extern.h ||
echo 'restore of extern.h failed'
Wc_c="`wc -c < 'extern.h'`"
test 2904 -eq "$Wc_c" ||
echo 'extern.h: original size 2904, current size' "$Wc_c"
fi
# ============= dirs.h ==============
if test -f 'dirs.h' -a X"$1" != X"-c"; then
echo 'x - skipping dirs.h (File already exists)'
else
echo 'x - extracting dirs.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dirs.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: dirs.h,v 1.6 91/02/22 15:59:05 hmgr Exp $
X
// for reading font directory names into memory for fast traversal
//
// by Parag Patel
X
#ifndef _D_I_R_S_
#define _D_I_R_S_
X
X
struct Dirent
{
X char *name;
X long val;
X
X Dirent();
};
declare_array(Dirlist, Dirent);
X
X
struct Pathent
{
X char *path;
X Dirlist dirs;
X
X Pathent();
X Pathent &operator=(Pathent &x);
};
declare_array(Pathlist, Pathent);
X
X
X
#endif /* _D_I_R_S_ */
SHAR_EOF
chmod 0444 dirs.h ||
echo 'restore of dirs.h failed'
Wc_c="`wc -c < 'dirs.h'`"
test 506 -eq "$Wc_c" ||
echo 'dirs.h: original size 506, current size' "$Wc_c"
fi
# ============= font.h ==============
if test -f 'font.h' -a X"$1" != X"-c"; then
echo 'x - skipping font.h (File already exists)'
else
echo 'x - extracting font.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'font.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: font.h,v 1.13 91/02/22 15:59:11 hmgr Exp $
X
// describe fonts
//
// by Parag Patel
X
X
// X and Y are cartesian coordinates
// sp == scaled points == points * 2^16
// si == scaled integer == num * 2^16
// spx == scaled pixels == pixels * 2^16
// pix == pixels (whatever they are for a device)
X
X
// This is what a character in a METAFONT file should look like.
//
class fontchar
{
public:
X boolean downloaded; // is char currently in printer?
X boolean charbig; // is char too big for printer?
X long dx; // X spx displacement for typesetting
X long dy; // Y spx delta
X double width; // sp width to move after typesetting
X long minm; // start X pix coord for char
X long maxm; // end X - these describe the box
X long minn; // start Y - that this character should
X long maxn; // end Y - fit within
X long floc; // file pointer to start of char data
};
X
X
// this describes a particular font that TeX wishes to use - it is
// information from the DVI file and the GF file
//
class font
{
public:
X int type; // GF or PK ID value
X long checksum; // in both DVI and font files
X long scaledsize; // scaled font size in sp
X long designsize; // design size in sp (DVI & font)
X long mag; // magnification calculated from above
X char *path; // path name to font file
X char *basename; // basename of above for messages
X boolean onpage; // is font on the current page?
X boolean toomany; // too many fonts on page - reload this one
X boolean downloaded; // is font currently downloaded?
X boolean setup; // is font setup in memory?
X long use; // use count - least recently used
X long num; // number of this font
X long hppp; // horizontal pixels per point (si)
X long vppp; // vertical pixels per point
X long minm; // smallest X in this font
X long maxm; // largest X - used to for gross char sizing
X long minn; // smallest Y - when allocating memory for
X long maxn; // largest Y - building bitmap images
X FILE *fp;
X fontchar *chr;
X
X font();
X ~font();
};
X
X
// current GF ID byte and FILLER byte values
const int GFID = 131;
const int GFILLER = 223;
X
// opcodes in a GF file
//
enum gfcodes
{
X PAINT0 = 0, // range of paint commands
X PAINT63 = 63,
X
X PAINT1 = 64, // paint a row of pixels
X PAINT2 = 65,
X PAINT3 = 66,
X
X BOC = 67, // Beginning Of a Character description
X BOC1 = 68,
X EOC = 69, // End Of Character
X
X SKIP0 = 70, // vertical skip
X SKIP1 = 71,
X SKIP2 = 72,
X SKIP3 = 73,
X
X NEWROW0 = 74, // another vertical skip (range)
X NEWROW164 = 238,
X
X FXXX1 = 239, // special (user definable)
X FXXX2 = 240,
X FXXX3 = 241,
X FXXX4 = 242,
X
X YYY = 243, // also special
X
X FNOOP = 244, // noop!
X
X CHARLOC = 245, // character locators
X CHARLOC0 = 246,
X
X FPRE = 247, // preamble
X FPOST = 248, // start of postamble
X FPOSTPOST = 249, // end of postamble
};
X
X
// current PK identification byte value
const int PKID = 89;
X
// PK font file opcodes & special values
enum pkcodes
{
X PKCHAR = 239,
X
X PKXXX1 = 240,
X PKXXX2 = 241,
X PKXXX3 = 242,
X PKXXX4 = 243,
X PKYYY = 244,
X PKPOST = 245,
X PKNOOP = 246,
X PKPRE = 247,
X
X PKREPEAT = 14,
X PKREPEAT1 = 15,
X PKRUNLARGE = 0,
X PKRUNBEGIN = 1,
X PKRUNEND = 13,
};
SHAR_EOF
chmod 0444 font.h ||
echo 'restore of font.h failed'
Wc_c="`wc -c < 'font.h'`"
test 3299 -eq "$Wc_c" ||
echo 'font.h: original size 3299, current size' "$Wc_c"
fi
# ============= dev.h ==============
if test -f 'dev.h' -a X"$1" != X"-c"; then
echo 'x - skipping dev.h (File already exists)'
else
echo 'x - extracting dev.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dev.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: dev.h,v 1.17 91/02/22 15:59:17 hmgr Exp $
X
// Base device class definition. Specific devices should derive a
// class from this base class, and overload every virtual function.
//
// by Parag Patel
X
X
class font;
class fontchar;
X
class Device
{
public:
X const int maxfonts;
X const int maxchars;
X const int maxonpage;
X const int maxloaded;
X const int resolution;
X const int hoff;
X const int voff;
X const int fhmin;
X const int fhmax;
X const int fvmin;
X const int fvmax;
X const int fwidth;
X const int fheight;
X char *deffontpath;
X
protected:
X // a Device may only be created by a derived class and is never
X // directly used
X Device(int maxf, int maxc, int maxpg, int maxld, int res,
X int ho, int vo, int fhmn, int fhmx, int fvmn, int fvmx,
X int fwd, int fhg, char *deffp);
X
public:
X virtual ~Device();
X
X //virtual void color(long red, long green, long blue);
X
X // the following are pure virtual functions and MUST be overridden
X // by a derived class since the are NOT defined
X //
X virtual const char *char2dev(int ch, int &len) = 0;
X virtual long sp2dev(double sp) = 0;
X virtual double dev2sp(long pix) = 0;
X virtual void newpage(boolean odd, boolean first) = 0;
X virtual void downchar(font & f, fontchar & g, int ch) = 0;
X virtual void bigchar(font & f, fontchar & g, int ch) = 0;
X virtual void movehv(long h, long v) = 0;
X virtual void moveh(long n) = 0;
X virtual void movev(long n) = 0;
X virtual void push() = 0;
X virtual void pop() = 0;
X virtual void delfont(font & f) = 0;
X virtual void newfont(font & f) = 0;
X virtual void usefont(font & f) = 0;
X virtual void rule(double v, double h) = 0;
};
X
X
// The following macros are for backward compatibility with the older
// code in this program. It was originally C code that was upgraded to
// C++. Since there may only be a single "device" per invocation,
// there's little need to change all the old code. Yet.
X
extern Device *device;
X
#define MAXFONTS device->maxfonts
#define MAXCHARS device->maxchars
X
#define MAXONPAGE device->maxonpage
#define MAXLOADED device->maxloaded
X
#define RESOLUTION device->resolution
X
#define HOFF device->hoff
#define VOFF device->voff
X
#define FHMIN device->fhmin
#define FHMAX device->fhmax
#define FVMIN device->fvmin
#define FVMAX device->fvmax
#define FWIDTH device->fwidth
#define FHEIGHT device->fheight
X
#define DEFFONTPATH device->deffontpath
X
#define dev_char2dev device->char2dev
#define dev_sp2dev device->sp2dev
#define dev_dev2sp device->dev2sp
#define dev_newpage device->newpage
#define dev_downchar device->downchar
#define dev_bigchar device->bigchar
#define dev_movehv device->movehv
#define dev_moveh device->moveh
#define dev_movev device->movev
#define dev_push device->push
#define dev_pop device->pop
#define dev_delfont device->delfont
#define dev_newfont device->newfont
#define dev_usefont device->usefont
#define dev_rule device->rule
#define dev_color device->color
SHAR_EOF
chmod 0444 dev.h ||
echo 'restore of dev.h failed'
Wc_c="`wc -c < 'dev.h'`"
test 3077 -eq "$Wc_c" ||
echo 'dev.h: original size 3077, current size' "$Wc_c"
fi
# ============= darray.h ==============
if test -f 'darray.h' -a X"$1" != X"-c"; then
echo 'x - skipping darray.h (File already exists)'
else
echo 'x - extracting darray.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'darray.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: darray.h,v 1.3 91/02/22 15:59:22 hmgr Exp $
X
// Handle simple dynamic arrays of arbitrary type and range.
// They are automatically grown to fit any array-like reference.
// by Parag Patel
X
#ifndef __DARRAY_H_
#define __DARRAY_H_
X
X
// this is used to create an ARRAY of a TYPE
#define declare_array(ARRAY, TYPE) \
class ARRAY \
{ \
X long len; \
X long max; \
X TYPE *arr; \
X TYPE &bumpsize(long); \
public: \
X ARRAY() { arr = 0; max = len = 0; } \
X ARRAY(long siz) \
X { arr = 0; max = len = 0; if (siz > 0) bumpsize(siz-1); } \
X ARRAY(const ARRAY &); \
X ~ARRAY() { delete[max] arr; } \
X ARRAY &operator=(const ARRAY &); \
X long size() const { return len; } \
X void reset(long l = 0) { bumpsize(l); len = l; } \
X TYPE &operator[](long e) \
X { if (e < len) return arr[e]; else return bumpsize(e); } \
};
X
// this implements an ARRAY of a TYPE
#define implement_array(ARRAY, TYPE) \
TYPE &ARRAY::bumpsize(long elt) \
{ \
X if (elt < 0) \
X elt = 0; \
X if (elt >= max) \
X { \
X long omax = max; \
X if (max <= 0) \
X max = 1; \
X TYPE *narr = new TYPE[max = elt + (max > 1024 ? 1024 : max)]; \
X for (long i = 0; i < len; i++) \
X narr[i] = arr[i]; \
X delete[omax] arr; \
X arr = narr; \
X } \
X if (elt >= len) \
X len = elt + 1; \
X return arr[elt]; \
} \
ARRAY &ARRAY::operator=(const ARRAY &a) \
{ \
X if (&a == this) \
X return *this; \
X if (a.len > len) \
X bumpsize(a.len); \
X len = a.len; \
X for (long i = 0; i < len; i++) \
X arr[i] = a.arr[i]; \
X return *this; \
} \
ARRAY::ARRAY(const ARRAY &t) \
{ \
X arr = 0; \
X max = len = 0; \
X *this = t; \
}
X
#endif /* __DARRAY_H_ */
SHAR_EOF
chmod 0444 darray.h ||
echo 'restore of darray.h failed'
Wc_c="`wc -c < 'darray.h'`"
test 1656 -eq "$Wc_c" ||
echo 'darray.h: original size 1656, current size' "$Wc_c"
fi
# ============= boolean.h ==============
if test -f 'boolean.h' -a X"$1" != X"-c"; then
echo 'x - skipping boolean.h (File already exists)'
else
echo 'x - extracting boolean.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'boolean.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: boolean.h,v 1.3 91/02/22 15:59:28 hmgr Exp $
X
#ifndef __BOOLEAN_H_
#define __BOOLEAN_H_
X
typedef int boolean;
const boolean FALSE = 0;
const boolean TRUE = 1;
X
#endif /* __BOOLEAN_H_ */
SHAR_EOF
chmod 0444 boolean.h ||
echo 'restore of boolean.h failed'
Wc_c="`wc -c < 'boolean.h'`"
test 258 -eq "$Wc_c" ||
echo 'boolean.h: original size 258, current size' "$Wc_c"
fi
# ============= bitvec.h ==============
if test -f 'bitvec.h' -a X"$1" != X"-c"; then
echo 'x - skipping bitvec.h (File already exists)'
else
echo 'x - extracting bitvec.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'bitvec.h' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
// $Header: bitvec.h,v 1.4 91/02/22 15:59:36 hmgr Exp $
X
#ifndef __BITVEC_H_
#define __BITVEC_H_
X
#include "boolean.h"
X
// BUG: machine dependent macros: sizeof (unsigned long) must == 32 bits
#define __B_V_BIT(n) ((unsigned long)(1L << (n & 0x1F)))
#define __B_V_ELT(n) (n >> 5)
X
// a set of longs (esp. enums) - also an array of bits
class Bitvec
{
X long num;
X unsigned long *elts;
X
X void bumpsize(long); // grow the Bitvec
X // inline for speed
X void BUMPSIZE(long largest) { if (num < largest) bumpsize(largest); }
X
public:
X Bitvec(long); // new size
X Bitvec(Bitvec const &); // new Bitvec
X Bitvec() { elts = new unsigned long; num = 0; elts[0] = 0L; }
X ~Bitvec() { delete elts; } // destructor
X
X Bitvec& operator=(Bitvec const &); // dup
X
X Bitvec& add(long); // add to
X Bitvec& remove(long); // delete from
X Bitvec& operator+=(long e) { return add(e); }
X Bitvec& operator-=(long e) { return remove(e); }
X
X long size() const; // number of elements in Bitvec
X boolean isin(long bit) const
X { return bit >= 0 && bit <= num &&
X (elts[__B_V_ELT(bit)] & __B_V_BIT(bit)); }
X void clear(); // clear the set
X
X long get(long elt) const
X { return (elt >= 0 && elt <= num &&
X (elts[__B_V_ELT(elt)] & __B_V_BIT(elt))) ? 1 : 0; }
X long operator[](long elt) const { return get(elt); }
X unsigned long *getelts() { return elts; }
X
X // equality testing:
X boolean operator==(Bitvec const &s) const;
X boolean operator!=(Bitvec const &s) const { return !(s == *this); }
};
X
#undef __B_V_ELT
#undef __B_V_BIT
X
#endif /* __BITVEC_H_ */
SHAR_EOF
chmod 0444 bitvec.h ||
echo 'restore of bitvec.h failed'
Wc_c="`wc -c < 'bitvec.h'`"
test 1665 -eq "$Wc_c" ||
echo 'bitvec.h: original size 1665, current size' "$Wc_c"
fi
# ============= ljdump.c ==============
if test -f 'ljdump.c' -a X"$1" != X"-c"; then
echo 'x - skipping ljdump.c (File already exists)'
else
echo 'x - extracting ljdump.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'ljdump.c' &&
/* Copyright (c) 1991 by Parag Patel. All Rights Reserved. */
static char rcsid[] = "$Header: ljdump.c,v 1.8 91/02/22 15:59:49 hmgr Exp $";
X
/*
X NOT written by me. The real author refuses to stick his name in
X here, but he can't stop me from adding this note! -- Parag
X
X BTW - This is C code - NOT C++!
X */
X
#include <stdio.h>
#include <ctype.h>
X
#define SAME(a,b) (strcmp(a,b)==0)
#define SEQ(s,c,x) (x[strlen(x)-1]==c && strncmp(s,x,strlen(s))==0)
X
int
getnum(cp)
char *cp;
{
X cp = &cp[strlen(cp)] - 2;
X while (isdigit(*cp))
X cp--;
X return atoi(cp + 1);
}
X
void
dump_data(nbytes)
int nbytes;
{
X int max = 32;
X int ch;
X
X printf("\t");
X while (nbytes-- > 0)
X {
X ch = getchar();
X if (max > 0)
X printf("%.2X", ch);
X
X if (max-- == 0)
X printf("->");
X }
X putchar('\n');
}
X
void
do_esc(seq)
char *seq;
{
X typedef char byte;
X typedef unsigned char ubyte;
X typedef short word;
X typedef unsigned short uword;
X struct
X {
X uword size;
X byte dummy0;
X byte is_eightbit;
X word dummy1;
X uword baseline;
X uword cell_width;
X uword cell_height;
X byte is_landscape;
X byte is_proportional;
X uword symbol_set;
X uword pitch;
X uword height;
X word dummy2;
X byte dummy3;
X byte is_italic;
X byte stroke_weight;
X ubyte typeface;
X } fontdesc;
X struct
X {
X word dummy0;
X word dummy1;
X byte is_landscape;
X byte dymmy2;
X word left_offset;
X word top_offset;
X uword width;
X uword height;
X word deltax;
X } chardesc;
X
X printf("^[%s", seq);
X if (SEQ(")s", 'W', seq))
X {
X fread(&fontdesc, sizeof fontdesc, 1, stdin);
X printf("\n\t");
X if (fontdesc.is_proportional)
X printf("proportional ");
X else
X printf("fixed ");
X if (fontdesc.is_landscape)
X printf("landscape ");
X else
X printf("portrait ");
X if (fontdesc.is_italic)
X printf("italic ");
X printf("%d-bit chars, symbol set: %d%c\n",
X fontdesc.is_eightbit + 7,
X fontdesc.symbol_set >> 5,
X (fontdesc.symbol_set & 0x1F) + 64);
X printf("\tbaseline: %d dots\n", fontdesc.baseline);
X printf("\tcell height: %d dots width: %d dots\n",
X fontdesc.cell_height, fontdesc.cell_width);
X printf("\tpitch: %.1f dots\n", fontdesc.pitch / 4.0);
X printf("\theight: %.1f dots\n", fontdesc.height / 4.0);
X printf("\tstroke weight: %d, typeface: %d\n",
X fontdesc.stroke_weight, fontdesc.typeface);
X }
X else if (SEQ("(s", 'W', seq))
X {
X fread(&chardesc, sizeof chardesc, 1, stdin);
X if (chardesc.is_landscape)
X printf("\n\tlandscape");
X printf("\n\ttop offset: %d dots, left offset: %d dots\n",
X chardesc.top_offset, chardesc.left_offset);
X printf("\theight: %d dots, width: %d dots\n",
X chardesc.height, chardesc.width);
X printf("\tdelta X: %.1f dots\n", chardesc.deltax / 4.0);
X dump_data(getnum(seq) - sizeof chardesc);
X }
X else if (SEQ("*b", 'W', seq))
X {
X dump_data(getnum(seq));
X }
X else if (SEQ("*c", 'E', seq) && isprint(getnum(seq)))
X printf(" ('%c')\n", getnum(seq));
X else
X putchar('\n');
}
X
main()
{
X int ch;
X char *cp;
X char seq[100];
X
X while ((ch = getchar()) != EOF)
X {
X switch (ch)
X {
X case '\033':
X for (cp = seq; !isupper((ch = getchar())); *cp++ = ch)
X ;
X *cp++ = ch;
X *cp = '\0';
X do_esc(seq);
X break;
X default:
X printf("'%c' (%d) (0x%X) (0%o)\n", ch, ch, ch, ch);
X break;
X }
X }
X
X exit(0);
}
SHAR_EOF
chmod 0444 ljdump.c ||
echo 'restore of ljdump.c failed'
Wc_c="`wc -c < 'ljdump.c'`"
test 3296 -eq "$Wc_c" ||
echo 'ljdump.c: original size 3296, current size' "$Wc_c"
fi
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list