 /*
  * Khoros: $Id: hpgl.c,v 1.2 1991/12/18 09:09:03 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: hpgl.c,v 1.2 1991/12/18 09:09:03 dkhoros Exp $";
#endif

 /*
  * $Log: hpgl.c,v $
 * Revision 1.2  1991/12/18  09:09:03  dkhoros
 * HellPatch3
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "X3D.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    	    file name: hpgl.c                         <<<<
   >>>>                                                       <<<<
   >>>>                 HPGL Utilities			      <<<<
   >>>>                                                       <<<<
   >>>>			X3D_set_HPGL()			      <<<<
   >>>>			HPGL_DrawLine()			      <<<<
   >>>>			HPGL_DrawLines()		      <<<<
   >>>>			HPGL_DrawSegments()		      <<<<
   >>>>			HPGL_DrawRectangle()		      <<<<
   >>>>			HPGL_DrawArc()			      <<<<
   >>>>			HPGL_FillPolygon()		      <<<<
   >>>>			HPGL_DrawXTic()		      	      <<<<
   >>>>			HPGL_DrawYTic()		      	      <<<<
   >>>>			HPGL_close_device()		      <<<<
   >>>>			HPGL_set_line_width()		      <<<<
   >>>>			HPGL_set_line_type()		      <<<<
   >>>>			HPGL_set_draw()			      <<<<
   >>>>			HPGL_set_fill()			      <<<<
   >>>>			HPGL_DrawPolygon()		      <<<<
   >>>>			HPGL_DrawText()			      <<<<
   >>>>			HPGL_FillArc()			      <<<<
   >>>>			HPGL_FillRectangle()		      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


#define LOWER_X (short)0
#define LOWER_Y (short)0
#define UPPER_X (short)30000
#define UPPER_Y (short)30000

/************************************************************
*
*  MODULE NAME:  X3D_set_hpgl
*
*      PURPOSE:  Output graphics to HPGL file
*
*        INPUT:  id - xvgraphics id
*		 file - ImPress file to be sent to ImPress printer 
*		 width - width of output (on paper)
*		 height - height of output (on paper)
*		 xoffset - X offset from upper left hand corner (of paper)
*		 yoffset - Y offset from upper left hand corner (of paper)
*		 overlay - Don't force page output 
*		 landscape - landscape mode (horizontal output)
*
*    CALLED BY:  application program
*
*   WRITTEN BY:  Mike Lang & Mark Young
*
*
*************************************************************/


int X3D_set_HPGL(id, file, width, height, xoffset, yoffset, overlay,
		   landscape)

int     id, overlay, landscape;
FILE	*file;
float	width, height, xoffset, yoffset;
{
	X3DGraphics     *graphics;

	if (!(graphics = _X3D_get_graphics(id)))
	{
	   fprintf (stderr,"X3D_set_hpgl:");
	   fprintf (stderr,"\t unknown graphics id %d\n",id);
	   return(FALSE);
	}

	graphics->device = HPGL;
	graphics->hfile   = file;
	X3D_set_window(id, LOWER_X, LOWER_Y, UPPER_X, UPPER_Y);

	if(graphics->hfile != NULL)
	{
	   /* initialize the plotter */
	   (void) fprintf(file,"IN;SP1;IP 0,0,7650,7650;\n");
	   (void) fprintf(file,"SC %d,%d,%d,%d;\n",LOWER_X,UPPER_X,LOWER_Y,UPPER_Y);
	   if (landscape)
	   {
	   	(void) fprintf(file,"RO 90;\n");
	   }

	}
	else
	{
	   fprintf (stderr,"X3D_set_hpgl:");
	   fprintf (stderr,"\t unknown graphics file pointer");
	   return(FALSE);
	}
	return(TRUE);
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawLine
*
*      PURPOSE: Draw a single line for an hpgl device
*
*        INPUT:  graphics - graphics structure
*
*       OUTPUT: displays a line to hpgl device
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/

void HPGL_DrawLine (graphics, p1x, p1y, p2x, p2y)

X3DGraphics *graphics;
short   p1x, p1y, p2x, p2y;
{
	fprintf(graphics->hfile,"PA;PU%d,%d;PD%d,%d;\n", p1x, p1y, p2x, p2y);
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawLines
*
*      PURPOSE:  Draw a series of lines for a hpgl device
*
*        INPUT:  graphics - graphics structure
*
*       OUTPUT: displays a a set of lines to an hpgl device
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/

void HPGL_DrawLines (graphics, points, size, coordmode)

X3DGraphics *graphics;
int     coordmode, size;
XPoint  *points;
{
	int		i;


	if(coordmode == CoordModeOrigin)
	{
	   fprintf(graphics->hfile,"PAPU%d,%d\nPD ", points[0].x, points[0].y);
	   for(i = 1; i < size; i++)
	   {
	      fprintf(graphics->hfile,"%d,%d,", points[i].x, points[i].y);
	   }
	}
	else if(coordmode == CoordModePrevious)
	{
	   fprintf(graphics->hfile,"PA;PU%d,%d;\nPR;PD", points[0].x,
		   points[0].y);
	   for(i = 1; i < size; i++)
	   {
	      fprintf(graphics->hfile,"%d,%d,", points[i].x, points[i].y);
	   }
	}
	fprintf(graphics->hfile,";\n");
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawSegments
*
*      PURPOSE: Draw a series of disjoint segments for a hpgl device
*
*        INPUT:  graphics - graphics structure
*
*       OUTPUT: displays a a set of segments to a hpgl device
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/

void HPGL_DrawSegments (graphics, segments, seg_num)

X3DGraphics *graphics;
int	 seg_num;
XSegment *segments;
{
	int		i;


	fprintf(graphics->hfile,"PA;");
	for(i = 0; i < seg_num; i++)
	{
	   fprintf(graphics->hfile,"PU%d,%d;PD%d,%d;\n", segments[i].x1, 
		   segments[i].y1, segments[i].x2, segments[i].y2);
	}
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawRectangle
*
*      PURPOSE: Draw a rectangle to a hpgl device
*
*        INPUT:  graphics - graphics structure
*
*       OUTPUT: displays a rectangle to a hpgl device
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/

void HPGL_DrawRectangle (graphics, x, y, w, h)

X3DGraphics *graphics;
int      x, y, w, h;
{
	fprintf(graphics->hfile,"PA;PU%d,%d;\n", x, y); 
	fprintf(graphics->hfile,"PR;PD%d,0;\n", w); 
	fprintf(graphics->hfile,"PD0,%d;\n", -h); 
	fprintf(graphics->hfile,"PD%d,0;\n", -w); 
	fprintf(graphics->hfile,"PD0,%d;\n", h); 
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawArc
*
*      PURPOSE:  Draw an arc (circle) for a hpgl device
*		 x,y are the upper left corner of the bounding box of
*		 the circle ang1 & ang2 are the start and finish angles
*		 in degrees
*
*        INPUT:  graphics - graphics structure
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/

void HPGL_DrawArc (graphics, x, y, w, h, ang1, ang2) 

X3DGraphics *graphics;
int      x, y, ang1, ang2;
int     w, h;
{
	int		ang,center_x,center_y;

	center_x    =  x;
	center_y    =  y;

	center_x    +=  w/2 + .5;
	center_y    -=  h/2 + .5;
	
	/* this should really recalculate x and y */
	/* and rescale to support elipses */
	ang = ang2 - ang1;
	fprintf(graphics->hfile,"PA;PU%d,%d;\n",x, center_y);
	fprintf(graphics->hfile,"AA%d,%d,%d,5;\n",center_x, center_y, ang);
}



/************************************************************
*
*  MODULE NAME:  HPGL_FillPolygon
*
*      PURPOSE:  Uses the proper graphics routines to draw an arc
*
*        INPUT:  graphics - graphics structure
*
*       OUTPUT: displays a line (or a set of lines) to graphics workstation
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/


void HPGL_FillPolygon(graphics, points, size, shape, coordmode)

X3DGraphics *graphics;
int     size, shape, coordmode;
XPoint  *points;
{
	int		i;

	/*
	 *  Filled polygons is going to take some thought
	 *  no plotter support at this time
	 */
	if(coordmode == CoordModeOrigin)
	{
	   fprintf(graphics->hfile,"PA;PU%d,%d;\nPD",points[0].x,points[0].y);
	   for(i = 1; i < size; i++)
		fprintf(graphics->hfile,"%d,%d,",points[i].x, points[i].y);
	}
	else if(coordmode == CoordModePrevious)
	{
	   fprintf(graphics->hfile,"PA;PU%d,%d;\nPR;PD", points[0].x,
		   points[0].y);
	   for(i = 1; i < size; i++)
		fprintf(graphics->hfile,"%d,%d,", points[i].x, points[i].y);
	}
	fprintf(graphics->hfile,";\n");
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawTic
*
*      PURPOSE:  Uses the proper graphics routines to draw a tic
*
*        INPUT:  graphics - graphics structure
*
*       OUTPUT: displays a tic to a HPGL device
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/


void HPGL_DrawXTic (graphics, size, x, y)

X3DGraphics *graphics;
int     size, x, y;
{
	if (size <= 0)
	   size = 10;

	fprintf(graphics->hfile,"PA;PU%d,%d;PR0,%d;\n", x, y,
		(UPPER_Y - LOWER_Y)*(size/100));
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawYTic
*
*      PURPOSE:  Uses the proper graphics routines to draw a tic
*
*        INPUT:  graphics - graphics structure
*
*       OUTPUT: displays a tic to a HPGL device
*
*    CALLED BY: graphics routines
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/


void HPGL_DrawYTic (graphics, size, x, y)

X3DGraphics *graphics;
int     size, x, y;
{
	if (size <= 0)
	   size = 10;

	fprintf(graphics->hfile,"PA;PU%d,%d;PR%d,0;\n", x, y,
		(UPPER_X - LOWER_X)*(size/100));
}



/************************************************************
*
*  MODULE NAME:  HPGL_close_device
*
*      PURPOSE:  
*
*        INPUT:  graphics - graphics structure
*
*    CALLED BY:  application program
*
*   WRITTEN BY:  Mike Lang & Mark Young
*
*
*************************************************************/


void HPGL_close_device(graphics)

X3DGraphics *graphics;
{
	/* close the file or plotter */
	fprintf(graphics->hfile,"\n");
	fprintf(graphics->hfile,"\n");
}



/************************************************************
*
*  MODULE NAME:  HPGL_set_line_width
*
*      PURPOSE:  Sets the line width for a given graphics context
*
*        INPUT:  graphics - pointer to graphics context
*		 line_width - line width as defined in xvgraphics.h
*
*    CALLED BY:  application program
*
*   WRITTEN BY:  Mike Lang & Tom Sauer
*
*
*************************************************************/

void HPGL_set_line_width(graphics,line_width)

X3DGraphics     *graphics;
int line_width;
{
	float hpgl_line_width;

	/* best done by changing pens or possible redrawing lines */
/*
	hpgl_line_width = line_widths[line_width][graphics->device];
 */
}



/************************************************************
*
*  MODULE NAME:  HPGL_set_line_type
*
*      PURPOSE:  Sets the line type for a given graphics context
*
*        INPUT:  graphics - pointer to graphics context
*		 line_type - line type as defined in xvgraphics.h
*
*    CALLED BY:  application program
*
*
*   WRITTEN BY:  Tom Sauer & Mike Lang
*
*
*************************************************************/


void HPGL_set_line_type(graphics, line_type)

X3DGraphics  *graphics;
int	     line_type;
{
	/* Change the line type or no argument for solid */
	/* This is my best guess to map xprism to HPGL */

	graphics->line_type = line_type;

	switch (line_type) {
		case Dotted:
			fprintf(graphics->hfile,"LT 1,2;\n");
			break;
		case DotDash:
			fprintf(graphics->hfile,"LT 4;\n");
			break;
		case ShortDash:
			fprintf(graphics->hfile,"LT 2;\n");
			break;
		case LongDash:
			fprintf(graphics->hfile,"LT 3;\n");
			break;
		case OddDash:
			fprintf(graphics->hfile,"LT 5;\n");
			break;
		case Grid_Dotted:
			fprintf(graphics->hfile,"LT 1,0.5;\n");
			break;
		case Solid:
		default:
			fprintf(graphics->hfile,"LT;\n");
			break;
		}
}



/************************************************************
*
*  MODULE NAME:  HPGL_set_draw
*
*      PURPOSE:  Set the foreground draw color.
*
*        INPUT:  graphics - graphics context
*	         fg	  - foreground color
*		 override - whether the foreground color can
*			    be overriden.
*
*    CALLED BY:  application program
*
*   WRITTEN BY:  Mark Young
*
*
*************************************************************/

void HPGL_set_draw(graphics, fg, override)

X3DGraphics     *graphics;
XColor		*fg;
int		override;
{
}



/************************************************************
*
*  MODULE NAME:  HPGL_set_fill
*
*      PURPOSE:  Set the background fill color.
*
*        INPUT:  graphics - graphics context
*	         bg	  - background color
*		 override - whether the background color can
*			    be overriden.
*
*    CALLED BY:  application program
*
*   WRITTEN BY:  Mark Young
*
*
*************************************************************/

void HPGL_set_fill(graphics, bg, override)

X3DGraphics     *graphics;
XColor		*bg;
int		override;
{
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawPolygon
*
*      PURPOSE:  Draw a filled polygon.
*
*        INPUT:  graphics - graphics structure
*	         points   - points to be drawn
*	         size     - number of points
*
*   WRITTEN BY:
*
*
*************************************************************/

void HPGL_DrawPolygon(graphics, points, size)

X3DGraphics     *graphics;
XPoint		*points;
int		size;
{
   /* just return */
}



/************************************************************
*
*  MODULE NAME:  HPGL_DrawText
*
*      PURPOSE:  Draw text at the given position.
*
*        INPUT:  graphics - graphics structure
*	         x	  - x position
*	         y	  - y position
*	         text	  - text to be printed
*	         size	  - size of text array
*
*   WRITTEN BY:
*
*
*************************************************************/

void HPGL_DrawText(graphics, x, y, text, size)

X3DGraphics     *graphics;
char		*text;
int		x, y, size;
{
	/* not yet */
}



/************************************************************
*
*  MODULE NAME:  HPGL_FillArc
*
*      PURPOSE: Draw a filled arc.
*
*        INPUT:  graphics - graphics structure
*	         x	  - of upper left corner
*	         y	  - of upper left corner
*	         w	  - width of Arc
*	         h	  - height of Arc
*	         arc1	  - start angle
*	         arc2	  - end angle
*
*   WRITTEN BY:
*
*
*************************************************************/

void HPGL_FillArc(graphics, x, y, w, h, ang1, ang2)

X3DGraphics	*graphics;
int		x, y, ang1, ang2;
unsigned int	w, h;
{
   /* just return */
}



/************************************************************
*
*  MODULE NAME:  HPGL_FillRectangle
*
*      PURPOSE:  Draw a filled rectangle.
*
*        INPUT:  graphics - graphics structure
*	         x	  - of upper left corner
*	         y	  - of upper left corner
*	         w	  - width of rectangle
*	         h	  - height of rectangle
*
*   WRITTEN BY:
*
*
*************************************************************/

void HPGL_FillRectangle(graphics, x, y, w, h)

X3DGraphics     *graphics;
int		x, y, w, h;
{
   /* just return */
}
