diff --git a/vm/cmake/dependencies.cmake b/vm/cmake/dependencies.cmake
index 67e8535..7f17ac0 100644
--- a/vm/cmake/dependencies.cmake
+++ b/vm/cmake/dependencies.cmake
@@ -29,10 +29,12 @@ if(SELF_X11)
       endif()
       set(X11_INCLUDE_DIRS ${X11_INCLUDE_DIR})
     endif()
+
+   pkg_check_modules(XFT REQUIRED xft)
     
-    link_directories(${X11_LIBRARY_DIRS})
-    include_directories(${X11_INCLUDE_DIRS})
-    list(APPEND 3RD_PARTY_LIBS ${X11_LIBRARIES})     
+    link_directories(${X11_LIBRARY_DIRS} ${XFT_LIBRARY_DIRS})
+    include_directories(${X11_INCLUDE_DIRS} ${XFT_INCLUDE_DIRS})
+    list(APPEND 3RD_PARTY_LIBS ${X11_LIBRARIES} ${XFT_LIBRARIES})     
 endif()
 
 if(PKG_CONFIG_FOUND)
diff --git a/vm/src/any/os/xlibWindow.cpp b/vm/src/any/os/xlibWindow.cpp
index 2abf4d2..f23df24 100644
--- a/vm/src/any/os/xlibWindow.cpp
+++ b/vm/src/any/os/xlibWindow.cpp
@@ -16,8 +16,10 @@
 
 
 XPlatformWindow::XPlatformWindow() : AbstractPlatformWindow() {
-  _display   = NULL;
-  _font_info = NULL;
+  _display = NULL;
+  _gc = NULL;
+  _xft_drawable = NULL;
+  _xft_font = NULL;
 }
 
 
@@ -27,45 +29,47 @@ bool XPlatformWindow::open( const char* display_name,
                             int x, int y, int w, int h,
                             int min_w, int max_w, int min_h, int max_h, // -1 for don't care
                             const char* window_name,  const char* icon_name,
-                            const char* font_name,    int   /*font_size unimp X*/ ) {
+                            const char* font_name, int font_size) {
 
   // (adapted from Spy open routine, needs font info for sizing)
   // XOpenDisplay fails silently if a signal is received during the call.
-  // All signals except user interrupts are therefore blocked. 
+  // All signals except user interrupts are therefore blocked.
   SignalBlocker sb(SignalBlocker::allow_user_int);
-  
+
   if (!open_xdisplay(display_name)) { close();  return false; }
-  
+
   bool debugMe = false;              // set to true when debugging X
-  XSynchronize(_display, debugMe);  
+  XSynchronize(_display, debugMe);
   XSetErrorHandler(XErrorHandlers::handle_X_error);
 
   _screen_num     = DefaultScreen(_display);
+  _colormap       = DefaultColormap(_display, _screen_num);
   _display_width  = DisplayWidth (_display, _screen_num);
   _display_height = DisplayHeight(_display, _screen_num);
-  
+
   _window_x = x;  _window_y = y;  _width = w;  _height = h;
 
   // create the window; will be resized and repositioned when reparented
   Window root = RootWindow(_display, _screen_num);
-  
-  _xwindow = XCreateSimpleWindow(  _display, root,
-                                   _window_x, _window_y,
-                                   width(), height(), 0,
-                                   BlackPixel(_display, _screen_num),
-                                   WhitePixel(_display, _screen_num));
-  
-  if (!set_font_info(font_name))                       {  close();  return false; }
-  if (!change_size_hints(min_w, max_w, min_h, max_h))  {  close();  return false; }
-  
+
+  _xwindow = XCreateSimpleWindow(_display, root,
+                                 _window_x, _window_y,
+                                 width(), height(), 0,
+                                 BlackPixel(_display, _screen_num),
+                                 WhitePixel(_display, _screen_num));
+
+  if (!setup_xft_drawable())                           { close();  return false; }
+  if (!set_font_info(font_name, font_size))            { close();  return false; }
+  if (!change_size_hints(min_w, max_w, min_h, max_h))  { close();  return false; }
+
   if (!set_name(     window_name))  {  close(); return false; }
   if (!set_icon_name(  icon_name))  {  close(); return false; }
-  
-  setup_events();  
+
+  setup_events();
   XMapWindow(_display, _xwindow);
-  
+
  if (!setup_gcs())      {  close(); return false; }
- 
+
   return true;
 }
 
@@ -82,8 +86,8 @@ bool XPlatformWindow::open_xdisplay(const char *n) {
   return true;
 }
 
-  
-bool XPlatformWindow::set_icon_name(const char* icon_name) {  
+
+bool XPlatformWindow::set_icon_name(const char* icon_name) {
   XTextProperty iconName;
   if (XStringListToTextProperty((char**)&icon_name, 1, &iconName) == 0) {
     warning("X structure allocation for icon name failed--window won't work.");
@@ -105,12 +109,12 @@ bool XPlatformWindow::set_name(const char* window_name) {
 }
 
 
-void XPlatformWindow::setup_events() {  
+void XPlatformWindow::setup_events() {
   // to catch the clientMessage event when user deletes
   _wmProtocolsAtom    = XInternAtom(_display, "WM_PROTOCOLS",     false);
   _wmDeleteWindowAtom = XInternAtom(_display, "WM_DELETE_WINDOW", false);
   XSetWMProtocols(_display, _xwindow, &_wmDeleteWindowAtom, 1);
-  
+
   // choose events to receive
   long event_mask = ExposureMask | StructureNotifyMask;
   XSelectInput(_display, _xwindow, event_mask);
@@ -120,7 +124,7 @@ void XPlatformWindow::setup_events() {
 bool XPlatformWindow::tell_platform_size_hints() {
   if ( _min_w == -1)
     return true; // hack for don't care
-    
+
   // tell window manager that we'd like our own size and position
   XSizeHints* size_hints;
   if ((size_hints = XAllocSizeHints()) == NULL) {
@@ -138,10 +142,13 @@ bool XPlatformWindow::tell_platform_size_hints() {
 }
 
 
-bool XPlatformWindow::set_font_info(const char* font_name) {  
-  // must set _font_info here so that font_height() is defined for BOTTOM 
-  _font_info = XLoadQueryFont(_display, font_name);
-  return _font_info != NULL;
+bool XPlatformWindow::set_font_info(const char* font_name, int size) {
+  // must set _xft_font here so that font_height() is defined for BOTTOM
+  _xft_font = XftFontOpen(_display, _screen_num,
+                          XFT_FAMILY, XftTypeString, font_name,
+                          XFT_SIZE, XftTypeDouble, double(size),
+                          NULL);
+  return _xft_font != NULL;
 }
 
 
@@ -150,11 +157,10 @@ bool XPlatformWindow::setup_gcs() {
   unsigned long valuemask = 0;
   XGCValues values;
   _gc = XCreateGC(_display, _xwindow, valuemask, &values);
-  
-  XSetFont(_display, _gc, _font_info->fid);
+
   XSetForeground(_display, _gc, BlackPixel(_display, _screen_num));
   XSetBackground(_display, _gc, WhitePixel(_display, _screen_num));
-  
+
   // 16x16 grey stipple pixmap (16x16 is preferred stipple size)
   const int grey_width = 16;
   const int grey_height = 16;
@@ -165,28 +171,35 @@ bool XPlatformWindow::setup_gcs() {
   Pixmap stipple = XCreateBitmapFromData(_display, _xwindow, grey_bits,
                                          grey_width, grey_height);
   XSetStipple(_display, _gc, stipple);
-  
+
   _black= BlackPixel(_display, _screen_num);
   _white= WhitePixel(_display, _screen_num);
   _is_mono = DefaultDepth(_display, _screen_num) == 1;
   if (_is_mono)
     _red= _yellow= _gray= _black;
   else {
-    Colormap cmap= DefaultColormap(_display, _screen_num);
     XColor col1, col2;
-    _red= XAllocNamedColor(_display, cmap, "red", &col1, &col2)
+    _red= XAllocNamedColor(_display, _colormap, "red", &col1, &col2)
       ? col1.pixel : _black;
-    _yellow= XAllocNamedColor(_display, cmap, "gold", &col1, &col2)
+    _yellow= XAllocNamedColor(_display, _colormap, "gold", &col1, &col2)
       ? col1.pixel : _black;
-    _gray= XAllocNamedColor(_display, cmap, "gray", &col1, &col2)
+    _gray= XAllocNamedColor(_display, _colormap, "gray", &col1, &col2)
       ? col1.pixel : _black;
   }
   return true;
 }
 
 
-void XPlatformWindow::close() { 
-  if (_font_info != NULL) { XFreeFont(_display, _font_info); _font_info = NULL; }
+void XPlatformWindow::close() {
+  if (_xft_font) {
+    XftFontClose(_display, _xft_font);
+    _xft_font = NULL;
+  }
+  if (_xft_drawable) {
+    XftColorFree(_display, DefaultVisual(_display, _screen_num), _colormap, &_foreground_xft_color);
+    XftDrawDestroy(_xft_drawable);
+    _xft_drawable = NULL;
+  }
   if (_gc        != NULL) { XFreeGC(  _display, _gc);               _gc = NULL; }
   if (_display   != NULL) { XCloseDisplay(_display);           _display = NULL; }
 }
@@ -213,17 +226,17 @@ int  XPlatformWindow::height() { return _height; }
 int  XPlatformWindow::screen_width()   { return _display_width; }
 int  XPlatformWindow::screen_height()  { return _display_height; }
 int  XPlatformWindow::menubar_height() { return 0; } // none in X
-  
-int  XPlatformWindow::font_width() { return _font_info->max_bounds.width; }
-int  XPlatformWindow::font_height() { return _font_info->max_bounds.ascent + _font_info->max_bounds.descent; }
 
-const char* XPlatformWindow::default_fixed_font_name() { return "fixed"; }
+int  XPlatformWindow::font_width() { return _xft_font->max_advance_width; }
+int  XPlatformWindow::font_height() { return _xft_font->height; }
+
+const char* XPlatformWindow::default_fixed_font_name() { return "monospace"; }
 int   XPlatformWindow::default_fixed_font_size() { return 10; }
 
 
 // Handy operations;
 
-bool XPlatformWindow::change_extent(int left, int top, int w, int h) { 
+bool XPlatformWindow::change_extent(int left, int top, int w, int h) {
   // left, top in global coordinates
   // don't need to adjust by insets for X
   XMoveResizeWindow(_display, _xwindow, left, top, w, h);
@@ -233,7 +246,7 @@ bool XPlatformWindow::change_extent(int left, int top, int w, int h) {
   _height = h;
   return true;
 }
-void XPlatformWindow::adjust_after_resize() { 
+void XPlatformWindow::adjust_after_resize() {
   if (TheSpy != NULL)
     TheSpy->adjust_after_resize(); // in case this is the spy
 }
@@ -255,7 +268,12 @@ bool XPlatformWindow:: pre_draw( bool incremental) {
 void XPlatformWindow::post_draw( bool ) { /* XFlush(_display); should be needed but was not there before */ }
 
 void XPlatformWindow::draw_text(const char* text, int x, int y) {
-  XDrawImageString(_display, _xwindow, _gc, x, y, text, strlen(text));
+  assert(_xft_drawable);
+  assert(_xft_font);
+
+  XftDrawStringUtf8(_xft_drawable, &_foreground_xft_color,
+                    _xft_font, x, y, (FcChar8*)text,
+                    strlen(text));
 }
 
 void XPlatformWindow::draw_line(int x1, int y1, int x2, int y2) {
@@ -266,7 +284,7 @@ void XPlatformWindow::draw_rectangle_black(int x, int y, int w, int h) {
   if (w > 0 && h > 0)
     XDrawRectangle(_display, _xwindow, _gc, x, y, w, h);
 }
-      
+
 
 void XPlatformWindow::clear_rectangle(int x, int y, int w, int h) {
   if (w > 0 && h > 0)
@@ -275,23 +293,82 @@ void XPlatformWindow::clear_rectangle(int x, int y, int w, int h) {
 
 
 // X drawing functions
-// the X calls do the wrong thing if w or h is 0, so suppress these calls 
+// the X calls do the wrong thing if w or h is 0, so suppress these calls
 
 void XPlatformWindow::fill_rectangle(int x, int y, int w, int h) {
   if (w > 0 && h > 0)
     XFillRectangle(_display, _xwindow, _gc, x, y, w, h);
 }
 
-void XPlatformWindow::set_color(int c)     { XSetForeground    (_display, _gc, c); }
+void XPlatformWindow::set_color(int c) {
+  XSetForeground(_display, _gc, c);
+  set_xft_color_from_pixel(c);
+}
+
 void XPlatformWindow::set_thickness(int t) { XSetLineAttributes(_display, _gc, t, LineSolid, CapButt, JoinMiter); }
 void XPlatformWindow::set_xor()            { XSetFunction      (_display, _gc, GXxor);  }
 void XPlatformWindow::set_copy()           { XSetFunction      (_display, _gc, GXcopy); }
 
+bool XPlatformWindow::setup_xft_drawable()
+{
+  _foreground_render_color.red = 0;
+  _foreground_render_color.green = 0;
+  _foreground_render_color.blue = 0;
+  _foreground_render_color.alpha = 65535u;
+
+  if (!XftColorAllocValue(_display,
+                          DefaultVisual(_display, _screen_num),
+                          _colormap,
+                          &_foreground_render_color,
+                          &_foreground_xft_color))
+  {
+    return false;
+  }
+
+  _xft_drawable = XftDrawCreate(_display,
+                                _xwindow,
+                                DefaultVisual(_display, _screen_num),
+                                _colormap);
+  if (!_xft_drawable)
+  {
+    XftColorFree(_display, DefaultVisual(_display, _screen_num), _colormap, &_foreground_xft_color);
+    return false;
+  }
 
-bool XPlatformWindow::get_graphics_semaphore() { 
+  return true;
+}
+
+void XPlatformWindow::set_xft_color_from_pixel(unsigned long pixel)
+{
+  XColor xcolor = {0};
+  xcolor.pixel = pixel;
+  xcolor.flags = DoRed | DoGreen | DoBlue;
+  XQueryColor(_display, _colormap, &xcolor);
+
+  XRenderColor renderColor;
+  renderColor.red = xcolor.red;
+  renderColor.green = xcolor.green;
+  renderColor.blue = xcolor.blue;
+  renderColor.alpha = 65535u;
+
+  XftColor xftColor;
+
+  if (XftColorAllocValue(_display,
+                         DefaultVisual(_display, _screen_num),
+                         _colormap,
+                         &renderColor,
+                         &xftColor))
+  {
+    XftColorFree(_display, DefaultVisual(_display, _screen_num), _colormap, &_foreground_xft_color);
+    _foreground_render_color = renderColor;
+    _foreground_xft_color = xftColor;
+  }
+}
+
+bool XPlatformWindow::get_graphics_semaphore() {
   // if you draw while X may be drawing something else, check this
   // and don't draw if it is true
-  extern bool xlib_semaphore; 
+  extern bool xlib_semaphore;
   return xlib_semaphore;
 }
 
@@ -306,22 +383,22 @@ bool XPlatformWindow::handle_polled_events() {
   while ( XPending(_display) > 0 ) {
     XNextEvent(_display, &event);
     switch (event.type) {
-    
+
      case Expose:
       if (event.xexpose.count != 0) break;
       full_redraw(); // force redraw
       break;
-      
+
      case ConfigureNotify:
       _width  = event.xconfigure.width;
       _height = event.xconfigure.height;
       adjust_after_resize();
       break;
-      
-     case ReparentNotify: 
+
+     case ReparentNotify:
       handle_reparent_event(event);
       break;
-      
+
      case ClientMessage:
       if ((event.xclient.message_type = _wmProtocolsAtom)
           && (event.xclient.data.l[0] = _wmDeleteWindowAtom)) {
@@ -330,7 +407,7 @@ bool XPlatformWindow::handle_polled_events() {
         return false;
       }
       break;
-      
+
      default:
       break;
     }
@@ -344,13 +421,13 @@ void XPlatformWindow::handle_reparent_event(XEvent& event) {
   int x, y;
   unsigned w, h, border_width, depth;
   if (XGetGeometry(_display, event.xreparent.parent, &root, &x, &y,
-                   &w, &h, &border_width, &depth) == 0) 
+                   &w, &h, &border_width, &depth) == 0)
     return;
   int wdelta = w - width();
   // sanity check: sometimes X gives weird width
   if (wdelta < 0) {
     if (XGetGeometry(_display, event.xreparent.parent, &root, &x, &y,
-                     &w, &h, &border_width, &depth) == 0) 
+                     &w, &h, &border_width, &depth) == 0)
       return;
     wdelta = w - width();
     if (wdelta < 0) {
diff --git a/vm/src/any/os/xlibWindow.hh b/vm/src/any/os/xlibWindow.hh
index 396bf5a..a6c43d0 100644
--- a/vm/src/any/os/xlibWindow.hh
+++ b/vm/src/any/os/xlibWindow.hh
@@ -20,11 +20,15 @@ class XPlatformWindow: public AbstractPlatformWindow {
   int           _screen_num;
   int           _display_width, _display_height;
   Window        _xwindow;
+  XftDraw*      _xft_drawable;
+  Colormap      _colormap;
   int           _window_x, _window_y;
-  int           _width,  _height;  
-  XFontStruct*  _font_info;  
+  int           _width,  _height;
+  XftFont*      _xft_font;
   Atom          _wmProtocolsAtom, _wmDeleteWindowAtom;
   GC            _gc;
+  XRenderColor  _foreground_render_color;
+  XftColor      _foreground_xft_color;
   bool          _is_mono;
 
  public:
@@ -90,11 +94,14 @@ class XPlatformWindow: public AbstractPlatformWindow {
   // Open helpers
   bool  open_xdisplay(const char*);
   void  setup_events();
+  bool  setup_xft_drawable();
   bool  set_name(const char*);
   bool  set_icon_name(const char*);
-  bool  set_font_info(const char*);
+  bool  set_font_info(const char*, int size);
   bool  setup_gcs();
   
+  void set_xft_color_from_pixel(unsigned long pixel);
+  
   // Drawing helpers
   bool    get_graphics_semaphore(); // X is not reentrant
     
diff --git a/vm/src/unix/prims/x_includes.hh b/vm/src/unix/prims/x_includes.hh
index 9349ee8..06db282 100644
--- a/vm/src/unix/prims/x_includes.hh
+++ b/vm/src/unix/prims/x_includes.hh
@@ -12,6 +12,7 @@
 # define Cursor SelfX11Cursor // prevent clash with Carbon
 # include <X11/Xlib.h>
 # include <X11/Xutil.h>
+# include <X11/Xft/Xft.h>
 # undef Cursor
 # if TARGET_OS_VERSION == MACOSX_VERSION
 #     undef Status
