[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 and 1.1.1.3

version 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;
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 593  int count;
Line 599  int count;
             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);
         }          }
Line 646  int count;
Line 654  int count;
   
     /* 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;
Line 659  int count;
Line 667  int count;
          * 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);
         }          }
Line 699  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 839  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)
             + 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);
         }          }
Line 854  int count;
Line 874  int count;
     } 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 }}} */
   
   
Line 900  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 913  int count;
Line 928  int count;
             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);
         }          }
Line 929  int count;
Line 944  int count;
         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;
   
Line 942  int count;
Line 957  int count;
                 /* 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;
             }              }
         }          }
Line 973  int count;
Line 986  int count;
     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;
Line 1002  int count;
Line 1011  int count;
   
     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;
   
Line 1215  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 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;
Line 3876  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 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 */
Line 4475  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 4500  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  
changed lines
  Added in v.1.1.1.3

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