diff --git a/shoes/native.h b/shoes/native.h
index e4285dd..6b436de 100644
--- a/shoes/native.h
+++ b/shoes/native.h
@@ -56,6 +56,7 @@ void shoes_native_control_focus(SHOES_CONTROL_REF);
 void shoes_native_control_state(SHOES_CONTROL_REF, SHOES_BOOL, SHOES_BOOL);
 void shoes_native_control_remove(SHOES_CONTROL_REF, shoes_canvas *);
 void shoes_native_control_free(SHOES_CONTROL_REF);
+void shoes_native_control_setfont(SHOES_CONTROL_REF, char *, int);
 SHOES_SURFACE_REF shoes_native_surface_new(shoes_canvas *, VALUE, shoes_place *);
 void shoes_native_surface_position(SHOES_SURFACE_REF, shoes_place *, 
   VALUE, shoes_canvas *, shoes_place *);
diff --git a/shoes/native/cocoa.m b/shoes/native/cocoa.m
index 2c643a8..69f0072 100644
--- a/shoes/native/cocoa.m
+++ b/shoes/native/cocoa.m
@@ -909,6 +909,13 @@ shoes_native_control_remove(SHOES_CONTROL_REF ref, shoes_canvas *canvas)
   COCOA_DO([ref removeFromSuperview]);
 }
 
+
+void
+shoes_native_control_setfont(SHOES_CONTROL_REF ref, char *fontname, int fontsize)
+{
+  return;
+}
+
 void
 shoes_native_control_free(SHOES_CONTROL_REF ref)
 {
diff --git a/shoes/native/gtk.c b/shoes/native/gtk.c
index 671e3cb..2d6f90d 100644
--- a/shoes/native/gtk.c
+++ b/shoes/native/gtk.c
@@ -751,6 +751,12 @@ shoes_native_control_remove(SHOES_CONTROL_REF ref, shoes_canvas *canvas)
 }
 
 void
+shoes_native_control_setfont(SHOES_CONTROL_REF ref, char *fontname, int fontsize)
+{
+  return;
+}
+
+void
 shoes_native_control_free(SHOES_CONTROL_REF ref)
 {
   //
diff --git a/shoes/native/windows.c b/shoes/native/windows.c
index abd3aa0..2eae736 100644
--- a/shoes/native/windows.c
+++ b/shoes/native/windows.c
@@ -1122,6 +1122,27 @@ shoes_native_control_remove(SHOES_CONTROL_REF ref, shoes_canvas *canvas)
   DestroyWindow(ref);
 }
 
+
+// joel
+void
+shoes_native_control_setfont(SHOES_CONTROL_REF ref, char *fontname, int fontsize)
+{
+  HFONT hf;
+  HDC hdc;
+  long lfHeight;
+
+  // create font
+  hdc = GetDC(NULL);
+  lfHeight = -MulDiv(fontsize, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+  hf = CreateFont(lfHeight, 0, 0, 0, 0, FALSE, 0, 0, 0, 0, 0, 0, 0, fontname);
+
+  // send control set-font message
+  PostMessage(ref, WM_SETFONT, (WPARAM)hf, MAKELPARAM(TRUE,0));
+
+  SetFocus(ref);
+}
+
+
 void
 shoes_native_control_free(SHOES_CONTROL_REF ref)
 {
diff --git a/shoes/ruby.c b/shoes/ruby.c
index 1992940..a586143 100644
--- a/shoes/ruby.c
+++ b/shoes/ruby.c
@@ -3168,6 +3168,12 @@ shoes_control_set_state(VALUE self, VALUE state)
   return self;
 }
 
+VALUE shoes_control_get_font(VALUE self, char * font)
+{
+  GET_STRUCT(control, self_t);
+  return ATTR(self_t->attr, font);
+}
+
 VALUE
 shoes_control_temporary_hide(VALUE self)
 {
@@ -3218,7 +3224,18 @@ void
 shoes_control_check_styles(shoes_control *self_t)
 {
   VALUE x = ATTR(self_t->attr, state);
+  VALUE font;
   shoes_control_try_state(self_t, x);
+
+  // joel
+  if (!NIL_P(self_t->attr))
+  {
+    font = rb_hash_aref(self_t->attr, ID2SYM(rb_intern("font")));
+    if(!NIL_P(font))
+      {
+	shoes_native_control_setfont(self_t->ref, STR2CSTR(font), 12);
+      }
+  }
 }
 
 void
@@ -4723,6 +4740,7 @@ shoes_ruby_init()
   rb_define_method(cNative, "show", CASTHOOK(shoes_control_show), 0);
   rb_define_method(cNative, "state=", CASTHOOK(shoes_control_set_state), 1);
   rb_define_method(cNative, "state", CASTHOOK(shoes_control_get_state), 0);
+  rb_define_method(cNative, "font", CASTHOOK(shoes_control_get_font), 0);
   rb_define_method(cNative, "move", CASTHOOK(shoes_control_move), 2);
   rb_define_method(cNative, "top", CASTHOOK(shoes_control_get_top), 0);
   rb_define_method(cNative, "left", CASTHOOK(shoes_control_get_left), 0);
