diff --git a/pd/src/g_readwrite.c b/pd/src/g_readwrite.c
index 259d947fc525cc182a998ec2f77fb9f8e31c31ed..fd817d6b3c445b067bfda967474224a3d38379bf 100644
--- a/pd/src/g_readwrite.c
+++ b/pd/src/g_readwrite.c
@@ -458,6 +458,36 @@ static void canvas_addtemplatesforscalar(t_symbol *templatesym,
     }
 }
 
+static void canvas_addtemplatesforstruct(t_template *template,
+    int *p_ntemplates, t_symbol ***p_templatevec)
+{
+    t_dataslot *ds;
+    int i;
+    canvas_doaddtemplate(template->t_sym, p_ntemplates, p_templatevec);
+    if (!template)
+        bug("canvas_addtemplatesforscalar");
+    else for (ds = template->t_vec, i = template->t_n; i--; ds++)
+    {
+        if (ds->ds_type == DT_ARRAY)
+        {
+            t_symbol *arraytemplatesym = ds->ds_arraytemplate;
+            t_template *arraytemplate = template_findbyname(arraytemplatesym);
+            if (arraytemplate)
+            {
+                canvas_doaddtemplate(arraytemplatesym, p_ntemplates,
+                    p_templatevec);
+                canvas_addtemplatesforstruct(arraytemplate,
+                        p_ntemplates, p_templatevec);
+            }
+        }
+        /* not sure about this part-- all the sublist datatype seems
+           to do is crash */
+        //else if (ds->ds_type == DT_LIST)
+        //    canvas_addtemplatesforlist(w->w_list->gl_list,
+        //        p_ntemplates, p_templatevec);
+    }
+}
+
 static void canvas_addtemplatesforlist(t_gobj *y,
     int  *p_ntemplates, t_symbol ***p_templatevec)
 {
@@ -625,6 +655,9 @@ static void canvas_saveto(t_canvas *x, t_binbuf *b)
     }
 }
 
+/* yuck, wish I didn't have to do this... */
+extern t_class *gtemplate_class;
+
     /* call this recursively to collect all the template names for
     a canvas or for the selection. */
 static void canvas_collecttemplatesfor(t_canvas *x, int *ntemplatesp,
@@ -638,6 +671,10 @@ static void canvas_collecttemplatesfor(t_canvas *x, int *ntemplatesp,
             (wholething || glist_isselected(x, y)))
                 canvas_addtemplatesforscalar(((t_scalar *)y)->sc_template,
                     ((t_scalar *)y)->sc_vec,  ntemplatesp, templatevecp);
+        else if ((pd_class(&y->g_pd) == gtemplate_class) &&
+            (wholething || glist_isselected(x, y)))
+                canvas_addtemplatesforstruct(gtemplate_get((t_gtemplate *)y),
+                    ntemplatesp, templatevecp);
         else if ((pd_class(&y->g_pd) == canvas_class) &&
             (wholething || glist_isselected(x, y)))
                 canvas_collecttemplatesfor((t_canvas *)y,
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index 3c75a8a5c99794560df7e7c10e325ca7771a5029..2ad5a9136c636adb1d130120d7405c5b6775fc73 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -140,20 +140,25 @@ int template_hasxy(t_template *template)
 int template_check_array_fields(t_symbol *structname, t_template *template)
 {
     /* We're calling this from template_cancreate as well as
-       gtemplate_cancreate.
-       With gtemplate_cancreate, the t_template doesn't exist yet.
-       So we send the struct name to see if it matches the name of any
-       array field templates that our gtemplate will depend on. If we find
-       a match we will refuse to create the gtemplate.
-       However, template_cancreate starts from the struct name for a template
-       that already exists.  So on the first time through this recursive
-       function, there isn't a containing structname yet.
-       So we suppress this conditional the first
-       time through the recursive loop, and then set the structname for
-       all subsequent iterations through the loop. */
+       gtemplate_cancreate. With gtemplate_cancreate, the t_template doesn't
+       exist yet. So we send the struct name to see if it matches the name of
+       any array field templates that our gtemplate will depend on. If we find
+       a match we will refuse to create the gtemplate. However,
+       template_cancreate starts from the struct name for a template that
+       already exists.  On the first time through this recursive function,
+       there isn't a containing structname yet. So we suppress this conditional
+       the first time through the recursive loop, and then set the structname
+       for all subsequent iterations through the loop.
+       
+       1 = success
+       0 = circular dependency
+       -1 = non-existant array elemtemplate found */
     if (structname && structname == template->t_sym)
     {
-        return 0;
+        t_object *ob = template_getstruct(template);
+        pd_error(ob, "%s: circular dependency",
+            template->t_sym->s_name);
+       return (0);
     }
     int i, nitems = template->t_n;
     t_dataslot *datatypes = template->t_vec;
@@ -168,7 +173,7 @@ int template_check_array_fields(t_symbol *structname, t_template *template)
                 t_object *ob = template_getstruct(template);
                 pd_error(ob, "%s: no such template",
                     datatypes->ds_arraytemplate->s_name);
-                return (0);
+                return (-1);
             }
             else if (elemtemplate->t_sym == structname)
             {
@@ -187,13 +192,13 @@ int template_check_array_fields(t_symbol *structname, t_template *template)
             }
         }
     }
-    return (1);
+    return 1;
 }
 
 int template_cancreate(t_template *template)
 {
     /* we send "0" for the structname since there is no container struct */
-    return (template_check_array_fields(0, template));
+    return (template_check_array_fields(0, template) == 1);
 }
 
     /* make a new scalar and add to the glist.  We create a "gp" here which
@@ -703,10 +708,16 @@ static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
     {
         t_float xscale = glist_xtopixels(owner, 1) - glist_xtopixels(owner, 0);
         t_float yscale = glist_ytopixels(owner, 1) - glist_ytopixels(owner, 0);
-        /* we could use the tag .template%lx for easy access from
-           the draw_class, but that's not necessary at this point */
+        /* we translate the .scalar%lx group to displace it on the tk side.
+           This is the outermost group for the scalar, something like a
+           poor man's viewport.
+           Also, the default stroke is supposed to be "none" and default
+           fill is supposed to be black. Unfortunately tkpath does the
+           opposite.  To fix this, we set the correct fill/stroke options
+           here on the .scalar%lx group. Notice also that tkpath doesn't
+           understand "None"-- instead we must send an empty symbol. */
         sys_vgui(".x%lx.c create group -tags {.scalar%lx %s} "
-            "-matrix { {%g %g} {%g %g} {%d %d} }\n",
+            "-matrix { {%g %g} {%g %g} {%d %d} } -stroke \"\" -fill black\n",
             glist_getcanvas(owner), x->sc_vec,
             (glist_isselected(owner, &x->sc_gobj) ? "scalar_selected" : ""),
             xscale, 0.0, 0.0, yscale, (int)glist_xtopixels(owner, basex),
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index a72d8202446e80f4a57c5895aac5a1debcabc790..adb60b26dfce443b325e071f6fa7eb22b4dcd66a 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -45,7 +45,7 @@ static int drawimage_getindex(void *z, t_template *template, t_word *data);
 
 /* ---------------------- storage ------------------------- */
 
-static t_class *gtemplate_class;
+t_class *gtemplate_class;
 static t_class *template_class;
 
 /* there's a pre-defined "float" template.  LATER should we bind this
@@ -673,9 +673,13 @@ int gtemplate_cancreate(t_symbol *templatename, int argc, t_atom *argv)
                 /* check for cancreation here */
                 t_template *elemtemplate =
                     template_findbyname(canvas_makebindsym(argv[2].a_w.w_symbol));
-                if (!elemtemplate ||
-                    !template_check_array_fields(
-                        canvas_makebindsym(templatename), elemtemplate))
+                if (!elemtemplate)
+                {
+                    post("warning: template %s does not exist",
+                        argv[2].a_w.w_symbol->s_name);
+                }
+                else if (template_check_array_fields(
+                        canvas_makebindsym(templatename), elemtemplate) == 0)
                 {
                     return 0;
                 }
@@ -707,7 +711,7 @@ static void *gtemplate_new(t_symbol *s, int argc, t_atom *argv)
         return (gtemplate_donew(canvas_makebindsym(sym), argc, argv));
     }
     else
-        return 0;
+        return (0);
 }
 
     /* old version (0.34) -- delete 2003 or so */
@@ -1244,7 +1248,7 @@ void *svg_new(t_pd *parent, t_symbol *s, int argc, t_atom *argv)
     }
     if (argc & 1 && x->x_type != gensym("path"))
         fielddesc_setfloat_const(fd, 0);
-    x->x_filltype = 42;
+    x->x_filltype = 0;
     x->x_fillopacity.a_flag = 0;
     x->x_fillrule.a_flag = 0;
     x->x_stroketype = 0;
@@ -1399,15 +1403,17 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s,
     t_template *template, t_word *data, int *predraw_bbox, void *parent,
     t_scalar *sc)
 {
- /* todo-- I'm mixing "c" with glist_getcanvas(c) a little too freely...
-    need to experiment with gop scalars to make sure I'm not breaking
-    anything */ 
-   char tag[MAXPDSTRING];
+   /* todo-- I'm mixing "c" with glist_getcanvas(c) a little too freely...
+      need to experiment with gop scalars to make sure I'm not breaking
+      anything */ 
+    int in_array = (sc->sc_vec != data);
+    post("in_array is %d", in_array);
+    char tag[MAXPDSTRING];
     if (x->x_type == gensym("group"))
     {
-        template_findcanvas(template);
-        sprintf(tag, ".dgroup%lx.%lx",
-            (long unsigned int)template_findcanvas(template),
+        sprintf(tag, "%s%lx.%lx",
+            (in_array ? ".scelem" : ".dgroup"),
+            (long unsigned int)x->x_parent,
             (long unsigned int)data);
     }
     else
@@ -1537,14 +1543,6 @@ void svg_sendupdate(t_svg *x, t_canvas *c, t_symbol *s,
             x->x_pathrect_cache = 0;
         }
         svg_parsetransform(x, template, data, &m1, &m2, &m3, &m4, &m5, &m6);
-        if (x->x_type == gensym("group"))
-        {
-            sys_vgui(".x%lx.c itemconfigure .dgroup%lx.%lx -matrix "
-                "{ {%g %g} {%g %g} {%g %g} }\n",
-                glist_getcanvas(c), x->x_parent, data,
-                m1, m2, m3, m4, m5, m6);
-        }
-        else
             sys_vgui(".x%lx.c itemconfigure %s -matrix "
                     "{ {%g %g} {%g %g} {%g %g} }\n",
                     glist_getcanvas(c), tag,
@@ -1650,6 +1648,7 @@ void svg_updatevec(t_canvas *c, t_word *data, t_template *template,
     t_template *target, void *parent, t_symbol *s, t_svg *x, t_scalar *sc,
     int *predraw_bbox)
 {
+    post("updateing vec...");
     int i, j;
     for (i = 0; i < template->t_n; i++)
     {
@@ -2103,7 +2102,8 @@ void svg_rectpoints(t_svg *x, t_symbol *s, int argc, t_atom *argv)
             if (type == A_FLOAT || type == A_SYMBOL)
             {
                 t_fielddesc *fd = x->x_vec;
-                if (type == A_FLOAT && argv[0].a_w.w_float < 0)
+                /* don't allow negative height/width */
+                if (type == A_FLOAT && i > 1 && argv[0].a_w.w_float < 0)
                     fielddesc_setfloat_const(fd + i, 0);
                 else
                     fielddesc_setfloatarg(fd + i, argc, argv);
@@ -3443,16 +3443,6 @@ static void draw_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
             */
 
             int in_array = (sc->sc_vec == data) ? 0 : 1;
-//            if (in_array)
-//            {
-                /* we probably don't need 'p' anymore... */
-                //t_canvas *p =
-                //    template_findcanvas(template_findbyname(sc->sc_template));
-//               sys_vgui(".x%lx.c create group -tags {.scelem%lx} "
-//                    "-parent .scelem%lx.%lx -matrix { {1 0} {0 1} {%g %g} }\n",
-//                    glist_getcanvas(glist), data,
-//                    parentglist, data, basex, basey);
-//            }
             //int flags = sa->x_flags;
             t_float pix[500];
             if (n > 500)
@@ -3875,7 +3865,7 @@ typedef struct _curve
    when loading a file.) The reason is that they have not had their
    motionfn revised to respect the parent affine transformations.  If they
    did then we could allow them inside a [group]. */
-extern canvas_isgroup(t_canvas *x);
+extern int canvas_isgroup(t_canvas *x);
 
 static int legacy_draw_in_group(t_canvas *c)
 {
@@ -4097,18 +4087,6 @@ static void curve_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
                revised so it's done in a more sane fashion
             */
             int in_array = (sc->sc_vec == data) ? 0 : 1;
-            if (in_array)
-            {
-               /* since the old drawing commands don't have svg attributes
-                  or transforms, we just make them children of the scalar's
-                  group.  That seems to work just fine. */
-               t_canvas *p =
-                    template_findcanvas(template_findbyname(sc->sc_template));
-               sys_vgui(".x%lx.c create group -tags {.scelem%lx} "
-                    "-parent .dgroup%lx.%lx -matrix { {1 0} {0 1} {%g %g} }\n",
-                    glist_getcanvas(glist), data,
-                    p, sc->sc_vec, basex, basey);
-            }
             int flags = x->x_flags;
             t_float width = fielddesc_getfloat(&x->x_width, template, data, 1);
             char outline[20], fill[20];
@@ -4166,10 +4144,9 @@ static void curve_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
             }
             for (i = 0; i < n; i++)
             {
-                //sys_vgui("%d %d \\\n", pix[2*i], pix[2*i+1]);
                 sys_vgui("%d %d \\\n",
-                    pix[2*i] + (in_array ? (int)basex : 0),
-                    pix[2*i+1] + (in_array ? (int)basey : 0));
+                    pix[2*i],
+                    pix[2*i+1]);
                 if ((flags & BEZ) && (flags & BBOX))
                 {
                     sys_vgui("-rx %d -ry %d \\\n",
@@ -4184,9 +4161,9 @@ static void curve_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
             if (flags & CLOSED) sys_vgui("-fill %s -stroke %s \\\n",
                 fill, outline);
             else if(flags & BBOX) sys_vgui("-stroke %s \\\n", outline);
-            else sys_vgui("-stroke %s \\\n", outline);
+            else sys_vgui("-stroke %s -fill \"\" \\\n", outline);
             if (in_array)
-                sys_vgui("-parent .scelem%lx \\\n", data);
+                sys_vgui("-parent .scelem%lx.%lx \\\n", parentglist, data);
             else
                 sys_vgui("-parent .dgroup%lx.%lx \\\n", x->x_canvas, sc->sc_vec);
             // this doesn't work with tkpath...
@@ -4920,7 +4897,7 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
         if (symfill == &s_) symfill = gensym("#000000");
         if (style == PLOTSTYLE_POINTS || style == PLOTSTYLE_BARS)
         {
-            symfill = style == PLOTSTYLE_POINTS ? symoutline : symfill;
+            symfill = (style == PLOTSTYLE_POINTS ? symoutline : symfill);
             t_float minyval = 1e20, maxyval = -1e20;
             int ndrawn = 0;
             sys_vgui(".x%lx.c create path { \\\n", glist_getcanvas(glist));
@@ -5165,7 +5142,7 @@ static void plot_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
                         fielddesc_cvttocoord(yfielddesc, yval));
                 }
 
-                sys_vgui("-strokewidth %f -stroke %s \\\n", linewidth, symoutline->s_name);
+                sys_vgui("-strokewidth %f -stroke %s -fill \"\" \\\n", linewidth, symoutline->s_name);
                 //if (style == PLOTSTYLE_BEZ) sys_vgui("-smooth 1 \\\n"); //this doesn't work with tkpath
                 if (in_array)
                     sys_vgui(" -parent .scelem%lx \\\n", data);
@@ -6277,8 +6254,8 @@ static void drawnumber_getrect(t_gobj *z, t_glist *glist,
     drawnumber_sprintf(x, buf, &at);
     *xp1 = xloc;
     *yp1 = yloc;
-    *xp2 = xloc + (fontwidth * strlen(buf) * xscale);
-    *yp2 = yloc + (fontheight * yscale);
+    *xp2 = xloc + (fontwidth * strlen(buf));
+    *yp2 = yloc + (fontheight);
 }
 
 static void drawnumber_displace(t_gobj *z, t_glist *glist,
@@ -6323,7 +6300,11 @@ static void drawnumber_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
     if (vis)
     {
         t_atom at;
-
+        int in_array = (sc->sc_vec == data) ? 0 : 1;
+        t_float xscale = glist_xtopixels(glist, 1) - glist_xtopixels(glist, 0);
+        t_float yscale = glist_ytopixels(glist, 1) - glist_ytopixels(glist, 0);
+        if (xscale != 0) xscale = 1.0 / xscale;
+        if (yscale != 0) yscale = 1.0 / yscale;
         int fontsize = fielddesc_getfloat(&x->x_fontsize, template, data, 0);
         if (!fontsize) fontsize = glist_getfont(glist);
         /*int xloc = glist_xtopixels(glist,
@@ -6351,8 +6332,14 @@ static void drawnumber_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
                sys_hostfontsize(fontsize), yloc, colorstring, buf);
         /* have to remove fontweight for the time being... */
         sys_vgui(" -fontfamily {%s} -fontsize %d", sys_font, fontsize);
-        sys_vgui(" -parent .scalar%lx", data);
-        /* sys_vgui(" -matrix {{%g 0.0} {0.0 %g} {0.0 0.0}}", xinv, yinv); */
+        sys_vgui(" -matrix { {%g 0} {0 %g} {0 0} }", xscale, yscale);
+
+        if (in_array)
+            sys_vgui(" -parent .scelem%lx.%lx \\\n", parentglist, data);
+        else
+            sys_vgui(" -parent .dgroup%lx.%lx \\\n",
+                x->x_canvas, data);
+
         sys_vgui(" -tags {.x%lx.x%lx.template%lx scalar%lx}\n", 
             glist_getcanvas(glist), glist, data, sc);
     }
@@ -6654,6 +6641,7 @@ static void drawsymbol_getrect(t_gobj *z, t_glist *glist,
         basex + fielddesc_getcoord(&x->x_xloc, template, data, 0));
     yloc = glist_ytopixels(glist,
         basey + fielddesc_getcoord(&x->x_yloc, template, data, 0));
+
     font = fielddesc_getfloat(&x->x_fontsize, template, data, 0);
     if (!font) font = glist_getfont(glist);
     fontwidth = sys_fontwidth(font);
@@ -6664,8 +6652,8 @@ static void drawsymbol_getrect(t_gobj *z, t_glist *glist,
     drawsymbol_sprintf(x, buf, &at);
     *xp1 = xloc;
     *yp1 = yloc;
-    *xp2 = (xloc + (fontwidth * strlen(buf) * xscale));
-    *yp2 = (yloc + (fontheight * yscale));
+    *xp2 = (xloc + (fontwidth * strlen(buf)));
+    *yp2 = (yloc + (fontheight));
 }
 
 static void drawsymbol_displace(t_gobj *z, t_glist *glist,
@@ -6708,8 +6696,12 @@ static void drawsymbol_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
         return;
     if (vis)
     {
-        int in_array = (sc->sc_vec == data) ? 0 : 1;
         t_atom at;
+        int in_array = (sc->sc_vec == data) ? 0 : 1;
+        t_float xscale = glist_xtopixels(glist, 1) - glist_xtopixels(glist, 0);
+        t_float yscale = glist_ytopixels(glist, 1) - glist_ytopixels(glist, 0);
+        if (xscale != 0) xscale = 1.0 / xscale;
+        if (yscale != 0) yscale = 1.0 / yscale;
 
         int fontsize = fielddesc_getfloat(&x->x_fontsize, template, data, 0);
         if (!fontsize) fontsize = glist_getfont(glist);
@@ -6734,8 +6726,14 @@ static void drawsymbol_vis(t_gobj *z, t_glist *glist, t_glist *parentglist,
                 glist_getcanvas(glist), xloc, sys_font,
                 sys_hostfontsize(fontsize), yloc, colorstring, buf);
         sys_vgui(" -fontfamily {%s} -fontsize %d ", sys_font, fontsize);
-        sys_vgui(" -parent .scalar%lx", data);
-        /*  sys_vgui(" -matrix {{%g 0.0} {0.0 %g} {0.0 0.0}}", xinv, yinv); */
+        sys_vgui(" -matrix { {%g 0} {0 %g} {0 0} }", xscale, yscale);
+
+        if (in_array)
+            sys_vgui(" -parent .scelem%lx.%lx \\\n", parentglist, data);
+        else
+            sys_vgui(" -parent .dgroup%lx.%lx \\\n",
+                x->x_canvas, data);
+
         sys_vgui(" -tags {.x%lx.x%lx.template%lx scalar%lx}\n", 
             glist_getcanvas(glist), glist, data, sc);
     }