[BACK]Return to graphics.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Diff for /OpenXM_contrib/gnuplot/Attic/graphics.c between version 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2000/01/22 14:15:57 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;
Line 583  int count;
Line 588  int count;
     /* 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;
Line 668  int count;
Line 674  int count;
     /* 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;
Line 704  int count;
Line 710  int count;
         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)
Line 844  int count;
Line 854  int count;
     /* 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)
Line 905  int count;
Line 915  int count;
     /* 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; */
Line 1012  int count;
Line 1022  int count;
   
     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;
         }          }
Line 1175  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;
   
Line 1214  int guide;
Line 1224  int guide;
   
 /*{{{  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 1285  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 1369  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 1388  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 1409  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 1426  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 1454  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 1470  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 1490  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 1507  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 1560  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_Y_AXIS] = map_y(0.0);  
     axis_zero[FIRST_X_AXIS] = map_x(0.0);  
   
     if (axis_zero[FIRST_Y_AXIS] < ybot || is_log_y)      if (y_min >= 0.0 && y_max >= 0.0 || is_log_y)
         axis_zero[FIRST_Y_AXIS] = ybot;         /* save for impulse plotting */          axis_zero[FIRST_Y_AXIS] = ybot;         /* save for impulse plotting */
     else if (axis_zero[FIRST_Y_AXIS] >= ytop)      else if (y_min <= 0.0 && y_max <= 0.0)
         axis_zero[FIRST_Y_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_Y_AXIS]);          if (xzeroaxis.l_type > -3) {
         (*t->vector) (xright, axis_zero[FIRST_Y_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_X_AXIS] >= xleft          axis_zero[FIRST_X_AXIS] = xleft;
         && axis_zero[FIRST_X_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_X_AXIS], ybot);      else {
         (*t->vector) (axis_zero[FIRST_X_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_Y_AXIS] = map_y(0.0);  
     axis_zero[SECOND_X_AXIS] = map_x(0.0);  
   
     if (axis_zero[SECOND_Y_AXIS] < ybot || is_log_y2)      if (is_log_y2 || y_min >= 0.0 && y_max >= 0.0)
         axis_zero[SECOND_Y_AXIS] = ybot;  /* save for impulse plotting */          axis_zero[SECOND_Y_AXIS] = ybot;  /* save for impulse plotting */
     else if (axis_zero[SECOND_Y_AXIS] >= ytop)      else if (y_min <= 0.0 && y_max <= 0.0)
         axis_zero[SECOND_Y_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_Y_AXIS]);          if (x2zeroaxis.l_type > -3) {
         (*t->vector) (xright, axis_zero[SECOND_Y_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 &&      if (y_min >= 0.0 && y_max >= 0.0)
         axis_zero[SECOND_X_AXIS] >= xleft &&          axis_zero[SECOND_X_AXIS] = xleft;
         axis_zero[SECOND_X_AXIS] < xright) {      else if (x_min <= 0.0 && x_max <= 0.0)
         term_apply_lp_properties(&y2zeroaxis);          axis_zero[SECOND_X_AXIS] = xright;
         (*t->move) (axis_zero[SECOND_X_AXIS], ybot);      else {
         (*t->vector) (axis_zero[SECOND_X_AXIS], ytop);          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 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 1808  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 1958  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 2213  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 2221  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 2236  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 2248  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 2284  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 2734  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 3724  char *font;   /* NULL or "" means use default */
Line 3806  char *font;   /* NULL or "" means use default */
   
 }  }
   
   /* 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 3799  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;
Line 3886  int *lines;
Line 3972  int *lines;
   
   
 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 3900  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 3982  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 4147  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 4159  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 4176  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 4226  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 4237  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 4257  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 4365  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 4487  char *what;
Line 4576  char *what;
     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;
         }          }
     }      }
Line 4512  char *what;
Line 4603  char *what;
     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;
         }          }
     }      }

Legend:
Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>