Received: by ATHENA-PO-3.MIT.EDU (5.45/4.7) id AA25075; Mon, 16 Sep 91 04:22:31 EDT
Received: from yarra.pyramid.com.au by ATHENA.MIT.EDU with SMTP
	id AA22710; Mon, 16 Sep 91 04:19:54 EDT
Received: by yarra.pyramid.com.au id AA12302
  (5.65c/IDA-1.4.4 for bug-at@athena.mit.edu); Mon, 16 Sep 1991 18:18:22 +1000
Received: from baby.bby.oz.au by melba.bby.oz.au (4.0/SMI-4.0/BBY)
	id AA10580; Mon, 16 Sep 91 18:14:29 EST
       (from gnb@bby.oz.au for bug-at@athena.mit.edu)
Received: by baby.bby.oz.au (4.1/SMI-4.1)
	id AA03757; Mon, 16 Sep 91 18:13:54 EST
Message-Id: <9109160813.AA03757@baby.bby.oz.au>
To: bug-at@ATHENA.MIT.EDU, ware@cis.ohio-state.edu (Pete Ware),
        jordan@tcs.com (Jordan Hayes),
        "Timothy H Panton." <thp%westhawk.uucp@ukc.ac.uk>,
        Richard Hesketh <rlh2@ukc.ac.uk>, Barry <SOLOMON%DEV8K@mdcbbs.com>
Subject: AthenaPlotter Widget beta test: Patch 2
Date: Mon, 16 Sep 91 18:13:49 +1000
From: Gregory Bond <gnb@bby.oz.au>

A couple of people have expressed the desire to get to the latest
version, so I have attached below the diffs AGAINST THE ORIGINAL TAR
FILE.  This includes a patch I sent out about two weeks ago, so if you
have already applied that one, this patch will fail.  It fixes a lot
more bugs, some quite nasty, and makes the redraw decisions smarter in
a number of cases.  The major improvement is much better EPSF support,
and some more documentation in the man pages on the PostScript
generation.  See the AtText and AtPlotter man pages.

The only outstanding bug is some sort of race condition in the redraw
code that loses expose events occasionally.  I am still working on
that as time permits.

I will include my latest notes and todo files as well as the patch.
Comments etc welcome.

(I am probably going to drop the R5 contrib release as I will not have
R5 up and running by then, and there are a number of neat features
in R5 that the plotter would use.  Unless I get a volunteer to compile
and check it under R5....)

Greg.
-- 
Gregory Bond, Burdett Buckeridge & Young Ltd, Melbourne, Australia
Internet: gnb@melba.bby.oz.au    non-MX: gnb%melba.bby.oz@uunet.uu.net
Uucp: {uunet,pyramid,ubc-cs,ukc,mcvax,prlb2,nttlab...}!munnari!melba.bby.oz!gnb

-*- text -*-

Notes on results from beta testers

1) misspelled header files in LinePlot.h and Plot.h	[FIXED]

2) MKDIRHIER in Imakefile is often wrong		[FIXED]

3) header files installed mode 555

3) Mention in README and Using that is is widget-set independent
   (i.e. Athena and Motif).  (Almost.  Some Motif container widgets
   prang when certain resources are used, e.g. XmPanedWindow and
   setting the XmNpaneMinimum constraint resource. May be fixed by
   making the AtPlotter a subclass of XmManager.)

4) In some unspecified cases redraw will be dropped (e.g. expose    [1/2 FIXED??]
   events and plot changed at the same time) - occasionally
   infinite-loops at the same time.

5) AxisCore needs to zero pointer stuff in the initialize routine.	[FIXED]

6) Infinite loop in axis code if 1 tic and +ve and -ve numbers.	[FIXED]

7) PIX is not an lvalue, dies on SGI machines. (pete)		[FIXED]

8) Tabs in Imakefile macros prangs SGI make. (pete)		[FIXED]

9) AxisCore.h should include X11/StringDefs.h			[FIXED]

10) Axis occasionally gets "recalc without recalc pending" message, [FIXED]
    and then doesn't calculate tic labels....

11) Can't write PostScript from multiple graphs to one file - can't	[FIXED]
    get prolog.  Documentation on it improved.

12) AxisCore.c, need to intialise position_changed and
    numbers_changed = True.					    [FIXED]

13) Similar to 5) and 12), need to check all classes that the init	[FIXED]
    routine does the right thing.

14) Oops.  The PostScript output from LinePlot and BarPlot ignored the [FIXED]
    start parameter to the attach routine, giving offset graphs.

15) Line and Bar plot ran 1 too far in full recalc mode. 		[FIXED]

16) If min==max, nasty things happen, either assertion failures in the	[FIXED]
    axis code or infinite loops.  So Plotter needs to make sure
    min!=max.  

17) Calculation of num_tics in the Axis code was succeptible to		[FIXED]
    roundoff problems.

18) Provide a patchlevel.h for comp.sources.x submission.		[FIXED]

19) AxisCore was using actual_num_width before calculating it....	[FIXED]

20) off by 1 error on label axes (looks past end of data array)		[FIXED]

21) AxisCoreSetValues can coredump if a label is given after the axis	[FIXED]
    is created.

22) redraw when only refresh required:  plot changing background,	[FIXED]
    barplot changing do_fill and do_outline

----------------------------------------------------------------

 -*- text -*- $Id: ToDo,v 1.1 91/08/22 15:40:18 gnb Exp Locker: gnb $

Things to Do:
-------------

(In no particular order)

- Change the handling of FontFamily resources to avoid the
  intermediate string version.   Let the X resource converters do it!

- Build an outline sort of Manhatten geometry of BarGraphs and draw
  and fill that (controlled by boolean); will allow large pixmaps in
  fill GC to draw pictures clipped by bars.

- Motif driver program, with each resource available to be modified.

- Use m4 or cpp to simplify generation of wcl scripts for driver.

- Expand the SPlot to have 2/3 variables (or perhaps subclass?)

- An ErrorLinePLot class for high/low/last lineplots.

- Port XYPlot and ContourPlot classes. (Needs expanded/subclasses SPlot).

- Do the log axis (A subclass of AtAxis that uses the AtAxis code for
  the linear stuff).

- Have legend on either side (or top or bottom).

- Provide set_values_hook to simulate old usage of XtNxPoints et al.

- Document the internals, specifically writing new widgets.

- Have a stab at color postscript code.

- Some way of selecting plots (I think I've ripped this out once 
  already....) A suggestion: A user-supplied widget to include in the
  legend (e.g. pushbutton...)

- Some way of asking the labelAxis to not overlap labels, or asking
  the width of the widest one, or something, so that apps can arrange
  enough labels without them cluttering up.

----------------------------------------------------------------

*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:49 1991
--- AtPlot.man	Mon Sep 16 17:17:10 1991
***************
*** 67,78 ****
  specifying a width of 1.
  
  .IP XtNlineStyle
! Specifies the line style to use to draw the plot.  This resource is used
! for the line_style field of a GC.  Possible values are LineSolid,
! LineDoubleDash, or LineOnOffDash.
  
  .IP XtNdashLength
! Specifies the dash length to use when drawing dashed lines. 
  
  .IP XtNfastUpdate
  Provides a "hint" as to whether the plot should attempt to configure
--- 67,89 ----
  specifying a width of 1.
  
  .IP XtNlineStyle
! Specifies the line style to use to draw the plot.  This resource is
! used for the line_style field of a GC.  Possible values are LineSolid,
! LineDoubleDash, or LineOnOffDash.  On the X display, LineOnOffDash and
! LineDoubleDash differ in this respect: LineOnOffDash has alternate
! dashes of forgound color and gaps where the underneath shows up;
! LineDoubleDash has alternate dashes of forground color and background
! color.  Normally they would not be distinguishable because the default
! background for AtPlot widgets is the backgound color of the parent
! AtPlotter widget.  All dashes are the same length, as specified using
! XtNdashLength.  LineDoubleDash and LineOnOffDash \fIare\fP
! distinguishable in the generated PostScript output, because
! LineOnOfDash appears as a dot-dash line.
  
  .IP XtNdashLength
! Specifies the dash length to use when drawing dashed lines.  Each "on"
! and "off" dash is this many pixels long.  This resource is ignored
! when XtNlineStyle is set to LineSolid. 
  
  .IP XtNfastUpdate
  Provides a "hint" as to whether the plot should attempt to configure
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:50 1991
--- AtPlotter.man	Mon Sep 16 18:02:37 1991
***************
*** 220,225 ****
--- 220,226 ----
  .nf
  \fB
  void AtPlotterDrawPS(\fIf, w, x1, y1, x2, y2\fP)
+ void AtPlotterWritePostscriptProcSet(\fIf\fP)
  void AtPlotterGeneratePostscript(\fIfilename, w, title, x1, y1, x2, y2, landscape\fP)
  FILE *\fIf\fP;
  AtPlotterWidget \fIw\fP;
***************
*** 232,248 ****
  .fi
  .IP AtPlotterGeneratePostscript()
  Opens \fIfilename\fP and writes the Postscript representation of
! \fIplotter\fP to the file.  The plotter will have \fItitle\fP as a
! title.  The representation will be drawn inside the bounding box
! described by \fI(x1, y1)\fP and \fI(x2, y2)\fP.  If \fIlandscape\fP is
! True, the plotter representation will be rotated and drawn in
! Landscape mode.
  
  .IP AtPlotterDrawPS()
  Writes the Postscript representation of \fIplotter\fP to the file
  pointer \fIfp\fP.  The plotter representation will be drawn inside the
  bounding box described by \fI(x1, y1)\fP and \fI(x2, y2)\fP.
  
  .SH PLOTTER ROUTINES
  
  These routines are publicly visible, but are intended for
--- 233,268 ----
  .fi
  .IP AtPlotterGeneratePostscript()
  Opens \fIfilename\fP and writes the Postscript representation of
! \fIplotter\fP to the file.  The generated file will have \fItitle\fP
! as the EPSF title.  The representation will be drawn inside the
! bounding box described by \fI(x1, y1)\fP and \fI(x2, y2)\fP.  If
! \fIlandscape\fP is True, the plotter representation will be rotated
! and drawn in Landscape mode.  This generates a complete ESPF-2.0 file
! with header comments, the proc set, and bounding box comments, and
! adds a \fBshowpage\fP at the end so the EPSF file can be printed.
! (The trailing \fBshowpage\fP may need to be deleted if the document
! system that is including the EPSF file cannot handle it.  If this is
! the case, complain to your vendor as it is broken).
  
  .IP AtPlotterDrawPS()
  Writes the Postscript representation of \fIplotter\fP to the file
  pointer \fIfp\fP.  The plotter representation will be drawn inside the
  bounding box described by \fI(x1, y1)\fP and \fI(x2, y2)\fP.
+ It is assumed that the proc set has been included.  No other PostScript
+ is generated, so headers, the showpage etc will need to be added by
+ the application.  This is useful in drawing multiple graphs on the one
+ page.
  
+ .IP AtPlotterWritePostscriptProcSet()
+ Ouputs to the specified file the PostScript proc set used by the
+ plotter code.  It is up to the application to ensure that this proc
+ set is included before calls to AtPlotterDrawPS, as well as adding the
+ comments section and showpage operators required to make proper
+ conformant Structured PostScript.  The AtTextStartFontCollection() and
+ AtTextEndFontCollection() routines may be useful in generating
+ conformant EPSF.  See
+ .IR AtText (3).
+ 
  .SH PLOTTER ROUTINES
  
  These routines are publicly visible, but are intended for
***************
*** 316,321 ****
--- 336,357 ----
  	Widget \fIparent\fP;
  	ArgList \fIargs\fP;
  	Cardinal \fInum_args\fP;
+ .sp
+ fp = fopen(filename, "w");
+ fputs("%!PS-Adobe\\n", fp);
+ \fIPrint out all the header comments here...\fP
+ fputs("%%DocumentFonts: (atend)\\n", fp);
+ fputs("%%BoundingBox: 100 100 500 500\\n", fp);
+ fputs("%%EndComments\\n", fp);
+ AtPlotterWritePostscriptProcSet(fp);
+ AtTextStartFontCollection();
+ fputs("%%EndProlog\\n", fp);
+ AtPlotterDrawPS(fp, \fIplotter\fP, 100, 100, 500, 500);
+ fputs("showpage\\n",fp);
+ fputs("%%Trailer\\n", fp);
+ fputs("%%DocumentFonts:", fp);
+ AtTextEndFontCollection(fp);
+ fclose(fp);
  .fi
  
  .SH "SEE ALSO"
***************
*** 322,327 ****
--- 358,367 ----
  AtText(3X), AtFontFamily(3X), AtPlot(3X), AtAxisCore(3X), AtSPlot(3X)
  .br
  ``Using The AthenaTools Plotter Widget Set''
+ .br
+ ``Document Structuring Conventions'' in
+ ``PostScript Language Reference Manual'', Adobe Systems Inc..
+ 
  .SH AUTHORS
  David Flanagan (MIT Project Athena), Chris Craig (MIT Project Athena),
  and Kambiz Soroushian (MIT Project Athena) wrote an earlier version of
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:50 1991
--- AtText.man	Wed Sep 11 13:25:50 1991
***************
*** 37,42 ****
--- 37,45 ----
  int AtTextPSAscent(\fItext\fP);
  int AtTextPSDescent(\fItext\fP);
  void AtTextPSDraw(\fIfile, text, x, y\fP);
+ .sp
+ void AtTextStartFontCollection();
+ void AtTextEndFontCollection(\fifile\fP);
  void AtTextWritePostscriptProlog(\fIfile\fP);
  .sp
  	char *\fIstring\fP;
***************
*** 130,138 ****
  the same.
  
  .IP  "\fBAtTextWritePostscriptProlog()\fP"
! This writes a simple two-line prolog for the text facilities to the
  given file.
  
  .SH FORMATTING
  
  Text is formatted by using embedded commands, all of which begin with an
--- 133,156 ----
  the same.
  
  .IP  "\fBAtTextWritePostscriptProlog()\fP"
! This writes a simple three-line prolog for the text facilities to the
  given file.
  
+ .IP "\fBAtTextStartFontCollection()\fP"
+ .IP "\fBAtTextEndFontCollection()\fP"
+ These routines can be used to collect a list of fonts actually used in
+ set of AtText objects so the Structured PostScript comments such as
+ %%DocumentFonts can be generated. After a call to
+ AtTextStartFontCollection, each call to AtTestPSDraw will record in a
+ per-application list the names of all the fonts used.  Then a call to
+ AtTextEndFontCollection can be used to print out the names of all the
+ unique fonts, delete the internal list and stop the collection
+ process.  The font list is produced with a leading space, but no
+ leading comment.  If the number of fonts exceeds 60 characters, then a
+ newline followed by the Structured PostScript "%%+ " continuation marker is
+ output, and the list is split over multiple lines.  See the usage
+ section for an outline of how to use these routines.
+ 
  .SH FORMATTING
  
  Text is formatted by using embedded commands, all of which begin with an
***************
*** 327,333 ****
--- 345,362 ----
  t = AtTextCreate("@g(D)G@+[H@-{2}O]", ff, AtFontNORMAL, AtFontPLAIN);
  AtTextRotate(t);
  AtTextDraw(dpy, win, gc, t, 100,100);
+ .sp
+ fp = fopen(filename, "w");
+ fputs("%!PS-Adobe\\n%%Title: Test\\n%%DocumentFonts: (atend)\\n", fp);
+ AtTextWritePostscriptProlog(fp);
+ AtTextStartFontCollection();
+ fputs("%%EndProlog\\n", fp);
+ \fIlots of calls and writing, including calls like\fP
  AtTextPSDraw(fp, t, 100, 200);
+ ...
+ fputs("\\n%%Trailer\\n%%DocumentFonts:", fp);
+ AtTextEndFontCollection(fp);
+ fclose(fp);
  .fi
  
  .SH AUTHOR
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:51 1991
--- AtTextPlot.man	Wed Sep 11 13:11:45 1991
***************
*** 49,56 ****
  XtNfontSize	XtCFontSize	AtFontSize	AtFontNORMAL
  XtNfontStyle	XtCFontStyle	AtFontStyle	AtFontPLAIN
  XtNjustify	XtCJustify	AtJustify	AtTextJUSTIFY_CENTER
! XtNx		XtCPosition	int	0
! XtNy		XtCPosition	int	0
  XtNfloatingPosition	XtCFloatingPosition	Boolean	True
  XtNfloatingX	XtCFloatingX	double	0.0
  XtNfloatingY	XtCFloatingY	double	0.0
--- 49,56 ----
  XtNfontSize	XtCFontSize	AtFontSize	AtFontNORMAL
  XtNfontStyle	XtCFontStyle	AtFontStyle	AtFontPLAIN
  XtNjustify	XtCJustify	AtJustify	AtTextJUSTIFY_CENTER
! XtNx	XtCPosition	int	0
! XtNy	XtCPosition	int	0
  XtNfloatingPosition	XtCFloatingPosition	Boolean	True
  XtNfloatingX	XtCFloatingX	double	0.0
  XtNfloatingY	XtCFloatingY	double	0.0
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:52 1991
--- Axis.c	Tue Aug 27 13:47:35 1991
***************
*** 267,272 ****
--- 267,273 ----
       
       nt = len / (th * .75 * (8 - aw->axis.tic_density));
       if (nt < 1) nt = 1;
+      if (nt < 2 && min * max < 0) nt = 2; /* Stops an infinite loop... */
       nst = (len / nt) / (8 - aw->axis.subtic_density);
  
       mag = log10(fabs(max - min));
***************
*** 339,346 ****
       mn = *minp;
       mx = *maxp;
       
       do {
! 	  ti = CalcTicInterval(aw, mn, mx);
  	  if (aw->axis.round_endpoints) {
  	       mn = floor(*minp / ti) * ti;
  	       mx = ceil(*maxp / ti) * ti;
--- 340,348 ----
       mn = *minp;
       mx = *maxp;
       
+      nti = CalcTicInterval(aw, mn, mx);
       do {
! 	  ti = nti;
  	  if (aw->axis.round_endpoints) {
  	       mn = floor(*minp / ti) * ti;
  	       mx = ceil(*maxp / ti) * ti;
***************
*** 374,381 ****
       l = ceil(ac->min / ac->tic_interval) * ac->tic_interval;
       h = floor(ac->max / ac->tic_interval) * ac->tic_interval;
  
!      /* Now include the endpoints */
!      ac->num_tics = 1 + (h - l) / ac->tic_interval;
       if (h < ac->max) ac->num_tics++;
       if (l > ac->min) ac->num_tics++;
  
--- 376,383 ----
       l = ceil(ac->min / ac->tic_interval) * ac->tic_interval;
       h = floor(ac->max / ac->tic_interval) * ac->tic_interval;
  
!      /* Now include the endpoints - #$%& roundoff */
!      ac->num_tics = 1.0000001 + (h - l) / ac->tic_interval;
       if (h < ac->max) ac->num_tics++;
       if (l > ac->min) ac->num_tics++;
  
***************
*** 407,413 ****
       h = floor(ac->max / sti) * sti;
       l = ceil(ac->min / sti) * sti;
       
!      ac->num_subtics = (h - l) / sti + 1;
  
       ac->subtic_values = (double *)XtMalloc(sizeof (double) *
  					    ac->num_subtics);
--- 409,415 ----
       h = floor(ac->max / sti) * sti;
       l = ceil(ac->min / sti) * sti;
       
!      ac->num_subtics = (h - l) / sti + 1.00000001;
  
       ac->subtic_values = (double *)XtMalloc(sizeof (double) *
  					    ac->num_subtics);
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:52 1991
--- AxisCore.c	Wed Sep 11 12:43:14 1991
***************
*** 310,316 ****
  	  ac->label_text = NULL;
  }
  
! #define FreeLabelText(a) AtTextDestroy(a->axiscore.label_text)
  
  #define GetFF(a) \
       a->axiscore.ff = \
--- 310,317 ----
  	  ac->label_text = NULL;
  }
  
! #define FreeLabelText(a) \
!      if (a->axiscore.label_text) AtTextDestroy(a->axiscore.label_text)
  
  #define GetFF(a) \
       a->axiscore.ff = \
***************
*** 350,356 ****
--- 351,370 ----
       }
       new->axiscore.num_tics = new->axiscore.num_segments =
  	  new->axiscore.num_subtics = 0;
+      new->axiscore.x1 = new->axiscore.y1 = 0;
+      new->axiscore.x2 = new->axiscore.x2 = new->axiscore.grid_length = 10;
+      new->axiscore.max_num_width = new->axiscore.actual_num_width =
+ 	  new->axiscore.axis_width = new->axiscore.label_line =
+ 	       new->axiscore.tic_label_line = 0;
       
+      new->axiscore.tic_values = NULL;
+      new->axiscore.tic_label_string = NULL;
+      new->axiscore.subtic_values = NULL;
+      new->axiscore.segments = NULL;
+      new->axiscore.tic_pos = NULL;
+      new->axiscore.grid_segments = NULL;
+      new->axiscore.tic_label_text = NULL;
+      new->axiscore.numbers_changed = new->axiscore.position_changed = True;
  }
  
  static void AxisCoreDestroy(ac)
***************
*** 414,425 ****
       }
       if (Changed(label) || Changed(font_family) ||
  	 Changed(label_style) || Changed(label_size)) {
! 	  old_w = (ac->vertical ? AtTextWidth(ac->label_text) :
! 		   AtTextHeight(ac->label_text));
  	  FreeLabelText(new);
  	  GetLabelText(new);
! 	  new_w = (ac->vertical ? AtTextWidth(ac->label_text) :
! 		   AtTextHeight(ac->label_text));
  	  redraw = True;
  	  if (old_w != new_w) {
  	       relayout = True;
--- 428,439 ----
       }
       if (Changed(label) || Changed(font_family) ||
  	 Changed(label_style) || Changed(label_size)) {
! 	  old_w = ac->label_text ? (ac->vertical ? AtTextWidth(ac->label_text) :
! 				    AtTextHeight(ac->label_text)) : 0;
  	  FreeLabelText(new);
  	  GetLabelText(new);
! 	  new_w = ac->label_text ? (ac->vertical ? AtTextWidth(ac->label_text) :
! 				    AtTextHeight(ac->label_text)) : 0;
  	  redraw = True;
  	  if (old_w != new_w) {
  	       relayout = True;
***************
*** 616,621 ****
--- 630,646 ----
       int i, tp, tm, stp, stm, old_num_tics = ac->num_tics;
       XSegment *sp;
       
+      if (!(ac->numbers_changed || ac->position_changed)) {
+ 	  /* Hmm. how come we got called if there is nothing to change?? */
+ 	  /* Because a full recale might have been forced by another
+ 	     axis */
+ #if 0
+ 	  XtAppWarning(XtWidgetToApplicationContext(XtParent((Widget)pw)), 
+ 		       "AtAxis Recalc called without a recalc pending?");
+ #endif
+ 	  return;
+      }
+      
       if (ac->numbers_changed) {
  	  XtFree((char *)ac->tic_values);
  	  XtFree((char *)ac->subtic_values);
***************
*** 638,650 ****
  	  }
       }
  
-      if (!(ac->numbers_changed || ac->position_changed)) {
- 	  /* Hmm. how come we got called if there is nothing to change?? */
- 	  XtAppWarning(XtWidgetToApplicationContext(XtParent((Widget)pw)), 
- 		       "AtAxis Recalc called without a recalc pending?");
- 	  return;
-      }
-      
       /*
        * Make the pixel arrays from the stores position arrays
        *
--- 663,668 ----
***************
*** 710,715 ****
--- 728,738 ----
  	  } 
       }
  
+      /*
+       * Now convert the tic labels to AtText format
+       */
+      ReformatLabels((AtAxisCoreWidget)pw, False);
+      
       /* Now define the line against which tic labels are displayed */
       tp = ac->tics_outside && ac->numbers_outside || 
  	  ac->tics_inside && !ac->numbers_outside ? 
***************
*** 718,730 ****
  	  ac->tic_label_line = 
  	       (!ac->mirror ^ !!ac->numbers_outside) ? 
  		    ac->x2 + tp + MARGIN :
! 			 ac->x1 - tp - MARGIN - ac->max_num_width;
       } else {
  	  /* Remember, towards bottom is DECREASING pixel address!! */
  	  ac->tic_label_line = 
  	       (!ac->mirror ^ !!ac->numbers_outside) ?
  		    ac->y2 - MARGIN - tp :
! 			 ac->y1 + MARGIN + tp + ac->max_num_width;
       } 
  
       /*
--- 741,757 ----
  	  ac->tic_label_line = 
  	       (!ac->mirror ^ !!ac->numbers_outside) ? 
  		    ac->x2 + tp + MARGIN :
! 			 ac->x1 - tp - MARGIN - 
! 			      (ac->numbers_outside ? ac->max_num_width
! 			       : ac->actual_num_width);
       } else {
  	  /* Remember, towards bottom is DECREASING pixel address!! */
  	  ac->tic_label_line = 
  	       (!ac->mirror ^ !!ac->numbers_outside) ?
  		    ac->y2 - MARGIN - tp :
! 			 ac->y1 + MARGIN + tp +  
! 			      (ac->numbers_outside ? ac->max_num_width
! 			       : ac->actual_num_width);
       } 
  
       /*
***************
*** 749,759 ****
       }
  
       /*
-       * Now convert the tic labels to AtText format
-       */
-      ReformatLabels((AtAxisCoreWidget)pw, False);
-      
-      /*
        * Now, layout the label etc
        */
       if (ac->label_text) {
--- 776,781 ----
***************
*** 794,805 ****
  	       AtTextHeight(ac->tic_label_text[i]);
  	  maxwid = Max(maxwid, wid); 
       }
!      if (maxwid != ac->actual_num_width && ac->draw_numbers &&
! 	 ac->numbers_outside && ac->max_num_width < maxwid) {
  	  /* 
  	   * The width of the numbers has changed, so request a rescale
  	   * (so the max_num_width can be calculated). Its a pity,
! 	   * relayout is pretty much all that changes.
  	   */
  	  ac->numbers_changed = True;
  	  AtPlotterRescaleRequired((AtPlotWidget)acw);
--- 816,828 ----
  	       AtTextHeight(ac->tic_label_text[i]);
  	  maxwid = Max(maxwid, wid); 
       }
!      if (maxwid != ac->actual_num_width && ac->max_num_width < maxwid) {
  	  /* 
  	   * The width of the numbers has changed, so request a rescale
  	   * (so the max_num_width can be calculated). Its a pity,
! 	   * relayout is pretty much all that changes.  We need to do
! 	   * this even if we are not displaying the axis in case this
! 	   * axis is the target of a Frame axis.
  	   */
  	  ac->numbers_changed = True;
  	  AtPlotterRescaleRequired((AtPlotWidget)acw);
***************
*** 1104,1111 ****
       int tll, max_num_width;
       int x, y;
  
!      fprintf(fp, "%%%% BeginObject: AtAxisCore\n");
!      fprintf(fp, "GS\n");
       
       /* draw the line */
       fprintf(fp, "%d %d M %d %d L\n", x1, y1, x2, y2);    
--- 1127,1133 ----
       int tll, max_num_width;
       int x, y;
  
!      fputs("%%BeginObject: AtAxisCore\nGS\n", fp);
       
       /* draw the line */
       fprintf(fp, "%d %d M %d %d L\n", x1, y1, x2, y2);    
***************
*** 1241,1246 ****
  	  }
  	  AtTextPSDraw(fp, acp->label_text, x, y);
       }
!     fprintf(fp, "GR\n%%%% EndObject AtAxisCore\n");
  }
  
--- 1263,1268 ----
  	  }
  	  AtTextPSDraw(fp, acp->label_text, x, y);
       }
!     fputs("GR\n%%EndObject AtAxisCore\n", fp);
  }
  
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:53 1991
--- AxisCore.h	Mon Aug 26 11:21:22 1991
***************
*** 48,53 ****
--- 48,54 ----
  #define _AxisCore_h
  
  #include <X11/Intrinsic.h>
+ #include <X11/StringDefs.h>
  
  #ifdef _AtDevelopment_
  #include "Plot.h"
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:53 1991
--- AxisCoreP.h	Mon Aug 26 18:25:50 1991
***************
*** 119,126 ****
       Dimension		label_line; /* Start drawing the label at this pos */
  
       GC			number_gc;
-      AtText		number_text;
- 
       GC			grid_gc;
       
       /*
--- 119,124 ----
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:54 1991
--- BarPlot.c	Thu Sep 12 13:49:17 1991
***************
*** 40,47 ****
   */
  
  #include <X11/IntrinsicP.h>
- #include <X11/StringDefs.h>
- 
  #include <math.h>
  
  #ifdef _AtDevelopment_
--- 40,45 ----
***************
*** 247,252 ****
--- 245,251 ----
  {
  #define Changed(fld) (old->barplot.fld != new->barplot.fld)
       Boolean recalc = False;
+      Boolean refresh = False;
       Boolean redraw = False;
       
       if (new->barplot.cell_width <= 0 || new->barplot.cell_width > 1) {
***************
*** 269,275 ****
  			    "BarPlot must have either doFill or doOutline");
  	       new->barplot.do_fill = True;
  	  }
! 	  redraw = True;
       }
       
       if (Changed(zero_min)) {
--- 268,275 ----
  			    "BarPlot must have either doFill or doOutline");
  	       new->barplot.do_fill = True;
  	  }
! 	  refresh = True;
! 	  if (Changed(do_fill) && !new->barplot.do_fill) redraw = True;
       }
       
       if (Changed(zero_min)) {
***************
*** 279,292 ****
  	  AtPlotterPlotDataChanged((AtPlotWidget)new, &bb, False); 
       }
       
!      if (Changed(fill_color) || Changed(shading) || Changed(screen_shade)) {
  	  FreeFillGC(new);
  	  GetFillGC(new);
! 	  redraw = True;
       }
       
       if (redraw)
  	  AtPlotterRedrawRequired((AtPlotWidget)new);
       if (recalc)
  	  AtPlotterRecalcThisPlot((AtPlotWidget)new);
       return False;
--- 279,298 ----
  	  AtPlotterPlotDataChanged((AtPlotWidget)new, &bb, False); 
       }
       
!      if (Changed(fill_color) || 
! 	 (new->plot.background != old->plot.background) ||
! 	 Changed(shading) || Changed(screen_shade)) {
  	  FreeFillGC(new);
  	  GetFillGC(new);
! 	  refresh = True;
! 	  if (Changed(shading) || Changed(screen_shade))
! 	       redraw = True;
       }
       
       if (redraw)
  	  AtPlotterRedrawRequired((AtPlotWidget)new);
+      else if (refresh)
+ 	  AtPlotterRefreshRequired((AtPlotWidget)new);
       if (recalc)
  	  AtPlotterRecalcThisPlot((AtPlotWidget)new);
       return False;
***************
*** 327,332 ****
--- 333,339 ----
  #define bp  (&((AtBarPlotWidget)self)->barplot)
  #define bpw ((AtBarPlotWidget)self)
  #define PIX ((XRectangle *)bpw->splot.pix)
+ /* NB PIX is not an lvalue (at least to some picky compilers) */
  
  /*****************************************************************
   *
***************
*** 339,347 ****
  int extending;
  {
       if (extending) {
! 	  PIX = (XRectangle *) 
! 	       XtRealloc((char *)PIX, 
! 			 bpw->splot.num_points * sizeof (XRectangle));
  	  bp->fill_rectangles = (XRectangle *) 
  	       XtRealloc((char *)bp->fill_rectangles, 
  			 bpw->splot.num_points * sizeof (XRectangle));
--- 346,353 ----
  int extending;
  {
       if (extending) {
! 	  bpw->splot.pix = XtRealloc((char *)PIX, 
! 				     bpw->splot.num_points * sizeof (XRectangle));
  	  bp->fill_rectangles = (XRectangle *) 
  	       XtRealloc((char *)bp->fill_rectangles, 
  			 bpw->splot.num_points * sizeof (XRectangle));
***************
*** 355,362 ****
  	       Min(bp->saved_bb.ymin, bbp->ymin);
       } else {
  	  bp->saved_bb = *bbp;
! 	  PIX = (XRectangle *)XtMalloc(bpw->splot.num_points * 
! 				       sizeof (XRectangle));
  	  XtFree((char *)bp->fill_rectangles);
  	  bp->fill_rectangles = (XRectangle *)XtMalloc(bpw->splot.num_points * 
  						       sizeof (XRectangle));
--- 361,367 ----
  	       Min(bp->saved_bb.ymin, bbp->ymin);
       } else {
  	  bp->saved_bb = *bbp;
! 	  bpw->splot.pix = XtMalloc(bpw->splot.num_points * sizeof (XRectangle));
  	  XtFree((char *)bp->fill_rectangles);
  	  bp->fill_rectangles = (XRectangle *)XtMalloc(bpw->splot.num_points * 
  						       sizeof (XRectangle));
***************
*** 450,456 ****
       char term[100];
       char *shade = AtShadingPS(bp->shading);
       
!      fprintf(fp, "%% BeginObject: BarPlot\nGS\n");
       AtPlotPSLineStyle(fp, (AtPlotWidget)bpw);
       
       if (AtScaleGetLow(ys) < 0 && AtScaleGetHigh(ys) > 0) {
--- 455,461 ----
       char term[100];
       char *shade = AtShadingPS(bp->shading);
       
!      fputs("%%BeginObject: BarPlot\nGS\n", fp);
       AtPlotPSLineStyle(fp, (AtPlotWidget)bpw);
       
       if (AtScaleGetLow(ys) < 0 && AtScaleGetHigh(ys) > 0) {
***************
*** 472,480 ****
  	  int x0pix, x1pix, y1pix;
  	  
  	  x0pix = 
! 	       AtScaleUserToPixel(xs, i + bp->cell_offset);
  	  x1pix = 
! 	       AtScaleUserToPixel(xs, i + bp->cell_offset
  				  + bp->cell_width);
  	  y1pix = AtScaleUserToPixel(ys, AtSPlotGetValue((AtSPlotWidget)bpw, i));
  	  
--- 477,485 ----
  	  int x0pix, x1pix, y1pix;
  	  
  	  x0pix = 
! 	       AtScaleUserToPixel(xs, i + bpw->splot.start + bp->cell_offset);
  	  x1pix = 
! 	       AtScaleUserToPixel(xs, i + bpw->splot.start + bp->cell_offset
  				  + bp->cell_width);
  	  y1pix = AtScaleUserToPixel(ys, AtSPlotGetValue((AtSPlotWidget)bpw, i));
  	  
***************
*** 481,487 ****
  	  fprintf(fp, "%d %d M %d %d L %d %d L %d %d L CP %s\n",
  		  x0pix, y0pix, x0pix, y1pix, x1pix, y1pix, x1pix, y0pix, term);
       }
!      fprintf(fp, "GR\n%% EndObject\n");
  }
  
  
--- 486,492 ----
  	  fprintf(fp, "%d %d M %d %d L %d %d L %d %d L CP %s\n",
  		  x0pix, y0pix, x0pix, y1pix, x1pix, y1pix, x1pix, y0pix, term);
       }
!      fputs("GR\n%%EndObject\n", fp);
  }
  
  
***************
*** 525,531 ****
  #endif 
       if (from > to) {
  	  from = 0;
! 	  to = bpw->splot.num_points;
       }
       
       if (AtScaleGetLow(ys) < 0 && AtScaleGetHigh(ys) > 0) {
--- 530,536 ----
  #endif 
       if (from > to) {
  	  from = 0;
! 	  to = bpw->splot.num_points - 1;
       }
       
       if (AtScaleGetLow(ys) < 0 && AtScaleGetHigh(ys) > 0) {
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:54 1991
--- BarPlot.h	Mon Aug 26 11:27:33 1991
***************
*** 41,46 ****
--- 41,48 ----
  #ifndef _AtBarPlot_h
  #define _AtBarPlot_h
  
+ #include <X11/StringDefs.h>
+ 
  #ifndef _AtDevelopment_
  #include <At/SPlot.h>
  #include <At/Shading.h>
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:55 1991
--- Imakefile	Tue Sep 10 15:16:15 1991
***************
*** 15,24 ****
  # The headers will be in $(ATINCDIR)/At.
  # The man pages will have the name $(ATMANDIR)/AtPlot.$(ATMANSUFFIX)
  
! ATLIBDIR =	/usr/local/lib
! ATINCDIR =	/usr/local/include
! ATMANDIR =	/usr/local/man/man3
! ATMANSUFFIX =	3X
  
  # Define one of these to force use of either ansi of traditional compilers.
  # Defining neither will use the default compiler.
--- 15,24 ----
  # The headers will be in $(ATINCDIR)/At.
  # The man pages will have the name $(ATMANDIR)/AtPlot.$(ATMANSUFFIX)
  
! ATLIBDIR	= /usr/local/lib
! ATINCDIR	= /usr/local/include
! ATMANDIR	= /usr/local/man/man3
! ATMANSUFFIX	= 3X
  
  # Define one of these to force use of either ansi of traditional compilers.
  # Defining neither will use the default compiler.
***************
*** 42,48 ****
  # path to the Postscript font metrics files on your system.  Don't get
  # rid of the quoted "s -- they're very important!
  
! AFMPATH =	\"/usr/local/lib/afm\"
  
  # Cpp defines.
  #
--- 42,48 ----
  # path to the Postscript font metrics files on your system.  Don't get
  # rid of the quoted "s -- they're very important!
  
! AFMPATH	= \"/usr/local/lib/afm\"
  
  # Cpp defines.
  #
***************
*** 54,60 ****
  # X11R4_INTRINSICS required if Xt is R4 or greater 
  #	(actually, it probably no longer compiles under R3)
  
! DEFINES = -DDEBUG -D_AtDevelopment_ -DX11R4_INTRINSICS
  
  # The command used to preformat the man pages.  Must be functionally
  # equivalent to the Unix command 'tbl'.  If your man(1) command supports the
--- 54,60 ----
  # X11R4_INTRINSICS required if Xt is R4 or greater 
  #	(actually, it probably no longer compiles under R3)
  
! DEFINES	= -DDEBUG -D_AtDevelopment_ -DX11R4_INTRINSICS
  
  # The command used to preformat the man pages.  Must be functionally
  # equivalent to the Unix command 'tbl'.  If your man(1) command supports the
***************
*** 63,75 ****
  # to run tbl, then cat will be fine.  
  # SunOS certainly supports this from 4.0 onwards.
  
! #TBL	=	tbl
! TBL	=	cat
  
  # For making PostScript versions of th man page (so they're easy to print 
  # out!)  define this command that takes an input file called "$*.man" and
  # runs tbl, troff and your troff to ps converter then sticks the ps on STDOUT.
! MAN2PS	=	tbl $*.man | troff -t -man | thack 
  # You could use this to create lpr-able text versions (if you don't mind the
  # confusion arising from the dual use of the .ps suffix!)
  # MAN2PS = tbl $*.man | nroff -man 
--- 63,75 ----
  # to run tbl, then cat will be fine.  
  # SunOS certainly supports this from 4.0 onwards.
  
! #TBL	= tbl
! TBL	= cat
  
  # For making PostScript versions of th man page (so they're easy to print 
  # out!)  define this command that takes an input file called "$*.man" and
  # runs tbl, troff and your troff to ps converter then sticks the ps on STDOUT.
! MAN2PS	= tbl $*.man | troff -t -man | thack 
  # You could use this to create lpr-able text versions (if you don't mind the
  # confusion arising from the dual use of the .ps suffix!)
  # MAN2PS = tbl $*.man | nroff -man 
***************
*** 86,91 ****
--- 86,94 ----
  #define WclCFlags -I/usr/local/include
  #define WclLibs -lWc -lXp
  
+ # Some imake setups have MAKEDIRHIER badly defined in the template file...
+ 	MKDIRHIER = mkdirhier.sh
+ 
  #################################################################
  #
  #  You shouldn't need to edit from here on
***************
*** 240,249 ****
  # dependencies of anything else loops result.
  # sample_prog.tex is a latex-ified version of sample_prog.c.
  
! FIGS =		classes.fig layout.fig bars.fig 
! FIGS_UU = 	classes.uu layout.uu bars.uu 
! FIGS_PS =	classes.ps layout.ps bars.ps
! FIGS_TEX =	classes.tex layout.tex bars.tex
  
  DOC_INCLUDE_SRC = Sample.PS
  DOC_INCLUDE_FILES = Sample.tex $(FIGS_TEX) sample_prog.tex
--- 243,252 ----
  # dependencies of anything else loops result.
  # sample_prog.tex is a latex-ified version of sample_prog.c.
  
! FIGS = classes.fig layout.fig bars.fig 
! FIGS_UU = classes.uu layout.uu bars.uu 
! FIGS_PS = classes.ps layout.ps bars.ps
! FIGS_TEX = classes.tex layout.tex bars.tex
  
  DOC_INCLUDE_SRC = Sample.PS
  DOC_INCLUDE_FILES = Sample.tex $(FIGS_TEX) sample_prog.tex
***************
*** 257,263 ****
  # Extra files to include in the tar.z/shar archive
  # REGISTER_C and CASECMP_C are only defined if those files aren't in $(SRCS)
  EXTRAFILES = README CHANGED-V4 redraw-protocol Imakefile ToDo ispell-words \
! 	$(REGISTER_C) $(CASECMP_C) \
  	Makefile.std Test.ad test.c sample_prog.c $(DOC_SRC)
  
  
--- 260,266 ----
  # Extra files to include in the tar.z/shar archive
  # REGISTER_C and CASECMP_C are only defined if those files aren't in $(SRCS)
  EXTRAFILES = README CHANGED-V4 redraw-protocol Imakefile ToDo ispell-words \
! 	$(REGISTER_C) $(CASECMP_C) patchlevel.h \
  	Makefile.std Test.ad test.c sample_prog.c $(DOC_SRC)
  
  
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:56 1991
--- LabelAxis.c	Tue Sep 10 15:16:34 1991
***************
*** 206,215 ****
  	  i < end || i <= imax; i++) {
  	  if (i < imin) continue;
  	  if (i > imax) break;
- 	  p = (String *)((char *)la->data + (i - la->start) * la->stride); 
  	  if (i == imin) ni++;
  	  else if (i == imax) ni++;
! 	  else if (p && *p && **p) ni++;
       }
       ac->num_tics = ni;
       ac->num_subtics = 0;	/* For now! */
--- 206,217 ----
  	  i < end || i <= imax; i++) {
  	  if (i < imin) continue;
  	  if (i > imax) break;
  	  if (i == imin) ni++;
  	  else if (i == imax) ni++;
! 	  else if (i < end) {
! 	       p = (String *)((char *)la->data + (i - la->start) * la->stride); 
! 	       if (p && *p && **p) ni++;
! 	  } 
       }
       ac->num_tics = ni;
       ac->num_subtics = 0;	/* For now! */
***************
*** 237,246 ****
  	       ac->tic_values[ni] = i; 
  	       ac->tic_label_string[ni++] = 
  		    XtNewString((p && *p && **p) ? *p : ""); 
! 	  } else if (p && *p && **p) {
! 	       ac->tic_values[ni] = i; 
! 	       ac->tic_label_string[ni++] = XtNewString(*p); 
! 	  }
       }
       assert(ni == ac->num_tics);
  }
--- 239,251 ----
  	       ac->tic_values[ni] = i; 
  	       ac->tic_label_string[ni++] = 
  		    XtNewString((p && *p && **p) ? *p : ""); 
! 	  } else if (i < end) {
! 	       p = (String *)((char *)la->data + (i - la->start) * la->stride); 
! 	       if (p && *p && **p) {
! 		    ac->tic_values[ni] = i; 
! 		    ac->tic_label_string[ni++] = XtNewString(*p); 
! 	       }
! 	  } 
       }
       assert(ni == ac->num_tics);
  }
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:57 1991
--- LabelAxisP.h	Mon Aug 26 18:25:49 1991
***************
*** 58,63 ****
--- 58,64 ----
  extern AtLabelAxisClassRec atLabelAxisClassRec;
  
  typedef struct {
+      /* Resources */
       Boolean		auto_scale;
  
       /* These set via the member function */
***************
*** 65,73 ****
       Cardinal		stride;
       Cardinal		start;
       Cardinal		num_items;
- 
-      /* Internal state varialbles */
-      int		max_width; /* Max width of a label */
  } AtLabelAxisPart;
  
  typedef struct _AtLabelAxisRec {
--- 66,71 ----
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:57 1991
--- LinePlot.c	Wed Sep 11 12:50:15 1991
***************
*** 121,126 ****
--- 121,127 ----
   */
  #define lp ((AtLinePlotWidget)self)
  #define PIX ((XPoint *)lp->splot.pix)
+ /* NB: PIX is NOT an lvalue (on some very picky compilers!!!) */
  
  /*
   * Don't need to adjust the bbox, only to allocate the memory.
***************
*** 131,140 ****
  int extending;
  {
       if (extending)
! 	  PIX = (XPoint *)XtRealloc((char *)PIX,
! 				    lp->splot.num_points * sizeof (XPoint)); 
       else
! 	  PIX = (XPoint *)XtMalloc(lp->splot.num_points * sizeof (XPoint)); 
  }
  
  /*
--- 132,141 ----
  int extending;
  {
       if (extending)
! 	  lp->splot.pix = XtRealloc((char *)PIX, 
! 				    lp->splot.num_points * sizeof (XPoint));  
       else
! 	  lp->splot.pix = XtMalloc(lp->splot.num_points * sizeof (XPoint)); 
  }
  
  /*
***************
*** 195,220 ****
  {
       int i = 0, count = 0;
       
!      fprintf(fp, "%% BeginObject: AtLinePlot\nGS\n");
       AtPlotPSLineStyle(fp, self);
       
       for (i = 1; i < lp->splot.num_points; i++) {
  	  if (!count) {
! 	       fprintf(fp, "%d %d M ", AtScaleUserToPixel(xs, (double)(i - 1)),
! 		       AtScaleUserToPixel(ys, 
! 					  AtSPlotGetValue((AtSPlotWidget)lp, 
! 							  i - 1)));
  	  }
! 	  fprintf(fp, "%d %d L\n", AtScaleUserToPixel(xs, (double)i),
! 		  AtScaleUserToPixel(ys, 
! 				     AtSPlotGetValue((AtSPlotWidget)lp, i)));
  	  if (++count > 50) {
  	       fprintf(fp, "ST\n");
  	       count = 0;
  	  }
       }
!      fprintf(fp, "%sGR\n%% EndObject\n", count ? "ST\n" : "");
!      fp = (FILE *)RCSid;	/* Keep gcc quiet */
  }
  
  
--- 196,221 ----
  {
       int i = 0, count = 0;
       
!      fputs("%%BeginObject: AtLinePlot\nGS\n", fp);
       AtPlotPSLineStyle(fp, self);
       
       for (i = 1; i < lp->splot.num_points; i++) {
  	  if (!count) {
! 	       fprintf(fp, "%d %d M ", 
! 		       AtScaleUserToPixel(xs, (double)(i+lp->splot.start-1)), 
! 		       AtScaleUserToPixel(ys, AtSPlotGetValue((AtSPlotWidget)lp, 
! 							      i - 1)));
  	  }
! 	  fprintf(fp, "%d %d L\n", 
! 		  AtScaleUserToPixel(xs, (double)(i + lp->splot.start)),
! 		  AtScaleUserToPixel(ys, AtSPlotGetValue((AtSPlotWidget)lp, i)));
  	  if (++count > 50) {
  	       fprintf(fp, "ST\n");
  	       count = 0;
  	  }
       }
!      fprintf(fp, "%sGR\n%%%%EndObject\n", count ? "ST\n" : "");
!      *RCSid = *RCSid;	/* Keep gcc quiet */
  }
  
  
***************
*** 245,251 ****
  #endif 
       if (from > to) {
  	  from = 0;
! 	  to = lp->splot.num_points;
       }
       for (i = from; i <= to; i++) {
  	  PIX[i].x = AtScaleUserToPixel(xs, (double)(i + lp->splot.start));
--- 246,252 ----
  #endif 
       if (from > to) {
  	  from = 0;
! 	  to = lp->splot.num_points - 1;
       }
       for (i = from; i <= to; i++) {
  	  PIX[i].x = AtScaleUserToPixel(xs, (double)(i + lp->splot.start));
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:57 1991
--- LinePlot.h	Fri Aug 23 10:26:43 1991
***************
*** 44,50 ****
  #ifdef _AtDevelopment_
  #include "SPlot.h"
  #else
! #include <At/Splot.h>
  #endif
  
  /* declare specific AtLinePlotWidget class and instance datatypes */
--- 44,50 ----
  #ifdef _AtDevelopment_
  #include "SPlot.h"
  #else
! #include <At/SPlot.h>
  #endif
  
  /* declare specific AtLinePlotWidget class and instance datatypes */
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:58 1991
--- MANIFEST	Tue Sep 10 15:17:56 1991
***************
*** 1,61 ****
     File Name		Archive #	Description
  -----------------------------------------------------------
   AtAxis.man                 3	Manual page for the simple axis widget
!  AtAxisCore.man             6	Manual page for the axis core widget
!  AtBarPlot.man              3	Manual page for the bar plot widget
!  AtConverters.c             4	Converters between local types for X resources
   AtConverters.h             1	Header file declaring converter functions
   AtFontFamily.man           4	Manual page for the font handling code
   AtFrameAxis.man            2	Manual page for the frame axis widget
   AtLabelAxis.man            2	Manual page for the label axis widget
   AtLinePlot.man             2	Manual page for the line plot widget
!  AtPlot.man                 2	Manual page for the plot metaclass
   AtPlotter.man              7	Manual page for the main plotter widget
   AtSPlot.man                3	Manual page for the SPlot metaclass
   AtShading.man              2	Manual page for the Shading/grayscale code
   AtText.man                 6	Manual page for the text handling code
   AtTextPlot.man             3	Manual page for the text-on-graphs widget
!  Axis.c                     6	The simple linear axis class
   Axis.h                     1	Public definitions for simple linear axis
!  AxisCore.c                 9	The guts of the picels handling for axis classes
!  AxisCore.h                 2	The guts of the picels handling for axis classes
!  AxisCoreP.h                2	The guts of the picels handling for axis classes
   AxisP.h                    1	Private definitions for simple linear axis
!  BarPlot.c                  7	Class for simple bar plots
!  BarPlot.h                  1	Class for simple bar plots
   BarPlotP.h                 1	Class for simple bar plots
   CHANGED-V4                 6	What's changed since the Version 4 plotter?
   FontFamily.c               4	Integrated X/PostScript font handling
!  FontFamily.h               2   Integrated X/PostScript font handling
   FontFamilyP.h              1	Integrated X/PostScript font handling
   FontFamilyPS.c             2	Integrated X/PostScript font handling
!  FrameAxis.c                4	Axis that gets info from aonther axis
   FrameAxis.h                1	Axis that gets info from aonther axis
   FrameAxisP.h               1	Axis that gets info from aonther axis
!  Imakefile                  6	Feed this to xmkmf
   LabelAxis.c                4	Axis labelled with program-supplied labels
   LabelAxis.h                1	Axis labelled with program-supplied labels
   LabelAxisP.h               1	Axis labelled with program-supplied labels
!  LinePlot.c                 3	Simple line plot class
   LinePlot.h                 1	Simple line plot class
   LinePlotP.h                1	Simple line plot class
   MANIFEST                   1	This shipping list
!  Makefile.std               8	A Makefile for those who can't use xmkmf
   Plot.c                     5	The parent class of all plot widgets
!  Plot.h                     1	The parent class of all plot widgets
   PlotP.h                    2	The parent class of all plot widgets
!  Plotter.c                 11	The core widget that controls the whole process
   Plotter.h                  2	The core widget that controls the whole process
   PlotterP.h                 3	The core widget that controls the whole process
!  PlotterPS.c                5	PostScript code for plot widget
   README                     1	whadda you think?
!  SPlot.c                    3	The superclass that can examine application data
   SPlot.h                    2	The superclass that can examine application data
!  SPlotP.h                   1	The superclass that can examine application data
   Sample.PS                  5	The postscript generated by the sample_prog
   Sample.tex                 1	A simple tex source to include the sample plot
   Scale.c                    3	Flexible user-to-pixel scaling
!  Scale.h                    1	Flexible user-to-pixel scaling
   Shading.c                  4	Integrated X/Postscript shading/stipple handling
   Shading.h                  1	Integrated X/Postscript shading/stipple handling
   Test.ad                    4	AppDefaults file for wcl-based test program
--- 1,61 ----
     File Name		Archive #	Description
  -----------------------------------------------------------
   AtAxis.man                 3	Manual page for the simple axis widget
!  AtAxisCore.man             7	Manual page for the axis core widget
!  AtBarPlot.man              4	Manual page for the bar plot widget
!  AtConverters.c             5	Converters between local types for X resources
   AtConverters.h             1	Header file declaring converter functions
   AtFontFamily.man           4	Manual page for the font handling code
   AtFrameAxis.man            2	Manual page for the frame axis widget
   AtLabelAxis.man            2	Manual page for the label axis widget
   AtLinePlot.man             2	Manual page for the line plot widget
!  AtPlot.man                 3	Manual page for the plot metaclass
   AtPlotter.man              7	Manual page for the main plotter widget
   AtSPlot.man                3	Manual page for the SPlot metaclass
   AtShading.man              2	Manual page for the Shading/grayscale code
   AtText.man                 6	Manual page for the text handling code
   AtTextPlot.man             3	Manual page for the text-on-graphs widget
!  Axis.c                     7	The simple linear axis class
   Axis.h                     1	Public definitions for simple linear axis
!  AxisCore.c                10	The guts of the picels handling for axis classes
!  AxisCore.h                 3	The guts of the picels handling for axis classes
!  AxisCoreP.h                3	The guts of the picels handling for axis classes
   AxisP.h                    1	Private definitions for simple linear axis
!  BarPlot.c                  8	Class for simple bar plots
!  BarPlot.h                  2	Class for simple bar plots
   BarPlotP.h                 1	Class for simple bar plots
   CHANGED-V4                 6	What's changed since the Version 4 plotter?
   FontFamily.c               4	Integrated X/PostScript font handling
!  FontFamily.h               2	Integrated X/PostScript font handling
   FontFamilyP.h              1	Integrated X/PostScript font handling
   FontFamilyPS.c             2	Integrated X/PostScript font handling
!  FrameAxis.c                5	Axis that gets info from aonther axis
   FrameAxis.h                1	Axis that gets info from aonther axis
   FrameAxisP.h               1	Axis that gets info from aonther axis
!  Imakefile                  7	Feed this to xmkmf
   LabelAxis.c                4	Axis labelled with program-supplied labels
   LabelAxis.h                1	Axis labelled with program-supplied labels
   LabelAxisP.h               1	Axis labelled with program-supplied labels
!  LinePlot.c                 4	Simple line plot class
   LinePlot.h                 1	Simple line plot class
   LinePlotP.h                1	Simple line plot class
   MANIFEST                   1	This shipping list
!  Makefile.std               9	A Makefile for those who can't use xmkmf
   Plot.c                     5	The parent class of all plot widgets
!  Plot.h                     2	The parent class of all plot widgets
   PlotP.h                    2	The parent class of all plot widgets
!  Plotter.c                 12	The core widget that controls the whole process
   Plotter.h                  2	The core widget that controls the whole process
   PlotterP.h                 3	The core widget that controls the whole process
!  PlotterPS.c                6	PostScript code for plot widget
   README                     1	whadda you think?
!  SPlot.c                    4	The superclass that can examine application data
   SPlot.h                    2	The superclass that can examine application data
!  SPlotP.h                   2	The superclass that can examine application data
   Sample.PS                  5	The postscript generated by the sample_prog
   Sample.tex                 1	A simple tex source to include the sample plot
   Scale.c                    3	Flexible user-to-pixel scaling
!  Scale.h                    2	Flexible user-to-pixel scaling
   Shading.c                  4	Integrated X/Postscript shading/stipple handling
   Shading.h                  1	Integrated X/Postscript shading/stipple handling
   Test.ad                    4	AppDefaults file for wcl-based test program
***************
*** 62,72 ****
   Text.c                     8	Integrated flexible text handling
   Text.h                     2	Integrated flexible text handling
   TextPS.c                   5	PostScript output from test handling stuff
!  TextPlot.c                 5	Label a spot on the graph with some text
   TextPlot.h                 1	Label a spot on the graph with some text
   TextPlotP.h                1	Label a spot on the graph with some text
   ToDo                       1	Wishlist of things to do
!  Using.tex                 10	LaTeX users document
   WclRegister.c              1	Register all widget classes with WCL
   bars.ps                    1	PS version of xfig picture for Using document
   bars.tex                   1	tex stub to include PS figure
--- 62,72 ----
   Text.c                     8	Integrated flexible text handling
   Text.h                     2	Integrated flexible text handling
   TextPS.c                   5	PostScript output from test handling stuff
!  TextPlot.c                 6	Label a spot on the graph with some text
   TextPlot.h                 1	Label a spot on the graph with some text
   TextPlotP.h                1	Label a spot on the graph with some text
   ToDo                       1	Wishlist of things to do
!  Using.tex                 11	LaTeX users document
   WclRegister.c              1	Register all widget classes with WCL
   bars.ps                    1	PS version of xfig picture for Using document
   bars.tex                   1	tex stub to include PS figure
***************
*** 78,84 ****
   layout.ps                  1	PS version of xfig picture for Using document
   layout.tex                 1	tex stub to include PS figur
   layout.uu                  1	xfig picture for document (uuencoded
!  redraw-protocol            7	widget-widget communication description
!  sample_prog.tex            5	sample_prog.c run through tgrind
   strcasecmp.c               1	strcasecmp() for systems without it
   tgrind.sty                 3	LaTeX style file for use with tgrind'd file
--- 78,86 ----
   layout.ps                  1	PS version of xfig picture for Using document
   layout.tex                 1	tex stub to include PS figur
   layout.uu                  1	xfig picture for document (uuencoded
!  redraw-protocol            8	widget-widget communication description
!  sample_prog.tex            6	sample_prog.c run through tgrind
   strcasecmp.c               1	strcasecmp() for systems without it
+  test.c                     5	wcl-based test driver program
   tgrind.sty                 3	LaTeX style file for use with tgrind'd file
+  patchlevel.h               0   Bookkeeping for comp.sources.x!
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:58 1991
--- Plot.c	Thu Sep 12 13:44:37 1991
***************
*** 179,191 ****
  #define Changed(field) (new->plot.field != current->plot.field)
       Boolean redraw = False;
       
!      if (Changed(background) ||
! 	 Changed(line_width) || Changed(line_style) || Changed(dash_length) ||
  	 Changed(fast_update)) {
  	  redraw = True;
       }
       
!      if (redraw || Changed(foreground)) {
  	  FreeGC(new);
  	  GetGC(new);
  	  if (redraw)
--- 179,190 ----
  #define Changed(field) (new->plot.field != current->plot.field)
       Boolean redraw = False;
       
!      if (Changed(line_width) || Changed(line_style) || Changed(dash_length) ||
  	 Changed(fast_update)) {
  	  redraw = True;
       }
       
!      if (redraw || Changed(background) || Changed(foreground)) {
  	  FreeGC(new);
  	  GetGC(new);
  	  if (redraw)
***************
*** 237,251 ****
       
       if (dl <= 0) dl = 1;
       dl2 = (dl + 1) >> 1;
       
       if (w->plot.line_width > 0)
  	  fprintf(fp, "%d setlinewidth ", w->plot.line_width);
       
       switch (w->plot.line_style) {
!      case LineOnOffDash:
  	  fprintf(fp, "[ %d ] 0 setdash\n", dl); 
  	  break;
!      case LineDoubleDash:
  	  fprintf(fp, "[ %d %d %d %d ] 0 setdash\n", dl, dl2, dl2, dl2);
  	  break; 
       default:
--- 236,251 ----
       
       if (dl <= 0) dl = 1;
       dl2 = (dl + 1) >> 1;
+      if (dl2 <= 0) dl2 = 1;
       
       if (w->plot.line_width > 0)
  	  fprintf(fp, "%d setlinewidth ", w->plot.line_width);
       
       switch (w->plot.line_style) {
!      case LineDoubleDash:
  	  fprintf(fp, "[ %d ] 0 setdash\n", dl); 
  	  break;
!      case LineOnOffDash:
  	  fprintf(fp, "[ %d %d %d %d ] 0 setdash\n", dl, dl2, dl2, dl2);
  	  break; 
       default:
*** /tmp/,RCSt1a17346	Mon Sep 16 18:02:59 1991
--- Plot.h	Fri Aug 23 10:26:19 1991
***************
*** 41,47 ****
  #ifdef _AtDevelopment_
  #include "Scale.h"
  #else
! #include <At/Scale.v>
  #endif 
  
  #define XtNlineWidth "lineWidth"
--- 41,47 ----
  #ifdef _AtDevelopment_
  #include "Scale.h"
  #else
! #include <At/Scale.h>
  #endif 
  
  #define XtNlineWidth "lineWidth"
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:00 1991
--- Plotter.c	Tue Sep 10 15:16:24 1991
***************
*** 350,356 ****
  
  static void Initialize P((AtPlotterWidget request,
  			  AtPlotterWidget new));
! static void Initialize (request, new)
  AtPlotterWidget request, new;
  {
       XGCValues gcv;
--- 350,356 ----
  
  static void Initialize P((AtPlotterWidget request,
  			  AtPlotterWidget new));
! static void Initialize(request, new)
  AtPlotterWidget request, new;
  {
       XGCValues gcv;
***************
*** 381,386 ****
--- 381,387 ----
       
       pp->rescale_required = pp->layout_required = pp->redraw_required = True;
       pp->expose_requested = True; /* Redraw will come from map */
+      pp->in_layout_mode = False;
       
       if (pp->xaxis) {
  	  XtCheckSubclass((Widget)pp->xaxis, atAxisCoreWidgetClass,
***************
*** 875,880 ****
--- 876,895 ----
       /* First, make a copy of the raw bounding box as a starting point. */
       obb = pw->plotter.bounding_box;
       pw->plotter.bounding_box = pw->plotter.raw_bounding_box;
+ 
+      /* Bad things happen when max=min, so make sure it aint so! */
+      if (bbp->xmax == bbp->xmin)
+ 	  if (bbp->xmax) bbp->xmax *= 1.01;
+ 	  else bbp->xmax = 1.0;
+      if (bbp->x2max == bbp->x2min)
+ 	  if (bbp->x2max) bbp->x2max *= 1.01;
+ 	  else bbp->x2max = 1.0;
+      if (bbp->ymax == bbp->ymin)
+ 	  if (bbp->ymax) bbp->ymax *= 1.01;
+ 	  else bbp->ymax = 1.0;
+      if (bbp->y2max == bbp->y2min)
+ 	  if (bbp->y2max) bbp->y2max *= 1.01;
+ 	  else bbp->y2max = 1.0;
       
       /*
        * Is there is some data plot depending on this axis, make sure
***************
*** 1025,1032 ****
       
       if (ev->send_event) region = NULL; /* Is Synthetic! */
       
!      /* If the event covers (nearly) the whole window, ignore the region
!       *      (for speed!) */
       if (region) {
  	  if (ev->x < 10 && ev->y < 10 && 
  	      ev->width > pw->core.width - 20 &&
--- 1040,1049 ----
       
       if (ev->send_event) region = NULL; /* Is Synthetic! */
       
!      /* 
!       * If the event covers (nearly) the whole window, ignore the region
!       * (for speed!)
!       */
       if (region) {
  	  if (ev->x < 10 && ev->y < 10 && 
  	      ev->width > pw->core.width - 20 &&
***************
*** 1037,1044 ****
  	  fprintf(stderr, "full refresh because of region + area\n");
  #endif 
       }
       
-      
       /* 
        * Come back to here if the length of an axis changed by > 25%
        * and the axis indicates tic_interval et al needs recalculating,
--- 1054,1068 ----
  	  fprintf(stderr, "full refresh because of region + area\n");
  #endif 
       }
+      /*
+       * if this is _NOT_ a synth event, then an expose might have come
+       * along at an interesting time, so we want to make SURE that we
+       * do a full refresh if this is a real expose event, even though
+       * partial refresh might be indicated.
+       */
+      if (ev->send_event) full_refresh = True;
+           
       
       /* 
        * Come back to here if the length of an axis changed by > 25%
        * and the axis indicates tic_interval et al needs recalculating,
***************
*** 1047,1053 ****
        * number width has changed).
        */ 
   recalc_again:
!      pp->in_layout_mode = True;
       
       if (pp->rescale_required) {
  	  numbers_moved |= DecideAxisValues(pw);
--- 1071,1077 ----
        * number width has changed).
        */ 
   recalc_again:
!      pp->in_layout_mode = True;	/* This avoids infinite loops.  I hope. */
       
       if (pp->rescale_required) {
  	  numbers_moved |= DecideAxisValues(pw);
***************
*** 1540,1545 ****
--- 1564,1570 ----
       GetLegendText(c, p);
       c->plotter.bounding_box = default_bounding_box;
       c->plotter.extended_list = NULL;
+      c->plotter.needs_refresh = False;
  }
  
  
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:01 1991
--- Plotter.h	Wed Sep 11 11:51:12 1991
***************
*** 127,135 ****
  #endif 
  
  
! void AtPlotterGeneratePostscript P((char *, AtPlotterWidget, char *,
! 				    int, int, int, int, int landscape));
  extern void AtPlotterDrawPS P((FILE *, AtPlotterWidget, int, int, int, int));
  
  /*
   * These functions are for the plot children to communicate with the parent
--- 127,136 ----
  #endif 
  
  
! extern void AtPlotterGeneratePostscript P((char *, AtPlotterWidget, char *,
! 					   int, int, int, int, int landscape));
  extern void AtPlotterDrawPS P((FILE *, AtPlotterWidget, int, int, int, int));
+ extern void AtPlotterWritePostscriptProcSet P((FILE *)); 
  
  /*
   * These functions are for the plot children to communicate with the parent
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:01 1991
--- PlotterPS.c	Wed Sep 11 12:59:26 1991
***************
*** 102,108 ****
       int i;
       AtText *t;
       
!      fprintf(f, "%%%%BeginObject: AtPlotter legend\nGS\n");
       
       h = height(w->plotter.legend_title_text) + w->plotter.margin_height;
       for(i=0; i < NUMCHILDREN(w); i++) {
--- 102,108 ----
       int i;
       AtText *t;
       
!      fputs("%%BeginObject: AtPlotter legend\nGS\n", f);
       
       h = height(w->plotter.legend_title_text) + w->plotter.margin_height;
       for(i=0; i < NUMCHILDREN(w); i++) {
***************
*** 129,135 ****
  	  }
       }
       
!      fprintf(f, "GR\n%%%%EndObject AtPlotter legend\n");
  }    
  #undef height
  
--- 129,135 ----
  	  }
       }
       
!      fputs("GR\n%%EndObject AtPlotter legend\n", f);
  }    
  #undef height
  
***************
*** 148,154 ****
       double min, max;
       AtScale *xs, *ys;
       
!      fprintf(f, "%%%% BeginObject: AtPlotter\nGS\n");
       
       x1 = xll;
       y1 = yll;
--- 148,154 ----
       double min, max;
       AtScale *xs, *ys;
       
!      fputs("%%BeginObject: AtPlotter\nGS\n", f);
       
       x1 = xll;
       y1 = yll;
***************
*** 277,287 ****
       }
       
       /* finish up */
!      fprintf(f, "GR\n%%%%EndObject AtPlotter\n");
  }
  
  static char prolog[] =
! "/F {findfont exch scalefont setfont} bind def\n\
  /S {moveto show} bind def\n\
  /L {lineto} bind def\n\
  /M {moveto} bind def\n\
--- 277,288 ----
       }
       
       /* finish up */
!      fputs("GR\n%%EndObject AtPlotter\n", f);
  }
  
  static char prolog[] =
! "%%BeginProcSet: AthenaToolsPlotter 5 0\n\
! /F {findfont exch scalefont setfont} bind def\n\
  /S {moveto show} bind def\n\
  /L {lineto} bind def\n\
  /M {moveto} bind def\n\
***************
*** 299,306 ****
  /STA { M 0 4 RM 0 -8 RL 4 4 RM -8 0 RL\n\
         1.17 2.83 RM 5.66 -5.66 RL 0 5.66 RM -5.66 -5.66 RL ST} bind def\n\
  /DIA {M 0 5.66 RM 5.66 -5.66 RL -5.66 -5.66 RL -5.66 5.66 RL CP ST} bind def\n\
! /DOT { 1 0 360 arc fill} bind def\n";
!     
  #include <sys/types.h>
  #ifndef VMS
  #include <pwd.h>
--- 300,314 ----
  /STA { M 0 4 RM 0 -8 RL 4 4 RM -8 0 RL\n\
         1.17 2.83 RM 5.66 -5.66 RL 0 5.66 RM -5.66 -5.66 RL ST} bind def\n\
  /DIA {M 0 5.66 RM 5.66 -5.66 RL -5.66 -5.66 RL -5.66 5.66 RL CP ST} bind def\n\
! /DOT { 1 0 360 arc fill} bind def\n\
! %%EndProcSet\n";
! 
! void AtPlotterWritePostscriptProcSet(fp)
! FILE *fp;
! {
!      fputs(prolog, fp);
! }
! 
  #include <sys/types.h>
  #ifndef VMS
  #include <pwd.h>
***************
*** 333,341 ****
  #endif
       
       /* do header info */
!      fprintf(f,"%%!PS-Adobe-2.0\n");
!      fprintf(f,"%%%%Title: %s\n", title);
!      fprintf(f,"%%%%Creator: the Athena Tools plotter widget\n");
       fprintf(f,"%%%%CreationDate: %s",asctime(localtime(&now)));
  #ifndef VMS
       fprintf(f,"%%%%For: %s\n", getpwuid(getuid())->pw_name);
--- 341,350 ----
  #endif
       
       /* do header info */
!      fputs("%!PS-Adobe-2.0 ESPF-2.0\n", f);
!      /* NB: printf needs % doubled!!! */
!      fprintf(f, "%%%%Title: %s\n", title);
!      fputs("%%Creator: the Athena Tools plotter widget, version 5\n", f);
       fprintf(f,"%%%%CreationDate: %s",asctime(localtime(&now)));
  #ifndef VMS
       fprintf(f,"%%%%For: %s\n", getpwuid(getuid())->pw_name);
***************
*** 343,365 ****
       fprintf(f, "%%%%For: %s\n", cuserid(user_name));
  #endif
       fprintf(f,"%%%%BoundingBox: %d %d %d %d\n", x1, y1, x2, y2);
!      fprintf(f,"%%%%Pages: 1\n");
!      fprintf(f,"%%%%EndComments\n");
       
       /* do prolog */
!      fprintf(f, prolog);
!      fprintf(f, "%%%%EndProlog\n");
       
       if (landscape) {
! 	  
! 	  fprintf(f, "90 rotate\n");
! 	  fprintf(f, "0 -612 translate\n");
       }
       /* do the body of the postscript */
       AtPlotterDrawPS(f, w, x1, y1, x2, y2);
       
       /* finish up */
!      fprintf(f, "showpage\n");
       
       fclose(f);
       *RCSid = *RCSid; 
--- 352,377 ----
       fprintf(f, "%%%%For: %s\n", cuserid(user_name));
  #endif
       fprintf(f,"%%%%BoundingBox: %d %d %d %d\n", x1, y1, x2, y2);
!      fputs("%%Pages: 1\n", f);
!      fputs("%%DocumentSuppliedProcSets: AthenaToolsPlotter 5 0\n", f); 
!      fputs("%%DocumentProcSets: AthenaToolsPlotter 5 0\n", f);
!      fputs("%%DocumentFonts: (atend)\n", f); 
!      fputs("%%EndComments\n", f);
       
       /* do prolog */
!      fputs(prolog, f);
!      fputs("%%EndProlog\n", f);
       
       if (landscape) {
! 	  fputs("%%BeginSetup\n90 rotate\n0 -612 translate\n%%EndSetup\n", f);
       }
       /* do the body of the postscript */
+      AtTextStartFontCollection(); 
       AtPlotterDrawPS(f, w, x1, y1, x2, y2);
       
       /* finish up */
!      fputs("showpage\n%%Trailer:\n%%DocumentFonts:", f);
!      AtTextEndFontCollection(f);
       
       fclose(f);
       *RCSid = *RCSid; 
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:02 1991
--- Test.ad	Thu Sep 12 14:35:28 1991
***************
*** 33,41 ****
  !
  *plot.wcClassName:	AtPlotter
  *plot.wcCallback:	AttachDataCB(plot)
! *plot.wcChildren:	xaxis, x2axis, yaxis, y2axis, a, b, text
  *plot.title:		Plotter Widget Test
  *plot.fontFamily:	helvetica
  *plot.titleColor:	purple
  *plot.titleStyle:	BoldItalic
  *plot.yaxis.displayed:	False
--- 33,42 ----
  !
  *plot.wcClassName:	AtPlotter
  *plot.wcCallback:	AttachDataCB(plot)
! *plot.wcChildren:	xaxis, x2axis, yaxis, y2axis, a, b, text, text2
  *plot.title:		Plotter Widget Test
  *plot.fontFamily:	helvetica
+ *plot.legendTitleStyle: bold
  *plot.titleColor:	purple
  *plot.titleStyle:	BoldItalic
  *plot.yaxis.displayed:	False
***************
*** 88,98 ****
  *AtPlotter*wcManaged:	False
  *AtPlotter.wcManaged:	True
  
  !!!!!!!!!!!!!!!!!
  !
  ! The actual plot elements
  !
! *a.wcClassName:		AtBarPlot
  *a.wcCallback:		AttachDataCB(a)
  *a.foreground:		red
  *a.legendName:		Plot A
--- 89,104 ----
  *AtPlotter*wcManaged:	False
  *AtPlotter.wcManaged:	True
  
+ *AtLinePlot.background:	puce
+ *AtLinePlot.dashLength:	10
+ 
  !!!!!!!!!!!!!!!!!
  !
  ! The actual plot elements
  !
! !*a.wcClassName:		AtBarPlot
! *a.wcClassName:		AtLinePlot
! *a.lineStyle:		LineOnOffDash
  *a.wcCallback:		AttachDataCB(a)
  *a.foreground:		red
  *a.legendName:		Plot A
***************
*** 103,108 ****
--- 109,115 ----
  *a.useY2Axis:		True
  
  *b.wcClassName:		AtLinePlot
+ *b.lineStyle:		LineDoubleDash
  *b.wcCallback:		AttachDataCB(b)
  *b.foreground:		green
  *b.legendName:		Plot B
***************
*** 111,116 ****
--- 118,125 ----
  
  *text.wcClassName:	AtTextPlot
  *text.label:		@leftarrow This is 10, 1000
+ *text.fontFamily:	times
+ *text.fontStyle:	bolditalic
  *text.Foreground:	Purple
  *text.floatingPosition:	True
  *text.floatingX:	10
***************
*** 117,122 ****
--- 126,142 ----
  *text.floatingY:	1000
  *text.useY2Axis:	True
  *text.justify:		LEFT
+ 
+ *text2.wcClassName:	AtTextPlot
+ *text2.label:		@leftarrow This is pixel 100, 100
+ *text2.fontFamily:	Courier
+ *text2.fontStyle:	bolditalic
+ *text2.Foreground:	Yellow
+ *text2.floatingPosition:	False
+ *text2.x:		100
+ *text2.y:		100
+ *text2.useY2Axis:	True
+ *text2.justify:		LEFT
  
  ! The buttons
  
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:03 1991
--- Text.h	Wed Sep 11 11:49:35 1991
***************
*** 117,120 ****
--- 117,124 ----
  extern int AtTextPSDescent P((AtText *));
  extern void AtTextPSDraw P((FILE *, AtText *, int, int));
  extern void AtTextWritePostscriptProlog P((FILE *));
+ 
+ extern void AtTextStartFontCollection P((void));
+ extern void AtTextEndFontCollection P((FILE *));
+ 
  #endif
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:03 1991
--- TextPS.c	Wed Sep 11 13:14:48 1991
***************
*** 243,249 ****
--- 243,341 ----
      to[j] = '\0';
  }
  
+ /*
+  * This is a pretty ugly hack that allows us to collect the list of
+  * fonts used and then print them out at the end in a form like:
+  * 	%%DocumentFonts: font1 font2 font2
+  * This is for the structured PostScript/EPSF requirements.
+  *
+  * This can get ugly is the start routine is called twice....
+  *
+  * Need to be called in start/end pairs due or memory leaks will occur.
+  *
+  * The first element on the list is a sentinal and is not a valid font
+  * list (used to distinguish an empty list from a not-collecting list).
+  */
  
+ struct font_info {
+      char *name;
+      struct font_info *next;
+ };
+ 
+ static struct font_info *font_list = NULL;
+ 
+ /*
+  * Start the collecting by adding an empty struct to the start of the list
+  */
+ void AtTextStartFontCollection()
+ {
+      struct font_info *new;
+ 
+      if (font_list) return;
+      
+      new = (struct font_info *)XtMalloc(sizeof (struct font_info));
+      new->name = NULL;
+      new->next = NULL;
+      font_list = new; 
+ }
+ 
+ /*
+  * Assume the application has written the header (e.g.
+  * "%%DocumentFonts: ", we write a list of fonts, with "\n%%+ " if the
+  * line length is too long!  Then we delete everything.
+  */
+ void AtTextEndFontCollection(fp)
+ FILE *fp;
+ {
+      int len = 0;
+      struct font_info *p = font_list, *old_p = p;
+ 
+      if (p) {			/* skip empty sentinal record */
+ 	  p = p->next;
+ 	  XtFree(old_p);
+      }
+ 
+      while (p) {
+ 	  if (len > 60) {
+ 	       fputs("\n%%+", fp);
+ 	       len = 0;
+ 	  }
+ 	  fprintf(fp, " %s", p->name);
+ 	  len += strlen(p->name);
+ 	  
+ 	  old_p = p;
+ 	  p = p->next;
+ 	  XtFree((char *)old_p);
+      }
+      
+      fputs("\n", fp);
+      font_list = NULL;
+ }
+ 
+ /*
+  * Add the named font to the list (if it doesn't exist!)
+  */
+ static void add_font P((char *));
+ static void add_font(fname)
+ char *fname;
+ {
+      struct font_info *new, *p = font_list;
+      
+      if (!p) return;
+ 
+      p = p->next;		/* skip sentinal */
+      
+      while (p) {
+ 	  if (strcmp(p->name, fname) == 0) return;
+ 	  p = p->next;
+      }
+      /* New one if we got here, insert after sentinal but before rest */
+      new = (struct font_info *)XtMalloc(sizeof (struct font_info));
+      new->name = fname;
+      new->next = font_list->next;
+      font_list->next = new;
+ }
+ 
  static void psdraw P((FILE *f, AtText *t, int x, int y)); 
  static void psdraw(f, t, x, y)
  FILE *f;
***************
*** 275,280 ****
--- 367,373 ----
  		    fmt->font, tok->code,
  		    x, y+fmt->baseline);
  	    x += fmt->width;
+ 	    if (font_list) add_font(fmt->font); 
  	    break;
  	    
  	case STRING:
***************
*** 284,289 ****
--- 377,383 ----
  		    fmt->font, buf,
  		    x, y+fmt->baseline);
  	    x += fmt->width;
+ 	    if (font_list) add_font(fmt->font); 
  	    break;
  	    
  	case START_OF_STRING:
***************
*** 344,350 ****
  {
    static char prolog[] =
      "/F {findfont exch scalefont setfont} bind def\n\
!      /S {moveto show} bind def\n";
  
      fprintf(f, prolog);
      *RCSid = *RCSid;		/* Keep gcc quiet */
--- 438,445 ----
  {
    static char prolog[] =
      "/F {findfont exch scalefont setfont} bind def\n\
!      /S {moveto show} bind def\n\
!      /GS {gsave} bind def /GR {grestore} bind def\n";
  
      fprintf(f, prolog);
      *RCSid = *RCSid;		/* Keep gcc quiet */
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:04 1991
--- TextPlot.c	Wed Sep 11 13:11:47 1991
***************
*** 324,330 ****
  	  x -= - AtTextPSWidth(p->label_text);
  	  break;
       }
!      
       AtTextPSDraw(f, p->label_text, x, y);
  }
  
--- 324,331 ----
  	  x -= - AtTextPSWidth(p->label_text);
  	  break;
       }
!      fputs("%%BeginObject: AtTextPlot\n", f); 
       AtTextPSDraw(f, p->label_text, x, y);
+      fputs("%%EndObject AtTextPlot\n", f); 
  }
  
*** /tmp/,RCSt1a17346	Mon Sep 16 18:03:05 1991
--- ToDo	Wed Sep 11 13:14:27 1991
***************
*** 25,34 ****
  - Do the log axis (A subclass of AtAxis that uses the AtAxis code for
    the linear stuff).
  
- - Do a hi/lo/last error plot type based on expanded SPlot.
- 
  - Have legend on either side (or top or bottom).
  
  - Provide set_values_hook to simulate old usage of XtNxPoints et al.
  
  - Document the internals, specifically writing new widgets.
--- 25,34 ----
  - Do the log axis (A subclass of AtAxis that uses the AtAxis code for
    the linear stuff).
  
  - Have legend on either side (or top or bottom).
  
  - Provide set_values_hook to simulate old usage of XtNxPoints et al.
  
  - Document the internals, specifically writing new widgets.
+ 
+ - Have a stab at color postscript code.
