[comp.text] DVI-LaserJetII converter - Part 3 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:45 1989
#
# This archive contains:
#	dvilj.c-part2	
#

unset LANG

echo x - dvilj.c-part2
cat >dvilj.c-part2 <<'@EOF'
printf("setting y_goffset to %hd, y_offset= %f, y_origin= %hd\n",
        y_goffset, y_offset, y_origin);
*/
        if (dvifp == NULL)  {
          printf("\nThis is the DVI to %s converter version %s",
              PRINTER, VERSION);
          printf(" (%s)\n", OS);
          printf("usage: %s [OPTIONS] dvifile\n", G_progname);
     
          printf("OPTIONS are:\n");
          printf(
            "\t-aX ..... X= searchpath leading to pixel-files (.pk or .pxl)\n");
#ifdef IBM3812
          printf(
            "\t-b  ..... take paper for first page from alternate casette\n");
#endif
          printf("\t-cX ..... X= number of copies\n");
#ifdef DEBUG
          printf("\t-d  ..... turns debug output on\n");
#endif
          printf("\t-eX ..... X= outputfile\n");
          printf("\t-fX ..... print from begin of page number X\n");
#ifdef LJ
          printf("\t-g  ..... do not reset printer at begin of job (go)\n");
#endif
          printf("\t-hX ..... X= name of headerfile\n");
          printf("\t-mX ..... magnification X=0;h;1;2;3;4;5;#xxxx\n");
          printf("\t-p  ..... turn off font-description preload \n");
          printf("\t-q  ..... quiet operation\n");
          printf("\t-r  ..... process pages in reverse order\n");
          printf("\t-tX ..... print to end of page number X\n");
          printf("\t-w  ..... don't print out warnings\n");
          printf("\t-v  ..... tell user what pixel-files are used\n");
          printf("\t-xX ..... X= x-offset on printout in mm\n");
          printf("\t-yX ..... X= y-offset on printout in mm\n");
          printf("\t-XO ..... O= x page origin in dots (default=%d)\n",
                        XDEFAULTOFF );
          printf("\t-YO ..... O= y page origin in dots (default=%d)\n",
                        YDEFAULTOFF );
          exit(1);
        }
        if (EQ(EmitFileName, "")) {
                (void) strcpy(EmitFileName, curname);
                tcp1 = strchr(EmitFileName, '.');
                *tcp1 = '\0';
                strcat(EmitFileName, EMITFILE_EXTENSION);
        }
}
     
     
/*-->DoConv*/
/*********************************************************************/
/********************************  DoConv  ***************************/
/*********************************************************************/
long
DoConv(num, den, convResolution)
long    num, den;
int     convResolution;
{
        /*register*/ double conv;
        /* conv = ((double)den / (double)num) *
                    (1000.0 / (double)mag) *
                  (254000.0 / (double)convResolution) + 0.5; */
        conv = ((double)num / (double)den) *
                    ((double)mag / 1000.0) *
                  ((double)convResolution/254000.0);
     
        return((long) ((1.0/conv)+0.5));
}
     
     
/*-->DoSpecial*/
/*********************************************************************/
/*****************************  DoSpecial  ***************************/
/*********************************************************************/
typedef enum  {
        None, String, Integer, Number, Dimension}
     
     
ValTyp;
typedef struct {
        char    *Key;           /* the keyword string */
        char    *Val;           /* the value string */
        ValTyp  vt;             /* the value type */
        union {                 /* the decoded value */
                int     i;
                float   n;
        } v;
} KeyWord;
typedef struct {
        char    *Entry;
        ValTyp  Typ;
} KeyDesc;
#define PSFILE 0
#define ORIENTATION 1
KeyDesc KeyTab[] = {
        { "file", String },
        { "orientation", Integer} /*,
                         {"hsize", Dimension},
                         {"vsize", Dimension},
                         {"hoffset", Dimension},
                         {"voffset", Dimension},
                         {"hscale", Number},
                         {"vscale", Number}*/
     
     
};
     
     
#define NKEYS (sizeof(KeyTab)/sizeof(KeyTab[0]))
void
DoSpecial( str, n )
/* interpret a \special command, made up of keyword=value pairs */
char    *str;
int     n;
{
        char    spbuf[STRSIZE];
        char    *sf = NULL;
        KeyWord k;
        int     i, j;
#ifdef IBM3812
        str[n] = '\0';
        spbuf[0] = '\0';
        SetPosn(h, v);
        while ( (str = GetKeyStr(str, &k)) != NULL ) {
                /* get all keyword-value pairs */
                /* for compatibility, single words are taken as file names */
                if ( k.vt == None && access(k.Key, 0) == 0) {
                        if ( sf )
                                Warning(
                       "More than one \\special file name given. %s ignored",
                                     sf);
                        (void) strcpy(spbuf, k.Key);
                        sf = spbuf;
                        for (j = 1; !((sf[j] == '/' ? sf[j] = '\\' : sf[j])
                            == '\0'); j++)
                                ;
                } else if ( GetKeyVal( &k, KeyTab, NKEYS, &i ) && i !=
                    -1 )
                        switch (i) {
                        case PSFILE:
                                if ( sf )
                                        Warning(
                      "More than one \\special file name given. %s ignored",
                                                                sf);
                                (void) strcpy(spbuf, k.Val);
                                sf = spbuf;
                                for (j = 1; !((sf[j] == '/' ? sf[j] = '\\'
                                    : sf[j]) == '\0'); j++)
                                        ;
                                break;
                        case ORIENTATION:
                                if ((k.v.i >= 0) && (k.v.i < 4)) {
                                        last_ry = UNKNOWN;
                                        sprintf(PMPformat, "\322%c", (unsigned
                                            char)k.v.i);
                                        PMPout(2, PMPformat);
                                } else
                                        Warning(
                                   "Invalid orientation (%d)given; ignored.",
                                                                        k.v.i);
                                break;
                        default:
                                Warning("Can't handle %s=%s command; ignored.",
                                                                    k.Key,
                                    k.Val);
                                break;
                        }
                else
                        Warning(
                     "Invalid keyword or value in \\special - <%s> ignored",
                                               k.Key );
        }
        if ( sf ) {
                last_ry = UNKNOWN;
                PMPflush;
                CopyFile( sf );
        }
#endif
#ifdef LJ
        Warning("'\\special'commands are not implemented for this printer");
        return;
#endif
}
     
     
/*-->EmitChar*/
/**********************************************************************/
/****************************  EmitChar  ******************************/
/**********************************************************************/
void                                     /* output a character bitmap */
EmitChar(c, ce)
long    c;
struct char_entry *ce;
{
        register int    i;
        register unsigned char  *sl;
        unsigned short  nbpl, nwpl;
        long    total;
     
        if ( fontptr->ncdl == 0 ) {
#ifdef IBM3812
                used_fontstorage += 1028;
#endif
#ifdef LJ
                /* open font dict before first char, set active font */
                EMIT(outfp, "\033*c%dD\033)s26W", fontptr->plusid);
                EMITB(20, "\0\032\0\1\0\0\0\310\0\377\0\377\0\1\1\025\0\4\0\4");
                EMITB(6, "\0\0\0\0\0\0");
                EMIT(outfp, "\033*c4F");
#endif
        }
        if ( fontptr != prevfont ) {   /* because this isn't done on pass 0 */
#ifdef LJ
                EMIT(outfp, "\033(%dX", fontptr->plusid);
#endif
                prevfont = fontptr;
        }
     
        if (fontptr->id == pk89)   {
                nbpl = ((ce->width) +  7) >> 3;
                total = (long)ce->height * nbpl;
        } else if (fontptr->id == id1002)   {
                nbpl = ((ce->width) +  7) >> 3;
                total = (long)ce->height * nbpl;
        } else if (fontptr->id == id1001) {
                nwpl = ((ce->width) + 31) >> 5;
                nbpl = ((ce->width) + 7) >> 3;
                total = (long)ce->height * nbpl;
        }
     
        /***************************************************************/
        /*if ( ((char) c == 'a') && (fontptr->plusid == 8)) {          */
        /*        printf("cols=%ld, ncols=%ld\n",nwpl,nbpl);           */
        /*                                                             */
        /*        printf("%ld Bytes:->",total);                        */
        /*        for (j=0; j<total;j++) {                             */
        /*                char *ch; char ic;                           */
        /*                ch=(char *)(ce->where.address.pixptr);       */
        /*                ic=*(ch+j);                                  */
        /*                printf("%X.",ic);                            */
        /*                    }                                        */
        /*        printf("<- Now Emitting\n");                         */
        /*        }                                                    */
        /***************************************************************/
     
        if ((short)(ce->height) - ce->yOffset > 55) {
                ce->yyOffset = (short) ce->height - ce->yOffset;
                ce->yOffset  = (short) ce->height;
        } else {
                ce->yyOffset = (short) 0;
        }
        /* ce->cw = (long)(((double)ce->tfmw / (double)hconv) +0.5); */
        /* set active font to nn, load font pattern  xx ... */
     
#ifdef IBM3812
        PMPcont(total + 9);
        sprintf(PMPformat, "\323%c\360%c%c%c",
            (unsigned char)fontptr->plusid,
            (unsigned char)VisChar((char)c),
            (unsigned char)ce->height,
            (unsigned char)ce->width);
        PMPout(6, PMPformat);
        PMPoutC((char)(-(ce->xOffset)));
        PMPoutC((char)(ce->cw - (-ce->xOffset + ce->width)));
        PMPoutC((char)(ce->yOffset));
#endif
#ifdef LJ
        EMIT(outfp, "\033*c%dd%dE\033(s%ldW", fontptr->plusid,
            (unsigned int)VisChar((char)c), (long)(total + 16));
        EMITB(6, "\4\0\016\1\0\0");
        EMITWORD(-ce->xOffset);
        EMITWORD(ce->yOffset);
        EMITWORD(ce->width);
        EMITWORD(ce->height);
        EMITWORD((int)ce->cw * 4);
#endif
        if (fontptr->id == pk89)
                PkRaster(ce, FALSE);
        else if (fontptr->id == id1002)
                for (i = 0; i < (int) ce->height; i++) {
                        sl = ((unsigned char *)(ce->where.address.pixptr) +
                            i * nbpl);
                        EMITL(nbpl, sl);
                }
        else if (fontptr->id == id1001)
                for (i = 0; i < (int) ce->height; i++) {
                        sl = (unsigned char *)(ce->where.address.pixptr +
                            i * nwpl);
                        EMITL(nbpl, sl);
                }
#ifdef IBM3812
        used_fontstorage += (long)ce->height * ((ce->width + 15) >> 4)
            *2 + 14;
#endif
        fontptr->ncdl += 1;
}
     
     
/*-->RasterLine*/
/**********************************************************************/
/****************************  RasterLine  ****************************/
/**********************************************************************/
void
RasterLine(ce, nbpl, current_line, buffer)
struct char_entry *ce;
unsigned short  nbpl, current_line;
char    *buffer;
{
#ifdef IBM3812
        long    total;
        static unsigned short   maxlines;
     
        if (current_line == 0) {
                maxlines = ce->height;
     
                MoveVert(-ce->yOffset);      /* move cursor up */
                MoveHor(-ce->xOffset);       /* move cursor right */
                last_ry = UNKNOWN;           /* next time full positioning */
        }
     
        if (current_line % maxlines == 0) {
                if (current_line > 0) {    /* maxlines lines have been printed*/
                        MoveVert(maxlines);   /*   move cursor down         */
                        last_ry = UNKNOWN;    /* next time full positioning */
                }
                total = (long)(ce->height - current_line) * (long)nbpl;
                if ((total + 9) > 65535) {
                        maxlines = (unsigned short)((65535 - 9) / nbpl);
                        total = (long)maxlines * (long)nbpl;
                }
     
                PMPcont(total + 9);
                PMPout(2, "\365\0");
                EMITWORD(maxlines);
                EMITWORD(ce->width);
                PMPoutC((unsigned char) (total >> 16) & 0xFF);
                PMPoutC((unsigned char) (total >> 8 ) & 0xFF);
                PMPoutC((unsigned char)  total     & 0xFF);
        }
        EMITL((int)nbpl, buffer);
#endif
#ifdef LJ
        register int    emitbytes;
     
        for (emitbytes = (int)nbpl;
            (*(buffer + emitbytes - 1) == '\0') && (emitbytes > 0);
            emitbytes--)
                ;
        EMIT(outfp, "\033*b%dW", emitbytes);
        EMITL(emitbytes, buffer);
#endif
}
     
     
/*-->RasterChar*/
/**********************************************************************/
/****************************  RasterChar  ****************************/
/**********************************************************************/
void                                     /* raster a character bitmap */
RasterChar(c, ce)
long    c;
struct char_entry *ce;
{
        int     i;
        register unsigned char  *sl;
        unsigned short  nbpl, nwpl;
        unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
     
#ifdef DEBUG
        if (Debug)
                printf("Raster character <%c>... \n", (char) c);
#endif
     
     
        if (fontptr->id == pk89)   {
                nbpl = ((ce->width) +  7) >> 3;
        } else if (fontptr->id == id1002)   {
                nbpl = ( ce->width +  7) >> 3;
        } else if (fontptr->id == id1001) {
                nwpl = ( ce->width + 31) >> 5;
                nbpl = ( ce->width + 7) >> 3;
        }
     
#ifdef LJ
        EMIT(outfp, "\033*t300R\033*r1A");
#endif
     
        if (ce->charsize == HUGE_SIZE) { /* read pixel from file */
                OpenFontFile();
                fseek(pxlfp, ce->where.address.fileOffset, 0);
        }
     
        if (fontptr->id == pk89)
                PkRaster(ce, TRUE);
        else if (fontptr->id == id1002) {
                for (i = 0; i < (int) ce->height; i++) {
                        if (ce->charsize == HUGE_SIZE) {
                                fread(raster_line_buf, 1, (int) nbpl ,
                                    pxlfp);
                                sl = raster_line_buf;
                        } else
                                sl =
                                   ((unsigned char *)(ce->where.address.pixptr)
                                    + i * nbpl);
     
                        RasterLine(ce, (unsigned int)nbpl, i, sl);
                }
        } else if (fontptr->id == id1001) {
                long    filediff;
                filediff = (long)nwpl * 4 - nbpl;
                for (i = 0; i < (int) ce->height; i++) {
                        if (ce->charsize == HUGE_SIZE) {
                                fread(raster_line_buf, 1, (int) nbpl ,
                                    pxlfp);
                                /* skip fill bytes */
                                fseek(pxlfp, filediff, 1);
                                sl = raster_line_buf;
                        } else
                                sl =
                                    (unsigned char *)(ce->where.address.pixptr +
                                    i * nwpl);
     
                        RasterLine(ce, (unsigned int)nbpl, i, sl);
                }
        }
#ifdef LJ
        EMIT(outfp, "\033*rB");
#endif
        last_ry = UNKNOWN;
}
     
     
/*-->Fatal*/
/**********************************************************************/
/******************************  Fatal  *******************************/
/**********************************************************************/
void
Fatal(fmt, a, b, c)      /* issue a fatal error message */
char    *fmt;               /* format                      */
char    *a, *b, *c;         /* arguments                   */
{
        fprintf(stderr, "\n");
        fprintf(stderr, "%s: FATAL--", G_progname);
        fprintf(stderr, fmt, a, b, c);
        fprintf(stderr, "\n\n");
        exit(2);
}
     
     
/*-->FindPostAmblePtr*/
/**********************************************************************/
/************************  FindPostAmblePtr  **************************/
/**********************************************************************/
void
FindPostAmblePtr(postambleptr)
long    *postambleptr;
/* this routine will move to the end of the file and find the start
    of the postamble */
{
        long    i;
        fseek (dvifp,  0l, 2);   /* goto end of file */
        *postambleptr = ftell (dvifp) - 4;
        fseek (dvifp, *postambleptr, 0);
        while (TRUE) {
                fseek (dvifp, --(*postambleptr), 0);
                if (((i = NoSignExtend(dvifp, 1)) != 223) &&
                    (i != DVIFORMAT))
                        Fatal ("Bad end of DVI file");
                if (i == DVIFORMAT)
                        break;
        }
        fseek (dvifp, (*postambleptr) - 4, 0);
        (*postambleptr) = NoSignExtend(dvifp, 4);
        fseek (dvifp, *postambleptr, 0);
}
     
     
/*-->GetBytes*/
/**********************************************************************/
/*****************************  GetBytes  *****************************/
/**********************************************************************/
void
GetBytes(fp, cp, n)         /* get n bytes from file fp */
/*register*/ FILE *fp;      /* file pointer  */
register char   *cp;        /* character pointer */
int     n;                    /* number of bytes  */
{
        while (n--)
                *cp++ = (char)getc(fp);
}
     
     
/*-->GetFontDef*/
/**********************************************************************/
/**************************** GetFontDef  *****************************/
/**********************************************************************/
void
GetFontDef()
/***********************************************************************
   Read the font  definitions as they  are in the  postamble of the  DVI
   file.
***********************************************************************/
{
        unsigned char   byte;
        while (((byte = (unsigned char) NoSignExtend(dvifp, 1)) >= FNT_DEF1) &&
            (byte <= FNT_DEF4)) {
                switch (byte) {
                case FNT_DEF1:
                        ReadFontDef ( NoSignExtend(dvifp, 1));
                        break;
                case FNT_DEF2:
                        ReadFontDef ( NoSignExtend(dvifp, 2));
                        break;
                case FNT_DEF3:
                        ReadFontDef ( NoSignExtend(dvifp, 3));
                        break;
                case FNT_DEF4:
                        ReadFontDef ( NoSignExtend(dvifp, 4));
                        break;
                default:
                        Fatal ("Bad byte value in font defs");
                        break;
                }
        }
        if (byte != POST_POST)
                Fatal ("POST_POST missing after fontdefs");
}
     
     
#ifdef IBM3812
/*-->GetKeyStr*/
/**********************************************************************/
/*****************************  GetKeyStr  ****************************/
/**********************************************************************/
/* extract first keyword-value pair from string (value part may be null)
 * return pointer to remainder of string
 * return NULL if none found
 */
char    KeyStr[STRSIZE];
char    ValStr[STRSIZE];
char
*GetKeyStr( str, kw )
char    *str;
KeyWord *kw;
{
        char    *s, *k, *v, t;
        if ( !str )
                return( NULL );
        for ( s = str; *s == ' '; s++)
                ;                  /* skip over blanks */
        if ( *s == '\0' )
                return( NULL );
        for ( k = KeyStr; /* extract keyword portion */
        *s != ' ' && *s != '\0' && *s != '=';
            *k++ = *s++)
                ;
        *k = '\0';
        kw->Key = KeyStr;
        kw->Val = v = NULL;
        kw->vt = None;
        for ( ; *s == ' '; s++)
                ;                        /* skip over blanks */
        if ( *s != '=' )                 /* look for "=" */
                return( s );
        for ( s++; *s == ' '; s++);      /* skip over blanks */
        if ( *s == '\'' || *s == '\"' )  /* get string delimiter */
                t = *s++;
        else
                t = ' ';
        for ( v = ValStr; /* copy value portion up to delim */
        *s != t && *s != '\0';
            *v++ = *s++)
                ;
        if ( t != ' ' && *s == t )
                s++;
        *v = '\0';
        kw->Val = ValStr;
        kw->vt = String;
        return( s );
}
     
     
/*-->GetKeyVal*/
/**********************************************************************/
/*****************************  GetKeyVal  ****************************/
/**********************************************************************/
/* get next keyword-value pair decode value according to table entry  */
bool
GetKeyVal( kw, tab, nt, tno)
KeyWord *kw;
KeyDesc tab[];
int     nt;
int     *tno;
{
        int     i;
        char    c = '\0';
        *tno = -1;
        for (i = 0; i < nt; i++)
                if ( IsSame(kw->Key, tab[i].Entry) ) {
                        *tno = i;
                        switch ( tab[i].Typ ) {
                        case None:
                                if ( kw->vt != None )
                                        return( FALSE );
                                break;
                        case String:
                                if ( kw->vt != String )
                                        return( FALSE );
                                break;
                        case Integer:
                                if ( kw->vt != String )
                                        return( FALSE );
                                if ( sscanf(kw->Val, "%d%c",
                                    &(kw->v.i), &c) != 1
                                     || c != '\0' )
                                        return( FALSE );
                                break;
/*                      case Number:
 *                      case Dimension:
 *                              if( kw->vt != String ) return( FALSE );
 *                              if( sscanf(kw->Val,"%f%c",
 *                                         &(kw->v.n), &c) != 1
 *                                  || c != '\0' ) return( FALSE );
 *                              break;
 */
                        }
                        kw->vt = tab[i].Typ;
                        return( TRUE );
                }
        return( TRUE );
}
     
     
#endif
/*-->HasBeenRead*/
/**********************************************************************/
/***************************  HasBeenRead  ****************************/
/**********************************************************************/
bool
HasBeenRead(k)
long    k;
{
        struct font_entry *ptr;
        ptr = hfontptr;
        while ((ptr != NULL) && (ptr->k != k))
                ptr = ptr->next;
        return((bool)(ptr != NULL));
}
     
     
/*-->IsSame*/
/**********************************************************************/
/*******************************  IsSame  *****************************/
/**********************************************************************/
bool                                  /* compare strings, ignore case */
IsSame(a, b)
char    *a, *b;
{
        char    *x, *y;
        x = a;
        y = b;
        for ( ; *a != '\0'; )
                if ( tolower(*a++) != tolower(*b++) )
                        return( FALSE );
        return( *x == *y ? TRUE : FALSE );
}
     
     
/*-->NoSignExtend*/
/**********************************************************************/
/***************************  NoSignExtend  ***************************/
/**********************************************************************/
long
NoSignExtend(fp, n)     /* return n byte quantity from file fd */
register FILE *fp;      /* file pointer    */
register int    n;      /* number of bytes */
{
        long    x;      /* number being constructed */
        x = 0;
        while (n--)  {
                x <<= 8;
                x |= getc(fp);
        }
        return(x);
}
     
     
/*-->OpenFontFile*/
/**********************************************************************/
/************************** OpenFontFile  *****************************/
/**********************************************************************/
void
OpenFontFile()
/***********************************************************************
    The original version of this dvi driver reopened the font file  each
    time the font changed, resulting in an enormous number of relatively
    expensive file  openings.   This version  keeps  a cache  of  up  to
    MAXOPEN open files,  so that when  a font change  is made, the  file
    pointer, pxlfp, can  usually be  updated from the  cache.  When  the
    file is not found in  the cache, it must  be opened.  In this  case,
    the next empty slot  in the cache  is assigned, or  if the cache  is
    full, the least used font file is closed and its slot reassigned for
    the new file.  Identification of the least used file is based on the
    counts of the number  of times each file  has been "opened" by  this
    routine.  On return, the file pointer is always repositioned to  the
    beginning of the file.
***********************************************************************/
{
        int     i, least_used, current;
        struct pixel_list tmp;   /* gustaf */
     
#ifdef DEBUG
        if (Debug)
                printf("open font file\n");
#endif
        if (pfontptr == fontptr)
                return;                 /* we need not have been called */
     
       if (fontptr->font_file_id == NO_FILE)
                return;                 /* we need not have been called */
     
        tmp = pixel_files[1];
        for (current = 1;
            (current <= nopen) &&
            (tmp.pixel_file_id != fontptr->font_file_id); ) {
                ++current;
                tmp = pixel_files[current];
        }
        /* try to find file in open list */
     
        if (current <= nopen)       /* file already open */ {
                if ( (pxlfp = pixel_files[current].pixel_file_id) != NO_FILE )
                        fseek(pxlfp, 0l, 0);
                        /* reposition to start of file */
        } else {
                        /* file not in open list                  */
                if (nopen < MAXOPEN)    /* just add it to list    */
                        current = ++nopen;
                else  {
                        /* list full -- find least used file,     */
                        /* close it, and reuse slot for new file  */
                        least_used = 1;
                        for (i = 2; i <= MAXOPEN; ++i)
                                if (pixel_files[least_used].use_count >
                                    pixel_files[i].use_count)
                                        least_used = i;
                        if (pixel_files[least_used].pixel_file_id != NO_FILE) {
                                FILE * fid;
                                struct font_entry *fp;
                                fid = pixel_files[least_used].pixel_file_id;
                                /* mark file as being closed in the entry */
                                fp = hfontptr;
                                while (fp != NULL && fp->font_file_id !=
                                    fid)
                                        fp = fp->next;
                                if (fp == NULL)
                           Fatal("Open file %x not found in font entry list.\n",
                                             fid);
                                else {
                                        fp->font_file_id = NULL;
                                }
                                fclose( fid );
                        }
#ifdef DEBUG
                        if (Debug)
                                printf("\n__reuse slot %d\n", least_used);
#endif
                        current = least_used;
                }
                if ((pxlfp = BINOPEN(fontptr->name)) == NULL) {
                        Warning("PXL-file %s could not be opened",
                              fontptr->name);
                        pxlfp = NO_FILE;
                } else {
#ifdef DEBUG
                     if (Debug) printf(
                         "Opening File  <%s> /%x/, Size(font_entry)=%d\n",
                          fontptr->name, pxlfp, sizeof(struct font_entry ));
#endif
                }
                pixel_files[current].pixel_file_id = pxlfp;
                pixel_files[current].use_count = 0;
        }
        pfontptr = fontptr;                 /* make previous = current font */
        fontptr->font_file_id = pxlfp;      /* set file identifier */
        pixel_files[current].use_count++;   /* update reference count */
}
     
     
/*-->PixRound*/
/**********************************************************************/
/*****************************  PixRound  *****************************/
/**********************************************************************/
long
PixRound(x, conv)       /* return rounded number of pixels */
long    x;              /* in DVI units     */
long    conv;           /* conversion factor */
{
    /*    return((long)((((double)x + (double)(conv >> 1)) / (double)conv)
            + 0.5)); */
        return((x + conv) / conv);
}


/*-->Warning*/
/**********************************************************************/
/*****************************  Warning  ******************************/
/**********************************************************************/
void                                               /* issue a warning */
Warning(fmt, a, b, c, d)
char    *fmt;             /* format    */
char    *a, *b, *c, *d;   /* arguments */
{
        G_errenc = 1;
        if ( G_nowarn || G_quiet )
                return;
     
        printf("warning : ");
        printf(fmt, a, b, c, d);
        printf("\n");
}
     
     
void
PutWord(w)
int     w;
{
        EMITC((char)(w >> 8) & 0xff);
        EMITC((char)w & 0xff);
}
     
     
#define VIS   33
#define VIS2  (VIS+32)
unsigned char
VisChar(c)
unsigned char   c;
{
        c &= 0xff;
        if (c < VIS)
                return ((unsigned char)(160 + c));
        if (c < 128)
                return (c);
        if (c < (255 - VIS2))
                return ((unsigned char)(VIS2 + c));
        return (255);
}
     
     
#ifdef IBM3812
/*-->PMPout*/
/*****************************************************************************/
/* This routine produces the PMP-envelopes for the 3812. Its semantics are:
     
   first arg == 0  ... flush buffer
   first arg == -1 ... number of bytes specified in the second argument
                       have to be continuous, that is they must not
                       be disrupted by ENTER PMP etc.
   first arg > 0       output first arg bytes
     
                       If arg2 > OUTBUFSIZE ... flush buffer,
                                                switch to unbuffered mode
                                                (dont't collect PMP commands)
                       If arg2+bufferpointer > OUTBUFSIZE ... flush buffer,
                                                block will fit into buffer
                       otherwise ..... block will fit into buffer
     
  Buffering is done to reduce the ENTER PMP-commands. Initially
  the 3812 is in PC-ASCII mode. In order to issue a PMP-command it is
  necessary to enter PMP mode. The ENTER-PMP-command contains the
  number of bytes that will be interpreted as PMP-commands. In the
  most naive approach for each primitive command (eg. set cursor) you
  have to produce a seperate ENTER-PMP-envelope (5 bytes). It is
  favourable to collect as many PMP commands as possible in one envelope. */
/*****************************************************************************/
void
PMPout(l, s)
char    *s;
int     l;
{
        static char     buffer[OUTBUFSIZE];
        static unsigned short   bp = 0;             /* range 0..OUTBUFSIZE */
        static long     continuous = 0l;
        static bool buffered = TRUE;
     
        if (l == 0) {
                if (bp == 0)
                        return;
                EMIT(outfp, "\033[C%c%c", (unsigned char)(bp & 0xFF),
                    (unsigned char)(bp >> 8));
                EMITB((int)bp, buffer);
                bp = 0;
                return;
        }
        if (l == -1) {
                continuous = (long)s;
                if (continuous + (long)bp + 5l > (long) OUTBUFSIZE)
                        PMPflush;
                buffered = (bool) ((continuous + 5l <= (long) OUTBUFSIZE));
                if (!buffered) {
                        EMIT(outfp, "\033[C%c%c",
                            (unsigned char)(continuous & 0xFF),
                            (unsigned char)((continuous >> 8) & 0xFF));
                }
                return;
        }
        if (buffered) {
                register int    i;
                if ( ((long)l + bp) > OUTBUFSIZE)
                        PMPflush;
                for (i = 0; i < l; i++)
                        buffer[bp+i] = s[i];
                bp += (unsigned short)l;
        } else {
                EMITB((int)l, s);
                buffered = (bool) ((continuous -= (long)l) <= 0) ;
        }
}
     
     
void
PMPoutC(c)
char    (c);
{
        PMPout(1, &c);
}
     
     
#endif
#ifndef unix
/*-->AssureBinary*/
/**********************************************************************/
/*************************** AssureBinary *****************************/
/**********************************************************************/
/* This procedure is both DOS AND MSC dependent. The MSC file open on */
/* a device ignores the 'binary' of the "wb" parameter and opens the  */
/* file in ascii mode. This procedure sets the file f to binary mode  */
/* if it is connected to a device that is not console input or output */
/* or the null device. For other operating systems this routine is    */
/* useless. (Background: MSDOS 3.2 Technical Reference upd 1 pg 6-137 */
/**********************************************************************/
void
AssureBinary(f)
FILE *f;
{
        union REGS regs;                      /* registers for bios call */
     
        regs.h.ah = (unsigned char) 0x44;     /* IOCTL                    */
        regs.h.al = (unsigned char) 0x00;     /* get device information   */
        regs.x.bx = (unsigned int) fileno(f); /* handle from MSC          */
        intdos(&regs, &regs);                 /* call DOS interrupt       */
                                              /* ---> result in DX        */
     
        if (  (regs.h.dl & 0x80)         /* file handle points to a device */
             && !(regs.h.dl & 0x07) )    /* neither console i/o or null    */ {
     
                regs.h.dl  |= 0x20;      /* set BINARY bit in device info  */
     
                regs.h.ah = (unsigned char) 0x44;    /* IOCTL                 */
                regs.h.al = (unsigned char) 0x01;    /* set device information*/
                regs.x.bx = (unsigned int) fileno(f); /* handle from MSC      */
                regs.h.dh = (unsigned char) 0x00;    /* clear DH              */
                intdos(&regs, &regs);               /* call DOS interrupt     */
        }
}
     
     
#endif
     
bool getbit ();
unsigned char   getnyb ();
long    pk_packed_num ();
     
     
#define  PKBYTE   *pkloc; pkloc ++
#define  OUTCHAR(c) raster_line_buf[bp]= (unsigned char)c; bp++
     
unsigned char   bitweight, inputbyte ;
unsigned char   dyn_f ;
unsigned char   *pkloc;
int     repeatcount;
     
void                      /* <Read and translate raster description@>*/
PkRaster(ce, raster)
struct char_entry *ce;
bool raster;
{
        int     rp;
        int     current_line;
        int     wordwidth ;
        bool turnon;
        unsigned short  nbpl;
        long    rowsleft, word, wordweight, hbit, count, i, j, tl;
        long    row[101] ;
        unsigned char   raster_line_buf[BYTES_PER_PIXEL_LINE];
        unsigned short  bp;
     
        if (ce->charsize == HUGE_SIZE)
                Fatal(
                  "cannot process currently PK font patterns of that size!\n");
     
        current_line = 0;
        pkloc = (unsigned char *)ce->where.address.pixptr;
        dyn_f = (unsigned char)(ce->flag_byte >> 4);
        turnon = (bool)((ce->flag_byte & 8) == 8);
        wordwidth = (int)(ce->width + 31) >> 5 ;
        nbpl = ((ce->width) +  7) >> 3;
     
        bitweight = 0 ;
        if (dyn_f == 14) {
            /*printf("<Get raster by bits@>\n");*/
            for (i = 1; i <= (long)ce->height; i++) {
                word = 0 ;
                wordweight = 31 ;
     
                /* printf("     |"); */
                for (j = 1; j <= (long) ce->width; j++) {
                    bool getbit;
                    bp = 0;
/*******************************************begin Getbit *********/
                    bitweight /= 2 ;
                    if ( bitweight == 0 ) {
                            inputbyte = PKBYTE ;
                            bitweight = 128 ;
                    }
                    getbit = (bool)
                         ( inputbyte >= bitweight ) ;
                    if ( getbit )
                            inputbyte -= bitweight ;
/*********************************************end Getbit *********/
     
                    if (getbit)
                            word += power[wordweight] ;
     
                    wordweight --;
                    if (wordweight == -1) {
/*
 * { int k;
 *   for (k=31; k>=0; k--) {
 *       if ((power[k] & word)!=0) printf("M");
 *       else printf(".");
 *   }
 * }
 */
                        OUTCHAR((word >> 24 & 0xFF));
                        OUTCHAR((word >> 16 & 0xFF));
                        OUTCHAR((word >> 8 & 0xFF));
                        OUTCHAR((word    & 0xFF));
     
                        word = 0 ;
                        wordweight = 31 ;
                    }
                }
                if (wordweight < 31) {
/*
 * { int k;
 *   for (k=31; k>=0; k--) {
 *      if ((power[k] & word)!=0) printf("M");
 *      else printf(".");
 *   }
 *  }
 *  printf("|\n ----|");
 */
                    for (j = 3; j >= (wordwidth * 4 - (long)nbpl);
                        j--) {
     
                            OUTCHAR(((word >> (j << 3)) & 0xff));
/*
 * { int k;
 *   for (k=7; k>=0; k--) {
 *      if ((power[k] & temp)!=0) printf("M");
 *      else printf(".");
 *   }
 * }
 */
                    }
                }
     
                if (raster) {
                        RasterLine(ce, (unsigned int)nbpl,
                            current_line, raster_line_buf);
                        current_line++;
                } else
                        EMITL(bp, raster_line_buf);
     
                /*  printf("|\n");*/
            }
        } else {
            /* printf("@<Create normally packed raster@>\n"); */
            rowsleft = (long) ce->height ;
            hbit = (long) ce->width ;
            repeatcount = 0 ;
            wordweight = 32 ;
            word = 0 ;
            rp = 1 ;
            while ( rowsleft > 0 ) {
                count = pk_packed_num() ;
                bp = 0;
     
@EOF

chmod 666 dvilj.c-part2

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)