Index: /branches/eam_branches/20090715/Ohana/src/kapa2/src/CursorOps.c
===================================================================
--- /branches/eam_branches/20090715/Ohana/src/kapa2/src/CursorOps.c	(revision 25289)
+++ /branches/eam_branches/20090715/Ohana/src/kapa2/src/CursorOps.c	(revision 25290)
@@ -2,4 +2,5 @@
 
 // input coordinates are relative to the picture bounding box
+// XXX pre-calculate fexpand, Xc, Yc when expand is set?
 void Picture_to_Image (double *x1, double *y1, double x2, double y2, Picture *picture) {
 
@@ -14,10 +15,14 @@
   
   // pixel coordinates in picture frame
-  dx = expand*(x2 - 0.5*picture[0].dx);
-  dy = expand*(y2 - 0.5*picture[0].dy);
+  dx = expand*(x2 - (int)(0.5*picture[0].dx));
+  dy = expand*(y2 - (int)(0.5*picture[0].dy));
+
+  // set the true center (image and screen pixel boundaries must be aligned)
+  // Xc = (int)(picture[0].Xc / expand) * expand;
+  // Yc = (int)(picture[0].Yc / expand) * expand;
 
   // picture[0].X,Y is the image coordinate in the center of the picture
-  *x1 = picture[0].flipx ? picture[0].X - dx : picture[0].X + dx;
-  *y1 = picture[0].flipy ? picture[0].Y - dy : picture[0].Y + dy;
+  *x1 = picture[0].flipx ? picture[0].Xc - dx : picture[0].Xc + dx;
+  *y1 = picture[0].flipy ? picture[0].Yc - dy : picture[0].Yc + dy;
 }
 
@@ -46,10 +51,14 @@
   }
   
+  // set the true center (image and screen pixel boundaries must be aligned)
+  // Xc = ((int)(picture[0].Xc * expand)) / expand;
+  // Yc = ((int)(picture[0].Yc * expand)) / expand;
+
   // pixel coordinates in picture frame
-  dx = picture[0].flipx ? picture[0].X - x2 : x2 - picture[0].X;
-  dy = picture[0].flipy ? picture[0].Y - y2 : y2 - picture[0].Y;
+  dx = picture[0].flipx ? picture[0].Xc - x2 : x2 - picture[0].Xc;
+  dy = picture[0].flipy ? picture[0].Yc - y2 : y2 - picture[0].Yc;
     
-  *x1 = expand*dx + 0.5*picture[0].dx;
-  *y1 = expand*dy + 0.5*picture[0].dy;
+  *x1 = expand*dx + (int)(0.5*picture[0].dx);
+  *y1 = expand*dy + (int)(0.5*picture[0].dy);
 }
 
@@ -66,5 +75,5 @@
 
 // input coordinates are relative to the picture bounding box
-void Picture_Lower (int *i_start, int *j_start, Matrix *matrix, Picture *picture) {
+void Picture_Lower (int *i_start, int *j_start, int *I_start, int *J_start, Matrix *matrix, Picture *picture) {
 
   double Ix, Iy, Sx, Sy;
@@ -72,8 +81,4 @@
   // Ix, Iy are the image coordinates of the specified screen pixel
   Picture_to_Image (&Ix, &Iy, 0.0, 0.0, picture);
-
-  // Ix, Iy are now limited to valid image coordinates
-  Ix = MIN (MAX (Ix, 0), matrix[0].Naxis[0]);
-  Iy = MIN (MAX (Iy, 0), matrix[0].Naxis[1]);
 
   // round up (down) to nearest pixel boundary
@@ -84,4 +89,12 @@
     Iy = picture[0].flipy ? (int)(Iy) : (int)(Iy) + 1;
   }
+
+  // Ix, Iy are now limited to valid image coordinates
+  Ix = MIN (MAX (Ix, 0), matrix[0].Naxis[0]);
+  Iy = MIN (MAX (Iy, 0), matrix[0].Naxis[1]);
+
+  // I_start, J_start are the first displayed image pixel 
+  *I_start = Ix;
+  *J_start = Iy;
 
   // Sx, Sy are the screen coordinates of the Ix,Iy pixel
@@ -94,6 +107,7 @@
   
 // input coordinates are relative to the picture bounding box
-void Picture_Upper (int *i_end, int *j_end, Matrix *matrix, Picture *picture) {
+void Picture_Upper (int *i_end, int *j_end, int i_start, int j_start, Matrix *matrix, Picture *picture) {
 
+  int nExtra;
   double Ix, Iy, Sx, Sy;
 
@@ -101,15 +115,19 @@
   Picture_to_Image (&Ix, &Iy, picture[0].dx, picture[0].dy, picture);
 
+  // round down (up) to nearest pixel boundary
+  if (Ix > (int)(Ix)) {
+    Ix = picture[0].flipx ? (int)(Ix) + 1: (int)(Ix);
+  }
+  if (Iy > (int)(Iy)) {
+    Iy = picture[0].flipy ? (int)(Iy) + 1: (int)(Iy);
+  }
+
   // Ix, Iy are now limited to valid image coordinates
   Ix = MIN (MAX (Ix, 0), matrix[0].Naxis[0]);
   Iy = MIN (MAX (Iy, 0), matrix[0].Naxis[1]);
 
-  // round down (up) to nearest pixel boundary
-  if (Ix > (int)(Ix)) {
-    Ix = picture[0].flipx ? (int)(Ix) + 1 : (int)(Ix);
-  }
-  if (Iy > (int)(Iy)) {
-    Iy = picture[0].flipy ? (int)(Iy) + 1: (int)(Iy);
-  }
+  // I_end, J_end are the last displayed image pixel 
+  // *I_end = Ix;
+  // *J_end = Iy;
 
   // Sx, Sy are the screen coordinates of the Ix,Iy pixel
@@ -119,3 +137,11 @@
   *i_end = MIN (MAX (Sx, 0), picture[0].dx);
   *j_end = MIN (MAX (Sy, 0), picture[0].dy);
+
+  // round off error can leave us with a small number of extra pixels here.
+  if (picture[0].expand > 1) {
+    nExtra = (*i_end - i_start) % picture[0].expand;
+    *i_end -= nExtra;
+    nExtra = (*j_end - j_start) % picture[0].expand;
+    *j_end -= nExtra;
+  }
 }
