version 1.1.1.1, 2000/01/09 17:00:51 |
version 1.1.1.3, 2003/09/15 07:09:24 |
Line 37 static char *RCSid = "$Id$"; |
|
Line 37 static char *RCSid = "$Id$"; |
|
|
|
#include "plot.h" |
#include "plot.h" |
#include "setshow.h" |
#include "setshow.h" |
|
#include "alloc.h" |
|
|
/* key placement is calculated in boundary, so we need file-wide variables |
/* key placement is calculated in boundary, so we need file-wide variables |
* To simplify adjustments to the key, we set all these once [depends on |
* To simplify adjustments to the key, we set all these once [depends on |
Line 137 static double make_tics __PROTO((int axis, int guide)) |
|
Line 138 static double make_tics __PROTO((int axis, int guide)) |
|
/* widest2d_callback keeps longest so far in here */ |
/* widest2d_callback keeps longest so far in here */ |
static int widest_tic; |
static int widest_tic; |
|
|
static void widest2d_callback __PROTO((int axis, double place, char *text, |
/* HBB 20010118: these should be static, but can't --- HP-UX assembler bug */ |
struct lp_style_type grid)); |
void widest2d_callback __PROTO((int axis, double place, char *text, |
static void ytick2d_callback __PROTO((int axis, double place, char *text, |
struct lp_style_type grid)); |
struct lp_style_type grid)); |
void ytick2d_callback __PROTO((int axis, double place, char *text, |
static void xtick2d_callback __PROTO((int axis, double place, char *text, |
struct lp_style_type grid)); |
struct lp_style_type grid)); |
void xtick2d_callback __PROTO((int axis, double place, char *text, |
|
struct lp_style_type grid)); |
|
int histeps_compare __PROTO((SORTFUNC_ARGS p1, SORTFUNC_ARGS p2)); |
static void map_position __PROTO((struct position * pos, unsigned int *x, |
static void map_position __PROTO((struct position * pos, unsigned int *x, |
unsigned int *y, char *what)); |
unsigned int *y, char *what)); |
static void mant_exp __PROTO((double log_base, double x, int scientific, |
static void mant_exp __PROTO((double log_base, double x, int scientific, |
Line 244 static double scale[AXIS_ARRAY_SIZE]; /* scale factors |
|
Line 247 static double scale[AXIS_ARRAY_SIZE]; /* scale factors |
|
|
|
/* (DFK) Watch for cancellation error near zero on axes labels */ |
/* (DFK) Watch for cancellation error near zero on axes labels */ |
/* less than one hundredth of a tic mark */ |
/* less than one hundredth of a tic mark */ |
#define SIGNIF (0.01) |
|
#define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x)) |
#define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x)) |
#define NearlyEqual(x,y,tic) (fabs((x)-(y)) < ((tic) * SIGNIF)) |
#define NearlyEqual(x,y,tic) (fabs((x)-(y)) < ((tic) * SIGNIF)) |
/*}}} */ |
/*}}} */ |
Line 425 char *axis_name; |
|
Line 427 char *axis_name; |
|
/* we determine widest tick label by getting gen_ticks to call this |
/* we determine widest tick label by getting gen_ticks to call this |
* routine with every label |
* routine with every label |
*/ |
*/ |
|
/* HBB 20010118: all the *_callback() functions made non-static. This |
|
* is necessary to work around a bug in HP's assembler shipped with |
|
* HP-UX 10 and higher, if GCC tries to use it */ |
|
|
static void widest2d_callback(axis, place, text, grid) |
void widest2d_callback(axis, place, text, grid) |
int axis; |
int axis; |
double place; |
double place; |
char *text; |
char *text; |
Line 461 struct lp_style_type grid; |
|
Line 466 struct lp_style_type grid; |
|
*/ |
*/ |
|
|
static void boundary(scaling, plots, count) |
static void boundary(scaling, plots, count) |
TBOOLEAN scaling; /* TRUE if terminal is doing the scaling */ |
TBOOLEAN scaling; /* TRUE if terminal is doing the scaling */ |
struct curve_points *plots; |
struct curve_points *plots; |
int count; |
int count; |
{ |
{ |
int ytlen; |
int ytlen; |
int yticlin = 0, y2ticlin = 0, timelin = 0; |
int yticlin = 0, y2ticlin = 0, timelin = 0; |
|
|
/* compute ytop from the various components |
/* compute ytop from the various components |
* unless tmargin is explicitly specified */ |
* unless tmargin is explicitly specified */ |
|
|
ytop = (int) ((ysize + yoffset) * (t->ymax)); |
/* HBB 20020426: fix round-off bug --- in 3.8 since 20010118 ;-[ */ |
|
ytop = (int) (0.5 + (ysize + yoffset) * (t->ymax)); |
|
|
if (tmargin < 0) { |
if (tmargin < 0) { |
int top_margin = x2label_textheight + title_textheight; |
int top_margin = x2label_textheight + title_textheight; |
|
|
top_margin = y2label_textheight; |
top_margin = y2label_textheight; |
|
|
top_margin += x2tic_height + x2tic_textheight; |
top_margin += x2tic_height + x2tic_textheight; |
/* FIXME: what is this additional space reservation for??? */ |
/* x2tic_height and x2tic_textheight are computed as only the |
|
* relevant heights, but they nonetheless need a blank |
|
* space above them */ |
if (top_margin > x2tic_height) |
if (top_margin > x2tic_height) |
top_margin += (int) (t->v_char); |
top_margin += (int) (t->v_char); |
|
|
ytop -= top_margin; |
ytop -= top_margin; |
if (ytop == (int) ((ysize + yoffset) * (t->ymax))) { |
if (ytop == (int) (0.5 + (ysize + yoffset) * (t->ymax))) { |
/* make room for the end of rotated ytics or y2tics */ |
/* make room for the end of rotated ytics or y2tics */ |
ytop -= (int) ((t->h_char) * 2); |
ytop -= (int) ((t->h_char) * 2); |
} |
} |
|
|
|
|
/* xlabel */ |
/* xlabel */ |
if (xlablin) { |
if (xlablin) { |
/* offset is subtracted because if . 0, the margin is smaller */ |
/* offset is subtracted because if > 0, the margin is smaller */ |
xlabel_textheight = (int) ((xlablin - xlabel.yoffset) * (t->v_char)); |
xlabel_textheight = (int) ((xlablin - xlabel.yoffset) * (t->v_char)); |
if (!xtics) |
if (!xtics) |
xlabel_textheight += 0.5 * t->v_char; |
xlabel_textheight += 0.5 * t->v_char; |
|
|
* DBT 11-18-98 resize plot for vertical timelabels too ! |
* DBT 11-18-98 resize plot for vertical timelabels too ! |
*/ |
*/ |
/* offset is subtracted because if . 0, the margin is smaller */ |
/* offset is subtracted because if . 0, the margin is smaller */ |
timebot_textheight = (int) ((timelin - timelabel.yoffset + 1.5) * (t->v_char)); |
timebot_textheight = (int) ((timelin - timelabel.yoffset) * (t->v_char)); |
} |
} else |
else |
|
timebot_textheight = 0; |
timebot_textheight = 0; |
|
|
/* compute ybot from the various components |
/* compute ybot from the various components |
* unless bmargin is explicitly specified */ |
* unless bmargin is explicitly specified */ |
|
|
ybot = (int) ((t->ymax) * yoffset); |
ybot = (int) (0.5 + (t->ymax) * yoffset); |
|
|
if (bmargin < 0) { |
if (bmargin < 0) { |
ybot += xtic_height + xtic_textheight; |
ybot += xtic_height + xtic_textheight; |
if (timebot_textheight > 0 || xlabel_textheight > 0) |
if (xlabel_textheight > 0) |
ybot += (timebot_textheight > xlabel_textheight) ? timebot_textheight : xlabel_textheight; |
ybot += xlabel_textheight; |
if (ybot == (t->ymax) * yoffset) { |
if (timebot_textheight > 0) |
|
ybot += timebot_textheight; |
|
/* HBB 19990616: round to nearest integer, required to escape |
|
* floating point inaccuracies */ |
|
if (ybot == (int)(0.5 + (t->ymax) * yoffset)) { |
/* make room for the end of rotated ytics or y2tics */ |
/* make room for the end of rotated ytics or y2tics */ |
ybot += (int) ((t->h_char) * 2); |
ybot += (int) ((t->h_char) * 2); |
} |
} |
|
|
if (key_entry_height < (t->v_char)) |
if (key_entry_height < (t->v_char)) |
key_entry_height = (t->v_char) * key_vert_factor; |
key_entry_height = (t->v_char) * key_vert_factor; |
|
|
|
/* HBB 20020122: safeguard to prevent division by zero later */ |
|
if (key_entry_height == 0) |
|
key_entry_height = 1; |
|
|
/* count max_len key and number keys with len > 0 */ |
/* count max_len key and number keys with len > 0 */ |
max_ptitl_len = find_maxl_keys(plots, count, &ptitl_cnt); |
max_ptitl_len = find_maxl_keys(plots, count, &ptitl_cnt); |
if ((ytlen = label_width(key_title, &ktitl_lines)) > max_ptitl_len) |
if ((ytlen = label_width(key_title, &ktitl_lines)) > max_ptitl_len) |
|
|
/* compute xleft from the various components |
/* compute xleft from the various components |
* unless lmargin is explicitly specified */ |
* unless lmargin is explicitly specified */ |
|
|
xleft = (int) ((t->xmax) * xoffset); |
xleft = (int) (0.5 + (t->xmax) * xoffset); |
|
|
if (lmargin < 0) { |
if (lmargin < 0) { |
xleft += (timelabel_textwidth > ylabel_textwidth ? timelabel_textwidth : ylabel_textwidth) |
xleft += (timelabel_textwidth > ylabel_textwidth ? timelabel_textwidth : ylabel_textwidth) |
+ ytic_width + ytic_textwidth; |
+ ytic_width + ytic_textwidth; |
|
|
if (xleft == (t->xmax) * xoffset) { |
/* make sure xleft is wide enough for a negatively |
|
* x-offset horizontal timestamp |
|
*/ |
|
if (!vertical_timelabel && xleft - ytic_width - ytic_textwidth < -(int) (timelabel.xoffset * (t->h_char))) |
|
xleft = ytic_width + ytic_textwidth - (int) (timelabel.xoffset * (t->h_char)); |
|
if (xleft == (int)(0.5 + (t->xmax) * xoffset)) { |
/* make room for end of xtic or x2tic label */ |
/* make room for end of xtic or x2tic label */ |
xleft += (int) ((t->h_char) * 2); |
xleft += (int) ((t->h_char) * 2); |
} |
} |
|
|
} else |
} else |
xleft += (int) (lmargin * (t->h_char)); |
xleft += (int) (lmargin * (t->h_char)); |
|
|
/* make sure xleft is wide enough for a negatively |
|
* x-offset horizontal timestamp |
|
*/ |
|
if (!vertical_timelabel && xleft - ytic_width - ytic_textwidth < -(int) (timelabel.xoffset * (t->h_char))) |
|
xleft = ytic_width + ytic_textwidth - (int) (timelabel.xoffset * (t->h_char)); |
|
/* end of xleft calculation }}} */ |
/* end of xleft calculation }}} */ |
|
|
|
|
|
|
/* compute xright from the various components |
/* compute xright from the various components |
* unless rmargin is explicitly specified */ |
* unless rmargin is explicitly specified */ |
|
|
xright = (int) ((t->xmax) * (xsize + xoffset)); |
xright = (int) (0.5 + (t->xmax) * (xsize + xoffset)); |
|
|
if (rmargin < 0) { |
if (rmargin < 0) { |
/* xright -= y2label_textwidth + y2tic_width + y2tic_textwidth; */ |
/* xright -= y2label_textwidth + y2tic_width + y2tic_textwidth; */ |
|
|
xright -= key_col_wth * key_cols; |
xright -= key_col_wth * key_cols; |
key_xl = xright + (int) (t->h_tic); |
key_xl = xright + (int) (t->h_tic); |
} |
} |
if (xright == (t->xmax) * (xsize + xoffset)) { |
if (xright == (int)(0.5 + (t->xmax) * (xsize + xoffset))) { |
/* make room for end of xtic or x2tic label */ |
/* make room for end of xtic or x2tic label */ |
xright -= (int) ((t->h_char) * 2); |
xright -= (int) ((t->h_char) * 2); |
} |
} |
|
|
double current_aspect_ratio; |
double current_aspect_ratio; |
|
|
if (aspect_ratio < 0 && (max_array[x_axis] - min_array[x_axis]) != 0.0) { |
if (aspect_ratio < 0 && (max_array[x_axis] - min_array[x_axis]) != 0.0) { |
current_aspect_ratio = -aspect_ratio * (max_array[y_axis] - min_array[y_axis]) / (max_array[x_axis] - min_array[x_axis]); |
current_aspect_ratio = -aspect_ratio * fabs((max_array[y_axis] - min_array[y_axis]) / (max_array[x_axis] - min_array[x_axis])); |
} else |
} else |
current_aspect_ratio = aspect_ratio; |
current_aspect_ratio = aspect_ratio; |
|
|
|
|
/* too tall */ |
/* too tall */ |
ytop = ybot + required * (xright - xleft); |
ytop = ybot + required * (xright - xleft); |
} else { |
} else { |
/* HBB: y2label_x wasn't defined yet, and would be |
|
* overwritten later */ |
|
xright = xleft + (ytop - ybot) / required; |
xright = xleft + (ytop - ybot) / required; |
} |
} |
} |
} |
|
|
if (tmargin < 0 && x2tics & TICS_ON_BORDER && vertical_x2tics) { |
if (tmargin < 0 && x2tics & TICS_ON_BORDER && vertical_x2tics) { |
widest_tic = 0; /* reset the global variable ... */ |
widest_tic = 0; /* reset the global variable ... */ |
gen_tics(SECOND_X_AXIS, &x2ticdef, 0, 0, 0.0, widest2d_callback); |
gen_tics(SECOND_X_AXIS, &x2ticdef, 0, 0, 0.0, widest2d_callback); |
/* HBB: redid this: remove rough guess value first. Among other reasons, |
|
* I suspected the '-4 lines' of the original code to be in error, as the |
|
* original calc. of x2tic_textheight uses *5* lines */ |
|
ytop += x2tic_textheight; |
ytop += x2tic_textheight; |
/* Now compute a new one and use that instead: */ |
/* Now compute a new one and use that instead: */ |
x2tic_textheight = (int) ((t->h_char) * (widest_tic)); |
x2tic_textheight = (int) ((t->h_char) * (widest_tic)); |
ytop -= x2tic_textheight; |
ytop -= x2tic_textheight; |
} |
} |
if (bmargin < 0 && xtics & TICS_ON_BORDER && vertical_xtics) { |
if (bmargin < 0 && xtics & TICS_ON_BORDER && vertical_xtics) { |
widest_tic = 0; /* reset the global variable ... */ |
widest_tic = 0; /* reset the global variable ... */ |
gen_tics(FIRST_X_AXIS, &xticdef, 0, 0, 0.0, widest2d_callback); |
gen_tics(FIRST_X_AXIS, &xticdef, 0, 0, 0.0, widest2d_callback); |
/* HBB: same changes as for tmargin/ytop above */ |
|
ybot -= xtic_textheight; |
ybot -= xtic_textheight; |
xtic_textheight = (int) ((t->h_char) * widest_tic); |
xtic_textheight = (int) ((t->h_char) * widest_tic); |
ybot += xtic_textheight; |
ybot += xtic_textheight; |
|
|
|
|
y2label_y = ytop + x2tic_height + x2tic_textheight + y2label_textheight; |
y2label_y = ytop + x2tic_height + x2tic_textheight + y2label_textheight; |
|
|
xlabel_y = ybot - xtic_height - xtic_textheight - xlabel_textheight + t->v_char; |
xlabel_y = ybot - xtic_height - xtic_textheight - xlabel_textheight + xlablin*(t->v_char); |
ylabel_x = xleft - ytic_width - ytic_textwidth; |
ylabel_x = xleft - ytic_width - ytic_textwidth; |
if (*ylabel.text && can_rotate) |
if (*ylabel.text && can_rotate) |
ylabel_x -= ylabel_textwidth; |
ylabel_x -= ylabel_textwidth; |
|
|
y2label_x = xright + y2tic_width + y2tic_textwidth; |
y2label_x = xright + y2tic_width + y2tic_textwidth; |
if (*y2label.text && can_rotate) |
if (*y2label.text && can_rotate) |
y2label_x += y2label_textwidth - t->v_char; |
y2label_x += y2label_textwidth - y2lablin * t->v_char; |
|
|
if (vertical_timelabel) { |
if (vertical_timelabel) { |
if (timelabel_bottom) |
if (timelabel_bottom) |
time_y = xlabel_y - timebot_textheight + xlabel_textheight; |
time_y = ybot - xtic_height - xtic_textheight - xlabel_textheight - timebot_textheight + t->v_char; |
else { |
else { |
time_y = title_y + timetop_textheight - title_textheight - x2label_textheight; |
time_y = title_y + timetop_textheight - title_textheight - x2label_textheight; |
} |
} |
} else { |
} else { |
if (timelabel_bottom) |
if (timelabel_bottom) |
time_y = xlabel_y - timebot_textheight + xlabel_textheight; |
time_y = ybot - xtic_height - xtic_textheight - xlabel_textheight - timebot_textheight + t->v_char; |
else if (ylabel_textheight > 0) |
else if (ylabel_textheight > 0) |
time_y = ylabel_y + timetop_textheight; |
time_y = ylabel_y + timetop_textheight; |
else |
else |
Line 1176 double amin, amax; |
|
Line 1185 double amin, amax; |
|
*/ |
*/ |
|
|
double set_tic(l10, guide) |
double set_tic(l10, guide) |
double l10; |
double l10; |
int guide; |
int guide; |
{ |
{ |
double xnorm, tics, posns; |
double xnorm, tics, posns; |
|
|
|
|
|
|
/*{{{ make_tics() */ |
/*{{{ make_tics() */ |
static double make_tics(axis, guide) |
static double make_tics(axis, guide) |
int axis, guide; |
int axis, guide; |
{ |
{ |
register double xr, tic, l10; |
register double xr, tic, l10; |
|
|
Line 1286 int axis, guide; |
|
Line 1295 int axis, guide; |
|
|
|
|
|
void do_plot(plots, pcount) |
void do_plot(plots, pcount) |
struct curve_points *plots; |
struct curve_points *plots; |
int pcount; /* count of plots in linked list */ |
int pcount; /* count of plots in linked list */ |
{ |
{ |
|
|
/* BODGES BEFORE I FIX IT UP */ |
|
#define ytic ticstep[y_axis] |
|
#define xtic ticstep[x_axis] |
|
|
|
register struct termentry *t = term; |
register struct termentry *t = term; |
register int curve; |
register int curve; |
int axis_zero[AXIS_ARRAY_SIZE]; /* axes in terminal coords for FIRST_X_AXIS, etc */ |
int axis_zero[AXIS_ARRAY_SIZE]; /* axes in terminal coords for FIRST_X_AXIS, etc */ |
Line 1304 int pcount; /* count of plots in linked list */ |
|
Line 1308 int pcount; /* count of plots in linked list */ |
|
struct text_label *this_label; |
struct text_label *this_label; |
struct arrow_def *this_arrow; |
struct arrow_def *this_arrow; |
TBOOLEAN scaling; |
TBOOLEAN scaling; |
char ss[MAX_LINE_LEN + 1], *s, *e; |
char *s, *e; |
|
|
/* so that macros for x_min etc pick up correct values |
/* so that macros for x_min etc pick up correct values |
* until this is done properly |
* until this is done properly |
Line 1370 int pcount; /* count of plots in linked list */ |
|
Line 1374 int pcount; /* count of plots in linked list */ |
|
|
|
/* label first y axis tics */ |
/* label first y axis tics */ |
if (ytics) { |
if (ytics) { |
int axis = map_x(ZERO); |
|
/* set the globals ytick2d_callback() needs */ |
/* set the globals ytick2d_callback() needs */ |
|
|
if (rotate_ytics && (*t->text_angle) (1)) { |
if (rotate_ytics && (*t->text_angle) (1)) { |
Line 1389 int pcount; /* count of plots in linked list */ |
|
Line 1392 int pcount; /* count of plots in linked list */ |
|
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
|
|
if ((ytics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(axis, xleft, xright)) { |
if ((ytics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(0.0, x_min, x_max)) { |
tic_start = axis; |
tic_start = map_x(0.0); |
tic_direction = -1; |
tic_direction = -1; |
if (ytics & TICS_MIRROR) |
if (ytics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1410 int pcount; /* count of plots in linked list */ |
|
Line 1413 int pcount; /* count of plots in linked list */ |
|
} |
} |
/* label first x axis tics */ |
/* label first x axis tics */ |
if (xtics) { |
if (xtics) { |
int axis = map_y(ZERO); |
|
/* set the globals xtick2d_callback() needs */ |
/* set the globals xtick2d_callback() needs */ |
|
|
if (rotate_xtics && (*t->text_angle) (1)) { |
if (rotate_xtics && (*t->text_angle) (1)) { |
Line 1427 int pcount; /* count of plots in linked list */ |
|
Line 1429 int pcount; /* count of plots in linked list */ |
|
tic_mirror = ytop; |
tic_mirror = ytop; |
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
if ((xtics & TICS_ON_AXIS) && !log_array[FIRST_Y_AXIS] && inrange(axis, ybot, ytop)) { |
if ((xtics & TICS_ON_AXIS) && !log_array[FIRST_Y_AXIS] && inrange(0.0, y_min, y_max)) { |
tic_start = axis; |
tic_start = map_y(0.0); |
tic_direction = -1; |
tic_direction = -1; |
if (xtics & TICS_MIRROR) |
if (xtics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1455 int pcount; /* count of plots in linked list */ |
|
Line 1457 int pcount; /* count of plots in linked list */ |
|
/* label second y axis tics */ |
/* label second y axis tics */ |
if (y2tics) { |
if (y2tics) { |
/* set the globalss ytick2d_callback() needs */ |
/* set the globalss ytick2d_callback() needs */ |
int axis = map_x(ZERO); |
|
|
|
if (rotate_y2tics && (*t->text_angle) (1)) { |
if (rotate_y2tics && (*t->text_angle) (1)) { |
tic_hjust = CENTRE; |
tic_hjust = CENTRE; |
Line 1471 int pcount; /* count of plots in linked list */ |
|
Line 1472 int pcount; /* count of plots in linked list */ |
|
tic_mirror = xleft; |
tic_mirror = xleft; |
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
if ((y2tics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(axis, xleft, xright)) { |
if ((y2tics & TICS_ON_AXIS) && !log_array[FIRST_X_AXIS] && inrange(0.0, x_min, x_max)) { |
tic_start = axis; |
tic_start = map_x(0.0); |
tic_direction = 1; |
tic_direction = 1; |
if (y2tics & TICS_MIRROR) |
if (y2tics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1491 int pcount; /* count of plots in linked list */ |
|
Line 1492 int pcount; /* count of plots in linked list */ |
|
} |
} |
/* label second x axis tics */ |
/* label second x axis tics */ |
if (x2tics) { |
if (x2tics) { |
int axis = map_y(ZERO); |
|
/* set the globals xtick2d_callback() needs */ |
/* set the globals xtick2d_callback() needs */ |
|
|
if (rotate_x2tics && (*t->text_angle) (1)) { |
if (rotate_x2tics && (*t->text_angle) (1)) { |
Line 1508 int pcount; /* count of plots in linked list */ |
|
Line 1508 int pcount; /* count of plots in linked list */ |
|
tic_mirror = ybot; |
tic_mirror = ybot; |
else |
else |
tic_mirror = -1; /* no thank you */ |
tic_mirror = -1; /* no thank you */ |
if ((x2tics & TICS_ON_AXIS) && !log_array[SECOND_Y_AXIS] && inrange(axis, ybot, ytop)) { |
if ((x2tics & TICS_ON_AXIS) && !log_array[SECOND_Y_AXIS] && inrange(0.0, y_min, y_max)) { |
tic_start = axis; |
tic_start = map_y(0.0); |
tic_direction = 1; |
tic_direction = 1; |
if (x2tics & TICS_MIRROR) |
if (x2tics & TICS_MIRROR) |
tic_mirror = tic_start; |
tic_mirror = tic_start; |
Line 1561 int pcount; /* count of plots in linked list */ |
|
Line 1561 int pcount; /* count of plots in linked list */ |
|
|
|
x_axis = FIRST_X_AXIS; |
x_axis = FIRST_X_AXIS; |
y_axis = FIRST_Y_AXIS; /* chose scaling */ |
y_axis = FIRST_Y_AXIS; /* chose scaling */ |
axis_zero[FIRST_X_AXIS] = map_y(0.0); |
|
axis_zero[FIRST_Y_AXIS] = map_x(0.0); |
|
|
|
if (axis_zero[FIRST_X_AXIS] < ybot || is_log_y) |
if (y_min >= 0.0 && y_max >= 0.0 || is_log_y) |
axis_zero[FIRST_X_AXIS] = ybot; /* save for impulse plotting */ |
axis_zero[FIRST_Y_AXIS] = ybot; /* save for impulse plotting */ |
else if (axis_zero[FIRST_X_AXIS] >= ytop) |
else if (y_min <= 0.0 && y_max <= 0.0) |
axis_zero[FIRST_X_AXIS] = ytop; |
axis_zero[FIRST_Y_AXIS] = ytop; |
else if (xzeroaxis.l_type > -3) { |
else { |
term_apply_lp_properties(&xzeroaxis); |
axis_zero[FIRST_Y_AXIS] = map_y(0.0); |
(*t->move) (xleft, axis_zero[FIRST_X_AXIS]); |
if (xzeroaxis.l_type > -3) { |
(*t->vector) (xright, axis_zero[FIRST_X_AXIS]); |
term_apply_lp_properties(&xzeroaxis); |
|
(*t->move) (xleft, axis_zero[FIRST_Y_AXIS]); |
|
(*t->vector) (xright, axis_zero[FIRST_Y_AXIS]); |
|
} |
} |
} |
if ((yzeroaxis.l_type > -3) && !is_log_x |
if (x_min >= 0.0 && x_max >= 0.0) |
&& axis_zero[FIRST_Y_AXIS] >= xleft |
axis_zero[FIRST_X_AXIS] = xleft; |
&& axis_zero[FIRST_Y_AXIS] < xright) { |
else if (x_min <= 0.0 && x_max <= 0.0) |
term_apply_lp_properties(&yzeroaxis); |
axis_zero[FIRST_X_AXIS] = xright; |
(*t->move) (axis_zero[FIRST_Y_AXIS], ybot); |
else { |
(*t->vector) (axis_zero[FIRST_Y_AXIS], ytop); |
axis_zero[FIRST_X_AXIS] = map_x(0.0); |
|
if ((yzeroaxis.l_type > -3) && !is_log_x) { |
|
term_apply_lp_properties(&yzeroaxis); |
|
(*t->move) (axis_zero[FIRST_X_AXIS], ybot); |
|
(*t->vector) (axis_zero[FIRST_X_AXIS], ytop); |
|
} |
} |
} |
|
|
x_axis = SECOND_X_AXIS; |
x_axis = SECOND_X_AXIS; |
y_axis = SECOND_Y_AXIS; /* chose scaling */ |
y_axis = SECOND_Y_AXIS; /* chose scaling */ |
axis_zero[SECOND_X_AXIS] = map_y(0.0); |
|
axis_zero[SECOND_Y_AXIS] = map_x(0.0); |
|
|
|
if (axis_zero[SECOND_X_AXIS] < ybot || is_log_y2) |
if (is_log_y2 || y_min >= 0.0 && y_max >= 0.0) |
axis_zero[SECOND_X_AXIS] = ybot; /* save for impulse plotting */ |
axis_zero[SECOND_Y_AXIS] = ybot; /* save for impulse plotting */ |
else if (axis_zero[SECOND_X_AXIS] >= ytop) |
else if (y_min <= 0.0 && y_max <= 0.0) |
axis_zero[SECOND_X_AXIS] = ytop; |
axis_zero[SECOND_Y_AXIS] = ytop; |
else if (x2zeroaxis.l_type > -3) { |
else { |
term_apply_lp_properties(&x2zeroaxis); |
axis_zero[SECOND_Y_AXIS] = map_y(0.0); |
(*t->move) (xleft, axis_zero[SECOND_X_AXIS]); |
if (x2zeroaxis.l_type > -3) { |
(*t->vector) (xright, axis_zero[SECOND_X_AXIS]); |
term_apply_lp_properties(&x2zeroaxis); |
|
(*t->move) (xleft, axis_zero[SECOND_Y_AXIS]); |
|
(*t->vector) (xright, axis_zero[SECOND_Y_AXIS]); |
|
} |
} |
} |
if ((y2zeroaxis.l_type > -3) && !is_log_x2 && axis_zero[SECOND_Y_AXIS] >= xleft && |
if (y_min >= 0.0 && y_max >= 0.0) |
axis_zero[SECOND_Y_AXIS] < xright) { |
axis_zero[SECOND_X_AXIS] = xleft; |
term_apply_lp_properties(&y2zeroaxis); |
else if (x_min <= 0.0 && x_max <= 0.0) |
(*t->move) (axis_zero[SECOND_Y_AXIS], ybot); |
axis_zero[SECOND_X_AXIS] = xright; |
(*t->vector) (axis_zero[SECOND_Y_AXIS], ytop); |
else { |
|
axis_zero[SECOND_X_AXIS] = map_x(0.0); |
|
if ((y2zeroaxis.l_type > -3) && !is_log_x2) { |
|
term_apply_lp_properties(&y2zeroaxis); |
|
(*t->move) (axis_zero[SECOND_X_AXIS], ybot); |
|
(*t->vector) (axis_zero[SECOND_X_AXIS], ytop); |
|
} |
} |
} |
/* DRAW PLOT BORDER */ |
/* DRAW PLOT BORDER */ |
if (draw_border) { |
if (draw_border) { |
Line 1629 int pcount; /* count of plots in linked list */ |
|
Line 1643 int pcount; /* count of plots in linked list */ |
|
} |
} |
/* YLABEL */ |
/* YLABEL */ |
if (*ylabel.text) { |
if (*ylabel.text) { |
strcpy(ss, ylabel.text); |
|
/* we worked out x-posn in boundary() */ |
/* we worked out x-posn in boundary() */ |
if ((*t->text_angle) (1)) { |
if ((*t->text_angle) (1)) { |
unsigned int x = ylabel_x + (t->v_char / 2); |
unsigned int x = ylabel_x + (t->v_char / 2); |
unsigned int y = (ytop + ybot) / 2 + ylabel.yoffset * (t->h_char); |
unsigned int y = (ytop + ybot) / 2 + ylabel.yoffset * (t->h_char); |
write_multiline(x, y, ss, CENTRE, JUST_TOP, 1, ylabel.font); |
write_multiline(x, y, ylabel.text, CENTRE, JUST_TOP, 1, ylabel.font); |
(*t->text_angle) (0); |
(*t->text_angle) (0); |
} else { |
} else { |
/* really bottom just, but we know number of lines |
/* really bottom just, but we know number of lines |
so we need to adjust x-posn by one line */ |
so we need to adjust x-posn by one line */ |
unsigned int x = ylabel_x; |
unsigned int x = ylabel_x; |
unsigned int y = ylabel_y; |
unsigned int y = ylabel_y; |
write_multiline(x, y, ss, LEFT, JUST_TOP, 0, ylabel.font); |
write_multiline(x, y, ylabel.text, LEFT, JUST_TOP, 0, ylabel.font); |
} |
} |
} |
} |
/* Y2LABEL */ |
/* Y2LABEL */ |
if (*y2label.text) { |
if (*y2label.text) { |
strcpy(ss, y2label.text); |
|
/* we worked out coordinates in boundary() */ |
/* we worked out coordinates in boundary() */ |
if ((*t->text_angle) (1)) { |
if ((*t->text_angle) (1)) { |
unsigned int x = y2label_x + (t->v_char / 2) - 1; |
unsigned int x = y2label_x + (t->v_char / 2) - 1; |
unsigned int y = (ytop + ybot) / 2 + y2label.yoffset * (t->h_char); |
unsigned int y = (ytop + ybot) / 2 + y2label.yoffset * (t->h_char); |
write_multiline(x, y, ss, CENTRE, JUST_TOP, 1, y2label.font); |
write_multiline(x, y, y2label.text, CENTRE, JUST_TOP, 1, y2label.font); |
(*t->text_angle) (0); |
(*t->text_angle) (0); |
} else { |
} else { |
/* really bottom just, but we know number of lines */ |
/* really bottom just, but we know number of lines */ |
unsigned int x = y2label_x; |
unsigned int x = y2label_x; |
unsigned int y = y2label_y; |
unsigned int y = y2label_y; |
write_multiline(x, y, ss, RIGHT, JUST_TOP, 0, y2label.font); |
write_multiline(x, y, y2label.text, RIGHT, JUST_TOP, 0, y2label.font); |
} |
} |
} |
} |
/* XLABEL */ |
/* XLABEL */ |
if (*xlabel.text) { |
if (*xlabel.text) { |
unsigned int x = (xright + xleft) / 2 + xlabel.xoffset * (t->h_char); |
unsigned int x = (xright + xleft) / 2 + xlabel.xoffset * (t->h_char); |
unsigned int y = xlabel_y - t->v_char / 2; /* HBB */ |
unsigned int y = xlabel_y - t->v_char / 2; /* HBB */ |
strcpy(ss, xlabel.text); |
write_multiline(x, y, xlabel.text, CENTRE, JUST_TOP, 0, xlabel.font); |
write_multiline(x, y, ss, CENTRE, JUST_TOP, 0, xlabel.font); |
|
} |
} |
/* PLACE TITLE */ |
/* PLACE TITLE */ |
if (*title.text) { |
if (*title.text) { |
/* we worked out y-coordinate in boundary() */ |
/* we worked out y-coordinate in boundary() */ |
unsigned int x = (xleft + xright) / 2 + title.xoffset * t->h_char; |
unsigned int x = (xleft + xright) / 2 + title.xoffset * t->h_char; |
unsigned int y = title_y - t->v_char / 2; |
unsigned int y = title_y - t->v_char / 2; |
strcpy(ss, title.text); |
write_multiline(x, y, title.text, CENTRE, JUST_TOP, 0, title.font); |
write_multiline(x, y, ss, CENTRE, JUST_TOP, 0, title.font); |
|
} |
} |
/* X2LABEL */ |
/* X2LABEL */ |
if (*x2label.text) { |
if (*x2label.text) { |
/* we worked out y-coordinate in boundary() */ |
/* we worked out y-coordinate in boundary() */ |
unsigned int x = (xright + xleft) / 2 + x2label.xoffset * (t->h_char); |
unsigned int x = (xright + xleft) / 2 + x2label.xoffset * (t->h_char); |
unsigned int y = x2label_y - t->v_char / 2 - 1; |
unsigned int y = x2label_y - t->v_char / 2 - 1; |
strcpy(ss, x2label.text); |
write_multiline(x, y, x2label.text, CENTRE, JUST_TOP, 0, x2label.font); |
write_multiline(x, y, ss, CENTRE, JUST_TOP, 0, x2label.font); |
|
} |
} |
/* PLACE TIMEDATE */ |
/* PLACE TIMEDATE */ |
if (*timelabel.text) { |
if (*timelabel.text) { |
/* we worked out coordinates in boundary() */ |
/* we worked out coordinates in boundary() */ |
char str[MAX_LINE_LEN + 1]; |
char *str; |
time_t now; |
time_t now; |
unsigned int x = time_x; |
unsigned int x = time_x; |
unsigned int y = time_y; |
unsigned int y = time_y; |
time(&now); |
time(&now); |
|
/* there is probably now way to find out in advance how many |
|
* chars strftime() writes */ |
|
str = gp_alloc(MAX_LINE_LEN + 1, "timelabel.text"); |
strftime(str, MAX_LINE_LEN, timelabel.text, localtime(&now)); |
strftime(str, MAX_LINE_LEN, timelabel.text, localtime(&now)); |
|
|
if (timelabel_rotate && (*t->text_angle) (1)) { |
if (timelabel_rotate && (*t->text_angle) (1)) { |
Line 1713 int pcount; /* count of plots in linked list */ |
|
Line 1725 int pcount; /* count of plots in linked list */ |
|
this_label = this_label->next) { |
this_label = this_label->next) { |
unsigned int x, y; |
unsigned int x, y; |
map_position(&this_label->place, &x, &y, "label"); |
map_position(&this_label->place, &x, &y, "label"); |
strcpy(ss, this_label->text); |
|
if (this_label->rotate && (*t->text_angle) (1)) { |
if (this_label->rotate && (*t->text_angle) (1)) { |
write_multiline(x, y, ss, this_label->pos, JUST_TOP, 1, this_label->font); |
write_multiline(x, y, this_label->text, this_label->pos, JUST_TOP, 1, this_label->font); |
(*t->text_angle) (0); |
(*t->text_angle) (0); |
} else { |
} else { |
write_multiline(x, y, ss, this_label->pos, JUST_TOP, 0, this_label->font); |
write_multiline(x, y, this_label->text, this_label->pos, JUST_TOP, 0, this_label->font); |
} |
} |
} |
} |
|
|
Line 1742 int pcount; /* count of plots in linked list */ |
|
Line 1753 int pcount; /* count of plots in linked list */ |
|
yl = key_yt; |
yl = key_yt; |
|
|
if (*key_title) { |
if (*key_title) { |
sprintf(ss, "%s\n", key_title); |
char *ss = gp_alloc(strlen(key_title) + 2, "tmp string ss"); |
|
strcpy(ss, key_title); |
|
strcat(ss, "\n"); |
|
|
s = ss; |
s = ss; |
yl -= t->v_char / 2; |
yl -= t->v_char / 2; |
while ((e = (char *) strchr(s, '\n')) != NULL) { |
while ((e = (char *) strchr(s, '\n')) != NULL) { |
Line 1755 int pcount; /* count of plots in linked list */ |
|
Line 1769 int pcount; /* count of plots in linked list */ |
|
(*t->put_text) (xl + key_text_right, yl, s); |
(*t->put_text) (xl + key_text_right, yl, s); |
} else { |
} else { |
int x = xl + key_text_right - (t->h_char) * strlen(s); |
int x = xl + key_text_right - (t->h_char) * strlen(s); |
if (key_hpos == TOUT || inrange(x, xleft, xright)) |
if (key_hpos == TOUT || |
|
key_vpos == TUNDER || /* HBB 990327 */ |
|
inrange(x, xleft, xright)) |
(*t->put_text) (x, yl, s); |
(*t->put_text) (x, yl, s); |
} |
} |
} |
} |
Line 1763 int pcount; /* count of plots in linked list */ |
|
Line 1779 int pcount; /* count of plots in linked list */ |
|
yl -= t->v_char; |
yl -= t->v_char; |
} |
} |
yl += t->v_char / 2; |
yl += t->v_char / 2; |
|
free(ss); |
} |
} |
yl_ref = yl -= key_entry_height / 2; /* centralise the keys */ |
yl_ref = yl -= key_entry_height / 2; /* centralise the keys */ |
key_count = 0; |
key_count = 0; |
Line 1807 int pcount; /* count of plots in linked list */ |
|
Line 1824 int pcount; /* count of plots in linked list */ |
|
} else { |
} else { |
int x = xl + key_text_right - (t->h_char) * strlen(this_plot->title); |
int x = xl + key_text_right - (t->h_char) * strlen(this_plot->title); |
if (key_hpos == TOUT || |
if (key_hpos == TOUT || |
|
key_vpos == TUNDER || /* HBB 990327 */ |
i_inrange(x, xleft, xright)) |
i_inrange(x, xleft, xright)) |
(*t->put_text) (x, yl, this_plot->title); |
(*t->put_text) (x, yl, this_plot->title); |
} |
} |
Line 1841 int pcount; /* count of plots in linked list */ |
|
Line 1859 int pcount; /* count of plots in linked list */ |
|
switch (this_plot->plot_style) { |
switch (this_plot->plot_style) { |
/*{{{ IMPULSE */ |
/*{{{ IMPULSE */ |
case IMPULSES: |
case IMPULSES: |
plot_impulses(this_plot, axis_zero[y_axis], axis_zero[x_axis]); |
plot_impulses(this_plot, axis_zero[x_axis], axis_zero[y_axis]); |
break; |
break; |
/*}}} */ |
/*}}} */ |
/*{{{ LINES */ |
/*{{{ LINES */ |
Line 1905 int pcount; /* count of plots in linked list */ |
|
Line 1923 int pcount; /* count of plots in linked list */ |
|
/*}}} */ |
/*}}} */ |
/*{{{ BOXXYERROR */ |
/*{{{ BOXXYERROR */ |
case BOXXYERROR: |
case BOXXYERROR: |
plot_boxes(this_plot, axis_zero[x_axis]); |
plot_boxes(this_plot, axis_zero[y_axis]); |
break; |
break; |
/*}}} */ |
/*}}} */ |
/*{{{ BOXERROR (falls through to) */ |
/*{{{ BOXERROR (falls through to) */ |
Line 1916 int pcount; /* count of plots in linked list */ |
|
Line 1934 int pcount; /* count of plots in linked list */ |
|
/*}}} */ |
/*}}} */ |
/*{{{ BOXES */ |
/*{{{ BOXES */ |
case BOXES: |
case BOXES: |
plot_boxes(this_plot, axis_zero[x_axis]); |
plot_boxes(this_plot, axis_zero[y_axis]); |
break; |
break; |
/*}}} */ |
/*}}} */ |
/*{{{ VECTOR */ |
/*{{{ VECTOR */ |
Line 1957 int pcount; /* count of plots in linked list */ |
|
Line 1975 int pcount; /* count of plots in linked list */ |
|
} |
} |
|
|
|
|
/* BODGES */ |
|
#undef ytic |
|
#undef xtic |
|
|
|
/* plot_impulses: |
/* plot_impulses: |
* Plot the curves in IMPULSES style |
* Plot the curves in IMPULSES style |
*/ |
*/ |
Line 2212 struct curve_points *plot; |
|
Line 2226 struct curve_points *plot; |
|
} |
} |
} |
} |
|
|
|
/* HBB 20010625: replaced homegrown bubblesort in plot_histeps() by |
|
* call of standard routine qsort(). Need to tell the compare function |
|
* about the plotted dataset via this file scope variable: */ |
|
static struct curve_points *histeps_current_plot; |
|
|
|
/* NOTE: I'd have made the comp.function 'static', but the HP-sUX gcc |
|
* bug seems to forbid that :-( */ |
|
int |
|
histeps_compare(p1, p2) |
|
SORTFUNC_ARGS p1; |
|
SORTFUNC_ARGS p2; |
|
{ |
|
double x1=histeps_current_plot->points[*(int *)p1].x; |
|
double x2=histeps_current_plot->points[*(int *)p2].x; |
|
|
|
if (x1 < x2) |
|
return -1; |
|
else |
|
return (x2 > x1); |
|
} |
|
|
/* CAC */ |
/* CAC */ |
/* plot_histeps: |
/* plot_histeps: |
* Plot the curves in HISTEPS style |
* Plot the curves in HISTEPS style |
Line 2220 static void plot_histeps(plot) |
|
Line 2255 static void plot_histeps(plot) |
|
struct curve_points *plot; |
struct curve_points *plot; |
{ |
{ |
int i; /* point index */ |
int i; /* point index */ |
int hold, bigi; /* indices for sorting */ |
|
int xl, yl; /* cursor position in terminal coordinates */ |
int xl, yl; /* cursor position in terminal coordinates */ |
struct termentry *t = term; |
struct termentry *t = term; |
double x, y, xn, yn; /* point position */ |
double x, y, xn, yn; /* point position */ |
|
double y_null; /* y coordinate of histogram baseline */ |
int *gl, goodcount; /* array to hold list of valid points */ |
int *gl, goodcount; /* array to hold list of valid points */ |
|
|
/* preliminary count of points inside array */ |
/* preliminary count of points inside array */ |
Line 2235 struct curve_points *plot; |
|
Line 2270 struct curve_points *plot; |
|
if (goodcount < 2) |
if (goodcount < 2) |
return; /* cannot plot less than 2 points */ |
return; /* cannot plot less than 2 points */ |
|
|
gl = (int *) gp_alloc(goodcount * sizeof(int), "histeps valid point mapping"); |
gl = gp_alloc(goodcount * sizeof(int), "histeps valid point mapping"); |
if (gl == NULL) |
if (gl == NULL) |
return; |
return; |
|
|
Line 2247 struct curve_points *plot; |
|
Line 2282 struct curve_points *plot; |
|
gl[goodcount] = i; |
gl[goodcount] = i; |
++goodcount; |
++goodcount; |
} |
} |
/* sort the data */ |
|
for (bigi = i = 1; i < goodcount;) { |
|
if (plot->points[gl[i]].x < plot->points[gl[i - 1]].x) { |
|
hold = gl[i]; |
|
gl[i] = gl[i - 1]; |
|
gl[i - 1] = hold; |
|
if (i > 1) { |
|
i--; |
|
continue; |
|
} |
|
} |
|
i = ++bigi; |
|
} |
|
|
|
|
/* sort the data --- tell histeps_compare about the plot |
|
* datastructure to look at, then call qsort() */ |
|
histeps_current_plot = plot; |
|
qsort(gl, goodcount, sizeof(*gl), histeps_compare); |
|
/* play it safe: invalidate the static pointer after usage */ |
|
histeps_current_plot = NULL; |
|
|
|
/* HBB 20010625: log y axis must treat 0.0 as -infinity. Define |
|
* the correct y position for the histogram's baseline once. It'll |
|
* be used twice (once for each endpoint of the histogram). */ |
|
if (log_array[y_axis]) |
|
y_null = GPMIN(min_array[y_axis], max_array[y_axis]); |
|
else |
|
y_null = 0.0; |
|
|
x = (3.0 * plot->points[gl[0]].x - plot->points[gl[1]].x) / 2.0; |
x = (3.0 * plot->points[gl[0]].x - plot->points[gl[1]].x) / 2.0; |
y = 0.0; |
y = y_null; |
|
|
xl = map_x(x); |
xl = map_x(x); |
yl = map_y(y); |
yl = map_y(y); |
(*t->move) (xl, yl); |
(*t->move) (xl, yl); |
|
|
for (i = 0; i < goodcount - 1; i++) { /* loop over all points except last */ |
for (i = 0; i < goodcount - 1; i++) { /* loop over all points except last */ |
|
|
yn = plot->points[gl[i]].y; |
yn = plot->points[gl[i]].y; |
xn = (plot->points[gl[i]].x + plot->points[gl[i + 1]].x) / 2.0; |
xn = (plot->points[gl[i]].x + plot->points[gl[i + 1]].x) / 2.0; |
histeps_vertical(&xl, &yl, x, y, yn); |
histeps_vertical(&xl, &yl, x, y, yn); |
Line 2283 struct curve_points *plot; |
|
Line 2319 struct curve_points *plot; |
|
xn = (3.0 * plot->points[gl[i]].x - plot->points[gl[i - 1]].x) / 2.0; |
xn = (3.0 * plot->points[gl[i]].x - plot->points[gl[i - 1]].x) / 2.0; |
histeps_vertical(&xl, &yl, x, y, yn); |
histeps_vertical(&xl, &yl, x, y, yn); |
histeps_horizontal(&xl, &yl, x, xn, yn); |
histeps_horizontal(&xl, &yl, x, xn, yn); |
histeps_vertical(&xl, &yl, xn, yn, 0.0); |
histeps_vertical(&xl, &yl, xn, yn, y_null); |
|
|
free(gl); |
free(gl); |
} |
} |
Line 2733 struct curve_points *plot; |
|
Line 2769 struct curve_points *plot; |
|
* Plot the curves in VECTORS style |
* Plot the curves in VECTORS style |
*/ |
*/ |
static void plot_vectors(plot) |
static void plot_vectors(plot) |
struct curve_points *plot; |
struct curve_points *plot; |
{ |
{ |
int i; |
int i; |
int x1, y1, x2, y2; |
int x1, y1, x2, y2; |
struct termentry *t = term; |
struct termentry *t = term; |
|
TBOOLEAN head; |
|
struct coordinate points[2]; |
|
double ex, ey; |
|
double lx[2], ly[2]; |
|
|
for (i = 0; i < plot->p_count; i++) { |
for (i = 0; i < plot->p_count; i++) { |
if (plot->points[i].type == INRANGE) { |
points[0] = plot->points[i]; |
x1 = map_x(plot->points[i].xlow); |
points[1].x = plot->points[i].xhigh; |
y1 = map_y(plot->points[i].ylow); |
points[1].y = plot->points[i].yhigh; |
x2 = map_x(plot->points[i].xhigh); |
if (inrange(points[1].x, x_min, x_max) && |
y2 = map_y(plot->points[i].yhigh); |
inrange(points[1].y, y_min, y_max)) { |
(*t->arrow) (x1, y1, x2, y2, TRUE); |
/* to inrange */ |
|
points[1].type = INRANGE; |
|
x2 = map_x(points[1].x); |
|
y2 = map_y(points[1].y); |
|
head = TRUE; |
|
if (points[0].type == INRANGE) { |
|
x1 = map_x(points[0].x); |
|
y1 = map_y(points[0].y); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} else if (points[0].type == OUTRANGE) { |
|
/* from outrange to inrange */ |
|
if (clip_lines1) { |
|
edge_intersect(points, 1, &ex, &ey); |
|
x1 = map_x(ex); |
|
y1 = map_y(ey); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} |
|
} |
|
} else { |
|
/* to outrange */ |
|
points[1].type = OUTRANGE; |
|
head = FALSE; |
|
if (points[0].type == INRANGE) { |
|
/* from inrange to outrange */ |
|
if (clip_lines1) { |
|
x1 = map_x(points[0].x); |
|
y1 = map_y(points[0].y); |
|
edge_intersect(points, 1, &ex, &ey); |
|
x2 = map_x(ex); |
|
y2 = map_y(ey); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} |
|
} else if (points[0].type == OUTRANGE) { |
|
/* from outrange to outrange */ |
|
if (clip_lines2) { |
|
if (two_edge_intersect(points, 1, lx, ly)) { |
|
x1 = map_x(lx[0]); |
|
y1 = map_y(ly[0]); |
|
x2 = map_x(lx[1]); |
|
y2 = map_y(ly[1]); |
|
(*t->arrow) (x1, y1, x2, y2, head); |
|
} |
|
} |
|
} |
} |
} |
} |
} |
} |
} |
Line 3667 int vert; /* ... and vertical just - text in hor dir |
|
Line 3750 int vert; /* ... and vertical just - text in hor dir |
|
int angle; /* assume term has already been set for this */ |
int angle; /* assume term has already been set for this */ |
char *font; /* NULL or "" means use default */ |
char *font; /* NULL or "" means use default */ |
{ |
{ |
/* assumes we are free to mangle the text */ |
|
register struct termentry *t = term; |
register struct termentry *t = term; |
char *p; |
char *p = text; |
|
|
|
if (!p) |
|
return; |
|
|
if (vert != JUST_TOP) { |
if (vert != JUST_TOP) { |
/* count lines and adjust y */ |
/* count lines and adjust y */ |
int lines = 0; /* number of linefeeds - one fewer than lines */ |
int lines = 0; /* number of linefeeds - one fewer than lines */ |
for (p = text; *p; ++p) |
while (*p++) { |
if (*p == '\n') |
if (*p == '\n') |
++lines; |
++lines; |
|
} |
if (angle) |
if (angle) |
x -= (vert * lines * t->v_char) / 2; |
x -= (vert * lines * t->v_char) / 2; |
else |
else |
Line 3687 char *font; /* NULL or "" means use default */ |
|
Line 3774 char *font; /* NULL or "" means use default */ |
|
|
|
for (;;) { /* we will explicitly break out */ |
for (;;) { /* we will explicitly break out */ |
|
|
if ((p = strchr(text, '\n')) != NULL) |
if ((text != NULL) && (p = strchr(text, '\n')) != NULL) |
*p = 0; /* terminate the string */ |
*p = 0; /* terminate the string */ |
|
|
if ((*t->justify_text) (hor)) { |
if ((*t->justify_text) (hor)) { |
Line 3706 char *font; /* NULL or "" means use default */ |
|
Line 3793 char *font; /* NULL or "" means use default */ |
|
|
|
if (!p) |
if (!p) |
break; |
break; |
|
else { |
|
/* put it back */ |
|
*p = '\n'; |
|
} |
|
|
text = p + 1; |
text = p + 1; |
} /* unconditional branch back to the for(;;) - just a goto ! */ |
} /* unconditional branch back to the for(;;) - just a goto ! */ |
|
|
if (font && *font) |
if (font && *font) |
(*t->set_font) (default_font); |
(*t->set_font) (default_font); |
|
|
} |
} |
|
|
|
/* HBB 20010118: all the *_callback() functions made non-static. This |
|
* is necessary to work around a bug in HP's assembler shipped with |
|
* HP-UX 10 and higher, if GCC tries to use it */ |
|
|
/* display a x-axis ticmark - called by gen_ticks */ |
/* display a x-axis ticmark - called by gen_ticks */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
static void xtick2d_callback(axis, place, text, grid) |
void xtick2d_callback(axis, place, text, grid) |
int axis; |
int axis; |
double place; |
double place; |
char *text; |
char *text; |
Line 3789 struct lp_style_type grid; /* linetype or -2 for no gr |
|
Line 3885 struct lp_style_type grid; /* linetype or -2 for no gr |
|
|
|
/* display a y-axis ticmark - called by gen_ticks */ |
/* display a y-axis ticmark - called by gen_ticks */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
/* also uses global tic_start, tic_direction, tic_text and tic_just */ |
static void ytick2d_callback(axis, place, text, grid) |
void ytick2d_callback(axis, place, text, grid) |
int axis; |
int axis; |
double place; |
double place; |
char *text; |
char *text; |
|
|
|
|
|
|
void setup_tics(axis, ticdef, format, max) |
void setup_tics(axis, ticdef, format, max) |
int axis; |
int axis; |
struct ticdef *ticdef; |
struct ticdef *ticdef; |
char *format; |
char *format; |
int max; /* approx max number of slots available */ |
int max; /* approx max number of slots available */ |
{ |
{ |
double tic = 0; /* HBB: shut up gcc -Wall */ |
double tic = 0; /* HBB: shut up gcc -Wall */ |
|
|
Line 3890 int max; /* approx max number of slots available */ |
|
Line 3986 int max; /* approx max number of slots available */ |
|
ticstep[axis] = tic = ticdef->def.series.incr; |
ticstep[axis] = tic = ticdef->def.series.incr; |
fixmin &= (ticdef->def.series.start == -VERYLARGE); |
fixmin &= (ticdef->def.series.start == -VERYLARGE); |
fixmax &= (ticdef->def.series.end == VERYLARGE); |
fixmax &= (ticdef->def.series.end == VERYLARGE); |
|
if (log_array[axis]) |
|
tic = fabs(log(fabs(tic))) / log_base_array[axis]; |
} else if (ticdef->type == TIC_COMPUTED) { |
} else if (ticdef->type == TIC_COMPUTED) { |
ticstep[axis] = tic = make_tics(axis, max); |
ticstep[axis] = tic = make_tics(axis, max); |
} else { |
} else { |
Line 3972 char *dest, *format; |
|
Line 4070 char *dest, *format; |
|
size_t count; |
size_t count; |
double log_base, x; /* we print one number in a number of different formats */ |
double log_base, x; /* we print one number in a number of different formats */ |
{ |
{ |
#define LOC_PI 3.14159265358979323846 /* local definition of PI */ |
|
char temp[MAX_LINE_LEN]; |
char temp[MAX_LINE_LEN]; |
char *t; |
char *t; |
|
|
Line 4137 double log_base, x; /* we print one number in a numbe |
|
Line 4234 double log_base, x; /* we print one number in a numbe |
|
{ |
{ |
t[0] = 'f'; |
t[0] = 'f'; |
t[1] = 0; |
t[1] = 0; |
sprintf(dest, temp, x / LOC_PI); |
sprintf(dest, temp, x / M_PI); |
dest += strlen(dest); |
dest += strlen(dest); |
++format; |
++format; |
break; |
break; |
Line 4149 double log_base, x; /* we print one number in a numbe |
|
Line 4246 double log_base, x; /* we print one number in a numbe |
|
/*}}} */ |
/*}}} */ |
} |
} |
} |
} |
#undef LOC_PI /* local definition of PI */ |
|
/*}}} */ |
/*}}} */ |
#ifdef HAVE_SNPRINTF |
#ifdef HAVE_SNPRINTF |
# undef sprintf |
# undef sprintf |
Line 4166 double log_base, x; /* we print one number in a numbe |
|
Line 4262 double log_base, x; /* we print one number in a numbe |
|
*/ |
*/ |
|
|
void gen_tics(axis, def, grid, minitics, minifreq, callback) |
void gen_tics(axis, def, grid, minitics, minifreq, callback) |
int axis; /* FIRST_X_AXIS, etc */ |
int axis; /* FIRST_X_AXIS, etc */ |
struct ticdef *def; /* tic defn */ |
struct ticdef *def; /* tic defn */ |
int grid; /* GRID_X | GRID_MX etc */ |
int grid; /* GRID_X | GRID_MX etc */ |
int minitics; /* minitics - off/default/auto/explicit */ |
int minitics; /* minitics - off/default/auto/explicit */ |
double minifreq; /* frequency */ |
double minifreq; /* frequency */ |
tic_callback callback; /* fn to call to actually do the work */ |
tic_callback callback; /* fn to call to actually do the work */ |
{ |
{ |
/* seperate main-tic part of grid */ |
/* seperate main-tic part of grid */ |
struct lp_style_type lgrd, mgrd; |
struct lp_style_type lgrd, mgrd; |
Line 4216 tic_callback callback; /* fn to call to actually do t |
|
Line 4312 tic_callback callback; /* fn to call to actually do t |
|
return; /* NO MINITICS FOR USER-DEF TICS */ |
return; /* NO MINITICS FOR USER-DEF TICS */ |
/*}}} */ |
/*}}} */ |
} |
} |
|
|
/* series-tics |
/* series-tics |
* need to distinguish user co-ords from internal co-ords. |
* need to distinguish user co-ords from internal co-ords. |
* - for logscale, internal = log(user), else internal = user |
* - for logscale, internal = log(user), else internal = user |
Line 4227 tic_callback callback; /* fn to call to actually do t |
|
Line 4324 tic_callback callback; /* fn to call to actually do t |
|
* If step>1, we are looking at 1,1e6,1e12 for example, so |
* If step>1, we are looking at 1,1e6,1e12 for example, so |
* minitics are 10,100,1000,... - done in internal co-ords |
* minitics are 10,100,1000,... - done in internal co-ords |
*/ |
*/ |
|
|
{ |
{ |
double tic; /* loop counter */ |
double tic; /* loop counter */ |
double internal; /* in internal co-ords */ |
double internal; /* in internal co-ords */ |
Line 4247 tic_callback callback; /* fn to call to actually do t |
|
Line 4343 tic_callback callback; /* fn to call to actually do t |
|
lmin = lmax; |
lmin = lmax; |
lmax = temp; |
lmax = temp; |
} |
} |
|
|
/*{{{ choose start, step and end */ |
/*{{{ choose start, step and end */ |
switch (def->type) { |
switch (def->type) { |
case TIC_SERIES: |
case TIC_SERIES: |
|
start = def->def.series.start; |
|
step = def->def.series.incr; |
|
end = def->def.series.end; |
|
|
if (log_array[axis]) { |
if (log_array[axis]) { |
/* we can tolerate start <= 0 if step and end > 0 */ |
step = fabs(log(fabs(step))) / log_base_array[axis]; |
if (def->def.series.end <= 0 || |
|
def->def.series.incr <= 0) |
|
return; /* just quietly ignore */ |
|
step = log(def->def.series.incr) / log_base_array[axis]; |
|
end = log(def->def.series.end) / log_base_array[axis]; |
|
start = def->def.series.start > 0 ? |
|
log(def->def.series.start) / log_base_array[axis] : |
|
step; |
|
} else { |
|
start = def->def.series.start; |
|
step = def->def.series.incr; |
|
end = def->def.series.end; |
|
if (start == -VERYLARGE) |
|
start = step * floor(lmin / step); |
|
if (end == VERYLARGE) |
|
end = step * ceil(lmax / step); |
|
} |
} |
|
|
|
/* NOTE: lmin/lmax already are already logarithms, if |
|
* applicable */ |
|
if (start == -VERYLARGE) |
|
start = step * floor(lmin / step); |
|
else if (log_array[axis]) |
|
start = log(fabs(start)) / log_base_array[axis]; |
|
|
|
if (end == VERYLARGE) |
|
end = step * ceil(lmax / step); |
|
else if (log_array[axis]) |
|
end = log(fabs(end)) / log_base_array[axis]; |
|
|
break; |
break; |
case TIC_COMPUTED: |
case TIC_COMPUTED: |
/* round to multiple of step */ |
/* round to multiple of step */ |
Line 4355 tic_callback callback; /* fn to call to actually do t |
|
Line 4453 tic_callback callback; /* fn to call to actually do t |
|
minitics = 0; /* dont get stuck in infinite loop */ |
minitics = 0; /* dont get stuck in infinite loop */ |
/*}}} */ |
/*}}} */ |
} |
} |
|
|
/*{{{ a few tweaks and checks */ |
/*{{{ a few tweaks and checks */ |
/* watch rounding errors */ |
/* watch rounding errors */ |
end += SIGNIF * step; |
end += SIGNIF * step; |
Line 4413 tic_callback callback; /* fn to call to actually do t |
|
Line 4512 tic_callback callback; /* fn to call to actually do t |
|
gstrftime(label, 24, ticfmt[axis], (double) user); |
gstrftime(label, 24, ticfmt[axis], (double) user); |
} else if (polar) { |
} else if (polar) { |
/* if rmin is set, we stored internally with r-rmin */ |
/* if rmin is set, we stored internally with r-rmin */ |
#if 0 /* Igor's polar-grid patch */ |
/* Igor's polar-grid patch */ |
|
#if 1 |
|
/* HBB 990327: reverted to 'pre-Igor' version... */ |
double r = fabs(user) + (autoscale_r & 1 ? 0 : rmin); |
double r = fabs(user) + (autoscale_r & 1 ? 0 : rmin); |
#else |
#else |
/* Igor removed fabs to allow -ve labels */ |
/* Igor removed fabs to allow -ve labels */ |
|
|
case screen: |
case screen: |
{ |
{ |
register struct termentry *t = term; |
register struct termentry *t = term; |
*x = pos->x * (t->xmax) + 0.5; |
/* HBB 20000914: Off-by-one bug. Max. allowable result is |
|
* t->xmax - 1, not t->xmax ! */ |
|
*x = pos->x * (t->xmax - 1) + 0.5; |
break; |
break; |
} |
} |
} |
} |
|
|
case screen: |
case screen: |
{ |
{ |
register struct termentry *t = term; |
register struct termentry *t = term; |
*y = pos->y * (t->ymax) + 0.5; |
/* HBB 20000914: Off-by-one bug. Max. allowable result is |
|
* t->ymax - 1, not t->ymax ! */ |
|
*y = pos->y * (t->ymax -1) + 0.5; |
return; |
return; |
} |
} |
} |
} |