From beb1b2d93d3976e1865967317856ca97cf367cca Mon Sep 17 00:00:00 2001
From: user <user@user-ThinkPad-X60.(none)>
Date: Fri, 15 May 2015 01:17:31 -0400
Subject: [PATCH] fixed bug where scalar bbox cache prevented garrays from
 registering mouse clicks

---
 pd/src/g_array.c    | 50 +++++++++++++++++-------
 pd/src/g_canvas.h   |  3 +-
 pd/src/g_scalar.c   | 62 +++++++++++++++++++++++-------
 pd/src/g_template.c | 92 +++++++++++++++++++++++++++------------------
 4 files changed, 143 insertions(+), 64 deletions(-)

diff --git a/pd/src/g_array.c b/pd/src/g_array.c
index adf403da4..a41c5787a 100644
--- a/pd/src/g_array.c
+++ b/pd/src/g_array.c
@@ -872,11 +872,17 @@ void array_redraw(t_array *a, t_glist *glist)
 }
 
     /* routine to get screen coordinates of a point in an array */
+    /* glist_topixels parameter was added because of t_scalar
+       and t_draw caching mechanism. For scalers, we're only
+       converting to pixels in scalar_getrect. So in plot_getrect
+       we need to get the coordinate without regard to the x/y
+       offset (and scaling factor) of a gop window */
 void array_getcoordinate(t_glist *glist,
     char *elem, int xonset, int yonset, int wonset, int indx,
     t_float basex, t_float basey, t_float xinc,
     t_fielddesc *xfielddesc, t_fielddesc *yfielddesc, t_fielddesc *wfielddesc,
-    t_float *xp1, t_float *xp2, t_float *yp, t_float *wp)
+    t_float *xp1, t_float *xp2, t_float *yp, t_float *wp,
+    int glist_topixels)
 {
     t_float xval, yval, ypix, wpix;
     if (xonset >= 0)
@@ -885,23 +891,39 @@ void array_getcoordinate(t_glist *glist,
     if (yonset >= 0)
         yval = *(t_float *)(elem + yonset);
     else yval = 0;
-    ypix = glist_ytopixels(glist, basey +
-        fielddesc_cvttocoord(yfielddesc, yval));
+//    ypix = glist_ytopixels(glist, basey +
+//        fielddesc_cvttocoord(yfielddesc, yval));
+    ypix = basey + fielddesc_cvttocoord(yfielddesc, yval);
+    if (glist_topixels)
+        ypix = glist_ytopixels(glist, ypix);
     if (wonset >= 0)
     {
             /* found "w" field which controls linewidth. */
         t_float wval = *(t_float *)(elem + wonset);
-        wpix = glist_ytopixels(glist, basey + 
-            fielddesc_cvttocoord(yfielddesc, yval) +
-                fielddesc_cvttocoord(wfielddesc, wval)) - ypix;
+//        wpix = glist_ytopixels(glist, basey + 
+//            fielddesc_cvttocoord(yfielddesc, yval) +
+//                fielddesc_cvttocoord(wfielddesc, wval)) - ypix;
+        wpix = basey + fielddesc_cvttocoord(yfielddesc, yval) +
+            fielddesc_cvttocoord(wfielddesc, wval);
+        if (glist_topixels)
+            wpix = glist_ytopixels(glist, wpix);
+        wpix -= ypix;
         if (wpix < 0)
             wpix = -wpix;
     }
     else wpix = 1;
-    *xp1 = glist_xtopixels(glist, basex +
-        fielddesc_cvttocoord(xfielddesc, xval));
-    *xp2 = glist_xtopixels(glist, basex +
-        fielddesc_cvttocoord(xfielddesc, xval+1))-1;
+    if (glist_topixels)
+    {
+        *xp1 = glist_xtopixels(glist, basex +
+            fielddesc_cvttocoord(xfielddesc, xval));
+        *xp2 = glist_xtopixels(glist, basex +
+            fielddesc_cvttocoord(xfielddesc, xval+1))-1;
+    }
+    else
+    {
+        *xp1 = basex + fielddesc_cvttocoord(xfielddesc, xval);
+        *xp2 = basex + fielddesc_cvttocoord(xfielddesc, xval+1)-1;
+    }
     *yp = ypix;
     // increased following on 20140830 to 8 (+4 and -4) and 
     // so that the smallest hitbox is always at least 8x8
@@ -1119,13 +1141,14 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap,
         {
             array_getcoordinate(glist, (char *)(array->a_vec) + i * elemsize,
                 xonset, yonset, wonset, i, xloc, yloc, xinc,
-                xfield, yfield, wfield, &pxpix1, &pxpix2, &pypix, &pwpix);
+                xfield, yfield, wfield, &pxpix1, &pxpix2, &pypix, &pwpix, 1);
             //fprintf(stderr,"    array_getcoordinate %d: pxpix1:%f pxpix2:%f pypix:%f pwpix:%f dx:%f dy:%f elemsize:%d yonset:%d wonset:%d xonset:%d xloc:%f yloc:%f xinc:%f\n", i, pxpix1, pxpix2, pypix, pwpix, dx, dy, elemsize, yonset, wonset, xonset, xloc, yloc, xinc);
             // increased following on 20140830 to 8 and updated array_getcoordinate
             // so that the smallest hitbox is always at least 8x8--check with
             // all_about_arrays.pd inside custom scalars in an array
             if (pwpix < 8)
                 pwpix = 8;
+
             if (xpix >= (int)pxpix1-pwpix && xpix <= (int)pxpix2+pwpix &&
                 ((array_joc) ||
                  (ypix >= pypix-pwpix && ypix <= pypix+pwpix)))
@@ -1180,7 +1203,7 @@ int array_doclick(t_array *array, t_glist *glist, t_scalar *sc, t_array *ap,
         //{
             //array_getcoordinate(glist, (char *)(array->a_vec) + i * elemsize,
             //    xonset, yonset, wonset, i, xloc, yloc, xinc,
-            //    xfield, yfield, wfield, &pxpix1, &pxpix2, &pypix, &pwpix);
+            //    xfield, yfield, wfield, &pxpix1, &pxpix2, &pypix, &pwpix, 1);
             //dx = pxpix1 - xpix;
             //if (dx < 0) dx = -dx;
             dy = pypix - ypix;
@@ -1371,7 +1394,7 @@ static void array_getrect(t_array *array, t_glist *glist,
                 i * elemsize,
                 xonset, yonset, wonset, i, 0, 0, 1,
                 0, 0, 0,
-                &pxpix1, &pxpix2, &pypix, &pwpix);
+                &pxpix1, &pxpix2, &pypix, &pwpix, 1);
             if (pwpix < 2)
                 pwpix = 2;
             if (pxpix1 < x1)
@@ -1452,7 +1475,6 @@ static void garray_vis(t_gobj *z, t_glist *glist, int vis)
 static int garray_click(t_gobj *z, t_glist *glist,
     int xpix, int ypix, int shift, int alt, int dbl, int doit)
 {
-    //fprintf(stderr,"garray_click\n");
     t_garray *x = (t_garray *)z;
     array_garray = x;
     return (gobj_click(&x->x_scalar->sc_gobj, glist,
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index c130fe1b4..4337d37bd 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -638,7 +638,8 @@ EXTERN void array_getcoordinate(t_glist *glist,
     char *elem, int xonset, int yonset, int wonset, int indx,
     t_float basex, t_float basey, t_float xinc,
     t_fielddesc *xfielddesc, t_fielddesc *yfielddesc, t_fielddesc *wfielddesc,
-    t_float *xp1, t_float *xp2, t_float *yp, t_float *wp);
+    t_float *xp1, t_float *xp2, t_float *yp, t_float *wp,
+    int glist_topixels);
 
 EXTERN int array_getfields(t_symbol *elemtemplatesym,
     t_canvas **elemtemplatecanvasp,
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index 7539e9182..cdbaafe36 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -361,6 +361,7 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
     t_canvas *templatecanvas = template_findcanvas(template);
     int x1 = 0x7fffffff, x2 = -0x7fffffff, y1 = 0x7fffffff, y2 = -0x7fffffff;
     t_float basex, basey;
+    t_float screenx1, screeny1, screenx2, screeny2;
 
     // EXPERIMENTAL: we assume that entire canvas is within
     // the rectangle--this is for arrays
@@ -371,7 +372,6 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
     {
         x1 = -0x7fffffff, y1 = -0x7fffffff, x2 = 0x7fffffff, y2 = 0x7fffffff;
     }
-
     else
     {
         scalar_getbasexy(x, &basex, &basey);
@@ -385,12 +385,25 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
         else
         {
             /* todo: bad flow with internal return here. make it cleaner */
-            if (x->sc_bboxcache)
+            if (x->sc_bboxcache && 0)
             {
-                *xp1 = x->sc_x1;
-                *yp1 = x->sc_y1;
-                *xp2 = x->sc_x2;
-                *yp2 = x->sc_y2;
+                screenx1 = glist_xtopixels(owner, x->sc_x1);
+                screeny1 = glist_ytopixels(owner, x->sc_y1);
+                screenx2 = glist_xtopixels(owner, x->sc_x2);
+                screeny2 = glist_ytopixels(owner, x->sc_y2);
+
+                *xp1 = (int)(screenx1 < screenx2 ? screenx1 : screenx2);
+                *yp1 = (int)(screeny1 < screeny2 ? screeny1 : screeny2);
+                *xp2 = (int)(screenx2 > screenx1 ? screenx2 : screenx1);
+                *yp2 = (int)(screeny2 > screeny1 ? screeny2 : screeny1);
+
+                //fprintf(stderr,"CACHED FINAL scalar_getrect "
+                //               "x1 %g y1 %g x2 %g y2 %g\n",
+                    screenx1,
+                    screeny1,
+                    screenx2,
+                    screeny2);
+
                 return;
             }
             x1 = y1 = 0x7fffffff;
@@ -401,13 +414,31 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
                 x1 = y1 = x2 = y2 = 0;
         }
     }
-    //fprintf(stderr,"FINAL scalar_getrect x1 %d y1 %d x2 %d y2 %d\n",
-    //    x1, y1, x2, y2);
-    *xp1 = x->sc_x1 = x1;
-    *yp1 = x->sc_y1 = y1;
-    *xp2 = x->sc_x2 = x2;
-    *yp2 = x->sc_y2 = y2; 
-    x->sc_bboxcache = 1;
+    screenx1 = glist_xtopixels(owner, x1);
+    screeny1 = glist_ytopixels(owner, y1);
+    screenx2 = glist_xtopixels(owner, x2);
+    screeny2 = glist_ytopixels(owner, y2);
+
+    // Values for screen bounding box
+    *xp1 = (int)(screenx1 < screenx2 ? screenx1 : screenx2);
+    *xp2 = (int)(screenx2 > screenx1 ? screenx2 : screenx1);
+    *yp1 = (int)(screeny1 < screeny2 ? screeny1 : screeny2);
+    *yp2 = (int)(screeny2 > screeny1 ? screeny2 : screeny1);
+
+    // Cache without glist_topixel (in case a gop is moved, for example)
+    x->sc_x1 = x1;
+    x->sc_x2 = x2;
+    x->sc_y1 = y1;
+    x->sc_y2 = y2;
+
+    //fprintf(stderr,"COMPUTED FINAL scalar_getrect "
+    //    "x1 %g y1 %g x2 %g y2 %g\n",
+    //    screenx1,
+    //    screeny1,
+    //    screenx2,
+    //    screeny2);
+
+    x->sc_bboxcache = 1; // We now have cached values for the next call
 }
 
 void scalar_drawselectrect(t_scalar *x, t_glist *glist, int state)
@@ -426,6 +457,11 @@ void scalar_drawselectrect(t_scalar *x, t_glist *glist, int state)
         x1--; x2++; y1--; y2++;
         if (glist_istoplevel(glist))
         {
+            t_float xscale = glist_xtopixels(glist, 1) -
+                glist_xtopixels(glist, 0);
+            t_float yscale = glist_ytopixels(glist, 1) -
+                glist_ytopixels(glist, 0);
+
             //sys_vgui(".x%lx.c create prect %d %d %d %d "
             //         "-strokewidth 1 -stroke $pd_colors(selection) "
             //         "-tags {select%lx selected}\n",
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index b3497dc3c..83022ab38 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -2323,16 +2323,16 @@ void svg_parsetransform(t_svg *x, t_template *template, t_word *data,
         }
         else if (type == gensym("skewx"))
         {
-            t_float a = fielddesc_getfloat(fd++, template, data, 0); // *
-            //    3.14159 / 180;
+            t_float a = fielddesc_getfloat(fd++, template, data, 0) *
+                3.14159 / 180;
             argc--;
             mset(m2, 1, 0, tan(a), 1, 0, 0);
             mmult(m, m2, m);
         }
         else if (type == gensym("skewy"))
         {
-            t_float a = fielddesc_getfloat(fd++, template, data, 0); // *
-            //    3.14159 / 180;
+            t_float a = fielddesc_getfloat(fd++, template, data, 0) *
+                3.14159 / 180;
             argc--;
             mset(m2, 1, tan(a), 0, 1, 0, 0);
             mmult(m, m2, m);
@@ -3121,14 +3121,14 @@ static void svg_getpathrect(t_svg *x, t_glist *glist,
     x->x_y2 = finaly2;
     if (x->x_pathrect_cache != -1)
         x->x_pathrect_cache = 1;
-    finalx1 = glist_xtopixels(glist, basex + finalx1);
-    finalx2 = glist_xtopixels(glist, basex + finalx2);
-    finaly1 = glist_ytopixels(glist, basey + finaly1);
-    finaly2 = glist_ytopixels(glist, basey + finaly2);
-    *xp1 = (int)finalx1;
-    *xp2 = (int)finalx2;
-    *yp1 = (int)finaly1;
-    *yp2 = (int)finaly2;
+    //finalx1 = glist_xtopixels(glist, basex + finalx1);
+    //finalx2 = glist_xtopixels(glist, basex + finalx2);
+    //finaly1 = glist_ytopixels(glist, basey + finaly1);
+    //finaly2 = glist_ytopixels(glist, basey + finaly2);
+    *xp1 = (int)(finalx1 + basex);
+    *xp2 = (int)(finalx2 + basex);
+    *yp1 = (int)(finaly1 + basey);
+    *yp2 = (int)(finaly2 + basey);
 }
 
 static void draw_getrect(t_gobj *z, t_glist *glist,
@@ -3155,10 +3155,16 @@ static void draw_getrect(t_gobj *z, t_glist *glist,
 
     if (sa->x_pathrect_cache == 1)
     {
-        *xp1 = glist_xtopixels(glist, basex + sa->x_x1);
-        *xp2 = glist_xtopixels(glist, basex + sa->x_x2);
-        *yp1 = glist_ytopixels(glist, basey + sa->x_y1);
-        *yp2 = glist_ytopixels(glist, basey + sa->x_y2);
+        //*xp1 = glist_xtopixels(glist, basex + sa->x_x1);
+        //*xp2 = glist_xtopixels(glist, basex + sa->x_x2);
+        //*yp1 = glist_ytopixels(glist, basey + sa->x_y1);
+        //*yp2 = glist_ytopixels(glist, basey + sa->x_y2);
+
+        *xp1 = basex + sa->x_x1;
+        *xp2 = basex + sa->x_x2;
+        *yp1 = basey + sa->x_y1;
+        *yp2 = basey + sa->x_y2;
+
         return;
     }
 
@@ -3208,10 +3214,15 @@ static void draw_getrect(t_gobj *z, t_glist *glist,
         }
         if (n)
         {
-            x1 = glist_xtopixels(glist, basex + x1);
-            x2 = glist_xtopixels(glist, basex + x2);
-            y1 = glist_ytopixels(glist, basey + y1);
-            y2 = glist_ytopixels(glist, basey + y2);
+            //x1 = glist_xtopixels(glist, basex + x1);
+            //x2 = glist_xtopixels(glist, basex + x2);
+            //y1 = glist_ytopixels(glist, basey + y1);
+            //y2 = glist_ytopixels(glist, basey + y2);
+
+            x1 = basex + x1;
+            x2 = basex + x2;
+            y1 = basey + y1;
+            y2 = basey + y2;
         }
     }
     else if (sa->x_type == gensym("rect") ||
@@ -3301,10 +3312,15 @@ static void draw_getrect(t_gobj *z, t_glist *glist,
         if (tx2 > x2) x2 = tx2;
         if (ty1 > y2) y2 = ty1;
         if (ty2 > y2) y2 = ty2;
-        x1 = glist_xtopixels(glist, basex + x1);
-        x2 = glist_xtopixels(glist, basex + x2);
-        y1 = glist_ytopixels(glist, basey + y1);
-        y2 = glist_ytopixels(glist, basey + y2);
+        //x1 = glist_xtopixels(glist, basex + x1);
+        //x2 = glist_xtopixels(glist, basex + x2);
+        //y1 = glist_ytopixels(glist, basey + y1);
+        //y2 = glist_ytopixels(glist, basey + y2);
+
+        x1 = basex + x1;
+        x2 = basex + x2;
+        y1 = basey + y1;
+        y2 = basey + y2;
     }
     if (fielddesc_getfloat(&sa->x_strokewidth.a_attr, template, data, 0))
     {
@@ -4342,10 +4358,8 @@ static void curve_getrect(t_gobj *z, t_glist *glist,
     }
     for (i = 0, f = x->x_vec; i < n; i++, f += 2)
     {
-        int xloc = glist_xtopixels(glist,
-            basex + fielddesc_getcoord(f, template, data, 0));
-        int yloc = glist_ytopixels(glist,
-            basey + fielddesc_getcoord(f+1, template, data, 0));
+        int xloc = basex + fielddesc_getcoord(f, template, data, 0);
+        int yloc = basey + fielddesc_getcoord(f+1, template, data, 0);
         if (xloc < x1) x1 = xloc;
         if (xloc > x2) x2 = xloc;
         if (yloc < y1) y1 = yloc;
@@ -4977,7 +4991,8 @@ static void plot_getrect(t_gobj *z, t_glist *glist,
     mset(mtx1, 1, 0, 0, 1, 0, 0);
     if (x->x_canvas->gl_owner && x->x_canvas->gl_svg)
         svg_dogroupmtx(x->x_canvas, template, data, mtx1);
-//post("plot_getrect matrix: %g %g %g %g %g %g", mtx1[0][0], mtx1[1][0], mtx1[0][1], mtx1[1][1], mtx1[0][2], mtx1[2][1]);
+    //post("plot_getrect matrix: %g %g %g %g %g %g",
+    //  mtx1[0][0], mtx1[1][0], mtx1[0][1], mtx1[1][1], mtx1[0][2], mtx1[2][1]);
     int elemsize, yonset, wonset, xonset;
     t_canvas *elemtemplatecanvas;
     t_template *elemtemplate;
@@ -5016,7 +5031,7 @@ static void plot_getrect(t_gobj *z, t_glist *glist,
             array_getcoordinate(glist, (char *)(array->a_vec) + i * elemsize,
                 xonset, yonset, wonset, i, basex + xloc, basey + yloc, xinc,
                 xfielddesc, yfielddesc, wfielddesc,
-                &xpix1, &xpix2, &ypix, &wpix);
+                &xpix1, &xpix2, &ypix, &wpix, 0);
             //fprintf(stderr,"elemsize%d yonset%d wonset%d xonset%d "
             //               "i%d basex%f xloc%f basey%f yloc%f xinc%f "
             //               "xpix%f ypix%f wpix%f\n",
@@ -5104,7 +5119,7 @@ static void plot_getrect(t_gobj *z, t_glist *glist,
             //    x1, y1, x2, y2);
         }
     }
-    //fprintf(stderr,"FINAL plot_getrect %d %d %d %d\n", x1, y1, x2, y2);
+    fprintf(stderr,"FINAL plot_getrect %d %d %d %d\n", x1, y1, x2, y2);
     //fprintf(stderr,"basex %g basey %g\n", basex, basey);
     *xp1 = x1;
     *yp1 = y1;
@@ -6765,7 +6780,7 @@ static void drawimage_getrect(t_gobj *z, t_glist *glist,
     x1 = y1 = 0x7fffffff;
     x2 = y2 = -0x7fffffff;
 
-//    char buf[DRAWNUMBER_BUFSIZE];
+    //char buf[DRAWNUMBER_BUFSIZE];
     t_float mtx1[3][3] = { {1, 0, 0}, {0, 1, 0}, {0, 0, 1} };
     t_float mtx2[3][3] = { {1, 0, 0}, {0, 1, 0}, {1, 0, 1} };
     t_float m1, m2, m3, m4, m5, m6,
@@ -6811,10 +6826,15 @@ static void drawimage_getrect(t_gobj *z, t_glist *glist,
     if (tx2 > x2) x2 = tx2;
     if (ty1 > y2) y2 = ty1;
     if (ty2 > y2) y2 = ty2;
-    x1 = glist_xtopixels(glist, basex + x1);
-    x2 = glist_xtopixels(glist, basex + x2);
-    y1 = glist_ytopixels(glist, basey + y1);
-    y2 = glist_ytopixels(glist, basey + y2);
+    //x1 = glist_xtopixels(glist, basex + x1);
+    //x2 = glist_xtopixels(glist, basex + x2);
+    //y1 = glist_ytopixels(glist, basey + y1);
+    //y2 = glist_ytopixels(glist, basey + y2);
+
+    x1 = basex + x1;
+    x2 = basex + x2;
+    y1 = basey + y1;
+    y2 = basey + y2;
 
     /* todo: put these up top */
     if (!fielddesc_getfloat(&x->x_vis, template, data, 0))
-- 
GitLab