	/* LJ-GRAPH graphics output driver for laserjet printers*/

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>
#include <wgt4.h>
#include <ctype.h>

#define PORTRAIT 0      /*definitionsforPrint Graph*/
#define LANDSCAPE 1     /* image orientation */
#define GREYSCALE 2     /* and (olor to grey scale */
static unsigned DensityTbl[256];
static char graph_ends[ ]="\x1B*rB";
static char graph_init[ ]="\x1B E\x1B&l1H\x1B&l0O\x1B*p0X\x1B*p0Y\x1B*t";
int Negative;   /* flag for grey scale order */
block screen;

color pal[256];
int RES;
float STEPr;


void InitDensityTbl( void )
{
unsigned ColorEntry, ColorNum;
unsigned Intensity;


wreadpalette(0,255,pal);

/* this procedure builds the DensityTbl based upon the intensity of
the colors used in the palette to display the PCX image.
The intensity are calculated as described above. */




	     /* 256 color mode */
		   /* for each color register */
   for (ColorNum=0;ColorNum<256;ColorNum++)
     {

		/* calculate the intensity from the color values */
		Intensity = ((unsigned) pal[ColorNum].r*30); /* calculate red contribution */
		Intensity += ((unsigned) pal[ColorNum].g*59); /* calculate green contribution */
		Intensity += ((unsigned) pal[ColorNum].b*11); /* calculate blue contribution */

	/* scale and store intensity result */
     if(Intensity>0){
	DensityTbl[ColorNum] =
	(unsigned)(((((double)Intensity*(double)16)/6300)+0.5));
	/*(unsigned)(((((double)Intensity*(double)16)/6300)+0.5));*/
	/*DensityTbl[ColorNum]=(int)(DensityTbl[ColorNum]/4);*/
	DensityTbl[ColorNum]=(int)((Intensity/420)+.5);
	if(DensityTbl[ColorNum]>15) DensityTbl[ColorNum]=15;
     }
     if(Intensity<=0) DensityTbl[ColorNum]=0;
     }
}

int PromptLine()
{
char p;
int Ch;
	wcls(0);

	wtextcolor(255);      /* Ser current color to white   */

	wouttextxy(0,50,NULL,"<P>ortrait,<L>andscape,<G>reyscale");
	p=toupper(getch());
	if(p=='P') Ch=1;
	if(p=='L') Ch=2;
	if(p=='G') Ch=3;

return(Ch);
}



int format( double position )
{
int width = 6;
	if( position < 1000.0 ) width--;
	if( position < 100.0 ) width--;
	if( position < 10.0 ) width--;
return( width );
}

int Grey_Scale( int scanline, int palette_entry )
{
int grey = 0;
palette_entry=DensityTbl[palette_entry];

	switch(scanline)
	{
	case 0: {
		if( palette_entry & 4 ) grey |= 5;    /* sets bits .1.1*/
		if( palette_entry & 8 ) grey |= 10;   /* sets bits 1.1. */
		} break;
	case 1: {
		if( palette_entry & 1 ) grey |= 2;    /* sets hits    1. */
		if( palette_entry & 2 ) grey |= 8;    /* sets bits 1 */
		if( palette_entry & 8 ) grey |= 5;    /* sets bits .1.1 */
		} break;
	case 2: {
		if( palette_entry & 4 ) grey |= 5;    /* sets bits .1.1 */
		if( palette_entry & 8 ) grey |= 10;   /* sets bits 1.1. */
		} break;
	case 3: {
	    /*	if( palette_entry & 2 ) grey |= 2;    REMOVE sets bits    1. */
		if( palette_entry & 2 ) grey |= 5;    /* sets bits    1. */
		if( palette_entry & 8 ) grey |= 10;    /* sets bits .1.1 */
		} break;

	}

    if(Negative) grey ^=0x0F;    /* inverts grey scale bitpatterns */
return(grey);
}



void LJ_Graphic(int Mode)
{
int i, j, k, p, q, xasp,yasp;


double xprint, yprint, prstep, AspR;
int MaxX =320;
int MaxY =200;
char m, resolution[3];


AspR = 1;  /*set aspect ratio*/


switch(Mode)
	{
	case PORTRAIT:
	   {
		xprint = 690.0; /* initial page print positions */
		yprint = 500.0;
		strcpy( resolution, "150" );/* select 150 DPI resolution */
		prstep = STEPr/AspR;    /* adjust to match screen image */
		fprintf(stdprn,"%s%sR",graph_init,resolution);
	  for( j=0; j<=MaxY; j++ )
	  {
		fprintf( stdprn, "\x1B&a%-*.1fH%-*.1fV",
			format(xprint),xprint,
			format(yprint),yprint);
		yprint += prstep;
		fprintf( stdprn, "\x1B*r1A\x1B*b%dW",MaxX/8);
		for(i=0;i<MaxX/8;i++)
		{
			m=0;
			for(k=0;k<8;k++)
			{
				m<<=1;        /* shift m left one hit */
				if(Negative==1){
				  if(wgetpixel(i*8+k,j)) m++; /* if pixel on bit on */
				}
			}

			fprintf(stdprn,"%c",m);
		}
		fprintf(stdprn,"%s",graph_ends);
	  }
	} break;

	case LANDSCAPE:
	{
		xprint = 1000.0;        /* initial page print positions */
		yprint= 1000.0;
		strcpy(resolution,"75");     /* select 75 DPI resolution */
		prstep = 9.6 * AspR;    /* adjust to match screen image */
		fprintf(stdprn,"%s%sR",graph_init,resolution);
	    for(j=0;j<MaxX;j++)
	    {
		fprintf( stdprn, "\x1B&a%-*.1fh%-*.1fV",
			format( xprint ), xprint,
			format( yprint ), yprint );
		yprint+=prstep;
		fprintf(stdprn,"\x1B*r1A\x1B*b%dW",(int)(MaxY+4)/8);
		for(i=0;i<=MaxY/8;i++)
		{
			m=0;
			for(k=0;k<8;k++)
			{
				m <<= 1;       /* shift m left one bit */
				if(wgetpixel(MaxX-j,i*8+k)) m++;
					       /* if pixel bit on */
			}
			fprintf(stdprn,"%c",m);
		}
		fprintf(stdprn,"%s",graph_ends);
	    }
	} break;

	case GREYSCALE:
	{
		xprint = 1000.0; /* initial page print positions */
		yprint= 1000.0;
		itoa(RES,resolution,10);
	      /*strcpy( resolution,"300");*/ /*select 300 DPI resolution */
	       prstep = STEPr * AspR; /* adjust to match screen image */

		fprintf(stdprn,"%s%sR",graph_init,resolution);
		for( j=0; j<=MaxX; j++ )
			for( p=0; p<4; p++ ){
				fprintf(stdprn,"\x1B&a%-*.1fH%-*.1fV",
					format(xprint),xprint,
					format(yprint),yprint);
				yprint+=prstep;
				fprintf(stdprn,"\x1B*r1A\x1B*b%dW",MaxY/2);
				for(i=0;i<=MaxY/2;i++)
				{
					m=0;
					for(k=0;k<=1;k++)
					{
					    m<<=4;/* shift m leftfour bits */
					    m|=Grey_Scale(p,
					      wgetpixel(MaxX-j,i*2+k));
					}
					fprintf(stdprn,"%c",m);
				}
				fprintf(stdprn,"%s",graph_ends);
			}
		} break;
	} /* end of Switch */
	fprintf(stdprn,"\x0C\x1B&l0O\x1B(8U\x1B(sp10h12vsb3T\x1B&l1H");
					/* close operations */
}


void Print_Pause(int Invert)
{

int Done=0;
int Ch;

if( Invert ) Negative = 1;
else Negative = 0;
	screen=wloadpcx256("test.pcx",pal);
	wsetpalette(0,255,pal);
	wcls(0);
Ch=PromptLine();

while( !Done )
{


	wcls(0);
	/*screen=wloadpcx256("test.pcx",pal);
	wsetpalette(0,255,pal);*/
	wputblock(0,0,screen,0);
	InitDensityTbl();
	switch(Ch)
	{
		case 1 : {
			LJ_Graphic( PORTRAIT );
				Done++;
				break;
				}
		case 2: {
			LJ_Graphic(LANDSCAPE );
				Done++;
				break;
				}
		case 3: {
			LJ_Graphic( GREYSCALE );
				Done++;
				break;
				}
		default : Done++;
	}
   }
}


void main()
{
	int oldmode;
	int perv;
	oldmode=wgetmode();
	printf("1 or 0 for inverse.  please mark\n");
	scanf("%d",&perv);
	printf("enter resolution 75,100,150,300\n");
	scanf("%d",&RES);
	printf("enter step 2.4 7.2 9.6\n");
	scanf("%f",&STEPr);
	vga256();
	wcls(0);
	Print_Pause(perv);    /*1=normal white is white 0=white is black*/
	wfreeblock(screen);
	wsetmode(oldmode);

	exit(0);
}


