[alt.sources] Fchart part 03/04

fs@uwasa.fi (Filip Sawicki LAKE) (06/04/90)

Submitted-by: fs@chyde
Archive-name: Fchart/part03

#!/bin/sh
# This is part 03 of Fchart
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= flblarr.c ==============
echo "x - extracting flblarr.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > flblarr.c &&
X/*
X *
X *  Fchart  --  flblarr.c
X *
X *  Copyright (C) 1990 Piotr Filip Sawicki
X *
X * Permission to use, copy, and distribute this software and its
X * documentation for any purpose with or without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and
X * that both that copyright notice and this permission notice appear
X * in supporting documentation.
X *
X * Permission to modify the software is granted, but not the right to
X * distribute the modified code.  Modifications are to be distributed
X * as patches to released version.
X *
X *  Please e-mail any useful additions to fs@uwasa.fi so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X
X#include <stdio.h>
X#include <math.h>
X#include "plot.h"
X#include "fchart.h"
X	
Xstruct label_def *first_label = NULL;
Xstruct linearrow_def *first_arrow = NULL;
X
Xextern char *strcpy(),*strcat();
Xextern int strlen();
X
X/* input data, parsing variables */
Xextern struct lexical_unit token[];
Xextern char input_line[];
Xextern int num_tokens, c_token;
X
Xextern double real();
X
X/******** Local functions ********/
Xstatic int assign_label_tag();
Xstatic int assign_arrow_tag();
Xstatic void delete_label();
Xstatic void delete_arrow();
X
X/* not static: used by fcmd.c */
Xvoid show_labels(), show_arrow();		
Xvoid set_label();
Xvoid set_nolabel();
Xvoid set_arrow();
Xvoid set_noarrow();
X
X/* process a 'set label' command */
X/* set label {tag} {label_text} {at {page|picture} x,y} {pos} {height h} {width w} */
Xvoid
Xset_label()
X{
X    struct label_def *this_label = NULL;
X    struct label_def *new_label = NULL;
X    struct label_def *prev_label = NULL;
X    double x, y, h, w, a;
X    char text[MAX_LINE_LEN+1];
X    enum JUSTIFY just = LEFT;
X	enum LAB_ROT rot;
X    int tag;
X    BOOLEAN set_text, set_position, set_just=FALSE, set_h, set_w, set_r;
X	BOOLEAN page_label;
X	
X    /* get tag */
X    if (!END_OF_COMMAND && isnumber(c_token)) {
X		tag = (int)real(c_token);
X		if (tag == 0)
X			int_error("tag must be > zero", c_token);
X		c_token++;
X    } else
X		tag = assign_label_tag(); /* default next tag */
X	
X    /* get text */
X    if (!END_OF_COMMAND && isstring(c_token)) {
X		quote_str(text, c_token);
X		c_token++;
X		set_text = TRUE;
X    } else {
X		text[0] = '\0';		/* default no text */
X		set_text = FALSE;
X    }
X		
X    /* get justification -- why not here ? */
X    if (!END_OF_COMMAND) {
X		if (almost_equals(c_token,"l$eft")) {
X			just = LEFT;
X			set_just = TRUE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"c$entre")
X				 || almost_equals(c_token,"c$enter")) {
X			just = CENTRE;
X			set_just = TRUE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"ri$ght")) {
X			just = RIGHT;
X			set_just = TRUE;
X			c_token++;
X		}
X	}
X
X    /* get position */
X    if (!END_OF_COMMAND && equals(c_token, "at")) {
X		c_token++;
X		if (END_OF_COMMAND)
X			int_error("coordinates expected", c_token);
X		if (almost_equals(c_token, "pa$ge")) {
X			c_token++;
X			page_label = TRUE;
X		}
X		else if (almost_equals(c_token, "pi$cture")) {
X			c_token++;
X			page_label = FALSE;
X		}
X		else if (!isnumber(c_token))
X			int_error("'page' or 'picture' expected", c_token);
X		else
X			page_label = FALSE;
X		x = real(c_token++);
X		if (!equals(c_token,","))
X			int_error("',' expected", c_token);
X		else
X			c_token++;
X		y = real(c_token++);
X		set_position = TRUE;
X    } else {
X		x = y = 0;			/* default at origin */
X		page_label = FALSE;
X		set_position = FALSE;
X    }
X	
X    /* get justification */
X    if (!END_OF_COMMAND) {
X		if (almost_equals(c_token,"l$eft")) {
X			if (set_just)
X				int_error("only one justification is allowed", c_token);
X			just = LEFT;
X			set_just = TRUE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"c$entre")
X				 || almost_equals(c_token,"c$enter")) {
X			if (set_just)
X				int_error("only one justification is allowed", c_token);
X			just = CENTRE;
X			set_just = TRUE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"ri$ght")) {
X			if (set_just)
X				int_error("only one justification is allowed", c_token);
X			just = RIGHT;
X			set_just = TRUE;
X			c_token++;
X		}
X	}
X
X	/* get height */
X	if (!END_OF_COMMAND && almost_equals(c_token, "he$ight")) {
X		c_token++;
X		h = real(c_token++);
X		set_h = TRUE;
X	}
X	else {
X		h = 0.0;
X		set_h = FALSE;
X	}
X
X	/* get width */
X	if (!END_OF_COMMAND && almost_equals(c_token, "wi$dth")) {
X		c_token++;
X		w = real(c_token++);
X		set_w = TRUE;
X	}
X	else {
X		w = 0.0;
X		set_w = FALSE;
X	}
X
X	/* get angle */
X	if (!END_OF_COMMAND && almost_equals(c_token, "ro$tation")) {
X		int sign = 1;
X		c_token++;
X		if (equals(c_token, "-")) {
X			c_token++;
X			sign = -1;
X		}
X		a = (double)sign * real(c_token++);
X		rot = L_RANDOM;
X		set_r = TRUE;
X	}
X	else if (!END_OF_COMMAND) {
X		if (almost_equals(c_token, "di$rection")) {
X			c_token++;
X			set_r = TRUE;		/* empty direction defaults to normal */
X		}
X		else
X			set_r = FALSE;
X		if (!END_OF_COMMAND && (almost_equals(c_token, "n$orth") ||
X			almost_equals(c_token, "v$ertical") || almost_equals(c_token, "u$p"))) {
X			c_token++;
X			rot = L_BOTTOM;
X			set_r = TRUE;
X		}
X		else if (!END_OF_COMMAND && (almost_equals(c_token, "s$outh") ||
X				 almost_equals(c_token, "do$wn"))) {
X			c_token++;
X			rot = L_TOP;
X			set_r = TRUE;
X		}
X		else if (!END_OF_COMMAND && (almost_equals(c_token, "we$st") ||
X				 almost_equals(c_token, "l$eft"))) {
X			c_token++;
X			rot = L_UPSIDE;
X			set_r = TRUE;
X		}
X		else if (!END_OF_COMMAND && (almost_equals(c_token, "ho$rizontal") ||
X				 almost_equals(c_token, "e$ast") || almost_equals(c_token, "ri$ght"))) {
X			c_token++;
X			rot = L_NORMAL;
X			set_r = TRUE;
X		}
X		else {
X			rot = L_NORMAL;
X		}
X	}
X	else {
X		rot = L_NORMAL;
X		set_r = FALSE;
X	}
X		
X    if (!END_OF_COMMAND)
X		int_error("extraneous or out-of-order arguments in set label", c_token);
X	
X    /* OK! add label */
X    if (first_label != NULL) { /* skip to last label */
X		for (this_label = first_label; this_label != NULL ; 
X			 prev_label = this_label, this_label = this_label->next)
X			/* is this the label we want? */
X			if (tag <= this_label->tag)
X				break;
X    }
X    if (this_label != NULL && tag == this_label->tag) {
X		/* changing the label */
X		if (set_position) {
X			this_label->x = x;
X			this_label->y = y;
X			this_label->paged = page_label;
X		}
X		if (set_text)
X			(void) strcpy(this_label->text, text);
X		if (set_just)
X			this_label->pos = just;
X		if (set_h)
X			this_label->h = h;
X		if (set_w)
X			this_label->w = w;
X		if (set_r) {
X			this_label->rot = rot;
X			this_label->a = a;
X		}
X    } else {
X		/* adding the label */
X		new_label = (struct label_def *) 
X			alloc ( (unsigned int) sizeof(struct label_def), "label");
X		if (prev_label != NULL)
X			prev_label->next = new_label; /* add it to end of list */
X		else 
X			first_label = new_label; /* make it start of list */
X		new_label->tag = tag;
X		new_label->next = this_label;
X		new_label->x = x;
X		new_label->y = y;
X		(void) strcpy(new_label->text, text);
X		new_label->pos = just;
X		new_label->h = h;
X		new_label->w = w;
X		new_label->rot = rot;
X		new_label->a = a;
X		new_label->paged = page_label;
X    }
X}
X
X/* process 'set nolabel' command */
X/* set nolabel {tag} */
Xvoid
Xset_nolabel()
X{
X    struct label_def *this_label;
X    struct label_def *prev_label; 
X    int tag;
X	
X    if (END_OF_COMMAND) {		/* delete all labels */
X		while (first_label != NULL)
X			delete_label((struct label_def *)NULL, first_label);
X    }
X    else {
X		tag = (int)real(c_token++);
X		if (!END_OF_COMMAND)
X			int_error("extraneous arguments to set nolabel", c_token);
X		for (this_label = first_label, prev_label = NULL;
X			 this_label != NULL;
X			 prev_label = this_label, this_label = this_label->next) {
X			if (this_label->tag == tag) {
X				delete_label(prev_label, this_label);
X				return;		/* exit, our job is done */
X			}
X		}
X		int_error("label not found", c_token);
X    }
X}
X
X/* assign a new label tag */
X/* labels are kept sorted by tag number, so this is easy */
Xstatic int				/* the lowest unassigned tag number */
Xassign_label_tag()
X{
X    struct label_def *this_label;
X    int last = 0;			/* previous tag value */
X	
X    for (this_label = first_label; this_label != NULL;
X		 this_label = this_label->next)
X		if (this_label->tag == last+1)
X			last++;
X		else
X			break;
X    
X    return (last+1);
X}
X
X/* delete label from linked list started by first_label.
X * called with pointers to the previous label (prev) and the 
X * label to delete (this).
X * If there is no previous label (the label to delete is
X * first_label) then call with prev = NULL.
X */
Xstatic void
Xdelete_label(prev,this)
Xstruct label_def *prev, *this;
X{
X    if (this!=NULL)	{		/* there really is something to delete */
X		if (prev!=NULL)		/* there is a previous label */
X			prev->next = this->next; 
X		else				/* this = first_label so change first_label */
X			first_label = this->next;
X		free((char *)this);
X    }
X}
X
X
X/* process a 'set arrow' and 'set line' command */
X/* set arrow|line {tag} {from { {page|picture} x,y} {to {page|picture} x,y} */
Xvoid
Xset_arrow(arrow)
XBOOLEAN arrow;
X{
X    struct linearrow_def *this_arrow = NULL;
X    struct linearrow_def *new_arrow = NULL;
X    struct linearrow_def *prev_arrow = NULL;
X    double sx, sy;
X    double ex, ey;
X    int tag;
X    BOOLEAN set_start, set_end;
X	BOOLEAN sp, ep;
X	
X    /* get tag */
X    if (!END_OF_COMMAND && isnumber(c_token)) {
X		tag = (int)real(c_token++);
X		if (tag == 0)
X			int_error("tag must be > zero", c_token);
X    } else
X		tag = assign_arrow_tag(); /* default next tag */
X	
X    /* get start position */
X    if (!END_OF_COMMAND && almost_equals(c_token, "f$rom")) {
X		c_token++;
X		if (END_OF_COMMAND)
X			int_error("start coordinates expected", c_token);
X		else if (almost_equals(c_token, "pa$ge")) {
X			c_token++;
X			sp = TRUE;
X		}
X		else if (almost_equals(c_token, "pi$cture")) {
X			c_token++;
X			sp = FALSE;
X		}
X		else
X			sp = FALSE;
X
X		sx = real(c_token++);
X		if (!equals(c_token,","))
X			int_error("',' expected",c_token);
X		c_token++;
X		sy = real(c_token++);
X		set_start = TRUE;
X    } else {
X		sx = sy = 0;			/* default at origin */
X		sp = FALSE;
X		set_start = FALSE;
X    }
X	
X    /* get end position */
X    if (!END_OF_COMMAND && almost_equals(c_token, "t$o")) {
X		c_token++;
X		if (END_OF_COMMAND)
X			int_error("end coordinates expected", c_token);
X		else if (almost_equals(c_token, "pa$ge")) {
X			c_token++;
X			ep = TRUE;
X		}
X		else if (almost_equals(c_token, "pi$cture")) {
X			c_token++;
X			ep = FALSE;
X		}
X		else
X			ep = FALSE;
X
X		ex = real(c_token++);
X		if (!equals(c_token,","))
X			int_error("',' expected",c_token);
X		c_token++;
X		ey = real(c_token++);
X		set_end = TRUE;
X    } else {
X		ex = ey = 0;			/* default at origin */
X		ep = FALSE;
X		set_end = FALSE;
X    }
X	
X    /* get start position - what the heck, either order is ok */
X    if (!END_OF_COMMAND && almost_equals(c_token, "f$rom")) {
X		if (set_start)
X			int_error("only one 'from' is allowed", c_token);
X		c_token++;
X		if (END_OF_COMMAND)
X			int_error("start coordinates expected", c_token);
X		else if (almost_equals(c_token, "pa$ge")) {
X			c_token++;
X			sp = TRUE;
X		}
X		else if (almost_equals(c_token, "pi$cture")) {
X			c_token++;
X			sp = FALSE;
X		}
X		else
X			sp = FALSE;
X
X		sx = real(c_token++);
X		if (!equals(c_token,","))
X			int_error("',' expected",c_token);
X		c_token++;
X		sy = real(c_token++);
X		set_start = TRUE;
X    }
X	
X    if (!END_OF_COMMAND)
X		int_error("extraneous or out-of-order arguments in set arrow/line", c_token);
X	
X    /* OK! add arrow */
X    if (first_arrow != NULL) { /* skip to last arrow */
X		for (this_arrow = first_arrow; this_arrow != NULL ; 
X			 prev_arrow = this_arrow, this_arrow = this_arrow->next)
X			/* is this the arrow we want? */
X			if (tag <= this_arrow->tag)
X				break;
X    }
X    if (this_arrow != NULL && tag == this_arrow->tag) {
X		/* changing the arrow */
X		if (set_start) {
X			this_arrow->sx = sx;
X			this_arrow->sy = sy;
X			this_arrow->startp = sp;
X		}
X		if (set_end) {
X			this_arrow->ex = ex;
X			this_arrow->ey = ey;
X			this_arrow->endp = ep;
X		}
X		this_arrow->arrow = arrow;
X    } else {
X		/* adding the arrow */
X		new_arrow = (struct linearrow_def *) 
X			alloc ( (unsigned int) sizeof(struct linearrow_def), "arrow");
X		if (prev_arrow != NULL)
X			prev_arrow->next = new_arrow; /* add it to end of list */
X		else 
X			first_arrow = new_arrow; /* make it start of list */
X		new_arrow->tag = tag;
X		new_arrow->next = this_arrow;
X		new_arrow->sx = sx;
X		new_arrow->sy = sy;
X		new_arrow->startp = sp;
X		new_arrow->ex = ex;
X		new_arrow->ey = ey;
X		new_arrow->endp = ep;
X		new_arrow->arrow = arrow;
X    }
X}
X
X/* process 'set noarrow' and 'set noline' command */
X/* set noarrow {tag} */
Xvoid
Xset_noarrow()
X{
X    struct linearrow_def *this_arrow;
X    struct linearrow_def *prev_arrow; 
X    int tag;
X	
X    if (END_OF_COMMAND) {
X		/* delete all arrows */
X		while (first_arrow != NULL)
X			delete_arrow((struct linearrow_def *)NULL,first_arrow);
X    }
X    else {
X		/* get tag */
X		tag = (int)real(c_token++);
X		if (!END_OF_COMMAND)
X			int_error("extraneous arguments to set noarrow/noline", c_token);
X		for (this_arrow = first_arrow, prev_arrow = NULL;
X			 this_arrow != NULL;
X			 prev_arrow = this_arrow, this_arrow = this_arrow->next) {
X			if (this_arrow->tag == tag) {
X				delete_arrow(prev_arrow, this_arrow);
X				return;		/* exit, our job is done */
X			}
X		}
X		int_error("arrow/line not found", c_token);
X    }
X}
X
X/* assign a new arrow tag */
X/* arrows are kept sorted by tag number, so this is easy */
Xstatic int				/* the lowest unassigned tag number */
Xassign_arrow_tag()
X{
X    struct linearrow_def *this_arrow;
X    int last = 0;			/* previous tag value */
X	
X    for (this_arrow = first_arrow; this_arrow != NULL;
X		 this_arrow = this_arrow->next)
X		if (this_arrow->tag == last+1)
X			last++;
X		else
X			break;
X	
X    return (last+1);
X}
X
X/* delete arrow from linked list started by first_arrow.
X * called with pointers to the previous arrow (prev) and the 
X * arrow to delete (this).
X * If there is no previous arrow (the arrow to delete is
X * first_arrow) then call with prev = NULL.
X */
Xstatic void
Xdelete_arrow(prev,this)
Xstruct linearrow_def *prev, *this;
X{
X    if (this!=NULL)	{		/* there really is something to delete */
X		if (prev!=NULL)		/* there is a previous arrow */
X			prev->next = this->next; 
X		else				/* this = first_arrow so change first_arrow */
X			first_arrow = this->next;
X		free((char *)this);
X    }
X}
X
Xvoid
Xshow_labels(tag, fp, save)
Xint tag;				/* 0 means show all */
XFILE *fp;
XBOOLEAN save;
X{
X    struct label_def *this_label;
X    BOOLEAN showed = FALSE;
X	
X    for (this_label = first_label; this_label != NULL;
X		 this_label = this_label->next) {
X		if (tag == 0 || tag == this_label->tag) {
X			showed = TRUE;
X			fprintf(fp,"%slabel %d \"%s\" %s at %s %lg,%lg",
X					save ? "set " : "\t",
X					this_label->tag, this_label->text,
X					(this_label->pos==LEFT ? "left" : (this_label->pos==RIGHT ? "right" : "centre")),
X					this_label->paged ? "page" : "picture",
X					this_label->x, this_label->y);
X			if (this_label->h != 0.0)
X				fprintf(fp, " height %lg", this_label->h);
X			if (this_label->w != 0.0)
X				fprintf(fp, " width %lg", this_label->w);
X			switch(this_label->rot) {
X				case L_NORMAL: {
X					break;
X				}
X				case L_UPSIDE: {
X					fprintf(fp, " direction left");
X					break;
X				}
X				case L_BOTTOM: {
X					fprintf(fp, " vertical");
X					break;
X				}
X				case L_TOP: {
X					fprintf(fp, " direction down");
X					break;
X				}
X				case L_RANDOM: {
X					fprintf(fp, " rotation %lg", this_label->a);
X					break;
X				}
X			}
X			fputc('\n',fp);
X		}
X    }
X    if (tag > 0 && !showed)
X		int_error("label not found", c_token);
X}
X
Xvoid
Xshow_arrow(tag, fp, save)
Xint tag;				/* 0 means show all */
XFILE *fp;
XBOOLEAN save;
X{
X    struct linearrow_def *this_arrow;
X    BOOLEAN showed = FALSE;
X	
X    for (this_arrow = first_arrow; this_arrow != NULL;
X		 this_arrow = this_arrow->next) {
X		if (tag == 0 || tag == this_arrow->tag) {
X			showed = TRUE;
X			fprintf(fp,"%s%s %d from %s %lg,%lg to %s %lg,%lg\n",
X					save ? "set " : "\t",
X					this_arrow->arrow ? "arrow" : "line",
X					this_arrow->tag,
X					this_arrow->startp ? "page" : "picture",
X					this_arrow->sx, this_arrow->sy,
X					this_arrow->endp ? "page" : "picture",
X					this_arrow->ex, this_arrow->ey);
X		}
X    }
X    if (tag > 0 && !showed)
X		int_error("arrow not found", c_token);
X}
X
X
X
X
X
X
X
X
X
SHAR_EOF
$TOUCH -am 0604152590 flblarr.c &&
chmod 0666 flblarr.c ||
echo "restore of flblarr.c failed"
set `wc -c flblarr.c`;Wc_c=$1
if test "$Wc_c" != "16228"; then
	echo original size 16228, current size $Wc_c
fi
# ============= fmisc.c ==============
echo "x - extracting fmisc.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > fmisc.c &&
X/* Fchart - fmisc.c */
X/*
X * Gnuplot code
X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
X *
X * Permission to use, copy, and distribute this software and its
X * documentation for any purpose with or without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and
X * that both that copyright notice and this permission notice appear
X * in supporting documentation.
X *
X * Permission to modify the software is granted, but not the right to
X * distribute the modified code.  Modifications are to be distributed
X * as patches to released version.
X *
X * This software  is provided "as is" without express or implied warranty.
X *
X *
X * AUTHORS
X *
X *   Original Software:
X *     Thomas Williams,  Colin Kelley.
X *
X *   Gnuplot 2.0 additions:
X *       Russell Lang, Dave Kotz, John Campbell.
X *
X *   Fchart changes and additions:
X *       Piotr Filip Sawicki
X *
X * send your comments or suggestions to fs@uwasa.fi
X *
X */
X
X#include <stdio.h>
X#include "plot.h"
X#include "fchart.h"
X#include "help.h"
X
X#ifdef __TURBOC__
X#include <graphics.h>
X#endif
X
Xextern BOOLEAN autoscale;
Xextern BOOLEAN auto_label;
Xextern BOOLEAN log_y;
Xextern BOOLEAN b_clockwise, p_clockwise;
Xextern BOOLEAN draw_border;
Xextern FILE* outfile;
Xextern char outstr[];
Xextern int samples;
Xextern int term;
Xextern double zero;
Xextern double base;
Xextern double radexp;
Xextern double b_wid, b_spc, b_int;
Xextern float xsize, ysize;
Xextern double roff, loff, toff, boff;
Xextern enum GRAV_DIR gravity, explode;
Xextern enum INP_STYLE inp_style;
Xextern enum DRAW_STYLE data_style;
Xextern enum FONT_STYLE vect_font;
Xextern struct pair data_place, label_plac;
Xextern int HLitem;
Xextern struct dfile data_head;
Xextern int xmin, xmax;
Xextern double treshold;
Xextern char thrname[];
Xextern char tic_form[];
Xextern int strunc;
X
Xextern BOOLEAN screen_ok;
X
Xextern int c_token, num_tokens;
Xextern struct termentry term_tbl[];
X
Xextern char *sprintf(),*strcpy();
Xstatic char *grav_name();
X
Xextern void show_labels(), show_arrow();
X
Xchar *alloc(size, message)
Xunsigned size;
Xchar *message;
X{
X	char *malloc();
X    char *p;                /* the new allocation */
X    char errbuf[100];       /* error message string */
X    extern char *malloc();
X
X    p = malloc(size);
X    if (p == (char *)NULL) {
X
X#ifndef VMS
X       FreeHelp();          /* out of memory, try to make some room */
X#endif
X
X       p = malloc(size);        /* try again */
X       if (p == (char *)NULL) {
X          /* really out of memory */
X          if (message != NULL) {
X             (void) sprintf(errbuf, "out of memory for %s", message);
X             int_error(errbuf, NO_CARET);
X             /* NOTREACHED */
X          }
X          /* else we return NULL */
X       }
X    }
X
X    return(p);
X}
X	
Xdestroy(p)		/* destroy dfile structure p and all the following */
Xstruct dfile *p;
X{
Xstruct dfile *t;
Xstruct chunk *a, *b;
Xint i;
X
X	while (p) {
X		for (a=p->data; a; ) {
X			free((char *)a->dval);
X			if (a->vlbl) {
X				for (i=0; i<a->used; i++)
X					if (a->vlbl[i])
X						free(a->vlbl[i]);
X				free((char *)a->vlbl);
X			}
X			b = a;
X			a = a->next;
X			free((char *)b);
X		}
X		if (p->fname) free(p->fname);
X		t = p;
X		p = p->dnxt;
X		free((char *)t);
X	}
X}
X
Xload_file(fp)
XFILE *fp;
X{
X	register int len;
X	extern char input_line[];
X	int start, left, more, stop = FALSE;
X
X	if (!fp)
X		os_error("Cannot open load file",c_token);
X	
X	while (!stop) {      /* read all commands in file */
X		/* read one command */
X		left = MAX_LINE_LEN;
X		start = 0;
X		more = TRUE;
X		
X		while (more) {
X			if (fgets(&(input_line[start]), left, fp) == NULL) {
X                stop = TRUE; /* EOF in file */
X                input_line[start] = '\0';
X                more = FALSE;
X			} else {
X                len = strlen(input_line) - 1;
X                if (input_line[len] == '\n') { /* remove any newline */
X                    input_line[len] = '\0';
X                    /* Look, len was 1-1 = 0 before, take care here! */
X                    if (len > 0) --len;
X                } else if (len+1 >= left)
X					int_error("Input line too long",NO_CARET);
X				
X                if (input_line[len] == '\\') { /* line continuation */
X                    start = len;
X                    left -= len;
X                } else
X					more = FALSE;
X			}
X		}
X		
X		if (strlen(input_line) > 0) {
X			screen_ok = FALSE; /* make sure command line is
X								  echoed on error */
X			do_line();
X		}
X	}
X}
X
Xsave_sets(fp)		/* save all current settings */
XFILE *fp;
X{
X	char comm[MAX_LINE_LEN+1];
X	
X	if (!fp)
X		os_error("Cannot open save file",c_token);
X
X	for(c_token++; !END_OF_COMMAND; c_token++) {
X		if (equals(c_token,",")) continue;
X		if (!isstring(c_token)) break;		/* causes error, but later */
X		quote_str(comm, c_token);
X		fprintf(fp,"# %s\n",comm);
X	}
X
X	(void) putc('\n',fp);
X	fprintf(fp,"set %sautolabel\n", auto_label ? "" : "no");
X	fprintf(fp,"set %struncate", strunc==-1 ? "no" : "");
X	if (strunc>0)
X		fprintf(fp," %d", strunc);
X	(void) putc('\n',fp);
X	fprintf(fp,"set cust ");
X	if (data_place.from != -1) {
X		show_segment(data_place.from,data_place.upto,fp);
X		(void) putc(' ',fp);
X		if (label_plac.from != -1)
X			show_segment(label_plac.from,label_plac.upto,fp);
X	}
X	(void) putc('\n',fp);
X	fprintf(fp,"set font ");
X	switch (vect_font) {
X		case F_NEVER: {
X			fprintf(fp,"never\n");
X			break;
X		}
X		case F_WHENN: {
X			fprintf(fp,"when_needed\n");
X			break;
X		}
X		case F_ROTAT: {
X			fprintf(fp,"rotated\n");
X			break;
X		}
X		case F_ALWYS: {
X			fprintf(fp,"always\n");
X			break;
X		}
X	}
X	fprintf(fp,"set format \"%s\"\n", tic_form);
X	fprintf(fp,"set %sframe\n", draw_border ? "" : "no");
X	fprintf(fp,"set highlight ");
X	switch (HLitem) {
X		case HL_MIN: {
X			fprintf(fp,"min\n");
X			break;
X		}
X		case HL_MAX: {
X			fprintf(fp,"max\n");
X			break;
X		}
X		case HL_NON: {
X			fprintf(fp,"none\n");
X			break;
X		}
X		default: {
X			fprintf(fp,"%d\n",HLitem);
X			break;
X		}
X	}
X	fprintf(fp,"set input ");
X	switch (inp_style) {
X		case GNUPLOT: {
X			fprintf(fp,"gnuplot\n");
X			break;
X		}
X		case PRIVATE: {
X			fprintf(fp,"private\n");
X			break;
X		}
X		case CUSTOMD: {
X			fprintf(fp,"customized\n");
X			break;
X		}
X	}
X	fprintf(fp,"set %slogscale\n", log_y ? "" : "no");
X	fprintf(fp,"set offsets %lg, %lg, %lg, %lg\n", loff, roff, toff, boff);
X	fprintf(fp,"set output %s\n", strcmp(outstr,"STDOUT") ? outstr : "");
X	fprintf(fp,"set size %g, %g\n", xsize, ysize);
X	fprintf(fp,"set style ");
X	switch (data_style) {
X		case ABARS:		fprintf(fp,"adj\n"); break;
X		case SBAR:		fprintf(fp,"sta\n"); break;
X		case LAYB:		fprintf(fp,"lay\n"); break;
X		case PIECHART:	fprintf(fp,"pie\n"); break;
X	}
X	fprintf(fp,"set term %s\n", term_tbl[term].name);
X	fprintf(fp,"set title ");
X	if (data_head.fname) fprintf(fp,"\"%s\"\n", data_head.fname);
X	else (void) putc('\n',fp);
X	show_labels(0, fp, TRUE);
X	show_arrow(0, fp, TRUE);
X	fprintf(fp,"set range ");
X	if (xmin != -1) show_segment(xmin,xmax,fp);
X	(void) putc('\n',fp);
X	fprintf(fp,"set zero %lg\n", zero);
X
X	(void) putc('\n',fp);
X	
X	fprintf(fp,"set bar %sautoscale\n", autoscale ? "" : "no");
X	fprintf(fp,"set bar base %lg\n", base);
X	fprintf(fp,"set bar %sclock\n", b_clockwise ? "" : "counter_");
X	fprintf(fp,"set bar grav %s\n", grav_name(gravity));
X	fprintf(fp,"set bar width %lg, %lg, %lg\n", b_wid, b_int, b_spc);
X
X	(void) putc('\n',fp);
X
X	fprintf(fp,"set pie expl %s\n", grav_name(explode));
X	fprintf(fp,"set pie %sclockwise\n", p_clockwise ? "" : "counter_");
X	fprintf(fp,"set pie radius %lg\n", radexp);
X	fprintf(fp,"set pie samples %d\n", samples);
X	fprintf(fp,"set pie threshold %lg \"%s\"\n", treshold, thrname);
X
X	(void) fclose(fp);
X}
X
Xint instring(str, c)
Xchar *str;
Xchar c;
X{
X    int pos = 0;
X	
X    while (str != NULL && *str != '\0' && c != *str) {
X		str++;
X		pos++;
X    }
X    return (pos);
X}
X
Xshow_style()
X{
X	fprintf(stderr,"\tdata are plotted with ");
X	switch (data_style) {
X		case ABARS: fprintf(stderr,"adjacent bars\n"); break;
X		case LAYB: fprintf(stderr,"layer bars\n"); break;
X		case SBAR: fprintf(stderr,"stacked bars\n"); break;
X		case PIECHART: fprintf(stderr,"piechart\n"); break;
X	}
X}
X
Xshow_range()
X{
X	if (xmin==-1)
X		fprintf(stderr,"\twhole file is processed");
X	else {
X		fprintf(stderr,"\tdata range is: ");
X		show_segment(xmin,xmax,stderr);
X	}
X	(void) putc('\n',stderr);
X}
X
Xshow_zero()
X{
X	fprintf(stderr,"\tzero/epsilon is %lg\n",zero);
X}
X
Xshow_offsets()
X{
X	fprintf(stderr,"\toffsets are %lg, %lg, %lg, %lg\n",loff,roff,toff,boff);
X}
X
Xshow_samples()
X{
X	fprintf(stderr,"\tsampling rate for piechart is %d\n",samples);
X}
X
Xshow_output()
X{
X	fprintf(stderr,"\toutput is sent to %s\n",outstr);
X}
X
Xshow_term()
X{
X	fprintf(stderr,"\tterminal type is %s\n",term_tbl[term].name);
X}
X
Xshow_autoscale()
X{
X	fprintf(stderr,"\tbar autoscaling is %s\n",(autoscale)? "ON" : "OFF");
X}
X
Xshow_logscale()
X{
X	if (log_y)
X		fprintf(stderr,"\tlogscaling is ON\n");
X	else
X		fprintf(stderr,"\tno logscaling\n");
X}
X
Xshow_version()
X{
Xextern char version[];
Xextern char date[];
Xstatic char *authors[] = {"Thomas Williams","Colin Kelley"};
Xextern int patchlevel;
Xextern char bug_email[];
Xint x;
Xlong time();
X
X	x = time((long *)NULL) & 1;
X	fprintf(stderr,"\n\t%s\n\t%sversion %s patchlevel %d\n\tlast modified %s\n",
X		PROGRAM, OS, version, patchlevel, date);
X	fprintf(stderr,"\tGnuplot v.1.x Copyright (C) 1986, 1987  %s, %s\n",
X		authors[x],authors[1-x]);
X	fprintf(stderr,"\tGnuplot v.2.0 John Campbell, David Kotz, Russell Lang\n");
X	fprintf(stderr,"\t%s Copyright (C) 1990 Piotr Filip Sawicki\n",PROGRAM);
X#ifdef __TURBOC__
X	fprintf(stderr,"\tCreated using Turbo C, Copyright Borland 1987, 1988\n");
X#endif
X	fprintf(stderr, "\n\tSend bugs and comments to %s\n\n", bug_email);
X}
X
Xstatic char *grav_name(what)
Xenum GRAV_DIR what;
X{
X	static char buf[20];
X	switch (what) {
X		case(SOUTH)   : (void) strcpy(buf,"bottom"); break;
X		case(NORTH)   : (void) strcpy(buf,"top"); break;
X		case(EAST)    : (void) strcpy(buf,"right"); break;
X		case(WEST)    : (void) strcpy(buf,"left"); break;
X		case(DEFAULT) : buf[0] = '\0'; break;
X	}
X	return(buf);
X}
X
Xshow_gravity()
X{
X	fprintf(stderr,"\tbar gravitation to the %s\n", grav_name(gravity));
X}
X
Xshow_explode()
X{
X	fprintf(stderr,"\thighlited slice explodes %s\n",
X			explode == DEFAULT
X				? "where it should"
X				: grav_name(explode));
X}
X
Xshow_HLset()
X{
X	switch (HLitem) {
X		case(HL_NON): fprintf(stderr,"\tno item"); break;
X		case(HL_MIN): fprintf(stderr,"\tminimal item"); break;
X		case(HL_MAX): fprintf(stderr,"\tmaximal item"); break;
X		default     : fprintf(stderr,"\titem no. %d",HLitem); break;
X	}
X	fprintf(stderr," is highlited\n");
X}
X
Xshow_base()
X{
X	fprintf(stderr,"\tbase for bars is %lg\n",base);
X}	
X
Xshow_input()
X{
X	switch (inp_style) {
X		case(GNUPLOT) : fprintf(stderr,"\tgnuplot-compatible"); break;
X		case(PRIVATE) : fprintf(stderr,"\tstandard"); break;
X		case(CUSTOMD) : fprintf(stderr,"\tcustomized"); break;
X	}
X	fprintf(stderr," data input style\n");
X}
X
Xshow_custom()
X{
X	if (data_place.from == -1) 
X		fprintf(stderr,"\tcustomized input format not given\n");
X	else {
X		fprintf(stderr,"\tcustomized input format:\n");
X		fprintf(stderr,"\t\tvalue: ");
X		show_segment(data_place.from,data_place.upto,stderr);
X		if (label_plac.from == -1) fprintf(stderr,"\n\t\tno label position");
X		else {
X			fprintf(stderr,"\n\t\tlabel: ");
X			show_segment(label_plac.from,label_plac.upto,stderr);
X		}
X		(void) putc('\n',stderr);
X	}
X}
X
Xstatic show_segment(l,r,fp)
Xint l,r;
XFILE *fp;
X{
X	(void) putc('[',fp);
X	if (l) fprintf(fp,"%d",l);
X	fprintf(fp," : ");
X	if (r>-1) fprintf(fp,"%d",r);
X	(void) putc(']',fp);
X}
X
Xshow_label()
X{
X	fprintf(stderr,"\tlabels are%s auto-generated\n",
X			auto_label ? "" : "n't");
X}
X
Xshow_clock(pie)
XBOOLEAN pie;
X{
X	if (pie)
X		fprintf(stderr,"\tpies are drawn %sclockwise\n",
X				p_clockwise ? "" : "counter-");
X	else
X		fprintf(stderr,"\tbars are drawn %sclockwise\n",
X				b_clockwise ? "" : "counter-");
X}
X
Xshow_width()
X{
X	fprintf(stderr,"\tbar width params are %lg, %lg, %lg\n",b_wid,b_int,b_spc);
X}
X
Xshow_radius()
X{
X	fprintf(stderr,"\texplosion radius ratio is %lg\n",radexp);
X}
X
Xshow_border()
X{
X	fprintf(stderr,"\tpicture frame is%s drawn\n",draw_border?"":" not");
X}
X
Xshow_size()
X{
X	fprintf(stderr,"\tsize is scaled by %g, %g\n",xsize,ysize);
X}
X
Xshow_title()
X{
X	if (!data_head.fname || !*(data_head.fname))
X		fprintf(stderr,"\tpicture has no title\n");
X	else
X		fprintf(stderr,"\ttitle for picture is: \"%s\"\n",data_head.fname);
X}
X
Xshow_tresh()
X{
X	fprintf(stderr,"\tslices glue threshold is %lg with name \"%s\"\n", treshold, thrname);
X}
X
Xshow_format()
X{
X	fprintf(stderr,"\tformat for numbers is: \"%s\"\n", tic_form);
X}
X
Xshow_font()
X{
X	fprintf(stderr,"\tvector font is ");
X	switch (vect_font) {
X		case F_NEVER: fprintf(stderr,"never used\n"); break;
X		case F_WHENN: fprintf(stderr,"used when needed\n"); break;
X		case F_ROTAT: fprintf(stderr,"for rotated text\n"); break;
X		case F_ALWYS: fprintf(stderr,"always used\n"); break;
X	}
X}
X
Xshow_trunc()
X{
X	fprintf(stderr,"\tlabels are%s truncated", strunc==-1 ? " not" : "");
X	if (strunc>0)
X		fprintf(stderr," at char no. %d", strunc);
X	fprintf(stderr,"\n");
X}
SHAR_EOF
$TOUCH -am 0604152590 fmisc.c &&
chmod 0666 fmisc.c ||
echo "restore of fmisc.c failed"
set `wc -c fmisc.c`;Wc_c=$1
if test "$Wc_c" != "12994"; then
	echo original size 12994, current size $Wc_c
fi
# ============= font.c ==============
echo "x - extracting font.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > font.c &&
X/* Fchart - font.c */
X/*
X * Copyright (C) 1990 Piotr Filip Sawicki
X *
X * Permission to use, copy, and distribute this software and its
X * documentation for any purpose with or without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and
X * that both that copyright notice and this permission notice appear
X * in supporting documentation.
X *
X * Permission to modify the software is granted, but not the right to
X * distribute the modified code.  Modifications are to be distributed
X * as patches to released version.
X *
X * This software  is provided "as is" without express or implied warranty.
X *
X * send your comments or suggestions to fs@uwasa.fi
X *
X ***********************************************************************
X * This file contains two vector fonts:
X *   - nonstandard my private one
X *   - public-domain Hershey Roman
X *       courtesy Joe Felsenstein, joe@genetics.washington.edu
X * Currently the latter is used, though the former has better digits.
X * To use my font, add the following line to the "fchart.h":
X * #define NO_ROMAN_FONT
X * and rebuild the entire application.
X ***********************************************************************
X *
X */
X
X#include <stdio.h>
X#include <math.h>
X#include "plot.h"
X#include "fchart.h"
X
X#ifdef NO_ROMAN_FONT
X
X/* character height: 256, character width: 20-256 */	
X
Xstatic unsigned char I_shape[] = { 10,20 , 10,220 , 0 };
Xstatic unsigned char P_shape[] = { 10,220 , 150,220 , 200,190 , 200,160 , 150,130 , 10,130 , 0 };
Xstatic unsigned char B_shape[] = { 150,130 , 200,90 , 200,55 , 150,20 , 10,20 , 0 };
Xstatic unsigned char R_shape[] = { 150,130 , 200,90 , 200,20 , 0 };
Xstatic unsigned char D_shape[] = { 10,220 , 150,220 , 200,190 , 200,55 , 150,20 , 10,20 , 0 };
Xstatic unsigned char t_shape[] = { 150,220 , 10,220 , 0 };
Xstatic unsigned char m_shape[] = { 10,120 , 150,120 , 0 };
Xstatic unsigned char l_shape[] = { 150,20 , 10,20 , 0 };
Xstatic unsigned char L_shape[] = { 10,220 , 10,20 , 150,20 , 0 };
Xstatic unsigned char i_shape[] = { 150,20 , 150,220 , 0 };
Xstatic unsigned char b_shape[] = { 10,220 , 150,20 , 0 };
Xstatic unsigned char s_shape[] = { 10,20 , 150,220 , 0 };
Xstatic unsigned char u_shape[] = { 5,10 , 105,10 , 0 };
Xstatic unsigned char T_shape[] = { 80,20 , 80,220 , 0 };
Xstatic unsigned char d1shape[] = { 80,220 , 10,170 , 0 };
Xstatic unsigned char J_shape[] = { 80,220 , 80,55 , 50,20 , 20,20 , 10,35 , 0 };
Xstatic unsigned char V_shape[] = { 80,20 , 10,220 , 0 };
Xstatic unsigned char d7shape[] = { 80,20 , 150,220 , 0 };
Xstatic unsigned char d4shape[] = { 10,220 , 10,100 , 100,100 , 0 };
Xstatic unsigned char M_shape[] = { 10,220 , 125,20 , 240,220 , 240,20 , 0 };
Xstatic unsigned char W_shape[] = { 10,220 , 80,20 , 130,130 , 180,20 , 250,220 , 0 };
Xstatic unsigned char K_shape[] = { 200,220 , 10,100 , 200,20 , 0 };		/* wrong !!! */
Xstatic unsigned char C_shape[] = { 200,190 , 150,220 , 60,220 , 10,190 , 10,55 , 60,20 , 150,20 , 200,55 , 0 };
Xstatic unsigned char O_shape[] = { 200,55 , 200,190 , 0 };
Xstatic unsigned char G_shape[] = { 200,20 , 200,120 , 120,120 , 0 };
Xstatic unsigned char Q_shape[] = { 130,55 , 190,10 , 0 };
Xstatic unsigned char d0shape[] = { 10,55 , 60,20 , 100,20 , 150,55 , 150,190 , 100,220 , 60,220 , 10,190 , 10,55 , 150,190 , 0 };
Xstatic unsigned char p_shape[] = { 10,20 , 10,20 , 0 };
Xstatic unsigned char S_shape[] = { 200,190 , 150,220 , 60,220 , 10,190 , 10,160 , 60,130 , 150,120 , 200,90 , 200,55 , 150,20 , 60,20 , 10,55 , 0 };
Xstatic unsigned char U_shape[] = { 10,220 , 10,55 , 60,20 , 100,20 , 150,55 , 150,220 , 0 };
Xstatic unsigned char A_shape[] = { 10,20 , 80,220 , 150,20 , 0 };
Xstatic unsigned char a_shape[] = { 45,100 , 115,100 , 0 };
Xstatic unsigned char Y_shape[] = { 150,220 , 80,100 , 80,20 , 0 };
Xstatic unsigned char y_shape[] = { 10,220 , 80,100 , 0 };
Xstatic unsigned char d_shape[] = { 150,180 , 100,210 , 60,210 , 10,180 , 10,150, 60,130 , 100,110 , 150,95 , 150,65 , 100,30 , 60,30 , 10,65 , 0 };
Xstatic unsigned char d2shape[] = { 10,190 , 60,220 , 100,220 , 150,190 , 150,160 , 10,55 , 10,20 , 150,20 , 0 };
Xstatic unsigned char d3shape[] = { 10,190 , 60,220 , 100,220 , 150,190 , 150,160 , 100,130 , 150,90 , 150,55 , 100,20 , 60,20 , 10,55 , 0 };
Xstatic unsigned char x_shape[] = { 80,50 , 80,190 , 0 };
Xstatic unsigned char d5shape[] = { 150,220 , 10,220 , 10,120 , 100,120 , 150,90 , 150,55 , 100,20 , 60,20 , 10,55 , 0 };
Xstatic unsigned char d6shape[] = { 150,190 , 100,220 , 60,220 , 10,190 , 10,90 , 60,120 , 100,120 , 150,90 , 150,55 , 100,20 , 60,20 , 10,55 , 10,90 , 0 };
Xstatic unsigned char d9shape[] = { 10,55 , 60,20 , 100,20 , 150,55 , 150,160 , 100,130 , 60,130 , 10,160 , 10,190 , 60,220 , 100,220 , 150,190 , 150,160 , 0 };
Xstatic unsigned char d8shape[] = { 60,130 , 100,130 , 150,160 , 150,190 , 100,220 , 60,220 , 10,190 , 10,160 , 60,130 , 10,90 , 10,55 , 60,20 , 100,20 , 150,55 , 150,90 , 100,130 , 0 };
Xstatic unsigned char pLshape[] = { 60,220 , 10,160 , 10,55 , 60,20 , 0 };
Xstatic unsigned char pRshape[] = { 10,220 , 60,160 , 60,55 , 10,20 , 0 };
X
Xstruct Char trt[128] = {
X/* . */ { 20 , p_shape , NULL , NULL }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
X		{ 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
X		{ 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
X		{ 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 },
X/*   */ {  20 , NULL , NULL , NULL }, { 0 }, { 0 }, { 0 }, 
X/* $ */ { 160 , T_shape , d_shape , NULL }, { 0 }, { 0 }, { 0 },
X/* ( */ {  70 , pLshape , NULL , NULL },
X/* ) */ {  70 , pRshape , NULL , NULL },
X		{ 0 },
X/* + */ { 160 , m_shape , x_shape , NULL },
X		{ 0 }, 
X/* - */ { 160 , m_shape , NULL , NULL },
X/* . */ { 20 , p_shape , NULL , NULL }, 
X/* / */ { 160 , s_shape , NULL , NULL },
X/* 0 */ { 160 , d0shape , NULL , NULL },
X/* 1 */ {  90 , T_shape , d1shape , NULL },
X/* 2 */ { 160 , d2shape , NULL , NULL },
X/* 3 */ { 160 , d3shape , NULL , NULL },
X/* 4 */ { 110 , T_shape , d4shape , NULL },
X/* 5 */ { 160 , d5shape , NULL , NULL },
X/* 6 */ { 160 , d6shape , NULL , NULL },
X/* 7 */ { 160 , d7shape , t_shape , NULL },
X/* 8 */ { 160 , d8shape , NULL , NULL },
X/* 9 */ { 160 , d9shape , NULL , NULL }, { 0 }, { 0 },
X		{ 0 }, { 0 }, { 0 }, { 0 },
X		{ 0 }, 
X/* A */ { 160 , A_shape , a_shape , NULL },
X/* B */ { 210 , I_shape , P_shape , B_shape },
X/* C */ { 210 , C_shape , NULL , NULL },
X/* D */ { 210 , I_shape , D_shape , NULL },
X/* E */ { 160 , t_shape , L_shape , m_shape },
X/* F */ { 160 , t_shape , I_shape , m_shape },
X/* G */ { 210 , C_shape , G_shape , NULL },
X/* H */ { 160 , I_shape , m_shape , i_shape },
X/* I */ {  20 , I_shape , NULL , NULL },
X/* J */ {  90 , J_shape , NULL , NULL },
X/* K */ { 210 , I_shape , K_shape , NULL },
X/* L */ { 160 , L_shape , NULL , NULL },
X/* M */ { 250 , I_shape , M_shape , NULL },
X/* N */ { 160 , I_shape , b_shape , i_shape },
X/* O */ { 210 , C_shape , O_shape , NULL },
X/* P */ { 210 , I_shape , P_shape , NULL },
X/* Q */ { 210 , C_shape , O_shape , Q_shape },
X/* R */ { 210 , I_shape , P_shape , R_shape },
X/* S */ { 210 , S_shape , NULL , NULL },
X/* T */ { 160 , T_shape , t_shape , NULL },
X/* U */ { 160 , U_shape , NULL , NULL },
X/* V */ { 160 , V_shape , d7shape , NULL },
X/* W */ { 260 , W_shape , NULL , NULL },
X/* X */ { 160 , b_shape , s_shape , NULL },
X/* Y */ { 160 , Y_shape , y_shape , NULL },
X/* Z */ { 160 , l_shape , s_shape , t_shape }, { 0 },
X/* \ */ { 160 , b_shape , NULL , NULL }, { 0 }, { 0 }, /* _ */ { 110 , u_shape , NULL , NULL },
X		{ 0 },
X/* A */ { 160 , A_shape , a_shape , NULL },
X/* B */ { 210 , I_shape , P_shape , B_shape },
X/* C */ { 210 , C_shape , NULL , NULL },
X/* D */ { 210 , I_shape , D_shape , NULL },
X/* E */ { 160 , t_shape , L_shape , m_shape },
X/* F */ { 160 , t_shape , I_shape , m_shape },
X/* G */ { 210 , C_shape , G_shape , NULL },
X/* H */ { 160 , I_shape , m_shape , i_shape },
X/* I */ {  20 , I_shape , NULL , NULL },
X/* J */ {  90 , J_shape , NULL , NULL },
X/* K */ { 210 , I_shape , K_shape , NULL },
X/* L */ { 160 , L_shape , NULL , NULL },
X/* M */ { 250 , I_shape , M_shape , NULL },
X/* N */ { 160 , I_shape , b_shape , i_shape },
X/* O */ { 210 , C_shape , O_shape , NULL },
X/* P */ { 210 , I_shape , P_shape , NULL },
X/* Q */ { 210 , C_shape , O_shape , Q_shape },
X/* R */ { 210 , I_shape , P_shape , R_shape },
X/* S */ { 210 , S_shape , NULL , NULL },
X/* T */ { 160 , T_shape , t_shape , NULL },
X/* U */ { 160 , U_shape , NULL , NULL },
X/* V */ { 160 , V_shape , d7shape , NULL },
X/* W */ { 260 , W_shape , NULL , NULL },
X/* X */ { 160 , b_shape , s_shape , NULL },
X/* Y */ { 160 , Y_shape , y_shape , NULL },
X/* Z */ { 160 , l_shape , s_shape , t_shape }, { 0 },
X/* | */ {  90 , T_shape , NULL , NULL }, { 0 }, { 0 }, { 0 }
X	} ;
X
X#else		/* use roman font */
X
X/* character height: 80, character width: ~30 */	
X
Xstatic int char_32[2] = { -2600, 0 };
Xstatic int char_33[9] = { -1531, 1517, -1512, 1411, 1510, 1611, 1512, -2000, 0 };
Xstatic int char_40[12] = { -2135, 1933, 1730, 1526, 1421, 1417, 1512, 1708, 1905, 2103, -2400, 0 };
Xstatic int char_41[12] = { -1335, 1533, 1730, 1926, 2021, 2017, 1912, 1708, 1505, 1303, -2400, 0 };
Xstatic int char_42[8] = { -1825, 1813, -1322, 2316, -2322, 1316, -2600, 0 };
Xstatic int char_44[10] = { -1611, 1510, 1411, 1512, 1611, 1609, 1507, 1406, -2000, 0 };
Xstatic int char_45[4] = { -1419, 3219, -3600, 0 };
Xstatic int char_46[7] = { -1512, 1411, 1510, 1611, 1512, -2000, 0 };
Xstatic int char_47[4] = { -3035, 1203, -3200, 0 };
Xstatic int char_0[19] = { -1931, 1630, 1427, 1322, 1319, 1414, 1611, 1910, 2110, 2411, 2614, 2719, 2722, 2627, 2430, 2131, 1931, -3000, 0 };
Xstatic int char_1[6] = { -1627, 1828, 2131, 2110, -3000, 0 };
Xstatic int char_2[16] = { -1426, 1427, 1529, 1630, 1831, 2231, 2430, 2529, 2627, 2625, 2523, 2320, 1310, 2710, -3000, 0 };
Xstatic int char_3[17] = { -1531, 2631, 2023, 2323, 2522, 2621, 2718, 2716, 2613, 2411, 2110, 1810, 1511, 1412, 1314, -3000, 0 };
Xstatic int char_4[7] = { -2331, 1317, 2817, -2331, 2310, -3000, 0 };
Xstatic int char_5[19] = { -2531, 1531, 1422, 1523, 1824, 2124, 2423, 2621, 2718, 2716, 2613, 2411, 2110, 1810, 1511, 1412, 1314, -3000, 0 };
Xstatic int char_6[25] = { -2628, 2530, 2231, 2031, 1730, 1527, 1422, 1417, 1513, 1711, 2010, 2110, 2411, 2613, 2716, 2717, 2620, 2422, 2123, 2023, 1722, 1520, 1417, -3000, 0 };
Xstatic int char_7[6] = { -2731, 1710, -1331, 2731, -3000, 0 };
Xstatic int char_8[31] = { -1831, 1530, 1428, 1426, 1524, 1723, 2122, 2421, 2619, 2717, 2714, 2612, 2511, 2210, 1810, 1511, 1412, 1314, 1317, 1419, 1621, 1922, 2323, 2524, 2626, 2628, 2530, 2231, 1831, -3000, 0 };
Xstatic int char_9[25] = { -2624, 2521, 2319, 2018, 1918, 1619, 1421, 1324, 1325, 1428, 1630, 1931, 2031, 2330, 2528, 2624, 2619, 2514, 2311, 2010, 1810, 1511, 1413, -3000, 0 };
Xstatic int char_58[12] = { -1524, 1423, 1522, 1623, 1524, -1512, 1411, 1510, 1611, 1512, -2000, 0 };
Xstatic int char_59[15] = { -1524, 1423, 1522, 1623, 1524, -1611, 1510, 1411, 1512, 1611, 1609, 1507, 1406, -2000, 0 };
Xstatic int char_63[21] = { -1326, 1327, 1429, 1530, 1731, 2131, 2330, 2429, 2527, 2525, 2423, 2322, 1920, 1917, -1912, 1811, 1910, 2011, 1912, -2800, 0 };
Xstatic int char_A[8] = { -1931, 1110, -1931, 2710, -1417, 2417, -2800, 0 };
Xstatic int char_B[23] = { -1431, 1410, -1431, 2331, 2630, 2729, 2827, 2825, 2723, 2622, 2321, -1421, 2321, 2620, 2719, 2817, 2814, 2712, 2611, 2310, 1410, -3100, 0 };
Xstatic int char_C[20] = { -2826, 2728, 2530, 2331, 1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, -3100, 0 };
Xstatic int char_D[16] = { -1431, 1410, -1431, 2131, 2430, 2628, 2726, 2823, 2818, 2715, 2613, 2411, 2110, 1410, -3100, 0 };
Xstatic int char_E[10] = { -1431, 1410, -1431, 2731, -1421, 2221, -1410, 2710, -2900, 0 };
Xstatic int char_F[8] = { -1431, 1410, -1431, 2731, -1421, 2221, -2800, 0 };
Xstatic int char_G[23] = { -2826, 2728, 2530, 2331, 1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, 2818, -2318, 2818, -3100, 0 };
Xstatic int char_H[8] = { -1431, 1410, -2831, 2810, -1421, 2821, -3200, 0 };
Xstatic int char_I[4] = { -1431, 1410, -1800, 0 };
Xstatic int char_J[12] = { -2231, 2215, 2112, 2011, 1810, 1610, 1411, 1312, 1215, 1217, -2600, 0 };
Xstatic int char_K[8] = { -1431, 1410, -2831, 1417, -1922, 2810, -3100, 0 };
Xstatic int char_L[6] = { -1431, 1410, -1410, 2610, -2700, 0 };
Xstatic int char_M[10] = { -1431, 1410, -1431, 2210, -3031, 2210, -3031, 3010, -3400, 0 };
Xstatic int char_N[8] = { -1431, 1410, -1431, 2810, -2831, 2810, -3200, 0 };
Xstatic int char_O[23] = { -1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, 2918, 2923, 2826, 2728, 2530, 2331, 1931, -3200, 0 };
Xstatic int char_P[14] = { -1431, 1410, -1431, 2331, 2630, 2729, 2827, 2824, 2722, 2621, 2320, 1420, -3100, 0 };
Xstatic int char_Q[25] = { -1931, 1730, 1528, 1426, 1323, 1318, 1415, 1513, 1711, 1910, 2310, 2511, 2713, 2815, 2918, 2923, 2826, 2728, 2530, 2331, 1931, -2214, 2808, -3200, 0 };
Xstatic int char_R[16] = { -1431, 1410, -1431, 2331, 2630, 2729, 2827, 2825, 2723, 2622, 2321, 1421, -2121, 2810, -3100, 0 };
Xstatic int char_S[22] = { -2728, 2530, 2231, 1831, 1530, 1328, 1326, 1424, 1523, 1722, 2320, 2519, 2618, 2716, 2713, 2511, 2210, 1810, 1511, 1313, -3000, 0 };
Xstatic int char_T[6] = { -1831, 1810, -1131, 2531, -2600, 0 };
Xstatic int char_U[12] = { -1431, 1416, 1513, 1711, 2010, 2210, 2511, 2713, 2816, 2831, -3200, 0 };
Xstatic int char_V[6] = { -1131, 1910, -2731, 1910, -2800, 0 };
Xstatic int char_W[10] = { -1231, 1710, -2231, 1710, -2231, 2710, -3231, 2710, -3400, 0 };
Xstatic int char_X[6] = { -1331, 2710, -2731, 1310, -3000, 0 };
Xstatic int char_Y[7] = { -1131, 1921, 1910, -2731, 1921, -2800, 0 };
Xstatic int char_Z[8] = { -2731, 1310, -1331, 2731, -1310, 2710, -3000, 0 };
Xstatic int char_a[18] = { -2524, 2510, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
Xstatic int char_b[18] = { -1431, 1410, -1421, 1623, 1824, 2124, 2323, 2521, 2618, 2616, 2513, 2311, 2110, 1810, 1611, 1413, -2900, 0 };
Xstatic int char_c[16] = { -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2800, 0 };
Xstatic int char_d[18] = { -2531, 2510, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
Xstatic int char_e[19] = { -1318, 2518, 2520, 2422, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2800, 0 };
Xstatic int char_f[9] = { -2031, 1831, 1630, 1527, 1510, -1224, 1924, -2200, 0 };
Xstatic int char_g[23] = { -2524, 2508, 2405, 2304, 2103, 1803, 1604, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
Xstatic int char_h[11] = { -1431, 1410, -1420, 1723, 1924, 2224, 2423, 2520, 2510, -2900, 0 };
Xstatic int char_i[9] = { -1331, 1430, 1531, 1432, 1331, -1424, 1410, -1800, 0 };
Xstatic int char_j[12] = { -1531, 1630, 1731, 1632, 1531, -1624, 1607, 1504, 1303, 1103, -2000, 0 };
Xstatic int char_k[8] = { -1431, 1410, -2424, 1414, -1818, 2510, -2700, 0 };
Xstatic int char_l[4] = { -1431, 1410, -1800, 0 };
Xstatic int char_m[18] = { -1424, 1410, -1420, 1723, 1924, 2224, 2423, 2520, 2510, -2520, 2823, 3024, 3324, 3523, 3620, 3610, -4000, 0 };
Xstatic int char_n[11] = { -1424, 1410, -1420, 1723, 1924, 2224, 2423, 2520, 2510, -2900, 0 };
Xstatic int char_o[19] = { -1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, 2616, 2618, 2521, 2323, 2124, 1824, -2900, 0 };
Xstatic int char_p[18] = { -1424, 1403, -1421, 1623, 1824, 2124, 2323, 2521, 2618, 2616, 2513, 2311, 2110, 1810, 1611, 1413, -2900, 0 };
Xstatic int char_q[18] = { -2524, 2503, -2521, 2323, 2124, 1824, 1623, 1421, 1318, 1316, 1413, 1611, 1810, 2110, 2311, 2513, -2900, 0 };
Xstatic int char_r[9] = { -1424, 1410, -1418, 1521, 1723, 1924, 2224, -2300, 0 };
Xstatic int char_s[19] = { -2421, 2323, 2024, 1724, 1423, 1321, 1419, 1618, 2117, 2316, 2414, 2413, 2311, 2010, 1710, 1411, 1313, -2700, 0 };
Xstatic int char_t[9] = { -1531, 1514, 1611, 1810, 2010, -1224, 1924, -2200, 0 };
Xstatic int char_u[11] = { -1424, 1414, 1511, 1710, 2010, 2211, 2514, -2524, 2510, -2900, 0 };
Xstatic int char_v[6] = { -1224, 1810, -2424, 1810, -2600, 0 };
Xstatic int char_w[10] = { -1324, 1710, -2124, 1710, -2124, 2510, -2924, 2510, -3200, 0 };
Xstatic int char_x[6] = { -1324, 2410, -2424, 1310, -2700, 0 };
Xstatic int char_y[10] = { -1224, 1810, -2424, 1810, 1606, 1404, 1203, 1103, -2600, 0 };
Xstatic int char_z[8] = { -2424, 1310, -1324, 2424, -1310, 2410, -2700, 0 };
Xstruct Char trt[128] = {
X/* ^@ */ 	{ 10 , char_46 },
X/* ^A */ 	{ 10 , char_46 },
X/* ^B */ 	{ 10 , char_46 },
X/* ^C */ 	{ 10 , char_46 },
X/* ^D */ 	{ 10 , char_46 },
X/* ^E */ 	{ 10 , char_46 },
X/* ^F */ 	{ 10 , char_46 },
X/* ^G */ 	{ 10 , char_46 },
X/* ^H */ 	{ 10 , char_46 },
X/* ^I */ 	{ 10 , char_46 },
X/* ^J */ 	{ 10 , char_46 },
X/* ^K */ 	{ 10 , char_46 },
X/* ^L */ 	{ 10 , char_46 },
X/* ^M */ 	{ 10 , char_46 },
X/* ^N */ 	{ 10 , char_46 },
X/* ^O */ 	{ 10 , char_46 },
X/* ^P */ 	{ 10 , char_46 },
X/* ^Q */ 	{ 10 , char_46 },
X/* ^R */ 	{ 10 , char_46 },
X/* ^S */ 	{ 10 , char_46 },
X/* ^T */ 	{ 10 , char_46 },
X/* ^U */ 	{ 10 , char_46 },
X/* ^V */ 	{ 10 , char_46 },
X/* ^W */ 	{ 10 , char_46 },
X/* ^X */ 	{ 10 , char_46 },
X/* ^Y */ 	{ 10 , char_46 },
X/* ^Z */ 	{ 10 , char_46 },
X/* ^[ */ 	{ 10 , char_46 },
X/* ^\ */ 	{ 10 , char_46 },
X/* ^] */ 	{ 10 , char_46 },
X/* ^^ */ 	{ 10 , char_46 },
X/* ^_ */ 	{ 10 , char_46 },
X/*    */ 	{ 16 , char_32 },
X/*  ! */ 	{ 10 , char_33 },
X/*  " */ 	{ 10 , char_46 },
X/*  # */ 	{ 10 , char_46 },
X/*  $ */ 	{ 10 , char_46 },
X/*  % */ 	{ 10 , char_46 },
X/*  & */ 	{ 10 , char_46 },
X/*  ' */ 	{ 10 , char_46 },
X/*  ( */ 	{ 14 , char_40 },
X/*  ) */ 	{ 14 , char_41 },
X/*  * */ 	{ 16 , char_42 },
X/*  + */ 	{ 10 , char_46 },
X/*  , */ 	{ 10 , char_44 },
X/*  - */ 	{ 26 , char_45 },
X/*  . */ 	{ 10 , char_46 },
X/*  / */ 	{ 22 , char_47 },
X/*  0 */ 	{ 20 , char_0 },
X/*  1 */ 	{ 20 , char_1 },
X/*  2 */ 	{ 20 , char_2 },
X/*  3 */ 	{ 20 , char_3 },
X/*  4 */ 	{ 20 , char_4 },
X/*  5 */ 	{ 20 , char_5 },
X/*  6 */ 	{ 20 , char_6 },
X/*  7 */ 	{ 20 , char_7 },
X/*  8 */ 	{ 20 , char_8 },
X/*  9 */ 	{ 20 , char_9 },
X/*  : */ 	{ 10 , char_58 },
X/*  ; */ 	{ 10 , char_59 },
X/*  < */ 	{ 10 , char_46 },
X/*  = */ 	{ 10 , char_46 },
X/*  > */ 	{ 10 , char_46 },
X/*  ? */ 	{ 18 , char_63 },
X/*  @ */ 	{ 10 , char_46 },
X/*  A */ 	{ 18 , char_A },
X/*  B */ 	{ 21 , char_B },
X/*  C */ 	{ 21 , char_C },
X/*  D */ 	{ 21 , char_D },
X/*  E */ 	{ 19 , char_E },
X/*  F */ 	{ 18 , char_F },
X/*  G */ 	{ 21 , char_G },
X/*  H */ 	{ 22 , char_H },
X/*  I */ 	{  8 , char_I },
X/*  J */ 	{ 16 , char_J },
X/*  K */ 	{ 21 , char_K },
X/*  L */ 	{ 17 , char_L },
X/*  M */ 	{ 24 , char_M },
X/*  N */ 	{ 22 , char_N },
X/*  O */ 	{ 22 , char_O },
X/*  P */ 	{ 21 , char_P },
X/*  Q */ 	{ 22 , char_Q },
X/*  R */ 	{ 21 , char_R },
X/*  S */ 	{ 20 , char_S },
X/*  T */ 	{ 16 , char_T },
X/*  U */ 	{ 22 , char_U },
X/*  V */ 	{ 18 , char_V },
X/*  W */ 	{ 24 , char_W },
X/*  X */ 	{ 20 , char_X },
X/*  Y */ 	{ 18 , char_Y },
X/*  Z */ 	{ 20 , char_Z },
X/*  [ */ 	{ 10 , char_46 },
X/*  \ */ 	{ 10 , char_46 },
X/*  ] */ 	{ 10 , char_46 },
X/*  ^ */ 	{ 10 , char_46 },
X/*  _ */ 	{ 10 , char_46 },
X/*  ` */ 	{ 10 , char_46 },
X/*  a */ 	{ 19 , char_a },
X/*  b */ 	{ 19 , char_b },
X/*  c */ 	{ 18 , char_c },
X/*  d */ 	{ 19 , char_d },
X/*  e */ 	{ 18 , char_e },
X/*  f */ 	{ 12 , char_f },
X/*  g */ 	{ 19 , char_g },
X/*  h */ 	{ 19 , char_h },
X/*  i */ 	{  8 , char_i },
X/*  j */ 	{ 10 , char_j },
X/*  k */ 	{ 17 , char_k },
X/*  l */ 	{  8 , char_l },
X/*  m */ 	{ 30 , char_m },
X/*  n */ 	{ 19 , char_n },
X/*  o */ 	{ 19 , char_o },
X/*  p */ 	{ 19 , char_p },
X/*  q */ 	{ 19 , char_q },
X/*  r */ 	{ 13 , char_r },
X/*  s */ 	{ 17 , char_s },
X/*  t */ 	{ 12 , char_t },
X/*  u */ 	{ 19 , char_u },
X/*  v */ 	{ 16 , char_v },
X/*  w */ 	{ 22 , char_w },
X/*  x */ 	{ 17 , char_x },
X/*  y */ 	{ 16 , char_y },
X/*  z */ 	{ 17 , char_z },
X/*  { */ 	{ 10 , char_46 },
X/*  | */ 	{ 10 , char_46 },
X/*  } */ 	{ 10 , char_46 },
X/*  ~ */ 	{ 10 , char_46 },
X/* 46 */ 	{ 10 , char_46 }
X};
X
X#endif 		/* NO_ROMAN_FONT */
X
X/* procedures for vector fonts */
X
Xtransp(tx, ty, A)
Xint tx, ty;
XMATRIX A;
X/* transpose */
X{
X	register int i, j;
X	for (i=0; i<3; i++) {
X		for (j=0; j<3; j++)
X			A[i][j] = 0.0;
X		A[i][i] = 1.0;
X	}
X	A[0][2] = -tx;
X	A[1][2] = -ty;
X}
X
Xscale(sx, sy, A)
Xdouble sx, sy;
XMATRIX A;
X/* scale */
X{
X	register int i, j;
X	for (i=0; i<3; i++)
X		for (j=0; j<3; j++)
X			A[i][j] = 0.0;
X	A[0][0] = sx;
X	A[1][1] = sy;
X	A[2][2] = 1.0;
X}
X
Xrotat(al, A)
Xdouble al;
XMATRIX A;
X/* rotate */
X{
X	register int i;
X	double s;
X	for (i=0; i<2; i++)
X		A[i][2] = A[2][i] = 0.0;
X	A[2][2] = 1.0;
X	s = sin(al);
X	A[0][0] = A[1][1] = cos(al);
X	A[0][1] = s;
X	A[1][0] = -s;
X}
X
Xmulti(A, B, C)
XMATRIX A, B, C;
X/* multiply matrices */
X{
X	register int i, j, k;
X	register double db;
X	for (i=0; i<3; i++) 
X		for (j=0; j<3; j++) {
X			for (k=0, db=0.0; k<3; k++)
X				db += A[i][k] * B[k][j];
X			C[i][j] = db;
X		}
X}
SHAR_EOF
$TOUCH -am 0604152590 font.c &&
chmod 0666 font.c ||
echo "restore of font.c failed"
set `wc -c font.c`;Wc_c=$1
if test "$Wc_c" != "20937"; then
	echo original size 20937, current size $Wc_c
fi
echo "End of part 3, continue with part 4"
exit 0