v19i065: dvi - C++ DVI filter for HP LaserJets, Part02/03
Parag Patel
parag at hpsdeb.sde.hp.com
Wed May 15 04:23:08 AEST 1991
Submitted-by: Parag Patel <parag at hpsdeb.sde.hp.com>
Posting-number: Volume 19, Issue 65
Archive-name: dvi/part02
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 02 of dvi
# ============= stack.C ==============
if test -f 'stack.C' -a X"$1" != X"-c"; then
echo 'x - skipping stack.C (File already exists)'
else
echo 'x - extracting stack.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'stack.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: stack.C,v 1.7 91/02/22 15:57:07 hmgr Exp $";
X
// manipulate a DVI stack
//
// by Parag Patel
X
#include "defs.h"
X
X
// a stack representation
struct stkrep
{
X double h, v, w, x, y, z;
};
X
declare_array(Stack, stkrep);
implement_array(Stack, stkrep);
X
static int top = 0; // top of the stack;
static Stack sp(50); // the DVI stack itself
X
X
// save current DVI/TeX variable values
//
void pushdvi()
{
X sp[top].h = H;
X sp[top].v = V;
X sp[top].w = W;
X sp[top].x = X;
X sp[top].y = Y;
X sp[top].z = Z;
X top++;
}
X
X
// restore current DVI/TeX variable values
//
void popdvi()
{
X if (top <= 0)
X quit("Stack underflow");
X top--;
X H = sp[top].h;
X V = sp[top].v;
X W = sp[top].w;
X X = sp[top].x;
X Y = sp[top].y;
X Z = sp[top].z;
}
X
X
// clear the stack and dvi vars
//
void cleardvi()
{
X H = V = W = X = Y = Z = 0.0;
X top = 0;
}
SHAR_EOF
chmod 0444 stack.C ||
echo 'restore of stack.C failed'
Wc_c="`wc -c < 'stack.C'`"
test 970 -eq "$Wc_c" ||
echo 'stack.C: original size 970, current size' "$Wc_c"
fi
# ============= dirs.C ==============
if test -f 'dirs.C' -a X"$1" != X"-c"; then
echo 'x - skipping dirs.C (File already exists)'
else
echo 'x - extracting dirs.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dirs.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: dirs.C,v 1.10 91/02/22 15:57:16 hmgr Exp $";
X
// read font directory names into memory for fast traversal
//
// by Parag Patel
X
#include "defs.h"
#include "dirs.h"
#ifdef __ZTC__
#include <dos.h>
#define d_name name
#else
#ifdef BSD
#include <sys/dir.h>
#else
#include <ndir.h>
#endif
#endif
X
X
implement_array(Dirlist, Dirent);
implement_array(Pathlist, Pathent);
X
X
Pathlist pathlist;
X
X
Dirent::Dirent()
{
X name = NULL;
X val = 0;
}
X
Pathent::Pathent()
{
X path = NULL;
}
X
Pathent &Pathent::operator=(Pathent &x)
{
X path = x.path;
X dirs = x.dirs;
X return *this;
}
X
X
void setupdirs(char *path)
{
X path = strdup(path);
X char *save = path;
X
X pathlist.reset();
X
X debug(3, "Setup dirpaths = %s", path);
X while (path != NULL && *path != '\0')
X {
X char *dirpath = path;
X while (*path != PATHSEP && *path != '\0')
X path++;
X if (*path != '\0')
X *path++ = '\0';
X debug(4, " DIR = %s", dirpath);
X
#ifndef __ZTC__
X DIR *dir = opendir(dirpath);
X if (dir == NULL)
X {
X warn("Cannot opendir directory \"%s\" for scanning", dirpath);
X continue;
X }
#endif
X
X Pathent & path = pathlist[pathlist.size()];
X path.path = strdup(dirpath);
X path.dirs.reset();
X
#ifdef __ZTC__
X char dos_dirpath[64];
X (void)strcpy(dos_dirpath, dirpath);
X (void)strcat(dos_dirpath, "/*.*");
X for (FIND *ent = findfirst(dos_dirpath, FA_DIREC); ent != NULL;
X ent = findnext())
#else
X for (direct * ent = readdir(dir); ent != NULL; ent = readdir(dir))
#endif
X {
X char *s = strchr(ent->d_name, '.');
X int magent;
X
X if (s != NULL)
X {
X // if there is a dot in the name, it may be the newer
X // magnification value naming conventions: "1.000"
X *s = '\0';
X magent = atoi(ent->d_name) * 1000 + atoi(s + 1);
X *s = '.';
X }
X else
X // older resolution naming convention: "300", "1000"
X magent = atoi(ent->d_name);
X
X if (magent <= 0)
X continue;
X
X Dirent & d = path.dirs[path.dirs.size()];
X d.name = strdup(ent->d_name);
X d.val = magent;
X debug(5, " name=%s val=%d", d.name, d.val);
X }
X
#ifndef __ZTC__
X closedir(dir);
#endif
X }
X strfree(save);
}
SHAR_EOF
chmod 0444 dirs.C ||
echo 'restore of dirs.C failed'
Wc_c="`wc -c < 'dirs.C'`"
test 2199 -eq "$Wc_c" ||
echo 'dirs.C: original size 2199, current size' "$Wc_c"
fi
# ============= dvi.C ==============
if test -f 'dvi.C' -a X"$1" != X"-c"; then
echo 'x - skipping dvi.C (File already exists)'
else
echo 'x - extracting dvi.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'dvi.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: dvi.C,v 1.24 91/02/22 15:57:33 hmgr Exp $";
X
// dvi scanning routines
//
// by Parag Patel
X
#include "defs.h"
X
X
static long mag = 1000;
static double magval = 1.0;
X
X
// print the specified page from the file "fp" at the specified
// magnification - this is called for any page in the DVI file provided
// that the "fp" has been set to the start of a page in the DVI file -
// thus pages may be printed in any random order
//
static void dopage(FILE *fp, long page)
{
X // clear and initialize the global state for a new page
X cleardvi();
X clearfonts();
X
X // if this is not the first page, then eject the previous
X // page from the printer
X //
X static first = TRUE;
X dev_newpage((page & 0x01) || page == 0, first);
X first = FALSE;
X
X // now go through the DVI file executing opcodes...
X register int opcode;
X while ((opcode = (int)getuval(1, fp)) != EOP)
X {
X debug(7, " H=%f V=%f W=%f X=%f Y=%f Z=%f", H, V, W, X, Y, Z);
X debug(6, "opcode = %d", opcode);
X
X if (opcode >= SET0 && opcode <= SET127)
X {
X // typeset (print) a character
X typeset(opcode, TRUE, magval);
X continue;
X }
X if (opcode >= FONT0 && opcode <= FONT63)
X {
X // switch to a new font
X newfont(opcode - FONT0);
X continue;
X }
X switch (opcode)
X {
X // print (typeset) a character and move the cursor
X Case SET1:
X typeset(getuval(1, fp), TRUE, magval);
X Case SET2:
X typeset(getuval(2, fp), TRUE, magval);
X Case SET3:
X typeset(getuval(3, fp), TRUE, magval);
X Case SET4:
X typeset(getsval(4, fp), TRUE, magval);
X
X // just typeset a character
X Case PUT1:
X typeset(getuval(1, fp), FALSE, magval);
X Case PUT2:
X typeset(getuval(2, fp), FALSE, magval);
X Case PUT3:
X typeset(getuval(3, fp), FALSE, magval);
X Case PUT4:
X typeset(getsval(4, fp), FALSE, magval);
X
X // print a rule
X Case SETRULE:
X typerule(fp, TRUE, magval);
X Case PUTRULE:
X typerule(fp, FALSE, magval);
X
X Case NOOP:
X
X Case PUSH:
X pushdvi();
X Case POP:
X popdvi();
X
X // horizontal moves (negative == move left)
X Case RIGHT1:
X moveright(Getsval(1, fp) * magval);
X Case RIGHT2:
X moveright(Getsval(2, fp) * magval);
X Case RIGHT3:
X moveright(Getsval(3, fp) * magval);
X Case RIGHT4:
X moveright(Getsval(4, fp) * magval);
X
X // move horizontal based on the var W
X Case W0:
X moveright(W);
X Case W1:
X moveright(W = Getsval(1, fp) * magval);
X Case W2:
X moveright(W = Getsval(2, fp) * magval);
X Case W3:
X moveright(W = Getsval(3, fp) * magval);
X Case W4:
X moveright(W = Getsval(4, fp) * magval);
X
X // move horizontal based on the var X
X Case X0:
X moveright(X);
X Case X1:
X moveright(X = Getsval(1, fp) * magval);
X Case X2:
X moveright(X = Getsval(2, fp) * magval);
X Case X3:
X moveright(X = Getsval(3, fp) * magval);
X Case X4:
X moveright(X = Getsval(4, fp) * magval);
X
X // move vertically (negative == towards top of page)
X Case DOWN1:
X movedown(Getsval(1, fp) * magval);
X Case DOWN2:
X movedown(Getsval(2, fp) * magval);
X Case DOWN3:
X movedown(Getsval(3, fp) * magval);
X Case DOWN4:
X movedown(Getsval(4, fp) * magval);
X
X // move vertically based on the var Y
X Case Y0:
X movedown(Y);
X Case Y1:
X movedown(Y = Getsval(1, fp) * magval);
X Case Y2:
X movedown(Y = Getsval(2, fp) * magval);
X Case Y3:
X movedown(Y = Getsval(3, fp) * magval);
X Case Y4:
X movedown(Y = Getsval(4, fp) * magval);
X
X // move vertically based on the var Z
X Case Z0:
X movedown(Z);
X Case Z1:
X movedown(Z = Getsval(1, fp) * magval);
X Case Z2:
X movedown(Z = Getsval(2, fp) * magval);
X Case Z3:
X movedown(Z = Getsval(3, fp) * magval);
X Case Z4:
X movedown(Z = Getsval(4, fp) * magval);
X
X // change current font
X Case FNT1:
X newfont(getuval(1, fp));
X Case FNT2:
X newfont(getuval(2, fp));
X Case FNT3:
X newfont(getuval(3, fp));
X Case FNT4:
X newfont(getsval(4, fp));
X
X // special - used definable
X Case XXX1:
X special(fp, getuval(1, fp));
X Case XXX2:
X special(fp, getuval(2, fp));
X Case XXX3:
X special(fp, getuval(3, fp));
X Case XXX4:
X special(fp, getsval(4, fp));
X
X // define a font - note that this will be a redefinition
X Case FNTDEF1:
X definefont(fp, getuval(1, fp), mag);
X Case FNTDEF2:
X definefont(fp, getuval(2, fp), mag);
X Case FNTDEF3:
X definefont(fp, getuval(3, fp), mag);
X Case FNTDEF4:
X definefont(fp, getsval(4, fp), mag);
X
X Default:
X quit("Unexpected opcode %d", opcode);
X }
X }
}
X
X
// read the DVI file and create a list with pointers to every
// page in the file - also calculate a section number for each page
//
static void loadpages(FILE *fp, long pageloc, long numpages,
X long §ions, Pageinfo &pages)
{
X long loc = pageloc;
X long lastpage = MAXLONG;
X long i;
X
X sections = 1;
X
X // search backwards through the DVI file
X for (i = numpages - 1; loc >= 0 && i >= 0; i--)
X {
X (void)fseek(fp, loc, SEEK_SET);
X if (getuval(1, fp) != BOP)
X quit("Expected BOP");
X
X // get the values of the internal TeX variables
X // - the first is a page number (c[0])
X long c[10];
X for (int j = 0; j < 10; j++)
X c[j] = getsval(4, fp);
X loc = getsval(4, fp); // location of previous page in file
X
X // new section if we see a page larger than the previous one
X if (c[0] >= lastpage)
X sections++;
X lastpage = c[0];
X
X // save the "real" page number and the offset in the file
X pages[i].page = c[0];
X pages[i].section = sections;
X pages[i].loc = ftell(fp);
X }
X
X // now change the section numbers to be in the proper order
X for (i = 0; i < numpages; i++)
X pages[i].section = sections - pages[i].section + 1;
}
X
X
// dump only the specified pages from the DVI file
//
static void dumppages(FILE *fp, Pagespec &pages,
X Pageinfo &allpages, long sections)
{
X long numpages = allpages.size();
X
X for (int i = 0; i < pages.size(); i++)
X {
X // get the page spec entry in normal or reverse order
X long pent = reverse ? pages.size() - i - 1 : i;
X
X // if the end is not specified, take the current maximum
X long endsect = pages[pent].endsection == MAXLONG ? sections
X : pages[pent].endsection;
X long endpage = pages[pent].endpage == MAXLONG ? numpages
X : pages[pent].endpage;
X
X // print only the last section? make sure we go through loop once
X long startsect = pages[pent].section;
X if (startsect == MAXLONG)
X startsect = endsect;
X
X for (long s = startsect; s <= endsect; s++)
X {
X long snum = reverse ? endsect - s + startsect : s;
X for (long p = pages[pent].page; p <= endpage; p++)
X {
X long pnum = reverse ? endpage - p + pages[pent].page : p;
X
X // look for this page/section in the list of allpages
X // - if section == MAXLONG - 1, then use the last section
X long ent;
X for (ent = numpages - 1; ent >= 0; ent--)
X if (allpages[ent].page == pnum
X && allpages[ent].section == snum)
X break;
X
X if (ent < 0)
X {
X // print an error only if the user explicitly specified
X // a page that does not exist - do not print an error
X // if we are going through to the end
X if (pages[pent].section == MAXLONG
X || pages[pent].endsection <= pages[pent].section)
X if (pages[pent].endpage == MAXLONG
X || pages[pent].endpage < pages[pent].page)
X if (pages[pent].section <= sections)
X continue;
X
X error("No page/section %ld.%ld in DVI file", pnum, snum);
X continue;
X }
X
X // seek to that page and spit it out
X (void)fseek(fp, allpages[ent].loc, SEEK_SET);
X mesg(" [%ld.%ld", allpages[ent].page, allpages[ent].section);
X debug(1, "Page: %ld.%ld (%ld)", allpages[ent].page,
X allpages[ent].section, ent + 1);
X dopage(fp, allpages[ent].page);
X mesg("]");
X }
X }
X }
}
X
X
// dump all the pages in the DVI file in either forward or reverse order
//
static void dumpall(FILE *fp, Pageinfo &allpages)
{
X long numpages = allpages.size();
X for (int i = 0; i < numpages; i++)
X {
X long p = reverse ? numpages - i - 1 : i;
X (void)fseek(fp, allpages[p].loc, SEEK_SET);
X mesg(" [%ld.%ld", allpages[p].page, allpages[p].section);
X debug(1, "Page: %ld.%ld (%ld)", allpages[p].page,
X allpages[p].section, p + 1);
X dopage(fp, allpages[p].page);
X mesg("]");
X }
}
X
X
// process the DVI file "fp" - verify the file, setup the fonts, then
// print pages in the file either backwards or forwards - print only
// that "pages" specified, or everything if none were specified
//
void dodvi(FILE *fp, Pagespec &pages)
{
X // verify the preamble and id value
X if (getuval(1, fp) != PRE)
X quit("Not a DVI file");
X long version = getuval(1, fp);
X if (version != ID)
X {
X debug(7, "DVI file version = %ld instead of %d", version, ID);
X quit("Incorrect DVI file version");
X }
X
X // if we cannot seek, then we cannot do anything
X if (fseek(fp, 0, SEEK_END) != 0)
X quit("Cannot seek to end of DVI file");
X
X long floc = ftell(fp);
X debug(2, "DVI file len = %ld", floc);
X
X // now look for the real end of the DVI file (after the POSTPOST)
X register int opcode = FILLER;
X while (opcode == FILLER && floc > 0)
X {
X (void)fseek(fp, --floc, SEEK_SET);
X opcode = (int)getuval(1, fp);
X }
X if (opcode != ID)
X {
X debug(7, "DVI file version = %d instead of %d", opcode, ID);
X quit("Incorrect DVI file version");
X }
X
X // get the pointer to the start of the postamble
X (void)fseek(fp, floc -= 4, SEEK_SET);
X long postloc = getuval(4, fp);
X (void)fseek(fp, postloc, SEEK_SET);
X
X // verify that we are where we think we are
X if (getuval(1, fp) != POST)
X quit("Expected POST");
X
X // pointer to the last page in the DVI file
X long pageloc = getsval(4, fp);
X
X // read in the other values in the postamble
X double numerator = Getsval(4, fp);
X if (numerator <= 0)
X quit("Illegal numerator");
X
X double denominator = Getsval(4, fp);
X if (denominator <= 0)
X quit("Illegal denominator");
X
X mag = getsval(4, fp);
X if (usermag > 0)
X mag = usermag;
X magval = (double)mag;
X if (mag <= 0)
X quit("Illegal magnification");
X magval *= numerator / denominator / 25400000.0 * 473628672.0 / 1000.0;
X debug(3, "num=%f denom=%f mag=%ld/%f", numerator, denominator,
X mag, magval);
X
X // worst-case page sizes - we ignore these for now
X long tallest = getsval(4, fp);
X long widest = getsval(4, fp);
X long maxdepth = getsval(2, fp);
X long numpages = getuval(2, fp);
X debug(3, "tallest=%ld widest=%ld maxdepth=%ld", tallest, widest, maxdepth);
X debug(1, "numpages=%ld", numpages);
X
X // scan the opcodes in the rest of the postamble - only font
X // definitions and specials are allowed here
X while ((opcode = (int)getuval(1, fp)) != POSTPOST)
X switch (opcode)
X {
X Case FNTDEF1:
X definefont(fp, getuval(1, fp), mag);
X Case FNTDEF2:
X definefont(fp, getuval(2, fp), mag);
X Case FNTDEF3:
X definefont(fp, getuval(3, fp), mag);
X Case FNTDEF4:
X definefont(fp, getsval(4, fp), mag);
X
X Case XXX1:
X special(fp, getuval(1, fp));
X Case XXX2:
X special(fp, getuval(2, fp));
X Case XXX3:
X special(fp, getuval(3, fp));
X Case XXX4:
X special(fp, getsval(4, fp));
X
X Case NOOP:
X
X Default:
X quit("Illegal opcode = %d in font definitions", opcode);
X }
X
X // initialize the page pointer table
X Pageinfo allpages(numpages);
X long sections;
X loadpages(fp, pageloc, numpages, sections, allpages);
X
X // process the pages as specified
X if (pages.size() < 1)
X dumpall(fp, allpages);
X else
X dumppages(fp, pages, allpages, sections);
X
X mesg(NULL);
}
SHAR_EOF
chmod 0444 dvi.C ||
echo 'restore of dvi.C failed'
Wc_c="`wc -c < 'dvi.C'`"
test 11617 -eq "$Wc_c" ||
echo 'dvi.C: original size 11617, current size' "$Wc_c"
fi
# ============= font.C ==============
if test -f 'font.C' -a X"$1" != X"-c"; then
echo 'x - skipping font.C (File already exists)'
else
echo 'x - extracting font.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'font.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: font.C,v 1.42 91/04/02 17:59:01 hmgr Exp $";
X
// font manipulation and basic typesetting functions
//
// by Parag Patel
X
#include "defs.h"
X
X
// local globals
static int fontsonpage; // # of fonts on current page
static long devv; // current device Vertical coord
static long devh; // Horizontal coord (both in pixels)
static font *devfont; // current font in device
X
X
font::font()
{
X chr = new fontchar[MAXCHARS];
X // this initialization is redundant, but safer
X fp = NULL;
X use = 0;
X path = basename = NULL;
X onpage = toomany = downloaded = setup = NULL;
}
X
font::~font()
{
X if (fp != NULL)
X fclose(fp);
X delete[MAXCHARS] chr;
}
X
// return the fontlist location for the font number specified
// - returns one more than the current size if there is no such font
static long getfontloc(long fnum)
{
X for (long f = 0; f < fontlist.size(); f++)
X if (fontlist[f] != NULL && fontlist[f]->num == fnum)
X break;
X return f;
}
X
// clear font info for a new page - there are currently no fonts on
// this page - reset the device coordinates to "unknown" - there is no
// current font selected, nor a current font in the device
//
void clearfonts()
{
X for (int i = 0; i < fontlist.size(); i++)
X if (fontlist[i] != NULL)
X fontlist[i]->toomany = fontlist[i]->onpage = FALSE;
X fontsonpage = 0;
X devh = devv = -MAXLONG;
X currfont = devfont = NULL;
}
X
X
static void setupbits(font &f)
{
X static long minm = MAXLONG;
X static long maxm = -MAXLONG;
X static long minn = MAXLONG;
X static long maxn = -MAXLONG;
X
X if (f.minm >= minm && f.maxm <= maxm
X && f.minn >= minn && f.maxn <= maxn)
X return;
X
X if (fontbits != NULL)
X {
X for (long i = maxn - minn; i >= 0; i--)
X delete fontbits[i];
X delete fontbits;
X }
X
X if (f.maxm > maxm)
X maxm = f.maxm + 10;
X if (f.minm < minm)
X minm = f.minm - 10;
X if (f.maxn > maxn)
X maxn = f.maxn + 10;
X if (f.minn < minn)
X minn = f.minn - 10;
X
X debug(4, "newbits maxm=%ld minm=%ld maxn=%ld minn=%ld",
X maxm, minm, maxn, minn);
X
X // allocate the memory that we will need
X fontbits = new Bitvec *[maxn - minn + 2];
X for (long i = maxn - minn; i >= 0; i--)
X fontbits[i] = new Bitvec(maxm - minm + 2);
}
X
X
// define a font "fnum" from the file "fp" at the magnification "mag"
// - "fp" is a pointer into a DVI file right after the FNTDEF byte
// - this function will be called twice for each font - once in the
// postamble and once just before it is used (if it is used)
//
void definefont(FILE *fp, long fnum, long mag)
{
X // find the font with this number in our fontlist
X long floc = getfontloc(fnum);
X
X // if already loaded, then we are not in the postamble anymore
X boolean loaded = (fontlist[floc] != NULL);
X
X debug(2, "fontnum = %ld(%ld)%s", fnum, floc, loaded ? " loaded" : "");
X
X // allocate space for this font, if necessary
X if (!loaded)
X fontlist[floc] = new font;
X
X font &f = *fontlist[floc].ptr;
X
X if (loaded)
X {
X // ignore the values in the file - we already have them
X (void)getsval(4, fp);
X (void)getsval(4, fp);
X (void)getsval(4, fp);
X skipbytes(getuval(1, fp) + getuval(1, fp), fp);
X return;
X }
X
X // initialize the font and start reading the values out of the file
X f.fp = NULL;
X f.use = 0;
X f.num = fnum;
X f.checksum = getsval(4, fp);
X f.scaledsize = getsval(4, fp);
X f.designsize = getsval(4, fp);
X debug(3, "checksum=%ld scaled=%ld design=%ld",
X f.checksum, f.scaledsize, f.designsize);
X
X f.mag = (long)((double)mag * (double)f.scaledsize /
X (double)f.designsize + 0.5);
X
X // get the name of the font file - if the library name length
X // (liblen) is 0, then use the default library directory instead
X
X int liblen = (int)getuval(1, fp);
X int namelen = (int)getuval(1, fp);
X
X f.path = NULL;
X f.basename = new char[namelen + 1];
X int i;
X
X // read the optional font directory name from the DVI file
X if (liblen != 0)
X {
X // just use what the DVI file has
X char *s = f.path = new char[liblen + 1];
X for (i = 0; i < liblen; i++)
X *s++ = (unsigned char)getuval(1, fp);
X *s = '\0';
X }
X
X // get the name of the font file to load
X char *s = f.basename;
X for (i = 0; i < namelen; i++)
X *s++ = (unsigned char)getuval(1, fp);
X *s = '\0';
X debug(4, "libname=%s basename=%s",
X f.path == NULL ? "" : f.path, f.basename);
X
X // just defined - not yet downloaded - not setup
X f.setup = f.downloaded = f.onpage = f.toomany = FALSE;
X
X // no characters are downloaded either
X for (i = 0; i < MAXCHARS; i++)
X f.chr[i].downloaded = f.chr[i].charbig = FALSE;
}
X
X
// change to a new font "fnum" - this is the FNT DVI command
//
void newfont(long fnum)
{
X long f = getfontloc(fnum);
X debug(5, "Change to font %ld(%ld)", fnum, f);
X
X currfont = fontlist[f];
X if (currfont == NULL)
X quit("Font %ld(%ld) has not been defined yet", fnum, f);
}
X
X
// move the device's cursor to the current H and V values
//
void makecurrent(boolean force)
{
X long h = dev_sp2dev(H);
X long v = dev_sp2dev(V);
X
X // use the most efficient move that we can
X if (force || (devh != h && devv != v))
X dev_movehv(h, v);
X else if (devh != h)
X dev_moveh(h);
X else if (devv != v)
X dev_movev(v);
X
X debug(8, "lastH=%ld lastV=%ld H=%ld V=%ld", devh, devv, h, v);
X
X // update the current cursor values
X devh = h;
X devv = v;
}
X
X
static void dumpescape(const char *s, long len)
{
X for (long i = 0; i < len; s++, i++)
X {
X if (*s != '\\' && *s != '`')
X {
X putchar(*s);
X continue;
X }
X s++;
X i++;
X if (i >= len)
X break;
X
X if (isdigit(*s))
X {
X int chr = *s - '0';
X int base = 8;
X if (*s == '0')
X {
X s++;
X i++;
X switch (isupper(*s) ? tolower(*s) : *s)
X {
X Case 'b':
X base = 2;
X Case 'o':
X base = 8;
X Case 'd':
X base = 10;
X Case 'x':
X base = 16;
X Default:
X s--;
X i--;
X }
X }
X s++;
X i++;
X for (; isxdigit(*s) && i < len; s++, i++)
X {
X int d = (islower(*s) ? toupper(*s) : *s)
X - (isdigit(*s) ? '0' : 'A' - 10);
X if (d >= base)
X break;
X chr = (chr * base) + d;
X }
X s--;
X i--;
X putchar(chr);
X continue;
X }
X
X switch (isupper(*s) ? tolower(*s) : *s)
X {
X Case 'b':
X putchar('\b');
X Case 'f':
X putchar('\f');
X Case 'n':
X putchar('\n');
X Case 'r':
X putchar('\r');
X Case 't':
X putchar('\t');
X Case 'v':
X putchar('\v');
X Case '\\':
X putchar('\\');
X Case '`':
X putchar('`');
X Case 'e':
X putchar('\033');
X Case '?':
X putchar('\177');
X Case '^':
X s++;
X i++;
X putchar(*s == '?' ? '\177' : (*s & 037));
X Default:
X // putchar('\\');
X putchar(*s);
X }
X }
}
X
// DVI XXX special command - "num" is the number of bytes in the DVI
// file that are for the special command
// take the special string as a file name of a raw device-specific
// image file and dump it straight to the device
//
void special(FILE *fp, long num)
{
X debug(2, "special length = %ld", num);
X
X // allocate a buffer that is large enough for this length
X static char *buf = NULL;
X static long blen = 0;
X if (num >= blen)
X {
X if (buf != NULL)
X delete buf;
X buf = new char[blen = num + 1];
X }
X
X // read in the data from the DVI file into our buffer
X char *s = buf;
X for (long i = num; i-- > 0;)
X *s++ = (unsigned char)getuval(1, fp);
X *s = '\0';
X
X // we use the first word (up to a space) for identifying different
X // kinds of special files
X enum Specials
X {
X S_NONE = 0,
X S_RASTERFILE,
X S_ESCAPESEQ,
X S_RAWSTRING,
X } type;
X
X // handle special escape-sequences
X if (strncmp("escapeseq ", buf, 10) == 0)
X {
X s = buf + 10;
X num -= 10;
X type = S_ESCAPESEQ;
X debug(4, "Special == escapeseq = %s", s);
X mesg(" <<escapeseq");
X makecurrent();
X dev_push();
X dumpescape(s, num);
X dev_pop();
X mesg(">>");
X return;
X }
X
X // handle special raw-strings
X if (strncmp("rawstring ", buf, 10) == 0)
X {
X s = buf + 10;
X num -= 10;
X type = S_RAWSTRING;
X debug(4, "Special == rawstring = %s", s);
X mesg(" <<rawstring");
X makecurrent();
X dev_push();
X while (num-- > 0)
X putchar(*s++);
X dev_pop();
X mesg(">>");
X return;
X }
X
X // handle raw file dumps - usually graphics data
X if (strncmp("rasterfile ", buf, 11) == 0)
X {
X s = buf + 11;
X type = S_RASTERFILE;
X }
X else if (strncmp("pcl:", buf, 4) == 0)
X {
X s = buf + 4;
X type = S_RASTERFILE;
X }
X else
X s = buf;
X
X debug(4, "Special == rasterfile = %s", s);
X mesg(" <%s", s);
X
X // now open this file and dump it to the device
X
X FILE *sp = fopenp(dviinput, s, F_READ);
X if (sp == NULL)
X quit("Cannot open \"%s\" for reading", s);
X
X // move the cursor, and save the current location in the device
X makecurrent();
X dev_push();
X
X // dump the file
X int l;
X char dat[1024];
X while ((l = fread(dat, sizeof *dat, sizeof dat, sp)) > 0)
X fwrite(dat, sizeof *dat, l, stdout);
X
X fclose(sp);
X
X // restore the cursor
X dev_pop();
X mesg(">");
}
X
X
// change the current font that is downloaded to the device if we have
// to - this is completely demand-driven - a font is never even read into
// memory much less downloaded unless a character from it is actually
// going to be printed
//
static void changefont()
{
X // do we need to download this font?
X if (!currfont->downloaded)
X {
X mesg(" (");
X
X if (!currfont->setup)
X {
X // load in the font info - we're really going to use it
X setupfont(*currfont);
X setupbits(*currfont);
X currfont->setup = TRUE;
X }
X mesg("%s", currfont->basename);
X
X static int fontsdown = 0;
X currfont->use++;
X
X if (fontsdown < MAXLOADED)
X fontsdown++;
X else
X {
X // we need to delete a font from the device
X register int i;
X int fn = -1;
X long u = MAXLONG;
X
X // find the least recently used font
X for (i = 0; i < fontlist.size(); i++)
X if (fontlist[i] != NULL && fontlist[i]->downloaded
X && !fontlist[i]->onpage && fontlist[i]->use < u)
X {
X fn = i;
X u = fontlist[i]->use;
X }
X
X // we need too many fonts - dump currfont in graphics mode
X if (fn < 0)
X {
X currfont->toomany = TRUE;
X mesg("#)");
X return;
X }
X
X // mark it as not downloaded, then delete it
X font &f = *fontlist[fn].ptr;
X for (i = 0; i < MAXCHARS; i++)
X f.chr[i].downloaded = FALSE;
X f.toomany = f.downloaded = FALSE;
X dev_delfont(f);
X }
X
X // downloaded this font
X dev_newfont(*currfont);
X currfont->downloaded = TRUE;
X
X mesg(")");
X }
X
X // select this font in the device
X dev_usefont(*currfont);
X devfont = currfont;
X
X // if this font is already being used on page, we are done
X if (currfont->onpage || currfont->toomany)
X return;
X currfont->onpage = TRUE;
X
X // are there too many fonts on this page? if so, mark
X // the font as toomany to print it in graphics mode
X if (++fontsonpage > MAXONPAGE)
X {
X debug(3, "too many fonts on page - currfont marked");
X currfont->toomany = TRUE;
X mesg("#");
X }
}
X
X
// typeset a character - this is the DVI SET or PUT command - if "move"
// is TRUE, then the cursor will be moved right by the width of the
// character
//
void typeset(long ch, boolean move, double magval)
{
X fontchar & gch = currfont->chr[ch];
X
X // change the font if we have to
X if (currfont != devfont)
X changefont();
X
X // download the character if we have to - this also gets bigchars
X if (!gch.downloaded || gch.charbig || currfont->toomany)
X downchar((int)ch, currfont->toomany);
X
X // print the character if it is not too big
X if (!gch.charbig && !currfont->toomany)
X {
X makecurrent();
X int len;
X const char *dat = dev_char2dev((int)ch, len);
X fwrite(dat, sizeof *dat, len, stdout);
X devh += gch.dx >> 16;
X }
X
X if (move)
X moveright(gch.width * magval);
}
X
X
// DVI SETRULE or PUTRULE command - again, if "move" is TRUE, then the
// cursor is moved to the right, else it isn't
//
void typerule(FILE *fp, boolean move, double magval)
{
X double a = Getsval(4, fp) * magval;
X double b = Getsval(4, fp) * magval;
X
X // let the device do the work (if it can)
X if (a > 0 && b > 0)
X dev_rule(a, b);
X
X if (move)
X moveright(b);
}
SHAR_EOF
chmod 0444 font.C ||
echo 'restore of font.C failed'
Wc_c="`wc -c < 'font.C'`"
test 12300 -eq "$Wc_c" ||
echo 'font.C: original size 12300, current size' "$Wc_c"
fi
# ============= readfont.C ==============
if test -f 'readfont.C' -a X"$1" != X"-c"; then
echo 'x - skipping readfont.C (File already exists)'
else
echo 'x - extracting readfont.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'readfont.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: readfont.C,v 1.21 91/04/02 17:50:26 hmgr Exp $";
X
// read font data from the METAFONT GF (generic font) files
//
// by Parag Patel
X
#include "defs.h"
X
X
// maximum number of file that we can keep open at one time - we try to
// keep as many font files open at one time as we can instead of
// reading the entire font into memory - this should gain a little
// speed if only a few characters are loaded from many different fonts
// (which is the normal case)
//
#ifdef _SC_OPEN_MAX
const long MAXFILES = sysconf(_SC_OPEN_MAX) - NUMOPENFILES;
#else
const long MAXFILES = _NFILE - NUMOPENFILES;
#endif
X
static int numfiles = 0; // number of files currently open
X
X
// try looking for a particular type of font file - this is called
// multiple times until we succeeding in finding a font we can use
//
static int tryfile(font &f, char *dir, char *mag, char *base, char *ext)
{
X static char buf[MAXPATHLEN + 1];
X sprintf(buf, "%s/%s/%s%s", dir, mag, base, ext);
X char *path = buf;
X FILE *fp = fopen(path, F_READ);
X if (fp == NULL)
X return FALSE;
X
X // first byte is a preamble byte - same for GF and PK files
X if (getuval(1, fp) != FPRE)
X {
X fclose(fp);
X return FALSE;
X }
X
X // second byte is the font version ID field
X f.type = (int)getuval(1, fp);
X char *old = f.path;
X f.path = path;
X switch (f.type)
X {
X Case GFID:
X debug(2, "GF font file %s", path);
X setupgffont(f, fp);
X Case PKID:
X debug(2, "PK font file %s", path);
X setuppkfont(f, fp);
X Default:
X fclose(fp);
X f.path = old;
X return FALSE;
X }
X
X delete old;
X f.path = strdup(path);
X old = f.basename;
X sprintf(buf, "%s/%s%s", mag, base, ext);
X f.basename = strdup(buf);
X delete old;
X debug(6, "font basename = %s", f.basename);
X
X // keep only a MAXFILES number of font files open at one time
X if (numfiles >= MAXFILES)
X {
X fclose(fp);
X f.fp = NULL;
X }
X else
X {
X f.fp = fp;
X numfiles++;
X }
X
X return TRUE;
}
X
X
// setup a new font in memory - the font is already initialized with
// the information from the DVI file - we now have to actually read the
// font file (GF or PK) to get the rest of the font's description
//
void setupfont(font &f)
{
X if (f.path != NULL)
X if (tryfile(f, f.path, "", f.basename, ""))
X return;
X
X // setup the font directory cache if we need to
X if (pathlist.size() < 1)
X setupdirs(fontpath);
X
X for (int i = 0; i < pathlist.size(); i++)
X {
X Pathent & p = pathlist[i];
X
X if (tryfile(f, p.path, pkmagdir(p.dirs, f.mag), f.basename, ".pk"))
X return;
X if (tryfile(f, p.path, gfmagdir(p.dirs, f.mag), f.basename, ".gf"))
X return;
X if (tryfile(f, p.path, gfmagdir(p.dirs, f.mag), f.basename, ""))
X return;
X if (tryfile(f, p.path, pkmagdir(p.dirs, f.mag), f.basename, ""))
X return;
X }
X quit("Cannot find font file \"%s\" (at or near magnification %ld.%03ld) anywhere",
X f.basename, f.mag / 1000, f.mag % 1000);
}
X
X
// dump the current "fontbits" on screen in a human-readable
// format - this is really for debugging only
//
void dumpbits(int ch)
{
X register long i, j;
X font & f = *currfont;
X fontchar & g = f.chr[ch];
X
X // print a row of 2-digit X coordinate values across the top
X fprintf(stderr, " ");
X for (j = 0; j <= g.maxm - g.minm; j++)
X fprintf(stderr, "%2ld", j + g.minm);
X fprintf(stderr, "\n\n");
X
X // print the Y coordinate on both sides of each row of pixels
X for (i = g.maxn - g.minn; i >= 0; i--)
X {
X fprintf(stderr, "%3ld ", i + g.minn);
X for (j = 0; j <= g.maxm - g.minm; j++)
X fprintf(stderr, "%s", fontbits[i]->isin(j) ? "[]" : " .");
X fprintf(stderr, " %3ld\n", i + g.minn);
X }
X
X // and finally another row of X-coords across the bottom
X fprintf(stderr, "\n ");
X for (j = 0; j <= g.maxm - g.minm; j++)
X fprintf(stderr, "%2ld", j + g.minm);
X fprintf(stderr, "\n");
}
X
X
// down load the specified character "ch" to the device - we read this
// character's GF paint commands to build a bitmap of the character in
// memory - then we download this image to the printer
//
void downchar(int ch, boolean toomany)
{
X font & f = *currfont;
X fontchar & g = f.chr[ch];
X
X // is this font file open?
X if (f.fp == NULL)
X {
X // we need to close another font file if we already have the
X // maximum number open
X if (numfiles >= MAXFILES)
X {
X register int i;
X int fn = -1;
X long u = MAXLONG;
X
X // look for the least-recently used font
X for (i = 0; i < fontlist.size(); i++)
X if (fontlist[i] != NULL && fontlist[i]->fp != NULL
X && fontlist[i]->use < u)
X {
X fn = i;
X u = fontlist[i]->use;
X }
X if (fn < 0)
X quit("Cannot open another font file - all fonts are in use");
X
X // close this font file
X fclose(fontlist[fn]->fp);
X fontlist[fn]->fp = NULL;
X numfiles--;
X mesg("@");
X }
X
X // open the new font file
X f.fp = fopen(f.path, F_READ);
X if (f.fp == NULL)
X quit("Cannot re-open font file \"%s\"", f.path);
X numfiles++;
X }
X
X switch (f.type)
X {
X Case GFID:
X getgfchar(f, g, ch);
X Case PKID:
X getpkchar(f, g, ch);
X Default:
X quit("?!BUG? Internal font type id changed");
X }
X
X // show what this character looks like
X if (debuglevel > 12)
X dumpbits(ch);
X
X // now download this character to the printer...
X
X long width = g.maxm - g.minm + 1;
X long height = g.maxn - g.minn + 1;
X if (toomany || g.minm < FHMIN || g.minm > FHMAX || width > FWIDTH
X || g.maxn < FVMIN || g.maxn > FVMAX || height > FHEIGHT)
X {
X // char is too big - send it down as a graphics
X // image but do NOT mark it as downloaded
X if (!toomany)
X g.charbig = TRUE;
X dev_bigchar(f, g, ch);
X return;
X }
X
X // this is the usual method...
X g.downloaded = TRUE;
X dev_downchar(f, g, ch);
}
SHAR_EOF
chmod 0444 readfont.C ||
echo 'restore of readfont.C failed'
Wc_c="`wc -c < 'readfont.C'`"
test 5861 -eq "$Wc_c" ||
echo 'readfont.C: original size 5861, current size' "$Wc_c"
fi
# ============= gffont.C ==============
if test -f 'gffont.C' -a X"$1" != X"-c"; then
echo 'x - skipping gffont.C (File already exists)'
else
echo 'x - extracting gffont.C (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gffont.C' &&
// Copyright (c) 1991 by Parag Patel. All Rights Reserved.
static const char rcsid[] = "$Header: gffont.C,v 1.20 91/02/22 15:58:04 hmgr Exp $";
X
// read font data from the METAFONT GF (generic 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 *gfmagdir(Dirlist &dirlist, long mag)
{
X // look for the closest magnification 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 d = mag - dirlist[i].val;
X long newdiff = d < 0 ? -d : d; // absolute value
X if (newdiff >= diff)
X continue;
X diff = newdiff;
X ent = i;
X }
X
X // we should be within 1/32 (.03%) of the desired mag value
X if (ent < 0 || diff > (mag >> 5))
X return "";
X
X // return the new value as a string
X return dirlist[ent].name;
}
X
X
// setup a GF font file in memory
//
void setupgffont(font &f, FILE *fp)
{
X // skip the comment
X int len = (int)getuval(1, fp);
X while (len-- > 0)
X (void)getuval(1, fp);
X
X // now we jump to the end to find the postamble
X if (fseek(fp, 0, SEEK_END) != 0)
X quit("Cannot seek to end of GF file %s", f.path);
X
X register int op = GFILLER;
X long floc = ftell(fp);
X
X // skip the filler bytes at the end of the file
X while (op == GFILLER && floc > 0)
X {
X (void)fseek(fp, --floc, SEEK_SET);
X op = (int)getuval(1, fp);
X }
X if (op != GFID)
X quit("Incorrect GF version for %s", f.path);
X
X // now we get the file-pointer to the start of the postamble
X (void)fseek(fp, floc -= 4, SEEK_SET);
X long postloc = getuval(4, fp);
X
X // verify that we have a POST byte
X (void)fseek(fp, postloc, SEEK_SET);
X if (getuval(1, fp) != FPOST)
X quit("Expected FPOST");
X
X long fsize = getuval(4, fp);// pointer to last EOC in file
X debug(3, "GF last EOC=%ld", fsize);
X
X // get and verify that the design size is ok - the GF 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, "GF 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 GF file %s does not match", f.path);
X else
X warn("Designsize in DVI and GF file %s does not match", f.path);
X
X // check the checksum (!)
X long check = getuval(4, fp);
X debug(5, "GF 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 GF file %s do not match", f.path);
X else
X warn("Checksums in DVI and GF 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 // get the size ranges of the characters in this font
X f.minm = getsval(4, fp);
X f.maxm = getsval(4, fp);
X f.minn = getsval(4, fp);
X f.maxn = getsval(4, fp);
X
X debug(3,"mag=%ld hppp=%ld vppp=%ld minm=%ld maxm=%ld minn=%ld, maxn=%ld",
X f.mag, f.hppp, f.vppp, f.minm, f.maxm, f.minn, f.maxn);
X
X // now initialize the info for each character in this font - note
X // that there may only be CHARLOC or NOOPs in this part of the file
X while ((op = (int)getuval(1, fp)) != FPOSTPOST)
X {
X if (op == FNOOP)
X continue;
X
X // assume that the next byte is a character "residue" (id % 256)
X int c = (int)getuval(1, fp);
X if (c >= MAXCHARS)
X quit("Char %d too big in GF file %s", c, f.path);
X fontchar & g = f.chr[c];
X
X // get the values for delta-x, delta-y, width, and file-pointer
X // for this character
X switch (op)
X {
X Case CHARLOC:
X g.dx = getuval(4, fp);
X g.dy = getuval(4, fp);
X g.width = Getsval(4, fp);
X g.floc = getsval(4, fp);
X
X Case CHARLOC0:
X g.dx = getuval(1, fp) << 16;
X g.dy = 0;
X g.width = Getsval(4, fp);
X g.floc = getsval(4, fp);
X
X Default:
X quit("Illegal opcode %d in GF postamble", op);
X }
X
X g.width = g.width / double(16) * double(f.designsize) /
X double(65536L) * double(f.mag) / 1000.0;
X }
}
X
X
// load the specified character "ch" into the bitmap - we read this
// character's GF paint commands to paint this font
//
void getgfchar(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
X register int op = (int)getuval(1, f.fp);
X
X // we had better get some flavor of BOC here...
X switch (op)
X {
X Case BOC:
X // verify the character (Just In Case)
X if (ch != getsval(4, f.fp))
X quit("Character definition for %d does not match", ch);
X
X (void)getuval(4, f.fp); // pointer to next character % 256
X
X // get the size (in pixels) of this character
X g.minm = getsval(4, f.fp);
X g.maxm = getsval(4, f.fp);
X g.minn = getsval(4, f.fp);
X g.maxn = getsval(4, f.fp);
X
X Case BOC1:
X if (ch != getuval(1, f.fp))
X quit("Character definition for %d does not match", ch);
X
X // decode the size (in pixels) of this character
X g.minm = getuval(1, f.fp);
X g.maxm = getuval(1, f.fp);
X g.minm = g.maxm - g.minm;
X
X g.minn = getuval(1, f.fp);
X g.maxn = getuval(1, f.fp);
X g.minn = g.maxn - g.minn;
X
X Default:
X quit("Expected BOC* (not %d) in font file %s for char %d",
X op, f.path, ch);
X }
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=%f", g.dx, g.dy,
X g.dx >> 16, g.dy >> 16, g.width);
X }
X
X // initialize the character painting variables
X register long m = 0;
X register long n = g.maxn - g.minn;
X int p = WHITE;
X
X long width = g.maxm - g.minm + 1;
X long height = g.maxn - g.minn + 1;
X
X // clear the global fontbits for the bitmap
X register long d;
X for (d = f.maxn - f.minn; d >= 0; d--)
X fontbits[d]->clear();
X
X // paint the fontbits to build the character
X while ((op = (int)getuval(1, f.fp)) != EOC)
X {
X if (op > PAINT0 && op <= PAINT63)
X {
X // paint with the current color, advance X
X if (p == BLACK)
X while (op-- > 0)
X *fontbits[n] += m++;
X else
X m += op;
X p = !p;
X continue;
X }
X if (op >= NEWROW0 && op <= NEWROW164)
X {
X // advance Y, paint to black
X n--;
X m = op - NEWROW0;
X p = BLACK;
X continue;
X }
X
X switch (op)
X {
X // paint with current color, advange X
X Case PAINT0:
X p = !p;
X Case PAINT1:
X d = getuval(1, f.fp);
X if (p == BLACK)
X while (d-- > 0)
X *fontbits[n] += m++;
X else
X m += d;
X p = !p;
X Case PAINT2:
X d = getuval(2, f.fp);
X if (p == BLACK)
X while (d-- > 0)
X *fontbits[n] += m++;
X else
X m += d;
X p = !p;
X Case PAINT3:
X d = getuval(3, f.fp);
X if (p == BLACK)
X while (d-- > 0)
X *fontbits[n] += m++;
X else
X m += d;
X p = !p;
X
X // advance Y, paint to white
X Case SKIP0:
X n--;
X m = 0;
X p = WHITE;
X Case SKIP1:
X n -= getuval(1, f.fp) + 1;
X m = 0;
X p = WHITE;
X Case SKIP2:
X n -= getuval(2, f.fp) + 1;
X m = 0;
X p = WHITE;
X Case SKIP3:
X n -= getuval(3, f.fp) + 1;
X m = 0;
X p = WHITE;
X
X // special opcodes - just ignore for now
X Case FXXX1:
X skipbytes(getuval(1, f.fp), f.fp);
X Case FXXX2:
X skipbytes(getuval(2, f.fp), f.fp);
X Case FXXX3:
X skipbytes(getuval(3, f.fp), f.fp);
X Case FXXX4:
X skipbytes(getuval(4, f.fp), f.fp);
X
X // special numeric opcode - also ignored
X Case YYY:
X (void)getuval(4, f.fp);
X
X Case FNOOP:
X
X Default:
X quit("Illegal GF opcode %ld in file %f", d, f.path);
X }
X }
}
SHAR_EOF
chmod 0444 gffont.C ||
echo 'restore of gffont.C failed'
Wc_c="`wc -c < 'gffont.C'`"
test 7918 -eq "$Wc_c" ||
echo 'gffont.C: original size 7918, current size' "$Wc_c"
fi
true || echo 'restore of pkfont.C failed'
echo End of part 2, continue with part 3
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