/* -*-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"