1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
|
/*
* $Id: axis.h,v 1.46 2005/09/18 06:20:58 sfeam Exp $
*
*/
/*[
* Copyright 2000, 2004 Thomas Williams, Colin Kelley
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted, but not the right to
* distribute the complete modified source code. Modifications are to
* be distributed as patches to the released version. Permission to
* distribute binaries produced by compiling modified sources is granted,
* provided you
* 1. distribute the corresponding source modifications from the
* released version in the form of a patch file along with the binaries,
* 2. add special version identification to distinguish your version
* in addition to the base release version number,
* 3. provide your name and address as the primary contact for the
* support of your modified version, and
* 4. retain our contact information in regard to use of the base
* software.
* Permission to distribute the released version of the source code along
* with corresponding source modifications in the form of a patch file is
* granted with same provisions 2 through 4 for binary distributions.
*
* This software is provided "as is" without express or implied warranty
* to the extent permitted by applicable law.
]*/
#ifndef GNUPLOT_AXIS_H
#define GNUPLOT_AXIS_H
#include "gp_types.h" /* for TBOOLEAN */
#include "gadgets.h"
#include "parse.h" /* for const_express() */
#include "tables.h" /* for the axis name parse table */
#include "term_api.h" /* for lp_style_type */
#include "util.h" /* for int_error() */
/* typedefs / #defines */
/* give some names to some array elements used in command.c and grap*.c
* maybe one day the relevant items in setshow will also be stored
* in arrays.
*
* Always keep the following conditions alive:
* SECOND_X_AXIS = FIRST_X_AXIS + SECOND_AXES
* FIRST_X_AXIS & SECOND_AXES == 0
*/
typedef enum AXIS_INDEX {
#define FIRST_AXES 0
FIRST_Z_AXIS,
FIRST_Y_AXIS,
FIRST_X_AXIS,
T_AXIS, /* fill gap */
#define SECOND_AXES 4
SECOND_Z_AXIS, /* not used, yet */
SECOND_Y_AXIS,
SECOND_X_AXIS,
R_AXIS, /* never used ? */
U_AXIS, /* ditto */
V_AXIS /* ditto */
,COLOR_AXIS
} AXIS_INDEX;
# define AXIS_ARRAY_SIZE 11
/* What kind of ticmarking is wanted? */
typedef enum en_ticseries_type {
TIC_COMPUTED=1, /* default; gnuplot figures them */
TIC_SERIES, /* user-defined series */
TIC_USER, /* user-defined points */
TIC_MONTH, /* print out month names ((mo-1)%12)+1 */
TIC_DAY /* print out day of week */
} t_ticseries_type;
/* Defines one ticmark for TIC_USER style.
* If label==NULL, the value is printed with the usual format string.
* else, it is used as the format string (note that it may be a constant
* string, like "high" or "low").
*/
typedef struct ticmark {
double position; /* where on axis is this */
char *label; /* optional (format) string label */
int level; /* 0=major tic, 1=minor tic */
struct ticmark *next; /* linked list */
} ticmark;
/* Tic-mark labelling definition; see set xtics */
typedef struct ticdef {
t_ticseries_type type;
char *font;
struct t_colorspec textcolor;
struct {
struct ticmark *user; /* for TIC_USER */
struct { /* for TIC_SERIES */
double start, incr;
double end; /* ymax, if VERYLARGE */
} series;
TBOOLEAN mix; /* TRUE to use both the above */
} def;
struct position offset;
} t_ticdef;
/* we want two auto modes for minitics - default where minitics are
* auto for log/time and off for linear, and auto where auto for all
* graphs I've done them in this order so that logscale-mode can
* simply test bit 0 to see if it must do the minitics automatically.
* similarly, conventional plot can test bit 1 to see if minitics are
* required */
enum en_minitics_status {
MINI_OFF,
MINI_DEFAULT,
MINI_USER,
MINI_AUTO
};
/* Function pointer type for callback functions doing operations for a
* single ticmark */
typedef void (*tic_callback) __PROTO((AXIS_INDEX, double, char *, struct lp_style_type ));
/* Values to put in the axis_tics[] variables that decides where the
* ticmarks should be drawn: not at all, on one or both plot borders,
* or the zeroaxes. These look like a series of values, but TICS_MASK
* shows that they're actually bit masks --> don't turn into an enum
* */
#define NO_TICS 0
#define TICS_ON_BORDER 1
#define TICS_ON_AXIS 2
#define TICS_MASK 3
#define TICS_MIRROR 4
#if 0 /* HBB 20010806 --- move GRID flags into axis struct */
/* Need to allow user to choose grid at first and/or second axes tics.
* Also want to let user choose circles at x or y tics for polar grid.
* Also want to allow user rectangular grid for polar plot or polar
* grid for parametric plot. So just go for full configurability.
* These are bitmasks
*/
#define GRID_OFF 0
#define GRID_X (1<<0)
#define GRID_Y (1<<1)
#define GRID_Z (1<<2)
#define GRID_X2 (1<<3)
#define GRID_Y2 (1<<4)
#define GRID_MX (1<<5)
#define GRID_MY (1<<6)
#define GRID_MZ (1<<7)
#define GRID_MX2 (1<<8)
#define GRID_MY2 (1<<9)
#define GRID_CB (1<<10)
#define GRID_MCB (1<<11)
#endif /* 0 */
/* HBB 20010610: new type for storing autoscale activity. Effectively
* two booleans (bits) in a single variable, so I'm using an enum with
* all 4 possible bit masks given readable names. */
typedef enum e_autoscale {
AUTOSCALE_NONE = 0,
AUTOSCALE_MIN = 1<<0,
AUTOSCALE_MAX = 1<<1,
AUTOSCALE_BOTH = (1<<0 | 1 << 1),
AUTOSCALE_FIXMIN = 1<<2,
AUTOSCALE_FIXMAX = 1<<3
} t_autoscale;
/* FIXME 20000725: collect some of those various TBOOLEAN fields into
* a larger int (or -- shudder -- a bitfield?) */
typedef struct axis {
/* range of this axis */
t_autoscale autoscale; /* Which end(s) are autoscaled? */
t_autoscale set_autoscale; /* what does 'set' think autoscale to be? */
int range_flags; /* flag bits about autoscale/writeback: */
/* write auto-ed ranges back to variables for autoscale */
#define RANGE_WRITEBACK 1
/* allow auto and reversed ranges */
#define RANGE_REVERSE 2
TBOOLEAN range_is_reverted; /* range [high:low] silently reverted? */
double min; /* 'transient' axis extremal values */
double max;
double set_min; /* set/show 'permanent' values */
double set_max;
double writeback_min; /* ULIG's writeback implementation */
double writeback_max;
/* output-related quantities */
int term_lower; /* low and high end of the axis on output, */
int term_upper; /* ... (in terminal coordinates)*/
double term_scale; /* scale factor: plot --> term coords */
unsigned int term_zero; /* position of zero axis */
/* log axis control */
TBOOLEAN log; /* log axis stuff: flag "islog?" */
double base; /* logarithm base value */
double log_base; /* ln(base), for easier computations */
/* time/date axis control */
TBOOLEAN is_timedata; /* is this a time/date axis? */
TBOOLEAN format_is_numeric; /* format string looks like numeric??? */
char timefmt[MAX_ID_LEN+1]; /* format string for input */
char formatstring[MAX_ID_LEN+1];
/* the format string for output */
/* ticmark control variables */
int ticmode; /* tics on border/axis? mirrored? */
struct ticdef ticdef; /* tic series definition */
int tic_rotate; /* ticmarks rotated by this angle */
TBOOLEAN gridmajor; /* Grid lines wanted on major tics? */
TBOOLEAN gridminor; /* Grid lines for minor tics? */
int minitics; /* minor tic mode (none/auto/user)? */
double mtic_freq; /* minitic stepsize */
double ticscale; /* scale factor for tic marks (was (0..1])*/
double miniticscale; /* and for minitics */
TBOOLEAN tic_in; /* tics to be drawn inward? */
/* other miscellaneous fields */
text_label label; /* label string and position offsets */
lp_style_type zeroaxis; /* drawing style for zeroaxis, if any */
} AXIS;
#define DEFAULT_AXIS_TICDEF {TIC_COMPUTED, NULL, {TC_DEFAULT, 0, 0}, {NULL, {0,0}, FALSE}, { character, character, character, 0., 0., 0. } }
# define DEFAULT_AXIS_ZEROAXIS {0, -3, 0, 1.0, 1.0, 0}
#define DEFAULT_AXIS_STRUCT { \
AUTOSCALE_BOTH, AUTOSCALE_BOTH, /* auto, set_auto */ \
0, FALSE, /* range_flags, rev_range */ \
-10.0, 10.0, /* 3 pairs of min/max */ \
-10.0, 10.0, \
-10.0, 10.0, \
0, 0, 0, 0, /* terminal dependents */ \
FALSE, 0.0, 0.0, /* log, base, log(base) */ \
0, 1, /* is_timedata, format_numeric */ \
DEF_FORMAT, TIMEFMT, /* output format, timefmt */ \
NO_TICS, /* tic output positions (border, mirror) */ \
DEFAULT_AXIS_TICDEF, /* tic series definition */ \
0, FALSE, FALSE, /* tic_rotate, grid{major,minor} */ \
MINI_DEFAULT, 10, /* minitics, mtic_freq */ \
1.0, 0.5, TRUE, /* ticscale, miniticscale, tic_in */ \
EMPTY_LABELSTRUCT, /* axis label */ \
DEFAULT_AXIS_ZEROAXIS /* zeroaxis line style */ \
}
/* Table of default behaviours --- a subset of the struct above. Only
* those fields are present that differ from axis to axis. */
typedef struct axis_defaults {
double min; /* default axis endpoints */
double max;
char name[4]; /* axis name, like in "x2" or "t" */
int ticmode; /* tics on border/axis? mirrored? */
} AXIS_DEFAULTS;
/* global variables in axis.c */
extern AXIS axis_array[AXIS_ARRAY_SIZE];
extern const AXIS_DEFAULTS axis_defaults[AXIS_ARRAY_SIZE];
/* A parsing table for mapping axis names into axis indices. For use
* by the set/show machinery, mainly */
extern const struct gen_table axisname_tbl[AXIS_ARRAY_SIZE+1];
extern const struct ticdef default_axis_ticdef;
/* default format for tic mark labels */
#define DEF_FORMAT "% g"
/* default parse timedata string */
#define TIMEFMT "%d/%m/%y,%H:%M"
/* axis labels */
extern const text_label default_axis_label;
/* zeroaxis linetype (flag type==-3 if none wanted) */
extern const lp_style_type default_axis_zeroaxis;
/* default grid linetype, to be used by 'unset grid' and 'reset' */
extern const struct lp_style_type default_grid_lp;
/* grid layer: -1 default, 0 back, 1 front */
extern int grid_layer;
/* global variables for communication with the tic callback functions */
/* FIXME HBB 20010806: had better be collected into a struct that's
* passed to the callback */
extern int tic_start, tic_direction, tic_mirror;
/* These are for passing on to write_multiline(): */
extern int tic_text, rotate_tics, tic_hjust, tic_vjust;
/* The remaining ones are for grid drawing; controlled by 'set grid': */
/* extern int grid_selection; --- comm'ed out, HBB 20010806 */
extern struct lp_style_type grid_lp; /* linestyle for major grid lines */
extern struct lp_style_type mgrid_lp; /* linestyle for minor grid lines */
extern double polar_grid_angle; /* angle step in polar grid in radians */
/* Length of the longest tics label, set by widest_tic_callback(): */
extern int widest_tic_strlen;
/* axes being used by the current plot */
extern AXIS_INDEX x_axis, y_axis, z_axis;
/* macros to reduce code clutter caused by the array notation, mainly
* in graphics.c and fit.c */
#define X_AXIS axis_array[x_axis]
#define Y_AXIS axis_array[y_axis]
#define Z_AXIS axis_array[z_axis]
#define CB_AXIS axis_array[COLOR_AXIS]
/* -------- macros using these variables: */
/* Macros to map from user to terminal coordinates and back */
#define AXIS_MAP(axis, variable) \
(int) ((axis_array[axis].term_lower) \
+ ((variable) - axis_array[axis].min) \
* axis_array[axis].term_scale + 0.5)
#define AXIS_MAPBACK(axis, pos) \
(((double)(pos)-axis_array[axis].term_lower)/axis_array[axis].term_scale \
+ axis_array[axis].min)
/* these are the old names for these: */
#define map_x(x) AXIS_MAP(x_axis, x)
#define map_y(y) AXIS_MAP(y_axis, y)
#define AXIS_SETSCALE(axis, out_low, out_high) \
axis_array[axis].term_scale = ((out_high) - (out_low)) \
/ (axis_array[axis].max - axis_array[axis].min)
/* write current min/max_array contents into the set/show status
* variables */
#define AXIS_WRITEBACK(axis) \
do { \
AXIS *this = axis_array + axis; \
\
if (this->range_flags & RANGE_WRITEBACK) { \
if (this->autoscale & AUTOSCALE_MIN) \
this->set_min = this->min; \
if (this->autoscale & AUTOSCALE_MAX) \
this->set_max = this->max; \
} \
} while(0)
/* HBB 20000430: New macros, logarithmize a value into a stored
* coordinate*/
#define AXIS_DO_LOG(axis,value) (log(value) / axis_array[axis].log_base)
#define AXIS_UNDO_LOG(axis,value) exp((value) * axis_array[axis].log_base)
/* HBB 20000430: same, but these test if the axis is log, first: */
#define AXIS_LOG_VALUE(axis,value) \
(axis_array[axis].log ? AXIS_DO_LOG(axis,value) : (value))
#define AXIS_DE_LOG_VALUE(axis,coordinate) \
(axis_array[axis].log ? AXIS_UNDO_LOG(axis,coordinate): (coordinate))
/* copy scalar data to arrays. The difference between 3D and 2D
* versions is: dont know we have to support ranges [10:-10] - lets
* reverse it for now, then fix it at the end. */
/* FIXME HBB 20000426: unknown if this distinction makes any sense... */
#define AXIS_INIT3D(axis, islog_override, infinite) \
do { \
AXIS *this = axis_array + axis; \
\
this->autoscale = this->set_autoscale; \
if ((this->autoscale & AUTOSCALE_BOTH) == AUTOSCALE_NONE \
&& this->set_max < this->set_min) { \
this->min = this->set_max; \
this->max = this->set_min; \
/* we will fix later */ \
} else { \
this->min = (infinite && (this->set_autoscale & AUTOSCALE_MIN)) \
? VERYLARGE : this->set_min; \
this->max = (infinite && (this->set_autoscale & AUTOSCALE_MAX)) \
? -VERYLARGE : this->set_max; \
} \
if (islog_override) { \
this->log = 0; \
this->base = 1; \
this->log_base = 0; \
} else { \
this->log_base = this->log ? log(this->base) : 0; \
} \
} while(0)
#define AXIS_INIT2D(axis, infinite) \
do { \
AXIS *this = axis_array + axis; \
\
this->autoscale = this->set_autoscale; \
this->min = (infinite && (this->set_autoscale & AUTOSCALE_MIN)) \
? VERYLARGE : this->set_min; \
this->max = (infinite && (this->set_autoscale & AUTOSCALE_MAX)) \
? -VERYLARGE : this->set_max; \
this->log_base = this->log ? log(this->base) : 0; \
} while(0)
/* handle reversed ranges */
#define CHECK_REVERSE(axis) do { \
AXIS *this = axis_array + axis; \
\
if (((this->autoscale & AUTOSCALE_BOTH) == AUTOSCALE_NONE) \
&& (this->max < this->min)) { \
double temp = this->min; \
\
this->min = this->max; \
this->max = temp; \
this->range_is_reverted = 1; \
} else \
this->range_is_reverted = (this->range_flags & RANGE_REVERSE); \
} while(0)
/* HBB NEW 20050316: macros to always access the actual minimum, even
* if 'set view map' or something else flipped things around behind
* our back */
#define AXIS_ACTUAL_MIN(axis) \
(axis_array[axis].range_flags & RANGE_REVERSE \
? axis_array[axis].max : axis_array[axis].min)
#define AXIS_ACTUAL_MAX(axis) \
(axis_array[axis].range_flags & RANGE_REVERSE \
? axis_array[axis].min : axis_array[axis].max)
/* HBB 20000725: new macro, built upon ULIG's SAVE_WRITEBACK(axis),
* but easier to use. Code like this occured twice, in plot2d and
* plot3d: */
#define SAVE_WRITEBACK_ALL_AXES \
do { \
AXIS_INDEX axis; \
\
for (axis = 0; axis < AXIS_ARRAY_SIZE; axis++) \
if(axis_array[axis].range_flags & RANGE_WRITEBACK) { \
set_writeback_min(axis); \
set_writeback_max(axis); \
} \
} while(0)
/* get optional [min:max] */
#define PARSE_RANGE(axis) \
do { \
if (equals(c_token, "[")) { \
c_token++; \
axis_array[axis].autoscale = \
load_range(axis, &axis_array[axis].min, &axis_array[axis].max, \
axis_array[axis].autoscale); \
if (!equals(c_token, "]")) \
int_error(c_token, "']' expected"); \
c_token++; \
} \
} while (0)
/* HBB 20000430: new macro, like PARSE_RANGE, but for named ranges as
* in 'plot [phi=3.5:7] sin(phi)' */
#define PARSE_NAMED_RANGE(axis, dummy_token) \
do { \
if (equals(c_token, "[")) { \
c_token++; \
if (isletter(c_token)) { \
if (equals(c_token + 1, "=")) { \
dummy_token = c_token; \
c_token += 2; \
} \
/* oops; probably an expression with a variable: act \
* as if no variable name had been seen, by \
* fallthrough */ \
} \
axis_array[axis].autoscale = load_range(axis, &axis_array[axis].min, \
&axis_array[axis].max, \
axis_array[axis].autoscale); \
if (!equals(c_token, "]")) \
int_error(c_token, "']' expected"); \
c_token++; \
} /* first '[' */ \
} while (0)
/* parse a position of the form
* [coords] x, [coords] y {,[coords] z}
* where coords is one of first,second.graph,screen,character
* if first or second, we need to take axis_is_timedata into account
*/
#define GET_NUMBER_OR_TIME(store,axes,axis) \
do { \
if (((axes) >= 0) && (axis_array[(axes)+(axis)].is_timedata) \
&& isstringvalue(c_token)) { \
struct tm tm; \
char *ss = try_to_get_string(); \
if (gstrptime(ss,axis_array[axis].timefmt,&tm)) \
(store) = (double) gtimegm(&tm); \
free(ss); \
} else { \
struct value value; \
(store) = real(const_express(&value)); \
} \
} while(0)
/* This is one is very similar to GET_NUMBER_OR_TIME, but has slightly
* different usage: it writes out '0' in case of inparsable time data,
* and it's used when the target axis is fixed without a 'first' or
* 'second' keyword in front of it. */
#define GET_NUM_OR_TIME(store,axis) \
do { \
(store) = 0; \
GET_NUMBER_OR_TIME(store, FIRST_AXES, axis); \
} while (0);
/* store VALUE or log(VALUE) in STORE, set TYPE as appropriate
* Do OUT_ACTION or UNDEF_ACTION as appropriate
* adjust range provided type is INRANGE (ie dont adjust y if x is outrange
* VALUE must not be same as STORE
* Note: see the particular implementation for COLOR AXIS below.
*/
#define STORE_WITH_LOG_AND_UPDATE_RANGE(STORE, VALUE, TYPE, AXIS, \
OUT_ACTION, UNDEF_ACTION) \
do { \
/* HBB 20000726: new check, to avoid crashes with axis index -1 */ \
if (AXIS==-1) \
break; \
/* HBB 20040304: new check to avoid storing infinities and NaNs */ \
if (! (VALUE > -VERYLARGE && VALUE < VERYLARGE)) { \
TYPE = UNDEFINED; \
UNDEF_ACTION; \
break; \
} \
if (axis_array[AXIS].log) { \
if (VALUE<0.0) { \
TYPE = UNDEFINED; \
UNDEF_ACTION; \
break; \
} else if (VALUE == 0.0) { \
STORE = -VERYLARGE; \
TYPE = OUTRANGE; \
OUT_ACTION; \
break; \
} else { \
STORE = AXIS_DO_LOG(AXIS,VALUE); \
} \
} else \
STORE = VALUE; \
if (TYPE != INRANGE) \
break; /* don't set y range if x is outrange, for example */ \
if ((int)AXIS < 0) \
break; /* HBB 20000507: don't check range if not a coordinate */ \
if ( VALUE<axis_array[AXIS].min ) { \
if (axis_array[AXIS].autoscale & AUTOSCALE_MIN) \
axis_array[AXIS].min = VALUE; \
else { \
TYPE = OUTRANGE; \
OUT_ACTION; \
break; \
} \
} \
if ( VALUE>axis_array[AXIS].max ) { \
if (axis_array[AXIS].autoscale & AUTOSCALE_MAX) \
axis_array[AXIS].max = VALUE; \
else { \
TYPE = OUTRANGE; \
OUT_ACTION; \
} \
} \
} while(0)
/* Implementation of the above for the color axis. It should not change
* the type of the point (out-of-range color is plotted with the color
* of the min or max color value).
*/
#define COLOR_STORE_WITH_LOG_AND_UPDATE_RANGE(STORE, VALUE, TYPE, AXIS, \
OUT_ACTION, UNDEF_ACTION) \
{ \
int c_type_tmp = TYPE; \
STORE_WITH_LOG_AND_UPDATE_RANGE(STORE, VALUE, c_type_tmp, AXIS, \
OUT_ACTION, UNDEF_ACTION); \
}
/* Empty macro arguments triggered NeXT cpp bug */
/* #define NOOP (0) caused many warnings from gcc 3.2 */
/* Now trying ((void)0) */
#define NOOP ((void)0)
/* HBB 20000506: new macro, initializes one variable to the same
* value, for all axes. */
#define INIT_AXIS_ARRAY(field, value) \
do { \
int tmp; \
for (tmp=0; tmp<AXIS_ARRAY_SIZE; tmp++) \
axis_array[tmp].field=(value); \
} while(0)
/* HBB 20000506: new macro to automatically build intializer lists
* for arrays of AXIS_ARRAY_SIZE equal elements */
#define AXIS_ARRAY_INITIALIZER(value) { \
value, value, value, value, value, \
value, value, value, value, value, value }
/* used by set.c */
#define SET_DEFFORMAT(axis, flag_array) \
if (flag_array[axis]) { \
(void) strcpy(axis_array[axis].formatstring,DEF_FORMAT); \
axis_array[axis].format_is_numeric = 1; \
}
/* 'roundoff' check tolerance: less than one hundredth of a tic mark */
#define SIGNIF (0.01)
/* (DFK) Watch for cancellation error near zero on axes labels */
/* FIXME HBB 20000521: these seem not to be used much, anywhere... */
#define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x))
#define NearlyEqual(x,y,tic) (fabs((x)-(y)) < ((tic) * SIGNIF))
/* ------------ functions exported by axis.c */
t_autoscale load_range __PROTO((AXIS_INDEX, double *, double *, t_autoscale));
void axis_unlog_interval __PROTO((AXIS_INDEX, double *, double *, TBOOLEAN));
void axis_revert_and_unlog_range __PROTO((AXIS_INDEX));
double axis_log_value_checked __PROTO((AXIS_INDEX, double, const char *));
void axis_checked_extend_empty_range __PROTO((AXIS_INDEX, const char *mesg));
char * copy_or_invent_formatstring __PROTO((AXIS_INDEX));
double quantize_normal_tics __PROTO((double, int));
void setup_tics __PROTO((AXIS_INDEX, int));
void gen_tics __PROTO((AXIS_INDEX, /* int, */ tic_callback));
void axis_output_tics __PROTO((AXIS_INDEX, int *, AXIS_INDEX, tic_callback));
void axis_set_graphical_range __PROTO((AXIS_INDEX, unsigned int lower, unsigned int upper));
void axis_draw_2d_zeroaxis __PROTO((AXIS_INDEX, AXIS_INDEX));
TBOOLEAN some_grid_selected __PROTO((void));
void add_tic_user __PROTO((AXIS_INDEX, char *, double, int));
double get_writeback_min __PROTO((AXIS_INDEX));
double get_writeback_max __PROTO((AXIS_INDEX));
void set_writeback_min __PROTO((AXIS_INDEX));
void set_writeback_max __PROTO((AXIS_INDEX));
/* set widest_tic_label: length of the longest tics label */
void widest_tic_callback __PROTO((AXIS_INDEX, double place, char *text, struct lp_style_type grid));
void get_position __PROTO((struct position *pos));
void get_position_default __PROTO((struct position *pos, enum position_type default_type));
/* ------------ autoscaling of the color axis */
#define NEED_PALETTE(plot) \
(PM3DSURFACE == (plot)->plot_style \
|| PM3D_IMPLICIT == pm3d.implicit \
|| 1 == (plot)->lp_properties.use_palette)
int set_cbminmax __PROTO((void));
#endif /* GNUPLOT_AXIS_H */
|