[comp.text] DVI-LaserJetII converter - Part 2 of 4

mah@hpuviea.UUCP (Michael Haberler) (01/19/89)

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Michael Haberler <mah@hpuviea> on Wed Jan 18 17:57:30 1989
#
# This archive contains:
#	dvilj.c-part1	
#

unset LANG

echo x - dvilj.c-part1
cat >dvilj.c-part1 <<'@EOF'
#define VERSION "0.41"
/**********************************************************************
 ****************************  Intro  *********************************
 **********************************************************************
 * This program translates TeX's DVI-Code into device dependent
 * code of either the
 *
 *         -   HP-LASERJET+ and compatibles (PCL), or the
 *         -   IBM 3812 pageprinter
 *
 * depending on the preprocessor switches specified before compilation.
 * The program is written to run on a PC XT/AT/PS2 under MS-DOS. It can
 * be compiled nicely with MSC Rel. 3 with option -AL (large memory
 * model).  Take care that in the CONFIG.SYS file the FILES parameter
 * is set to 20; otherwise reduce MAXOPEN.  640K are recommended.
 * I use link option /stack:9000 to increase runtime stack.
 * It also works without modifications on System V Unix Machines.
 **********************************************************************
 *                    Adapted for the PC:    Gustaf Neumann
 *                    +1002 stuff            University of Economics
 *                    +3812 support          Augasse 2-6
 *                    +Output buffering      A-1090 Vienna, AUSTRIA
 *                    +lpt binary support    Tel. *43-222-340525/533
 *                    +pk-89 stuff                               773
 *                    +pixelpaths
 *                    +alternative directory structure
 *                    +code compiles also under Unix V (HP/UX)
 *                                      (thx Michael Haberler)
 *                    +huge characters (a character bigger than 32K)
 *                                      formats PXL1001 and PXL 1002
 *                                     (use: raster graphics)
 *                    +reduction of the produced code
 *                    +new options -X -Y -c -g
 *                    +changed options -r (LJ now default from first to last)
 *                                     -x,-y  (accept floats)
 *
 *                    BITNET/EARN:           NEUMANN at AWIWUW11
 **********************************************************************
 * fixes in LJ-mode:  rule-drawing,
 *                    characters with 127<=height<=200
 *                    reset printer at beginning and end of each job
 *                    better positioning of rules
 * fixes in 3812-mode:  14.juli 87  positioning of rastered characters
 *                    better positioning of rules
 * 1.1.88             page origin set to 1in/1in (hopefully everywhere)
 **********************************************************************
 * Preprocessor switches:
 *      #define DEBUG    for massive printing of trace information
 *                       when -d cmdline option specified
 *      #define IBM3812  produce output for the IBM3812 pageprinter
 *      #define LJ       produce output for the HP Laserjet+
 */
/**********************************************************************
 ************************  Global Definitions  ************************
 **********************************************************************/
/*#define IBM3812*/
#define LJ
     
/* unix user: remove the following definition if you cannot access the
 * appropriate C library functions
 */
#define TIMING
     
#ifdef unix
#define OS "Unix"
#endif
#ifdef MSDOS
#define OS "MS-DOS"
#define MSC5
#endif
     
#include "commands.h"
#include "string.h"
#include <signal.h>
#include <stdio.h>
#include <ctype.h>
#ifdef MSDOS
#include <dos.h>    /* only for binaryopen on device  */
#endif
#ifdef  hpux
#include <sys/param.h>
#define labs(x) abs(x)
#endif
     
#define  DVIFORMAT        2
#define  TRUE      (bool) 1
#define  FALSE     (bool) 0
#define  UNKNOWN         -1
#define  FIRSTPXLCHAR     0
#define  LASTPXLCHAR    127          /* was 255 * change NPXLCHARS too !!  */
#define  FONTAREA       "/usr/local/lib/TeX/fonts"      /* "/usr/lib/tex/fonts"               */
#ifdef   hpux
#define  MAXOPEN        (NOFILE - 8)
#else
#define  MAXOPEN         12          /* limit on number of open PXL files  */
#endif
#define  NPXLCHARS      128          /* was 256  change LASTPXLCHAR too !! */
#define  STACKSIZE      100          /* DVI-stack size                     */
#define  STRSIZE        255          /* stringsize for file specification  */
#define  NONEXISTANT     -1          /* offset for PXL files not found     */
#define  NO_FILE        ((FILE *)-1)
#define  NEW(A) ((A *)  malloc(sizeof(A)))
#define  EQ(a,b)        (strcmp(a,b)==0)
#define  MM_TO_PXL(x)   (int)(((x)*RESOLUTION*10)/254)
#define  BOPENCMD fopen
#define  BINOPEN(f) BOPENCMD(f,"rb")
/* SMALL_SIZE characters are loaded into font storage of the printer   */
/* LARGE_SIZE characters are rastered                                  */
/* HUGE_SIZE characters are not loaded into the memory of the host */
#define  SMALL_SIZE     (unsigned char) 0
#define  LARGE_SIZE (unsigned char) 1
#define  HUGE_SIZE (unsigned char) 2
#define  HUGE_CHAR_PATTERN 32767l
#define  BYTES_PER_PIXEL_LINE 500    /* max number of bytes per pixel line */
     
     
#define PK_POST 245
#define PK_PRE 247
#define PK_ID 89
     
/* to speedup the program a little: redefinition of PixRound and PutWord */
/*#define PIXROUND(x,c) ((((double)x+(double)(c>>1))/(double)c)+0.5)*/
#define PIXROUND(x,c) (((x)+c)/c)
#define PUTWORD(w)  EMITC((char)(w>>8)&0xff); EMITC((char)w&0xff)
/*************************************************************************/
#define  EMIT           fprintf                /* output a formatted string   */
#define  EMITB(len,b)   fwrite(b,1,len,outfp)  /* output binary data of len   */
#define  EMITWORD(w)    PUTWORD((w))           /* output a 2 byte word of data*/
     
#define  MoveOver(b)  h += (long) b
#define  MoveDown(a)  v += (long) a
     
#ifdef IBM3812
#define  PRINTER      "IBM 3812 pageprinter"
#define  EMITC(c)      PMPoutC(c)                /* output a single character */
#define  PMPcont(l)    PMPout(-1,(long)l)          /* next l bytes continuous */
#define  PMPflush      PMPout(0l,"")                      /* flush PMP-buffer */
#define  EMITL(l,d)    PMPout((int)l,d)       /* EMIT-logical: via PMP-buffer */
#define  RESOLUTION        240
#define  hconvRESOLUTION   240
#define  vconvRESOLUTION   240
#define  CHAR_WIDTH_LARGE  100        /*  limit for loading into printer font */
#define  CHAR_HEIGTH_LARGE 127        /*  limit for loading into printer font */
#define  OUTBUFSIZE     20000         /*   size of output buffer for PMP cmds */
                                      /*   has to be less max(signed int)     */
#define  MAXFONTSTORAGE      130000l  /* font storage in the 3812 pageprinter */
#define  EMITFILE_EXTENSION    ".pmp"       /* default extension of emit file */
#define  XDEFAULTOFF    RESOLUTION         /* y default offset on page 1 inch */
#define  YDEFAULTOFF    RESOLUTION         /* y default offset on page 1 inch */
#define  CHARSTRINGMAX  80                 /* bufferlength for SetString      */
/**********************************************************************/
/**************  Positioning for the 3812  ****************************/
/**********************************************************************/
#define VERT_HALF(n) ((short)(n+1>>1)-1)
#define HOR_HALF(n)  ((short)(n>>1))
#define MoveHor(n)  if ((n)!=0) { PMPcont(3); PMPout(1,"\342"); EMITWORD((n)); }
#define MoveVert(n) if ((n)!=0) { PMPcont(3); PMPout(1,"\343"); EMITWORD((n)); }
#endif
     
#ifdef LJ
#define  PRINTER       "HP Laserjet+"
#define  RESOLUTION        300
#define  hconvRESOLUTION   300
#define  vconvRESOLUTION   300
#define  CHAR_WIDTH_LARGE  100         /* limit for loading into printer font */
#define  CHAR_HEIGTH_LARGE 127             /* y_offset reaches the same size! */
#define  EMITFILE_EXTENSION    ".lj"        /* default extension of emit file */
#define  MAX_FONTS_PER_PAGE 16            /* maximum number of fonts per page */
#define  EMITC(c)      putc(c,outfp)             /* output a single character */
#define  EMITL(l,d)    EMITB(l,d)                     /* EMIT-logical = EMITB */
#define  XDEFAULTOFF    RESOLUTION-54 /* y default offset on page 1 inch (LJ2)*/
#define  YDEFAULTOFF    RESOLUTION+9       /* y default offset on page 1 inch */
#endif
/**********************************************************************/
/***********************  external definitions  ***********************/
/**********************************************************************/
typedef  char    bool;
     
long    access();
FILE   *BOPENCMD();
void    exit();
int     fclose();
int     fprintf();
int     fseek();
#ifndef MSC5
int     fread();
int     fwrite();
#endif
char    *index();
int     intdos();
char    *malloc();
int     printf();
int     sprintf();
int     sscanf();
int     strcmp();
char    *strcpy();
#ifdef MSDOS
unsigned int    strlen();
#endif
void    free();
void    setbuf();
     
#include "findfile.h"
     
/**********************************************************************/
/*************************  Global Procedures  ************************/
/**********************************************************************/
/* Note: Global procedures are declared here in alphabetical order, with
   those which do not return values typed "void".  Their bodies occur in
   alphabetical order following the main() procedure.  The names are
   kept unique in the first 6 characters for portability. */
double  ActualFactor();
void    AllDone();
#ifdef  MSDOS
void    AssureBinary();  /* DOS and Microsoft C dependent !!! */
#endif
void    CopyFile();
void    DecodeArgs();
void    DoBop();
long    DoConv();
void    DoSpecial();
void    EmitChar();
void    Fatal();
void    FindPostAmblePtr();
void    GetBytes();
void    GetFontDef();
char    *GetKeyStr();
bool    GetKeyVal();
bool    HasBeenRead();
bool    IsSame();
void    lcase();
void    LoadAChar();
long    NoSignExtend();
/* see cautionary note in code, re arithmetic vs logical shifts */
void    OpenFontFile();
long    PixRound();
void    PkRaster();
void    PutWord();
void    ReadFontDef();
void    ReadPostAmble();
void    SetChar();
void    SetFntNum();
void    SetPosn();
void    SetRule();
void    SetString();
long    SignExtend();
/* see cautionary note in code, re arithmetic vs logical shifts */
void    SkipFontDef();
void    Warning();
unsigned char   VisChar();
unsigned char   skip_specials() ;
     
#ifdef IBM3812
void    PMPout();
void    PMPoutC();
#endif
     
/**********************************************************************/
/***********************  Font Data Structures  ***********************/
/**********************************************************************/
     
struct char_entry {                         /* character entry */
        unsigned short  width, height;      /* width and height in pixels */
        short   xOffset, yOffset, yyOffset; /* x offset and y offset in pixels*/
        struct {
                bool isloaded;
                union {
                        long    fileOffset;
                        long    *pixptr;
                } address;
        } where;
        long    tfmw;                        /* TFM width       */
        long    cw;                          /* character width in pixels */
        unsigned char   flag_byte;           /* for PK-files    */
        unsigned char   charsize;
};
struct font_entry {        /* font entry */
        long    k, c, s, d;
        int     a, l;
        /*   char n[STRSIZE]; */  /* FNT_DEF command parameters               */
        /*   long font_space; */  /* computed from FNT_DEF s parameter        */
        long    font_mag;         /* computed from FNT_DEF s and d parameters */
        /*char psname[STRSIZE];*/ /* PostScript name of the font              */
        char    name[STRSIZE];    /* full name of PXL file                    */
        FILE * font_file_id;      /* file identifier (NO_FILE if none)        */
        long    magnification;    /* magnification read from PXL file         */
        long    designsize;       /* design size read from PXL file           */
        struct char_entry ch[NPXLCHARS];   /* character information           */
        struct font_entry *next;
        int     ncdl;              /* #of different chars actually downloaded */
        int     plusid;            /* Font id in Printer                      */
        bool used_on_this_page;
        enum PxlId {
                id1001, id1002, pk89    } id;
};
     
     
struct pixel_list {
        FILE *pixel_file_id;        /* file identifier  */
        int     use_count;          /* count of "opens" */
};
/**********************************************************************/
/*************************  Global Variables  *************************/
/**********************************************************************/
long    FirstPage = -1000000;   /* first page to print (uses count0)   */
long    LastPage = 1000000;     /* last page to print                    */
char    G_progname[STRSIZE];    /* program name                            */
char    filename[STRSIZE];      /* DVI file name                           */
char    rootname[STRSIZE];      /* DVI filename without extension          */
char    *PXLpath = FONTAREA;    /* PXL path name for search                */
char    *HeaderFileName = "";   /* file name & path of Headerfile          */
char    *EmitFileName = "";     /* file name & path of produced output     */
#ifdef IBM3812
bool    FirstAlternate = FALSE; /* first page from alternate casette ?     */
#endif
bool    Reverse = FALSE;        /* process DVI pages in reverse order ?    */
bool    PreLoad = TRUE;         /* preload the font descriptions?          */
bool    ResetPrinter = TRUE;    /* reset printer at the begin of the job   */
short   G_errenc = 0;           /* has an error been encountered?          */
bool    G_header = FALSE;       /* copy header file to output?             */
bool    G_quiet = FALSE;        /* for quiet operation                     */
bool    G_noverbatim = TRUE;    /* inform user about pxl-files used        */
bool    G_nowarn = FALSE;       /* don't print out warnings                */
short   x_origin = XDEFAULTOFF; /* x-origin in dots                        */
short   y_origin = YDEFAULTOFF; /* y-origin in dots                        */
short   x_goffset;              /* global x-offset in dots                 */
short   y_goffset;              /* global y-offset in dots                 */
unsigned short ncopies = 1;     /* number of copies to print               */
long    hconv, vconv;           /* converts DVI units to pixels            */
long    den;                    /* denominator specified in preamble       */
long    num;                    /* numerator specified in preamble         */
long    h;                      /* current horizontal position             */
long    hh = 0;                 /* current h on device                     */
long    v;                      /* current vertical position               */
long    vv = 0;                 /* current v on device                     */
long    mag;                    /* magnification specified in preamble     */
long    usermag = 0;            /* user specified magnification            */
int     ndone = 0;              /* number of pages converted               */
int     nopen = 0;              /* number of open PXL files                */
FILE  *outfp = NULL;            /* output file                             */
FILE  *pxlfp;                   /* PXL file pointer                        */
FILE  *dvifp  = NULL;           /* DVI file pointer                        */
struct font_entry *prevfont = NULL; /* font_entry pointer previous font r  */
struct font_entry *fontptr;       /* font_entry pointer                    */
struct font_entry *hfontptr = NULL; /* font_entry pointer                  */
struct font_entry *pfontptr = NULL; /* previous font_entry pointer         */
struct pixel_list pixel_files[MAXOPEN+1]; /* list of open PXL files        */
long    postambleptr;               /* Pointer to the postamble            */
long    ppagep;                     /* previous page pointer               */
static int      last_ry = UNKNOWN;      /* last y-position on page         */
     
/* deactivated features */
/**********************/
/*int    nif = 0;     */        /* number of files to include              */
/*char  *Ifile[100];  */        /* files to include                        */
/*int    nps = 0;     */        /* number of PostScript commands to send   */
/*char  *PScmd[100];  */        /* PostScript commands to send             */
/**********************/
     
long    allocated_storage = 0; /* size of mallocated storage (statistics) */
long    power[32] ;
long    gpower[33] ;
     
     
#ifdef DEBUG
bool Debug = FALSE;
#endif
     
#ifdef LJ
int     fonts_used_on_this_page;
#endif
     
#ifdef IBM3812
char    PMPformat[20];
long    used_fontstorage = 0;
char    CharString[CHARSTRINGMAX];
unsigned int CharStringPos = 0;
#define CharStringOut \
        if (CharStringPos>0) { \
            PMPcont(CharStringPos+1);\
            PMPoutC((unsigned char)CharStringPos);\
            PMPout(CharStringPos, CharString); \
            CharStringPos=0; }
#endif
     
#ifdef TIMING
/************************timing stuff*********************/
#include <sys/timeb.h>
void ftime();
struct timeb timebuffer;
double  start_time;
#endif
     
     
/**********************************************************************/
/*******************************  main  *******************************/
/**********************************************************************/
void
main(argc, argv)
int     argc;
char    *argv[];
{
        struct stack_entry {  /* stack entry */
                long    h, v, w, x, y, z;  /* what's on stack */
        };
        short   command;          /* current command                         */
        long    count[10];        /* the 10 counters at begining of each page*/
        long    cpagep;           /* current page pointer                    */
        bool Emitting = FALSE;    /* outputting typsetting instructions?     */
        int     i;                /* command parameter; loop index           */
        int     k;                /* temporary parameter                     */
        char    n[STRSIZE];       /* command parameter                       */
        int     PassNo = 0;       /* which pass over the DVI page are we on? */
        bool SkipMode = FALSE;    /* in skip mode flag                       */
        int     sp;               /* stack pointer                           */
        struct stack_entry stack[STACKSIZE];   /* stack                      */
        char    SpecialStr[STRSIZE]; /* "\special" strings                   */
        long    val, val2;        /* temporarys to hold command information  */
        long    w;                /* current horizontal spacing              */
        long    x;                /* current horizontal spacing              */
        long    y;                /* current vertical spacing                */
        long    z;                /* current vertical spacing                */
     
        setbuf(stderr, NULL);
        (void) strcpy(G_progname, argv[0]);
        DecodeArgs( argc, argv );
     
        power [ 0 ] = 1 ;
        for ( i = 1 ; i <= 31 ; i ++)
                power [ i ] = power [ i - 1 ] << 1 ;
        gpower[0] = 0l ;
        for ( i = 1 ; i <= 32 ; i ++)
                gpower[i] = gpower[i - 1] + power[i - 1] ;
     
        if ((i = (int) NoSignExtend(dvifp, 1)) != PRE)  {
                Fatal(
            "%s: PRE doesn't occur first--are you sure this is a DVI file?\n\n",
                            G_progname);
        }
        i = (int) SignExtend(dvifp, 1);
        if (i != DVIFORMAT)  {
                Fatal(
                "%s: DVI format = %d, can only process DVI format %d files\n\n",
                            G_progname, i, DVIFORMAT);
        }
        outfp = fopen(EmitFileName, "wb");
#ifndef unix
        AssureBinary(outfp);
#endif
     
#ifdef TIMING
        ftime(&timebuffer);
        start_time = (timebuffer.time) + (timebuffer.millitm) / 1000.0;
#endif
     
        /* it is important that these be the very first things output !!! */
        if ( G_header )
                CopyFile( HeaderFileName );
     
        /*****************************/
        /*for( i0=0; i0<nif; i0++ )  */    /* copy all included files */
        /*    CopyFile( Ifile[i0] ); */
        /*****************************/
     
#ifdef IBM3812
        PMPout(1, "\307");              /* unload all fonts */
        PMPout(1, "\310");              /* unload all macros */
#endif
#ifdef LJ
        if (ResetPrinter)
            EMIT(outfp, "\033E");
     
        EMIT(outfp, "\033&l0E\033&a0L");
     
        if (ncopies>1)
            EMIT(outfp, "\033&l%hdX",ncopies);
#endif
     
        if (Reverse) {
#ifdef DEBUG
                if (Debug)
                        printf("reverse\n");
#endif
                ReadPostAmble(PreLoad);
                fseek(dvifp, ppagep, 0);
        } else {
                if (PreLoad) {
#ifdef DEBUG
                        if (Debug)
                                printf("preload\n");
#endif
                        ReadPostAmble(TRUE);
                        fseek(dvifp,  14l, 0);
                } else {
                        num = NoSignExtend(dvifp, 4);
                        den = NoSignExtend(dvifp, 4);
                        mag = NoSignExtend(dvifp, 4);
                        if ( usermag > 0 && usermag != mag && !(G_quiet))
                                printf(
                    "DVI magnification of %ld over-ridden by user (mag=%ld)\n",
                                                      mag, usermag );
                        if ( usermag > 0 )
                                mag = usermag;
                        hconv = DoConv(num, den, hconvRESOLUTION);
                        vconv = DoConv(num, den, vconvRESOLUTION);
                }
                k = (int) NoSignExtend(dvifp, 1);
                GetBytes(dvifp, n, k);
        }
        PassNo = 0;
     
        while (TRUE)  {
                command = (short) NoSignExtend(dvifp, 1)   ;
#ifdef DEBUG
                if (Debug)
                        printf("CMD:\t%d\n", command);
#endif
                /*      switch (command=NoSignExtend(dvifp, 1))  {*/
                switch (command)  {
                case SET1:
                case SET2:
                case SET3:
                case SET4:
                        val = NoSignExtend(dvifp, (int) command - SET1
                            + 1);
                        if (!SkipMode)
                                SetChar(val, command, PassNo, TRUE,FALSE);
                        break;
                case SET_RULE:
                        val = NoSignExtend(dvifp, 4);
                        val2 = NoSignExtend(dvifp, 4);
                        if (Emitting)
                                SetRule(val, val2, 1);
                        break;
                case PUT1:
                case PUT2:
                case PUT3:
                case PUT4:
                        val = NoSignExtend(dvifp, (int) command - PUT1
                            + 1);
                        if (!SkipMode)
                                SetChar(val, command, PassNo, TRUE,FALSE);
                        break;
                case PUT_RULE:
                        val = NoSignExtend(dvifp, 4);
                        val2 = NoSignExtend(dvifp, 4);
                        if (Emitting)
                                SetRule(val, val2, 0);
                        break;
                case NOP:
                        break;
                case BOP:
                        cpagep = ftell(dvifp) - 1;
                        for (i = 0; i <= 9; i++)
                                count[i] = NoSignExtend(dvifp, 4);
                        ppagep = NoSignExtend(dvifp, 4);
                        h = v = w = x = y = z = 0;
                        hh = vv = 0;
                        sp = 0;
                        fontptr = NULL;
                        prevfont = NULL;
                        DoBop();
                        if ( count[0] < FirstPage || count[0] > LastPage )
                                SkipMode = TRUE;
                        else
                                SkipMode = FALSE;
                        Emitting = (bool)((PassNo != 0) && !SkipMode);
                        if ( !SkipMode ) {
                                if ( PassNo == 0) {
                                        if ( !G_quiet )
                                                fprintf(stderr, "[%ld",
                                                     count[0] );
                                } else {
                                }
                        }
                        break;
                case EOP:
                        if ( !SkipMode ) {
                                if ( PassNo == 0 ) {
                                        /* start second pass on current page */
                                        fseek(dvifp, cpagep, 0);
                                        PassNo = 1;
                                } else { unsigned short pages;
                               /* end of second pass, and of page processing */
#ifdef IBM3812
                                        if ( (ndone == 0) && (FirstAlternate)){
                                            for(pages=1;pages<ncopies;pages++){
                                                PMPout(2, "\321\300");
                                                /* PMP-command xD1C0 */
                                            }
                                            PMPout(2, "\321\100");
                                            /* PMP-command xD140 */
                                        } else {
                                            for(pages=1;pages<ncopies;pages++){
                                                PMPout(2, "\321\200");
                                                /* PMP-command xD180 */
                                            }
                                            PMPout(2, "\321\0");
                                            /* PMP-command xD100 */
                                        }
#endif
#ifdef LJ
                                        EMITC('\f');
#endif
                                        ++ndone;
                                        if ( !G_quiet ) {
                                                fprintf(stderr, "] ");
                                                if ( (ndone % 10) == 0 )
                                                        fprintf(stderr,
                                                             "\n");
                                        }
                                        PassNo = 0;
                                }
                        } else
                                PassNo = 0;
                        if ( PassNo == 0 && Reverse ) {
                                if ( ppagep > 0 )
                                        fseek(dvifp, ppagep, 0);
                                else
                                        AllDone();
                        }
                        break;
                case PUSH:
                        if (sp >= STACKSIZE)
                                Fatal("stack overflow");
                        stack[sp].h = h;
                        stack[sp].v = v;
                        stack[sp].w = w;
                        stack[sp].x = x;
                        stack[sp].y = y;
                        stack[sp].z = z;
                        sp++;
                        break;
                case POP:
                        --sp;
                        if (sp < 0)
                                Fatal("stack underflow");
                        h = stack[sp].h;
                        v = stack[sp].v;
                        w = stack[sp].w;
                        x = stack[sp].x;
                        y = stack[sp].y;
                        z = stack[sp].z;
                        break;
                case RIGHT1:
                case RIGHT2:
                case RIGHT3:
                case RIGHT4:
                        val = SignExtend(dvifp, (int) command - RIGHT1 + 1);
                        if (Emitting)
                                MoveOver(val);
                        break;
                case W0:
                        if (Emitting)
                                MoveOver(w);
                        break;
                case W1:
                case W2:
                case W3:
                case W4:
                        w = SignExtend(dvifp, (int)command - W1 + 1);
                        if (Emitting)
                                MoveOver(w);
                        break;
                case X0:
                        if (Emitting)
                                MoveOver(x);
                        break;
                case X1:
                case X2:
                case X3:
                case X4:
                        x = SignExtend(dvifp, (int)command - X1 + 1);
                        if (Emitting)
                                MoveOver(x);
                        break;
                case DOWN1:
                case DOWN2:
                case DOWN3:
                case DOWN4:
                        val = SignExtend(dvifp, (int)command - DOWN1 +
                            1);
                        if (Emitting)
                                MoveDown(val);
                        break;
                case Y0:
                        if (Emitting)
                                MoveDown(y);
                        break;
                case Y1:
                case Y2:
                case Y3:
                case Y4:
                        y = SignExtend(dvifp, (int)command - Y1 + 1);
                        if (Emitting)
                                MoveDown(y);
                        break;
                case Z0:
                        if (Emitting)
                                MoveDown(z);
                        break;
                case Z1:
                case Z2:
                case Z3:
                case Z4:
                        z = SignExtend(dvifp, (int)command - Z1 + 1);
                        if (Emitting)
                                MoveDown(z);
                        break;
                case FNT1:
                case FNT2:
                case FNT3:
                case FNT4:
                        if (!SkipMode) {
                                SetFntNum(NoSignExtend(dvifp, (int)command
                                    -FNT1 + 1), Emitting);
                        }
                        break;
                case XXX1:
                case XXX2:
                case XXX3:
                case XXX4:
                        k = (int) NoSignExtend(dvifp, (int)command - XXX1
                            + 1);
                        GetBytes(dvifp, SpecialStr, k);
                        if (Emitting)
                                DoSpecial(SpecialStr, k);
                        break;
                case FNT_DEF1:
                case FNT_DEF2:
                case FNT_DEF3:
                case FNT_DEF4:
                        k = (int) NoSignExtend(dvifp, (int)command - FNT_DEF1
                            + 1);
                        if (PreLoad || HasBeenRead((long)k) ) {
                                SkipFontDef (k);
                        } else
                         {
                                ReadFontDef ( (long) k);
                        }
                        break;
                case PRE:
                        Fatal("PRE occurs within file");
                        break;
                case POST:
                        AllDone();
                        break;
                case POST_POST:
                        Fatal("POST_POST with no preceding POST");
                        break;
                default:
                        if (command >= FONT_00 && command <= FONT_63) {
                                if (!SkipMode)
                                        SetFntNum((long) command - FONT_00,
                                             Emitting);
                        } else if (command >= SETC_000 && command <= SETC_127) {
                                if (!SkipMode) {
                                        SetString(command, PassNo);
                                }
                        } else
                                Fatal("%d is an undefined command", command);
                        break;
                }
        } /* that's mine */
}
     
     
/*-->ActualFactor*/
/**********************************************************************/
/**************************  ActualFactor  ****************************/
/**********************************************************************/
double  /* compute the actual size factor given the approximation */
ActualFactor(unmodsize)
long    unmodsize;                             /* actually factor * 1000 */
{
        double  realsize;     /* the actual magnification factor */
        realsize = (double)unmodsize / 1000.0;
        if (abs((int)(unmodsize - 1095l))<2)
                realsize = 1.095445115; /*stephalf*/
        else if (abs((int)(unmodsize - 1315l))<2)
                realsize = 1.31453414; /*stepihalf*/
        else if (abs((int)(unmodsize - 1577l))<2)
                realsize = 1.57744097; /*stepiihalf*/
        else if (abs((int)(unmodsize - 1893l))<2)
                realsize = 1.89292916; /*stepiiihalf*/
        else if (abs((int)(unmodsize - 2074l))<2)
                realsize = 2.0736;   /*stepiv*/
        else if (abs((int)(unmodsize - 2488l))<2)
                realsize = 2.48832;  /*stepv*/
        else if (abs((int)(unmodsize - 2986l))<2)
                realsize = 2.985984; /*stepvi*/
        /* the remaining magnification steps are represented with sufficient
           accuracy already */
        return(realsize);
}
     
     
/*-->AllDone*/
/**********************************************************************/
/****************************** AllDone  ******************************/
/**********************************************************************/
void
AllDone()
{
        double  time;
     
#ifdef IBM3812
        PMPout(10, "\373\010PMP.init");  /* re-init printer  */
        PMPflush;
     
        if (used_fontstorage > MAXFONTSTORAGE) {
                Warning("\n\7used font_storage of 3812: %ld Bytes (of %ld)\7",
                                   used_fontstorage, MAXFONTSTORAGE);
                Warning("Try to format file in separate runs!");
        } else if (!G_quiet) {
                printf(
                   "\nAll done, used font_storage of 3812: %ld Bytes (of %ld)",
                                        used_fontstorage, MAXFONTSTORAGE);
        }
#endif
#ifdef LJ
        EMIT(outfp, "\033E");
#endif
     
        if (!G_quiet) {
                printf( "\nDynamically allocated storage: %ld Bytes \n",
                                    allocated_storage);
     
#ifdef TIMING
                ftime(&timebuffer);
                time = ((timebuffer.time) + (timebuffer.millitm) / 1000.0)
                    -start_time;
     
                if (ndone > 0)
                        printf(
         "Time of complete run: %.2f seconds, %d page(s), %.2f seconds/page\n",
                                          time, ndone, time / ndone);
                printf("\n");
#endif
        }
     
        exit(G_errenc);
}
     
     
/*-->CopyFile*/   /* copy a file straight through to output */
/*********************************************************************/
/***************************** CopyFile ******************************/
/*********************************************************************/
void
CopyFile( str )
char    *str;
{
        FILE    * spfp;
        char    t;
        if ( (spfp = fopen(str, "rb")) == NULL ) {
                Warning("Unable to open file %s", str );
                return;
        }
        if ( !G_quiet )
                printf(" [%s", str);
        for (t = (char)getc(spfp); !feof(spfp); t = (char)getc(spfp))
                putc(t, outfp);
        fclose(spfp);
        if ( !G_quiet )
                printf("]");
}
     


     
/*-->DecodeArgs*/
/*********************************************************************/
/***************************** DecodeArgs ****************************/
/*********************************************************************/
void
DecodeArgs( argc, argv )
int     argc;
char    *argv[];
{
        int     argind;            /* argument index for flags              */
        char    curarea[STRSIZE];  /* current file area                     */
        char    curname[STRSIZE];  /* current file name                     */
        char    *tcp, *tcp1;       /* temporary character pointers          */
        char    *this_arg, tmp;
        double  x_offset=0.0, y_offset=0.0;
     
        argind = 1;
        while (argind < argc) {
                tcp = argv[argind];
                if (*tcp == '-') {
                        tmp = *++tcp;
                        switch (*tcp) {
                        case 'a':       /* a selects different pxl font area */
                                PXLpath = ++tcp;
                                break;
#ifdef IBM3812
                        case 'b':       /* first page from alternate casette */
                                FirstAlternate = TRUE;
                                break;
#endif
                        case 'c':       /* number of copies to print */
                                if ( sscanf(tcp + 1, "%hd", &ncopies) != 1 )
                               Fatal("Argument of -c is not a valid integer\n");
                                if (ncopies<1) {
                                  Warning("argument of -c < 1; set to 1!");
                                  ncopies=1;
                                }
                                break;
#ifdef DEBUG
                        case 'd':       /* d selects Debug output */
                                Debug = TRUE;
                                break;
#endif
                        case 'e':       /* emit file is specified */
                                EmitFileName = ++tcp;
                                /* delete trailing ':' (causing hangup) */
                                if (EmitFileName[strlen(EmitFileName)-1] ==
                                    ':')
                                        EmitFileName[strlen(EmitFileName)-1] =
                                            '\0';
                                break;
                        case 'f':       /* next arg is starting pagenumber */
                                if ( sscanf(tcp + 1, "%ld", &FirstPage) != 1 )
                                    Fatal("Argument is not a valid integer\n");
                                break;
#ifdef LJ
                        case 'g':       /* do not reset printer (go) */
                                ResetPrinter = FALSE;
                                break;
#endif
                        case 'h':     /* copy header file through to output  */
                                HeaderFileName = ++tcp;
                                G_header = TRUE;
                                break;
#ifdef SUPERCOMMENT
                        case 'i':   /* next arg is a PostScript file to copy */
                                if ( ++argind >= argc )
                                        Fatal("No argument following -i\n");
                                Ifile[nif++] = argv[argind];
                                break;
#endif
                        case 'x':       /* specify x-offset */
                                this_arg = 0;
                                if (!(*++tcp)) {
                                        this_arg = (++argind >= argc ?
                                            0 : argv[argind]);
                                } else {
                                        this_arg = tcp;
                                }
                                if (!this_arg
                                     || sscanf(this_arg,"%lf", &x_offset) != 1)
                 Fatal("Argument of -x is not a valid floating point number\n");
                                break;
                        case 'y':       /* specify y-offset */
                                this_arg = 0;
                                if (!(*++tcp)) {
                                        this_arg = (++argind >= argc ?
                                            0 : argv[argind]);
                                } else {
                                        this_arg = tcp;
                                }
                                if (!this_arg ||
                                     sscanf(this_arg, "%lf", &y_offset) != 1)
                Fatal("Argument of -y is not a valid floating point number\n");
                                break;
                        case 'X':       /* specify X-origin in dots */
                                this_arg = 0;
                                if (!(*++tcp)) {
                                        this_arg = (++argind >= argc ?
                                            0 : argv[argind]);
                                } else {
                                        this_arg = tcp;
                                }
                                if (!this_arg
                                     || sscanf(this_arg,"%hd", &x_origin) != 1)
                       Fatal("Argument of -X is not a valid integer\n");
                                break;
                        case 'Y':       /* specify Y-origin in dots */
                                this_arg = 0;
                                if (!(*++tcp)) {
                                        this_arg = (++argind >= argc ?
                                            0 : argv[argind]);
                                } else {
                                        this_arg = tcp;
                                }
                                if (!this_arg ||
                                     sscanf(this_arg, "%hd", &y_origin) != 1)
                       Fatal("Argument of -Y is not a valid integer\n");
                                break;
                        case 'm':       /* specify magnification to use */
                                switch ( (*++tcp) ) {
                                case '#':
                                     /* next arg is a magnification to use */
                                        if ( sscanf(tcp + 1, "%ld", &usermag)
                                             != 1 )
                             Fatal("Argument of mag is not a valid integer\n");
                                        break;
                                case '0':
                                        usermag = 1000;
                                        break;
                                case 'h':
                                case 'H':
                                        usermag = 1095;
                                        break;
                                case '1':
                                        usermag = 1200;
                                        break;
                                case 'q':
                                        usermag = 1250;
                                        break;
                                case '2':
                                        usermag = 1440;
                                        break;
                                case '3':
                                        usermag = 1728;
                                        break;
                                case '4':
                                        usermag = 2074;
                                        break;
                                case '5':
                                        usermag = 2488;
                                        break;
                                default:
                                        Fatal("%c is a bad mag step\n", *tcp);
                                }
                                break;
#ifdef SUPERCOMMENT
                        case 'o':     /* PostScript command to send */
                                if ( ++argind >= argc )
                                        Fatal("No argument following -o\n",
                                             0);
                                PScmd[nps++] = argv[argind];
                                break;
#endif
                        case 'p':       /* prohibits pre-font loading */
                                PreLoad = FALSE;
                                Reverse = FALSE;
                                       /* must then process in forward order */
                                break;
                        case 'q':       /* quiet operation */
                                G_quiet = TRUE;
                                break;
                        case 'r':       /* switch order to process pages */
                                Reverse = (bool)(!Reverse);
                                break;
                        case 't':       /* ending pagenumber */
                                if ( sscanf(tcp + 1, "%ld", &LastPage) != 1 )
                                    Fatal("Argument is not a valid integer\n");
                                break;
                        case 'v':    /* verbatim mode (print pxl-file names) */
                                G_noverbatim = FALSE;
                                break;
                        case 'w':       /* don't print out warnings */
                                G_nowarn = TRUE;
                                break;
                        default:
                                printf("%c is not a legal flag\n", *tcp);
                        }
                } else {
                        /*          tcp = rindex(argv[argind], '/');    */
                        tcp = strchr(argv[argind], '/');
                        /* split into directory + file name */
                        if (tcp == NULL)  {
                                curarea[0] = '\0';
                                tcp = argv[argind];
                        } else {
                                (void) strcpy(curarea, argv[argind]);
                                curarea[tcp-argv[argind]+1] = '\0';
                                tcp += 1;
                        }
     
                        (void) strcpy(curname, tcp);
                        /* split into file name + extension */
                        tcp1 = strchr(tcp, '.');
                        if (tcp1 == NULL) {
                                (void) strcpy(rootname, curname);
                                strcat(curname, ".dvi");
                        } else {
                                *tcp1 = '\0';
                                (void) strcpy(rootname, curname);
                                *tcp1 = '.';
                        }
     
                        (void) strcpy(filename, curarea);
                        (void) strcat(filename, curname);
     
                        if ((dvifp = BINOPEN(filename)) == NULL)  {
                                Fatal("%s: can't find DVI file \"%s\"\n\n",
                                                          G_progname, filename);
                        }
                }
                argind++;
        }
     
        x_goffset = (short) MM_TO_PXL(x_offset) + x_origin;
        y_goffset = (short) MM_TO_PXL(y_offset) + y_origin;
/*
printf("setting x_goffset to %hd, x_offset= %f, x_origin= %hd\n",
        x_goffset, x_offset, x_origin);
@EOF

chmod 666 dvilj.c-part1

exit 0
-- 
Michael Haberler		mah@hpuviea.uucp 
Hewlett-Packard Austria GmbH, 	...mcvax!tuvie!hpuviea!mah
Lieblgasse 1 			...hplabs!hpfcla!hpbbn!hpuviea!mah
A-1220 Vienna, Austria		Tel: (0043) (222) 2500 x412 (9-18 CET)