diff --git a/src/g_editor.c b/src/g_editor.c
index 274cc752b3a0f9aa046282c1025b53e8e1dcf3e8..bf13840c75daba961df2b4891a30ba6486df2053 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -55,7 +55,7 @@ static int screenx2;
 static int screeny2;
 static int copiedfont;
 static void canvas_dofont(t_canvas *x, t_floatarg font, t_floatarg xresize,
-    t_floatarg yresize);
+    t_floatarg yresize, int preview);
 extern void canvas_setbounds(t_canvas *x, int x1, int y1, int x2, int y2);
 int canvas_apply_restore_original_position(t_canvas *x, int orig_pos);
 extern void canvas_draw_gop_resize_hooks(t_canvas *x);
@@ -68,7 +68,7 @@ struct _outlet
     t_symbol *o_sym;
 };
 
-/* ----------- 11. selection -------------- */
+/* ----------- ??. selection -------------- */
 /*typedef struct _undo_sel
 {
     int u_index;
@@ -1724,7 +1724,45 @@ void canvas_undo_recreate(t_canvas *x, void *z, int action)
 	}
 }
 
-/* ----------- 11. selection -------------- */
+/* ----------- 11. font -------------- */
+
+typedef struct _undo_font
+{
+    int font;
+} t_undo_font;
+
+void *canvas_undo_set_font(t_canvas *x, int font)
+{
+	t_undo_font *u_f = (t_undo_font *)getbytes(sizeof(*u_f));
+	u_f->font = font;
+    return (u_f);
+}
+
+void canvas_undo_font(t_canvas *x, void *z, int action)
+{
+    t_undo_font *u_f = z;
+
+    if (action == UNDO_UNDO || action == UNDO_REDO) 
+    {
+		int tmp_font = sys_defaultfont;
+		t_canvas *x2 = canvas_getrootfor(x);
+
+		t_float resize = (t_float)sys_fontwidth(u_f->font)/(t_float)sys_fontwidth(x2->gl_font);
+
+		canvas_dofont(x2, u_f->font, resize, resize, 1);
+		sys_defaultfont = u_f->font;
+
+		u_f->font = tmp_font;
+    }
+    else if (action == UNDO_FREE)
+    {
+		if (u_f)
+			freebytes(u_f, sizeof(*u_f));
+    }
+}
+
+
+/* ----------- ??. selection -------------- */
 
 //structs are defined at the top of the file due to unusual undo/redo design of the selection
 
@@ -4253,7 +4291,7 @@ static void canvas_dopaste(t_canvas *x, t_binbuf *b)
                 (int)(x->gl_screeny2 - x->gl_screeny1),
                 (int)(x->gl_screenx1), (int)(x->gl_screeny1));
 			//hardwired stretchval and whichstretch until we figure out proper resizing
-			canvas_dofont(x, copiedfont, 100, 1);
+			canvas_dofont(x, copiedfont, 100, 1, 1);
 			//sys_vgui("pdtk_canvas_checkgeometry .x%lx\n", x);
 			canvas_redraw(x);
 		}
@@ -4741,7 +4779,7 @@ void canvas_tooltips(t_canvas *x, t_floatarg fyesplease)
 
     /* called by canvas_font below */
 static void canvas_dofont(t_canvas *x, t_floatarg font, t_floatarg xresize,
-    t_floatarg yresize)
+    t_floatarg yresize, int preview)
 {
     t_gobj *y;
     x->gl_font = font;
@@ -4749,7 +4787,8 @@ static void canvas_dofont(t_canvas *x, t_floatarg font, t_floatarg xresize,
     {
         //canvas_setundo(x, canvas_undo_move, canvas_undo_set_move(x, 0),
         //    "motion");
-		canvas_undo_add(x, 4, "motion", canvas_undo_set_move(x, 0));
+		if (!preview)
+			canvas_undo_add(x, 4, "motion", canvas_undo_set_move(x, 0));
         for (y = x->gl_list; y; y = y->g_next)
         {
             int x1, x2, y1, y2, nx1, ny1;
@@ -4764,27 +4803,34 @@ static void canvas_dofont(t_canvas *x, t_floatarg font, t_floatarg xresize,
     for (y = x->gl_list; y; y = y->g_next)
         if (pd_class(&y->g_pd) == canvas_class
             && !canvas_isabstraction((t_canvas *)y))
-                canvas_dofont((t_canvas *)y, font, xresize, yresize);
+                canvas_dofont((t_canvas *)y, font, xresize, yresize, preview);
 	sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", x);
 }
 
     /* canvas_menufont calls up a TK dialog which calls this back */
 static void canvas_font(t_canvas *x, t_floatarg font, t_floatarg resize,
-    t_floatarg whichresize)
+    t_floatarg whichresize, t_floatarg preview)
 {
     t_float realresize, realresx = 1, realresy = 1;
     t_canvas *x2 = canvas_getrootfor(x);
     if (!resize) realresize = 1;
     else
     {
-        if (resize < 20) resize = 20;
-        if (resize > 500) resize = 500;
-        realresize = resize * 0.01;
+		//fprintf(stderr,"%d %d %d\n", sys_fontwidth(font), sys_fontwidth(x->gl_font), x->gl_font);
+		realresize = (t_float)sys_fontwidth(font)/(t_float)sys_fontwidth(x2->gl_font); //*100.0;
+        //if (resize < 20) resize = 20;
+        //if (resize > 500) resize = 500;
+        //realresize = resize * 0.01;
     }
     if (whichresize != 3) realresx = realresize;
     if (whichresize != 2) realresy = realresize;
-    canvas_dofont(x2, font, realresx, realresy);
-    sys_defaultfont = font;
+
+	if (!preview) {
+		if (sys_defaultfont != font)
+			canvas_undo_add(x, 11, "font", canvas_undo_set_font(x, sys_defaultfont));
+		sys_defaultfont = font;
+	}
+    canvas_dofont(x2, font, realresx, realresy, preview);
 }
 
 static t_glist *canvas_last_glist;
@@ -4923,7 +4969,7 @@ void g_editor_setup(void)
     class_addmethod(canvas_class, (t_method)canvas_menufont,
         gensym("menufont"), A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_font,
-        gensym("font"), A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
+        gensym("font"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_find,
         gensym("find"), A_SYMBOL, A_FLOAT, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_find_again,
diff --git a/src/g_graph.c b/src/g_graph.c
index fd11c0a3a9236084a0cc2fe3f5f8324f55e6beeb..1272bac57b6485eb1ca2fbc4f1fd857839601389 100644
--- a/src/g_graph.c
+++ b/src/g_graph.c
@@ -720,12 +720,12 @@ void glist_redraw(t_glist *x)
                 //post("draw it");
 				/* update gop rect size on toplevel in case font has
 				changed and we are showing text */
-				if (!x->gl_hidetext) {
+				/*if (!x->gl_hidetext) {
 					int x1, y1, x2, y2;
 					graph_getrect((t_gobj *)x, x, &x1, &y1, &x2, &y2);
 					if (x2-x1 > x->gl_pixwidth) x->gl_pixwidth = x2-x1;
 					if (y2-y1 > x->gl_pixheight) x->gl_pixheight = y2-y1;
-				}
+				}*/
                 canvas_drawredrect(x, 1);
             }
         }
diff --git a/src/g_undo.c b/src/g_undo.c
index 390241a208099bbb68937b818781cc7412675ef2..441960e53ad05dae9baebe8310cf882d4cec8f40 100644
--- a/src/g_undo.c
+++ b/src/g_undo.c
@@ -67,7 +67,7 @@ void canvas_undo_undo(t_canvas *x)
 		    case 8:	canvas_undo_canvas_apply(x, x->u_last->data, UNDO_UNDO); break;	//canvas apply
 		    case 9:	canvas_undo_create(x, x->u_last->data, UNDO_UNDO); break;		//create
 		    case 10:canvas_undo_recreate(x, x->u_last->data, UNDO_UNDO); break;		//recreate
-			//case 11:canvas_undo_selection(x, x->u_last->data, UNDO_UNDO); break;	//selection
+			case 11:canvas_undo_font(x, x->u_last->data, UNDO_UNDO); break;			//font
 		    default:
 		        error("canvas_undo_undo: unsupported undo command %d", x->u_last->type);
         }
@@ -101,7 +101,7 @@ void canvas_undo_redo(t_canvas *x)
 		    case 8:	canvas_undo_canvas_apply(x, x->u_last->data, UNDO_REDO); break;	//canvas apply
 		    case 9:	canvas_undo_create(x, x->u_last->data, UNDO_REDO); break;		//create
 		    case 10:canvas_undo_recreate(x, x->u_last->data, UNDO_REDO); break;		//recreate
-			//case 11:canvas_undo_selection(x, x->u_last->data, UNDO_REDO); break;	//selection
+			case 11:canvas_undo_font(x, x->u_last->data, UNDO_REDO); break;			//font
 		    default:
 		        error("canvas_undo_redo: unsupported redo command %d", x->u_last->type);
         }
@@ -134,7 +134,7 @@ void canvas_undo_rebranch(t_canvas *x)
 			    case 8:	canvas_undo_canvas_apply(x, a->data, UNDO_FREE); break;	//canvas apply
 				case 9:	canvas_undo_create(x, a->data, UNDO_FREE); break;		//create
 				case 10:canvas_undo_recreate(x, a->data, UNDO_FREE); break;		//recreate
-				//case 11:canvas_undo_selection(x, a->data, UNDO_FREE); break;	//selection
+				case 11:canvas_undo_font(x, a->data, UNDO_FREE); break;			//font
 				default:
 				    error("canvas_undo_rebranch: unsupported undo command %d", a->type);
 		    }
@@ -174,7 +174,7 @@ void canvas_undo_free(t_canvas *x)
 			    case 8:	canvas_undo_canvas_apply(x, a->data, UNDO_FREE); break;	//canvas apply
 				case 9:	canvas_undo_create(x, a->data, UNDO_FREE); break;		//create
 				case 10:canvas_undo_recreate(x, a->data, UNDO_FREE); break;		//recreate
-				//case 11:canvas_undo_selection(x, a->data, UNDO_FREE); break;	//selection
+				case 11:canvas_undo_font(x, a->data, UNDO_FREE); break;			//font
 				default:
 				    error("canvas_undo_free: unsupported undo command %d", a->type);
 		    }
diff --git a/src/g_undo.h b/src/g_undo.h
index 68c744ae862357b9855b7c19d705e807d94158d4..48e62941c86a5331885c8d5fb7b7c362025c7d0e 100644
--- a/src/g_undo.h
+++ b/src/g_undo.h
@@ -115,10 +115,10 @@ EXTERN void *canvas_undo_set_create(t_canvas *x);
 EXTERN void canvas_undo_recreate(t_canvas *x, void *z, int action);
 EXTERN void *canvas_undo_set_recreate(t_canvas *x, t_gobj *y, int old_pos);
 
-/* --------- 11. selection ------- */
+/* --------- 11. font ------------ */
 
-//EXTERN void canvas_undo_selection(t_canvas *x, void *z, int action);
-//EXTERN void *canvas_undo_set_selection(t_canvas *x);
+EXTERN void canvas_undo_font(t_canvas *x, void *z, int action);
+EXTERN void *canvas_undo_set_font(t_canvas *x, int font);
 
 /* ------------------------------- */
 
diff --git a/src/pd.tk b/src/pd.tk
index 305ed3f9493328e80e7f641adec9a89bb37b7a38..4220b75ee83d8b85201abe631f29d01b062fa7eb 100644
--- a/src/pd.tk
+++ b/src/pd.tk
@@ -2545,6 +2545,8 @@ proc pdtk_canvas_new {name width height geometry editable} {
         bind $name.c <Button-5>  "pdtk_canvas_scroll $name.c y +1"
         bind $name.c <Shift-Button-4>  "pdtk_canvas_scroll $name.c x -1"
         bind $name.c <Shift-Button-5>  "pdtk_canvas_scroll $name.c x +1"
+        bind $name.c <Control-Button-4>  "pdtk_zoom $name 1"
+        bind $name.c <Control-Button-5>  "pdtk_zoom $name -1"
     } default {
         bind $name.c  <MouseWheel> \
             "pdtk_canvas_scroll $name.c y \[expr -abs(%D)/%D\]"
@@ -3378,15 +3380,33 @@ proc pdtk_canvas_saveas {name initfile initdir} {
 
 ############ pdtk_canvas_dofont -- run a font and resize dialog #########
 
-set fontsize 0
-set dofont_fontsize 0
-set stretchval 0
-set whichstretch 0
+set fontsize 10
+set dofont_fontsize 10
+set stretchval 100
+set whichstretch 1
 
-proc dofont_apply {name myfontsize} {
+# zooming (a subset of dofont)
+set font_array { 8 10 12 16 24 36 }
+
+proc pdtk_zoom {name direction} {
+	#puts stderr "pdtk_zoom $name $direction"
+	global font_array
+	global dofont_fontsize
+	set index [lsearch $font_array $dofont_fontsize]
+	if { $index == 5 && $direction == 1 || $index == 0 && $direction == -1 } {
+		return
+	} else {
+		set dofont_fontsize [lindex $font_array [expr $index + $direction]]
+		dofont_apply $name $dofont_fontsize 1
+	}
+}
+# end zooming
+
+proc dofont_apply {name myfontsize preview} {
+	#puts stderr "dofont_apply $name $myfontsize $preview"
     global stretchval
     global whichstretch
-    set cmd [concat $name font $myfontsize $stretchval $whichstretch \;]
+    set cmd [concat $name font $myfontsize $stretchval $whichstretch $preview \;]
     #    puts stderr $cmd
     pd $cmd
 }
@@ -3399,7 +3419,7 @@ proc dofont_close {name} {
 
 proc dofont_cancel {name} {
     global fontsize
-    dofont_apply $name $fontsize
+    dofont_apply $name $fontsize 1
     set cmd [concat $name cancel \;]
     #    puts stderr $cmd
     pd $cmd
@@ -3408,7 +3428,7 @@ proc dofont_cancel {name} {
 proc dofont_ok {name} {
     global fontsize dofont_fontsize
     set fontsize $dofont_fontsize
-    dofont_apply $name $fontsize
+    dofont_apply $name $fontsize 0
     dofont_close $name
 }
 
@@ -3418,10 +3438,10 @@ proc pdtk_canvas_dofont {name initsize} {
     set dofont_fontsize $initsize
 
     global stretchval
-    set stretchval 100
+    #set stretchval 100
     
     global whichstretch
-    set whichstretch 1
+    #set whichstretch 1
     
     toplevel $name
 	match_linux_wm [list $name configure]
@@ -3448,22 +3468,22 @@ proc pdtk_canvas_dofont {name initsize} {
 
     match_linux_wm [list radiobutton $name.radiof.radio8 -value 8 \
 		-variable dofont_fontsize -text "8" \
-        -command [concat dofont_apply $name 8]]
+        -command [concat dofont_apply $name 8 1]]
     match_linux_wm [list radiobutton $name.radiof.radio10 -value 10 \
 		-variable dofont_fontsize -text "10" \
-        -command [concat dofont_apply $name 10]]
+        -command [concat dofont_apply $name 10 1]]
     match_linux_wm [list radiobutton $name.radiof.radio12 -value 12 \
 		-variable dofont_fontsize -text "12" \
-        -command [concat dofont_apply $name 12]]
+        -command [concat dofont_apply $name 12 1]]
     match_linux_wm [list radiobutton $name.radiof.radio16 -value 16 \
 		-variable dofont_fontsize -text "16" \
-        -command [concat dofont_apply $name 16]]
+        -command [concat dofont_apply $name 16 1]]
     match_linux_wm [list radiobutton $name.radiof.radio24 -value 24 \
 		-variable dofont_fontsize -text "24" \
-        -command [concat dofont_apply $name 24]]
+        -command [concat dofont_apply $name 24 1]]
     match_linux_wm [list radiobutton $name.radiof.radio36 -value 36 \
 		-variable dofont_fontsize -text "36" \
-        -command [concat dofont_apply $name 36]]
+        -command [concat dofont_apply $name 36 1]]
     pack $name.radiof.radio8 -side top -anchor w
     pack $name.radiof.radio10 -side top -anchor w
     pack $name.radiof.radio12 -side top -anchor w
@@ -3482,21 +3502,28 @@ proc pdtk_canvas_dofont {name initsize} {
 #    pack $name.stretchf -side left
 #    
 #    match_linux_wm [list label $name.stretchf.label -text {Stretch:}]
-#    pack $name.stretchf.label -side top
-#    
+#    pack $name.stretchf.label -side top    
 #    match_linux_wm [list entry $name.stretchf.entry -textvariable stretchval -width 5]
 #    pack $name.stretchf.entry -side left
 #
 #    match_linux_wm [list radiobutton $name.stretchf.radio1 \
-#        -value 1 -variable whichstretch -text "X and Y"]
+#        -value 1 -variable whichstretc -text "X and Y" \
+#		-command [concat dofont_apply $name $dofont_fontsize 1]]
 #    match_linux_wm [list radiobutton $name.stretchf.radio2 \
-#        -value 2 -variable whichstretch -text "X only"]
+#        -value 2 -variable whichstretch -text "X only" \
+#		-command [concat dofont_apply $name $dofont_fontsize 1]]
 #    match_linux_wm [list radiobutton $name.stretchf.radio3 \
-#        -value 3 -variable whichstretch -text "Y only"]
-#
+#        -value 3 -variable whichstretch -text "Y only" \
+#		-command [concat dofont_apply $name $dofont_fontsize 1]]
 #    pack $name.stretchf.radio1 -side top -anchor w
 #    pack $name.stretchf.radio2 -side top -anchor w
 #    pack $name.stretchf.radio3 -side top -anchor w
+#
+#	if {[info tclversion] >= 8.5 && $pd_nt == 0} {
+#	    $name.stretchf.radio1 invoke
+#	} else {
+#	    $name.stretchf.radio1 select
+#	}
 
 }
 
@@ -7195,6 +7222,20 @@ proc pdtk_tip {w fromc show args} {
 	variable select_color
 	variable nlet_color
 	variable tooltip_visible
+	variable dofont_fontsize
+    global pd_fontlist
+    switch -- $dofont_fontsize {
+        8  { set typeface [lindex $pd_fontlist 0] }
+        9  { set typeface [lindex $pd_fontlist 1] }
+        10 { set typeface [lindex $pd_fontlist 2] }
+        12 { set typeface [lindex $pd_fontlist 3] }
+        14 { set typeface [lindex $pd_fontlist 4] }
+        16 { set typeface [lindex $pd_fontlist 5] }
+        18 { set typeface [lindex $pd_fontlist 6] }
+        24 { set typeface [lindex $pd_fontlist 7] }
+        30 { set typeface [lindex $pd_fontlist 8] }
+        36 { set typeface [lindex $pd_fontlist 9] }
+    }
 	set exists [winfo exists $w.tiplabel]
     if {$show == 0} {
         catch {destroy $w.tiplabel}
@@ -7210,7 +7251,8 @@ proc pdtk_tip {w fromc show args} {
 			set fg "#000000"
 		}
 		if {$exists} {    	
-			$w.tiplabel configure -text [join $args] -fg $fg -bg $nlet_color
+			$w.tiplabel configure -text [join $args] -fg $fg -bg $nlet_color \
+				-font $typeface
         	$w itemconfigure tiparrow -fill $nlet_color
 	    	$w dtag $w.tipwindow "sticky"
 	    	if {$fromc == 1} {
@@ -7219,7 +7261,7 @@ proc pdtk_tip {w fromc show args} {
 		} else {
             label $w.tiplabel -text [join $args] -bd 1 \
 	        -wraplength [winfo width $w] -bg $nlet_color -fg $fg -bd 1 \
-	        -padx 2 -pady 2 -relief flat
+	        -padx 2 -pady 2 -relief flat -font $typeface
 		}
         set xreal [expr [$w canvasx 0] + [winfo pointerx $w]-[winfo rootx $w]]
         set yreal [expr [$w canvasy 0] + [winfo pointery $w]-[winfo rooty $w]]
@@ -7280,9 +7322,9 @@ proc pdtk_tip {w fromc show args} {
 		}
 
 		if { $top_bottom < 0 } {
-			set yarrow [expr $y + [winfo reqheight $w.tiplabel]]
+			set yarrow [expr $y + [winfo reqheight $w.tiplabel] - 1]
 		} else {
-			set yarrow [expr $y - [winfo reqheight $w.tiplabel]]
+			set yarrow [expr $y - [winfo reqheight $w.tiplabel] + 1]
 		}
 
 		$w create polygon 0 0 0 0 0 0 -fill $nlet_color -width 4 -tags tiparrow