/* -*-C-*- dvijet.c */
/*-->dvijet*/
/**********************************************************************/
/******************************* dvijet *******************************/
/**********************************************************************/

#include "dvihead.h"

/**********************************************************************/
/************************  Device Definitions  ************************/
/**********************************************************************/

/* All output-device-specific definitions go here.  This section must
be changed when modifying a dvi driver for use on a new device */

#undef HPLASERJET
#define  HPLASERJET       1             /* conditional compilation flag */

#define VERSION_NO      "2.10"          /* DVI driver version number */

#define  DEVICE_ID      "Hewlett-Packard 2686A Laser Jet laser printer"
                                /* this string is printed at runtime */

#define OUTFILE_EXT     "jet"

#define  DEFAULT_RESOLUTION 300         /* default dots/inch on HP Laser Jet */

#define  BYTE_SIZE        8             /* output file byte size */

#undef STDRES
#define STDRES  0                       /* 0 for low-resolution devices */

#define  XDPI           300             /* HP DeskJet horizontal dots/inch */
#define  XPSIZE         8               /* horizontal paper size in inches */

#define  XSIZE          (((XDPI*XPSIZE+2*HOST_WORD_SIZE-1)/\
                                (2*HOST_WORD_SIZE))*(2*HOST_WORD_SIZE))
                                        /* number of horizontal dots; */
                                        /* MUST BE multiple of */
                                        /* 2*HOST_WORD_SIZE */
#define  XWORDS         ((XSIZE + HOST_WORD_SIZE - 1)/HOST_WORD_SIZE)
                                        /* number of words in rows  */
                                        /* of bitmap array */

#define  YDPI           300             /* HP DeskJet vertical dots/inch */

#define  YPSIZE         11              /* vertical paper size in inches */
#define  YSIZE          (YDPI*YPSIZE)   /* number of vertical dots */

/* The printer bit map (must have an even number of columns). */

#define XBIT ((1+2*XWORDS)/2)
#define YBIT YSIZE
#if    (IBM_PC_LATTICE | IBM_PC_MICROSOFT | IBM_PC_WIZARD)
#undef SEGMEM
#define SEGMEM 1 /* ( ((long)XBIT * (long)YBIT) > 65536L ) */
#endif

#include "bitmap.h"

#include "main.h"
#include "abortrun.h"
#include "actfact.h"
#include "alldone.h"
#include "chargf.h"
#include "charpk.h"
#include "charpxl.h"
#include "clrbmap.h"
#include "clrrow.h"
#include "dbgopen.h"

/*-->devinit*/
/**********************************************************************/
/****************************** devinit *******************************/
/**********************************************************************/

void
devinit(argc,argv)              /* initialize device */
int argc;
char *argv[];
{
    (void)getbmap();
    OUTF("\033E\033*t%dR",(int)hpres);  /* printer reset, resolution */
}

/*-->devterm*/
/**********************************************************************/
/****************************** devterm *******************************/
/**********************************************************************/

void
devterm()                       /* terminate device */
{
}

#include "dvifile.h"
#include "dviinit.h"
#include "dviterm.h"
#include "dispchar.h"
#include "f20open.h"
#include "fatal.h"
#include "fillrect.h"
#include "findpost.h"
#include "fixpos.h"
#include "fontfile.h"
#include "fontsub.h"
#include "getbmap.h"
#include "getbytes.h"
#include "getfntdf.h"
#include "getpgtab.h"
#include "initglob.h"
#include "inch.h"
#include "loadchar.h"
#include "movedown.h"
#include "moveover.h"
#include "moveto.h"
#include "nosignex.h"
#include "openfont.h"
#include "option.h"

/*-->outline*/
/**********************************************************************/
/****************************** outline *******************************/
/**********************************************************************/

void
outline(pbit)
UNSIGN32 *pbit;                         /* pointer to raster line */

/*************************************************************************
Use machine-specific coding here for efficiency.  For TOPS-20, we encode
9 bytes from every pair  of 36-bit words.

For each raster line on the paper, the Laser Jet expects a binary  8-bit
byte stream of the form

    <ESC>*bnnnWxxxxxxx ... xxxxxxx
               <--- nnn bytes --->

where each byte contains, in order from high to low bit, a left-to-right
bit pattern.  No  end-of-line marker  is required;  the escape  sequence
automatically causes a new raster line to be started.
*************************************************************************/

{
    register UNSIGN32 w_even,w_odd;
    register UNSIGN32 *p;
    register BYTE *pbuf;
    BYTE buf[1+(XSIZE+7)/8];            /* space for EOS + n 8-bit bytes */
    register INT16 i,last_word;


#if    (IBM_PC_MICROSOFT & !OS_IBMOS2)
    for (last_word = XBIT - 1;
        (last_word >= 1) && (*(UNSIGN32*)normaddr(pbit,last_word) == 0);
        --last_word)
        ;                               /* trim white space a word at a time */
#else
    p = pbit + XBIT - 1;                /* point to last word on line */
    for (last_word = XBIT - 1; (last_word >= 1) && (*p == 0); --last_word)
        --p;                            /* trim white space a word at a time */
#endif

    p = pbit;
    pbuf = &buf[0];
    for (i = 0; i <= last_word; i += 2) /* loop over trimmed raster */
    {
        w_even = (*p++);
        w_odd = (*p++);

#if    (HOST_WORD_SIZE == 36)
        *pbuf++ = (BYTE)( (w_even >> 28) & 0xff);
        *pbuf++ = (BYTE)( (w_even >> 20) & 0xff);
        *pbuf++ = (BYTE)( (w_even >> 12) & 0xff);
        *pbuf++ = (BYTE)( (w_even >>  4) & 0xff);
        *pbuf++ = (BYTE)( ((w_even <<  4) | (w_odd >> 32)) & 0xff);
        *pbuf++ = (BYTE)( (w_odd  >> 24) & 0xff);
        *pbuf++ = (BYTE)( (w_odd  >> 16) & 0xff);
        *pbuf++ = (BYTE)( (w_odd  >>  8) & 0xff);
        *pbuf++ = (BYTE)( (w_odd       ) & 0xff);
#else /* HOST_WORD_SIZE == 32 */
        /* encode 8 bytes at a time on 32-bit machines */
        *pbuf++ = (BYTE)( (w_even >> 24) & 0xff);
        *pbuf++ = (BYTE)( (w_even >> 16) & 0xff);
        *pbuf++ = (BYTE)( (w_even >>  8) & 0xff);
        *pbuf++ = (BYTE)( (w_even      ) & 0xff);
        *pbuf++ = (BYTE)( (w_odd  >> 24) & 0xff);
        *pbuf++ = (BYTE)( (w_odd  >> 16) & 0xff);
        *pbuf++ = (BYTE)( (w_odd  >>  8) & 0xff);
        *pbuf++ = (BYTE)( (w_odd       ) & 0xff);
#endif

    }

    *pbuf = '\0';                       /* trailing EOS marker */

    last_word |= 1;                     /* make last_word ODD */
    for (i = ((last_word+1)*HOST_WORD_SIZE)/8;
        (*(--pbuf) == '\0') && (i > 1); --i)
        ;       /* trim trailing zero bytes, leaving at least one */
    last_word = i;

    /* Raster header for DeskJet ????? */
    OUTF("\033*b%dW",(int)last_word);
    pbuf = &buf[0];     /* cannot use fprintf with %s format because of
                           NUL's in string, and it is slow anyway */
    for (i = 0; i < last_word; ++pbuf,++i)
        OUTC(*pbuf);
}

/*-->prtbmap*/
/**********************************************************************/
/****************************** prtbmap *******************************/
/**********************************************************************/

void
prtbmap()

{
    register UNSIGN32 *p;
    register INT16 j,k,ybottom,ytop;

    if (DBGOPT(DBG_PAGE_DUMP))
    {
        INT16 k1,k2,k3;

        for (k3 = 0; k3 < XBIT; (k3 += 7, ++p))
        {       /*  print bitmap 7 words at a pass */
            k1 = k3;
            k2 = MIN(XBIT,k1+7);
            (void)printf("prtbmap()...bitmap words %d..%d",k1,k2-1);
            NEWLINE(stdout);
            (void)printf("     ");
            for (k = k1; k < k2; ++k)
                (void)printf("%10d",k*HOST_WORD_SIZE);
            NEWLINE(stdout);
            for (j = YBIT-1; j >= 0; --j)
            {
                p = BITMAP(j,0);
                for (k = 0; k < XBIT; (++k,++p))
                {
                    if (*p)     /* print non-blank raster line */
                    {
                        p = BITMAP(j,k1);
                        (void)printf("%5d:",j);
                        for (k = k1; k < k2; (++k,++p))
                            (void)printf(" %09lx",*p);
                        NEWLINE(stdout);
                        break;  /* exit loop over k */
                    }
                }
            }
        }
    }

    (void)clearerr(plotfp);

#if    ZAPTHISOUT
    k = -1;         /* find top non-zero raster */
    for (j = YBIT-1; (j > 0) && (k < 0); --j)  /* loop over raster lines */
    {
        p = BITMAP(j,XBIT-1);
        for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
            --p;                /* trim white space */
    }
    ytop = j;
#else
    ytop = YBIT-1;
#endif

    k = -1;         /* find bottom non-zero raster */
    for (j = 0; (j < ytop) && (k < 0); ++j) /* loop over raster lines */
    {

#if    IBM_PC_MICROSOFT
        for (k = XBIT - 1;((k >= 0) && (*BITMAP(j,k) == 0));--k)
            ;           /* trim white space */
#else
        p = BITMAP(j,XBIT-1);
        for (k = XBIT - 1; ((k >= 0) && (*p == 0)); --k)
            --p;                /* trim white space */
#endif

    }
    ybottom = MAX(0,j-1);

#if    ZAPTHISOUT
    for (j = ytop; (j >= ybottom); --j)
        {
        OUTF("%5d:",(int)j);
        for (k = 0; k < XBIT; ++k)
            OUTF(" %9x",*BITMAP(j,k));
        NEWLINE(plotfp);
        }
#endif

    OUTF("\033&l%dX",(int)copies);      /* number of copies */

    OUTS("\033*r1A");                   /* start plot at current position */

    for (j = ytop; (j >= ybottom) ; --j)        /* loop over raster lines */
        outline(BITMAP(j,0));

    OUTS("\033*rB\f");                  /* end raster graphics, eject page */

    (void)fflush(plotfp);
    if (DISKFULL(plotfp))
        (void)fatal("Output error -- disk storage probably full");
}

#include "outrow.h"
#include "prtpage.h"
#include "readfont.h"
#include "readgf.h"
#include "readpk.h"
#include "readpost.h"
#include "readpxl.h"
#include "reldfont.h"
#include "rulepxl.h"
#include "setchar.h"
#include "setfntnm.h"
#include "setrule.h"
#include "signex.h"
#include "skgfspec.h"
#include "skipfont.h"
#include "skpkspec.h"
#include "special.h"
#include "strchr.h"
#include "strcm2.h"
#include "strid2.h"
#include "strrchr.h"
#include "tctos.h"
#include "usage.h"
#include "warning.h"