#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  graphic.c graphic.h postscript.c postscript.h
# Wrapped by karin@borodin on Wed Jul 24 21:36:51 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'graphic.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'graphic.c'\"
else
echo shar: Extracting \"'graphic.c'\" \(26692 characters\)
sed "s/^X//" >'graphic.c' <<'END_OF_FILE'
X/*----------------------------------------------------------------------
X	graphic.c	
X	
X		simple interactive graphic system with a resizeable window
X		and a pull-down-menu inside the window	
X------------------------------------------------------------------------*/
X  
X#include <stdio.h>
X#include <math.h>
X#include <strings.h>
X#include <malloc.h>
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <suntool/panel.h>
X#include <suntool/tty.h>
X#include <suntool/textsw.h>
X#include <suntool/scrollbar.h>
X#include <suntool/seln.h>
X#include <suntool/alert.h>
X#include <sys/stat.h>
X
X#include "macros.h"
X#include "graphic.h"
X  
X#define PX(x) (((x) - picture->x_min) * x_scal + left_margin)
X#define PY(y) ((picture->y_max - (y)) * y_scal + top_margin)
X
X#define Y_OFFSET	-3		/* offset added to vertical center alignment */
X
X#define	LEFT_MARGIN	60
X#define RIGHT_MARGIN	20
X#define	TOP_MARGIN	10
X#define BOTTOM_MARGIN	30
X
X#define	PS_WIDTH	15.0
X#define	PS_HEIGHT	15.0
X
X#define WINDOW_X 	0
X#define WINDOW_Y 	100
X#define WINDOW_WIDTH 	600
X#define WINDOW_HEIGHT 	650
X
X#define TEXTSW_ROWS	10
X
X/*----------------------------------------------------------------------
X	global data	(sunview)	
X------------------------------------------------------------------------*/
X  
XFrame	frame;
XPanel	panel;
XTty	tty;
XTextsw	textsw;
XMenu	menu;
XCanvas	canvas;
Xstatic Cursor orig_cursor, crosshair_cursor;
X
X/*----------------------------------------------------------------------
X	definition of Notify_client, necessary for notify procedures 
X	
X	(causes a warning: illegal pointer combination)
X------------------------------------------------------------------------*/
X  
Xstatic int my_client_object;
Xstatic Notify_client *me = (Notify_client *) &my_client_object;
X
X/*----------------------------------------------------------------------
X	color-table (8 IBM-PC-like colors and 24 greys)	
X------------------------------------------------------------------------*/
X
Xtypedef int Color;
Xtypedef struct singlecolor Singlecolor;
X
X/*    recall: 	struct singlecolor {u_char red, green, blue; };			*/	
X
X/*----------------------------------------------------------------------
X	color-table (8 IBM-PC-like colors and 24 greys)	
X------------------------------------------------------------------------*/
X  
Xchar red  [COLORS] = { 255, 000, 252, 242, 237,   2, 000, 000,
X                       255, 255, 255, 255, 255, 255, 255, 255,
X                       255, 255, 255, 255, 255, 255, 255, 255,
X                       255, 255, 255, 255, 255, 255, 255,  50};
X                       
Xchar green[COLORS] = { 255, 000, 243,   8,   8, 171, 128, 000,
X                       255, 255, 255, 255, 255, 255, 255, 255,
X                       255, 255, 255, 255, 255, 255, 255, 255,
X                       255, 255, 255, 255, 255, 255, 255,  50};
X                       
Xchar blue [COLORS] = { 255, 000,   5, 132,   6, 250,  17, 228,
X                       255, 255, 255, 255, 255, 255, 255, 255,
X                       255, 255, 255, 255, 255, 255, 255, 255,
X                       255, 255, 255, 255, 255, 255, 255,  50};
X    
X/*----------------------------------------------------------------------
X	Marker Definitions		
X------------------------------------------------------------------------*/
X
Xstatic char markers[MAXMARKERS] = {' ', '*', 'x', '+', '.'};
Xstatic int dy_marker[MAXMARKERS] = {0, 4, 2, 3, 0};
X  
X/*----------------------------------------------------------------------
X	global data	(graphic)	
X------------------------------------------------------------------------*/
X  
XPicture *picture = nil;
X
X/*----------------------------------------------------------------------
X	local data		
X------------------------------------------------------------------------*/
X 
Xstatic int 	canvas_height, canvas_width, 
X			height, width, left, right, top, bottom;
X		
Xstatic REAL x_scal, y_scal;
Xstatic REAL x_min, x_max, y_min, y_max;
X
Xstatic Pixwin			*pw;
X
Xstatic Pr_brush	brush;
Xstatic int			op;
Xstatic Pixfont		*cour10, *cour12, *cour14, *font, *marker_font;
X
Xstatic int		left_margin 	= LEFT_MARGIN,
X				right_margin	= RIGHT_MARGIN,
X				top_margin		= TOP_MARGIN,
X				bottom_margin	= BOTTOM_MARGIN;
X		
Xstatic REAL *b, *bx, *by, *bx_sub, *by_sub;	/* data for plot_bezier_line*/
X		
X/*----------------------------------------------------------------------
X	transformation pixel --> real		
X------------------------------------------------------------------------*/
X
XREAL px_to_x(px)
X	int px;
X{
X	return ((double)(px) - left_margin) / x_scal + picture->x_min;
X} 
X
XREAL py_to_y(py)
X	int py;
X{
X	return picture->y_max - ((double)(py) - top_margin) / y_scal;
X} 
X
X/*----------------------------------------------------------------------
X	allocation routines		
X------------------------------------------------------------------------*/
X 
XPanel_item *panel_item_vector(nl, nh)
X	int nl, nh;
X{
X	Panel_item *v;
X	if (nh < nl) return nil;
X	v = (Panel_item *) malloc((unsigned) (nh-nl+1) * sizeof(Panel_item));
X	return v - nl;
X}
X
Xstatic init_data()
X{
X	b = (REAL *) malloc(4 * sizeof(REAL));
X	bx = (REAL *) malloc(4 * sizeof(REAL));
X	by = (REAL *) malloc(4 * sizeof(REAL));
X	bx_sub = (REAL *) malloc(7 * sizeof(REAL));
X	by_sub = (REAL *) malloc(7 * sizeof(REAL));
X} 
X  
XLine *create_line(root)
X	Line **root;
X{
X	Line *line;
X	
X	if (*root == nil) {
X		line = *root = (Line *) malloc(sizeof(Line));
X	}
X	else {
X		for (line = *root; line->next != nil; line = line->next)
X			;
X		line = line->next = (Line *) malloc(sizeof(Line));
X	}
X	line->next = nil;
X	line->type = LINEAR;
X	return line;
X}
X		
XLine *new_line()
X{
X	return create_line(&(picture->line));
X}
X		
X
XLine *new_sys_line()
X{
X	return create_line(&(picture->sys_line));
X}		
X
XText *create_text(root)
X	Text **root;
X{
X	Text *text;
X	
X	if (*root == nil) {
X		text = *root = (Text *) malloc(sizeof(Text));
X	}
X	else {
X		for (text = *root; text->next != nil; text = text->next)
X			;
X		text = text->next = (Text *) malloc(sizeof(Text));
X	}
X	text->next = nil;
X	return text;
X}
X		
XText *new_text()
X{
X	return create_text(&(picture->text));
X}
X		
XText *new_sys_text()
X{
X	return create_text(&(picture->sys_text));
X}		
X
XMarker *create_marker(root)
X	Marker **root;
X{
X	Marker *marker;
X	
X	if (*root == nil) {
X		marker = *root = (Marker *) malloc(sizeof(Marker));
X	}
X	else {
X		for (marker=*root; marker->next != nil; marker=marker->next)
X			;
X		marker = marker->next = (Marker *) malloc(sizeof(Marker));
X	}
X	marker->next = nil;
X	return marker;
X}		
X
XMarker *new_marker()
X{
X	return create_marker(&(picture->marker));
X}
X
XMarker *new_sys_marker()
X{
X	return create_marker(&(picture->sys_marker));
X}		
X
XPicture *new_picture()
X{
X	Picture *picture;
X	picture = (Picture *) malloc(sizeof(Picture));
X	picture->line 		= nil;
X	picture->marker 	= nil;
X	picture->text 		= nil;
X	picture->sys_line 	= nil;
X	picture->sys_marker = nil;
X	picture->sys_text 	= nil;
X	picture->auto_scaling 		= FALSE;
X	picture->plot_colors 		= TRUE;
X	picture->plot_scale			= TRUE;
X	picture->plot_dots			= TRUE;
X	picture->include_showpage	= TRUE;
X	picture->ps_height	= PS_HEIGHT;
X	picture->ps_width	= PS_WIDTH;
X	picture->scale_size = MEDIUMSIZE;
X	sprintf(picture->ps_file, "%s", "graphic.ps");
X	sprintf(picture->frame_label, "%s", "graphic");
X	return picture;
X}
X
Xvoid append_sys_text(x, y, halign, valign, s)
X	REAL x, y;
X	int halign, valign;
X	char *s;
X{
X	Text *text;
X	text = new_sys_text();
X	text->next 		= nil;
X	text->col		= BLACK;
X	text->size		= picture->scale_size;
X	text->x			= x;
X	text->y			= y;
X	text->halign	= halign;
X	text->valign	= valign;
X	text->string	= malloc(strlen(s)+1);
X	strcpy(text->string, s);
X}
X
X/*----------------------------------------------------------------------
X	deallocation routines		
X------------------------------------------------------------------------*/
X  
Xvoid free_line(line)
X	Line *line;
X{
X	if (line != nil) {
X		free_line(line->next);
X		free((char*)line->x);
X		free((char*)line->y);
X		free((char*)line);
X	}
X}
X
Xvoid free_text(text)
X	Text *text;
X{
X	if (text != nil) {
X		free_text(text->next);
X		free((char*)text->string);
X		free((char*)text);
X	}
X}
X
Xvoid free_marker(marker)
X	Marker *marker;
X{
X	if (marker != nil) {
X		free_marker(marker->next);
X		free((char*)marker->x);
X		free((char*)marker->y);
X		free((char*)marker);
X	}
X}
X
Xvoid free_picture(picture)
X	Picture *picture;
X{
X	if (picture != nil) {
X		free_line(picture->line);
X		free_text(picture->text);
X		free_marker(picture->marker);
X		free_line(picture->sys_line);
X		free_text(picture->sys_text);
X		free_marker(picture->sys_marker);
X		free((char*)picture);
X	}
X}
X
X/*----------------------------------------------------------------------
X	get a single color from the color table		
X------------------------------------------------------------------------*/
X  
XSinglecolor *get_singlecolor(col)
X	Color col;
X{
X	static Singlecolor singlecol;
X	singlecol.red   = red[col];
X	singlecol.green = green[col];
X	singlecol.blue  = blue[col];
X	return &singlecol;
X}	
X
Xvoid fprint_color(f, col)
X	FILE *f;
X	int col;
X{
X	switch (col) {
X		case BLACK:		fprintf(f, "black");	break;
X		case YELLOW:	fprintf(f, "yellow");	break;
X		case MAGENTA:	fprintf(f, "magenta");	break;
X		case RED:		fprintf(f, "red");		break;
X		case CYAN:		fprintf(f, "cyan");		break;
X		case GREEN:		fprintf(f, "green");	break;
X		case BLUE:		fprintf(f, "blue");		break;
X		case WHITE:		fprintf(f, "white");	break;
X		default:		fprintf(f, "%d", col);	break;
X	}
X}
X
X/*----------------------------------------------------------------------
X	initialization routines			
X------------------------------------------------------------------------*/
X  
Xstatic void get_dimensions()
X{
X	canvas_width	= (int) window_get(canvas, CANVAS_WIDTH) - 1;
X	canvas_height	= (int) window_get(canvas, CANVAS_HEIGHT) - 1; 
X	height 	= canvas_height - top_margin - bottom_margin;
X	width  	= canvas_width  - left_margin - right_margin;
X	left	= left_margin;
X	right 	= canvas_width - right_margin;
X	top		= top_margin;
X	bottom	= canvas_height - bottom_margin;
X}
X
Xstatic void min_max_dvector(v, nl, nh, v_min, v_max)
X	REAL *v, *v_min, *v_max;
X	int nl, nh;
X{
X	int i;
X	for (i=nl; i<=nh; i++) {
X		if (v[i] < *v_min) 		*v_min = v[i];
X		if (v[i] > *v_max) 		*v_max = v[i];
X	}
X}
X
Xvoid set_min_max()
X{
X	Line *line;
X	Marker *marker;
X	BOOLEAN first = TRUE;
X	
X	for (line = picture->line; line != nil; line = line->next) {
X		if (first) {
X			first = FALSE;
X			picture->x_min = picture->x_max = line->x[0];
X			picture->y_min = picture->y_max = line->y[0];
X		}
X		min_max_dvector(line->x, 0, line->n, &picture->x_min,
X			&picture->x_max);
X		min_max_dvector(line->y, 0, line->n, &picture->y_min,
X			&picture->y_max);
X	}
X	for (marker = picture->marker; marker != nil; marker = marker->next) {
X		if (first) {
X			first = FALSE;
X			picture->x_min = picture->x_max = marker->x[0];
X			picture->y_min = picture->y_max = marker->y[0];
X		}
X		min_max_dvector(marker->x, 0, marker->n-1, &picture->x_min,
X			&picture->x_max);
X		min_max_dvector(marker->y, 0, marker->n-1, &picture->y_min,
X			&picture->y_max);
X	}
X	if (fabs(picture->x_min - picture->x_max) < SQRT_EPS_MACH) {
X		picture->x_min -= 1;
X		picture->x_max += 1;
X	}
X	if (fabs(picture->y_min - picture->y_max) < SQRT_EPS_MACH) {
X		picture->y_min -= 1;
X		picture->y_max += 1;
X	}
X}
X
Xvoid redraw_picture()
X{
X	if (picture->auto_scaling) {
X		x_min = picture->x_min;
X		x_max = picture->x_max;
X		y_min = picture->y_min;
X		y_max = picture->y_max;
X		set_min_max();
X		if (x_min != picture->x_min || x_max != picture->x_max ||
X			y_min != picture->y_min || y_max != picture->y_max) {
X			draw_picture();
X		}
X	}
X}
X
Xstatic void compute_scaling()
X{
X	if (picture->auto_scaling) {
X		set_min_max();
X		create_axes();
X	}
X	x_scal = ((REAL) width) / (picture->x_max - picture->x_min) ;
X	y_scal = ((REAL) height) / (picture->y_max - picture->y_min);
X}
X
Xstatic void init_fonts()
X{
X	cour10 = pf_open("/usr/lib/fonts/fixedwidthfonts/cour.r.10");
X	cour12 = pf_open("/usr/lib/fonts/fixedwidthfonts/cour.r.12");
X	cour14 = pf_open("/usr/lib/fonts/fixedwidthfonts/cour.r.14");
X	font = marker_font = cour10;
X}
X
Xstatic void init_colors()
X{
X	int k, low = BLACK, high = WHITE;
X	REAL dRed, dGreen, dBlue;
X
X    pw = canvas_pixwin(canvas);
X    pw_setcmsname(pw, "colortest");
X    
X    dRed   = (red  [high] - red  [low]) / (SHADES-1);
X    dGreen = (green[high] - green[low]) / (SHADES-1);
X    dBlue  = (blue [high] - blue [low]) / (SHADES-1);
X    
X	for (k=0; k<=GRAYS; k++) {
X		red	  [WHITE+1+k] = red  [high] - k * dRed;
X		green [WHITE+1+k] = green[high] - k * dGreen;
X		blue  [WHITE+1+k] = blue [high] - k * dBlue;
X	}
X	pw_putcolormap(pw, 0, COLORS, red, green, blue);
X}
X	
X/*-------------------------------------------------------------------------
X	change the cursor in the canvas subwindow		
X---------------------------------------------------------------------------*/
X
Xvoid orig_cursor_proc()
X{
X	window_set(canvas, WIN_CURSOR, orig_cursor, 0);
X}
X
Xvoid crosshair_cursor_proc()
X{
X	window_set(canvas, WIN_CURSOR, crosshair_cursor, 0);
X}
X
X/*-------------------------------------------------------------------------
X	sunview window initialization (partly copied from Sun's cursor_demo.c)		
X---------------------------------------------------------------------------*/
X
Xstatic void repaint_canvas();
Xvoid canvas_event_proc();
Xstatic void quit_proc();
X
Xstatic void init_cursor()
X{
X	struct pixrect	*orig_pr, *new_pr;
X
X	/* copy the orignal cursor image */
X	orig_pr = (struct pixrect *) (LINT_CAST(
X	    cursor_get(window_get(canvas, WIN_CURSOR), CURSOR_IMAGE)));
X	new_pr = (struct pixrect *)(LINT_CAST(mem_create(
X		orig_pr->pr_width, orig_pr->pr_height, orig_pr->pr_depth)));
X	(void)pr_rop(new_pr, 0, 0, new_pr->pr_width, new_pr->pr_height, PIX_SRC,
X	    orig_pr, 0, 0);
X
X	orig_cursor = cursor_create(
X	    CURSOR_IMAGE, 		orig_pr,
X		CURSOR_SHOW_CURSOR, TRUE,
X	    0);
X
X	crosshair_cursor = cursor_create(
X	    CURSOR_IMAGE, 			new_pr,
X	    CURSOR_OP,    			PIX_SRC ^ PIX_DST, 
X		CURSOR_SHOW_CROSSHAIRS, TRUE,
X	    0);
X    window_set(canvas, WIN_CURSOR, orig_cursor, 0); 
X}
X
Xvoid init_window()
X{
X	Scrollbar scrollbar = scrollbar_create(SCROLL_MARGIN,10,0);
X
X	frame = window_create(NULL, FRAME, 
X		FRAME_LABEL, 		picture->frame_label,
X/*		FRAME_NO_CONFIRM, 	TRUE,		*/
X		WIN_X, 				WINDOW_X,
X		WIN_Y, 				WINDOW_Y,
X		WIN_WIDTH, 			WINDOW_WIDTH,
X		WIN_HEIGHT, 		WINDOW_HEIGHT,
X		WIN_ERROR_MSG, 		"Window open failed",
X		0);
X	
X	textsw = window_create(frame, TEXTSW,
X		WIN_ROWS,	TEXTSW_ROWS,
X		0);
X
X	panel  = window_create(frame, PANEL,
X/*		WIN_VERTICAL_SCROLLBAR, scrollbar,		*/
X		WIN_BELOW, 			textsw,
X		0);
X	
X	panel_create_item(panel, PANEL_BUTTON,
X		PANEL_ITEM_X,		ATTR_COL(0),
X		PANEL_ITEM_Y,		ATTR_ROW(0),
X		PANEL_LABEL_IMAGE, 	panel_button_image(panel, "quit", 5, 0),
X		PANEL_NOTIFY_PROC, 	quit_proc,
X		0);
X		
X	create_panel_items();
X	window_fit_height(panel);
X	
X	canvas = window_create(frame, CANVAS,
X		WIN_BELOW, 				panel,
X		CANVAS_RETAINED, 		FALSE,
X		CANVAS_FIXED_IMAGE, 	FALSE,
X		CANVAS_REPAINT_PROC,	repaint_canvas,
X		WIN_EVENT_PROC,			canvas_event_proc,
X		0);
X	pw = canvas_pixwin(canvas);
X	init_cursor();
X}
X
Xstatic void quit_proc()
X{
X	textsw_reset(textsw, 5, 5);
X	window_destroy(frame);
X}
X
X/*----------------------------------------------------------------------
X	simple plot routines (cf. sunplot, kaskplot, ...)			
X------------------------------------------------------------------------*/
X  
Xstatic void sun_text(px, py, s)
X  int px, py;
X  char *s;
X  {
X    pw_ttext(pw, px, py, op, font, s); 
X  }
X 
Xstatic void Settings(type, val)
X  int type, val;
X  {
X      switch (type) {
X        case PENSIZE:
X            switch (val) {
X              case SMALLSIZE:  brush.width = 1; break;
X              case MEDIUMSIZE: brush.width = 2; break;
X              case BIGSIZE:    brush.width = 3; break;
X            }
X            break;
X        case PENCOLOR:
X             op = PIX_SRC | PIX_COLOR(val);
X             break;
X        case FONTSIZE:
X            switch (val) {
X              case SMALLSIZE:  font = cour10; break;
X              case MEDIUMSIZE: font = cour12; break;
X              case BIGSIZE:    font = cour14; break;
X            }
X            break;
X      }
X      return;
X  } 
X
Xstatic void sun_line(px1, py1, px2, py2)
X    int px1, py1, px2, py2;
X{
X/*    pw_line(pw, px1, py1, px2, py2, brush, NULL, op); */
X 	pw_vector(pw, px1, py1, px2, py2, op, 1); 
X}
X 
Xstatic void plot_line(x, y, n)					/* n = number of lines */
X	REAL *x, *y;
X	int n;
X{
X	int px1, px2, py1, py2, i;
X		
X	if (n>0) {
X		px1 = PX(x[0]);
X		py1 = PY(y[0]);
X		for (i=1; i<=n; i++) {
X			px2 = PX(x[i]);
X			py2 = PY(y[i]);
X			sun_line(px1, py1, px2, py2);
X			px1 = px2;
X			py1 = py2;
X		}
X	}
X}
X 
X/*-----------------------------------------------------------------------
X	procedures for plotting Bezier-lines	
X------------------------------------------------------------------------*/
X
X/*-----------------------------------------------------------------------
X	subdivision by de Casteljau's algorithm
X	
X	b[0..3] = given Bezier-points,
X	c[0..6] = Bezier-points of two segments
X	
X	(b and c may be the same or overlapping)
X------------------------------------------------------------------------*/
X
Xstatic void subdivision(b,c)
X	REAL *b, *c;
X{
X	int i;
X	
X	if (b!=c) 	for (i=0;i<=3;i++)	c[i]=b[i];
X	c[6] = c[3];
X	c[0] = c[0];
X	c[3] = (c[1]+c[2])/2;
X	c[1] = (c[0]+c[1])/2;
X	c[5] = (c[2]+c[6])/2;
X	c[2] = (c[1]+c[3])/2;
X	c[4] = (c[5]+c[3])/2;
X	c[3] = (c[2]+c[4])/2;
X}
X
X/*-----------------------------------------------------------------------
X	de Casteljau's algorithm
X------------------------------------------------------------------------*/
X
X#define DEGREE	3
X
Xstatic REAL bezier_point(c, lambda)
X	REAL *c, lambda;
X{
X	int k, i;
X	
X	for (i=0; i<=DEGREE; i++) 	b[i] = c[i];
X	for (k=1; k<=DEGREE; k++) {
X		for (i=0; i<=DEGREE-k; i++) {
X			b[i] = (1-lambda) * b[i] + lambda * b[i+1];
X		}
X	}
X	return b[0]; 
X}
X
X/*-----------------------------------------------------------------------
X	length of the plane polygon given by x[nl..nh], y[nl..nh]
X------------------------------------------------------------------------*/
X
Xstatic REAL polygon_length(x, y, nl, nh)
X	REAL *x, *y;
X	int nl, nh;
X{
X	REAL temp = 0;
X	int i;
X	for (i=nl; i<nh; i++) {
X		temp += sqrt(SQR(x[i+1] - x[i]) + SQR(y[i+1] - y[i]));
X	}
X	return temp;
X}
X
X/*-----------------------------------------------------------------------
X	plot the cubic polynomial given by the Bezier-points x[0..3], y[0..3]
X------------------------------------------------------------------------*/
X
X#define PIXELS_PER_SEGMENT		2
X
Xstatic void plot_bezier_line(x, y)
X	REAL *x, *y;
X{
X	REAL l, lambda;
X	int px1, px2, py1, py2, i, n;
X	
X	for (i=0; i<=3; i++) {
X		bx[i] = PX(x[i]);
X		by[i] = PY(y[i]);
X	}
X	subdivision(bx, bx_sub);
X	subdivision(by, by_sub);
X	
X	l = polygon_length(bx_sub, by_sub, 0, 6);
X	n = l / PIXELS_PER_SEGMENT;
X	if (n<1) n=1;
X	
X	px1 = bezier_point(bx, 0.0);
X	py1 = bezier_point(by, 0.0);
X	for (i=1; i<=n; i++) {
X		lambda = (REAL) i  / (REAL) n;
X		px2 = bezier_point(bx, lambda);
X		py2 = bezier_point(by, lambda);
X		sun_line(px1, py1, px2, py2);
X		px1 = px2;
X		py1 = py2;
X
X	}
X}
X
Xstatic void plot_marker(symbol, x, y, n)		/* n = number of markers */
X	REAL *x, *y;
X	int n, symbol;
X{
X	int px, py, i;
X	char s[2];
X	
X	s[0] = markers[symbol];
X	s[1] = '\0';
X	for (i=0; i<n; i++) {		
X		px = PX(x[i]) - 3;
X		py = PY(y[i]) + dy_marker[symbol];
X	    pw_ttext(pw, px, py, op, marker_font, s); 
X	}
X}
X 
Xvoid draw_line(root)
X	Line *root;
X{
X	Line *line;
X	for (line = root; line != nil; line = line->next) {
X		Settings(PENCOLOR, line->col);
X		Settings(PENSIZE, line->size);
X		if (line->type == LINEAR) 
X			plot_line(line->x, line->y, line->n);
X		else plot_bezier_line(line->x, line->y);
X	}
X}
X
X/*-----------------------------------------------------------------------
X	for the usage of pf_textwidth() cf. Pixrect Reference Manual p. 46	
X------------------------------------------------------------------------*/
X
Xvoid draw_text(root)
X	Text *root;
X{
X	Text *text;
X	int px, py;
X	struct pr_size string_size;
X	
X	for (text = root; text != nil; text = text->next) {
X		Settings(PENCOLOR, text->col);
X		Settings(FONTSIZE, text->size);
X		string_size = pf_textwidth(strlen(text->string), font, text->string);
X		switch (text->halign) {
X			case LEFT: px = PX(text->x); break;
X			case CENTER: px = PX(text->x) - string_size.x / 2; break;
X			case RIGHT: px = PX(text->x) - string_size.x; break;
X		}
X		switch (text->valign) {
X			case TOP: py = PY(text->y) + string_size.y; break;
X			case CENTER: py = PY(text->y) + string_size.y / 2 + Y_OFFSET; break;
X			case BOTTOM: py = PY(text->y); break;
X		}
X		sun_text(px, py, text->string); 
X	}
X}
X
Xvoid draw_marker(root)
X	Marker *root;
X{
X	Marker *marker;
X	for (marker = root; marker != nil; marker = marker->next) {
X		Settings(PENCOLOR, marker->col);
X		plot_marker(marker->symbol, marker->x, marker->y, marker->n);
X	}
X}
X
Xvoid draw_picture()
X{
X	char *string;
X	
X	get_dimensions();
X	compute_scaling();
X	Settings(PENCOLOR, WHITE);
X	pw_writebackground(pw, 0, 0, canvas_width, canvas_height, op);
X	draw_line(picture->line);
X	draw_text(picture->text);
X	draw_marker(picture->marker);	
X	draw_line(picture->sys_line);
X	draw_text(picture->sys_text);
X	draw_marker(picture->sys_marker);	
X}
X
Xstatic void repaint_canvas(canvas, pw, repaint_area)
X	Canvas		canvas;
X	Pixwin		*pw;
X	Rectlist	*repaint_area;
X{
X	draw_picture();
X}
X
X
Xvoid canvas_event_proc(canvas, event)
X	Canvas	canvas;
X	Event	*event;
X{
X	if (event_action(event) == MS_RIGHT && event_is_down(event)) {
X		menu_show(menu, canvas, event, 0);
X	}
X	else window_default_event_proc(canvas, event, 0);
X}
X
X/*----------------------------------------------------------------------
X	axes functions			
X------------------------------------------------------------------------*/
X  
X#define X_FORMAT		"%.2lf"
X#define Y_FORMAT		"%.2lf "
X
Xstatic void axes_lines()
X{
X	Line *line;
X	int no = 2;
X	
X	line = new_sys_line();
X	line->col   = BLACK;
X	line->size	= SMALLSIZE;
X	line->n		= no;
X	line->x		= (REAL *) malloc((unsigned) (no + 1) * sizeof(REAL));	
X	line->y		= (REAL *) malloc((unsigned) (no + 1) * sizeof(REAL));	
X	line->x[0] = picture->x_min; line->y[0] = picture->y_max;
X	line->x[1] = picture->x_min; line->y[1] = picture->y_min;
X	line->x[2] = picture->x_max; line->y[2] = picture->y_min;
X}
X
Xvoid create_axes()
X{
X	int i, nx, ny, no;
X	REAL dx, dy, x, y, factor;
X	Marker *marker;
X	char s[10];
X
X	free_line(picture->sys_line); 		picture->sys_line = nil;
X	free_text(picture->sys_text); 		picture->sys_text = nil;
X	free_marker(picture->sys_marker); 	picture->sys_marker = nil;
X	
X	axes_lines();
X	
X	dx = picture->x_max - picture->x_min;
X	factor = exp10(floor(log10(dx)));
X	dx = dx / factor;
X	if (dx >= 5) 
X		dx = factor;
X	else if (dx >= 2.5) 
X		dx = factor / 2;
X	else 
X		dx = factor / 5;
X	x = dx * ceil(picture->x_min / dx);
X	nx = (int) ((picture->x_max - x) / dx) + 1;
X	
X	dy = picture->y_max - picture->y_min;
X	factor = exp10(floor(log10(dy)));
X	dy = dy / factor;
X	if (dy >= 5) 
X		dy = factor;
X	else if (dy >= 2.5) 
X		dy = factor / 2;
X	else 
X		dy = factor / 5;
X	y = dy * ceil(picture->y_min / dy);
X	ny = (int) ((picture->y_max - y) / dy) + 1;
X	
X	no = nx + ny;
X	
X	marker = new_sys_marker();
X	marker->col 	= BLACK;
X	marker->size 	= MEDIUMSIZE;
X	marker->n	 	= no;
X	marker->x		= (REAL *) malloc((unsigned) (no + 1) * sizeof(REAL));	
X	marker->y		= (REAL *) malloc((unsigned) (no + 1) * sizeof(REAL));	
X	marker->symbol	= PLUS;
X
X	for (i=0; i<nx; i++) {
X		marker->x[i] = x;
X		marker->y[i] = picture->y_min;
X		sprintf(s, X_FORMAT, x);
X		append_sys_text(x, picture->y_min, CENTER, TOP, s);
X		x += dx;
X	}	
X		
X	y = dy * ceil(picture->y_min / dy);
X	for (i=nx; i<no; i++) {
X		marker->x[i] = picture->x_min;
X		marker->y[i] = y;
X		sprintf(s, Y_FORMAT, y);
X		append_sys_text(picture->x_min, y, RIGHT, CENTER, s);
X		y += dy;
X	}		
X}
X
Xvoid init_frame()
X{
X	init_window();
X	init_colors();
X	init_fonts();	
X	init_data();
X	
X	Settings(PENCOLOR, BLACK);
X	Settings(PENSIZE, SMALLSIZE);
X	Settings(FONTSIZE, SMALLSIZE);
X	
X	window_set(frame, FRAME_BACKGROUND_COLOR, get_singlecolor(WHITE), 0);
X	window_set(frame, FRAME_FOREGROUND_COLOR, get_singlecolor(BLUE), 0);
X}
X
X/*----------------------------------------------------------------------
X	functions for timer-controlled background procedures			
X------------------------------------------------------------------------*/
X 
X#define ITIMER_NULL ((struct itimerval *)0)
X
Xtypedef struct itimerval Itimerval;
X
Xvoid timer_proc_on(timer_proc, sec, usec)
X	void (*timer_proc)();
X	int sec, usec;
X{
X	Itimerval *blink_timer;
X	
X	blink_timer = (Itimerval *) malloc(sizeof(Itimerval));
X	
X	blink_timer->it_interval.tv_usec = usec;
X	blink_timer->it_interval.tv_sec = sec;
X	blink_timer->it_value.tv_usec = usec;
X	blink_timer->it_value.tv_sec = sec;
X	(void) notify_set_itimer_func(me, timer_proc, ITIMER_REAL, blink_timer,
X		ITIMER_NULL);
X}
X
Xvoid timer_proc_off(timer_proc)
X	void (*timer_proc)();
X{
X	(void) notify_set_itimer_func(me, timer_proc, ITIMER_REAL, ITIMER_NULL,
X		ITIMER_NULL);
X}
X
X
X/*--------------------------------------------------------------------
X	file I/O	
X----------------------------------------------------------------------*/
X
XBOOLEAN fwrite_picture(f, picture)
X	FILE *f;
X	Picture *picture;
X{
X	if (!fwrite_int(f, &picture->scale_size)) 		return FALSE;
X	if (!fwrite_real(f, &picture->x_min)) 			return FALSE;
X	if (!fwrite_real(f, &picture->x_max)) 			return FALSE;
X	if (!fwrite_real(f, &picture->y_min)) 			return FALSE;
X	if (!fwrite_real(f, &picture->y_max)) 			return FALSE;
X	if (!fwrite_real(f, &picture->ps_height)) 		return FALSE;
X	if (!fwrite_real(f, &picture->ps_width)) 		return FALSE;
X	if (!fprintf(f, "%s\n", picture->ps_file)) 		return FALSE;
X	if (!fwrite_int(f, &picture->auto_scaling)) 	return FALSE;
X	if (!fwrite_int(f, &picture->plot_colors)) 		return FALSE;
X	if (!fwrite_int(f, &picture->plot_scale)) 		return FALSE;
X	if (!fwrite_int(f, &picture->plot_dots)) 		return FALSE;
X	if (!fwrite_int(f, &picture->include_showpage)) return FALSE;
X	if (!fprintf(f, "%s\n", picture->io_file))		return FALSE;
X        return TRUE;
X}
X
XBOOLEAN fread_picture(f, picture)
X	FILE *f;
X	Picture *picture;
X{
X	if (!fread_int(f, &picture->scale_size)) 		return FALSE;
X	if (!fread_real(f, &picture->x_min)) 			return FALSE;
X	if (!fread_real(f, &picture->x_max)) 			return FALSE;
X	if (!fread_real(f, &picture->y_min)) 			return FALSE;
X	if (!fread_real(f, &picture->y_max)) 			return FALSE;
X	if (!fread_real(f, &picture->ps_height)) 		return FALSE;
X	if (!fread_real(f, &picture->ps_width)) 		return FALSE;
X	if (!fscanf(f, "%s\n", picture->ps_file))		return FALSE;
X	if (!fread_int(f, &picture->auto_scaling)) 		return FALSE;
X	if (!fread_int(f, &picture->plot_colors)) 		return FALSE;
X	if (!fread_int(f, &picture->plot_scale)) 		return FALSE;
X	if (!fread_int(f, &picture->plot_dots)) 		return FALSE;
X	if (!fread_int(f, &picture->include_showpage)) 	return FALSE;
X	if (!fscanf(f, "%s\n", picture->io_file)) 		return FALSE;
X        return TRUE;
X}
X
X
X
END_OF_FILE
if test 26692 -ne `wc -c <'graphic.c'`; then
    echo shar: \"'graphic.c'\" unpacked with wrong size!
fi
# end of 'graphic.c'
fi
if test -f 'graphic.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'graphic.h'\"
else
echo shar: Extracting \"'graphic.h'\" \(3929 characters\)
sed "s/^X//" >'graphic.h' <<'END_OF_FILE'
X/*----------------------------------------------------------------------
X	graphic.h
X	
X		simple graphics with a resizeable window and pull-down-menus
X		inside the window		
X------------------------------------------------------------------------*/
X
X#define FILENAME_LENGTH		30
X
X/*----------------------------------------------------------------------
X	definitions for colors and the color-table	
X------------------------------------------------------------------------*/
X  
X#define COLORS 32
X#define GRAYS 23
X#define SHADES 22
X
X#define BLACK 	1
X#define YELLOW	2
X#define MAGENTA 3
X#define RED 	4
X#define CYAN 	5
X#define GREEN 	6
X#define BLUE 	7
X#define WHITE 	0	/* 8 for color screens, 0 for black and white */
X
X/*----------------------------------------------------------------------
X	definitions for settings (types, values), alignments,
X	line types and markers	
X------------------------------------------------------------------------*/
X  
X#define PENSIZE 	1
X#define FONTSIZE 	2
X#define PENCOLOR 	3
X
X#define SMALLSIZE 	1
X#define MEDIUMSIZE	2
X#define BIGSIZE 	3
X
X#define LEFT	 	1		/* horizontal alignment	*/
X#define CENTER		2
X#define RIGHT		3
X
X#define TOP		1		/* vertical alignment	*/
X#define BOTTOM	 	3
X
X#define LINEAR	 	1		/* line types			*/
X#define BEZIER	 	2
X
X#define MAXMARKERS	7		/* markers			*/
X#define STAR		1
X#define CROSS		2
X#define PLUS		3
X#define DOT			4
X  
X/*-----------------------------------------------------------------------
X	data structures for resizeable pictures	
X------------------------------------------------------------------------*/
X
Xtypedef struct LINE {
X	int col, size, type, n; 
X	REAL *x, *y;
X	struct LINE *next; 
X} Line;
X
Xtypedef struct TEXT {
X	int 	col, size, halign, valign; 
X	REAL x, y; 
X	char *string; 
X	struct TEXT *next;
X} Text;
X	
Xtypedef struct MARKER {
X	int col, size, symbol, n; 
X	REAL *x, *y;
X	struct MARKER *next; 
X} Marker;
X
Xtypedef struct {
X	Line *line, *sys_line;
X	Text *text, *sys_text; 
X	Marker *marker, *sys_marker;
X	int scale_size;
X	REAL x_min, x_max, y_min, y_max, ps_height, ps_width;
X	char frame_label[FILENAME_LENGTH], ps_file[FILENAME_LENGTH],
X		 io_file[FILENAME_LENGTH];
X	BOOLEAN auto_scaling, plot_colors, plot_scale, plot_dots, include_showpage;
X} Picture;
X
X
X/*----------------------------------------------------------------------
X	global data		
X------------------------------------------------------------------------*/
X  
Xextern Frame 	frame;
Xextern Menu		menu;
Xextern Textsw 	textsw;
Xextern Panel	panel;
Xextern Canvas	canvas;
X
Xextern Picture	*picture;
X
X/*-----------------------------------------------------------------------
X	functions imported by graphic	
X------------------------------------------------------------------------*/
X
Xextern void init_menu();
Xextern void create_panel_items();
X
X/*-----------------------------------------------------------------------
X	functions exported by graphic	
X------------------------------------------------------------------------*/
X
X/* extern Singlecolor *get_singlecolor();		*/
X
Xextern void init_frame();
Xextern void create_axes();
Xextern void paint_canvas();
X
Xextern Line *new_line();
Xextern Text *new_text();
Xextern Marker *new_marker();
Xextern Picture *new_picture();
X
Xextern void free_line();
Xextern void free_text();
Xextern void free_marker();
Xextern void free_picture();
X
Xextern void draw_picture();
Xextern void redraw_picture();
Xextern void draw_line();
Xextern void draw_text();
Xextern void draw_marker();
X
Xextern void timer_proc_on(), timer_proc_off();
X
Xextern void fprint_color();
X
Xextern REAL px_to_x(), py_to_y();
X
Xextern Panel_item *panel_item_vector();
Xextern void canvas_event_proc();
X
Xextern BOOLEAN fwrite_picture(), fread_picture();
Xextern void orig_cursor_proc(), crosshair_cursor_proc();
X
X/*-----------------------------------------------------------------------
X	procedures also used by postscript	
X------------------------------------------------------------------------*/
X
Xextern void set_min_max();
END_OF_FILE
if test 3929 -ne `wc -c <'graphic.h'`; then
    echo shar: \"'graphic.h'\" unpacked with wrong size!
fi
# end of 'graphic.h'
fi
if test -f 'postscript.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'postscript.c'\"
else
echo shar: Extracting \"'postscript.c'\" \(10297 characters\)
sed "s/^X//" >'postscript.c' <<'END_OF_FILE'
X/*----------------------------------------------------------------------
X    postscript.c    implementation of ps_draw_picture() 
X------------------------------------------------------------------------*/
X  
X#include <stdio.h>
X#include <math.h>
X#include <strings.h>
X#include <malloc.h>
X
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X#include <suntool/panel.h>
X#include <suntool/tty.h>
X#include <suntool/textsw.h>
X#include <suntool/scrollbar.h>
X
X#include "macros.h"
X#include "graphic.h"
X#include "postscript.h"
X  
X#define PX(x) (int) (((x) - picture->x_min) * x_scal + left_margin)
X#define PY(y) (int) (((y) - picture->y_min) * y_scal + bottom_margin)
X
X#define PALATINO_ROMAN      0
X#define TIMES_ROMAN         1
X#define SYMBOL              2
X
X#define SHEET_HEIGHT        29.6    /* height of a DIN A4 page in cm    */
X#define SHEET_WIDTH         21.0    /* width of a DIN A4 page in cm     */
X#define POINTS_PER_CM       2830
X
X/*----------------------------------------------------------------------
X    Marker Definitions      
X------------------------------------------------------------------------*/
X
X#define MAXPSMARKERS 7
X
Xstatic char *ps_fonts[3] =
X  {
X    "/Palatino-Roman",
X    "/Times-Roman",
X    "/Symbol"
X  };
X
Xstatic int marker_fonts[MAXPSMARKERS] = {
X    TIMES_ROMAN,
X    TIMES_ROMAN,
X    TIMES_ROMAN,
X    TIMES_ROMAN,
X    TIMES_ROMAN,
X    SYMBOL,
X    SYMBOL
X};
X
Xstatic char *markers[MAXPSMARKERS] =
X  {
X    "",
X    "*",
X    "x",                /*  "\\264",    */
X    "+",
X    "\\267",
X    "\\304",
X    "\\305"
X  };
X  
Xstatic REAL dy_marker[MAXPSMARKERS]
X         = {0.0, -.215, 0.0, 0.0, -0.1, 0.0, 0.0};
X
X/*----------------------------------------------------------------------
X    dash-patterns simulating colors     
X------------------------------------------------------------------------*/
X
X#define PATTERNS_MAX    12
X
Xstatic char *pattern_table[] = {
X    "",
X    "",
X    "100 200",
X    "300 200 100 200",
X    "500 200 100 200",
X    "300 200 100 200 100 200",
X    "700 200 100 200",
X    "500 200 100 200 100 200",
X    "500 200 300 200",
X    "500 200 300 200 300 200",
X    "100 100",
X    "100 100 200 100",
X    "100 100 100 100 200 100"
X};
X
X/*----------------------------------------------------------------------
X    module data     
X------------------------------------------------------------------------*/
X  
Xstatic int  sheet_height, sheet_width,
X            height, width, left, right, top, bottom;
X        
Xstatic REAL x_scal, y_scal;
X
Xstatic int  left_margin, right_margin, top_margin, bottom_margin;
X        
Xstatic int first = TRUE, fileNo = 0;
Xstatic FILE *actFile = nil;
Xstatic REAL fontSize[6] = {1,800.0,1200.0,1600.0, 2000.0, 2400.0};
Xstatic REAL lineWidth[4] = {1,5.0,50.0,150.0};
Xstatic int lineCount;
X
Xstatic int ps_color = 0, ps_size = 0, ps_font = 0;
Xstatic REAL gray = 0;
X
Xstatic char macros_filename[] = "macros.ps";
Xstatic char str[50];
X
X/*----------------------------------------------------------------------
X    initialization routines         
X------------------------------------------------------------------------*/
X  
Xstatic void get_dimensions()
X{
X    sheet_height    = SHEET_HEIGHT * POINTS_PER_CM;
X    sheet_width     = SHEET_WIDTH  * POINTS_PER_CM;
X    left_margin     = 5 * fontSize[picture->scale_size];
X    right_margin    = 2 * fontSize[picture->scale_size] + 
X                            (SHEET_WIDTH - picture->ps_width) * POINTS_PER_CM;
X    top_margin      = fontSize[picture->scale_size] + 
X                            (SHEET_HEIGHT - picture->ps_height) * POINTS_PER_CM;
X    bottom_margin   = 3 * fontSize[picture->scale_size];
X    height  = sheet_height - top_margin - bottom_margin;
X    width   = sheet_width  - left_margin - right_margin;
X    left    = left_margin;
X    right   = sheet_width - right_margin;
X    bottom  = bottom_margin;
X    top     = sheet_height - top_margin;
X}
X
Xstatic void compute_scaling()
X{
X    if (picture->auto_scaling) {
X        set_min_max();
X        create_axes();
X    }
X    x_scal = ((REAL) width) / (picture->x_max - picture->x_min) ;
X    y_scal = ((REAL) height) / (picture->y_max - picture->y_min);
X}
X
Xstatic void Settings(type, val)
X    int type, val;
X{
X    switch (type) {
X        case PENSIZE:
X            fprintf(actFile,"%4.2f SL\n", lineWidth[val]);
X            lineCount++;
X            break;
X        case PENCOLOR:
X            if (val != ps_color && picture->plot_colors) {
X                ps_color = val;
X                fprintf(actFile, "[%s] 0 setdash\n", pattern_table[val]);
X            }
X            break;
X     }
X}
X
Xstatic void set_font(font, size)
X    int font, size;
X{
X    if (font != ps_font || size != ps_size) {
X        ps_size = size;
X        ps_font = font;
X        fprintf(actFile, "%s findfont\n", ps_fonts[font]);
X        fprintf(actFile, "/scalefactor %3.1f def\n", fontSize[size]);
X        fprintf(actFile, "%3.1f scalefont setfont\n", fontSize[size]);
X        lineCount += 3;
X    }
X}
X 
Xstatic void close_ps_file()
X{
X    if (picture->include_showpage) {
X        fprintf(actFile,"\nshowpage\n0.01 0.01 scale\n");
X        lineCount ++;
X    }
X    fclose(actFile);
X    actFile = nil;
X    sprintf(str, "Postscript file %s contains %d lines\n", picture->ps_file,
X                lineCount);
X    textsw_insert(textsw, str, strlen(str));
X    lineCount = 0;
X}   
X
X/*----------------------------------------------------------------------
X    initialize new PostScript-file
X-----------------------------------------------------------------------*/
X
Xstatic void open_ps_file()
X{
X    int k;
X    char s[256];
X    char c;
X    FILE *macros;
X
X    if (actFile!=nil) close_ps_file();
X
X    actFile = fopen(picture->ps_file,"w");
X    if (actFile==nil)
X      {
X        sprintf(s,"open_ps_file: Open for '%s' failed",picture->ps_file);
X        printf("%s", s); 
X      }
X      
X/*----------------------------------------------------------------------
X    read PostScript macros from macros.ps
X-----------------------------------------------------------------------*/
X
X    if ((macros = fopen(macros_filename, "r")) == NULL) {
X        printf("File %s cannot be opened\n", macros_filename);
X        return;
X    }   
X    while ((c = getc(macros)) != EOF) {
X            putc(c, actFile);
X            if (c == '\n') lineCount ++;
X    }
X    fclose(macros);
X        if (picture->include_showpage) {
X            fprintf(actFile,"1000 1000 translate\n");
X          lineCount ++;
X            fprintf(actFile,"1000 1000 moveto\n");
X          lineCount ++;
X        }
X
X    set_font(PALATINO_ROMAN, MEDIUMSIZE);
X    Settings(PENSIZE, MEDIUMSIZE);
X    Settings(PENCOLOR, BLACK);
X}
X
X/*----------------------------------------------------------------------
X    simple plot routines (cf. psplot, kaskplot, ...)            
X------------------------------------------------------------------------*/
X  
Xstatic void ps_text(px, py, s)
X    int px, py;
X    char *s;
X{
X    fprintf(actFile,"(%s) %d %d T\n", s, px, py);
X    lineCount++;
X}
X 
Xstatic void ps_aligned_text(s, halign, valign, px, py)
X    char *s;
X    int halign, valign, px, py;
X{
X    fprintf(actFile,"%d %d (%s) %d %d AT\n", halign, valign, s, px, py);
X    lineCount++;
X}
X 
Xstatic void ps_newline(px, py)
X    int px, py;
X{
X    fprintf(actFile, "NP %d %d M ", px, py);
X}
X
Xstatic void ps_moveto(px, py)
X    int px, py;
X{
X    fprintf(actFile,"%d %d M ", px, py);
X}
X
Xstatic void ps_lineto(px, py)
X    int px, py;
X{
X    fprintf(actFile,"%d %d L ", px, py);
X}
X
Xstatic void ps_closeline()
X{
X    fprintf(actFile,"S\n");
X    lineCount++;
X}
X
Xstatic void plot_line(x, y, n)              /* n = number of lines */
X    REAL *x, *y;
X    int n;
X{
X    int px, py, i;
X        
X    if (n>0) {
X        px = PX(x[0]);
X        py = PY(y[0]);
X        ps_newline(px, py);
X        for (i=1; i<=n; i++) {
X            px = PX(x[i]);
X            py = PY(y[i]);
X            ps_lineto(px, py);
X        }
X        ps_closeline();
X    }
X}
X 
X/*-----------------------------------------------------------------------
X    plot the cubic polynomial given by the Bezier-points x[0..3], y[0..3]
X------------------------------------------------------------------------*/
X
Xstatic void plot_bezier_line(x, y)
X    REAL *x, *y;
X{
X    int i, px, py;
X    
X    px = PX(x[0]);
X    py = PY(y[0]);
X    ps_newline(px, py);
X    for (i=1; i<=3; i++) {
X        px = PX(x[i]);
X        py = PY(y[i]);
X        fprintf(actFile, "%d %d ", px, py);
X    }
X    fprintf(actFile, "curveto ");
X    ps_closeline();
X}
X
Xstatic void plot_marker(symbol, size, x, y, n)
X    REAL *x, *y;
X    int n, symbol, size;
X{
X    int px, py, i, new_size;
X    
X    if (symbol != DOT || picture->plot_dots) {
X        new_size = (symbol == STAR) ? size + 1 : size;
X        set_font(marker_fonts[symbol], new_size);   
X        for (i=0; i<n; i++) {       
X            px = PX(x[i]);
X            py = PY(y[i]) + fontSize[new_size] * dy_marker[symbol];
X            ps_aligned_text(markers[symbol], CENTER, CENTER, px, py);
X        }
X    }
X}
X
Xstatic void draw_line(root)
X    Line *root;
X{
X    Line *line;
X    for (line = root; line != nil; line = line->next) {
X        Settings(PENCOLOR, line->col);
X        Settings(PENSIZE, line->size);
X        if (line->type == LINEAR) 
X            plot_line(line->x, line->y, line->n);
X        else plot_bezier_line(line->x, line->y);
X    }
X}
X
Xstatic void draw_text(root)
X    Text *root;
X{
X    Text *text;
X    int px, py;
X    struct pr_size string_size;
X    
X    for (text = root; text != nil; text = text->next) {
X        Settings(PENCOLOR, text->col);
X        set_font(PALATINO_ROMAN, text->size);
X        px = PX(text->x);
X        py = PY(text->y);
X        ps_aligned_text(text->string, text->halign, text->valign, px, py); 
X    }
X}
X
Xstatic void draw_marker(root)
X    Marker *root;
X{
X    Marker *marker;
X    for (marker = root; marker != nil; marker = marker->next) {
X        Settings(PENCOLOR, marker->col);
X        plot_marker(marker->symbol, marker->size,
X                         marker->x, marker->y, marker->n);
X    }
X}
X
Xvoid ps_draw_picture()
X{
X    open_ps_file();
X    get_dimensions();
X    compute_scaling();
X    draw_line(picture->line);
X    draw_text(picture->text);
X    draw_marker(picture->marker);
X    if (picture->plot_scale) {  
X        draw_line(picture->sys_line);
X        draw_text(picture->sys_text);
X        draw_marker(picture->sys_marker);   
X    }
X    close_ps_file();
X}
X
X
END_OF_FILE
if test 10297 -ne `wc -c <'postscript.c'`; then
    echo shar: \"'postscript.c'\" unpacked with wrong size!
fi
# end of 'postscript.c'
fi
if test -f 'postscript.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'postscript.h'\"
else
echo shar: Extracting \"'postscript.h'\" \(311 characters\)
sed "s/^X//" >'postscript.h' <<'END_OF_FILE'
X/*----------------------------------------------------------------------
X	postscript.h		
X------------------------------------------------------------------------*/
X
Xextern void ps_draw_picture();  
X
Xextern REAL ps_width, ps_height;
Xextern REAL ps_top_offset, ps_bottom_offset, ps_left_offset, ps_right_offset; 
END_OF_FILE
if test 311 -ne `wc -c <'postscript.h'`; then
    echo shar: \"'postscript.h'\" unpacked with wrong size!
fi
# end of 'postscript.h'
fi
echo shar: End of shell archive.
exit 0

