Index: /trunk/Ohana/src/kapa2/Makefile
===================================================================
--- /trunk/Ohana/src/kapa2/Makefile	(revision 41156)
+++ /trunk/Ohana/src/kapa2/Makefile	(revision 41157)
@@ -42,5 +42,5 @@
 $(SRC)/bDrawObjects.$(ARCH).o	  	  $(SRC)/bDrawFrame.$(ARCH).o         \
 $(SRC)/bDrawLabels.$(ARCH).o              $(SRC)/bDrawIt.$(ARCH).o            \
-$(SRC)/bDrawImage.$(ARCH).o               \
+$(SRC)/bDrawImage.$(ARCH).o               $(SRC)/MemoryDump.$(ARCH).o	      \
 $(SRC)/PNGit.$(ARCH).o                    $(SRC)/PPMit.$(ARCH).o	      \
 $(SRC)/PSit.$(ARCH).o                     $(SRC)/CrossHairs.$(ARCH).o         \
Index: /trunk/Ohana/src/kapa2/doc/outline.txt
===================================================================
--- /trunk/Ohana/src/kapa2/doc/outline.txt	(revision 41157)
+++ /trunk/Ohana/src/kapa2/doc/outline.txt	(revision 41157)
@@ -0,0 +1,38 @@
+
+This document outlines the way kapa works.
+
+Top-Level (kapa.c):
+
+  * load arguments
+  * generate basic graphic structure (SetUpGraphic)
+    * this is held static by SetUpGraphic.c
+    * it currently does not carry all elements: sections are static elsewhere
+    * Graphic elements are a bit X-centric. 
+  * generate basic window elements (InitLayout / Layout.c)
+  * run event loop
+
+Event Loop:
+
+  * check pipe for messages
+  * in X context, check for various events (cursor interations, resizing, moving, raising)
+
+In X context, events which expose or reconfigure the window trigger Refresh().
+
+In non-X context:
+ * PNGit & JPEGit trigger bDrawIt (equivalent to Refresh)
+ * PSit is equivalent to bDrawIt
+
+------
+
+I would like to change from native X to native bDraw functions.  This
+would allow for opacity and anti-aliasing.  To do this, I need to do
+the following:
+
+* bDraw operations need to include a mask so we can distinguish layers
+  (e.g., text on image).  anti-aliasing needs to be applied to text
+  and graph elements, but not to the images
+
+* Refresh currently calls DrawImage with generates both the main image
+  as well as the extra elements: colorbar, zoom window, pan window,
+  buttons.
+
Index: /trunk/Ohana/src/kapa2/include/prototypes.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 41156)
+++ /trunk/Ohana/src/kapa2/include/prototypes.h	(revision 41157)
@@ -3,7 +3,13 @@
 int	      args		  PROTO((int *argc, char **argv));
 void          SetUpGraphic        PROTO((int *argc, char **argv));
+void          FreeGraphic         PROTO((void));
 void          DefineLayout        PROTO((int, char **));
 int	      EventLoop		  PROTO((void));
 void	      CloseDisplay	  PROTO((void));
+int           MemoryDump          PROTO((int sock));
+int           MemoryDumpLines     PROTO((int sock));
+int           MemoryDumpOnExit    PROTO((int sock));
+int           MemoryDumpSetOnExit PROTO((int state));
+int           MemoryDumpAndExit   PROTO((void));
 
 /* SetUpGraphic */
@@ -33,4 +39,6 @@
 void	      DrawTextlines	  PROTO((KapaGraphWidget *graph));
 void          DrawConnect         PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
+void          DrawPolygon         PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
+void          DrawPolyfill        PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
 void          DrawHistogram       PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
 int           DrawObjectN         PROTO((Graphic *graphic, KapaGraphWidget *graph, Gobjects *objects));
@@ -85,4 +93,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));
@@ -109,4 +118,5 @@
 
 void          InitLayout          PROTO((int argc, char **argv));
+void          FreeLayout          PROTO((void));
 
 /* PS drawing utilities */
@@ -142,4 +152,6 @@
 void          bDrawBars           PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object, int mode));
 void	      bDrawPoints	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
+void	      bDrawPolygons	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
+void	      bDrawFillPolygons	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
 void	      bDrawXErrors	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
 void	      bDrawYErrors	  PROTO((bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object));
@@ -179,4 +191,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: /trunk/Ohana/src/kapa2/include/structures.h
===================================================================
--- /trunk/Ohana/src/kapa2/include/structures.h	(revision 41156)
+++ /trunk/Ohana/src/kapa2/include/structures.h	(revision 41157)
@@ -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;
@@ -131,9 +133,23 @@
 } Overlay;
   
-typedef struct {
-  float *x, *y, *z, *dxp, *dxm, *dyp, *dym;
-  int Npts;
-  int style, ptype, ltype, color, etype, ebar;
-  double lweight, size;
+// a set of objects all have the same basic properties
+typedef struct {
+  float *x; // x-coordinates of the points
+  float *y; // y-coordinates of the points
+  float *z; // size/colorscale for points
+  float *dxp; // lower-errorbar in x
+  float *dxm; // upper-errorbar in x
+  float *dyp; // lower-errorbar in y
+  float *dym; // upper-errorbar in y
+  int Npts;   // number of points in this set
+  int style;  // how are the object draw: CONNECT, HISTOGRAM,
+  int ptype;  // shape of object at each point
+  // ptype is overloaded for NPOLYGON to be the number of points / polygon
+  int ltype;  // style of line (solid, dot, dash, etc)
+  int color;  // color for point (if not colorscaled)
+  int etype;  // errorbars to draw (0x01 = y, 0x02 = x)
+  int ebar;   // draw a cap on the error bar
+  double lweight; // line thickness
+  double size; // size of the object
   double x0, x1, y0, y1;  /* limits for this object */
   double alpha;
Index: /trunk/Ohana/src/kapa2/src/CheckPipe.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/CheckPipe.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/CheckPipe.c	(revision 41157)
@@ -352,4 +352,28 @@
   }
 
+  if (!strcmp (word, "SIGM")) {
+    SetSmoothSigma (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+
+  if (!strcmp (word, "MEMD")) {
+    MemoryDump (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+
+  if (!strcmp (word, "MEML")) {
+    MemoryDumpLines (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+
+  if (!strcmp (word, "MEMX")) {
+    MemoryDumpOnExit (sock);
+    KiiSendCommand (sock, 4, "DONE");
+    FINISHED (TRUE);
+  }
+
   fprintf (stderr, "unknown signal %s\n", word);
   KiiSendCommand (sock, 4, "DONE");
Index: /trunk/Ohana/src/kapa2/src/DrawObjects.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/DrawObjects.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/DrawObjects.c	(revision 41157)
@@ -97,26 +97,26 @@
   switch (object[0].style) {
     case KAPA_PLOT_CONNECT: 
-      // fprintf (stderr, "plot KAPA_PLOT_CONNECT: \n");
       DrawConnect (graphic, graph, object);
       break;
+    case KAPA_PLOT_POLYGON: 
+      DrawPolygon (graphic, graph, object);
+      break;
+    case KAPA_PLOT_POLYFILL: 
+      DrawPolyfill (graphic, graph, object);
+      break;
     case KAPA_PLOT_HISTOGRAM:
-      // fprintf (stderr, "plot KAPA_PLOT_HISTOGRAM:\n");
       DrawHistogram (graphic, graph, object);
       break;
     case KAPA_PLOT_BARS_SOLID:
-      // fprintf (stderr, "plot KAPA_PLOT_BARS_SOLID:\n");
       DrawBars (graphic, graph, object, KAPA_PLOT_BARS_SOLID);
       break;
     case KAPA_PLOT_BARS_OUTLINE:
-      // fprintf (stderr, "plot KAPA_PLOT_BARS_OUTLINE:\n");
       DrawBars (graphic, graph, object, KAPA_PLOT_BARS_OUTLINE);
       break;
     case KAPA_PLOT_BARS_OUTFILL:
-      // fprintf (stderr, "plot KAPA_PLOT_BARS_OUTFILL:\n");
       DrawBars (graphic, graph, object, KAPA_PLOT_BARS_OUTFILL);
       break;
     case KAPA_PLOT_POINTS:
     default:
-      // fprintf (stderr, "plot KAPA_PLOT_POINTS:\n");
       DrawPoints (graphic, graph, object);
       break;
@@ -172,5 +172,137 @@
     sx0 = sx1; sy0 = sy1;
   }
-  
+}
+
+/******/
+void DrawPolygon (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
+
+  float *x, *y;
+  double mxi, mxj, myi, myj, bxi, bxj, byi, byj, bx, by;
+  double sx0, sy0, sx1, sy1;
+  double X0, X1, Y0, Y1;
+
+  mxi = graph[0].axis[0].dfx / (object[0].x1 - object[0].x0);
+  mxj = graph[0].axis[1].dfx / (object[0].y1 - object[0].y0);
+  myi = graph[0].axis[0].dfy / (object[0].x1 - object[0].x0);
+  myj = graph[0].axis[1].dfy / (object[0].y1 - object[0].y0);
+  
+  bxi  =  graph[0].axis[0].fx - object[0].x0*graph[0].axis[0].dfx/(object[0].x1 - object[0].x0);
+  bxj  =  -object[0].y0*graph[0].axis[1].dfx/(object[0].y1 - object[0].y0);
+  byi  =  -object[0].x0*graph[0].axis[0].dfy/(object[0].x1 - object[0].x0);
+  byj  =  graph[0].axis[1].fy - object[0].y0*graph[0].axis[1].dfy/(object[0].y1 - object[0].y0);
+  
+  bx = bxi + bxj;
+  by = byi + byj;
+  
+  X0 = graph[0].axis[0].fx;
+  X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+  Y0 = graph[0].axis[1].fy;
+  Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+
+  x = object[0].x; y = object[0].y;
+
+  // ptype must > 2
+  // Npts % ptype must be 0
+  // who must validate that?
+
+  // each polygon is made of (N = ptype) points
+  // we connect each point and the last one back
+  for (int i = 0; i < object[0].Npts; i += object[0].ptype) {
+    // first check for any invalid values for this polygon
+    int skipObject = FALSE;
+    for (int j = 0; (j < object[0].ptype) && !skipObject; j++) {
+      int k = i + j;
+      if (!(finite(x[k]) && finite(y[k]))) skipObject = TRUE;
+    }
+    if (skipObject) continue;
+
+    for (int j = 0; (j < object[0].ptype); j++) {
+      int k = i + j;
+      sx0 = x[k]*mxi + y[k]*mxj + bx + XCENTER;
+      sy0 = x[k]*myi + y[k]*myj + by + YCENTER;
+
+      // last point connects to first
+      if (j == object[0].ptype - 1) {
+	sx1 = x[i]*mxi + y[i]*mxj + bx + XCENTER;
+	sy1 = x[i]*myi + y[i]*myj + by + YCENTER;
+      } else {
+	sx1 = x[k+1]*mxi + y[k+1]*mxj + bx + XCENTER;
+	sy1 = x[k+1]*myi + y[k+1]*myj + by + YCENTER;
+      }
+      ClipLine (graphic, sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
+    }
+  }
+}
+
+/******/
+void DrawPolyfill (Graphic *graphic, KapaGraphWidget *graph, Gobjects *object) {
+
+  float *x, *y, *z;
+  double mxi, mxj, myi, myj, bxi, bxj, byi, byj, bx, by;
+  double sx0, sy0;
+  // double X0, X1, Y0, Y1;
+
+  mxi = graph[0].axis[0].dfx / (object[0].x1 - object[0].x0);
+  mxj = graph[0].axis[1].dfx / (object[0].y1 - object[0].y0);
+  myi = graph[0].axis[0].dfy / (object[0].x1 - object[0].x0);
+  myj = graph[0].axis[1].dfy / (object[0].y1 - object[0].y0);
+  
+  bxi  =  graph[0].axis[0].fx - object[0].x0*graph[0].axis[0].dfx/(object[0].x1 - object[0].x0);
+  bxj  =  -object[0].y0*graph[0].axis[1].dfx/(object[0].y1 - object[0].y0);
+  byi  =  -object[0].x0*graph[0].axis[0].dfy/(object[0].x1 - object[0].x0);
+  byj  =  graph[0].axis[1].fy - object[0].y0*graph[0].axis[1].dfy/(object[0].y1 - object[0].y0);
+  
+  bx = bxi + bxj;
+  by = byi + byj;
+  
+  /*
+    window boundary so we can clip objects
+  X0 = graph[0].axis[0].fx;
+  X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+  Y0 = graph[0].axis[1].fy;
+  Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+  */
+
+  x = object[0].x; y = object[0].y; z = object[0].z;
+
+  // ptype must > 2
+  // Npts % ptype must be 0
+  // who must validate that?
+
+  ALLOCATE_PTR (points, XPoint, object[0].ptype);
+
+  // NOTE that LoadObject.c:45 limits the allow
+  // object styles which may have negative (scaled) colors
+  int scaleColor = (object[0].color < 0);
+
+  // each polygon is made of (N = ptype) points
+  // we connect each point and the last one back
+  for (int i = 0; i < object[0].Npts; i += object[0].ptype) {
+    // first check for any invalid values for this polygon
+    int skipObject = FALSE;
+    for (int j = 0; (j < object[0].ptype) && !skipObject; j++) {
+      int k = i + j;
+      if (!(finite(x[k]) && finite(y[k]))) skipObject = TRUE;
+    }
+    if (skipObject) continue;
+
+    for (int j = 0; (j < object[0].ptype); j++) {
+      int k = i + j;
+      sx0 = x[k]*mxi + y[k]*mxj + bx + XCENTER;
+      sy0 = x[k]*myi + y[k]*myj + by + YCENTER;
+
+      points[j].x = sx0;
+      points[j].y = sy0;
+    }
+
+    if (scaleColor) {
+      if (!finite(z[i])) continue;
+      int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+      XSetForeground (graphic->display, graphic->gc, graphic->cmap[pixel].pixel);
+    }
+    XFillPolygon (graphic->display, graphic->window, graphic->gc, points, object[0].ptype, Convex, CoordModeOrigin);
+  }
+
+  free (points);
 }
 
@@ -580,4 +712,7 @@
   int scaleColor = (object[0].color < 0);
 
+  // NOTE that LoadObject.c:45 limits the allow
+  // object styles which may have negative (scaled) colors
+
   ds = 0.5 * (graphic->dx + graphic->dy) * 0.003 * object[0].size;
   dz = 0.5 * (graphic->dx + graphic->dy) * 0.010;
@@ -916,8 +1051,8 @@
     // for open circles, only go to the outer radius
     D = 0;
-    if (object[0].ptype ==  7) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  1) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  5) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
-    if (object[0].ptype == 15) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
+    if (object[0].ptype == KAPA_POINT_CIRCLE_OPEN  	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_BOX_OPEN     	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN	) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN_DOWN) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
     if (!(finite(x[i]) && finite(y[i]) && finite(dxp[i]))) goto skip_dxp;
     if (D > fabs(dxp[i]*mxi)) goto skip_dxp;
@@ -999,8 +1134,8 @@
     // for open circles, only go to the outer radius
     D = 0;
-    if (object[0].ptype ==  7) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  1) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  5) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
-    if (object[0].ptype == 15) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
+    if (object[0].ptype == KAPA_POINT_CIRCLE_OPEN  	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_BOX_OPEN     	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN	) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN_DOWN) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
     if (!(finite(x[i]) && finite(y[i]) && finite(dyp[i]))) goto skip_dyp;
     if (D > fabs(dyp[i]*myj)) goto skip_dyp;
@@ -1023,6 +1158,6 @@
   skip_dyp:
     if (!(finite(x[i]) && finite(y[i]) && finite(dym[i]))) continue;
-    if (object[0].ptype ==  5) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
-    if (object[0].ptype == 15) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN	) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN_DOWN) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
     if (D > fabs(dym[i]*myj)) continue;
     sx0 = x[i]*mxi + y[i]*mxj + bx + XCENTER;
Index: /trunk/Ohana/src/kapa2/src/Image.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Image.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/Image.c	(revision 41157)
@@ -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: /trunk/Ohana/src/kapa2/src/InterpretKeys.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/InterpretKeys.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/InterpretKeys.c	(revision 41157)
@@ -160,4 +160,6 @@
       break;
 
+    case XK_plus:
+    case XK_equal:
     case XK_KP_Add:
       if (modstate & ControlMask) {
@@ -171,4 +173,7 @@
       Reorient (graphic, image, image[0].picture.Xc, image[0].picture.Yc, 0);
       break;
+
+    case XK_minus:
+    case XK_underscore:
     case XK_KP_Subtract:
       if (modstate & ControlMask) {
Index: /trunk/Ohana/src/kapa2/src/JPEGit24.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/JPEGit24.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/JPEGit24.c	(revision 41157)
@@ -212,4 +212,5 @@
     }
     bDrawBufferFree (buffer);
+    free (palette);
   }
 
Index: /trunk/Ohana/src/kapa2/src/Layout.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Layout.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/Layout.c	(revision 41157)
@@ -45,2 +45,7 @@
   AddSection ("default", 0.0, 0.0, 1.0, 1.0, -1);
 }
+
+void FreeLayout (void) {
+  FreeSections ();
+  FreeRotFonts ();
+}
Index: /trunk/Ohana/src/kapa2/src/LoadFrame.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadFrame.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/LoadFrame.c	(revision 41157)
@@ -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: /trunk/Ohana/src/kapa2/src/LoadLabels.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadLabels.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/LoadLabels.c	(revision 41157)
@@ -26,4 +26,6 @@
   label[Nbytes] = 0;
   
+  FREE (label);
+
   c = GetRotFont (&size);
 
Index: /trunk/Ohana/src/kapa2/src/LoadObject.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/LoadObject.c	(revision 41157)
@@ -42,5 +42,11 @@
       graph[0].objects[N].color = KapaColormapSize() - 1;
   }
-  if ((graph[0].objects[N].style != KAPA_PLOT_POINTS) && (graph[0].objects[N].color < 0)) {
+
+  // XXX watch out for this restriction in DrawObjects / bDrawObjects
+  int canScaleColor = FALSE;
+  canScaleColor |= (graph[0].objects[N].style == KAPA_PLOT_POINTS);
+  canScaleColor |= (graph[0].objects[N].style == KAPA_PLOT_POLYFILL);
+
+  if (!canScaleColor && (graph[0].objects[N].color < 0)) {
       graph[0].objects[N].color = 0;
   }
@@ -103,8 +109,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: /trunk/Ohana/src/kapa2/src/MemoryDump.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/MemoryDump.c	(revision 41157)
+++ /trunk/Ohana/src/kapa2/src/MemoryDump.c	(revision 41157)
@@ -0,0 +1,41 @@
+# include "Ximage.h"
+
+static int DumpOnExit = FALSE;
+
+int MemoryDump (int sock) {
+  OHANA_UNUSED_PARAM(sock);
+
+  ohana_memdump_file (stderr, TRUE);
+
+  return TRUE;
+}
+
+int MemoryDumpLines (int sock) {
+
+  int Nlines;
+  KiiScanMessage (sock, "%d", &Nlines);
+
+  ohana_memdump_set_maxlines (Nlines);
+
+  return TRUE;
+}
+
+int MemoryDumpOnExit (int sock) {
+  OHANA_UNUSED_PARAM(sock);
+
+  int state;
+  KiiScanMessage (sock, "%d", &state);
+
+  MemoryDumpSetOnExit (state);
+  return TRUE;
+}
+
+int MemoryDumpSetOnExit (int state) {
+  DumpOnExit = state;
+  return TRUE;
+}
+
+int MemoryDumpAndExit (void) {
+  if (DumpOnExit) MemoryDump(0);
+  exit (0);
+}
Index: /trunk/Ohana/src/kapa2/src/PNGit.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PNGit.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/PNGit.c	(revision 41157)
@@ -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: /trunk/Ohana/src/kapa2/src/PPMit.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/PPMit.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/PPMit.c	(revision 41157)
@@ -46,4 +46,6 @@
   
   bDrawBufferFree (buffer);
+  free (palette);
+
   return (TRUE);
 }
Index: /trunk/Ohana/src/kapa2/src/Refresh.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/Refresh.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/Refresh.c	(revision 41157)
@@ -1,5 +1,68 @@
 # include "Ximage.h"
 
+# define USE_BUFFERED_DRAW 1
+
+void bDrawXimage (bDrawBuffer *buffer);
+void Refresh_Buffered (void);
+void Refresh_Unbuffered (void);
+
 void Refresh (void) {
+  if (USE_BUFFERED_DRAW) {
+    Refresh_Buffered();
+  } else {
+    Refresh_Unbuffered();
+  }
+}
+
+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);
+  bDrawBufferFree (buffer);
+  free (palette);
+
+  // draw image tool for all sections
+  int Nsection = GetNumberOfSections ();
+  for (int i = 0; i < Nsection; i++) {
+    Section *section = GetSectionByNumber (i);
+
+    KapaImageWidget *image = section->image;
+    DrawImageTool (image);
+
+    /*** PaintOverlay is called in DrawImage ***
+    if (!image) continue;
+    for (int j = 0; j < NOVERLAYS; j++) {
+      if (image[0].overlay[j].active) {
+	PaintOverlay (graphic, image, j);
+      }
+    }
+    */
+  }
+
+  FlushDisplay ();
+}
+
+void Refresh_Unbuffered (void) {
 
   int i, Nsection;
@@ -20,8 +83,21 @@
   Nsection = GetNumberOfSections ();
   for (i = 0; i < Nsection; i++) {
-      section = GetSectionByNumber (i);
-      DrawSectionBG (graphic, section);
-      DrawImage (section->image);
-      DrawGraph (section->graph);
+    section = GetSectionByNumber (i);
+    DrawSectionBG (graphic, section);
+
+    KapaImageWidget *image = section->image;
+    DrawImage (image);
+    DrawImageTool (image);
+
+    /*** the overlay is added in DrawImage  ***/
+    if (image) {
+      for (int j = 0; j < NOVERLAYS; j++) {
+	if (image[0].overlay[j].active) {
+	  PaintOverlay (graphic, image, j);
+	}
+      }
+    }
+
+    DrawGraph (section->graph);
   }
 
Index: /trunk/Ohana/src/kapa2/src/SetColormap.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetColormap.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/SetColormap.c	(revision 41157)
@@ -72,5 +72,5 @@
 	  }
       }
-      fprintf (stderr, "ruff Npix: %d vs %d\n", i, graphic[0].Npixels);
+      // fprintf (stderr, "ruff Npix: %d vs %d\n", i, graphic[0].Npixels);
 
       // all other modes are 1D: set the flag:
@@ -217,4 +217,5 @@
       !strncmp (graphic->colormapName, "lgcy:", 5) || 
       !strncmp (graphic->colormapName, "cetf:", 5) || 
+      !strncmp (graphic->colormapName, "cetr:", 5) || 
       !strncmp (graphic->colormapName, "csvf:", 5)) {
 
@@ -233,9 +234,10 @@
     int isCSV = !strncmp (graphic->colormapName, "csvf:", 5);
     int isCET = !strncmp (graphic->colormapName, "cetf:", 5);
+    int isCETRev = !strncmp (graphic->colormapName, "cetr:", 5);
     int isLegacy = !strncmp (graphic->colormapName, "lgcy:", 5);
 
     float fracIndex, fracRed, fracBlue, fracGreen;
 
-    if (isCET) fracIndex = 0.0;
+    if (isCET || isCETRev) fracIndex = 0.0;
 
     while (scan_line_maxlen (f, line, 1024) != EOF) {
@@ -247,5 +249,5 @@
 	if (Nscan != 4) continue;
       }
-      if (isCET) {
+      if (isCET || isCETRev) {
 	Nscan = sscanf (line, "%f,%f,%f", &fracRed, &fracGreen, &fracBlue);
 	fracIndex += 1.0 / 256.0;
@@ -256,5 +258,5 @@
 	if (Nscan != 4) continue;
       }
-      if (!isCSV && !isLegacy && !isCET) {
+      if (!isCSV && !isLegacy && !isCET && !isCETRev) {
 	Nscan = sscanf (line, "%f %f %f %f", &fracIndex, &fracRed, &fracGreen, &fracBlue);
 	if (Nscan != 4) continue;
@@ -299,4 +301,16 @@
       }
     }
+
+    // reverse the color sequence:
+    if (isCETRev) {
+      for (i = 0; i < MaxValue / 2; i++) {  
+	unsigned short tmp;
+	// fprintf (stderr, "swap: %d %d\n", graphic[0].cmap[i].red, graphic[0].cmap[MaxValue - 1 - i].red);
+	tmp = graphic[0].cmap[i].red;   graphic[0].cmap[i].red   = graphic[0].cmap[MaxValue - 1 - i].red;   graphic[0].cmap[MaxValue - 1 - i].red   = tmp;
+	tmp = graphic[0].cmap[i].blue;  graphic[0].cmap[i].blue  = graphic[0].cmap[MaxValue - 1 - i].blue;  graphic[0].cmap[MaxValue - 1 - i].blue  = tmp;
+	tmp = graphic[0].cmap[i].green; graphic[0].cmap[i].green = graphic[0].cmap[MaxValue - 1 - i].green; graphic[0].cmap[MaxValue - 1 - i].green = tmp;
+      }
+    }
+
     goto store_colors;
   }
Index: /trunk/Ohana/src/kapa2/src/SetUpGraphic.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/SetUpGraphic.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/SetUpGraphic.c	(revision 41157)
@@ -32,4 +32,6 @@
   graphic->pixels       = NULL;
 
+  graphic->smooth_sigma = 0.0;
+
   if (!USE_XWINDOW) {
     ALLOCATE (graphic[0].pixels, unsigned long, NPIXELS_STATIC);
@@ -50,5 +52,4 @@
   CheckVisual (graphic, argc, argv);
   CheckColors (graphic, argc, argv);
-
 
   icon.width = icon_width;
@@ -84,2 +85,22 @@
 }
 
+int SetSmoothSigma (int sock) {
+
+  float sigma;
+  KiiScanMessage (sock, "%f", &sigma);
+
+  if (isfinite(sigma)) {
+    if ((sigma <= 1.1) && (sigma >= 0.0)) {
+      graphic->smooth_sigma = sigma;
+    }
+  }
+  return TRUE;
+}
+
+void FreeGraphic () {
+  free (graphic->pixels);
+  free (graphic->cmap);
+  free (graphic->color);
+  free (graphic->colormapName);
+  free (graphic);
+}
Index: /trunk/Ohana/src/kapa2/src/args.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/args.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/args.c	(revision 41157)
@@ -23,4 +23,9 @@
     NAME_WINDOW = strcreate (argv[N]);
     remove_argument(N, argc, argv);
+  }
+
+  if ((N = get_argument (*argc, argv, "-memdump"))) {
+    remove_argument(N, argc, argv);
+    MemoryDumpSetOnExit (TRUE);
   }
 
Index: /trunk/Ohana/src/kapa2/src/bDrawImage.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/bDrawImage.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/bDrawImage.c	(revision 41157)
@@ -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,27 @@
 
   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);
+
+  free (data);
 }
 
@@ -186,4 +220,5 @@
     }
     bDrawBufferFree (buffer);
+    free (palette);
   }
 
Index: /trunk/Ohana/src/kapa2/src/bDrawIt.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/bDrawIt.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/bDrawIt.c	(revision 41157)
@@ -3,31 +3,47 @@
 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) {
+    // anything > 1.1 blurs the image too much
+    graphic->smooth_sigma = MIN (graphic->smooth_sigma, 1.1);
+    bDrawSmooth (graph, graphic->smooth_sigma);
+  }
+  
+  // place graph on base
+  bDrawMerge (base, graph);
+  bDrawBufferFree (graph);
+
+  return (base);
 }
 
Index: /trunk/Ohana/src/kapa2/src/bDrawObjects.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/bDrawObjects.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/bDrawObjects.c	(revision 41157)
@@ -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;
 
@@ -35,4 +37,10 @@
     case KAPA_PLOT_CONNECT: 
       bDrawConnect (buffer, graph, object);
+      break;
+    case KAPA_PLOT_POLYGON: 
+      bDrawPolygons (buffer, graph, object);
+      break;
+    case KAPA_PLOT_POLYFILL: 
+      bDrawFillPolygons (buffer, graph, object);
       break;
     case KAPA_PLOT_HISTOGRAM:
@@ -103,4 +111,153 @@
     sx0 = sx1; sy0 = sy1;
   }
+}
+
+void bDrawPolygons (bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object) {
+
+  float *x, *y;
+  double mxi, mxj, myi, myj, bxi, bxj, byi, byj, bx, by;
+  double sx0, sy0, sx1, sy1;
+  double X0, X1, Y0, Y1;
+
+  mxi = graph[0].axis[0].dfx / (object[0].x1 - object[0].x0);
+  mxj = graph[0].axis[1].dfx / (object[0].y1 - object[0].y0);
+  myi = graph[0].axis[0].dfy / (object[0].x1 - object[0].x0);
+  myj = graph[0].axis[1].dfy / (object[0].y1 - object[0].y0);
+  
+  bxi  =  graph[0].axis[0].fx - object[0].x0*graph[0].axis[0].dfx/(object[0].x1 - object[0].x0);
+  bxj  =  -object[0].y0*graph[0].axis[1].dfx/(object[0].y1 - object[0].y0);
+  byi  =  -object[0].x0*graph[0].axis[0].dfy/(object[0].x1 - object[0].x0);
+  byj  =  graph[0].axis[1].fy - object[0].y0*graph[0].axis[1].dfy/(object[0].y1 - object[0].y0);
+  
+  bx = bxi + bxj;
+  by = byi + byj;
+  
+  X0 = graph[0].axis[0].fx;
+  X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+  Y0 = graph[0].axis[1].fy;
+  Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+
+  x = object[0].x; y = object[0].y;
+
+  // ptype must > 2
+  // Npts % ptype must be 0
+  // who must validate that?
+
+  // each polygon is made of (N = ptype) points
+  // we connect each point and the last one back
+  for (int i = 0; i < object[0].Npts; i += object[0].ptype) {
+    // first check for any invalid values for this polygon
+    int skipObject = FALSE;
+    for (int j = 0; (j < object[0].ptype) && !skipObject; j++) {
+      int k = i + j;
+      if (!(finite(x[k]) && finite(y[k]))) skipObject = TRUE;
+    }
+    if (skipObject) continue;
+
+    for (int j = 0; (j < object[0].ptype); j++) {
+      int k = i + j;
+      sx0 = x[k]*mxi + y[k]*mxj + bx;
+      sy0 = x[k]*myi + y[k]*myj + by;
+
+      // last point connects to first
+      if (j == object[0].ptype - 1) {
+	sx1 = x[i]*mxi + y[i]*mxj + bx;
+	sy1 = x[i]*myi + y[i]*myj + by;
+      } else {
+	sx1 = x[k+1]*mxi + y[k+1]*mxj + bx;
+	sy1 = x[k+1]*myi + y[k+1]*myj + by;
+      }
+      bDrawClipLine (buffer, sx0, sy0, sx1, sy1, X0, Y0, X1, Y1);
+    }
+  }
+}
+
+void bDrawFillPolygons (bDrawBuffer *buffer, KapaGraphWidget *graph, Gobjects *object) {
+
+  float *x, *y;
+  double mxi, mxj, myi, myj, bxi, bxj, byi, byj, bx, by;
+  double sx0, sy0;
+  // double X0, X1, Y0, Y1;
+
+  mxi = graph[0].axis[0].dfx / (object[0].x1 - object[0].x0);
+  mxj = graph[0].axis[1].dfx / (object[0].y1 - object[0].y0);
+  myi = graph[0].axis[0].dfy / (object[0].x1 - object[0].x0);
+  myj = graph[0].axis[1].dfy / (object[0].y1 - object[0].y0);
+  
+  bxi  =  graph[0].axis[0].fx - object[0].x0*graph[0].axis[0].dfx/(object[0].x1 - object[0].x0);
+  bxj  =  -object[0].y0*graph[0].axis[1].dfx/(object[0].y1 - object[0].y0);
+  byi  =  -object[0].x0*graph[0].axis[0].dfy/(object[0].x1 - object[0].x0);
+  byj  =  graph[0].axis[1].fy - object[0].y0*graph[0].axis[1].dfy/(object[0].y1 - object[0].y0);
+  
+  bx = bxi + bxj;
+  by = byi + byj;
+  
+  /*
+    window boundary so we can clip objects
+  X0 = graph[0].axis[0].fx;
+  X1 = graph[0].axis[0].fx + graph[0].axis[0].dfx;
+  Y0 = graph[0].axis[1].fy;
+  Y1 = graph[0].axis[1].fy + graph[0].axis[1].dfy;
+  */
+
+  x = object[0].x; y = object[0].y;
+
+  // ptype must > 2
+  // Npts % ptype must be 0
+  // who must validate that?
+
+  ALLOCATE_PTR (xpts, double, object[0].ptype);
+  ALLOCATE_PTR (ypts, double, object[0].ptype);
+
+  int scaleColor = (object[0].color < 0);
+  unsigned char *pixel1, *pixel2, *pixel3;
+  float *z = object[0].z;
+
+  if (scaleColor) {
+    // scaled colors use the colormap defined for the graphic
+    ALLOCATE (pixel1, unsigned char, graphic[0].Npixels);
+    ALLOCATE (pixel2, unsigned char, graphic[0].Npixels);
+    ALLOCATE (pixel3, unsigned char, graphic[0].Npixels);
+
+    /** cmap[i].pixel must be defined even if X is not used **/
+    for (int i = 0; i < graphic[0].Npixels; i++) { /* set up pixel array */
+      pixel1[i] = graphic[0].cmap[i].red >> 8;
+      pixel2[i] = graphic[0].cmap[i].green >> 8;
+      pixel3[i] = graphic[0].cmap[i].blue >> 8;
+    }
+
+  }
+
+  // each polygon is made of (N = ptype) points
+  // we connect each point and the last one back
+  for (int i = 0; i < object[0].Npts; i += object[0].ptype) {
+    // first check for any invalid values for this polygon
+    int skipObject = FALSE;
+    for (int j = 0; (j < object[0].ptype) && !skipObject; j++) {
+      int k = i + j;
+      if (!(finite(x[k]) && finite(y[k]))) skipObject = TRUE;
+    }
+    if (skipObject) continue;
+
+    for (int j = 0; (j < object[0].ptype); j++) {
+      int k = i + j;
+      sx0 = x[k]*mxi + y[k]*mxj + bx;
+      sy0 = x[k]*myi + y[k]*myj + by;
+
+      xpts[j] = sx0;
+      ypts[j] = sy0;
+    }
+    
+    if (scaleColor) {
+      if (!finite(z[i])) continue;
+      int pixel = MIN (graphic->Npixels - 2, MAX (0, z[i]*(graphic->Npixels - 1)));
+      buffer->bColor_R = pixel1[pixel];
+      buffer->bColor_G = pixel2[pixel];
+      buffer->bColor_B = pixel3[pixel];
+    }
+    bDrawPolyFill (buffer, xpts, ypts, object[0].ptype);
+  }
+  free (xpts);
+  free (ypts);
 }
 
@@ -886,8 +1043,8 @@
     // for open circles, only go to the outer radius
     D = 0;
-    if (object[0].ptype ==  7) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  1) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  5) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
-    if (object[0].ptype == 15) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
+    if (object[0].ptype == KAPA_POINT_CIRCLE_OPEN  	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_BOX_OPEN     	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN	) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN_DOWN) { D = scaleSize ? 0.66*dz*z[i] : 0.66*ds; }
     if (!(finite(x[i]) && finite(y[i]) && finite(dxp[i]))) goto skip_dxp;
     if (D > fabs(dxp[i]*mxi)) goto skip_dxp;
@@ -969,8 +1126,8 @@
     // for open circles, only go to the outer radius
     D = 0;
-    if (object[0].ptype ==  7) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  1) { D = scaleSize ? dz*z[i] : ds; }
-    if (object[0].ptype ==  5) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
-    if (object[0].ptype == 15) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
+    if (object[0].ptype == KAPA_POINT_CIRCLE_OPEN  	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_BOX_OPEN     	) { D = scaleSize ? dz*z[i] : ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN	) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN_DOWN) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
     if (!(finite(x[i]) && finite(y[i]) && finite(dyp[i]))) goto skip_dyp;
     if (D > fabs(dyp[i]*myj)) goto skip_dyp;
@@ -993,6 +1150,6 @@
   skip_dyp:
     if (!(finite(x[i]) && finite(y[i]) && finite(dym[i]))) continue;
-    if (object[0].ptype ==  5) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
-    if (object[0].ptype == 15) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN	) { D = scaleSize ? 0.58*dz*z[i] : 0.58*ds; }
+    if (object[0].ptype == KAPA_POINT_TRIANGLE_OPEN_DOWN) { D = scaleSize ? 1.15*dz*z[i] : 1.15*ds; }
     if (D > fabs(dym[i]*myj)) continue;
     sx0 = x[i]*mxi + y[i]*mxj + bx;
Index: /trunk/Ohana/src/kapa2/src/bDrawOverlay.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/bDrawOverlay.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/bDrawOverlay.c	(revision 41157)
@@ -24,8 +24,13 @@
   }
 
-  Xmin = 0;
-  Ymin = 0;
-  Xmax = image[0].picture.dx;
-  Ymax = image[0].picture.dy;
+  // Xmin = 0;
+  // Ymin = 0;
+  // Xmax = image[0].picture.dx;
+  // Ymax = image[0].picture.dy;
+
+  Xmin = image[0].picture.x;
+  Ymin = image[0].picture.y;
+  Xmax = image[0].picture.x + image[0].picture.dx; // maybe this should be just dx?
+  Ymax = image[0].picture.y + image[0].picture.dy;
 
   if (N == INFRONT) {
@@ -35,5 +40,7 @@
 
   for (i = 0; i < image[0].overlay[N].Nobjects; i++) {
-    Image_to_Picture (&X, &Y, image[0].overlay[N].objects[i].x, image[0].overlay[N].objects[i].y, &image[0].picture);
+    // XXX the 0.5,0.5 offset is apparently needed here.
+    // work on rationalizing these functions in the context of their different plotting types
+    Image_to_Screen (&X, &Y, image[0].overlay[N].objects[i].x - 0.5, image[0].overlay[N].objects[i].y - 0.5, &image[0].picture);
     dX = image[0].overlay[N].objects[i].dx * expand;
     dY = image[0].overlay[N].objects[i].dy * expand;
Index: /trunk/Ohana/src/kapa2/src/kapa.c
===================================================================
--- /trunk/Ohana/src/kapa2/src/kapa.c	(revision 41156)
+++ /trunk/Ohana/src/kapa2/src/kapa.c	(revision 41157)
@@ -11,4 +11,10 @@
 
   CloseDisplay ();
-  exit (0);
+
+  // free things
+  FreeLayout();
+  FreeGraphic();
+  FREE (NAME_WINDOW);
+
+  MemoryDumpAndExit ();
 }
