home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / jgraph / patch07.0 < prev    next >
Encoding:
Text File  |  1992-02-02  |  54.2 KB  |  1,909 lines

  1. Newsgroups: comp.sources.misc
  2. From: jsp@Princeton.EDU (James Plank)
  3. Subject:  v28i006:  jgraph - A filter for plotting postscript graphs, Patch07.0
  4. Message-ID: <1992Feb2.032802.24980@sparky.imd.sterling.com>
  5. X-Md4-Signature: f251e9b0a816e62bec19961e454241f4
  6. Date: Sun, 2 Feb 1992 03:28:02 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jsp@Princeton.EDU (James Plank)
  10. Posting-number: Volume 28, Issue 6
  11. Archive-name: jgraph/patch07.0
  12. Environment: UNIX, VMS, postscript
  13. Patch-To: jgraph: Volume 16, Issue 20
  14.  
  15. Jgraph Patch 7.0: Thu Jan 23 11:19:37 EST 1992
  16.  
  17. This patch adds a few things and fixes a few things.  
  18.  
  19. First, it uses a different algorithm for calculating bounding boxes, 
  20. so that now it attempts to get all of the axes (including the labels)
  21. and all of the legend into the bounding box.  The X and Y commands are
  22. a bit different as well -- they should work more consistently now -- 
  23. read the man page for the changes.  This means that graphs might look
  24. different in LaTeX or other systems.  Hopefully they'll work more
  25. consistently and correctly.
  26.  
  27. Second, arrows going into circluar marks now only go to the edge of the
  28. circle and not to the center of the mark.  I'd like to fix this for all
  29. marks, but I don't really have the time.  Maybe later if there's interest.
  30.  
  31. The following commands have been added:
  32.  
  33. bezier/nobezier (in curves) -- lets you plot bezier curves.  See the 
  34.   man page.
  35. copygraph -- Copies the last graph -- this should take the place of
  36.   inherit_axes.  Also, inherit_axes/copygraph have been updated so
  37.   they'll work across multiple pages.
  38. copycurve -- Makes a new curve and copies all the attributes from the
  39.    previous curve.
  40. copystring -- Same thing only for strings.
  41. newline -- An abbreviation for "newcurve marktype none linetype solid"
  42. text as a marktype.  Now you can plot labels like points.  See the
  43.   man page.
  44.  
  45. I believe that's it.  As always, if you find bugs, please send me email.
  46.  
  47. I'm including the README for jgraph below for those not familiar with it,
  48. and the patch from version 6.2:
  49.  
  50.  
  51. $Revision: 7.0 $
  52.  
  53. Jgraph takes the description of a graph or graphs in the standard
  54. input, and produces a postscript file on the standard output.  Jgraph
  55. is ideal for plotting any mixture of scatter point graphs, line
  56. graphs, and/or bar graphs, and embedding the output into LaTeX, or
  57. any other text processing system which can read postscript.
  58.  
  59. The graph description language is simple enough to get nice looking
  60. graphs with a minimum of effort, yet powerful enough to give the user
  61. the flexibility to tailor the appearance of the graph to his or her
  62. individual preferences.  This includes plotting multiple graphs and
  63. laying them out separately on the page (or pages). 
  64.  
  65. The program is written in C, and shouldn't take anything too fancy
  66. or machine-dependent.  It has been tested on DECstations, 
  67. sun3's, and sparc's (and is being used on many other types
  68. of machines).
  69.  
  70. There is a makefile, a man page (in jgraph.1), source code, and 
  71. example graphs.
  72.  
  73. Jgraph is available via anonymous ftp to princeton.edu, in the
  74. file jgraph.Z.  This file is a compressed shell bundle file.
  75.  
  76. There is also a mailing list in which I inform users directly 
  77. about bug fixes.  This is for those who don't read comp.sources.misc,
  78. or those who would like to hear about minor bug fixes which I
  79. haven't posted as a patch to comp.sources.misc.
  80.  
  81. Please send me comments and/or bug reports.
  82.  
  83. Author: Jim Plank
  84. Email:  jsp@princeton.edu
  85. USmail:    Department of Computer Science
  86.     Princeton University
  87.     35 Olden St.
  88.     Princeton, NJ 08544-2087
  89.  
  90.  
  91. Here's the patch from version 6.2
  92.  
  93. *** ../work//README    Thu Jan 23 11:14:16 1992
  94. --- README    Thu Jan 23 11:12:33 1992
  95. ***************
  96. *** 1,4 ****
  97. ! $Revision: 6.2 $
  98.   
  99.   Jgraph takes the description of a graph or graphs in the standard
  100.   input, and produces a postscript file on the standard output.  Jgraph
  101. --- 1,4 ----
  102. ! $Revision: 7.0 $
  103.   
  104.   Jgraph takes the description of a graph or graphs in the standard
  105.   input, and produces a postscript file on the standard output.  Jgraph
  106. *** ../work//draw.c    Thu Jan 23 11:14:20 1992
  107. --- draw.c    Thu Jan 23 11:12:27 1992
  108. ***************
  109. *** 1,7 ****
  110.   /* 
  111.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/draw.c,v $
  112. !  * $Revision: 6.2 $
  113. !  * $Date: 91/11/01 11:46:32 $
  114.    * $Author: jsp $
  115.    */
  116.   
  117. --- 1,7 ----
  118.   /* 
  119.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/draw.c,v $
  120. !  * $Revision: 7.0 $
  121. !  * $Date: 92/01/23 11:09:46 $
  122.    * $Author: jsp $
  123.    */
  124.   
  125. ***************
  126. *** 130,136 ****
  127.   Graph g;
  128.   {
  129.     Point p;
  130. !   int i;
  131.      float this_x, this_y, last_x, last_y;
  132.   
  133.     printf("gsave %f setgray\n", c->gray);
  134. --- 130,136 ----
  135.   Graph g;
  136.   {
  137.     Point p;
  138. !   int i, j;
  139.      float this_x, this_y, last_x, last_y;
  140.   
  141.     printf("gsave %f setgray\n", c->gray);
  142. ***************
  143. *** 137,174 ****
  144.     if (c->clip) set_clip(g);
  145.     comment("Drawing Curve");
  146.     if (c->linetype != '0') {
  147. !     i = 0;
  148. !     for (p = first(c->pts);
  149. !          p != nil(c->pts);
  150. !          p = next(p)) {
  151. !       if (i == 0) {
  152. !         start_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis), c);
  153. !       } else {
  154. !         cont_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis));
  155. !       } 
  156. !       if (i == 100) {
  157. !         end_line();
  158. !         p = prev(p);
  159. !         i = 0;
  160. !       } else i++;
  161.       }
  162. -     if (i != 0) end_line();
  163.     }
  164.     comment("Drawing Curve points");
  165.     for (p = first(c->pts);
  166.          p != nil(c->pts);
  167.          p = next(p)) {
  168.       this_x = ctop(p->x, g->x_axis);
  169.       this_y = ctop(p->y, g->y_axis);
  170. !     draw_mark(this_x, this_y, c, g);
  171.       if (p != first(c->pts)) {
  172. !       if (c->rarrows) 
  173. !         draw_arrow(this_x, this_y, last_x, last_y, c);
  174. !       if (c->larrows) 
  175. !         draw_arrow(last_x, last_y, this_x, this_y, c);
  176.       }
  177.       last_x = this_x;  
  178.       last_y = this_y;  
  179.     }
  180.     printf("     grestore\n");
  181.   }
  182. --- 137,203 ----
  183.     if (c->clip) set_clip(g);
  184.     comment("Drawing Curve");
  185.     if (c->linetype != '0') {
  186. !     if (c->bezier) {
  187. !       i = 0;
  188. !       j = 0;
  189. !       for (p = first(c->pts); p != nil(c->pts); p = next(p)) {
  190. !         if (j == 0 && i == 0) {
  191. !           start_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis), c);
  192. !           j++;
  193. !         } else if (i != 0) {
  194. !           bezier_control(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis));
  195. !         } else {
  196. !           bezier_end(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis));
  197. !           j++;
  198. !         }
  199. !         if (j == 30 && i == 0) {
  200. !           end_line();
  201. !           p = prev(p);
  202. !           j = 0;
  203. !           i = 0;
  204. !         } else i = (i + 1) % 3;
  205. !       }
  206. !       if (j != 0) end_line();
  207. !     } else {
  208. !       i = 0;
  209. !       for (p = first(c->pts);
  210. !            p != nil(c->pts);
  211. !            p = next(p)) {
  212. !         if (i == 0) {
  213. !           start_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis), c);
  214. !         } else {
  215. !           cont_line(ctop(p->x, g->x_axis), ctop(p->y, g->y_axis));
  216. !         } 
  217. !         if (i == 100) {
  218. !           end_line();
  219. !           p = prev(p);
  220. !           i = 0;
  221. !         } else i++;
  222. !       }
  223. !       if (i != 0) end_line();
  224.       }
  225.     }
  226.     comment("Drawing Curve points");
  227. +   i = 0;
  228.     for (p = first(c->pts);
  229.          p != nil(c->pts);
  230.          p = next(p)) {
  231.       this_x = ctop(p->x, g->x_axis);
  232.       this_y = ctop(p->y, g->y_axis);
  233. !     if (!c->bezier || i == 0) draw_mark(this_x, this_y, c, g);
  234.       if (p != first(c->pts)) {
  235. !       if (c->rarrows) {
  236. !         if (!c->bezier || i == 0) 
  237. !           draw_arrow(this_x, this_y, last_x, last_y, c);
  238. !       }
  239. !       if (c->larrows) {
  240. !         if (!c->bezier || i == 1) 
  241. !           draw_arrow(last_x, last_y, this_x, this_y, c);
  242. !       }
  243.       }
  244.       last_x = this_x;  
  245.       last_y = this_y;  
  246. +     i = (i + 1) % 3;
  247.     }
  248.     printf("     grestore\n");
  249.   }
  250. ***************
  251. *** 233,238 ****
  252. --- 262,273 ----
  253.                 cont_poly(g->y_axis->draw_at, y+ms1);
  254.                 end_poly(c->fill);
  255.                 break;
  256. +     case 'l': c->lmark->x += x;
  257. +               c->lmark->y += y;
  258. +               draw_label(c->lmark);
  259. +               c->lmark->x -= x;
  260. +               c->lmark->y -= y;
  261. +               break;
  262.       default: error_header(); 
  263.                fprintf(stderr, "Unknown mark: %c\n", c->marktype);
  264.                break;
  265. ***************
  266. *** 244,253 ****
  267. --- 279,309 ----
  268.   Curve c;
  269.   {
  270.     float dx, dy;
  271. +   float ms1, ms0;
  272. +   float theta, ct, st;
  273.     
  274. +   
  275. +   if (c->marktype == 'o') {
  276. +     dx = x1 - x2;
  277. +     dy = y1 - y2;
  278. +     if (dx == 0.0 && dy == 0.0) return;
  279. +     ms0 = c->marksize[0] / 2.0;
  280. +     if (dx == 0.0) theta = asin(1.0); else theta = atan(dy/dx);
  281. +     if (theta < 0.0) theta = -theta;
  282. +     ct = cos(theta)*ms0;
  283. +     st = sin(theta)*ms0;
  284. +     x1 = x1 + ct*(dx > 0.0 ? -1.0 : 1.0);
  285. +     y1 = y1 + st*(dy > 0.0 ? -1.0 : 1.0);
  286. +     if ( ((x1 - x2 > 0) != (dx > 0)) || 
  287. +          ((y1 - y2 > 0) != (dy > 0)) ) return;
  288. +   }
  289.     dx = x1 - x2;
  290.     dy = y1 - y2;
  291.     if (dx == 0.0 && dy == 0.0) return;
  292.     printf("gsave %f %f translate %f %f atan rotate\n", x1, y1, dy, dx);
  293.     start_poly(0.0, 0.0);
  294.     cont_poly(-(c->asize[0]), (c->asize[1]));
  295. ***************
  296. *** 262,267 ****
  297. --- 318,324 ----
  298.     Curve c;
  299.     Legend l;
  300.     float x, y;
  301. +   char tmpmktype;
  302.   
  303.     l = g->legend;
  304.     comment("Drawing legend");
  305. ***************
  306. *** 277,284 ****
  307. --- 334,344 ----
  308.             cont_line(x+l->linelength, y);
  309.             end_line();
  310.           }
  311. +         tmpmktype = c->marktype;
  312. +         c->marktype = 'n';
  313.           if (c->larrows) draw_arrow(x, y, x+l->linelength, y, c);
  314.           if (c->rarrows) draw_arrow(x+l->linelength, y, x, y, c);
  315. +         c->marktype = tmpmktype;
  316.           x = c->l->x - l->midspace - l->linelength / 2.0;
  317.         } else x = c->l->x - l->midspace;
  318.         if (c->marktype == 'X' || c->marktype == 'Y') {
  319. ***************
  320. *** 351,357 ****
  321.   {
  322.     printf("%%!PS-Adobe-2.0 EPSF-1.2\n");
  323.     printf("%%%%Pages: 0\n");
  324. !   printf("%%%%BoundingBox: %f %f %f %f\n", gs->bb[0], gs->bb[1], gs->bb[2], gs->bb[3]);
  325.     printf("%%%%EndComments\n");
  326.     printf("/$F2psDict 32 dict def $F2psDict begin\t$F2psDict /mtrx matrix put\n");
  327.     printf("/DrawEllipse {\t/endangle exch def\t/startangle exch def");
  328. --- 411,418 ----
  329.   {
  330.     printf("%%!PS-Adobe-2.0 EPSF-1.2\n");
  331.     printf("%%%%Pages: 0\n");
  332. !   printf("%%%%BoundingBox: %f %f %f %f\n", gs->bb[0], gs->bb[1], 
  333. !           gs->bb[2], gs->bb[3]);
  334.     printf("%%%%EndComments\n");
  335.     printf("/$F2psDict 32 dict def $F2psDict begin\t$F2psDict /mtrx matrix put\n");
  336.     printf("/DrawEllipse {\t/endangle exch def\t/startangle exch def");
  337. ***************
  338. *** 367,373 ****
  339.     if (pp)
  340.       printf("%f %f translate\n",
  341.         ((8.5 * FCPI) - (gs->bb[2] - gs->bb[0])) / 2.0,     
  342. !       (gs->bb[3] > (3*FCPI)) ? ((11*FCPI) - gs->bb[3]) / 2 : (3.5*FCPI));
  343.     printf("1 setlinecap 1 setlinejoin\n");
  344.     printf("0.700 setlinewidth\n");
  345.   }
  346. --- 428,434 ----
  347.     if (pp)
  348.       printf("%f %f translate\n",
  349.         ((8.5 * FCPI) - (gs->bb[2] - gs->bb[0])) / 2.0,     
  350. !       (gs->bb[3] > (3*FCPI)) ? ((11*FCPI) - gs->bb[3]) / 2 : (5.5*FCPI));
  351.     printf("1 setlinecap 1 setlinejoin\n");
  352.     printf("0.700 setlinewidth\n");
  353.   }
  354. *** ../work//edit.c    Thu Jan 23 11:14:21 1992
  355. --- edit.c    Thu Jan 23 11:12:27 1992
  356. ***************
  357. *** 1,7 ****
  358.   /* 
  359.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/edit.c,v $
  360. !  * $Revision: 6.2 $
  361. !  * $Date: 91/11/01 11:46:33 $
  362.    * $Author: jsp $
  363.    */
  364.   
  365. --- 1,7 ----
  366.   /* 
  367.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/edit.c,v $
  368. !  * $Revision: 7.0 $
  369. !  * $Date: 92/01/23 11:09:47 $
  370.    * $Author: jsp $
  371.    */
  372.   
  373. ***************
  374. *** 55,61 ****
  375.     }
  376.   }
  377.   
  378. ! copy_label(l1, l2) /* Copies label l1 to l2 */
  379.   Label l1, l2;
  380.   {
  381.     l1->label = l2->label;
  382. --- 55,100 ----
  383.     }
  384.   }
  385.   
  386. ! copy_curve(c1, c2) /* Copies curve c2 to c1 */
  387. ! Curve c1, c2;
  388. ! {
  389. !   Flist f, newf;
  390. !   Point p, newp;
  391. !   copy_label(c1->l, c2->l);
  392. !   copy_label(c1->lmark, c2->lmark);
  393. !   c1->l->label = CNULL;
  394. !   c1->clip = c2->clip;
  395. !   c1->gray = c2->gray;
  396. !   for (f = first(c2->gen_linetype); 
  397. !        f != nil(c2->gen_linetype); 
  398. !        f = next(f)) {
  399. !     newf = (Flist) get_node(c1->gen_linetype);
  400. !     newf->f = f->f;
  401. !     insert(newf, c1->gen_linetype);
  402. !   }
  403. !   c1->marktype = c2->marktype;
  404. !   c1->linetype = c2->linetype;
  405. !   c1->linethick = c2->linethick;
  406. !   c1->marksize[0] = c2->marksize[0];
  407. !   c1->marksize[1] = c2->marksize[1];
  408. !   for (p = first(c2->general_marks); 
  409. !        p != nil(c2->general_marks); 
  410. !        p = next(p)) {
  411. !     newp = (Point) get_node(c1->general_marks);
  412. !     newp->x = p->x;
  413. !     newp->y = p->y;
  414. !     insert(newp, c1->general_marks);
  415. !   }
  416. !   c1->fill = c2->fill;
  417. !   c1->rarrows = c2->rarrows;
  418. !   c1->larrows = c2->larrows;
  419. !   c1->asize[0] = c2->asize[0];
  420. !   c1->asize[1] = c2->asize[1];
  421. !   c1->bezier = c2->bezier;
  422. ! }
  423. ! copy_label(l1, l2) /* Copies label l2 to l1 */
  424.   Label l1, l2;
  425.   {
  426.     l1->label = l2->label;
  427. ***************
  428. *** 100,122 ****
  429.     a1->is_x = a2->is_x;
  430.   }
  431.   
  432. ! inherit_axes(g, gs)
  433.   Graph g;
  434.   Graphs gs;
  435.   {
  436. !   if (prev(g) == nil(gs->g)) {
  437. !     error_header(); 
  438. !     fprintf(stderr, "First graph cannot inherit axes\n");
  439. !     exit(1);
  440.     }
  441. !   copy_axis(g->x_axis, prev(g)->x_axis);
  442. !   copy_axis(g->y_axis, prev(g)->y_axis);
  443. !   g->x_translate = prev(g)->x_translate;
  444. !   g->y_translate = prev(g)->y_translate;
  445. !   g->clip = prev(g)->clip;
  446. !   g->border = prev(g)->border;
  447.   }
  448.   
  449.   edit_curve(c, g)
  450.   Curve c;
  451.   Graph g;
  452. --- 139,239 ----
  453.     a1->is_x = a2->is_x;
  454.   }
  455.   
  456. ! Curve do_copy_curve(g, gs, all_gs)
  457.   Graph g;
  458.   Graphs gs;
  459. + Graphs all_gs;
  460.   {
  461. !   Curve lastc, newc;
  462. !   Graph oldg;
  463. !   Graphs oldgs;
  464. !   oldg = g;
  465. !   oldgs = gs;
  466. !   while(gs != nil(all_gs)) {
  467. !     if (gs != oldgs) g = last(gs->g);
  468. !     while(g != nil(gs->g)) {
  469. !       if (first(g->curves) == nil(g->curves)) g = prev(g);
  470. !       else {
  471. !         lastc = last(g->curves);
  472. !         if (first(oldg->curves) == nil(oldg->curves))
  473. !           newc = new_curve(oldg->curves, 0);
  474. !         else newc = new_curve(oldg->curves, last(oldg->curves)->num + 1);
  475. !         copy_curve(newc, lastc);
  476. !         return newc;
  477. !       }
  478. !     }
  479. !     gs = prev(gs);
  480.     }
  481. !   
  482. !   error_header(); 
  483. !   fprintf(stderr, "Cannot perform copycurve on first curve\n");
  484. !   exit(1);
  485. !   return newc; /* To shut lint up */
  486.   }
  487.   
  488. + Label do_copy_string(g, gs, all_gs)
  489. + Graph g;
  490. + Graphs gs;
  491. + Graphs all_gs;
  492. + {
  493. +   String lastl, newl;
  494. +   Graph oldg;
  495. +   Graphs oldgs;
  496. +   oldg = g;
  497. +   oldgs = gs;
  498. +   while(gs != nil(all_gs)) {
  499. +     if (gs != oldgs) g = last(gs->g);
  500. +     while(g != nil(gs->g)) {
  501. +       if (first(g->strings) == nil(g->strings)) g = prev(g);
  502. +       else {
  503. +         lastl = last(g->strings);
  504. +         if (first(oldg->strings) == nil(oldg->strings))
  505. +           newl = new_string(oldg->strings, 0);
  506. +         else newl = new_string(oldg->strings, last(oldg->strings)->num + 1);
  507. +         copy_label(newl->s, lastl->s);
  508. +         return newl->s;
  509. +       }
  510. +     }
  511. +     gs = prev(gs);
  512. +   }
  513. +   
  514. +   error_header(); 
  515. +   fprintf(stderr, "Cannot perform copystring on first curve\n");
  516. +   exit(1);
  517. +   return newl->s; /* To shut lint up */
  518. + }
  519. + inherit_axes(g, gs, all_gs)
  520. + Graph g;
  521. + Graphs gs;
  522. + Graphs all_gs;
  523. + {
  524. +   Graph lastg;
  525. +   lastg = prev(g);
  526. +   while(lastg == nil(gs->g)) {
  527. +     if (prev(gs) == nil(all_gs)) {
  528. +       error_header(); 
  529. +       fprintf(stderr, "First graph cannot inherit axes\n");
  530. +       exit(1);
  531. +     } else {
  532. +       gs = prev(gs);
  533. +       lastg = last(gs->g);
  534. +     }
  535. +   }
  536. +   copy_axis(g->x_axis, lastg->x_axis);
  537. +   copy_axis(g->y_axis, lastg->y_axis);
  538. +   g->x_translate = lastg->x_translate;
  539. +   g->y_translate = lastg->y_translate;
  540. +   g->clip = lastg->clip;
  541. +   g->border = lastg->border;
  542. + }
  543.   edit_curve(c, g)
  544.   Curve c;
  545.   Graph g;
  546. ***************
  547. *** 151,156 ****
  548. --- 268,274 ----
  549.           }
  550.           /*insert(p, c->pts, 0); insert only takes 2 arguments -hdd */
  551.       insert(p, c->pts);
  552. +         c->npts++;
  553.         }
  554.         rejecttoken();
  555.       } else if (strcmp(inp_str, "label") == 0) {
  556. ***************
  557. *** 183,192 ****
  558.         if (i == NMARKTYPES) {
  559.           error_header(); fprintf(stderr, "Bad mark: %s\n", inp_str);
  560.           fprintf(stderr, "             Valid marks are:");
  561. !         for (i = 0; i < NMARKTYPES; i++) fprintf(stderr, " %s", MARKTYPESTRS[i]);
  562.           fprintf(stderr, "\n");
  563.           exit(1);
  564. !       } else c->marktype = MARKTYPES[i];
  565.       } else if (strcmp(inp_str, "glines") == 0) {
  566.         while (getfloat(&f)) {
  567.           fl = (Flist) get_node (c->gen_linetype);
  568. --- 301,315 ----
  569.         if (i == NMARKTYPES) {
  570.           error_header(); fprintf(stderr, "Bad mark: %s\n", inp_str);
  571.           fprintf(stderr, "             Valid marks are:");
  572. !         for (i = 0; i < NMARKTYPES; i++) {
  573. !           fprintf(stderr, " %s", MARKTYPESTRS[i]);
  574. !         }
  575.           fprintf(stderr, "\n");
  576.           exit(1);
  577. !       } else {
  578. !         c->marktype = MARKTYPES[i];
  579. !         if (c->marktype == 'l') edit_label(c->lmark);
  580. !       }
  581.       } else if (strcmp(inp_str, "glines") == 0) {
  582.         while (getfloat(&f)) {
  583.           fl = (Flist) get_node (c->gen_linetype);
  584. ***************
  585. *** 225,230 ****
  586. --- 348,357 ----
  587.         c->rarrows = 1;
  588.       } else if (strcmp(inp_str, "norarrows") == 0) {
  589.         c->rarrows = 0;
  590. +     } else if (strcmp(inp_str, "bezier") == 0) {
  591. +       c->bezier = 1;
  592. +     } else if (strcmp(inp_str, "nobezier") == 0) {
  593. +       c->bezier = 0;
  594.       } else if (strcmp(inp_str, "asize") == 0) {
  595.         if (!getfloat(&f)) rejecttoken(); 
  596.         else {
  597. ***************
  598. *** 364,369 ****
  599. --- 491,500 ----
  600.         a->draw_hash_labels = 0;
  601.       } else if (strcmp(inp_str, "draw_hash_labels") == 0) {
  602.         a->draw_hash_labels = 1;
  603. +     } else if (strcmp(inp_str, "no_draw_axis_line") == 0) {
  604. +       a->draw_axis_line = 0;
  605. +     } else if (strcmp(inp_str, "draw_axis_line") == 0) {
  606. +       a->draw_axis_line = 1;
  607.       } else if (strcmp(inp_str, "no_draw_axis") == 0) {
  608.         a->draw_axis_line = 0;
  609.       } else if (strcmp(inp_str, "draw_axis") == 0) {
  610. ***************
  611. *** 423,431 ****
  612.     }
  613.   }
  614.   
  615. ! edit_graph(g, gs)
  616.   Graph g;
  617.   Graphs gs;
  618.   {
  619.     char inp_str[80];
  620.     int num;
  621. --- 554,563 ----
  622.     }
  623.   }
  624.   
  625. ! edit_graph(g, gs, all_gs)
  626.   Graph g;
  627.   Graphs gs;
  628. + Graphs all_gs;
  629.   {
  630.     char inp_str[80];
  631.     int num;
  632. ***************
  633. *** 447,452 ****
  634. --- 579,590 ----
  635.         if (first(g->curves) == nil(g->curves))
  636.           edit_curve(new_curve(g->curves, 0), g);
  637.         else edit_curve(new_curve(g->curves, last(g->curves)->num + 1), g);
  638. +     } else if (strcmp(inp_str, "copycurve") == 0) {
  639. +       edit_curve(do_copy_curve(g, gs, all_gs), g);
  640. +     } else if (strcmp(inp_str, "newline") == 0) {
  641. +       if (first(g->curves) == nil(g->curves))
  642. +         edit_curve(new_line(g->curves, 0), g);
  643. +       else edit_curve(new_line(g->curves, last(g->curves)->num + 1), g);
  644.       } else if (strcmp(inp_str, "title") == 0) {
  645.         edit_label(g->title);
  646.       } else if (strcmp(inp_str, "legend") == 0) {
  647. ***************
  648. *** 467,474 ****
  649.           s = new_string(g->strings, 0);
  650.         else s = new_string(g->strings, last(g->strings)->num + 1);
  651.         edit_label(s->s);
  652.       } else if (strcmp(inp_str, "inherit_axes") == 0) {
  653. !       inherit_axes(g, gs);
  654.       } else if (strcmp(inp_str, "Y") == 0) {
  655.         if (!getfloat(&f)) rejecttoken(); else gs->height = f;
  656.       } else if (strcmp(inp_str, "X") == 0) {
  657. --- 605,614 ----
  658.           s = new_string(g->strings, 0);
  659.         else s = new_string(g->strings, last(g->strings)->num + 1);
  660.         edit_label(s->s);
  661. +     } else if (strcmp(inp_str, "copystring") == 0) {
  662. +       edit_label(do_copy_string(g, gs, all_gs));
  663.       } else if (strcmp(inp_str, "inherit_axes") == 0) {
  664. !       inherit_axes(g, gs, all_gs);
  665.       } else if (strcmp(inp_str, "Y") == 0) {
  666.         if (!getfloat(&f)) rejecttoken(); else gs->height = f;
  667.       } else if (strcmp(inp_str, "X") == 0) {
  668. ***************
  669. *** 492,497 ****
  670. --- 632,638 ----
  671.   Graphs gs;
  672.   {
  673.     Graphs the_g;
  674. +   Graph g;
  675.     char inp_str[80];
  676.     float f;
  677.     int num, i;
  678. ***************
  679. *** 503,513 ****
  680.           error_header(); fprintf(stderr, "\"graph\" not followed by number\n");
  681.           exit(1);
  682.         }
  683. !       edit_graph(get_graph(the_g->g, num), the_g);
  684.       } else if (strcmp(inp_str, "newgraph") == 0) {
  685.         if (first(the_g->g) == nil(the_g->g))
  686. !         edit_graph(new_graph(the_g->g, 0), the_g);
  687. !       else edit_graph(new_graph(the_g->g, last(the_g->g)->num + 1), the_g);
  688.       } else if (strcmp(inp_str, "Y") == 0) {
  689.         if (!getfloat(&f)) rejecttoken(); else the_g->height = f;
  690.       } else if (strcmp(inp_str, "X") == 0) {
  691. --- 644,660 ----
  692.           error_header(); fprintf(stderr, "\"graph\" not followed by number\n");
  693.           exit(1);
  694.         }
  695. !       edit_graph(get_graph(the_g->g, num), the_g, gs);
  696.       } else if (strcmp(inp_str, "newgraph") == 0) {
  697.         if (first(the_g->g) == nil(the_g->g))
  698. !         edit_graph(new_graph(the_g->g, 0), the_g, gs);
  699. !       else edit_graph(new_graph(the_g->g, last(the_g->g)->num + 1), the_g, gs);
  700. !     } else if (strcmp(inp_str, "copygraph") == 0) {
  701. !       if (first(the_g->g) == nil(the_g->g))
  702. !         g = new_graph(the_g->g, 0);
  703. !       else g = new_graph(the_g->g, last(the_g->g)->num + 1);
  704. !       inherit_axes(g, the_g, gs);
  705. !       edit_graph(g, the_g, gs);
  706.       } else if (strcmp(inp_str, "Y") == 0) {
  707.         if (!getfloat(&f)) rejecttoken(); else the_g->height = f;
  708.       } else if (strcmp(inp_str, "X") == 0) {
  709. *** ../work//jgraph.1    Thu Jan 23 11:14:26 1992
  710. --- jgraph.1    Thu Jan 23 11:12:32 1992
  711. ***************
  712. *** 200,220 ****
  713.   where n=0 if this is the first graph, otherwise n=m+1, where m is the
  714.   largest number of any graph so far.
  715.   .TP
  716. ! \fBX \|[\fIfloat\fB\|]\fR
  717. ! .br
  718. ! .ns
  719.   .TP
  720. - \fBY \|[\fIfloat\fB\|]\fR
  721. - Postscript files to be embedded in LaTeX
  722. - must contain a line specifying their height and width.  Usually,
  723. - \fBjgraph \fR
  724. - will automatically create one for the user, however, the user
  725. - may specify the height and width in inches using 
  726. - \fBY\fR
  727. - and
  728. - \fBX\fR
  729. - respectively.
  730. - .TP
  731.   .B newpage
  732.   This command is for plotting graphs on multiple pages.  After a 
  733.   \fBnewpage,\fR
  734. --- 200,221 ----
  735.   where n=0 if this is the first graph, otherwise n=m+1, where m is the
  736.   largest number of any graph so far.
  737.   .TP
  738. ! .B copygraph
  739. ! This creates a new graph, and copies all the attributes from the
  740. ! previous graph's x and y axes, as well as the x_translate and 
  741. ! y_translate values, and the clipping. 
  742. ! (Actually, this is a little bit of a lie, as it does not copy the
  743. ! values of the 
  744. ! \fB\fIhash_at\fB, \fImhash_at\fB,\fR
  745. ! and 
  746. ! \fB\fI\fIhash_label\fB\fR 
  747. ! attributes). 
  748. ! The previous graph is defined to be the graph with the largest number 
  749. ! less than the currrent graph's number.  If the current 
  750. ! graph has the smallest number, then it will take the last graph from 
  751. ! the previous page of graphs.  If there is no previous page, then an 
  752. ! error will be flagged.
  753.   .TP
  754.   .B newpage
  755.   This command is for plotting graphs on multiple pages.  After a 
  756.   \fBnewpage,\fR
  757. ***************
  758. *** 232,249 ****
  759.   \fB\-P\fR
  760.   option is not specified.
  761.   .TP
  762.   \fBbbox \fIfloat\fB \fIfloat\fB \fIfloat\fB \fIfloat\fB\fR
  763. ! Jgraph calculates a bounding box for the graph and
  764. ! includes it in the header of the postscript output.
  765. ! For the purposed of LaTeX, this is usually ok, as LaTeX doesn't
  766. ! clip outside of the bounding box.  Unfortunately, other programs
  767. ! do clip, and sometimes jgraph doesn't calculate the bounding box
  768. ! too well (text especially screws things up).  This command lets
  769. ! the user add his/her own bounding box.  The units of this are
  770.   final postscript units.  It's probably best to use the -p option
  771.   to see what the bounding box is that jgraph produces, and then
  772.   alter that accordingly with
  773. ! \fBbbox\fR.
  774.   .PD
  775.   .RE
  776.   .LP
  777. --- 233,281 ----
  778.   \fB\-P\fR
  779.   option is not specified.
  780.   .TP
  781. + \fBX \|[\fIfloat\fB\|]\fR
  782. + .br
  783. + .ns
  784. + .TP
  785. + \fBY \|[\fIfloat\fB\|]\fR
  786. + Postscript files to be embedded in LaTeX contain a ``bounding box''
  787. + which defines the area which LaTeX will allocate for the postscript.
  788. + Other programs use this bounding box as well, sometimes using it
  789. + to define where to clip the postscript image.
  790. + \fBJgraph \fR
  791. + uses the axis lines and labels, and the title to generate its 
  792. + bounding box.  Most of the time that's good enough to work in 
  793. + LaTeX.  The 
  794. + \fBY\fR
  795. + and
  796. + \fBX\fR
  797. + commands say to make the height and width of the bounding box at least
  798. + \fBY\fR
  799. + and
  800. + \fBX\fR
  801. + inches, respectively.  If you still need further control over the
  802. + bounding box, try the
  803. + \fBbbox\fR
  804. + command.  If there's more than one page in the jgraph file, 
  805. + \fBY,\fR
  806. + \fBX\fR
  807. + and
  808. + \fBbbox\fR
  809. + values can be given for each graph.  I'm not sure if that really
  810. + means anything though.
  811. + .TP
  812.   \fBbbox \fIfloat\fB \fIfloat\fB \fIfloat\fB \fIfloat\fB\fR
  813. ! If the 
  814. ! \fBY\fR
  815. ! and
  816. ! \fBX\fR
  817. ! commands aren't enough to help you define a good bounding box, this
  818. ! command lets you explicitly enter one which will go directly into the 
  819. ! jgraph output.  Its units are the 
  820.   final postscript units.  It's probably best to use the -p option
  821.   to see what the bounding box is that jgraph produces, and then
  822.   alter that accordingly with
  823. ! \fBbbox.\fR
  824.   .PD
  825.   .RE
  826.   .LP
  827. ***************
  828. *** 279,284 ****
  829. --- 311,329 ----
  830.   \fBgraph\fR
  831.   do.
  832.   .TP
  833. + \fBnewline\fR  
  834. + This is an abbreviation for:
  835. + .PP
  836. + .nf
  837. +       newcurve marktype none linetype solid
  838. + .fi
  839. + .PP
  840. + .TP
  841. + \fBcopycurve\fR  
  842. + This starts editing a new curve of the graph, and copies all its 
  843. + values from last curve in this graph.  If this graph currently has
  844. + no curves, then it searches backwards from the previous graph.
  845. + .TP
  846.   \fBtitle\fR   
  847.   This edits the title of the graph (see LABEL EDITING
  848.   COMMANDS).  The title is given a default location centered beneath
  849. ***************
  850. *** 296,306 ****
  851.   graph as well as curves.
  852.   .TP
  853.   \fBstring \|{\fIinteger\fB\|}\fR   
  854. ! This is to 
  855.   \fBnewstring\fR
  856.   as
  857.   \fBcurve\fR
  858. ! is to
  859.   \fBnewcurve.\fR
  860.   .TP
  861.   \fBborder\fR
  862. --- 341,360 ----
  863.   graph as well as curves.
  864.   .TP
  865.   \fBstring \|{\fIinteger\fB\|}\fR   
  866. ! .br
  867. ! .ns
  868. ! .TP
  869. ! \fBcopystring\fR
  870. ! \fBString\fR
  871. ! and
  872. ! \fBcopystring\fR
  873. ! are to 
  874.   \fBnewstring\fR
  875.   as
  876.   \fBcurve\fR
  877. ! and
  878. ! \fBcopycurve\fR
  879. ! are to
  880.   \fBnewcurve.\fR
  881.   .TP
  882.   \fBborder\fR
  883. ***************
  884. *** 324,345 ****
  885.   specifies that all curves in the graph will be clipped -- that is,
  886.   no points outside of the of axes will be plotted.  Clipping can also be
  887.   specified on a per-curve basis.  The default is
  888. ! \fBnoclip\fR.
  889.   .TP
  890.   \fBinherit_axes\fR   
  891. ! This lets the user ``inherit'' the values of the last
  892. ! graph's axes.  It copies all the attributes of the previous graph's x
  893. ! and y axes, as well as the x_translate and y_translate values, and the
  894. ! clipping. 
  895. ! (Actually, this is a little bit of a lie, as it does not copy the
  896. ! values of the 
  897. ! \fB\fIhash_at\fB, \fImhash_at\fB,\fR
  898. ! and 
  899. ! \fB\fI\fIhash_label\fB\fR 
  900. ! attributes). 
  901. ! The previous graph is the graph with the largest number greater than
  902. ! the currrent graph's number.  If the current graph has the smallest
  903. ! number, then this command will flag an error.
  904.   .TP
  905.   \fBx_translate \|[\fIfloat\fB\|]\fR   
  906.   By default, graphs are drawn centered at the
  907. --- 378,394 ----
  908.   specifies that all curves in the graph will be clipped -- that is,
  909.   no points outside of the of axes will be plotted.  Clipping can also be
  910.   specified on a per-curve basis.  The default is
  911. ! \fBnoclip.\fR
  912.   .TP
  913.   \fBinherit_axes\fR   
  914. ! This is an old command which is kept for backward compatibility.
  915. ! \fBCopycurve.\fR
  916. ! is equivalent to:
  917. ! .PP
  918. ! .nf
  919. !       newgraph inherit_axes
  920. ! .fi
  921. ! .PP
  922.   .TP
  923.   \fBx_translate \|[\fIfloat\fB\|]\fR   
  924.   By default, graphs are drawn centered at the
  925. ***************
  926. *** 493,499 ****
  927.   Do not draw the axis, the hash marks or any labels.  This
  928.   is useful for plotting points with no axes, and for overlaying graphs
  929.   on top of one another with no clashes.  This is equivalent to
  930. ! \fBno_draw_axis_line,\fR
  931.   \fBno_draw_axis_label,\fR
  932.   \fBno_draw_hash_marks,\fR
  933.   and
  934. --- 542,548 ----
  935.   Do not draw the axis, the hash marks or any labels.  This
  936.   is useful for plotting points with no axes, and for overlaying graphs
  937.   on top of one another with no clashes.  This is equivalent to
  938. ! \fBno_draw_axis,\fR
  939.   \fBno_draw_axis_label,\fR
  940.   \fBno_draw_hash_marks,\fR
  941.   and
  942. ***************
  943. *** 505,511 ****
  944.   Default = 
  945.   \fBdraw. This is\fR
  946.   equivalent to 
  947. ! \fBdraw_axis_line,\fR
  948.   \fBdraw_axis_label,\fR
  949.   \fBdraw_hash_marks,\fR
  950.   and 
  951. --- 554,560 ----
  952.   Default = 
  953.   \fBdraw. This is\fR
  954.   equivalent to 
  955. ! \fBdraw_axis,\fR
  956.   \fBdraw_axis_label,\fR
  957.   \fBdraw_hash_marks,\fR
  958.   and 
  959. ***************
  960. *** 519,525 ****
  961.   \fBGrid_lines\fR
  962.   specifies to plot a grid line at each (major and minor) hash
  963.   mark on this axis.  The default is 
  964. ! \fBno_grid_lines\fR.
  965.   .PD
  966.   .RE
  967.   .LP
  968. --- 568,574 ----
  969.   \fBGrid_lines\fR
  970.   specifies to plot a grid line at each (major and minor) hash
  971.   mark on this axis.  The default is 
  972. ! \fBno_grid_lines.\fR
  973.   .PD
  974.   .RE
  975.   .LP
  976. ***************
  977. *** 540,553 ****
  978.   point.  This command stops reading points when a non-float is given.
  979.   .TP
  980.   \fBmarktype\fR   
  981. ! This sets the kind of mark that is plotted for this
  982. ! curve.  Valid marks are: ``circle'', ``box'', ``diamond'', ``triangle'', ``x'',
  983. ! ``cross'', ``ellipse'', ``xbar'', ``ybar'', ``general'', and ``none''.  Most of these are
  984. ! self-explanatory, except for the last three.  ``Xbar'' makes the curve
  985. ! into a bar graph with the bars going to the x axis.  ``Ybar'' has the bars
  986. ! going to the y axis.  ``General'' lets the user define the marks using the
  987.   \fBgmarks\fR
  988. ! command defined below.  ``None'' means that no mark will be
  989.   plotted (this is useful for drawing lines).  By default, a new mark
  990.   is chosen for each curve.
  991.   .TP
  992. --- 589,614 ----
  993.   point.  This command stops reading points when a non-float is given.
  994.   .TP
  995.   \fBmarktype\fR   
  996. ! This sets the kind of mark that is plotted for this curve.  Valid
  997. ! marks are: ``circle'', ``box'', ``diamond'', ``triangle'', ``x'',
  998. ! ``cross'', ``ellipse'', ``xbar'', ``ybar'', ``general'', ``text'' and
  999. ! ``none''.  Most of these are self-explanatory, except for the last
  1000. ! five:  
  1001. !   ``Xbar'' makes the curve into a bar graph with the bars going
  1002. ! to the x axis.  ``Ybar'' has the bars going to the y axis. 
  1003. !   ``General'' lets the user define the marks using the 
  1004.   \fBgmarks\fR
  1005. ! command defined below.  
  1006. !   ``Text'' lets the user plot text instead of a mark.  The text is 
  1007. ! editted as a label (see LABEL EDITING COMMANDS) immediately following
  1008. ! the ``text'' command.  The x and y fields of the label have special
  1009. ! meanings here:  They define where the label is to be printed in relation
  1010. ! to the curve points.  For example, if they are both 0, the label will
  1011. ! be printed directly on the curve points.  If x is 1.0 and y is -1.0, then
  1012. ! the label will be printed one unit to the right and one unit below the
  1013. ! curve points.  Default label values are 0 for x and y, and center 
  1014. ! justification.
  1015. !   ``None'' means that no mark will be
  1016.   plotted (this is useful for drawing lines).  By default, a new mark
  1017.   is chosen for each curve.
  1018.   .TP
  1019. ***************
  1020. *** 606,612 ****
  1021.   \fBLarrows\fR 
  1022.   specifies to draw an arrow at the beginning of every line segment.
  1023.   The size of the arrows can be changed by using
  1024. ! \fBasize\fR.
  1025.   The 
  1026.   \fBfill\fR
  1027.   token controls the filling of the head of the arrows.
  1028. --- 667,673 ----
  1029.   \fBLarrows\fR 
  1030.   specifies to draw an arrow at the beginning of every line segment.
  1031.   The size of the arrows can be changed by using
  1032. ! \fBasize.\fR
  1033.   The 
  1034.   \fBfill\fR
  1035.   token controls the filling of the head of the arrows.
  1036. ***************
  1037. *** 614,619 ****
  1038. --- 675,683 ----
  1039.   \fBnolarrows\fR
  1040.   and
  1041.   \fBnorarrows\fR.
  1042. +   Arrows always go exactly to the point specified, with the exception 
  1043. + of when the marktype is ``circle''.  In this case, the arrow goes to
  1044. + the edge of the circle.
  1045.   .TP
  1046.   \fBasize \|[\fIfloat\fB\|] \|[\fIfloat\fB\|]\fR   
  1047.   This sets the size of the arrows.  The first 
  1048. ***************
  1049. *** 647,652 ****
  1050. --- 711,736 ----
  1051.   This defines the line thickness (in
  1052.   absolute postscript units) of the connecting line.  Default = 1.0.
  1053.   .TP
  1054. + \fBbezier\fR
  1055. + .br
  1056. + .ns
  1057. + .TP
  1058. + \fBnobezier\fR
  1059. + .br
  1060. + .ns
  1061. + \fBBezier\fR
  1062. + specifies to use the curve's points to define successive bezier curves.
  1063. + The first point is the starting point.  The next two are control points
  1064. + for the bezier curve and the next point is the ending point.  If there
  1065. + is another bezier, this ending point is also the beginning point of the 
  1066. + next curve.  The next two points are again control points, and the next
  1067. + point is the ending point.  Thus, a bezier must have a total of (3n + 1)
  1068. + points, where n is at least 1.
  1069. +   In bezier curves, marks and arrows only apply to every third point.
  1070. + \fNobezier\fR
  1071. + is the default.
  1072. + .TP
  1073.   \fBclip\fR
  1074.   This specifies that this curve will be clipped -- that is,
  1075.   no points outside of the of axes will be plotted.  
  1076. ***************
  1077. *** 1030,1046 ****
  1078.   should be able to draw any kind of scatter/line/bar graph that
  1079.   a user desires.  To embellish the graph with extra text, axes, lines,
  1080.   etc., it is helpful to use 
  1081. ! \fBnewgraph\fR
  1082. ! and 
  1083. ! \fBinherit_axes.\fR
  1084.   The following example graphs show how this can be done.  All graphs are
  1085. ! in the directory HOMEDIRECTORY/graphs.
  1086.   .sp
  1087.   - sin.jgr shows how a sin function can be plotted using a simple c
  1088.   program to produce the sin wave.  Moreover, this file shows a use of
  1089. ! \fBnewgraph\fR
  1090. ! and
  1091. ! \fBinherit_axes\fR
  1092.   to plot an extra x and y axis at the 0 point.
  1093.   .sp
  1094.   - sin1.jgr is a further extension of sin.jgr only with one x and y
  1095. --- 1114,1126 ----
  1096.   should be able to draw any kind of scatter/line/bar graph that
  1097.   a user desires.  To embellish the graph with extra text, axes, lines,
  1098.   etc., it is helpful to use 
  1099. ! \fBcopygraph.\fR
  1100.   The following example graphs show how this can be done.  All graphs are
  1101. ! in the directory ~plank/src/jgraph/graphs.
  1102.   .sp
  1103.   - sin.jgr shows how a sin function can be plotted using a simple c
  1104.   program to produce the sin wave.  Moreover, this file shows a use of
  1105. ! \fBcopygraph\fR
  1106.   to plot an extra x and y axis at the 0 point.
  1107.   .sp
  1108.   - sin1.jgr is a further extension of sin.jgr only with one x and y
  1109. ***************
  1110. *** 1105,1108 ****
  1111.   .sp
  1112.   There may well be loads of other bugs.  Send to jsp@princeton.edu.
  1113.   .sp
  1114. ! This is $Revision: 6.2 $.
  1115. --- 1185,1188 ----
  1116.   .sp
  1117.   There may well be loads of other bugs.  Send to jsp@princeton.edu.
  1118.   .sp
  1119. ! This is $Revision: 7.0 $.
  1120. *** ../work//jgraph.c    Thu Jan 23 11:14:27 1992
  1121. --- jgraph.c    Thu Jan 23 11:12:28 1992
  1122. ***************
  1123. *** 1,7 ****
  1124.   /* 
  1125.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/jgraph.c,v $
  1126. !  * $Revision: 6.2 $
  1127. !  * $Date: 91/11/01 11:46:38 $
  1128.    * $Author: jsp $
  1129.    */
  1130.   
  1131. --- 1,7 ----
  1132.   /* 
  1133.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/jgraph.c,v $
  1134. !  * $Revision: 7.0 $
  1135. !  * $Date: 92/01/23 11:09:52 $
  1136.    * $Author: jsp $
  1137.    */
  1138.   
  1139. ***************
  1140. *** 14,25 ****
  1141.   
  1142.   #include "jgraph.h"
  1143.   
  1144. ! int NMARKTYPES = 11;
  1145.   int NORMALMARKTYPES = 6;
  1146.   
  1147.   char *MARKTYPESTRS[] = { "circle", "box", "diamond", "triangle", "x", "cross", 
  1148. !                          "ellipse", "general", "xbar", "ybar", "none" };
  1149. ! char MARKTYPES[] = { 'o', 'b', 'd', 't', 'x', 'c', 'e', 'g', 'X', 'Y', 'n' };
  1150.   
  1151.   Label new_label()
  1152.   {
  1153. --- 14,26 ----
  1154.   
  1155.   #include "jgraph.h"
  1156.   
  1157. ! int NMARKTYPES = 12;
  1158.   int NORMALMARKTYPES = 6;
  1159.   
  1160.   char *MARKTYPESTRS[] = { "circle", "box", "diamond", "triangle", "x", "cross", 
  1161. !                          "ellipse", "general", "xbar", "ybar", "none", "text"};
  1162. ! char MARKTYPES[] = {     'o',      'b',   'd',       't',        'x', 'c', 
  1163. !              'e',       'g',       'X',    'Y',    'n',    'l' };
  1164.   
  1165.   Label new_label()
  1166.   {
  1167. ***************
  1168. *** 42,56 ****
  1169.   int num;
  1170.   {
  1171.     Curve new_c;
  1172. -   int i;
  1173.   
  1174.     new_c = (Curve) get_node(c);
  1175.     new_c->num = num;
  1176.     new_c->l = new_label();
  1177.     new_c->clip = 0;
  1178.     new_c->gray = 0.0;
  1179.     
  1180.     new_c->pts = (Point) make_list(sizeof(struct point));
  1181.     new_c->gen_linetype = (Flist) make_list(sizeof(struct flist));
  1182.     new_c->marktype = MARKTYPES[num % NORMALMARKTYPES];
  1183.     new_c->linetype = '0';
  1184. --- 43,60 ----
  1185.   int num;
  1186.   {
  1187.     Curve new_c;
  1188.   
  1189.     new_c = (Curve) get_node(c);
  1190.     new_c->num = num;
  1191.     new_c->l = new_label();
  1192. +   new_c->lmark = new_label();
  1193. +   new_c->lmark->hj = 'c';
  1194. +   new_c->lmark->vj = 'c';
  1195.     new_c->clip = 0;
  1196.     new_c->gray = 0.0;
  1197.     
  1198.     new_c->pts = (Point) make_list(sizeof(struct point));
  1199. +   new_c->npts = 0;
  1200.     new_c->gen_linetype = (Flist) make_list(sizeof(struct flist));
  1201.     new_c->marktype = MARKTYPES[num % NORMALMARKTYPES];
  1202.     new_c->linetype = '0';
  1203. ***************
  1204. *** 58,73 ****
  1205.     new_c->marksize[0] = FSIG;
  1206.     new_c->marksize[1] = FSIG;
  1207.     new_c->general_marks = (Point) make_list(sizeof(struct point));
  1208. -   i = num / NORMALMARKTYPES;
  1209.     new_c->fill = 0.0;
  1210.     new_c->rarrows = 0;
  1211.     new_c->larrows = 0;
  1212.     new_c->asize[0] = FSIG;
  1213.     new_c->asize[1] = FSIG;
  1214.     prio_insert(new_c, c, 0);
  1215.     return new_c;
  1216.   }
  1217.   
  1218.   Curve get_curve(c, num)
  1219.   Curve c;
  1220.   int num;
  1221. --- 62,89 ----
  1222.     new_c->marksize[0] = FSIG;
  1223.     new_c->marksize[1] = FSIG;
  1224.     new_c->general_marks = (Point) make_list(sizeof(struct point));
  1225.     new_c->fill = 0.0;
  1226.     new_c->rarrows = 0;
  1227.     new_c->larrows = 0;
  1228.     new_c->asize[0] = FSIG;
  1229.     new_c->asize[1] = FSIG;
  1230. +   new_c->bezier = 0;
  1231.     prio_insert(new_c, c, 0);
  1232.     return new_c;
  1233.   }
  1234.   
  1235. + Curve new_line(c, num)
  1236. + Curve c;
  1237. + int num;
  1238. + {
  1239. +   Curve new_c;
  1240. +   new_c = new_curve(c, num);
  1241. +   new_c->linetype = 's';
  1242. +   new_c->marktype = 'n';
  1243. +   return new_c;
  1244. + }
  1245.   Curve get_curve(c, num)
  1246.   Curve c;
  1247.   int num;
  1248. ***************
  1249. *** 205,211 ****
  1250.   
  1251.     g = (Graph) get_node(gs);
  1252.     g->num = num;
  1253. !   g->minval = 0.0;        /* added -hdd */
  1254.     g->x_axis = new_axis(1);
  1255.     g->y_axis = new_axis(0);
  1256.     g->x_translate = 0.0;
  1257. --- 221,230 ----
  1258.   
  1259.     g = (Graph) get_node(gs);
  1260.     g->num = num;
  1261. !   g->xminval = 0.0;
  1262. !   g->yminval = 0.0;
  1263. !   g->xmaxval = 0.0;
  1264. !   g->ymaxval = 0.0;
  1265.     g->x_axis = new_axis(1);
  1266.     g->y_axis = new_axis(0);
  1267.     g->x_translate = 0.0;
  1268. ***************
  1269. *** 268,273 ****
  1270. --- 287,293 ----
  1271.     process_graphs(gs);
  1272.     if (show) show_graphs(gs); else draw_graphs(gs, pp);
  1273.     exit(0);
  1274. +   return 0;
  1275.   }
  1276.   
  1277.   
  1278. *** ../work//jgraph.h    Thu Jan 23 11:14:28 1992
  1279. --- jgraph.h    Thu Jan 23 11:12:28 1992
  1280. ***************
  1281. *** 1,7 ****
  1282.   /* 
  1283.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/jgraph.h,v $
  1284. !  * $Revision: 6.2 $
  1285. !  * $Date: 91/11/01 11:46:40 $
  1286.    * $Author: jsp $
  1287.    */
  1288.   
  1289. --- 1,7 ----
  1290.   /* 
  1291.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/jgraph.h,v $
  1292. !  * $Revision: 7.0 $
  1293. !  * $Date: 92/01/23 11:09:54 $
  1294.    * $Author: jsp $
  1295.    */
  1296.   
  1297. ***************
  1298. *** 50,56 ****
  1299. --- 50,58 ----
  1300.     struct curve *blink;
  1301.     int num;
  1302.     Label l;
  1303. +   Label lmark;
  1304.     Point pts;
  1305. +   int npts;
  1306.     Point general_marks;
  1307.     float marksize[2];
  1308.     float fill;
  1309. ***************
  1310. *** 61,66 ****
  1311. --- 63,69 ----
  1312.     char linetype;
  1313.     int rarrows;
  1314.     int larrows;
  1315. +   int bezier;
  1316.     float asize[2];
  1317.     int clip;
  1318.   } *Curve;
  1319. ***************
  1320. *** 143,149 ****
  1321.     struct graph *flink;
  1322.     struct graph *blink;
  1323.     int num;
  1324. !   float minval;
  1325.     float x_translate;
  1326.     float y_translate;
  1327.     Axis x_axis;
  1328. --- 146,155 ----
  1329.     struct graph *flink;
  1330.     struct graph *blink;
  1331.     int num;
  1332. !   float xminval;
  1333. !   float yminval;
  1334. !   float xmaxval;
  1335. !   float ymaxval;
  1336.     float x_translate;
  1337.     float y_translate;
  1338.     Axis x_axis;
  1339. ***************
  1340. *** 176,181 ****
  1341. --- 182,188 ----
  1342.   
  1343.   /* Stuff defined in jgraph.c */
  1344.   
  1345. + extern Curve new_line();
  1346.   extern Curve new_curve();
  1347.   extern Curve get_curve();
  1348.   extern Graph new_graph();
  1349. *** ../work//list.c    Thu Jan 23 11:14:29 1992
  1350. --- list.c    Thu Jan 23 11:12:29 1992
  1351. ***************
  1352. *** 1,7 ****
  1353.   /* 
  1354.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/list.c,v $
  1355. !  * $Revision: 6.2 $
  1356. !  * $Date: 91/11/01 11:46:41 $
  1357.    * $Author: jsp $
  1358.    */
  1359.   
  1360. --- 1,7 ----
  1361.   /* 
  1362.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/list.c,v $
  1363. !  * $Revision: 7.0 $
  1364. !  * $Date: 92/01/23 11:09:55 $
  1365.    * $Author: jsp $
  1366.    */
  1367.   
  1368. *** ../work//list.h    Thu Jan 23 11:14:29 1992
  1369. --- list.h    Thu Jan 23 11:12:29 1992
  1370. ***************
  1371. *** 1,7 ****
  1372.   /* 
  1373.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/list.h,v $
  1374. !  * $Revision: 6.2 $
  1375. !  * $Date: 91/11/01 11:46:42 $
  1376.    * $Author: jsp $
  1377.    */
  1378.   
  1379. --- 1,7 ----
  1380.   /* 
  1381.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/list.h,v $
  1382. !  * $Revision: 7.0 $
  1383. !  * $Date: 92/01/23 11:09:55 $
  1384.    * $Author: jsp $
  1385.    */
  1386.   
  1387. *** ../work//printline.c    Thu Jan 23 11:14:31 1992
  1388. --- printline.c    Thu Jan 23 11:12:29 1992
  1389. ***************
  1390. *** 1,7 ****
  1391.   /* 
  1392.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/printline.c,v $
  1393. !  * $Revision: 6.2 $
  1394. !  * $Date: 91/11/01 11:46:44 $
  1395.    * $Author: jsp $
  1396.    */
  1397.   
  1398. --- 1,7 ----
  1399.   /* 
  1400.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/printline.c,v $
  1401. !  * $Revision: 7.0 $
  1402. !  * $Date: 92/01/23 11:09:57 $
  1403.    * $Author: jsp $
  1404.    */
  1405.   
  1406. ***************
  1407. *** 42,47 ****
  1408. --- 42,59 ----
  1409.     setlinewidth(1.0);
  1410.     setlinestyle('s', (Flist) 0);
  1411.   
  1412. + }
  1413. + bezier_control(x1, y1)
  1414. + float x1, y1;
  1415. + {
  1416. +   printf("  %f %f ", x1, y1);
  1417. + }
  1418. + bezier_end(x1, y1)
  1419. + float x1, y1;
  1420. + {
  1421. +   printf("  %f %f curveto\n", x1, y1);
  1422.   }
  1423.   
  1424.   
  1425. *** ../work//prio_list.c    Thu Jan 23 11:14:32 1992
  1426. --- prio_list.c    Thu Jan 23 11:12:29 1992
  1427. ***************
  1428. *** 1,7 ****
  1429.   /* 
  1430.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/prio_list.c,v $
  1431. !  * $Revision: 6.2 $
  1432. !  * $Date: 91/11/01 11:46:45 $
  1433.    * $Author: jsp $
  1434.    */
  1435.   
  1436. --- 1,7 ----
  1437.   /* 
  1438.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/prio_list.c,v $
  1439. !  * $Revision: 7.0 $
  1440. !  * $Date: 92/01/23 11:09:58 $
  1441.    * $Author: jsp $
  1442.    */
  1443.   
  1444. *** ../work//prio_list.h    Thu Jan 23 11:14:32 1992
  1445. --- prio_list.h    Thu Jan 23 11:12:30 1992
  1446. ***************
  1447. *** 1,7 ****
  1448.   /* 
  1449.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/prio_list.h,v $
  1450. !  * $Revision: 6.2 $
  1451. !  * $Date: 91/11/01 11:46:46 $
  1452.    * $Author: jsp $
  1453.    */
  1454.   
  1455. --- 1,7 ----
  1456.   /* 
  1457.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/prio_list.h,v $
  1458. !  * $Revision: 7.0 $
  1459. !  * $Date: 92/01/23 11:10:00 $
  1460.    * $Author: jsp $
  1461.    */
  1462.   
  1463. *** ../work//process.c    Thu Jan 23 11:14:33 1992
  1464. --- process.c    Thu Jan 23 11:12:30 1992
  1465. ***************
  1466. *** 1,7 ****
  1467.   /* 
  1468.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/process.c,v $
  1469. !  * $Revision: 6.2 $
  1470. !  * $Date: 91/11/01 11:46:47 $
  1471.    * $Author: jsp $
  1472.    */
  1473.   
  1474. --- 1,7 ----
  1475.   /* 
  1476.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/process.c,v $
  1477. !  * $Revision: 7.0 $
  1478. !  * $Date: 92/01/23 11:10:01 $
  1479.    * $Author: jsp $
  1480.    */
  1481.   
  1482. ***************
  1483. *** 20,40 ****
  1484.   Graph g;
  1485.   {
  1486.   
  1487.     if (g->title->x == FSIG) g->title->x = g->x_axis->psize / 2.0;
  1488.       else g->title->x = ctop(g->title->x, g->x_axis);
  1489. !   g->minval = 0.0;
  1490. !   if (g->x_axis->draw_axis_label) 
  1491. !     g->minval = MIN(g->minval, g->x_axis->label->y - 
  1492. !                     g->x_axis->label->fontsize);
  1493. !   if (g->x_axis->draw_hash_labels)
  1494. !     g->minval = MIN(g->minval, g->x_axis->draw_hash_labels_at
  1495. !                    - g->x_axis->hl->fontsize);
  1496. !   if (g->x_axis->draw_hash_marks)
  1497. !     g->minval = MIN(g->minval, g->x_axis->draw_hash_marks_at - HASH_SIZE);
  1498. !   g->minval -= 10.0;
  1499. !   if (g->title->y == FSIG) {
  1500. !     g->title->y = g->minval;
  1501. !   } else g->title->y = ctop(g->title->y, g->y_axis);
  1502.   }
  1503.   
  1504.   process_legend(g)
  1505. --- 20,46 ----
  1506.   Graph g;
  1507.   {
  1508.   
  1509. +   float ytitleloc;
  1510.     if (g->title->x == FSIG) g->title->x = g->x_axis->psize / 2.0;
  1511.       else g->title->x = ctop(g->title->x, g->x_axis);
  1512. !   if (g->title->y != FSIG) g->title->y = ctop(g->title->y, g->y_axis);
  1513. !   else {
  1514. !     ytitleloc = 0.0;
  1515. !     if (g->x_axis->draw_axis_label) 
  1516. !       ytitleloc = MIN(ytitleloc, g->x_axis->label->y - 
  1517. !                       g->x_axis->label->fontsize);
  1518. !     if (g->x_axis->draw_hash_labels)
  1519. !       ytitleloc = MIN(ytitleloc, g->x_axis->draw_hash_labels_at
  1520. !                      - g->x_axis->hl->fontsize);
  1521. !     if (g->x_axis->draw_hash_marks)
  1522. !       ytitleloc = MIN(ytitleloc, g->x_axis->draw_hash_marks_at - HASH_SIZE);
  1523. !     
  1524. !     if (g->title->y == FSIG) g->title->y = ytitleloc - 10.0;
  1525. !       else g->title->y = ctop(g->title->y, g->y_axis);
  1526. !   
  1527. !     g->title->y = ytitleloc - 10.0;
  1528. !   }
  1529.   }
  1530.   
  1531.   process_legend(g)
  1532. ***************
  1533. *** 437,442 ****
  1534. --- 443,455 ----
  1535.   Curve c;
  1536.   Graph g;
  1537.   {
  1538. +   if (c->bezier && (c->npts < 4 || (c->npts % 3 != 1))) {
  1539. +     error_header();
  1540. +     fprintf(stderr, "  Graph %d Curve %d:\n", g->num, c->num);
  1541. +     fprintf(stderr, "  Curve has %d points\n", c->npts);
  1542. +     fprintf(stderr, "  Bezier must have 3n + 1 points (n > 0)\n");
  1543. +     exit(1);
  1544. +   }
  1545.     c->marksize[0] = (c->marksize[0] == FSIG) ? 
  1546.                      4.0 : disttop(c->marksize[0], g->x_axis);
  1547.     c->marksize[1] = (c->marksize[1] == FSIG) ? 
  1548. ***************
  1549. *** 444,450 ****
  1550.     c->asize[0] = (c->asize[0] == FSIG) ? 
  1551.                      6.0 : disttop(c->asize[0], g->x_axis);
  1552.     c->asize[1] = (c->asize[1] == FSIG) ? 
  1553. !                    2.0 : disttop(c->asize[1], g->y_axis);
  1554.   }
  1555.   
  1556.   process_curves(g)
  1557. --- 457,465 ----
  1558.     c->asize[0] = (c->asize[0] == FSIG) ? 
  1559.                      6.0 : disttop(c->asize[0], g->x_axis);
  1560.     c->asize[1] = (c->asize[1] == FSIG) ? 
  1561. !                    2.0 : disttop(c->asize[1], g->y_axis) / 2.0;
  1562. !   c->lmark->x = disttop(c->lmark->x, g->x_axis);
  1563. !   c->lmark->y = disttop(c->lmark->y, g->y_axis);
  1564.   }
  1565.   
  1566.   process_curves(g)
  1567. ***************
  1568. *** 456,461 ****
  1569. --- 471,590 ----
  1570.     }
  1571.   }
  1572.    
  1573. + process_extrema(g)  /* This finds all the minval/maxvals for bbox calc */
  1574. + Graph g;
  1575. + {
  1576. +   Curve c;
  1577. +   float y, x;
  1578. +   g->xminval = 0.0;
  1579. +   g->yminval = 0.0;
  1580. +   g->xmaxval = g->x_axis->psize;
  1581. +   g->ymaxval = g->y_axis->psize;
  1582. +   
  1583. +   if (g->x_axis->draw_axis_label) {
  1584. +     g->yminval = MIN(g->yminval, g->x_axis->label->y - 
  1585. +                     g->x_axis->label->fontsize);
  1586. +     g->ymaxval = MAX(g->ymaxval, g->x_axis->label->y + 
  1587. +                     g->x_axis->label->fontsize);
  1588. +   }
  1589. +   if (g->y_axis->draw_axis_label) {
  1590. +     g->xminval = MIN(g->xminval, g->y_axis->label->y - 
  1591. +                     g->y_axis->label->fontsize);
  1592. +     g->xmaxval = MAX(g->xmaxval, g->y_axis->label->y + 
  1593. +                     g->y_axis->label->fontsize);
  1594. +   }
  1595. +   if (g->x_axis->draw_hash_labels) {
  1596. +     g->yminval = MIN(g->yminval, g->x_axis->draw_hash_labels_at
  1597. +                    - g->x_axis->hl->fontsize);
  1598. +     g->ymaxval = MAX(g->ymaxval, g->x_axis->draw_hash_labels_at
  1599. +                    + g->x_axis->hl->fontsize);
  1600. +   }
  1601. +   if (g->y_axis->draw_hash_labels) {
  1602. +     g->xminval = MIN(g->xminval, g->y_axis->draw_hash_labels_at
  1603. +                    - g->y_axis->hl->fontsize);
  1604. +     g->xmaxval = MAX(g->xmaxval, g->y_axis->draw_hash_labels_at
  1605. +                    + g->y_axis->hl->fontsize);
  1606. +   }
  1607. +   if (g->x_axis->draw_hash_marks) {
  1608. +       g->yminval = MIN(g->yminval, g->x_axis->draw_hash_marks_at - HASH_SIZE);
  1609. +       g->ymaxval = MAX(g->ymaxval, g->x_axis->draw_hash_marks_at + HASH_SIZE);
  1610. +   }
  1611. +   if (g->y_axis->draw_hash_marks) {
  1612. +       g->xminval = MIN(g->xminval, g->y_axis->draw_hash_marks_at - HASH_SIZE);
  1613. +       g->xmaxval = MAX(g->xmaxval, g->y_axis->draw_hash_marks_at + HASH_SIZE);
  1614. +   }
  1615. +     
  1616. +   if (g->title->label != CNULL) {
  1617. +       g->yminval = MIN(g->yminval, g->title->y - g->title->fontsize);
  1618. +       g->ymaxval = MAX(g->ymaxval, g->title->y + g->title->fontsize);
  1619. +   }    
  1620. +   if (g->legend->type != 'n') {
  1621. +     for (c = first(g->curves); c != nil(g->curves); c = next(c)) {
  1622. +       if (c->l->label != CNULL) {
  1623. +         y = c->l->y - (c->l->fontsize / 2.0 * FCPI / FPPI);
  1624. +         g->yminval = MIN(g->yminval, y);
  1625. +         g->ymaxval = MAX(g->ymaxval, y);
  1626. +         if (g->legend->anylines) {
  1627. +           if (c->linetype != '0' && g->legend->linelength != 0) {
  1628. +             x = c->l->x - g->legend->midspace - g->legend->linelength;
  1629. +             g->xminval = MIN(g->xminval, x);
  1630. +             g->xmaxval = MAX(g->xmaxval, x+ g->legend->linelength);
  1631. +           }
  1632. +           x = c->l->x - g->legend->midspace - g->legend->linelength / 2.0;
  1633. +         } else x = c->l->x - g->legend->midspace;
  1634. +         if (c->marktype != 'n') {
  1635. +           g->yminval = MIN(g->yminval, y - abs(c->marksize[1])/2.0);
  1636. +           g->ymaxval = MAX(g->ymaxval, y + abs(c->marksize[1])/2.0);
  1637. +           g->xminval = MIN(g->xminval, x - abs(c->marksize[0])/2.0);
  1638. +           g->xmaxval = MAX(g->xmaxval, x + abs(c->marksize[0])/2.0);
  1639. +         }
  1640. +         process_label_extrema(c->l, g);
  1641. +       }
  1642. +     }
  1643. +   }
  1644. + }
  1645. + process_label_extrema(l, g)
  1646. + Label l;
  1647. + Graph g;
  1648. + {
  1649. +   float len;
  1650. +   float height;
  1651. +   len = l->fontsize * FCPI / FPPI * strlen(l->label) * 0.8;
  1652. +   height = l->fontsize * FCPI / FPPI;
  1653. +   if (l->rotate == 0.0 || l->rotate == 180.0 || l->rotate == -180.0) {
  1654. +     if (l->hj == 'l') {
  1655. +       g->xminval = MIN(g->xminval, l->x);
  1656. +       g->xmaxval = MAX(g->xmaxval, l->x + len);
  1657. +     } else if (l->hj == 'c') {
  1658. +       g->xminval = MIN(g->xminval, l->x - len/2.0);
  1659. +       g->xmaxval = MAX(g->xmaxval, l->x + len/2.0);
  1660. +     } else if (l->hj == 'r') {
  1661. +       g->xminval = MIN(g->xminval, l->x - len);
  1662. +       g->xmaxval = MAX(g->xmaxval, l->x);
  1663. +     }
  1664. +     if (l->vj == 'b') {
  1665. +       g->yminval = MIN(g->yminval, l->y);
  1666. +       g->ymaxval = MAX(g->ymaxval, l->y + height);
  1667. +     } else if (l->vj == 'c') {
  1668. +       g->yminval = MIN(g->yminval, l->y - height/2.0);
  1669. +       g->ymaxval = MAX(g->ymaxval, l->y + height/2.0);
  1670. +     } else if (l->vj == 't') {
  1671. +       g->yminval = MIN(g->yminval, l->y - height);
  1672. +       g->ymaxval = MAX(g->ymaxval, l->y);
  1673. +     }
  1674. +   } else {         /* This is wrong -- I'm just estimating on the high side */
  1675. +     g->yminval = MIN(g->yminval, l->y - len);
  1676. +     g->ymaxval = MAX(g->ymaxval, l->y + len);
  1677. +     g->xminval = MIN(g->xminval, l->x - len);
  1678. +     g->xmaxval = MAX(g->xmaxval, l->x + len);
  1679. +   }
  1680. + }
  1681.   process_graph(g)
  1682.   Graph g;
  1683.   {
  1684. ***************
  1685. *** 469,474 ****
  1686. --- 598,604 ----
  1687.     process_legend(g);
  1688.     process_strings(g);
  1689.     process_title(g);
  1690. +   process_extrema(g);
  1691.   }
  1692.   
  1693.   process_graphs(gs)
  1694. ***************
  1695. *** 476,510 ****
  1696.   {
  1697.     Graphs the_g;
  1698.     Graph g;
  1699. !   float tmp_x, x, max_y, min_y;
  1700.     int do_bb, i;
  1701.   
  1702.     for (the_g = first(gs); the_g != nil(gs); the_g = next(the_g)) {
  1703.       for (g = first(the_g->g); g != nil(the_g->g); g = next(g)) process_graph(g);
  1704. !     x = 0.0;
  1705.       max_y = 0.0;
  1706.       min_y = 0.0;
  1707.       for (g = first(the_g->g); g != nil(the_g->g); g = next(g)) {
  1708. !       tmp_x = ABS(g->x_translate) * 2.0 + g->x_axis->psize;
  1709. !       x = MAX(x, tmp_x);
  1710. !       max_y = MAX(max_y, g->y_translate + g->y_axis->psize);
  1711. !       if (g->y_translate > 0.0)
  1712. !         min_y = MIN(min_y, g->y_translate + g->minval);
  1713. !       else
  1714. !         min_y = MIN(min_y, g->minval);
  1715.       }
  1716. !     if (the_g->height <= 0.00) 
  1717. !       the_g->height = max_y - min_y; 
  1718. !     else 
  1719.         the_g->height *= FCPI;
  1720. !     if (the_g->width <= 0.00) the_g->width = x; else the_g->width *= FCPI;
  1721.       do_bb = 1;
  1722.       for (i = 0; i < 4; i++) do_bb = (do_bb && the_g->bb[i] == FSIG);
  1723.       if (do_bb) {
  1724. !       the_g->bb[0] = 0.0;
  1725.         the_g->bb[1] = min_y;
  1726. !       the_g->bb[2] = the_g->width;
  1727. !       the_g->bb[3] = the_g->height + min_y;
  1728.       } 
  1729.     }
  1730.   }
  1731. --- 606,658 ----
  1732.   {
  1733.     Graphs the_g;
  1734.     Graph g;
  1735. !   float diff, max_y, min_y, max_x, min_x;
  1736.     int do_bb, i;
  1737.   
  1738.     for (the_g = first(gs); the_g != nil(gs); the_g = next(the_g)) {
  1739.       for (g = first(the_g->g); g != nil(the_g->g); g = next(g)) process_graph(g);
  1740. !     max_x = 0.0;
  1741. !     min_x = 0.0;
  1742.       max_y = 0.0;
  1743.       min_y = 0.0;
  1744.       for (g = first(the_g->g); g != nil(the_g->g); g = next(g)) {
  1745. !       max_y = MAX(max_y, g->y_translate + g->ymaxval);
  1746. !       min_y = MIN(min_y, g->y_translate + g->yminval);
  1747. !       max_x = MAX(max_x, g->x_translate + g->xmaxval);
  1748. !       min_x = MIN(min_x, g->x_translate + g->xminval);
  1749.       }
  1750. !     if (the_g->height >= 0.00) {
  1751.         the_g->height *= FCPI;
  1752. !       if (the_g->height > max_y - min_y) {
  1753. !         diff = (the_g->height - max_y + min_y) / 2.0;
  1754. !         max_y += diff;
  1755. !         min_y -= diff;
  1756. !       } else {
  1757. !         the_g->height = max_y - min_y;
  1758. !       }
  1759. !     } else {
  1760. !       the_g->height = max_y - min_y;
  1761. !     }
  1762. !     if (the_g->width >= 0.00) {
  1763. !       the_g->width *= FCPI;
  1764. !       if (the_g->width > max_x - min_x) {
  1765. !         diff = (the_g->width - max_x + min_x) / 2.0;
  1766. !         max_x += diff;
  1767. !         min_x -= diff;
  1768. !       } else {
  1769. !         the_g->width = max_x - min_x;
  1770. !       }
  1771. !     } else {
  1772. !       the_g->width = max_x - min_x;
  1773. !     }
  1774.       do_bb = 1;
  1775.       for (i = 0; i < 4; i++) do_bb = (do_bb && the_g->bb[i] == FSIG);
  1776.       if (do_bb) {
  1777. !       the_g->bb[0] = min_x;
  1778.         the_g->bb[1] = min_y;
  1779. !       the_g->bb[2] = max_x;
  1780. !       the_g->bb[3] = max_y;
  1781.       } 
  1782.     }
  1783.   }
  1784. *** ../work//show.c    Thu Jan 23 11:14:34 1992
  1785. --- show.c    Thu Jan 23 11:12:31 1992
  1786. ***************
  1787. *** 1,7 ****
  1788.   /* 
  1789.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/show.c,v $
  1790. !  * $Revision: 6.2 $
  1791. !  * $Date: 91/11/01 11:46:49 $
  1792.    * $Author: jsp $
  1793.    */ 
  1794.   
  1795. --- 1,7 ----
  1796.   /* 
  1797.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/show.c,v $
  1798. !  * $Revision: 7.0 $
  1799. !  * $Date: 92/01/23 11:10:04 $
  1800.    * $Author: jsp $
  1801.    */ 
  1802.   
  1803. ***************
  1804. *** 61,66 ****
  1805. --- 61,83 ----
  1806.     return;
  1807.   }
  1808.   
  1809. + show_lmark(l, nsp, g)
  1810. + Label l;
  1811. + int nsp;
  1812. + Graph g;
  1813. + {
  1814. +   char txt[300];
  1815. +   old_unprintable_text(l->label, txt);
  1816. +   spaces(nsp); printf(": %s\n", txt);
  1817. +   spaces(nsp); printf("x %f ", ptodist(l->x, g->x_axis));
  1818. +                printf("y %f\n", ptodist(l->y, g->y_axis));
  1819. +   spaces(nsp); printf("hj%c vj%c ", l->hj, l->vj);
  1820. +                printf("rotate %f\n", l->rotate);
  1821. +   spaces(nsp); printf("font %s ", l->font);
  1822. +                printf("fontsize %f\n", l->fontsize);
  1823. +   return;
  1824. + }
  1825.   show_curve(c, nsp, g)
  1826.   Curve c;
  1827.   int nsp;
  1828. ***************
  1829. *** 88,93 ****
  1830. --- 105,114 ----
  1831.       fprintf(stderr, "Unknown mark type %c\n", c->marktype);
  1832.       exit(1);
  1833.     } else printf("%s ", MARKTYPESTRS[i]);
  1834. +   if (c->marktype == 'l') {
  1835. +     show_lmark(c->lmark, nsp+2, g);
  1836. +     spaces(nsp);
  1837. +   }
  1838.     printf("marksize %f %f ", ptodist(c->marksize[0], g->x_axis), 
  1839.                               ptodist(c->marksize[1], g->y_axis));
  1840.     printf("fill %f\n", c->fill);
  1841. ***************
  1842. *** 130,137 ****
  1843.     if(!c->clip) printf("no"); printf("clip ");
  1844.     if(!c->rarrows) printf("no"); printf("rarrows ");
  1845.     if(!c->larrows) printf("no"); printf("larrows ");
  1846.     printf("asize %f %f\n", ptodist(c->asize[0], g->x_axis), 
  1847. !                           ptodist(c->asize[1], g->y_axis));
  1848.   }
  1849.   
  1850.   show_axis(a, nsp, g)
  1851. --- 151,159 ----
  1852.     if(!c->clip) printf("no"); printf("clip ");
  1853.     if(!c->rarrows) printf("no"); printf("rarrows ");
  1854.     if(!c->larrows) printf("no"); printf("larrows ");
  1855. +   if(!c->bezier) printf("no"); printf("bezier ");
  1856.     printf("asize %f %f\n", ptodist(c->asize[0], g->x_axis), 
  1857. !                           ptodist(c->asize[1], g->y_axis) * 2.0);
  1858.   }
  1859.   
  1860.   show_axis(a, nsp, g)
  1861. *** ../work//token.c    Thu Jan 23 11:14:44 1992
  1862. --- token.c    Thu Jan 23 11:12:32 1992
  1863. ***************
  1864. *** 1,7 ****
  1865.   /* 
  1866.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/token.c,v $
  1867. !  * $Revision: 6.2 $
  1868. !  * $Date: 91/11/01 11:46:50 $
  1869.    * $Author: jsp $
  1870.    */
  1871.   
  1872. --- 1,7 ----
  1873.   /* 
  1874.    * $Source: /n/fs/vd/jsp/src/jgraph/RCS/token.c,v $
  1875. !  * $Revision: 7.0 $
  1876. !  * $Date: 92/01/23 11:10:05 $
  1877.    * $Author: jsp $
  1878.    */
  1879.   
  1880. exit 0 # Just in case...
  1881.