Index: /branches/eam_branches/ohana.20190329/src/kapa2/include/prototypes.h
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/include/prototypes.h	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/include/prototypes.h	(revision 40731)
@@ -85,4 +85,5 @@
 int           SetColormapFromPipe PROTO((int sock));
 int           SetNanColorFromPipe PROTO((int sock));
+int           SetSmoothSigma      PROTO((int sock));
 
 int           LoadVectorData      PROTO((int sock, KapaGraphWidget *graph, int N, char *type));
@@ -179,4 +180,5 @@
 void          InitButtonFunc      PROTO((Button *button, int (*function)(Graphic *graphic, KapaImageWidget *image)));
 void          DrawImage           PROTO((KapaImageWidget *image));
+void          DrawImageTool       PROTO((KapaImageWidget *image));
 void          DrawButton          PROTO((Graphic *graphic, Button *button));
 void          DrawBitmap          PROTO((Graphic *graphic, int x, int y, int dx, int dy, unsigned char *bitmap, int mode));
Index: /branches/eam_branches/ohana.20190329/src/kapa2/include/structures.h
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/include/structures.h	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/include/structures.h	(revision 40731)
@@ -48,4 +48,6 @@
   unsigned long  back;	      // basic background color
 
+  float smooth_sigma; // anti-aliasing smoothing scale
+
   unsigned long  overlay_color[NOVERLAYS]; // image plotting colors 
 } Graphic;
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/CheckPipe.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/CheckPipe.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/CheckPipe.c	(revision 40731)
@@ -352,4 +352,10 @@
   }
 
+  if (!strcmp (word, "SIGM")) {
+    SetSmoothSigma (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+
   fprintf (stderr, "unknown signal %s\n", word);
   KiiSendCommand (sock, 4, "DONE");
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/Image.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/Image.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/Image.c	(revision 40731)
@@ -148,4 +148,21 @@
 void DrawImage (KapaImageWidget *image) {
 
+  Graphic *graphic;
+
+  if (image == NULL) return;
+
+  graphic = GetGraphic ();
+
+  if (image[0].picture.pix) {
+    XPutImage (graphic[0].display, graphic[0].window, graphic[0].gc,
+	       image[0].picture.pix, 0, 0, 
+	       image[0].picture.x + 1, image[0].picture.y + 1, 
+	       image[0].picture.dx, image[0].picture.dy);
+  }
+}
+
+// add the zoom, pan, crosshairs, status box, buttons
+void DrawImageTool (KapaImageWidget *image) {
+
   int i;
   Graphic *graphic;
@@ -160,17 +177,4 @@
 		  image[0].picture.dx+1, image[0].picture.dy+1);
   
-  if (image[0].picture.pix) {
-    XPutImage (graphic[0].display, graphic[0].window, graphic[0].gc,
-	       image[0].picture.pix, 0, 0, 
-	       image[0].picture.x + 1, image[0].picture.y + 1, 
-	       image[0].picture.dx, image[0].picture.dy);
-  }
-
-  for (i = 0; i < NOVERLAYS; i++) {
-    if (image[0].overlay[i].active) {
-      PaintOverlay (graphic, image, i);
-    }
-  }
-
   if (image[0].location) {
     if (image[0].cmapbar.pix) {
@@ -211,6 +215,4 @@
     StatusBox (graphic, image);
   }
-
-  FlushDisplay ();
 }
 
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/LoadFrame.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/LoadFrame.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/LoadFrame.c	(revision 40731)
@@ -93,20 +93,4 @@
   SetSectionSizes (section);
   Refresh();
-  // if (USE_XWINDOW) DrawFrame (graph);
-  // FlushDisplay ();
-
-  /* XXX why did I do this??? */
-# if (0)
-  status = TRUE;
-  if (status) {
-    for (i = 0; i < Nsection; i++) {
-      PositionPicture (&section[i]);
-    }
-    if (USE_XWINDOW) XClearWindow (graphic.display, graphic.window);
-    Refresh ();
-  } else {
-    FlushDisplay ();
-  } 
-# endif
 
   return (TRUE);
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/LoadObject.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/LoadObject.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/LoadObject.c	(revision 40731)
@@ -103,8 +103,13 @@
 
   if (USE_XWINDOW) {
-    Graphic *graphic = GetGraphic();
-    DrawObjectN (graphic, graph, &graph[0].objects[graph[0].Nobjects-1]);
-  }
-  FlushDisplay ();
+    if (0) {
+      // use this if we are not using buffered plotting
+      Graphic *graphic = GetGraphic();
+      DrawObjectN (graphic, graph, &graph[0].objects[graph[0].Nobjects-1]);
+      FlushDisplay ();
+    } else {
+      Refresh ();
+    }
+  }
 
   return (TRUE);
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/PNGit.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/PNGit.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/PNGit.c	(revision 40731)
@@ -98,4 +98,9 @@
   png_write_info (png_ptr, info_ptr);
 
+  if (graphic->smooth_sigma == 0.0) {
+    fprintf (stderr, "making PNG without antialias smoothing\n");
+    fprintf (stderr, "use 'antialias (value)' to set smoothing scale (0.4 - 0.7 recommended)\n");
+  }
+    
   if (haveImage) {
     buffer = bDrawIt (palette, Npalette, 3);
@@ -109,4 +114,6 @@
   
   bDrawBufferFree (buffer);
+  free (palette);
+  
   fclose (f);
   return (TRUE);
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/Refresh.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/Refresh.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/Refresh.c	(revision 40731)
@@ -1,5 +1,48 @@
 # include "Ximage.h"
 
+void bDrawXimage (bDrawBuffer *buffer);
+void Refresh_Buffered (void);
+void Refresh_Unbuffered (void);
+
 void Refresh (void) {
+  Refresh_Buffered();
+}
+
+void Refresh_Buffered (void) {
+
+  int Npalette;
+  Graphic *graphic;
+
+  if (!USE_XWINDOW) return;
+  // if (HAVE_BACKING) return;
+
+  graphic = GetGraphic();
+  
+  // limit the png window to the min needed to contain the active graphic regions
+  SectionMinBoundary (graphic);
+
+  // is the palette reasonable in modern context?
+  png_color *palette = KapaPNGPalette (&Npalette);
+
+  bDrawBuffer *buffer = bDrawIt (palette, Npalette, 3);
+  
+  /* XClearWindow   (graphic.display, graphic.window); */
+  XSetForeground (graphic->display, graphic->gc, graphic->back);
+  XFillRectangle (graphic->display, graphic->window, graphic->gc, 0, 0, graphic->dx, graphic->dy);
+  XSetForeground (graphic->display, graphic->gc, graphic->fore);
+  
+  // copy buffer to Xwindow as image?
+  bDrawXimage (buffer);
+
+  // draw image tool for all sections
+  int Nsection = GetNumberOfSections ();
+  for (int i = 0; i < Nsection; i++) {
+    Section *section = GetSectionByNumber (i);
+    DrawImageTool (section->image);
+  }
+  FlushDisplay ();
+}
+
+void Refresh_Unbuffered (void) {
 
   int i, Nsection;
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/SetUpGraphic.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/SetUpGraphic.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/SetUpGraphic.c	(revision 40731)
@@ -51,4 +51,5 @@
   CheckColors (graphic, argc, argv);
 
+  graphic->smooth_sigma = 0.0;
 
   icon.width = icon_width;
@@ -84,2 +85,14 @@
 }
 
+int SetSmoothSigma (int sock) {
+
+  float sigma;
+  KiiScanMessage (sock, "%f", &sigma);
+
+  if (isfinite(sigma)) {
+    if ((sigma < 10.0) && (sigma >= 0.0)) {
+      graphic->smooth_sigma = sigma;
+    }
+  }
+  return TRUE;
+}
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawImage.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawImage.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawImage.c	(revision 40731)
@@ -1,3 +1,6 @@
 # include "Ximage.h"
+
+// XXX for the moment, this function does NOT set the mask bits.
+// since we lay graphics on top of images, this is OK for now
 
 # define WHITE_R 255
@@ -54,10 +57,18 @@
 
   // the created buffer is supposed to contain the output windows
+  if (Xs < 0) {
+    fprintf (stderr, "image display boundaries out of range of window (invalid condition) : fix Kapa\n");
+    abort();
+  }
   if (buffer[0].Nx < Xs + dx) {
-    fprintf (stderr, "invalid condition\n");
+    fprintf (stderr, "image display boundaries out of range of window (invalid condition) : fix Kapa\n");
+    abort();
+  }
+  if (Ys < 0) {
+    fprintf (stderr, "image display boundaries out of range of window (invalid condition) : fix Kapa\n");
     abort();
   }
   if (buffer[0].Ny < Ys + dy) {
-    fprintf (stderr, "invalid condition\n");
+    fprintf (stderr, "image display boundaries out of range of window (invalid condition) : fix Kapa\n");
     abort();
   }
@@ -153,4 +164,25 @@
 
   return (TRUE);
+}
+
+void bDrawXimage (bDrawBuffer *buffer) {
+
+  Graphic *graphic = GetGraphic ();
+
+  ALLOCATE_PTR (data, char, 4*buffer->Nx*buffer->Ny);
+
+  for (int iy = 0; iy < buffer->Ny; iy++) {
+    for (int ix = 0; ix < buffer->Nx; ix++) {
+      data[4*(iy*buffer->Nx + ix) + 0] = buffer->pixels[iy][3*ix + 2];
+      data[4*(iy*buffer->Nx + ix) + 1] = buffer->pixels[iy][3*ix + 1];
+      data[4*(iy*buffer->Nx + ix) + 2] = buffer->pixels[iy][3*ix + 0];
+      data[4*(iy*buffer->Nx + ix) + 3] = 0;
+    }
+  }
+
+  XImage *pix = XCreateImage (graphic[0].display, graphic[0].visual, graphic[0].depth, ZPixmap, 0, 
+			      data, buffer->Nx, buffer->Ny, 32, 0);
+
+  XPutImage (graphic[0].display, graphic[0].window, graphic[0].gc, pix, 0, 0, 1, 1, buffer->Nx, buffer->Ny);
 }
 
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawIt.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawIt.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawIt.c	(revision 40731)
@@ -3,31 +3,45 @@
 bDrawBuffer *bDrawIt (png_color *palette, int Npalette, int Nbyte) {
 
-  int i, j, Nsection;
-  bDrawBuffer *buffer;
-  bDrawColor black;
-  Graphic *graphic;
-  Section *section;
+  Graphic *graphic = GetGraphic();
+  bDrawColor black = KapaColorByName ("black");
 
-  graphic = GetGraphic();
+  // get the number of sections
+  int Nsection = GetNumberOfSections ();
 
-  black = KapaColorByName ("black");
+  // in order to allow the anti-aliasing to affect the text & graphs but not the images
+  // I need to generate the images in one buffer and the graphs in a second buffer
+  // then merge the two buffers.
 
-  // if we want to trim, we'll need to carry about the start in graphic coords and
-  // the dx,dy size.  
-  buffer = bDrawBufferCreate (graphic->dxwin, graphic->dywin, Nbyte, palette, Npalette);
-  bDrawSetStyle (buffer, black, 0, 0, 1.0);
+  // base will hold the images
+  bDrawBuffer *base = bDrawBufferCreate (graphic->dxwin, graphic->dywin, Nbyte, palette, Npalette);
+  bDrawSetStyle (base, black, 0, 0, 1.0);
   
-  // reset the sizes for all sections
-  Nsection = GetNumberOfSections ();
-  for (i = 0; i < Nsection; i++) {
-      section = GetSectionByNumber (i);
-      bDrawImage (buffer, section->image, graphic);
-      for (j = 0; section->image && (j < NOVERLAYS); j++) {
-	if (section->image->overlay[j].active) bDrawOverlay (buffer, section->image, j);
-      }
-      bDrawGraph (buffer, section->graph);
+  for (int i = 0; i < Nsection; i++) {
+    Section *section = GetSectionByNumber (i);
+    bDrawImage (base, section->image, graphic);
   }
 
-  return (buffer);
+  // graph will hold the graphic overlay
+  bDrawBuffer *graph = bDrawBufferCreate (graphic->dxwin, graphic->dywin, Nbyte, palette, Npalette);
+  bDrawSetStyle (graph, black, 0, 0, 1.0);
+
+  for (int i = 0; i < Nsection; i++) {
+    Section *section = GetSectionByNumber (i);
+    for (int j = 0; section->image && (j < NOVERLAYS); j++) {
+      if (section->image->overlay[j].active) bDrawOverlay (graph, section->image, j);
+    }
+    bDrawGraph (graph, section->graph);
+  }
+
+  // apply anti-aliasing only to the graph
+  if (graphic->smooth_sigma > 0.0) {
+    bDrawSmooth (graph, graphic->smooth_sigma);
+  }
+  
+  // place graph on base
+  bDrawMerge (base, graph);
+  bDrawBufferFree (graph);
+
+  return (base);
 }
 
Index: /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawObjects.c
===================================================================
--- /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawObjects.c	(revision 40730)
+++ /branches/eam_branches/ohana.20190329/src/kapa2/src/bDrawObjects.c	(revision 40731)
@@ -9,4 +9,6 @@
 # define OpenTriangle(BUF,X1,Y1,X2,Y2,X3,Y3) (bDrawTriOpen (BUF, (X1), (Y1), (X2), (Y2), (X3), (Y3)))
 
+// I should not have a local static variable for this:
+// I should just pass the graphic structure to the called functions below
 static Graphic *graphic;
 
