1  /*


2  * $Source: /tmp_mnt/n/fs/grad1/jsp/src/jgraph/RCS/process.c,v $


3  * $Revision: 8.3 $


4  * $Date: 92/11/30 11:42:35 $


5  * $Author: jsp $


6  */


7 


8  #include <stdio.h>


9  #include <math.h>


10  #include <string.h>


11 


12  #include "jgraph.h"


13 


14  #define ABS(a) ((a > 0.0) ? (a) : (a))


15  #define MAX(a, b) ((a > b) ? (a) : (b))


16  #define MIN(a, b) ((a < b) ? (a) : (b))


17  #define AXIS_CHAR(a) ((a>is_x) ? 'x' : 'y')


18  #define HASH_DIR(a) ((a>hash_scale > 0.0) ? 1 : 1)


19 


20  static double Pi;


21 


22  void process_label(Label l, Graph g, int adjust);


23 


24  void process_title(Graph g)


25  {


26 


27  float ytitleloc;


28 


29  if (g>title>x == FSIG) g>title>x = g>x_axis>psize / 2.0;


30  else g>title>x = ctop(g>title>x, g>x_axis);


31  if (g>title>y != FSIG) g>title>y = ctop(g>title>y, g>y_axis);


32  else {


33  ytitleloc = 0.0;


34  if (g>x_axis>draw_axis_label && g>x_axis>label>label != CNULL)


35  ytitleloc = MIN(ytitleloc, g>x_axis>label>ymin);


36  if (g>x_axis>draw_hash_labels)


37  ytitleloc = MIN(ytitleloc, g>x_axis>hl>ymin);


38  if (g>x_axis>draw_hash_marks)


39  ytitleloc = MIN(ytitleloc, g>x_axis>draw_hash_marks_at  HASH_SIZE);


40  if (g>legend>type == 'u')


41  ytitleloc = MIN(ytitleloc, g>legend>l>ymin);


42 


43  g>title>y = ytitleloc  10.0;


44  }


45  process_label(g>title, g, 0);


46  }


47 


48  void process_label_max_n_mins(Label l, float len, float height)


49  {


50  float xlen, ylen, xheight, yheight;


51  float x, y;


52 


53  xlen = len * cos(l>rotate * Pi / 180.00);


54  ylen = height * cos((l>rotate + 90.0) * Pi / 180.00);


55  xheight = len * sin(l>rotate * Pi / 180.00);


56  yheight = height * sin((l>rotate + 90.0) * Pi / 180.00);


57 


58  x = l>x;


59  y = l>y;


60 


61  if (l>hj == 'c') {


62  x = xlen / 2.0;


63  y = xheight / 2.0;


64  } else if (l>hj == 'r') {


65  x = xlen;


66  y = xheight;


67  }


68  if (l>vj == 'c') {


69  x = ylen / 2.0;


70  y = yheight / 2.0;


71  } else if (l>vj == 't') {


72  x = ylen;


73  y = yheight;


74  }


75 


76  l>xmin = MIN(x, x + xlen);


77  l>xmin = MIN(l>xmin, x + xlen + ylen);


78  l>xmin = MIN(l>xmin, x + ylen);


79 


80  l>ymin = MIN(y, y + xheight);


81  l>ymin = MIN(l>ymin, y + yheight);


82  l>ymin = MIN(l>ymin, y + xheight + yheight);


83 


84  l>xmax = MAX(x, x + xlen);


85  l>xmax = MAX(l>xmax, x + xlen + ylen);


86  l>xmax = MAX(l>xmax, x + ylen);


87 


88  l>ymax = MAX(y, y + xheight);


89  l>ymax = MAX(l>ymax, y + yheight);


90  l>ymax = MAX(l>ymax, y + xheight + yheight);


91 


92  }


93 


94  void process_legend(Graph g)


95  {


96  Legend l;


97  int anything;


98  float height, hdist, y, x, width, maxmark, maxmarky;


99  Curve c;


100  char *s;


101 


102  l = g>legend;


103  if (l>type == 'n') return;


104  if (l>l>linesep == FSIG) l>l>linesep = l>l>fontsize;


105  l>anylines = 0;


106  maxmark = 0.0;


107  maxmarky = 0.0;


108  anything = 0;


109  for (c = first(g>curves); c != nil(g>curves); c = next(c)) {


110  if (c>l>label != CNULL) {


111  anything = 1;


112  if (c>marktype == 'l') {


113  maxmark = MAX(maxmark, c>lmark>xmax  c>lmark>xmin);


114  maxmarky = MAX(maxmarky, c>lmark>ymax  c>lmark>ymin);


115  } else if (c>marktype != 'n') {


116  maxmark = MAX(maxmark, ABS(c>marksize[0]));


117  maxmarky = MAX(maxmarky, ABS(c>marksize[1]));


118  }


119  if (c>linetype != '0') l>anylines = 1;


120  }


121  }


122  if (l>linelength == FSIG)


123  l>linelength = (l>anylines) ? (MAX(maxmark + 6.0, 24.0)) : 0.0;


124  else l>linelength = disttop(l>linelength, g>x_axis);


125  if (l>midspace == FSIG)


126  l>midspace = (l>anylines) ? 4.0 : (maxmark / 2.0) + 4.0;


127  else l>midspace = disttop(l>midspace, g>x_axis);


128  if (l>linebreak == FSIG)


129  l>linebreak = MAX(l>l>linesep * FCPI / FPPI, maxmarky);


130  else l>linebreak = disttop(l>linebreak, g>y_axis);


131 


132  if (l>type == 'c') {


133  for (c = first(g>curves); c != nil(g>curves); c = next(c)) {


134  if (c>l>label != CNULL) process_label(c>l, g, 1);


135  }


136  return;


137  }


138 


139  if (!anything) {


140  l>anylines = 1;


141  return;


142  }


143 


144  width = 0.0;


145  height = l>linebreak;


146  for (c = first(g>curves); c != nil(g>curves); c = next(c)) {


147  if (c>l>label != CNULL) {


148  s = c>l>label;


149  copy_label(c>l, l>l);


150  c>l>x = 0.0;


151  c>l>y = 0.0;


152  c>l>rotate = 0.0;


153  c>l>hj = 'l';


154  c>l>vj = 'b';


155  c>l>label = s;


156  process_label(c>l, g, 0);


157  height += c>l>ymax + l>linebreak;


158  width = MAX(width, c>l>xmax);


159  }


160  }


161  hdist = (l>anylines) ? l>midspace + l>linelength : l>midspace;


162  width += hdist;


163 


164  if (l>l>x == FSIG) {


165  if (l>l>hj == 'c') {


166  l>l>x = g>x_axis>psize / 2;


167  } else if (l>l>hj == 'l') {


168  if (l>l>vj == 'c') {


169  l>l>x = g>x_axis>psize;


170  if (g>y_axis>draw_axis_label)


171  l>l>x = MAX(l>l>x, g>y_axis>label>xmax);


172  if (g>y_axis>draw_hash_labels)


173  l>l>x = MAX(l>l>x, g>y_axis>hl>xmax);


174  if (g>y_axis>draw_hash_marks) {


175  l>l>x = MAX(l>l>x, g>y_axis>draw_hash_marks_at);


176  l>l>x = MAX(l>l>x, g>y_axis>draw_hash_marks_at +


177  HASH_DIR(g>y_axis) * HASH_SIZE);


178  }


179  l>l>x += 15.0;


180  } else {


181  l>l>x = 0.0;


182  }


183  } else {


184  if (l>l>vj == 'c') {


185  l>l>x = 0.0;


186  if (g>y_axis>draw_axis_label)


187  l>l>x = MIN(l>l>x, g>y_axis>label>xmin);


188  if (g>y_axis>draw_hash_labels)


189  l>l>x = MIN(l>l>x, g>y_axis>hl>xmin);


190  if (g>y_axis>draw_hash_marks) {


191  l>l>x = MIN(l>l>x, g>y_axis>draw_hash_marks_at);


192  l>l>x = MIN(l>l>x, g>y_axis>draw_hash_marks_at +


193  HASH_DIR(g>y_axis) * HASH_SIZE);


194  }


195  l>l>x = l>l>x  15.0;


196  } else {


197  l>l>x = g>x_axis>psize;


198  }


199  }


200  } else {


201  l>l>x = ctop(l>l>x, g>x_axis);


202  }


203  if (l>l>y == FSIG) {


204  if (l>l>vj == 'c') {


205  l>l>y = g>y_axis>psize / 2.0;


206  } else if (l>l>vj == 'b') {


207  l>l>y = g>y_axis>psize;


208  if (g>x_axis>draw_axis_label)


209  l>l>y = MAX(l>l>y, g>x_axis>label>ymax);


210  if (g>x_axis>draw_hash_labels)


211  l>l>y = MAX(l>l>y, g>x_axis>hl>ymax);


212  if (g>x_axis>draw_hash_marks) {


213  l>l>y = MAX(l>l>y, g>x_axis>draw_hash_marks_at);


214  l>l>y = MAX(l>l>y, g>x_axis>draw_hash_marks_at +


215  HASH_DIR(g>x_axis) * HASH_SIZE);


216  }


217  l>l>y += 15.0;


218  } else {


219  l>l>y = 0.0;


220  if (g>x_axis>draw_axis_label)


221  l>l>y = MIN(l>l>y, g>x_axis>label>ymin);


222  if (g>x_axis>draw_hash_labels)


223  l>l>y = MIN(l>l>y, g>x_axis>hl>ymin);


224  if (g>x_axis>draw_hash_marks) {


225  l>l>y = MIN(l>l>y, g>x_axis>draw_hash_marks_at);


226  l>l>y = MIN(l>l>y, g>x_axis>draw_hash_marks_at +


227  HASH_DIR(g>x_axis) * HASH_SIZE);


228  }


229  l>l>y = 15.0;


230  }


231  } else {


232  l>l>y = ctop(l>l>y, g>y_axis);


233  }


234 


235  if (l>l>hj == 'l') x = 0.0;


236  else if (l>l>hj == 'c') x =  width/2.0;


237  else x = width;


238 


239  if (l>l>vj == 't') y = 0.0;


240  else if (l>l>vj == 'c') y = height / 2.0;


241  else y = height;


242 


243  for (c = first(g>curves); c != nil(g>curves); c = next(c)) {


244  if (c>l>label != CNULL) {


245  c>l>x = hdist + x;


246  c>l>y = y;


247  c>l>vj = 't';


248  c>l>hj = 'l';


249  c>l>rotate = 0.0;


250  process_label(c>l, g, 0);


251  y = c>l>ymin  l>linebreak;


252  }


253  }


254 


255  process_label_max_n_mins(l>l, width, height);


256  }


257 


258  float find_reasonable_hash_interval(Axis a)


259  {


260  float s, d;


261 


262  if (a>is_lg) return 0.0;


263  s = a>max  a>min;


264  d = 1.0;


265  if (s > 5.0) {


266  while(1) {


267  if (s / d < 6.0) return d;


268  d *= 2.0;


269  if (s / d < 6.0) return d;


270  d *= 2.5;


271  if (s / d < 6.0) return d;


272  d *= 2.0;


273  }


274  } else {


275  while(1) {


276  if (s / d > 2.0) return d;


277  d /= 2.0;


278  if (s / d > 2.0) return d;


279  d /= 2.5;


280  if (s / d > 2.0) return d;


281  d /= 2.0;


282  }


283  }


284  }


285 


286  float find_reasonable_hash_start(Axis a)


287  {


288  int i;


289 


290  if (a>is_lg) return 0.0;


291  if (a>max > 0.0 && a>min < 0.0) return 0.0;


292  i = ((int) (a>min / a>hash_interval));


293  return ((float) i) * a>hash_interval;


294  }


295 


296  int find_reasonable_precision(Axis a)


297  {


298  int i, b, b2, done;


299  float x, x2, tolerance;


300 


301  if (a>hash_format == 'g'  a>hash_format == 'G') return 6;


302  if (a>hash_format == 'e'  a>hash_format == 'E') return 0;


303  if (a>is_lg) return 0;


304 


305  tolerance = 0.000001;


306  b = 0;


307  x = a>hash_interval;


308 


309  done = 0;


310  while(b < 6 && !done) {


311  i = (int) (x + 0.4);


312  x2 = i;


313  if (x2  x < tolerance && x  x2 < tolerance) done = 1;


314  else {


315  b++;


316  x *= 10.0;


317  tolerance *= 10.0;


318  }


319  }


320 


321  tolerance = 0.000001;


322  b2 = 0;


323  x = a>hash_start;


324 


325  done = 0;


326  while(b2 < 6 && !done) {


327  i = (int) (x + 0.4);


328  x2 = i;


329  if (x2  x < tolerance && x  x2 < tolerance) done = 1;


330  else {


331  b2++;


332  x *= 10.0;


333  tolerance *= 10.0;


334  }


335  }


336  return MAX(b, b2);


337  }


338 


339  int find_reasonable_minor_hashes(Axis a)


340  {


341  float d;


342  int i;


343 


344  if (a>is_lg) {


345  d = a>log_base;


346  while(d > 10.0) d /= 10.0;


347  while(d <= 1.0) d *= 10.0;


348  i = (int) d;


349  return MAX((i  2), 0);


350  } else {


351  d = a>hash_interval;


352  if (d == 0.0) return 0;


353  while(d > 10.0) d /= 10.0;


354  while(d <= 1.0) d *= 10.0;


355  i = (int) d;


356  if (((float) i) != d) return 0;


357  return i1;


358  }


359  }


360 


361  void process_axis1(Axis a, Graph g)


362  {


363  float tmp;


364  int i;


365 


366  if (a>min == FSIG) {


367  if (a>pmin == FSIG) {


368  error_header();


369  fprintf(stderr,


370  "Graph %d: %c axis has no minimum, and cannot derive one\n",


371  g>num, AXIS_CHAR(a));


372  fprintf(stderr, " Use %caxis min\n", AXIS_CHAR(a));


373  exit(1);


374  } else if (a>pmin <= 0.0 && a>is_lg) {


375  error_header();


376  fprintf(stderr, "Trying to derive %c axis\n", AXIS_CHAR(a));


377  fprintf(stderr,


378  " Minimum value %f will be infinity with log axes\n", a>pmin);


379  exit(1);


380  } else a>min = a>pmin;


381  }


382  if (a>max == FSIG) {


383  if (a>pmax == FSIG) {


384  error_header();


385  fprintf(stderr,


386  "Graph %d: %c axis has no maximum, and cannot derive one\n",


387  g>num, AXIS_CHAR(a));


388  fprintf(stderr, " Use %caxis max\n", AXIS_CHAR(a));


389  exit(1);


390  } else if (a>pmax <= 0.0 && a>is_lg) {


391  error_header();


392  fprintf(stderr, "Trying to derive %c axis\n", AXIS_CHAR(a));


393  fprintf(stderr,


394  " Maximum value %f will be infinity with log axes\n", a>pmax);


395  exit(1);


396  } else a>max = a>pmax;


397  }


398  if (a>max < a>min) {


399  tmp = a>max; a>max = a>min; a>min = tmp;


400  } else if (a>max == a>min) {


401  if (!a>is_lg) a>min = 1;


402  a>max += 1;


403  }


404  a>psize = intop(a>size);


405  if (a>is_lg) {


406  if (a>min <= 0.0) {


407  error_header();


408  fprintf(stderr,


409  "Graph %d, %c axis: Min value = %f. This is infinity with logrhythmic axes\n",


410  g>num, (a>is_x) ? 'x' : 'y', a>min);


411  exit(1);


412  }


413  a>logfactor = log(a>log_base);


414  a>logmin = log(a>min) / a>logfactor;


415  a>factor = a>psize / (log(a>max) / a>logfactor  a>logmin);


416  } else {


417  a>factor = a>psize / (a>max  a>min);


418  }


419  if (a>gr_graytype == '0') {


420  a>gr_graytype = a>graytype;


421  for (i = 0; i < 3; i++) a>gr_gray[i] = a>gray[i];


422  }


423  if (a>mgr_graytype == '0') {


424  a>mgr_graytype = a>gr_graytype;


425  for (i = 0; i < 3; i++) a>mgr_gray[i] = a>gr_gray[i];


426  }


427  }


428 


429  void process_axis2(Axis a, Graph g)


430  {


431  float t1, t2, t3, minor_hashes, hloc, tmp;


432  float ymin, ymax, xmin, xmax;


433  int prec, i1;


434  Hash h;


435  String s;


436  Axis other;


437 


438  other = (a>is_x) ? g>y_axis : g>x_axis;


439  if (a>draw_at == FSIG)


440  a>draw_at = (HASH_DIR(a) == 1) ? 0.0 : other>psize;


441  else a>draw_at = ctop(a>draw_at, other);


442 


443  if (a>hash_interval < 0.0) {


444  a>hash_interval = find_reasonable_hash_interval(a);


445  if (!a>start_given)


446  a>hash_start = find_reasonable_hash_start(a);


447  } else if (!a>start_given) a>hash_start = a>min;


448  if (a>minor_hashes < 0) {


449  a>minor_hashes = find_reasonable_minor_hashes(a);


450  }


451  if (a>precision < 0) a>precision = find_reasonable_precision(a);


452 


453  for (h = first(a>hash_lines) ; h != nil(a>hash_lines); h = next(h)) {


454  h>loc = ctop(h>loc, a);


455  }


456 


457  for (s = first(a>hash_labels); s != nil(a>hash_labels); s = next(s)) {


458  s>s>x = ctop(s>s>x, a);


459  s>s>y = ctop(s>s>y, a);


460  }


461 


462  if (((a>hash_interval != 0.0 && !a>is_lg)  a>is_lg) && a>auto_hash_marks) {


463  if (a>is_lg) {


464  for (t1 = 1.0; t1 > a>min; t1 /= a>log_base) ;


465  t2 = t1 * a>log_base  t1;


466  } else {


467  for (t1 = a>hash_start; t1 > a>min; t1 = a>hash_interval) ;


468  t2 = a>hash_interval;


469  }


470  while (t1 <= a>max) {


471  hloc = ctop(t1, a);


472  if (hloc > .05 && hloc < a>psize + .05) {


473  h = (Hash) get_node(a>hash_lines);


474  h>loc = hloc;


475  h>size = HASH_SIZE;


476  h>major = 1;


477  insert(h, a>hash_lines);


478  if (a>auto_hash_labels) {


479  s = (String) get_node (a>hash_labels);


480  s>s = new_label();


481  s>s>x = hloc;


482  s>s>y = hloc;


483  s>s>label = (char *) malloc (80);


484  if (a>precision >= 0) {


485  prec = a>precision;


486  } else {


487  if (ABS(t1) >= 1.0  t1 == 0.0) prec = 0;


488  else {


489  tmp = ABS(t1);


490  prec = 1;


491  while(tmp < 1.0) {tmp *= 10.0; prec++;}


492  }


493  }


494  switch(a>hash_format) {


495  case 'G': sprintf(s>s>label, "%.*G", prec, t1); break;


496  case 'g': sprintf(s>s>label, "%.*g", prec, t1); break;


497  case 'E': sprintf(s>s>label, "%.*E", prec, t1); break;


498  case 'e': sprintf(s>s>label, "%.*e", prec, t1); break;


499  case 'f': sprintf(s>s>label, "%.*f", prec, t1); break;


500  default: fprintf(stderr, "Internal jgraph error: hl_st\n");


501  exit(1);


502  }


503  insert(s, a>hash_labels);


504  }


505  }


506  minor_hashes = t2 / ((float) (a>minor_hashes + 1));


507  t3 = t1;


508  for (i1 = 1; i1 <= a>minor_hashes; i1++) {


509  t3 += minor_hashes;


510  hloc = ctop(t3, a);


511  if (hloc > .05 && hloc < a>psize + .05) {


512  h = (Hash) get_node(a>hash_lines);


513  h>loc = hloc;


514  h>size = MHASH_SIZE;


515  h>major = 0;


516  insert(h, a>hash_lines);


517  }


518  }


519  if (a>is_lg) {


520  t1 *= a>log_base;


521  t2 = t1 * a>log_base  t1;


522  } else t1 += t2;


523  }


524  }


525 


526  if (a>draw_hash_marks_at == FSIG)


527  a>draw_hash_marks_at = a>draw_at;


528  else a>draw_hash_marks_at = ctop(a>draw_hash_marks_at, other);


529  if (a>draw_hash_labels_at == FSIG)


530  a>draw_hash_labels_at = a>draw_hash_marks_at +


531  a>hash_scale * HASH_SIZE + HASH_DIR(a) * 3.0;


532  else a>draw_hash_labels_at = ctop(a>draw_hash_labels_at, other);


533 


534  if (a>is_x) {


535  a>hl>y = a>draw_hash_labels_at;


536  if (a>hl>hj == '0')


537  a>hl>hj = 'c';


538  if (a>hl>vj == '0')


539  a>hl>vj = (HASH_DIR(a) == 1) ? 't' : 'b';


540  } else {


541  a>hl>x = a>draw_hash_labels_at;


542  if (a>hl>vj == '0') a>hl>vj = 'c';


543  if (a>hl>hj == '0')


544  a>hl>hj = (HASH_DIR(a) == 1) ? 'r' : 'l';


545  }


546 


547  ymin = (a>is_x) ? a>hl>y : 0;


548  ymax = (a>is_x) ? a>hl>y : a>psize;


549  xmin = (!a>is_x) ? a>hl>x : 0;


550  xmax = (!a>is_x) ? a>hl>x : a>psize;


551 


552  for (s = first(a>hash_labels); s != nil(a>hash_labels); s = next(s)) {


553  if (a>is_x) a>hl>x = s>s>x; else a>hl>y = s>s>y;


554  a>hl>label = s>s>label;


555  process_label(a>hl, g, 0);


556  xmin = MIN(a>hl>xmin, xmin);


557  ymin = MIN(a>hl>ymin, ymin);


558  xmax = MAX(a>hl>xmax, xmax);


559  ymax = MAX(a>hl>ymax, ymax);


560  }


561  a>hl>xmin = xmin;


562  a>hl>ymin = ymin;


563  a>hl>xmax = xmax;


564  a>hl>ymax = ymax;


565 


566  /* HERE  now either test or continue */


567 


568  if (a>is_x) {


569  if (a>label>x == FSIG)


570  a>label>x = a>psize / 2.0;


571  else a>label>x = ctop(a>label>x, g>x_axis);


572  if (a>label>y == FSIG) {


573  ymin = 0.0;


574  ymax = other>psize;


575  if (a>draw_hash_labels) {


576  ymin = MIN(ymin, a>hl>ymin);


577  ymax = MAX(ymax, a>hl>ymax);


578  }


579  if (a>draw_hash_marks) {


580  ymin = MIN(ymin, a>draw_hash_marks_at);


581  ymin = MIN(ymin, a>draw_hash_marks_at + a>hash_scale * HASH_SIZE);


582  ymax = MAX(ymax, a>draw_hash_marks_at);


583  ymax = MAX(ymax, a>draw_hash_marks_at + a>hash_scale * HASH_SIZE);


584  }


585  a>label>y = (HASH_DIR(a) == 1) ? ymin  8.0 : ymax + 8.0 ;


586  } else a>label>y = ctop(a>label>y, g>y_axis);


587  if (a>label>hj == '0') a>label>hj = 'c';


588  if (a>label>vj == '0') a>label>vj = (HASH_DIR(a) == 1) ? 't' : 'b' ;


589  if (a>label>rotate == FSIG) a>label>rotate = 0.0;


590  } else {


591  if (a>label>y == FSIG)


592  a>label>y = a>psize / 2.0;


593  else a>label>y = ctop(a>label>y, g>y_axis);


594  if (a>label>x == FSIG) {


595  xmin = 0.0;


596  xmax = other>psize;


597  if (a>draw_hash_labels) {


598  xmin = MIN(xmin, a>hl>xmin);


599  xmax = MAX(xmax, a>hl>xmax);


600  }


601  if (a>draw_hash_marks) {


602  xmin = MIN(xmin, a>draw_hash_marks_at);


603  xmin = MIN(xmin, a>draw_hash_marks_at + a>hash_scale * HASH_SIZE);


604  xmax = MAX(xmax, a>draw_hash_marks_at);


605  xmax = MAX(xmax, a>draw_hash_marks_at + a>hash_scale * HASH_SIZE);


606  }


607  a>label>x = (HASH_DIR(a) == 1) ? xmin  8.0 : xmax + 8.0 ;


608  } else a>label>x = ctop(a>label>x, g>x_axis);


609  if (a>label>hj == '0') a>label>hj = 'c';


610  if (a>label>vj == '0') a>label>vj = 'b';


611  if (a>label>rotate == FSIG)


612  a>label>rotate = (HASH_DIR(a) == 1) ? 90.0 : 90.0;


613  }


614  process_label (a>label, g, 0);


615  }


616 


617  void process_label(Label l, Graph g, int adjust)


618  {


619  float len, height;


620  int f, i;


621  float fnl, tmp;


622  char *s;


623 


624  if (l>label == CNULL) return;


625 


626  if (adjust) {


627  l>x = ctop(l>x, g>x_axis);


628  l>y = ctop(l>y, g>y_axis);


629  }


630  if (l>linesep == FSIG) l>linesep = l>fontsize;


631 


632  l>nlines = 0;


633  for (i = 0; l>label[i] != '\0'; i++) {


634  if (l>label[i] == '\n') {


635  l>label[i] = '\0';


636  l>nlines++;


637  }


638  }


639  fnl = (float) l>nlines;


640 


641  len = 0.0;


642  s = l>label;


643  for (i = 0; i <= l>nlines; i++) {


644  tmp = l>fontsize * FCPI / FPPI * strlen(s) * 0.8;


645  len = MAX(len, tmp);


646  if (i != l>nlines) {


647  f = strlen(s);


648  s[f] = '\n';


649  s = &(s[f+1]);


650  }


651  }


652  height = (l>fontsize * (fnl+1) + l>linesep * fnl) * FCPI / FPPI;


653  process_label_max_n_mins(l, len, height);


654  }


655 


656  void process_strings(Graph g)


657  {


658  String s;


659 


660  for(s = first(g>strings); s != nil(g>strings); s = next(s)) {


661  process_label(s>s, g, 1);


662  }


663  }


664 


665  void process_curve(Curve c, Graph g)


666  {


667  if (c>bezier && (c>npts < 4  (c>npts % 3 != 1))) {


668  error_header();


669  fprintf(stderr, " Graph %d Curve %d:\n", g>num, c>num);


670  fprintf(stderr, " Curve has %d points\n", c>npts);


671  fprintf(stderr, " Bezier must have 3n + 1 points (n > 0)\n");


672  exit(1);


673  }


674  c>marksize[0] = (c>marksize[0] == FSIG) ?


675  4.0 : disttop(c>marksize[0], g>x_axis);


676  c>marksize[1] = (c>marksize[1] == FSIG) ?


677  4.0 : disttop(c>marksize[1], g>y_axis);


678  if (c>marktype == 'o') c>marksize[1] = c>marksize[0];


679  c>asize[0] = (c>asize[0] == FSIG) ?


680  6.0 : disttop(c>asize[0], g>x_axis);


681  c>asize[1] = (c>asize[1] == FSIG) ?


682  2.0 : disttop(c>asize[1], g>y_axis) / 2.0;


683  c>lmark>x = disttop(c>lmark>x, g>x_axis);


684  c>lmark>y = disttop(c>lmark>y, g>y_axis);


685  process_label(c>lmark, g, 0);


686  if (c>parg == FSIG) c>parg = 0.0;


687  if (c>aparg == FSIG) c>aparg = 0.0;


688  if (c>pparg == FSIG) c>pparg = 0.0;


689  }


690 


691  void process_curves(Graph g)


692  {


693  Curve c;


694  for(c = first(g>curves); c != nil(g>curves); c = next(c)) {


695  process_curve(c, g);


696  }


697  }


698 


699  void process_label_extrema(Label l, Graph g)


700  {


701  if (l>label == CNULL) return;


702  g>yminval = MIN(g>yminval, l>ymin);


703  g>ymaxval = MAX(g>ymaxval, l>ymax);


704  g>xminval = MIN(g>xminval, l>xmin);


705  g>xmaxval = MAX(g>xmaxval, l>xmax);


706  }


707 


708  void process_extrema(Graph g) /* Finds all the minval/maxvals for bbox calc */


709  {


710  Curve c;


711  String s;


712  Axis xa, ya;


713 


714  xa = g>x_axis;


715  ya = g>y_axis;


716 


717  g>xminval = 0.0;


718  g>yminval = 0.0;


719  g>xmaxval = xa>psize;


720  g>ymaxval = ya>psize;


721 


722  if (xa>draw_axis_label) process_label_extrema(xa>label, g);


723  if (ya>draw_axis_label) process_label_extrema(ya>label, g);


724  if (xa>draw_hash_labels) process_label_extrema(xa>hl, g);


725  if (ya>draw_hash_labels) process_label_extrema(ya>hl, g);


726 


727  if (xa>draw_hash_marks) {


728  g>yminval = MIN(g>yminval, xa>draw_hash_marks_at);


729  g>yminval = MIN(g>yminval,


730  xa>draw_hash_marks_at + HASH_DIR(xa) * HASH_SIZE);


731  g>ymaxval = MAX(g>ymaxval, xa>draw_hash_marks_at);


732  g>ymaxval = MAX(g>ymaxval,


733  xa>draw_hash_marks_at + HASH_DIR(xa) * HASH_SIZE);


734  }


735  if (ya>draw_hash_marks) {


736  g>xminval = MIN(g>xminval, ya>draw_hash_marks_at);


737  g>xminval = MIN(g>xminval,


738  ya>draw_hash_marks_at + HASH_DIR(ya) * HASH_SIZE);


739  g>xmaxval = MAX(g>xmaxval, ya>draw_hash_marks_at);


740  g>xmaxval = MAX(g>xmaxval,


741  ya>draw_hash_marks_at + HASH_DIR(ya) * HASH_SIZE);


742  }


743  process_label_extrema(g>title, g);


744 


745  if (g>legend>type == 'c') {


746  for (c = first(g>curves); c != nil(g>curves); c = next(c)) {


747  process_label_extrema(c>l, g);


748  }


749  } else if (g>legend>type == 'u' && g>legend>anylines >= 0) {


750  process_label_extrema(g>legend>l, g);


751  }


752  for(s = first(g>strings); s != nil(g>strings); s = next(s)) {


753  process_label_extrema(s>s, g);


754  }


755  }


756 


757  void process_graph(Graph g)


758  {


759  g>x_translate = intop(g>x_translate);


760  g>y_translate = intop(g>y_translate);


761  process_axis1(g>x_axis, g);


762  process_axis1(g>y_axis, g);


763  process_axis2(g>x_axis, g);


764  process_axis2(g>y_axis, g);


765  process_curves(g);


766  process_legend(g);


767  process_strings(g);


768  process_title(g);


769  process_extrema(g);


770  }


771 


772  void process_graphs(Graphs gs)


773  {


774  Graphs the_g;


775  Graph g;


776  float diff, max_y, min_y, max_x, min_x;


777  int do_bb, i;


778 


779  Pi = acos(1.0);


780  for (the_g = first(gs); the_g != nil(gs); the_g = next(the_g)) {


781  for (g = first(the_g>g); g != nil(the_g>g); g = next(g)) process_graph(g);


782  max_x = 0.0;


783  min_x = 0.0;


784  max_y = 0.0;


785  min_y = 0.0;


786  for (g = first(the_g>g); g != nil(the_g>g); g = next(g)) {


787  max_y = MAX(max_y, g>y_translate + g>ymaxval);


788  min_y = MIN(min_y, g>y_translate + g>yminval);


789  max_x = MAX(max_x, g>x_translate + g>xmaxval);


790  min_x = MIN(min_x, g>x_translate + g>xminval);


791  }


792 


793  if (the_g>height >= 0.00) {


794  the_g>height *= FCPI;


795  if (the_g>height > max_y  min_y) {


796  diff = (the_g>height  max_y + min_y) / 2.0;


797  max_y += diff;


798  min_y = diff;


799  } else {


800  the_g>height = max_y  min_y;


801  }


802  } else {


803  the_g>height = max_y  min_y;


804  }


805  if (the_g>width >= 0.00) {


806  the_g>width *= FCPI;


807  if (the_g>width > max_x  min_x) {


808  diff = (the_g>width  max_x + min_x) / 2.0;


809  max_x += diff;


810  min_x = diff;


811  } else {


812  the_g>width = max_x  min_x;


813  }


814  } else {


815  the_g>width = max_x  min_x;


816  }


817 


818  do_bb = 1;


819  for (i = 0; i < 4; i++) do_bb = (do_bb && the_g>bb[i] == ISIG);


820  if (do_bb) {


821  the_g>bb[0] = (int) (min_x  1.0);


822  the_g>bb[1] = (int) (min_y  1.0);


823  the_g>bb[2] = (int) (max_x + 1.0);


824  the_g>bb[3] = (int) (max_y + 1.0);


825  }


826  }


827  }

